bulk_dependency_eraser 1.1.0 → 1.2.0

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: dc49b9b507510ed728ba6434832c29c44d76fe144ee4b738a7f5ade224caf0d2
4
- data.tar.gz: 3437d5c44ca6ae2aaaf6d5e283da42d7267e5df2f378ef7abf7a72b63662cc5e
3
+ metadata.gz: 31e61c4af0756f5f3cb2f75ee9d3247e238fd83386fd8bdeace5bd60ebf17655
4
+ data.tar.gz: c3edbcc3cdfa4d56d398616780ba81ae254cf9224f9371fa60dbfbbc25b2b343
5
5
  SHA512:
6
- metadata.gz: 8f15ccf36462a1fa821843dd5b05144e078be9a624620b297c02b0bb9e4252b997c0db56ae7546962163559a4f141eeaa2c3be571e1edafb5faa41cb1c83c563
7
- data.tar.gz: 6a72116ef8842358a7de07f461cae3a3fbb2b6bfce2a0b725dd373534480a84fd69e81c18838178bea8d65788039671244c76df2d1669bc470687354929c130d
6
+ metadata.gz: '09c8931ca0720cf4a40639df42d1376745d32915167f2b78e43400280761249458e582bb872b8a4b5106d6c580ad82c88a26f2270a0227e457d045fe9490d388'
7
+ data.tar.gz: fa6224f8af00e73b0114666728547c4e64fdd2976c4026411d621ef411ffbc1bf484275e93076f8942d1ae99834600da794efa9590eab4827e1c55bcd1978912
@@ -13,7 +13,10 @@ module BulkDependencyEraser
13
13
  # Won't parse any table in this list
14
14
  ignore_tables_and_dependencies: [],
15
15
  ignore_klass_names_and_dependencies: [],
16
- batching_size_limit: 500,
16
+ # a general batching size
17
+ batch_size: 10_000,
18
+ # A specific batching size for this class, overrides the batch_size
19
+ read_batch_size: nil,
17
20
  }.freeze
18
21
 
19
22
  DEFAULT_DB_WRAPPER = ->(block) do
@@ -120,6 +123,10 @@ module BulkDependencyEraser
120
123
  attr_reader :table_names_to_parsed_klass_names
121
124
  attr_reader :ignore_table_name_and_dependencies, :ignore_klass_name_and_dependencies
122
125
 
126
+ def batch_size
127
+ opts_c.read_batch_size || opts_c.batch_size
128
+ end
129
+
123
130
  def deletion_query_parser query, association_parent = nil
124
131
  # necessary for "ActiveRecord::Reflection::ThroughReflection" use-case
125
132
  # force_through_destroy_chains = options[:force_destroy_chain] || {}
@@ -165,9 +172,12 @@ module BulkDependencyEraser
165
172
  return
166
173
  end
167
174
 
168
- # Pluck IDs of the current query
169
- query_ids = read_from_db do
170
- query.pluck(:id)
175
+ # Pluck IDs of the current query (batchified)
176
+ query_ids = []
177
+ query.in_batches(of: batch_size) do |batch|
178
+ read_from_db do
179
+ query_ids += batch.pluck(:id)
180
+ end
171
181
  end
172
182
 
173
183
  deletion_list[klass_name] ||= []
@@ -340,8 +350,11 @@ module BulkDependencyEraser
340
350
  # - handle primary key edge cases
341
351
  # - The associations might not be using the primary_key of the klass table, but we can support that here.
342
352
  if specified_primary_key && specified_primary_key&.to_s != 'id'
343
- alt_primary_ids = read_from_db do
344
- query.pluck(specified_primary_key)
353
+ alt_primary_ids = []
354
+ query.in_batches(of: batch_size) do |batch|
355
+ read_from_db do
356
+ alt_primary_ids += query.pluck(specified_primary_key)
357
+ end
345
358
  end
346
359
  assoc_query = assoc_query.where(specified_foreign_key.to_sym => alt_primary_ids)
347
360
  else
@@ -364,8 +377,11 @@ module BulkDependencyEraser
364
377
  elsif type == :nullify
365
378
  # No need for recursion here.
366
379
  # - we're not destroying these assocs (just nullifying foreign_key columns) so we don't need to parse their dependencies.
367
- assoc_ids = read_from_db do
368
- assoc_query.pluck(:id)
380
+ assoc_ids = []
381
+ assoc_query.in_batches(of: batch_size) do |batch|
382
+ read_from_db do
383
+ assoc_ids += batch.pluck(:id)
384
+ end
369
385
  end
370
386
 
371
387
  # No assoc_ids, no need to add it to the nullification list
@@ -409,7 +425,7 @@ module BulkDependencyEraser
409
425
  # assoc_query = assoc_klass.unscoped
410
426
  # query.in_batches
411
427
 
412
- assoc_klass.in_batches(of: opts_c.batching_size_limit) do |batch|
428
+ assoc_klass.in_batches(of: batch_size) do |batch|
413
429
  batch.each do |record|
414
430
  record.send(association_name)
415
431
  end
@@ -472,21 +488,23 @@ module BulkDependencyEraser
472
488
  return
473
489
  end
474
490
 
475
- assoc_query = read_from_db do
476
- assoc_query.where(
477
- specified_primary_key.to_sym => query.pluck(specified_foreign_key)
478
- )
479
- end
491
+ query.in_batches(of: batch_size) do |batch|
492
+ assoc_batch_query = read_from_db do
493
+ assoc_query.where(
494
+ specified_primary_key.to_sym => batch.pluck(specified_foreign_key)
495
+ )
496
+ end
480
497
 
481
- if type == :delete
482
- # Recursively call 'deletion_query_parser' on association query, to delete any if the assoc's dependencies
483
- deletion_query_parser(assoc_query, parent_class)
484
- elsif type == :restricted
485
- if traverse_restricted_dependency?(parent_class, reflection, assoc_query)
486
- deletion_query_parser(assoc_query, parent_class)
498
+ if type == :delete
499
+ # Recursively call 'deletion_query_parser' on association query, to delete any if the assoc's dependencies
500
+ deletion_query_parser(assoc_batch_query, parent_class)
501
+ elsif type == :restricted
502
+ if traverse_restricted_dependency?(parent_class, reflection, assoc_batch_query)
503
+ deletion_query_parser(assoc_batch_query, parent_class)
504
+ end
505
+ else
506
+ raise "invalid parsing type: #{type}"
487
507
  end
488
- else
489
- raise "invalid parsing type: #{type}"
490
508
  end
491
509
  end
492
510
 
@@ -538,28 +556,30 @@ module BulkDependencyEraser
538
556
  return
539
557
  end
540
558
 
541
- foreign_ids_by_type = read_from_db do
542
- query.pluck(specified_foreign_key, specified_foreign_type).each_with_object({}) do |(id, type), hash|
543
- hash.key?(type) ? hash[type] << id : hash[type] = [id]
559
+ query.in_batches(of: batch_size) do |batch|
560
+ foreign_ids_by_type = read_from_db do
561
+ batch.pluck(specified_foreign_key, specified_foreign_type).each_with_object({}) do |(id, type), hash|
562
+ hash.key?(type) ? hash[type] << id : hash[type] = [id]
563
+ end
544
564
  end
545
- end
546
565
 
547
- if type == :delete
548
- # Recursively call 'deletion_query_parser' on association query, to delete any if the assoc's dependencies
549
- foreign_ids_by_type.each do |type, ids|
550
- assoc_klass = type.constantize
551
- deletion_query_parser(assoc_klass.where(id: ids), assoc_klass)
552
- end
553
- elsif type == :restricted
554
- if traverse_restricted_dependency_for_belongs_to_poly?(parent_class, reflection, foreign_ids_by_type)
566
+ if type == :delete
555
567
  # Recursively call 'deletion_query_parser' on association query, to delete any if the assoc's dependencies
556
568
  foreign_ids_by_type.each do |type, ids|
557
569
  assoc_klass = type.constantize
558
570
  deletion_query_parser(assoc_klass.where(id: ids), assoc_klass)
559
571
  end
572
+ elsif type == :restricted
573
+ if traverse_restricted_dependency_for_belongs_to_poly?(parent_class, reflection, foreign_ids_by_type)
574
+ # Recursively call 'deletion_query_parser' on association query, to delete any if the assoc's dependencies
575
+ foreign_ids_by_type.each do |type, ids|
576
+ assoc_klass = type.constantize
577
+ deletion_query_parser(assoc_klass.where(id: ids), assoc_klass)
578
+ end
579
+ end
580
+ else
581
+ raise "invalid parsing type: #{type}"
560
582
  end
561
- else
562
- raise "invalid parsing type: #{type}"
563
583
  end
564
584
  end
565
585
 
@@ -4,7 +4,11 @@ module BulkDependencyEraser
4
4
  verbose: false,
5
5
  db_delete_wrapper: self::DEFAULT_DB_WRAPPER,
6
6
  # Set to true if you want 'ActiveRecord::InvalidForeignKey' errors raised during deletions
7
- enable_invalid_foreign_key_detection: false
7
+ enable_invalid_foreign_key_detection: false,
8
+ # a general batching size
9
+ batch_size: 300,
10
+ # A specific batching size for this class, overrides the batch_size
11
+ delete_batch_size: nil,
8
12
  }.freeze
9
13
 
10
14
  DEFAULT_DB_WRAPPER = ->(block) do
@@ -55,15 +59,21 @@ module BulkDependencyEraser
55
59
 
56
60
  protected
57
61
 
62
+ attr_reader :class_names_and_ids
63
+
64
+ def batch_size
65
+ opts_c.delete_batch_size || opts_c.batch_size
66
+ end
67
+
58
68
  def delete_by_klass_and_ids klass, ids
59
69
  puts "Deleting #{klass.name}'s IDs: #{ids}" if opts_c.verbose
60
- delete_in_db do
61
- klass.unscoped.where(id: ids).delete_all
70
+ ids.each_slice(batch_size) do |ids_subset|
71
+ delete_in_db do
72
+ klass.unscoped.where(id: ids_subset).delete_all
73
+ end
62
74
  end
63
75
  end
64
76
 
65
- attr_reader :class_names_and_ids
66
-
67
77
  def delete_in_db(&block)
68
78
  puts "Deleting from DB..." if opts_c.verbose
69
79
  opts_c.db_delete_wrapper.call(block)
@@ -6,7 +6,11 @@ module BulkDependencyEraser
6
6
  # Set to true if you want 'ActiveRecord::InvalidForeignKey' errors raised during nullifications
7
7
  # - I can't think of a use-case where a nullification would generate an invalid key error
8
8
  # - Not hurting anything to leave it in, but might remove it in the future.
9
- enable_invalid_foreign_key_detection: false
9
+ enable_invalid_foreign_key_detection: false,
10
+ # a general batching size
11
+ batch_size: 300,
12
+ # A specific batching size for this class, overrides the batch_size
13
+ nullify_batch_size: nil,
10
14
  }.freeze
11
15
 
12
16
  DEFAULT_DB_WRAPPER = ->(block) do
@@ -115,6 +119,10 @@ module BulkDependencyEraser
115
119
 
116
120
  attr_reader :class_names_columns_and_ids
117
121
 
122
+ def batch_size
123
+ opts_c.nullify_batch_size || opts_c.batch_size
124
+ end
125
+
118
126
  def nullify_by_klass_column_and_ids klass, columns, ids
119
127
  nullify_columns = {}
120
128
 
@@ -127,8 +135,10 @@ module BulkDependencyEraser
127
135
  nullify_columns[columns] = nil
128
136
  end
129
137
 
130
- nullify_in_db do
131
- klass.unscoped.where(id: ids).update_all(nullify_columns)
138
+ ids.each_slice(batch_size) do |ids_subset|
139
+ nullify_in_db do
140
+ klass.unscoped.where(id: ids_subset).update_all(nullify_columns)
141
+ end
132
142
  end
133
143
  end
134
144
 
@@ -1,3 +1,3 @@
1
1
  module BulkDependencyEraser
2
- VERSION = "1.1.0".freeze
2
+ VERSION = "1.2.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bulk_dependency_eraser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - benjamin.dana.software.dev@gmail.com