flydata 0.3.9 → 0.3.10

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 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