active_record_sql_exporter 0.2.8 → 0.2.9
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/active_record/sql_exporter.rb +75 -66
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1c44c585e477da643c57579a3ef10570114c0ff4
|
|
4
|
+
data.tar.gz: fdbba556edb6b9f70379c4713282e5bae63eb122
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c782f7eb0a7173f0a3927f922d9dc2f250278698640ef1f3fcbcf3abe24e03008c7d28f82ed477fee133007cc5f4e4cdfbb50c730fe9f3bc7efdef6b4a690718
|
|
7
|
+
data.tar.gz: 3b41f151a4084d599b9801ec24961e46c139b988024618b838443f55d4f1848fff28cff681063963a62c4580fb2c88ed93d259e84b41f38c9df0f6cf13b8621a
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
module ActiveRecord::SqlExporter
|
|
3
3
|
class NestedException < ArgumentError
|
|
4
4
|
attr_accessor :old_exception, :klass
|
|
5
|
-
def initialize(
|
|
5
|
+
def initialize(old_exception, klass, key)
|
|
6
6
|
@old_exception = old_exception
|
|
7
7
|
@klass = klass
|
|
8
8
|
@key = key
|
|
@@ -14,29 +14,35 @@ module ActiveRecord::SqlExporter
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
# ------------------------------------------------------------------ included?
|
|
17
|
-
def included?(
|
|
18
|
-
klass.include(
|
|
19
|
-
klass.extend(
|
|
17
|
+
def included?(klass)
|
|
18
|
+
klass.include(InstanceMethods)
|
|
19
|
+
klass.extend(ClassMethods)
|
|
20
|
+
return if klass.respond_to?(:quote_value)
|
|
21
|
+
class_eval <<-EOC
|
|
22
|
+
def self.quote_value(*args)
|
|
23
|
+
connection.quote_value(*args)
|
|
24
|
+
end
|
|
25
|
+
EOC
|
|
20
26
|
end
|
|
21
27
|
##############################################################################
|
|
22
28
|
# FileWriter
|
|
23
29
|
##############################################################################
|
|
24
30
|
class FileWriter
|
|
25
31
|
# --------------------------------------------------------------- initialize
|
|
26
|
-
def initialize(
|
|
32
|
+
def initialize(file)
|
|
27
33
|
@file = file
|
|
28
34
|
end
|
|
29
35
|
# ------------------------------------------------------------------------ +
|
|
30
|
-
def +(
|
|
31
|
-
@file.write(
|
|
36
|
+
def +(s)
|
|
37
|
+
@file.write(s)
|
|
32
38
|
return self
|
|
33
39
|
end
|
|
34
40
|
end
|
|
35
41
|
|
|
36
42
|
module ClassMethods
|
|
37
43
|
# ---------------------------------------------------------- build_check_sql
|
|
38
|
-
def build_check_sql(
|
|
39
|
-
"IF( NOT EXISTS( SELECT * FROM #{quoted_table_name} WHERE #{connection.quote_column_name(primary_key)} = #{quote_value(id, columns_hash[primary_key])}
|
|
44
|
+
def build_check_sql(id)
|
|
45
|
+
"IF( NOT EXISTS( SELECT * FROM #{quoted_table_name} WHERE #{connection.quote_column_name(primary_key)} = #{quote_value(id, columns_hash[primary_key])}) THEN ROLLBACK; END IF;\n"
|
|
40
46
|
end
|
|
41
47
|
end
|
|
42
48
|
|
|
@@ -44,17 +50,17 @@ module ActiveRecord::SqlExporter
|
|
|
44
50
|
CREATION_NODE = 1
|
|
45
51
|
EXISTENCE_CHECK_NODE = 2
|
|
46
52
|
UPDATE_NODE = 3
|
|
47
|
-
# --------------------- pretend_to_sql(
|
|
48
|
-
def print_relation_tree(
|
|
53
|
+
# --------------------- pretend_to_sql(args = {}, classes_to_ignore = [])
|
|
54
|
+
def print_relation_tree(args = {}, classes_to_ignore = [])
|
|
49
55
|
tree = {}
|
|
50
|
-
_print_relation(
|
|
51
|
-
return if classes_to_ignore.include?(
|
|
56
|
+
_print_relation(tree, classes_to_ignore)
|
|
57
|
+
return if classes_to_ignore.include?(self.class)
|
|
52
58
|
end
|
|
53
59
|
# ------------------------------------------------------------------- to_sql
|
|
54
|
-
def to_backup_sql(
|
|
60
|
+
def to_backup_sql(args = {}, classes_to_ignore = [])
|
|
55
61
|
tree = {}
|
|
56
|
-
build_export_tree(
|
|
57
|
-
sql = args[:file] ? ActiveRecord::SqlExporter::FileWriter.new(
|
|
62
|
+
build_export_tree(tree, classes_to_ignore)
|
|
63
|
+
sql = args[:file] ? ActiveRecord::SqlExporter::FileWriter.new(args[:file]) : ''
|
|
58
64
|
unless args[:no_transaction]
|
|
59
65
|
sql += "BEGIN;"
|
|
60
66
|
end
|
|
@@ -63,16 +69,16 @@ module ActiveRecord::SqlExporter
|
|
|
63
69
|
node = tree[klass][id]
|
|
64
70
|
begin
|
|
65
71
|
if node[:type] == EXISTENCE_CHECK_NODE
|
|
66
|
-
sql += klass.constantize.build_check_sql(
|
|
72
|
+
sql += klass.constantize.build_check_sql(id)
|
|
67
73
|
elsif node[:type] == CREATION_NODE
|
|
68
74
|
if id
|
|
69
|
-
object = klass.constantize.find(
|
|
75
|
+
object = klass.constantize.find(id)
|
|
70
76
|
sql += object.sql_restore_string
|
|
71
77
|
end
|
|
72
78
|
elsif node[:type] == UPDATE_NODE
|
|
73
79
|
if id
|
|
74
|
-
object = klass.constantize.find(
|
|
75
|
-
sql += object.update_sql_string(
|
|
80
|
+
object = klass.constantize.find(id)
|
|
81
|
+
sql += object.update_sql_string(node[:key])
|
|
76
82
|
end
|
|
77
83
|
end
|
|
78
84
|
rescue Encoding::UndefinedConversionError
|
|
@@ -83,17 +89,20 @@ module ActiveRecord::SqlExporter
|
|
|
83
89
|
sql += "COMMIT;" unless args[:no_transaction]
|
|
84
90
|
return sql
|
|
85
91
|
end
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
##############################################################################
|
|
93
|
+
|
|
94
|
+
protected
|
|
95
|
+
|
|
96
|
+
##############################################################################
|
|
89
97
|
# -------------------------------------------------------- update_sql_string
|
|
90
|
-
def update_sql_string(
|
|
98
|
+
def update_sql_string(key_name)
|
|
91
99
|
data = []
|
|
92
100
|
self.class.columns.map do |x|
|
|
93
101
|
next if is_primary_key_field?(x)
|
|
94
|
-
data << "#{self.class.connection.quote_column_name(
|
|
102
|
+
data << "#{self.class.connection.quote_column_name(x.name)}=#{self.class.connection.quote(read_attribute(x.name))}"
|
|
95
103
|
end
|
|
96
|
-
|
|
104
|
+
quoted_id = self.class.quote_value(id, self.class.columns_hash[self.class.primary_key])
|
|
105
|
+
"UPDATE #{self.class.quoted_table_name} SET #{data.join(',')} WHERE #{self.class.connection.quote_column_name(self.class.primary_key)} = #{quoted_id};\n"
|
|
97
106
|
end
|
|
98
107
|
|
|
99
108
|
def is_primary_key_field?(col)
|
|
@@ -101,12 +110,12 @@ module ActiveRecord::SqlExporter
|
|
|
101
110
|
end
|
|
102
111
|
|
|
103
112
|
# ------------------------------------------------------- sql_restore_string
|
|
104
|
-
def sql_restore_string(
|
|
113
|
+
def sql_restore_string(args = {})
|
|
105
114
|
columns = self.class.columns.map do |x|
|
|
106
|
-
self.class.connection.quote_column_name(
|
|
115
|
+
self.class.connection.quote_column_name(x.name)
|
|
107
116
|
end
|
|
108
117
|
values = self.class.columns.map do |x|
|
|
109
|
-
self.class.connection.quote(
|
|
118
|
+
self.class.connection.quote(read_attribute(x.name))
|
|
110
119
|
end
|
|
111
120
|
|
|
112
121
|
sql = "\nINSERT INTO #{self.class.quoted_table_name} (#{columns.join(',')}) VALUES (#{values.join(',')})"
|
|
@@ -121,16 +130,16 @@ module ActiveRecord::SqlExporter
|
|
|
121
130
|
return sql
|
|
122
131
|
end
|
|
123
132
|
# -------------------------------------------------------- build_export_tree
|
|
124
|
-
def build_export_tree(
|
|
125
|
-
return if classes_to_ignore.include?(
|
|
126
|
-
if tree[self.class.name].nil? || (
|
|
127
|
-
self.add_to_tree(
|
|
128
|
-
expand_tree_with_relations(
|
|
133
|
+
def build_export_tree(tree = {}, classes_to_ignore = [])
|
|
134
|
+
return if classes_to_ignore.include?(self.class)
|
|
135
|
+
if tree[self.class.name].nil? || (tree[self.class.name] && (tree[self.class.name][id].nil? || tree[self.class.name][id][:type] == EXISTENCE_CHECK_NODE))
|
|
136
|
+
self.add_to_tree(tree, CREATION_NODE)
|
|
137
|
+
expand_tree_with_relations(tree, self.class.reflections, classes_to_ignore)
|
|
129
138
|
end
|
|
130
139
|
return tree
|
|
131
140
|
end
|
|
132
141
|
# ------------------------------------------------------------- add_to_tree
|
|
133
|
-
def add_to_tree(
|
|
142
|
+
def add_to_tree(tree, type, options = {})
|
|
134
143
|
tree[self.class.name] ||= {}
|
|
135
144
|
node = tree[self.class.name][self.id]
|
|
136
145
|
if node.nil? || node[:type] == EXISTENCE_CHECK_NODE
|
|
@@ -141,17 +150,17 @@ module ActiveRecord::SqlExporter
|
|
|
141
150
|
end
|
|
142
151
|
# ---------------------------------------------------------- build_check_sql
|
|
143
152
|
def build_check_sql
|
|
144
|
-
"IF( NOT EXISTS( SELECT * FROM #{self.class.quoted_table_name} WHERE #{self.class.connection.quote_column_name(self.class.primary_key)} = #{quote_value(id)}
|
|
153
|
+
"IF( NOT EXISTS( SELECT * FROM #{self.class.quoted_table_name} WHERE #{self.class.connection.quote_column_name(self.class.primary_key)} = #{quote_value(id)}) THEN ROLLBACK; END IF;\n"
|
|
145
154
|
end
|
|
146
155
|
# ---------------------------------------- convert_has_many_relations_to_sql
|
|
147
|
-
def expand_tree_with_relations(
|
|
156
|
+
def expand_tree_with_relations(tree, reflections, classes_to_ignore)
|
|
148
157
|
reflections.each_pair do |key, value|
|
|
149
|
-
next if value.options[:dependent] && ![:destroy, :nullify].include?(
|
|
158
|
+
next if value.options[:dependent] && ![:destroy, :nullify].include?(value.options[:dependent])
|
|
150
159
|
if value.options[:polymorphic]
|
|
151
|
-
next if classes_to_ignore.include?(
|
|
160
|
+
next if classes_to_ignore.include?(send(key).class)
|
|
152
161
|
else
|
|
153
162
|
begin
|
|
154
|
-
next if classes_to_ignore.include?(
|
|
163
|
+
next if classes_to_ignore.include?(value.klass)
|
|
155
164
|
rescue
|
|
156
165
|
raise "Problem in a #{self.class.name} with #{key} = #{value}"
|
|
157
166
|
end
|
|
@@ -159,33 +168,33 @@ module ActiveRecord::SqlExporter
|
|
|
159
168
|
case value.macro
|
|
160
169
|
when :has_one
|
|
161
170
|
begin
|
|
162
|
-
singleton_method(
|
|
163
|
-
e.build_export_tree(
|
|
171
|
+
singleton_method(key) do |e|
|
|
172
|
+
e.build_export_tree(tree, classes_to_ignore)
|
|
164
173
|
end
|
|
165
174
|
rescue NestedException => ex
|
|
166
|
-
raise NestedException.new(
|
|
175
|
+
raise NestedException.new(ex.old_exception, "#{self.class.name}.#{ex.klass}", key)
|
|
167
176
|
rescue Exception => ex
|
|
168
|
-
raise NestedException.new(
|
|
177
|
+
raise NestedException.new(ex, self.class.name, key)
|
|
169
178
|
end
|
|
170
179
|
when :has_many, :has_and_belongs_to_many
|
|
171
180
|
begin
|
|
172
|
-
records = send(
|
|
181
|
+
records = send(key)
|
|
173
182
|
if value.options[:dependent] == :nullify
|
|
174
183
|
records.each do |record|
|
|
175
|
-
record.add_to_tree(
|
|
184
|
+
record.add_to_tree(tree, UPDATE_NODE, key: value.association_primary_key)
|
|
176
185
|
end
|
|
177
186
|
else
|
|
178
|
-
records.each{ |x| x.build_export_tree(
|
|
187
|
+
records.each{ |x| x.build_export_tree(tree, classes_to_ignore) }
|
|
179
188
|
end
|
|
180
189
|
rescue NestedException => ex
|
|
181
|
-
raise NestedException.new(
|
|
190
|
+
raise NestedException.new(ex.old_exception, "#{self.class.name}.#{ex.klass}", key)
|
|
182
191
|
rescue Exception => ex
|
|
183
192
|
raise ex
|
|
184
|
-
raise NestedException.new(
|
|
193
|
+
raise NestedException.new(ex, self.class.name, key)
|
|
185
194
|
end
|
|
186
195
|
when :belongs_to
|
|
187
|
-
singleton_method(
|
|
188
|
-
e.add_to_tree(
|
|
196
|
+
singleton_method(key) do |e|
|
|
197
|
+
e.add_to_tree(tree, EXISTENCE_CHECK_NODE)
|
|
189
198
|
end
|
|
190
199
|
else
|
|
191
200
|
raise "Unhandled reflection: #{value.macro}"
|
|
@@ -194,41 +203,41 @@ module ActiveRecord::SqlExporter
|
|
|
194
203
|
return tree
|
|
195
204
|
end
|
|
196
205
|
# ----------------------------------------------------------- print_relation
|
|
197
|
-
def _print_relation(
|
|
198
|
-
if tree[self.class.name].nil? || (
|
|
206
|
+
def _print_relation(tree, classes_to_ignore, indent_depth = 0)
|
|
207
|
+
if tree[self.class.name].nil? || (tree[self.class.name] && (tree[self.class.name][id].nil? || tree[self.class.name][id][:type] == EXISTENCE_CHECK_NODE))
|
|
199
208
|
puts "%s%s - %d" % ["\t" * indent_depth, self.class.name, self.id]
|
|
200
|
-
self.add_to_tree(
|
|
201
|
-
_print_reflection_relations(
|
|
209
|
+
self.add_to_tree(tree, CREATION_NODE)
|
|
210
|
+
_print_reflection_relations(tree, self.class.reflections, classes_to_ignore, indent_depth + 1)
|
|
202
211
|
end
|
|
203
212
|
end
|
|
204
213
|
# ---------------------------------------- convert_has_many_relations_to_sql
|
|
205
|
-
def _print_reflection_relations(
|
|
214
|
+
def _print_reflection_relations(tree, reflections, classes_to_ignore, indent_level = 1)
|
|
206
215
|
reflections.each_pair do |key, value|
|
|
207
|
-
next if value.options[:dependent] && ![:destroy, :nullify].include?(
|
|
216
|
+
next if value.options[:dependent] && ![:destroy, :nullify].include?(value.options[:dependent])
|
|
208
217
|
if value.options[:polymorphic]
|
|
209
|
-
next if classes_to_ignore.include?(
|
|
218
|
+
next if classes_to_ignore.include?(send(key).class)
|
|
210
219
|
else
|
|
211
220
|
begin
|
|
212
|
-
next if classes_to_ignore.include?(
|
|
221
|
+
next if classes_to_ignore.include?(value.klass)
|
|
213
222
|
rescue
|
|
214
223
|
raise "Problem in a #{self.class.name} with #{key} = #{value}"
|
|
215
224
|
end
|
|
216
225
|
end
|
|
217
226
|
case value.macro
|
|
218
227
|
when :has_one
|
|
219
|
-
singleton_method(
|
|
220
|
-
e._print_relation(
|
|
228
|
+
singleton_method(key) do |e|
|
|
229
|
+
e._print_relation(tree, classes_to_ignore, indent_level)
|
|
221
230
|
end
|
|
222
231
|
when :has_many, :has_and_belongs_to_many
|
|
223
|
-
records = send(
|
|
232
|
+
records = send(key)
|
|
224
233
|
if value.options[:dependent] == :nullify
|
|
225
234
|
records.each do |record|
|
|
226
|
-
record.add_to_tree(
|
|
235
|
+
record.add_to_tree(tree, UPDATE_NODE, key: value.primary_key_name)
|
|
227
236
|
puts "%s%s [UPDATE] - %d" % ["\t" * indent_level, record.class.name, record.id]
|
|
228
237
|
end
|
|
229
238
|
else
|
|
230
239
|
records.each do |x|
|
|
231
|
-
x._print_relation(
|
|
240
|
+
x._print_relation(tree, classes_to_ignore, indent_level)
|
|
232
241
|
end
|
|
233
242
|
end
|
|
234
243
|
when :belongs_to
|
|
@@ -238,8 +247,8 @@ module ActiveRecord::SqlExporter
|
|
|
238
247
|
end
|
|
239
248
|
end
|
|
240
249
|
# --------------------------------------------------------- singleton_method
|
|
241
|
-
def singleton_method(
|
|
242
|
-
if v = self.send(
|
|
250
|
+
def singleton_method(key)
|
|
251
|
+
if v = self.send(key)
|
|
243
252
|
yield v
|
|
244
253
|
end
|
|
245
254
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_record_sql_exporter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adam Palmblad
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2018-01-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|