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