forklift_etl 1.1.3 → 1.1.4
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 +8 -8
- data/lib/forklift/transports/mysql.rb +29 -5
- data/lib/forklift/version.rb +1 -1
- data/spec/integration/mysql_spec.rb +54 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MTFiNTAwY2RlOGQxOTUzY2Y3N2RiNTg3Njg2ZDJiZDE3NTY3MGNmZg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZmQ2NTQwZjEyZGFhMzY5MmRjMzQyNzVkZTIxYTM4YzNmM2FmZTFiOA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTU5YzAyZDQ5NmI3YTVkMGZmZmY3Yjc0MTc0NjBhZDQzODkwMDI0NDhjMDdi
|
10
|
+
YWM1ODkwNGI4NWVkZjA2MTlhOTkzNmE0MDY2MTFjMDk0ZDJhNWYyMTI3MzM3
|
11
|
+
MmZjMjVkNTM5YTdmYzY1NTU3ZDkxZDE5MGIzN2M3ZjNmYWU4OWY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MTI5YzU5YWQ4MjEyNmFhZDE1NTMyYjlkOTE2ZTUzODNhMzhmODQ5OTQyNGNm
|
14
|
+
OGJiZjJkZTgyNTc2ZGI0M2QyNzA5NDQxMzg5MjY4MWRiZTFlZTgzMTk0Nzhj
|
15
|
+
YzM4NmQxNzg5OGYxMGE5Y2JlYzVmYjg5NWI5MGQ0YzdkZTdhM2U=
|
@@ -60,7 +60,7 @@ module Forklift
|
|
60
60
|
data.map{|l| l.symbolize_keys! }
|
61
61
|
|
62
62
|
if tables.include? table
|
63
|
-
|
63
|
+
ensure_row_types(data, table, database)
|
64
64
|
elsif(lazy == true && data.length > 0)
|
65
65
|
lazy_table_create(table, data, database, primary_key)
|
66
66
|
end
|
@@ -72,7 +72,8 @@ module Forklift
|
|
72
72
|
if(to_update == true && !d[primary_key.to_sym].nil?)
|
73
73
|
q("DELETE FROM `#{database}`.`#{table}` WHERE `#{primary_key}` = #{d[primary_key.to_sym]}")
|
74
74
|
end
|
75
|
-
|
75
|
+
insert_q = "INSERT INTO `#{database}`.`#{table}` (#{safe_columns(d.keys)}) VALUES (#{safe_values(d.values)});"
|
76
|
+
q(insert_q)
|
76
77
|
end
|
77
78
|
forklift.logger.log "wrote #{data.length} rows to `#{database}`.`#{table}`"
|
78
79
|
end
|
@@ -86,12 +87,12 @@ module Forklift
|
|
86
87
|
end
|
87
88
|
end
|
88
89
|
|
89
|
-
data.first do |k,v|
|
90
|
+
data.first.each do |k,v|
|
90
91
|
keys[k] = sql_type(v) if ( keys[k].nil? )
|
91
92
|
end
|
92
93
|
|
93
94
|
command = "CREATE TABLE `#{database}`.`#{table}` ( "
|
94
|
-
command << " `#{primary_key}`
|
95
|
+
command << " `#{primary_key}` bigint(20) NOT NULL AUTO_INCREMENT, " if ( data.first[primary_key.to_sym].nil? )
|
95
96
|
keys.each do |col, type|
|
96
97
|
command << " `#{col}` #{type} DEFAULT NULL, "
|
97
98
|
end
|
@@ -113,7 +114,7 @@ module Forklift
|
|
113
114
|
return "tinyint(1)" if v.class == TrueClass
|
114
115
|
return "tinyint(1)" if v.class == FalseClass
|
115
116
|
return "text" if v.class == String
|
116
|
-
return "
|
117
|
+
return "varchar(0)" if v.class == NilClass
|
117
118
|
return "text" # catchall
|
118
119
|
end
|
119
120
|
|
@@ -214,6 +215,29 @@ module Forklift
|
|
214
215
|
|
215
216
|
private
|
216
217
|
|
218
|
+
def ensure_row_types(data, table, database=current_database)
|
219
|
+
read("describe `#{database}`.`#{table}`").each do |row|
|
220
|
+
if row[:Type] == 'varchar(0)'
|
221
|
+
|
222
|
+
value = nil
|
223
|
+
data.each do |r|
|
224
|
+
if ( !r[row[:Field].to_sym].nil? )
|
225
|
+
value = r[row[:Field].to_sym]
|
226
|
+
break
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
if !value.nil?
|
231
|
+
sql_type = sql_type(value)
|
232
|
+
alter_sql = "ALTER TABLE `#{database}`.`#{table}` CHANGE `#{row[:Field]}` `#{row[:Field]}` #{sql_type};"
|
233
|
+
puts alter_sql
|
234
|
+
q(alter_sql)
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
217
241
|
def safe_columns(cols)
|
218
242
|
a = []
|
219
243
|
cols.each do |c|
|
data/lib/forklift/version.rb
CHANGED
@@ -123,7 +123,7 @@ describe 'mysql' do
|
|
123
123
|
cols << row["Field"]
|
124
124
|
case row["Field"]
|
125
125
|
when "id"
|
126
|
-
expect(row["Type"]).to eql "
|
126
|
+
expect(row["Type"]).to eql "bigint(20)"
|
127
127
|
when "thing"
|
128
128
|
expect(row["Type"]).to eql "text"
|
129
129
|
when "updated_at"
|
@@ -164,6 +164,59 @@ describe 'mysql' do
|
|
164
164
|
expect(cols).to eql ['id', 'thing', 'updated_at', 'number']
|
165
165
|
end
|
166
166
|
|
167
|
+
it "null rows will be text, and can be updated on subsequent writes" do
|
168
|
+
data = [
|
169
|
+
{id: 1, number: nil, updated_at: Time.new},
|
170
|
+
{id: 2, number: nil, updated_at: Time.new},
|
171
|
+
]
|
172
|
+
|
173
|
+
table = "new_table"
|
174
|
+
|
175
|
+
plan = SpecPlan.new
|
176
|
+
plan.do! {
|
177
|
+
destination = plan.connections[:mysql][:forklift_test_source_a]
|
178
|
+
destination.write(data, table)
|
179
|
+
}
|
180
|
+
|
181
|
+
destination = SpecClient.mysql('forklift_test_source_a')
|
182
|
+
cols = []
|
183
|
+
|
184
|
+
destination.query("describe #{table}").each do |row|
|
185
|
+
cols << row["Field"]
|
186
|
+
case row["Field"]
|
187
|
+
when "id"
|
188
|
+
expect(row["Type"]).to eql "bigint(20)"
|
189
|
+
when "number"
|
190
|
+
expect(row["Type"]).to eql "varchar(0)"
|
191
|
+
when "updated_at"
|
192
|
+
expect(row["Type"]).to eql "datetime"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
expect(cols).to eql ['id', 'updated_at', 'number']
|
196
|
+
|
197
|
+
data = [
|
198
|
+
{id: 3, number: 123, updated_at: Time.new},
|
199
|
+
]
|
200
|
+
|
201
|
+
plan = SpecPlan.new
|
202
|
+
plan.do! {
|
203
|
+
destination = plan.connections[:mysql][:forklift_test_source_a]
|
204
|
+
destination.write(data, table)
|
205
|
+
}
|
206
|
+
|
207
|
+
destination = SpecClient.mysql('forklift_test_source_a')
|
208
|
+
cols = []
|
209
|
+
|
210
|
+
destination.query("describe #{table}").each do |row|
|
211
|
+
cols << row["Field"]
|
212
|
+
case row["Field"]
|
213
|
+
when "number"
|
214
|
+
expect(row["Type"]).to eql "bigint(20)"
|
215
|
+
end
|
216
|
+
end
|
217
|
+
expect(cols).to eql ['id', 'updated_at', 'number']
|
218
|
+
end
|
219
|
+
|
167
220
|
end
|
168
221
|
|
169
222
|
end
|