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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NmIzZGJlZDAwZDhlNjE3ZjIxMzdkNGQ2ZDQ5NDk3ZTUzMzkxM2Y5MQ==
4
+ MTFiNTAwY2RlOGQxOTUzY2Y3N2RiNTg3Njg2ZDJiZDE3NTY3MGNmZg==
5
5
  data.tar.gz: !binary |-
6
- NzE3NzZjOGNiOWZiMDYxNDk4ZGIyZjRlNjdmOTk4NjU5MDYzNWZiZA==
6
+ ZmQ2NTQwZjEyZGFhMzY5MmRjMzQyNzVkZTIxYTM4YzNmM2FmZTFiOA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YTIxMmJiMWE5Nzg3ZTdiNDQyZGZjNDBhNzllNTg5ZTAyZDk0NTNmMGU1NzAy
10
- ZjI4ZDY2NGM2ODkwNmViZGJjYTdmNzM0ZWFkMmM2MDFhNDUwY2ViMDJmODVk
11
- Y2NmYmM5YmYwMDg1ZGM5NTNmMTk4MGNhYzg4ZWM2ZTA1M2IxZDY=
9
+ YTU5YzAyZDQ5NmI3YTVkMGZmZmY3Yjc0MTc0NjBhZDQzODkwMDI0NDhjMDdi
10
+ YWM1ODkwNGI4NWVkZjA2MTlhOTkzNmE0MDY2MTFjMDk0ZDJhNWYyMTI3MzM3
11
+ MmZjMjVkNTM5YTdmYzY1NTU3ZDkxZDE5MGIzN2M3ZjNmYWU4OWY=
12
12
  data.tar.gz: !binary |-
13
- YTI1YWYxNzM4MDdlOWY1NTUyNzA4NTIwOWEwZWQwMjBkOGM0MGFkNzdiMGI4
14
- YmI1YjhiNDY3NjkzYmNhYTdlYzg2ZWY4OGMyODUxYzk0ODU1NTM2OWQxY2Uw
15
- NzE4MjNiZGY0YTNhMWU3OTg4ZDRhY2NhMTNhNzBjM2NhMTcyNDc=
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
- # all good, cary on
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
- q("INSERT INTO `#{database}`.`#{table}` (#{safe_columns(d.keys)}) VALUES (#{safe_values(d.values)});")
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}` int(11) NOT NULL AUTO_INCREMENT, " if ( data.first[primary_key.to_sym].nil? )
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 "text" if v.class == NilClass
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|
@@ -1,3 +1,3 @@
1
1
  module Forklift
2
- VERSION = "1.1.3"
2
+ VERSION = "1.1.4"
3
3
  end
@@ -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 "int(11)"
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forklift_etl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Tahler