bulk_dependency_eraser 2.2.0 → 3.0.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 +4 -4
- data/lib/bulk_dependency_eraser/base.rb +2 -0
- data/lib/bulk_dependency_eraser/builder.rb +41 -25
- data/lib/bulk_dependency_eraser/deleter.rb +24 -15
- data/lib/bulk_dependency_eraser/errors/base_error.rb +5 -0
- data/lib/bulk_dependency_eraser/errors/builder_error.rb +13 -0
- data/lib/bulk_dependency_eraser/errors/deleter_error.rb +13 -0
- data/lib/bulk_dependency_eraser/errors/nullifier_error.rb +14 -0
- data/lib/bulk_dependency_eraser/nullifier.rb +16 -2
- data/lib/bulk_dependency_eraser/version.rb +1 -1
- data/lib/bulk_dependency_eraser.rb +5 -1
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 954e4ce7b9c7d42a0cdcdc1403592dce3e61c6c196e72858a5c2f66f5be3e3df
|
4
|
+
data.tar.gz: 18233fefb36153a49d43d4aed40e3f44ca0f3123d346429a0a0b50a355577a16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e57be3e7ab4203123f919530710dd4f63842abbf588b49896fa78b2cb3fcf0c58d7e64e2881b165396cb919a897acfe3279d2c3d740a3c8f0ace8dfd923eb3c0
|
7
|
+
data.tar.gz: 3b05c7edc262d1cf0b663d451084698b52f2e11fb8ec03a057ac70551f630d35ad67530921f24535288adf1761377981e69803bb7519e8f4449977dab8ec56ca
|
@@ -123,6 +123,8 @@ module BulkDependencyEraser
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
+
# We're supporting custom query scopes on by klass name.
|
127
|
+
# - apply them here
|
126
128
|
def custom_scope_for_query(query)
|
127
129
|
klass = query.klass
|
128
130
|
if opts_c.proc_scopes_per_class_name.key?(klass.name)
|
@@ -1,8 +1,22 @@
|
|
1
1
|
module BulkDependencyEraser
|
2
2
|
class Builder < Base
|
3
|
+
DEFAULT_DB_BUILD_ALL_WRAPPER = ->(builder, block) do
|
4
|
+
begin
|
5
|
+
block.call
|
6
|
+
rescue StandardError => e
|
7
|
+
builder.report_error(
|
8
|
+
<<~STRING.strip
|
9
|
+
Issue attempting to build deletion query for '#{e.building_klass_name}'
|
10
|
+
=> #{e.original_error_klass.name}: #{e.message}
|
11
|
+
STRING
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
3
16
|
DEFAULT_OPTS = {
|
4
17
|
force_destroy_restricted: false,
|
5
18
|
verbose: false,
|
19
|
+
db_build_all_wrapper: self::DEFAULT_DB_BUILD_ALL_WRAPPER,
|
6
20
|
# Some associations scopes take parameters.
|
7
21
|
# - We would have to instantiate if we wanted to apply that scope filter.
|
8
22
|
instantiate_if_assoc_scope_with_arity: false,
|
@@ -38,6 +52,7 @@ module BulkDependencyEraser
|
|
38
52
|
attr_accessor :deletion_list, :nullification_list
|
39
53
|
attr_reader :ignore_table_deletion_list, :ignore_table_nullification_list
|
40
54
|
attr_reader :query_schema_parser
|
55
|
+
attr_reader :current_klass_name
|
41
56
|
|
42
57
|
delegate :circular_dependency_klasses, :flat_dependencies_per_klass, to: :query_schema_parser
|
43
58
|
|
@@ -57,6 +72,8 @@ module BulkDependencyEraser
|
|
57
72
|
@ignore_table_name_and_dependencies = opts_c.ignore_tables_and_dependencies.collect { |table_name| table_name }
|
58
73
|
@ignore_klass_name_and_dependencies = opts_c.ignore_klass_names_and_dependencies.collect { |klass_name| klass_name }
|
59
74
|
@query_schema_parser = BulkDependencyEraser::QuerySchemaParser.new(query:, opts:)
|
75
|
+
# Moving pointer, points to the current class that is being queries
|
76
|
+
@current_klass_name = query.is_a?(ActiveRecord::Relation) ? query.klass.name : query.name
|
60
77
|
end
|
61
78
|
|
62
79
|
def execute
|
@@ -82,33 +99,20 @@ module BulkDependencyEraser
|
|
82
99
|
end
|
83
100
|
|
84
101
|
def build
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
102
|
+
build_all_in_db do
|
103
|
+
begin
|
104
|
+
if opts_c.verbose
|
105
|
+
puts "Starting build for #{@query.is_a?(ActiveRecord::Relation) ? @query.klass.name : @query.name}"
|
106
|
+
end
|
89
107
|
|
90
|
-
|
108
|
+
deletion_query_parser(@query)
|
91
109
|
|
92
|
-
|
110
|
+
uniqify_errors!
|
93
111
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
klass = @query.klass
|
98
|
-
else
|
99
|
-
# current_query is a normal rails class
|
100
|
-
klass = @query
|
112
|
+
return errors.none?
|
113
|
+
rescue StandardError => e
|
114
|
+
raise BulkDependencyEraser::Errors::BuilderError.new(e.class, e.message, building_klass_name: current_klass_name)
|
101
115
|
end
|
102
|
-
report_error(
|
103
|
-
"
|
104
|
-
Error Encountered in 'execute' for '#{klass.name}':
|
105
|
-
#{e.class.name}
|
106
|
-
#{e.message}
|
107
|
-
"
|
108
|
-
)
|
109
|
-
raise e
|
110
|
-
|
111
|
-
return false
|
112
116
|
end
|
113
117
|
end
|
114
118
|
|
@@ -127,7 +131,8 @@ module BulkDependencyEraser
|
|
127
131
|
end
|
128
132
|
end
|
129
133
|
|
130
|
-
def pluck_from_query
|
134
|
+
def pluck_from_query(query, column = :id)
|
135
|
+
set_current_klass_name(query)
|
131
136
|
# ordering shouldn't matter in these queries, and would slow it down
|
132
137
|
# - we're ignoring default_scope ordering, but assoc-defined ordering would still take effect
|
133
138
|
query = query.reorder('')
|
@@ -293,6 +298,7 @@ module BulkDependencyEraser
|
|
293
298
|
is_polymorphic = reflection.options[:polymorphic]
|
294
299
|
unless is_polymorphic
|
295
300
|
klass = reflection.klass
|
301
|
+
set_current_klass_name(reflection.klass)
|
296
302
|
|
297
303
|
if ignore_table_name_and_dependencies.include?(klass.table_name)
|
298
304
|
# Not parsing, table and dependencies ignorable
|
@@ -445,7 +451,6 @@ module BulkDependencyEraser
|
|
445
451
|
assoc_klass = reflection.klass
|
446
452
|
assoc_klass_name = assoc_klass.name
|
447
453
|
|
448
|
-
|
449
454
|
# specified_primary_key = reflection.options[:primary_key]&.to_s
|
450
455
|
# specified_foreign_key = reflection.options[:foreign_key]&.to_s
|
451
456
|
|
@@ -739,5 +744,16 @@ module BulkDependencyEraser
|
|
739
744
|
|
740
745
|
return klass_index
|
741
746
|
end
|
747
|
+
|
748
|
+
def build_all_in_db(&block)
|
749
|
+
puts "Building all from DB..." if opts_c.verbose
|
750
|
+
opts_c.db_build_all_wrapper.call(self, block)
|
751
|
+
puts "Building all from DB complete." if opts_c.verbose
|
752
|
+
end
|
753
|
+
|
754
|
+
def set_current_klass_name(query_or_klass)
|
755
|
+
klass = query_or_klass.is_a?(ActiveRecord::Relation) ? query_or_klass.klass : query_or_klass
|
756
|
+
@current_klass_name = klass.name
|
757
|
+
end
|
742
758
|
end
|
743
759
|
end
|
@@ -3,8 +3,13 @@ module BulkDependencyEraser
|
|
3
3
|
DEFAULT_DB_DELETE_ALL_WRAPPER = ->(deleter, block) do
|
4
4
|
begin
|
5
5
|
block.call
|
6
|
-
rescue
|
7
|
-
report_error(
|
6
|
+
rescue BulkDependencyEraser::Errors::DeleterError => e
|
7
|
+
deleter.report_error(
|
8
|
+
<<~STRING.strip
|
9
|
+
Issue attempting to delete klass '#{e.deleting_klass_name}'
|
10
|
+
=> #{e.original_error_klass.name}: #{e.message}
|
11
|
+
STRING
|
12
|
+
)
|
8
13
|
end
|
9
14
|
end
|
10
15
|
|
@@ -60,23 +65,27 @@ module BulkDependencyEraser
|
|
60
65
|
|
61
66
|
current_class_name = 'N/A'
|
62
67
|
delete_all_in_db do
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
68
|
+
begin
|
69
|
+
class_names_and_ids.keys.reverse.each do |class_name|
|
70
|
+
current_class_name = class_name
|
71
|
+
ids = class_names_and_ids[class_name].reverse
|
72
|
+
klass = constantize(class_name)
|
67
73
|
|
68
|
-
|
69
|
-
|
70
|
-
delete_by_klass_and_ids(klass, ids)
|
71
|
-
else
|
72
|
-
# delete without referential integrity
|
73
|
-
# Disable any ActiveRecord::InvalidForeignKey raised errors.
|
74
|
-
# - src: https://stackoverflow.com/questions/41005849/rails-migrations-temporarily-ignore-foreign-key-constraint
|
75
|
-
# https://apidock.com/rails/ActiveRecord/ConnectionAdapters/AbstractAdapter/disable_referential_integrity
|
76
|
-
ActiveRecord::Base.connection.disable_referential_integrity do
|
74
|
+
if opts_c.enable_invalid_foreign_key_detection
|
75
|
+
# delete with referential integrity
|
77
76
|
delete_by_klass_and_ids(klass, ids)
|
77
|
+
else
|
78
|
+
# delete without referential integrity
|
79
|
+
# Disable any ActiveRecord::InvalidForeignKey raised errors.
|
80
|
+
# - src: https://stackoverflow.com/questions/41005849/rails-migrations-temporarily-ignore-foreign-key-constraint
|
81
|
+
# https://apidock.com/rails/ActiveRecord/ConnectionAdapters/AbstractAdapter/disable_referential_integrity
|
82
|
+
ActiveRecord::Base.connection.disable_referential_integrity do
|
83
|
+
delete_by_klass_and_ids(klass, ids)
|
84
|
+
end
|
78
85
|
end
|
79
86
|
end
|
87
|
+
rescue StandardError => e
|
88
|
+
raise BulkDependencyEraser::Errors::DeleterError.new(e.class, e.message, deleting_klass_name: current_class_name)
|
80
89
|
end
|
81
90
|
end
|
82
91
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module BulkDependencyEraser
|
2
|
+
module Errors
|
3
|
+
class BuilderError < BaseError
|
4
|
+
attr_reader :original_error_klass, :building_klass_name
|
5
|
+
|
6
|
+
def initialize(original_error_klass, message, building_klass_name:)
|
7
|
+
@original_error_klass = original_error_klass
|
8
|
+
@building_klass_name = building_klass_name
|
9
|
+
super(message)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module BulkDependencyEraser
|
2
|
+
module Errors
|
3
|
+
class DeleterError < BaseError
|
4
|
+
attr_reader :original_error_klass, :deleting_klass_name
|
5
|
+
|
6
|
+
def initialize(original_error_klass, message, deleting_klass_name:)
|
7
|
+
@original_error_klass = original_error_klass
|
8
|
+
@deleting_klass_name = deleting_klass_name
|
9
|
+
super(message)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module BulkDependencyEraser
|
2
|
+
module Errors
|
3
|
+
class NullifierError < BaseError
|
4
|
+
attr_reader :original_error_klass, :nullifying_klass_name, :nullifying_columns
|
5
|
+
|
6
|
+
def initialize(original_error_klass, message, nullifying_klass_name:, nullifying_columns:)
|
7
|
+
@original_error_klass = original_error_klass
|
8
|
+
@nullifying_klass_name = nullifying_klass_name
|
9
|
+
@nullifying_columns = nullifying_columns
|
10
|
+
super(message)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -3,8 +3,13 @@ module BulkDependencyEraser
|
|
3
3
|
DEFAULT_DB_NULLIFY_ALL_WRAPPER = ->(nullifier, block) do
|
4
4
|
begin
|
5
5
|
block.call
|
6
|
-
rescue
|
7
|
-
nullifier.report_error(
|
6
|
+
rescue BulkDependencyEraser::Errors::NullifierError => e
|
7
|
+
nullifier.report_error(
|
8
|
+
<<~STRING.strip
|
9
|
+
Issue attempting to nullify klass '#{e.nullifying_klass_name}' on column(s) '#{e.nullifying_columns}'
|
10
|
+
=> #{e.original_error_klass.name}: #{e.message}
|
11
|
+
STRING
|
12
|
+
)
|
8
13
|
end
|
9
14
|
end
|
10
15
|
|
@@ -114,6 +119,7 @@ module BulkDependencyEraser
|
|
114
119
|
current_class_name = 'N/A'
|
115
120
|
current_column = 'N/A'
|
116
121
|
nullify_all_in_db do
|
122
|
+
begin
|
117
123
|
# column_and_ids should have already been reversed in builder
|
118
124
|
class_names_columns_and_ids.keys.reverse.each do |class_name|
|
119
125
|
current_class_name = class_name
|
@@ -139,6 +145,14 @@ module BulkDependencyEraser
|
|
139
145
|
end
|
140
146
|
end
|
141
147
|
end
|
148
|
+
rescue StandardError => e
|
149
|
+
raise BulkDependencyEraser::Errors::NullifierError.new(
|
150
|
+
e.class,
|
151
|
+
e.message,
|
152
|
+
nullifying_klass_name: current_class_name,
|
153
|
+
nullifying_columns: current_column.to_s # could be an array, string, or symbol
|
154
|
+
)
|
155
|
+
end
|
142
156
|
end
|
143
157
|
|
144
158
|
return errors.none?
|
@@ -6,4 +6,8 @@ require_relative 'bulk_dependency_eraser/nullifier'
|
|
6
6
|
require_relative 'bulk_dependency_eraser/query_schema_parser'
|
7
7
|
require_relative 'bulk_dependency_eraser/manager'
|
8
8
|
require_relative 'bulk_dependency_eraser/utils'
|
9
|
-
require_relative 'bulk_dependency_eraser/version'
|
9
|
+
require_relative 'bulk_dependency_eraser/version'
|
10
|
+
require_relative 'bulk_dependency_eraser/errors/base_error'
|
11
|
+
require_relative 'bulk_dependency_eraser/errors/builder_error'
|
12
|
+
require_relative 'bulk_dependency_eraser/errors/deleter_error'
|
13
|
+
require_relative 'bulk_dependency_eraser/errors/nullifier_error'
|
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:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- benjamin.dana.software.dev@gmail.com
|
@@ -146,6 +146,10 @@ files:
|
|
146
146
|
- lib/bulk_dependency_eraser/base.rb
|
147
147
|
- lib/bulk_dependency_eraser/builder.rb
|
148
148
|
- lib/bulk_dependency_eraser/deleter.rb
|
149
|
+
- lib/bulk_dependency_eraser/errors/base_error.rb
|
150
|
+
- lib/bulk_dependency_eraser/errors/builder_error.rb
|
151
|
+
- lib/bulk_dependency_eraser/errors/deleter_error.rb
|
152
|
+
- lib/bulk_dependency_eraser/errors/nullifier_error.rb
|
149
153
|
- lib/bulk_dependency_eraser/full_schema_parser.rb
|
150
154
|
- lib/bulk_dependency_eraser/manager.rb
|
151
155
|
- lib/bulk_dependency_eraser/nullifier.rb
|