|
4 | 4 |
|
5 | 5 | describe BatchUpdate do
|
6 | 6 | describe '#batch_update_statements' do
|
7 |
| - subject(:sql_queries) { Cat.batch_update_statements(cats, **kwargs) } |
| 7 | + subject(:sql_queries) { Cat.__send__(:batch_update_statements, cats, **kwargs) } |
8 | 8 |
|
9 | 9 | let(:cats) { [] }
|
10 | 10 | let(:kwargs) { {} }
|
|
100 | 100 | end
|
101 | 101 | end
|
102 | 102 |
|
103 |
| - it 'batches queries accordingly' do |
104 |
| - query1 = <<~SQL.squish |
105 |
| - WITH "batch_updates" (id, name) AS ( |
106 |
| - VALUES (CAST(1 AS INTEGER), CAST('foo' AS varchar)) |
107 |
| - ) |
108 |
| - UPDATE "cats" |
109 |
| - SET |
110 |
| - "name" = "batch_updates"."name" |
111 |
| - FROM "batch_updates" |
112 |
| - WHERE |
113 |
| - "cats"."id" = "batch_updates"."id" |
114 |
| - SQL |
115 |
| - |
116 |
| - query2 = <<~SQL.squish |
117 |
| - WITH "batch_updates" (id, name) AS ( |
118 |
| - VALUES (CAST(2 AS INTEGER), CAST('bar' AS varchar)) |
119 |
| - ) |
120 |
| - UPDATE "cats" |
121 |
| - SET |
122 |
| - "name" = "batch_updates"."name" |
123 |
| - FROM "batch_updates" |
124 |
| - WHERE |
125 |
| - "cats"."id" = "batch_updates"."id" |
126 |
| - SQL |
127 |
| - |
128 |
| - expect( |
129 |
| - Cat.batch_update_statements( |
130 |
| - [ |
131 |
| - { id: 1, name: 'foo' }, |
132 |
| - { id: 2, name: 'bar' } |
133 |
| - ], |
134 |
| - batch_size: 1 |
135 |
| - ) |
136 |
| - ).to contain_exactly(query1, query2) |
| 103 | + context 'with a custom batch_size' do |
| 104 | + let(:cats) do |
| 105 | + [ |
| 106 | + { id: 1, name: 'foo' }, |
| 107 | + { id: 2, name: 'bar' } |
| 108 | + ] |
| 109 | + end |
| 110 | + |
| 111 | + let(:kwargs) do |
| 112 | + { batch_size: 1 } |
| 113 | + end |
| 114 | + |
| 115 | + it 'batches queries accordingly' do |
| 116 | + query1 = <<~SQL.squish |
| 117 | + WITH "batch_updates" (id, name) AS ( |
| 118 | + VALUES (CAST(1 AS INTEGER), CAST('foo' AS varchar)) |
| 119 | + ) |
| 120 | + UPDATE "cats" |
| 121 | + SET |
| 122 | + "name" = "batch_updates"."name" |
| 123 | + FROM "batch_updates" |
| 124 | + WHERE |
| 125 | + "cats"."id" = "batch_updates"."id" |
| 126 | + SQL |
| 127 | + |
| 128 | + query2 = <<~SQL.squish |
| 129 | + WITH "batch_updates" (id, name) AS ( |
| 130 | + VALUES (CAST(2 AS INTEGER), CAST('bar' AS varchar)) |
| 131 | + ) |
| 132 | + UPDATE "cats" |
| 133 | + SET |
| 134 | + "name" = "batch_updates"."name" |
| 135 | + FROM "batch_updates" |
| 136 | + WHERE |
| 137 | + "cats"."id" = "batch_updates"."id" |
| 138 | + SQL |
| 139 | + |
| 140 | + expect(sql_queries).to contain_exactly(query1, query2) |
| 141 | + end |
137 | 142 | end
|
138 | 143 | end
|
139 | 144 |
|
|
150 | 155 |
|
151 | 156 | it 'does not insert a new record' do
|
152 | 157 | expect do
|
153 |
| - Cat.batch_update([non_existing_record], columns: :all, validate: false) |
| 158 | + Cat.batch_update([non_existing_record], columns: :all) |
154 | 159 | end.to execute_queries(/UPDATE/)
|
155 | 160 | .and not_change(Cat, :count)
|
156 | 161 | .and(not_change { Cat.exists?(id: non_existing_record.id) })
|
|
166 | 171 | cat1.name = 'can I haz cheeseburger pls'
|
167 | 172 | cat2.name = 'O\'Sullivans cuba libre'
|
168 | 173 | cat2.birthday = '2024-01-01'
|
169 |
| - Cat.batch_update([cat1, cat2], columns: :all, validate: false) |
| 174 | + Cat.batch_update([cat1, cat2], columns: :all) |
170 | 175 | end.to execute_queries(
|
171 | 176 | /WITH "batch_updates" .* AS \( VALUES.* UPDATE "cats" SET "birthday" = "batch_updates"."birthday", "name" = "batch_updates"."name", "updated_at" = "batch_updates"."updated_at" FROM "batch_updates"/,
|
172 | 177 | /WITH "batch_updates" .* AS \( VALUES.* UPDATE "cats" SET "name" = "batch_updates"."name", "updated_at" = "batch_updates"."updated_at" FROM "batch_updates"/
|
|
182 | 187 | expect do
|
183 | 188 | cat1.bitcoin_address = 'abc'
|
184 | 189 |
|
185 |
| - Cat.batch_update([cat1], columns: %i[bitcoin_address], validate: false) |
| 190 | + Cat.batch_update([cat1], columns: %i[bitcoin_address]) |
186 | 191 | end.to execute_queries(
|
187 | 192 | /WITH "batch_updates" \(bitcoin_address, id, updated_at\) AS \( VALUES \(CAST\(.* AS varchar\), CAST\(\d* AS INTEGER\), CAST\(.* AS datetime\(6\)\)\) \) UPDATE "cats" SET "bitcoin_address" = "batch_updates"."bitcoin_address", "updated_at" = "batch_updates"."updated_at" FROM "batch_updates" WHERE "cats"."id" = "batch_updates"."id"/
|
188 | 193 | ).and change { cat1.reload.bitcoin_address }.to('abc')
|
|
195 | 200 | it 'does not remove it' do
|
196 | 201 | expect do
|
197 | 202 | cat1.name = 'can I haz cheeseburger pls'
|
198 |
| - Cat.batch_update([cat1], columns: :all, validate: false) |
| 203 | + Cat.batch_update([cat1], columns: :all) |
199 | 204 | end.to change { cat1.reload.name }.to('can I haz cheeseburger pls')
|
200 | 205 | end
|
201 | 206 | end
|
|
206 | 211 | it 'does not break the query' do
|
207 | 212 | expect do
|
208 | 213 | cat1.name = 'La Rose Blanche \\'
|
209 |
| - Cat.batch_update([cat1], columns: :all, validate: false) |
| 214 | + Cat.batch_update([cat1], columns: :all) |
210 | 215 | end.to change { cat1.reload.name }.to('La Rose Blanche \\')
|
211 | 216 | end
|
212 | 217 | end
|
213 | 218 | end
|
214 | 219 |
|
215 |
| - describe 'when some fields changed, but are not included in only kwarg' do |
216 |
| - let!(:cat1) { Cat.create!(name: 'Felix', birthday: Date.new(2010, 1, 1)) } |
217 |
| - let!(:cat2) { Cat.create!(name: 'Garfield', birthday: Date.new(2011, 2, 2)) } |
| 220 | + context 'when the columns kwargs is specified' do |
| 221 | + describe 'when not all changes are included the columns kwarg' do |
| 222 | + let!(:cat1) { Cat.create!(name: 'Felix', birthday: Date.new(2010, 1, 1)) } |
| 223 | + let!(:cat2) { Cat.create!(name: 'Garfield', birthday: Date.new(2011, 2, 2)) } |
218 | 224 |
|
219 |
| - it 'does not change them' do |
220 |
| - expect do |
221 |
| - cat1.name = 'can I haz cheeseburger pls' |
222 |
| - cat2.name = 'O\'Sullivans cuba libre' |
223 |
| - cat2.birthday = Date.new(2024, 1, 1) |
224 |
| - Cat.batch_update([cat1, cat2], columns: %w[name], validate: false) |
225 |
| - end.to execute_queries( |
226 |
| - /WITH "batch_updates" .* AS \( VALUES.* UPDATE "cats" SET "name" = "batch_updates"."name", "updated_at" = "batch_updates"."updated_at" FROM "batch_updates"/ |
227 |
| - ).and change { cat1.reload.name }.to('can I haz cheeseburger pls') |
228 |
| - .and change { cat2.reload.name }.to('O\'Sullivans cuba libre') |
229 |
| - .and(not_change { cat2.reload.birthday }) |
| 225 | + it 'does not change them' do |
| 226 | + expect do |
| 227 | + cat1.name = 'can I haz cheeseburger pls' |
| 228 | + cat2.name = 'O\'Sullivans cuba libre' |
| 229 | + cat2.birthday = Date.new(2024, 1, 1) |
| 230 | + Cat.batch_update([cat1, cat2], columns: %w[name]) |
| 231 | + end.to execute_queries( |
| 232 | + /WITH "batch_updates" .* AS \( VALUES.* UPDATE "cats" SET "name" = "batch_updates"."name", "updated_at" = "batch_updates"."updated_at" FROM "batch_updates"/ |
| 233 | + ).and(change { cat1.reload.name }.to('can I haz cheeseburger pls')) |
| 234 | + .and(change { cat2.reload.name }.to('O\'Sullivans cuba libre')) |
| 235 | + .and(not_change { cat2.reload.birthday }) |
| 236 | + end |
| 237 | + end |
| 238 | + |
| 239 | + describe 'when no changes overlap with the columns kwarg' do |
| 240 | + let!(:cat) { Cat.create!(name: 'Felix', birthday: Date.new(2010, 1, 1)) } |
| 241 | + |
| 242 | + it 'does not run any query and make no changes' do |
| 243 | + expect do |
| 244 | + cat.name = 'can I haz cheeseburger pls' |
| 245 | + Cat.batch_update([cat], columns: %w[birthday]) |
| 246 | + end.to execute_no_queries |
| 247 | + .and(not_change { cat.reload.name }) |
| 248 | + .and(not_change { cat.reload.birthday }) |
| 249 | + end |
230 | 250 | end
|
231 | 251 | end
|
232 | 252 |
|
|
259 | 279 | before_import_cat = cat1
|
260 | 280 | before_import_cat.name = 'Yoda'
|
261 | 281 |
|
262 |
| - Cat.batch_update([before_import_cat], columns: %i[name], validate: false) |
| 282 | + Cat.batch_update([before_import_cat], columns: %i[name]) |
263 | 283 |
|
264 | 284 | after_import_cat = Cat.find(before_import_cat.id)
|
265 | 285 | expect(before_import_cat.name).to eq('Yoda')
|
|
0 commit comments