flydata 0.3.9 → 0.3.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: abffe0873e3fe1143a5053d9f02b5c61eb1e90a3
4
- data.tar.gz: c7f54222297282bcc2c13ffa1ca18ddc45bb10ef
3
+ metadata.gz: 478d29c0767a534808dea15674528d5b5442bbed
4
+ data.tar.gz: c6536fb66fedffbdcc52069cb28f32f74fe3465d
5
5
  SHA512:
6
- metadata.gz: 3b81782a6f4ac5bf2c28485b56ea1912e6f8490d375cb6ffd5f70e070776691fe4d20f74cfb444672192a0440a651b73835765054fc9da617e36182e4c021655
7
- data.tar.gz: 7ef6babb2f76e4c1e75ff700a377c1b8a9504f022fe1bbe0fe09dc30f54e629277dafe2d55cfd905967edeac55d70d0019181fc1a90000c77172f9f7325961b8
6
+ metadata.gz: 6b97f3acc0e763fcff4f2d4a18dcc4d9625d736db229b00554aee36da0ff8e68a189324a46abb3d985dfd1e2d4964ec6963a9299d475170e759485cb1e07faec
7
+ data.tar.gz: fdee03e1c1bf32699f8c5157aa51f48ecf6f1c023d2160a63b996ca7ac0599fa952de02b55045715b4a66283083b204860201a31a157b9cbf92d2413aebc77d5
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.9
1
+ 0.3.10
@@ -51,6 +51,7 @@ end
51
51
  # RetryableError
52
52
 
53
53
  class RetryableError < StandardError
54
+ NO_RETRY_LIMIT = :no_retry_limit
54
55
  def initialize(original_exception, retry_alert_limit = nil)
55
56
  @original_exception = original_exception
56
57
  @retry_alert_limit = retry_alert_limit
@@ -59,10 +60,20 @@ class RetryableError < StandardError
59
60
  attr_reader :retry_alert_limit
60
61
  end
61
62
 
62
- # DataDeliveryError
63
+ # UserMaintenanceError
64
+
65
+ class UserMaintenanceError < StandardError
66
+ end
67
+
68
+ # An error that indicates that sync record was received for a table whose sync is broken
69
+ # These records cannot be retried, should be ignored
70
+ class BrokenTableSyncError < StandardError
71
+ end
72
+
73
+ # FlyDataError
63
74
  # data_node_id, data_entry_id, chunk_identifier, table_name, err_code, err_reason, err_level
64
75
 
65
- class DataDeliveryError < StandardError
76
+ class FlydataError < StandardError
66
77
  def initialize(error_reason, error_content = {})
67
78
  error_content = if error_reason.kind_of?(String)
68
79
  { err_reason: error_reason}.merge(error_content)
@@ -125,6 +136,14 @@ class DataDeliveryError < StandardError
125
136
  end
126
137
  end
127
138
 
139
+ # DataDeliveryError
140
+ # An error which results in data clog or loss of information.
141
+ # This type of error gets reported to customer as data delivery error.
142
+ # data_node_id, data_entry_id, chunk_identifier, table_name, err_code, err_reason, err_level
143
+
144
+ class DataDeliveryError < FlydataError
145
+ end
146
+
128
147
  # + RecordDeliveryError
129
148
  # data_node_id, data_entry_id, chunk_identifier, table_name, err_code, err_reason, err_level, record_no, raw_record
130
149
 
@@ -174,7 +193,8 @@ class TableRevisionError < RecordDeliveryError
174
193
  end
175
194
 
176
195
  # Table's revision is lower than the record's revision. Should catch up soon.
177
- class StaleTableRevisionError < TableRevisionError
196
+ class StaleTableRevisionError < FlydataError
197
+ def err_code; ErrorCode::TABLE_REVISION_ERROR; end
178
198
  end
179
199
 
180
200
  # Unsupported ALTER TABLE which breaks the tables sync consistency.
@@ -0,0 +1,8 @@
1
+ module Fluent
2
+ module MultiBufferedOutputConstant
3
+ # '-' was chosen because it's valid in URL but invalid in a SQL table name.
4
+ # Thus, it can be passed as an URL parameter yet it never conflicts with
5
+ # a table name.
6
+ TABLE_TOTAL = "-total"
7
+ end
8
+ end
@@ -108,33 +108,63 @@ module FlydataCore
108
108
  def log_common(level, message, log_params, options)
109
109
  msg = build_log_message(level, message, log_params, options)
110
110
  before_logging(level, message, msg, log_params, options)
111
- get_logger(options).send(level, msg)
111
+ logger = get_logger(options)
112
+ set_mutex(logger)
113
+ logger.mutex.synchronize do
114
+ original_depth_offset = nil
115
+ if logger.instance_variable_defined? :@depth_offset
116
+ original_depth_offset = logger.instance_variable_get(:@depth_offset)
117
+ depth_offset = 3 # log_common + synchronize + synchronized block
118
+ depth_offset += options[:depth_offset] if options.has_key?(:depth_offset)
119
+ logger.instance_variable_set(:@depth_offset, original_depth_offset + depth_offset)
120
+ end
121
+ logger.send(level, msg)
122
+ if original_depth_offset
123
+ logger.instance_variable_set(:@depth_offset, original_depth_offset)
124
+ end
125
+ end
112
126
  end
113
127
 
114
128
  def log_debug(message, log_params = {}, options = {})
115
- log_common(:debug, message, log_params, options)
129
+ opt = { depth_offset: 1}.merge(options)
130
+ log_common(:debug, message, log_params, opt)
116
131
  end
117
132
 
118
133
  def log_info(message, log_params = {}, options = {})
119
- log_common(:info, message, log_params, options)
134
+ opt = { depth_offset: 1}.merge(options)
135
+ log_common(:info, message, log_params, opt)
120
136
  end
121
137
 
122
138
  def log_warn(message, log_params = {}, options = {})
123
- log_common(:warn, message, log_params, options)
139
+ opt = { depth_offset: 1}.merge(options)
140
+ log_common(:warn, message, log_params, opt)
124
141
  end
125
142
 
126
143
  def log_error(message, log_params = {}, options = {})
127
- log_common(:error, message, log_params, options)
144
+ opt = { depth_offset: 1}.merge(options)
145
+ log_common(:error, message, log_params, opt)
128
146
  end
129
147
 
130
148
  def log_error_with_backtrace(message, log_params = {}, options = {})
131
- log_common(:error, message, log_params, options.merge(backtrace: true))
149
+ opt = { depth_offset: 1}.merge(options)
150
+ log_common(:error, message, log_params, opt.merge(backtrace: true))
132
151
  end
133
152
 
134
153
  def get_logger(options = {})
135
154
  options[:logger] || logger || log_context_logger || $log
136
155
  end
137
156
 
157
+ # set mutex if logger doesn't have one
158
+ def set_mutex(logger)
159
+ return if logger.respond_to?(:mutex)
160
+
161
+ mtx = Mutex.new
162
+ logger.instance_variable_set(:@mutex, mtx)
163
+ class << logger
164
+ attr_reader :mutex
165
+ end
166
+ end
167
+
138
168
  def build_log_message(level, raw_message, log_params = {}, options = {})
139
169
  message = raw_message.dup
140
170
  # check keys
@@ -209,7 +239,9 @@ module FlydataCore
209
239
  exception = exception.original_exception unless exception.original_exception.nil?
210
240
  end
211
241
 
212
- unless is_retryable_error && retry_count < retry_alert_limit
242
+ unless is_retryable_error &&
243
+ (retry_alert_limit == FlydataCore::RetryableError::NO_RETRY_LIMIT ||
244
+ retry_count < retry_alert_limit)
213
245
  if exception.kind_of?(FlydataCore::DataDeliveryError)
214
246
  # Do not log a DataDeliveryError as ERROR. It's a user error which
215
247
  # should not cause a system alert
@@ -62,6 +62,7 @@ class MysqlTableDef
62
62
  'tinytext' => {type: 'text'},
63
63
  'varbinary' => {type: 'varbinary', override: PROC_override_varbinary},
64
64
  'varchar' => {type: 'varchar', override: PROC_override_varchar},
65
+ 'year' => {type: 'year'},
65
66
  }
66
67
 
67
68
  def self.convert_to_flydata_type(type)
@@ -33,6 +33,7 @@ class RedshiftTableDef
33
33
  'time' => {type: 'timestamp', default_value: '0000-01-01'},
34
34
  'varbinary' => {type: 'varchar', use_params: true, max_size: 65535, default_value: ''},
35
35
  'varchar' => {type: 'varchar', use_params: true, max_size: 65535, default_value: ''},
36
+ 'year' => {type: 'date', default_value: '0001-01-01'},
36
37
  }
37
38
  def self.from_flydata_tabledef(flydata_tabledef, options = {})
38
39
  options[:flydata_ctl_table] = true unless options.has_key?(:flydata_ctl_table)
@@ -56,7 +57,7 @@ class RedshiftTableDef
56
57
  CREATE SCHEMA "%s";
57
58
  EOS
58
59
  CREATE_FLYDATA_CTL_TABLE_SQL = <<EOS
59
- CREATE TABLE %s(
60
+ CREATE TABLE IF NOT EXISTS %s(
60
61
  id integer NOT NULL IDENTITY(1,1),
61
62
  table_name varchar(128) NOT NULL,
62
63
  column_name varchar(128) NOT NULL,
@@ -86,7 +87,7 @@ EOS
86
87
  end
87
88
 
88
89
  CREATE_TABLE_SQL = <<EOS
89
- DROP TABLE %s;
90
+ DROP TABLE IF EXISTS %s;
90
91
  CREATE TABLE %s (
91
92
  %s
92
93
  )%s;
@@ -141,9 +142,10 @@ EOS
141
142
 
142
143
  NULL_STR = "NULL"
143
144
 
144
- def self.replace_default_value(type, default_value)
145
+ def self.replace_default_value(redshift_type, default_value)
145
146
  return NULL_STR if default_value.nil?
146
- case type
147
+
148
+ case redshift_type
147
149
  when 'timestamp'
148
150
  if default_value.upcase == "CURRENT_TIMESTAMP"
149
151
  'SYSDATE'
@@ -224,7 +226,7 @@ EOS
224
226
  def self.check_and_replace_max(params, max_size_a)
225
227
  final_params = []
226
228
  params.split(",").each_with_index do |param, i|
227
- final_params << (/\d+/.match(param) && max_size_a[i] && param.to_i > max_size_a[i].to_i ?
229
+ final_params << (/\d+/.match(param) && max_size_a[i] && param.to_i > max_size_a[i].to_i ?
228
230
  max_size_a[i] : param)
229
231
  end
230
232
  final_params.join(",")
@@ -234,23 +236,24 @@ EOS
234
236
  TIME_REGEXP = Regexp.new('^(?<sign>-)?(?<hour>\d{2,3}):(?<minute>[0-5][0-9]):(?<second>[0-5][0-9](\.\d+)?)$')
235
237
 
236
238
  def self.parse_timestamp(value)
237
- return nil if value.to_s.empty?
238
- if value.kind_of?(Integer) or /^\d+$/ === value
239
+ value_str = value.to_s
240
+ return nil if value_str.empty?
241
+ if value.kind_of?(Integer) or /^\d+$/ === value_str
239
242
  # Unix epoch in UTC
240
- t = DateTime.strptime(value.to_s, '%s')
241
- elsif APACHE_TIMESTAMP_REGEXP.match(value)
243
+ t = DateTime.strptime(value_str, '%s')
244
+ elsif APACHE_TIMESTAMP_REGEXP.match(value_str)
242
245
  # apache time format
243
246
  t = DateTime.strptime(value, "[%d/%b/%Y:%H:%M:%S %Z]")
244
- elsif time_match = TIME_REGEXP.match(value)
247
+ elsif time_match = TIME_REGEXP.match(value_str)
245
248
  t = convert_time_into_timestamp(time_match)
246
249
  else
247
- t = DateTime.parse(value)
250
+ t = DateTime.parse(value_str)
248
251
  end
249
252
  t = t.new_offset(0) # Redshift Plug-in uses UTC
250
253
  t.strftime('%Y-%m-%d %H:%M:%S.%6N')
251
254
  rescue ArgumentError => ae
252
255
  # '0000-00-00 00:00:00' is valid for mysql datetime column
253
- if value.start_with?('0000-00-00 00:00:00')
256
+ if value_str.start_with?('0000-00-00 00:00:00')
254
257
  return '0001-01-01 00:00:00.000000'
255
258
  else
256
259
  raise ae
@@ -268,15 +271,29 @@ EOS
268
271
  end
269
272
 
270
273
  def self.parse_date(value)
271
- dt = Date.parse(value)
274
+ dt = Date.parse(convert_year_into_date(value))
272
275
  dt.strftime('%Y-%m-%d')
273
276
  rescue ArgumentError => ae
274
277
  # '0000-00-00' is valid for mysql date column
275
278
  return '0001-01-01' if value == '0000-00-00'
276
279
  raise ae
277
280
  end
281
+
282
+ def self.convert_year_into_date(value)
283
+ if value == '0' || value == '0000'
284
+ converted_value = '0001-01-01' # '0001-01-01' is the "base" date
285
+ else
286
+ case value
287
+ when /^\d{4}$/
288
+ converted_value = "#{value}-01-01"
289
+ when /^\d{2}$/
290
+ converted_value = "#{value.to_i >= 70 ? "19" : "20"}#{value}-01-01"
291
+ else
292
+ converted_value = value # Return the value as is
293
+ end
294
+ end
295
+ end
278
296
  end
279
297
 
280
298
  end
281
299
  end
282
-
@@ -56,7 +56,10 @@ describe MysqlTableDef do
56
56
  {:column=>"col_tinyint", :type=>"int1(4)", :default=>nil},
57
57
  {:column=>"col_tinytext", :type=>"text"},
58
58
  {:column=>"col_varbinary", :type=>"varbinary(512)", :default=>nil},
59
- {:column=>"col_varchar", :type=>"varchar(372)", :default=>nil}
59
+ {:column=>"col_varchar", :type=>"varchar(372)", :default=>nil},
60
+ {:column=>"col_year", :type=>"year", :default=>nil},
61
+ {:column=>"col_year_4", :type=>"year(4)", :default=>nil},
62
+ {:column=>"col_year_2", :type=>"year(2)", :default=>nil},
60
63
  ]
61
64
  )
62
65
  end
@@ -329,6 +332,10 @@ describe MysqlTableDef do
329
332
  let(:flydata_type) { 'text' }
330
333
  it_behaves_like "converting the mysql data type to the expected flydata type"
331
334
  end
335
+ context "year" do
336
+ let(:flydata_type) { 'year' }
337
+ it_behaves_like "converting the mysql data type to the expected flydata type"
338
+ end
332
339
  end
333
340
  end
334
341
  end
@@ -27,7 +27,7 @@ module FlydataCore
27
27
 
28
28
  it 'should return ddl' do
29
29
  expect(subject).to eq( <<EOT.strip )
30
- CREATE TABLE "flydata_ctl_columns"(
30
+ CREATE TABLE IF NOT EXISTS "flydata_ctl_columns"(
31
31
  id integer NOT NULL IDENTITY(1,1),
32
32
  table_name varchar(128) NOT NULL,
33
33
  column_name varchar(128) NOT NULL,
@@ -36,7 +36,7 @@ CREATE TABLE "flydata_ctl_columns"(
36
36
  ordinal_position int NOT NULL,
37
37
  PRIMARY KEY(id)
38
38
  ) DISTKEY(table_name) SORTKEY(table_name);
39
- DROP TABLE "test_table_all";
39
+ DROP TABLE IF EXISTS "test_table_all";
40
40
  CREATE TABLE "test_table_all" (
41
41
  "id" int8 NOT NULL,
42
42
  "col_binary" varchar(202) DEFAULT NULL,
@@ -65,6 +65,9 @@ CREATE TABLE "test_table_all" (
65
65
  "col_tinytext" varchar(max),
66
66
  "col_varbinary" varchar(512) DEFAULT NULL,
67
67
  "col_varchar" varchar(372) DEFAULT NULL,
68
+ "col_year" date DEFAULT NULL,
69
+ "col_year_4" date DEFAULT NULL,
70
+ "col_year_2" date DEFAULT NULL,
68
71
  PRIMARY KEY (id)
69
72
  ) DISTKEY(id) SORTKEY(id);
70
73
  DELETE FROM "flydata_ctl_columns" WHERE table_name = 'test_table_all';
@@ -95,7 +98,10 @@ INSERT INTO "flydata_ctl_columns" (table_name, column_name, src_data_type, ordin
95
98
  ('test_table_all', 'col_tinyint', 'int1(4)', 24),
96
99
  ('test_table_all', 'col_tinytext', 'text', 25),
97
100
  ('test_table_all', 'col_varbinary', 'varbinary(512)', 26),
98
- ('test_table_all', 'col_varchar', 'varchar(372)', 27);
101
+ ('test_table_all', 'col_varchar', 'varchar(372)', 27),
102
+ ('test_table_all', 'col_year', 'year', 28),
103
+ ('test_table_all', 'col_year_4', 'year(4)', 29),
104
+ ('test_table_all', 'col_year_2', 'year(2)', 30);
99
105
  EOT
100
106
  end
101
107
  end
@@ -105,7 +111,7 @@ EOT
105
111
 
106
112
  it 'should return ddl' do
107
113
  expect(subject).to eq( <<EOT.strip )
108
- CREATE TABLE "flydata_ctl_columns"(
114
+ CREATE TABLE IF NOT EXISTS "flydata_ctl_columns"(
109
115
  id integer NOT NULL IDENTITY(1,1),
110
116
  table_name varchar(128) NOT NULL,
111
117
  column_name varchar(128) NOT NULL,
@@ -114,7 +120,7 @@ CREATE TABLE "flydata_ctl_columns"(
114
120
  ordinal_position int NOT NULL,
115
121
  PRIMARY KEY(id)
116
122
  ) DISTKEY(table_name) SORTKEY(table_name);
117
- DROP TABLE "bit_test_def_1";
123
+ DROP TABLE IF EXISTS "bit_test_def_1";
118
124
  CREATE TABLE "bit_test_def_1" (
119
125
  "id" int4 NOT NULL,
120
126
  "bit_value" bigint DEFAULT 1,
@@ -135,7 +141,7 @@ EOT
135
141
 
136
142
  it 'should return ddl' do
137
143
  expect(subject).to eq( <<EOT.strip )
138
- CREATE TABLE "flydata_ctl_columns"(
144
+ CREATE TABLE IF NOT EXISTS "flydata_ctl_columns"(
139
145
  id integer NOT NULL IDENTITY(1,1),
140
146
  table_name varchar(128) NOT NULL,
141
147
  column_name varchar(128) NOT NULL,
@@ -144,7 +150,7 @@ CREATE TABLE "flydata_ctl_columns"(
144
150
  ordinal_position int NOT NULL,
145
151
  PRIMARY KEY(id)
146
152
  ) DISTKEY(table_name) SORTKEY(table_name);
147
- DROP TABLE "product_order";
153
+ DROP TABLE IF EXISTS "product_order";
148
154
  CREATE TABLE "product_order" (
149
155
  "no" int4 NOT NULL,
150
156
  "product_category" int4 NOT NULL,
@@ -167,7 +173,7 @@ EOT
167
173
 
168
174
  it 'should return ddl' do
169
175
  expect(subject).to eq( <<EOT.strip )
170
- CREATE TABLE "flydata_ctl_columns"(
176
+ CREATE TABLE IF NOT EXISTS "flydata_ctl_columns"(
171
177
  id integer NOT NULL IDENTITY(1,1),
172
178
  table_name varchar(128) NOT NULL,
173
179
  column_name varchar(128) NOT NULL,
@@ -176,7 +182,7 @@ CREATE TABLE "flydata_ctl_columns"(
176
182
  ordinal_position int NOT NULL,
177
183
  PRIMARY KEY(id)
178
184
  ) DISTKEY(table_name) SORTKEY(table_name);
179
- DROP TABLE "test_table_column_comment";
185
+ DROP TABLE IF EXISTS "test_table_column_comment";
180
186
  CREATE TABLE "test_table_column_comment" (
181
187
  "id" int4 NOT NULL DEFAULT '0',
182
188
  "value" varchar(max),
@@ -197,7 +203,7 @@ EOT
197
203
 
198
204
  it 'should return ddl' do
199
205
  expect(subject).to eq( <<EOT.strip )
200
- CREATE TABLE "flydata_ctl_columns"(
206
+ CREATE TABLE IF NOT EXISTS "flydata_ctl_columns"(
201
207
  id integer NOT NULL IDENTITY(1,1),
202
208
  table_name varchar(128) NOT NULL,
203
209
  column_name varchar(128) NOT NULL,
@@ -206,7 +212,7 @@ CREATE TABLE "flydata_ctl_columns"(
206
212
  ordinal_position int NOT NULL,
207
213
  PRIMARY KEY(id)
208
214
  ) DISTKEY(table_name) SORTKEY(table_name);
209
- DROP TABLE "test_table_enum";
215
+ DROP TABLE IF EXISTS "test_table_enum";
210
216
  CREATE TABLE "test_table_enum" (
211
217
  "id" int4 NOT NULL,
212
218
  "enum_1" varchar encode bytedict DEFAULT NULL,
@@ -229,7 +235,7 @@ EOT
229
235
 
230
236
  it 'should return ddl' do
231
237
  expect(subject).to eq( <<EOT.strip )
232
- CREATE TABLE "flydata_ctl_columns"(
238
+ CREATE TABLE IF NOT EXISTS "flydata_ctl_columns"(
233
239
  id integer NOT NULL IDENTITY(1,1),
234
240
  table_name varchar(128) NOT NULL,
235
241
  column_name varchar(128) NOT NULL,
@@ -238,7 +244,7 @@ CREATE TABLE "flydata_ctl_columns"(
238
244
  ordinal_position int NOT NULL,
239
245
  PRIMARY KEY(id)
240
246
  ) DISTKEY(table_name) SORTKEY(table_name);
241
- DROP TABLE "test_table_multi_pk";
247
+ DROP TABLE IF EXISTS "test_table_multi_pk";
242
248
  CREATE TABLE "test_table_multi_pk" (
243
249
  "id1" int4 NOT NULL DEFAULT '0',
244
250
  "id2" int4 NOT NULL DEFAULT '0',
@@ -267,7 +273,7 @@ EOT
267
273
 
268
274
  it 'should return ddl' do
269
275
  expect(subject).to eq( <<EOT.strip )
270
- CREATE TABLE "flydata_ctl_columns"(
276
+ CREATE TABLE IF NOT EXISTS "flydata_ctl_columns"(
271
277
  id integer NOT NULL IDENTITY(1,1),
272
278
  table_name varchar(128) NOT NULL,
273
279
  column_name varchar(128) NOT NULL,
@@ -276,7 +282,7 @@ CREATE TABLE "flydata_ctl_columns"(
276
282
  ordinal_position int NOT NULL,
277
283
  PRIMARY KEY(id)
278
284
  ) DISTKEY(table_name) SORTKEY(table_name);
279
- DROP TABLE "sample1";
285
+ DROP TABLE IF EXISTS "sample1";
280
286
  CREATE TABLE "sample1" (
281
287
  "id" int4 NOT NULL,
282
288
  "title" varchar(768) DEFAULT NULL,
@@ -299,7 +305,7 @@ EOT
299
305
 
300
306
  it 'should return ddl' do
301
307
  expect(subject).to eq( <<EOT.strip )
302
- CREATE TABLE "flydata_ctl_columns"(
308
+ CREATE TABLE IF NOT EXISTS "flydata_ctl_columns"(
303
309
  id integer NOT NULL IDENTITY(1,1),
304
310
  table_name varchar(128) NOT NULL,
305
311
  column_name varchar(128) NOT NULL,
@@ -308,7 +314,7 @@ CREATE TABLE "flydata_ctl_columns"(
308
314
  ordinal_position int NOT NULL,
309
315
  PRIMARY KEY(id)
310
316
  ) DISTKEY(table_name) SORTKEY(table_name);
311
- DROP TABLE "sample1";
317
+ DROP TABLE IF EXISTS "sample1";
312
318
  CREATE TABLE "sample1" (
313
319
  "id" int4 NOT NULL,
314
320
  "title" varchar(768) DEFAULT NULL,
@@ -331,7 +337,7 @@ EOT
331
337
 
332
338
  it 'should return ddl' do
333
339
  expect(subject).to eq( <<EOT.strip )
334
- CREATE TABLE "flydata_ctl_columns"(
340
+ CREATE TABLE IF NOT EXISTS "flydata_ctl_columns"(
335
341
  id integer NOT NULL IDENTITY(1,1),
336
342
  table_name varchar(128) NOT NULL,
337
343
  column_name varchar(128) NOT NULL,
@@ -340,7 +346,7 @@ CREATE TABLE "flydata_ctl_columns"(
340
346
  ordinal_position int NOT NULL,
341
347
  PRIMARY KEY(id)
342
348
  ) DISTKEY(table_name) SORTKEY(table_name);
343
- DROP TABLE "invoice_items";
349
+ DROP TABLE IF EXISTS "invoice_items";
344
350
  CREATE TABLE "invoice_items" (
345
351
  "id" int4 NOT NULL,
346
352
  "app_id" int4 NOT NULL,
@@ -391,7 +397,7 @@ EOT
391
397
 
392
398
  it 'should return ddl' do
393
399
  expect(subject).to eq( <<EOT.strip )
394
- CREATE TABLE "flydata_ctl_columns"(
400
+ CREATE TABLE IF NOT EXISTS "flydata_ctl_columns"(
395
401
  id integer NOT NULL IDENTITY(1,1),
396
402
  table_name varchar(128) NOT NULL,
397
403
  column_name varchar(128) NOT NULL,
@@ -400,7 +406,7 @@ CREATE TABLE "flydata_ctl_columns"(
400
406
  ordinal_position int NOT NULL,
401
407
  PRIMARY KEY(id)
402
408
  ) DISTKEY(table_name) SORTKEY(table_name);
403
- DROP TABLE "zerofill_table";
409
+ DROP TABLE IF EXISTS "zerofill_table";
404
410
  CREATE TABLE "zerofill_table" (
405
411
  "id" int4 NOT NULL,
406
412
  "value_int" int8 DEFAULT NULL,
@@ -50,6 +50,9 @@ CREATE TABLE `test_table_all` (
50
50
  `col_tinytext` tinytext,
51
51
  `col_varbinary` varbinary(255) DEFAULT NULL,
52
52
  `col_varchar` varchar(124) DEFAULT NULL,
53
+ `col_year` year DEFAULT NULL,
54
+ `col_year_4` year(4) DEFAULT NULL,
55
+ `col_year_2` year(2) DEFAULT NULL,
53
56
  PRIMARY KEY (`id`)
54
57
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='test table includes all kind of format type';
55
58
  /*!40101 SET character_set_client = @saved_cs_client */;
@@ -22,7 +22,7 @@ describe RedshiftTableDef do
22
22
  context 'with simple flydatadef' do
23
23
  it 'should return ddl' do
24
24
  expect(subject).to eq( <<EOT.strip )
25
- DROP TABLE "test_table";
25
+ DROP TABLE IF EXISTS "test_table";
26
26
  CREATE TABLE "test_table" (
27
27
  "id" int4 NOT NULL,
28
28
  "age" int8,
@@ -43,7 +43,7 @@ EOT
43
43
 
44
44
  it 'should return ddl including flydata_ctl_columns creation' do
45
45
  expect(subject).to eq( <<EOT.strip )
46
- CREATE TABLE "flydata_ctl_columns"(
46
+ CREATE TABLE IF NOT EXISTS "flydata_ctl_columns"(
47
47
  id integer NOT NULL IDENTITY(1,1),
48
48
  table_name varchar(128) NOT NULL,
49
49
  column_name varchar(128) NOT NULL,
@@ -52,7 +52,7 @@ CREATE TABLE "flydata_ctl_columns"(
52
52
  ordinal_position int NOT NULL,
53
53
  PRIMARY KEY(id)
54
54
  ) DISTKEY(table_name) SORTKEY(table_name);
55
- DROP TABLE "test_table";
55
+ DROP TABLE IF EXISTS "test_table";
56
56
  CREATE TABLE "test_table" (
57
57
  "id" int4 NOT NULL,
58
58
  "age" int8,
@@ -80,7 +80,7 @@ EOT
80
80
 
81
81
  it 'should add comment creation ddl' do
82
82
  expect(subject).to eq( <<EOT.strip )
83
- DROP TABLE "test_table";
83
+ DROP TABLE IF EXISTS "test_table";
84
84
  CREATE TABLE "test_table" (
85
85
  "id" int4 NOT NULL,
86
86
  "value" varchar(max),
@@ -112,7 +112,7 @@ EOT
112
112
  it 'should preappend schema name to table name' do
113
113
  expect(subject).to eq( <<EOT.strip )
114
114
  CREATE SCHEMA "test_schema";
115
- CREATE TABLE "test_schema"."flydata_ctl_columns"(
115
+ CREATE TABLE IF NOT EXISTS "test_schema"."flydata_ctl_columns"(
116
116
  id integer NOT NULL IDENTITY(1,1),
117
117
  table_name varchar(128) NOT NULL,
118
118
  column_name varchar(128) NOT NULL,
@@ -121,7 +121,7 @@ CREATE TABLE "test_schema"."flydata_ctl_columns"(
121
121
  ordinal_position int NOT NULL,
122
122
  PRIMARY KEY(id)
123
123
  ) DISTKEY(table_name) SORTKEY(table_name);
124
- DROP TABLE "test_schema"."test_table";
124
+ DROP TABLE IF EXISTS "test_schema"."test_table";
125
125
  CREATE TABLE "test_schema"."test_table" (
126
126
  "id" int4 NOT NULL,
127
127
  "value" varchar(max),
@@ -409,6 +409,50 @@ EOT
409
409
  it_behaves_like *examples
410
410
  end
411
411
  end
412
+
413
+ context 'with year column def' do
414
+ before do
415
+ column[:column] = "value_year"
416
+ column[:type] = "year(4)"
417
+ end
418
+ let(:type_sql) { %Q|"value_year" date| }
419
+ let(:not_null_default_sql) { " DEFAULT '0001-01-01'" }
420
+
421
+ context 'when default_value is normal' do
422
+ let(:default_value) { "'2014'" }
423
+ let(:default_value_sql) { "'2014-01-01'" }
424
+ it_behaves_like *examples
425
+ end
426
+
427
+ context 'when default_value is 69' do
428
+ let(:default_value) { "'69'" }
429
+ let(:default_value_sql) { "'2069-01-01'" }
430
+ it_behaves_like *examples
431
+ end
432
+
433
+ context 'when default_value is 70' do
434
+ let(:default_value) { "'70'" }
435
+ let(:default_value_sql) { "'1970-01-01'" }
436
+ it_behaves_like *examples
437
+ end
438
+
439
+ context 'when default_value is 0' do
440
+ let(:default_value) { "'0'" }
441
+ let(:default_value_sql) { "'0001-01-01'" }
442
+ it_behaves_like *examples
443
+ end
444
+
445
+ context 'when the type has no width' do
446
+ before do
447
+ column[:type] = "year"
448
+ end
449
+ context 'when default_value is normal' do
450
+ let(:default_value) { "'2014'" }
451
+ let(:default_value_sql) { "'2014-01-01'" }
452
+ it_behaves_like *examples
453
+ end
454
+ end
455
+ end
412
456
  end
413
457
 
414
458
  context 'for create table' do
@@ -592,6 +636,63 @@ EOT
592
636
  let(:value) { 'abcd' }
593
637
  it { expect{subject}.to raise_error(ArgumentError) }
594
638
  end
639
+
640
+ context 'with boolean value' do
641
+ let(:value){ false }
642
+ it { expect{subject}.to raise_error(ArgumentError) }
643
+ end
644
+ end
645
+
646
+ describe '.convert_year_into_date' do
647
+ let(:value) { nil }
648
+ subject { described_class.convert_year_into_date(value) }
649
+
650
+ context 'with year values' do
651
+ context 'with value 0' do
652
+ let(:value){ '0' }
653
+ it { is_expected.to eq('0001-01-01') }
654
+ end
655
+
656
+ context 'with value 0000' do
657
+ let(:value){ '0000' }
658
+ it { is_expected.to eq('0001-01-01') }
659
+ end
660
+
661
+ context 'with year(4) >= 1970' do
662
+ let(:value){ '2000' }
663
+ it { is_expected.to eq('2000-01-01') }
664
+ end
665
+
666
+ context 'with year(4) < 1970' do
667
+ let(:value){ '1969' }
668
+ it { is_expected.to eq('1969-01-01') }
669
+ end
670
+
671
+ context 'with year(2) >= 70' do
672
+ let(:value){ '07' }
673
+ it { is_expected.to eq('2007-01-01') }
674
+ end
675
+
676
+ context 'with year(2) < 70' do
677
+ let(:value){ '69' }
678
+ it { is_expected.to eq('2069-01-01') }
679
+ end
680
+ end
681
+
682
+ context 'with date values' do
683
+ shared_examples "returning the input value as is" do
684
+ it { is_expected.to eq(value) }
685
+ end
686
+ context 'with valid date' do
687
+ let(:value){ '1920-01-01' }
688
+ it_behaves_like "returning the input value as is"
689
+ end
690
+
691
+ context 'with zero date' do
692
+ let(:value){ '0000-00-00' }
693
+ it_behaves_like "returning the input value as is"
694
+ end
695
+ end
595
696
  end
596
697
  end
597
698
 
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: flydata 0.3.9 ruby lib
5
+ # stub: flydata 0.3.10 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "flydata"
9
- s.version = "0.3.9"
9
+ s.version = "0.3.10"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Koichi Fujikawa", "Masashi Miyazaki", "Matthew Luu", "Mak Inada", "Sriram NS"]
14
- s.date = "2015-03-21"
14
+ s.date = "2015-03-31"
15
15
  s.description = "FlyData Agent"
16
16
  s.email = "sysadmin@flydata.com"
17
17
  s.executables = ["fdmysqldump", "flydata", "serverinfo"]
@@ -44,6 +44,7 @@ Gem::Specification.new do |s|
44
44
  "flydata-core/lib/flydata-core/core_ext/object.rb",
45
45
  "flydata-core/lib/flydata-core/core_ext/object/prepend.rb",
46
46
  "flydata-core/lib/flydata-core/errors.rb",
47
+ "flydata-core/lib/flydata-core/fluent-plugins/multi_buffer.rb",
47
48
  "flydata-core/lib/flydata-core/logger.rb",
48
49
  "flydata-core/lib/flydata-core/table_def.rb",
49
50
  "flydata-core/lib/flydata-core/table_def/mysql_table_def.rb",
@@ -167,7 +168,7 @@ Gem::Specification.new do |s|
167
168
  ]
168
169
  s.homepage = "http://flydata.com/"
169
170
  s.licenses = ["All right reserved."]
170
- s.rubygems_version = "2.2.2"
171
+ s.rubygems_version = "2.4.3"
171
172
  s.summary = "FlyData Agent"
172
173
 
173
174
  if s.respond_to? :specification_version then
@@ -24,7 +24,7 @@ module Flydata
24
24
  class Sync < Base
25
25
  include Helpers
26
26
  INSERT_PROGRESS_INTERVAL = 1000
27
- SERVER_DATA_PROCESSING_TIMEOUT = 600 # seconds
27
+ SERVER_DATA_PROCESSING_TIMEOUT = 3600 # seconds
28
28
 
29
29
  # for dump.pos file
30
30
  STATUS_PARSING = 'PARSING'
@@ -179,7 +179,10 @@ EOS
179
179
  sync_fm.table_rev_file_paths(*@input_tables),
180
180
  sync_fm.table_ddl_file_paths(*@input_tables)
181
181
  ]
182
- delete_files << sync_fm.binlog_path if @input_tables.empty? or @full_tables.empty?
182
+ new_tables_after_reset = @new_tables + @input_tables
183
+ if @input_tables.empty? or @full_tables.empty? or @full_tables.all?{|ft| new_tables_after_reset.include?(ft)}
184
+ delete_files << sync_fm.binlog_path
185
+ end
183
186
  delete_files.flatten.each do |path|
184
187
  FileUtils.rm(path) if File.exists?(path)
185
188
  end
@@ -737,13 +740,13 @@ Thank you for using FlyData!
737
740
  def flush_buffer_and_stop(tables = [])
738
741
  sender = Flydata::Command::Sender.new
739
742
  sender.flush_client_buffer
743
+ sender.stop(quiet: true)
740
744
  if opts.skip_flush?
741
745
  log_info_stdout("Skip waiting for server data processing.")
742
746
  else
743
747
  wait_for_server_data_processing(
744
748
  timeout: SERVER_DATA_PROCESSING_TIMEOUT, tables: tables)
745
749
  end
746
- sender.stop(quiet: true)
747
750
  end
748
751
 
749
752
  # Utility methods
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flydata
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.9
4
+ version: 0.3.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Fujikawa
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2015-03-21 00:00:00.000000000 Z
15
+ date: 2015-03-31 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rest-client
@@ -467,6 +467,7 @@ files:
467
467
  - flydata-core/lib/flydata-core/core_ext/object.rb
468
468
  - flydata-core/lib/flydata-core/core_ext/object/prepend.rb
469
469
  - flydata-core/lib/flydata-core/errors.rb
470
+ - flydata-core/lib/flydata-core/fluent-plugins/multi_buffer.rb
470
471
  - flydata-core/lib/flydata-core/logger.rb
471
472
  - flydata-core/lib/flydata-core/table_def.rb
472
473
  - flydata-core/lib/flydata-core/table_def/mysql_table_def.rb
@@ -607,7 +608,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
607
608
  version: '0'
608
609
  requirements: []
609
610
  rubyforge_project:
610
- rubygems_version: 2.2.2
611
+ rubygems_version: 2.4.3
611
612
  signing_key:
612
613
  specification_version: 4
613
614
  summary: FlyData Agent