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