bulk_dependency_eraser 4.4.0 → 4.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: edd475ac4b724fa8a753feae41ca8f49ec39aa35423148f8b47bd8e21c35308e
|
4
|
+
data.tar.gz: 685ed6ea1defca2e3406ada070642962c5cb884b18ce1eb52959f65703ddd5b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f87e4146f122cfd686c3475584ee01123f216220c251ee54c978918d2e9ebf8287f1f84cc2cfe1dc04302b17ff506c7c3b1513b2a974a2316b978b9bebbe8bb0
|
7
|
+
data.tar.gz: f1e5d3abf75c17dc750f2a687c8c6fc3a5b150e84559aefa8a89f26abfa1d6e7b7ec787b9fd987784f9ae932004f9ab2a9e25fd2ac3f4f10d2b2ce2ee5e7a27b
|
@@ -327,7 +327,8 @@ module BulkDependencyEraser
|
|
327
327
|
end
|
328
328
|
end
|
329
329
|
|
330
|
-
|
330
|
+
valid_primary_key = klass.primary_key == 'id' || klass.primary_key.is_a?(Array) && klass.primary_key.include?('id')
|
331
|
+
unless valid_primary_key
|
331
332
|
report_error(
|
332
333
|
"#{klass.name} - does not use primary_key 'id'. Cannot use this tool to bulk delete."
|
333
334
|
)
|
@@ -468,7 +469,8 @@ module BulkDependencyEraser
|
|
468
469
|
|
469
470
|
assoc_query = assoc_klass.unscoped
|
470
471
|
|
471
|
-
|
472
|
+
valid_primary_key = assoc_klass.primary_key == 'id' || assoc_klass.primary_key.is_a?(Array) && assoc_klass.primary_key.include?('id')
|
473
|
+
unless valid_primary_key
|
472
474
|
report_error("#{parent_class.name}'s association '#{association_name}' - assoc class does not use 'id' as a primary_key")
|
473
475
|
return
|
474
476
|
end
|
@@ -589,7 +591,8 @@ module BulkDependencyEraser
|
|
589
591
|
|
590
592
|
assoc_query = assoc_klass.unscoped
|
591
593
|
|
592
|
-
|
594
|
+
valid_primary_key = assoc_klass.primary_key == 'id' || assoc_klass.primary_key.is_a?(Array) && assoc_klass.primary_key.include?('id')
|
595
|
+
unless valid_primary_key
|
593
596
|
report_error("#{parent_class.name}'s association '#{association_name}' - assoc class does not use 'id' as a primary_key")
|
594
597
|
return
|
595
598
|
end
|
@@ -146,30 +146,19 @@ module BulkDependencyEraser
|
|
146
146
|
detected_additional_identifier_columns = additional_identifiers&.values&.flat_map(&:keys)&.uniq || []
|
147
147
|
|
148
148
|
if opts_c.use_pg_system_column_ctid && opts_c.delete_ctids_by_partions && (detected_additional_identifier_columns & ['ctid', 'tableoid::regclass']).size == 2
|
149
|
-
|
149
|
+
deletable_partioned_tables_by_ctids = additional_identifiers.values.pluck('tableoid::regclass').uniq
|
150
150
|
end
|
151
151
|
|
152
152
|
if batching_disabled?
|
153
153
|
puts "Deleting without batching" if opts_c.verbose
|
154
154
|
# Delete by partioned CTIDs
|
155
|
-
if
|
155
|
+
if deletable_partioned_tables_by_ctids
|
156
156
|
puts "Deleting via CTID and table partitions" if opts_c.verbose
|
157
|
-
|
157
|
+
deletable_partioned_tables_by_ctids.each do |table_partition|
|
158
158
|
identifiers_by_partition = additional_identifiers.filter { |id, identifiers| identifiers['tableoid::regclass'] == table_partition }
|
159
159
|
ctids = identifiers_by_partition.values.pluck('ctid')
|
160
|
-
|
161
|
-
|
162
|
-
DELETE FROM #{table_partition}
|
163
|
-
WHERE ctid IN (#{ctids.map { |c| "'#{c}'" }.join(', ')});
|
164
|
-
SQL
|
165
|
-
# Due to the way we've mocked/aliased the partition table in this gem test, we need to also add the partition name as a where clause.
|
166
|
-
if ENV['TEST_GEM_ENV'] == 'bulk_dependency_eraser'
|
167
|
-
sql.sub!(/;\s*$/, "") # remove terminating semicolon
|
168
|
-
sql << " AND tableoid = '#{table_partition}';"
|
169
|
-
end
|
170
|
-
deleted_count = klass.connection.delete(sql)
|
171
|
-
[deleted_count, sql, identifiers_by_partition.keys, identifiers_by_partition]
|
172
|
-
end
|
160
|
+
ids = identifiers_by_partition.values.pluck('id')
|
161
|
+
deletion_by_partitioned_ctids(query, ids, ctids, table_partition, identifiers_by_partition)
|
173
162
|
end
|
174
163
|
else
|
175
164
|
delete_in_db do
|
@@ -195,29 +184,15 @@ module BulkDependencyEraser
|
|
195
184
|
end
|
196
185
|
else
|
197
186
|
puts "Deleting with batching" if opts_c.verbose
|
198
|
-
if
|
187
|
+
if deletable_partioned_tables_by_ctids
|
199
188
|
puts "Deleting via CTID and table partitions" if opts_c.verbose
|
200
|
-
|
189
|
+
deletable_partioned_tables_by_ctids.each do |table_partition|
|
201
190
|
identifiers_by_partition = additional_identifiers.filter { |id, identifiers| identifiers['tableoid::regclass'] == table_partition }
|
202
191
|
ids = identifiers_by_partition.keys
|
203
192
|
ids.each_slice(batch_size) do |ids_subset|
|
204
193
|
additional_identifiers_subset = identifiers_by_partition.slice(*ids_subset)
|
205
194
|
ctids = additional_identifiers_subset.values.pluck('ctid')
|
206
|
-
|
207
|
-
sql = <<~SQL
|
208
|
-
DELETE FROM #{table_partition}
|
209
|
-
WHERE ctid IN (#{ctids.map { |c| "'#{c}'" }.join(', ')});
|
210
|
-
SQL
|
211
|
-
|
212
|
-
# Due to the way we've mocked/aliased the partition table in this gem test, we need to also add the partition name as a where clause.
|
213
|
-
if ENV['TEST_GEM_ENV'] == 'bulk_dependency_eraser'
|
214
|
-
sql.sub!(/;\s*$/, "") # remove terminating semicolon
|
215
|
-
sql << " AND tableoid = '#{table_partition}';"
|
216
|
-
end
|
217
|
-
|
218
|
-
deleted_count = klass.connection.delete(sql)
|
219
|
-
[deleted_count, sql, ids_subset, additional_identifiers_subset]
|
220
|
-
end
|
195
|
+
deletion_by_partitioned_ctids(query, ids_subset, ctids, table_partition, identifiers_by_partition)
|
221
196
|
end
|
222
197
|
end
|
223
198
|
else
|
@@ -251,6 +226,29 @@ module BulkDependencyEraser
|
|
251
226
|
end
|
252
227
|
end
|
253
228
|
|
229
|
+
def deletion_by_partitioned_ctids query, ids, ctids, partition_table_name, additional_identifiers
|
230
|
+
delete_in_db do
|
231
|
+
where_clause_sql = <<~SQL
|
232
|
+
ctid IN (#{ctids.map { |c| "'#{c}'" }.join(', ')})
|
233
|
+
SQL
|
234
|
+
|
235
|
+
deletion_sql = <<~SQL
|
236
|
+
DELETE FROM #{partition_table_name}
|
237
|
+
WHERE #{where_clause_sql};
|
238
|
+
SQL
|
239
|
+
|
240
|
+
# Due to the way we've mocked/aliased the partition table in this gem test, we need to also add the partition name as a where clause.
|
241
|
+
if ENV['TEST_GEM_ENV'] == 'bulk_dependency_eraser'
|
242
|
+
deletion_sql.sub!(/;\s*$/, "") # remove terminating semicolon
|
243
|
+
deletion_sql << " AND tableoid = '#{partition_table_name}';"
|
244
|
+
end
|
245
|
+
|
246
|
+
deleted_count = query.klass.connection.delete(deletion_sql)
|
247
|
+
selector_query = query.where(Arel.sql(where_clause_sql))
|
248
|
+
[deleted_count, selector_query, ids, additional_identifiers]
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
254
252
|
def delete_in_db(&block)
|
255
253
|
puts "Deleting from DB..." if opts_c.verbose
|
256
254
|
opts_c.db_delete_wrapper.call(block)
|