bulk_dependency_eraser 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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