flydata 0.6.14 → 0.7.0
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 +4 -4
- data/VERSION +1 -1
- data/flydata-core/Gemfile +1 -0
- data/flydata-core/Gemfile.lock +5 -0
- data/flydata-core/lib/flydata-core/errors.rb +4 -2
- data/flydata-core/lib/flydata-core/mysql/binlog_pos.rb +4 -0
- data/flydata-core/lib/flydata-core/postgresql/compatibility_checker.rb +119 -0
- data/flydata-core/lib/flydata-core/postgresql/config.rb +58 -0
- data/flydata-core/lib/flydata-core/postgresql/pg_client.rb +170 -0
- data/flydata-core/lib/flydata-core/postgresql/snapshot.rb +49 -0
- data/flydata-core/lib/flydata-core/postgresql/source_pos.rb +71 -10
- data/flydata-core/lib/flydata-core/table_def/mysql_table_def.rb +1 -1
- data/flydata-core/lib/flydata-core/table_def/postgresql_table_def.rb +76 -17
- data/flydata-core/lib/flydata-core/table_def/redshift_table_def.rb +59 -10
- data/flydata-core/spec/mysql/binlog_pos_spec.rb +10 -2
- data/flydata-core/spec/postgresql/compatibility_checker_spec.rb +148 -0
- data/flydata-core/spec/postgresql/config_spec.rb +85 -0
- data/flydata-core/spec/postgresql/pg_client_spec.rb +195 -0
- data/flydata-core/spec/postgresql/snapshot_spec.rb +55 -0
- data/flydata-core/spec/postgresql/source_pos_spec.rb +70 -8
- data/flydata-core/spec/table_def/postgresql_table_def_spec.rb +80 -19
- data/flydata-core/spec/table_def/redshift_table_def_spec.rb +211 -14
- data/flydata.gemspec +0 -0
- data/lib/flydata.rb +1 -0
- data/lib/flydata/command/sender.rb +10 -7
- data/lib/flydata/command/sync.rb +4 -1
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/base.rb +1 -0
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/fluent_log_ext.rb +73 -0
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync.rb +35 -10
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_diff_based.rb +29 -0
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_query_based.rb +26 -0
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/preference.rb +29 -13
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +10 -18
- data/lib/flydata/fluent-plugins/in_postgresql_query_based_flydata.rb +64 -0
- data/lib/flydata/helpers.rb +1 -3
- data/lib/flydata/plugin_support/context.rb +14 -2
- data/lib/flydata/plugin_support/source_position_file.rb +35 -0
- data/lib/flydata/plugin_support/sync_record_emittable.rb +2 -1
- data/lib/flydata/query_based_sync/client.rb +101 -0
- data/lib/flydata/query_based_sync/record_size_estimator.rb +39 -0
- data/lib/flydata/query_based_sync/resource_requester.rb +70 -0
- data/lib/flydata/query_based_sync/response.rb +122 -0
- data/lib/flydata/query_based_sync/response_handler.rb +30 -0
- data/lib/flydata/source/sync_generate_table_ddl.rb +1 -1
- data/lib/flydata/source_mysql/plugin_support/binlog_record_dispatcher.rb +2 -2
- data/lib/flydata/source_mysql/plugin_support/binlog_record_handler.rb +3 -9
- data/lib/flydata/source_mysql/plugin_support/context.rb +26 -2
- data/lib/flydata/source_mysql/plugin_support/source_position_file.rb +14 -0
- data/lib/flydata/source_mysql/table_ddl.rb +3 -3
- data/lib/flydata/source_mysql/{plugin_support/table_meta.rb → table_meta.rb} +3 -10
- data/lib/flydata/source_postgresql/generate_source_dump.rb +44 -63
- data/lib/flydata/source_postgresql/parse_dump_and_send.rb +2 -0
- data/lib/flydata/source_postgresql/plugin_support/context.rb +13 -0
- data/lib/flydata/source_postgresql/plugin_support/source_position_file.rb +14 -0
- data/lib/flydata/source_postgresql/query_based_sync/client.rb +16 -0
- data/lib/flydata/source_postgresql/query_based_sync/diff_query_generator.rb +135 -0
- data/lib/flydata/source_postgresql/query_based_sync/resource_requester.rb +86 -0
- data/lib/flydata/source_postgresql/query_based_sync/response.rb +12 -0
- data/lib/flydata/source_postgresql/query_based_sync/response_handler.rb +12 -0
- data/lib/flydata/source_postgresql/sync_generate_table_ddl.rb +25 -79
- data/lib/flydata/source_postgresql/table_meta.rb +168 -0
- data/lib/flydata/sync_file_manager.rb +5 -5
- data/lib/flydata/table_meta.rb +19 -0
- data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_context.rb +85 -0
- data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_diff_based_shared_examples.rb +36 -0
- data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_query_based_shared_examples.rb +37 -0
- data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_shared_examples.rb +67 -0
- data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +119 -96
- data/spec/flydata/fluent-plugins/in_postgresql_query_based_flydata_spec.rb +82 -0
- data/spec/flydata/fluent-plugins/sync_source_plugin_context.rb +29 -0
- data/spec/flydata/plugin_support/context_spec.rb +37 -3
- data/spec/flydata/query_based_sync/client_spec.rb +79 -0
- data/spec/flydata/query_based_sync/query_based_sync_context.rb +116 -0
- data/spec/flydata/query_based_sync/record_size_estimator_spec.rb +54 -0
- data/spec/flydata/query_based_sync/resource_requester_spec.rb +58 -0
- data/spec/flydata/query_based_sync/response_handler_spec.rb +36 -0
- data/spec/flydata/query_based_sync/response_spec.rb +157 -0
- data/spec/flydata/source_mysql/plugin_support/context_spec.rb +7 -1
- data/spec/flydata/source_mysql/plugin_support/dml_record_handler_spec.rb +2 -15
- data/spec/flydata/source_mysql/plugin_support/drop_database_query_handler_spec.rb +1 -1
- data/spec/flydata/source_mysql/plugin_support/shared_query_handler_context.rb +12 -11
- data/spec/flydata/source_mysql/plugin_support/source_position_file_spec.rb +53 -0
- data/spec/flydata/source_mysql/plugin_support/truncate_query_handler_spec.rb +1 -1
- data/spec/flydata/source_mysql/table_ddl_spec.rb +5 -5
- data/spec/flydata/source_mysql/{plugin_support/table_meta_spec.rb → table_meta_spec.rb} +6 -7
- data/spec/flydata/source_postgresql/generate_source_dump_spec.rb +165 -77
- data/spec/flydata/source_postgresql/query_based_sync/diff_query_generator_spec.rb +213 -0
- data/spec/flydata/source_postgresql/query_based_sync/query_based_sync_postgresql_context.rb +76 -0
- data/spec/flydata/source_postgresql/query_based_sync/resource_requester_spec.rb +70 -0
- data/spec/flydata/source_postgresql/table_meta_spec.rb +77 -0
- metadata +49 -6
- data/lib/flydata/source_mysql/plugin_support/binlog_position_file.rb +0 -23
- data/lib/flydata/source_postgresql/pg_client.rb +0 -43
|
@@ -267,12 +267,17 @@ EOT
|
|
|
267
267
|
|
|
268
268
|
shared_examples "test column types" do |*examples|
|
|
269
269
|
context 'with varchar column def' do
|
|
270
|
+
let(:default_value) { "something" }
|
|
271
|
+
let(:default_value_sql) { "'#{default_value}'" }
|
|
272
|
+
let(:not_null_default_sql) { " DEFAULT ''" }
|
|
273
|
+
before do
|
|
274
|
+
column[:column] = "col_char"
|
|
275
|
+
column[:type] = "varchar(255)"
|
|
276
|
+
end
|
|
277
|
+
let(:type_sql) { %Q|"col_char" varchar(255)| }
|
|
278
|
+
|
|
270
279
|
context 'when size is smaller than max size' do
|
|
271
|
-
let(:default_value) { "something" }
|
|
272
|
-
let(:default_value_sql) { "'#{default_value}'" }
|
|
273
|
-
let(:not_null_default_sql) { " DEFAULT ''" }
|
|
274
280
|
before do
|
|
275
|
-
column[:column] = "col_char"
|
|
276
281
|
column[:type] = "varchar(18)"
|
|
277
282
|
end
|
|
278
283
|
let(:type_sql) { %Q|"col_char" varchar(18)| }
|
|
@@ -281,11 +286,7 @@ EOT
|
|
|
281
286
|
end
|
|
282
287
|
|
|
283
288
|
context 'when size exceeds varchar max size' do
|
|
284
|
-
let(:default_value) { "something" }
|
|
285
|
-
let(:default_value_sql) { "'#{default_value}'" }
|
|
286
|
-
let(:not_null_default_sql) { " DEFAULT ''" }
|
|
287
289
|
before do
|
|
288
|
-
column[:column] = "col_char"
|
|
289
290
|
column[:type] = "varchar(1000000000)"
|
|
290
291
|
end
|
|
291
292
|
let(:type_sql) { %Q|"col_char" varchar(65535)| }
|
|
@@ -294,17 +295,21 @@ EOT
|
|
|
294
295
|
end
|
|
295
296
|
|
|
296
297
|
context 'when size is max size' do
|
|
297
|
-
let(:default_value) { "something" }
|
|
298
|
-
let(:default_value_sql) { "'#{default_value}'" }
|
|
299
|
-
let(:not_null_default_sql) { " DEFAULT ''" }
|
|
300
298
|
before do
|
|
301
|
-
column[:column] = "col_char"
|
|
302
299
|
column[:type] = "varchar(max)"
|
|
303
300
|
end
|
|
304
301
|
let(:type_sql) { %Q|"col_char" varchar(max)| }
|
|
305
302
|
|
|
306
303
|
it_behaves_like *examples
|
|
307
304
|
end
|
|
305
|
+
|
|
306
|
+
context 'when default_value has PostgreSQL-style type cast' do
|
|
307
|
+
let(:default_value) { "'2014-10-17'::text" }
|
|
308
|
+
let(:default_value_sql) { "'2014-10-17'" }
|
|
309
|
+
|
|
310
|
+
it_behaves_like *examples
|
|
311
|
+
end
|
|
312
|
+
|
|
308
313
|
end
|
|
309
314
|
|
|
310
315
|
context 'with medium blob column def' do
|
|
@@ -335,6 +340,34 @@ EOT
|
|
|
335
340
|
it_behaves_like *examples
|
|
336
341
|
end
|
|
337
342
|
|
|
343
|
+
context 'with boolean column def' do
|
|
344
|
+
context 'with true as column_default' do
|
|
345
|
+
let(:default_value) { true }
|
|
346
|
+
let(:default_value_sql) { "#{default_value.to_s.upcase}" }
|
|
347
|
+
let(:not_null_default_sql) { " DEFAULT FALSE" }
|
|
348
|
+
before do
|
|
349
|
+
column[:column] = "value_boolean"
|
|
350
|
+
column[:type] = "boolean"
|
|
351
|
+
end
|
|
352
|
+
let(:type_sql) { %Q|"value_boolean" boolean| }
|
|
353
|
+
|
|
354
|
+
it_behaves_like *examples
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
context 'with false as column_default' do
|
|
358
|
+
let(:default_value) { false }
|
|
359
|
+
let(:default_value_sql) { "#{default_value.to_s.upcase}" }
|
|
360
|
+
let(:not_null_default_sql) { " DEFAULT FALSE" }
|
|
361
|
+
before do
|
|
362
|
+
column[:column] = "value_boolean"
|
|
363
|
+
column[:type] = "boolean"
|
|
364
|
+
end
|
|
365
|
+
let(:type_sql) { %Q|"value_boolean" boolean| }
|
|
366
|
+
|
|
367
|
+
it_behaves_like *examples
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
338
371
|
context 'with date column def' do
|
|
339
372
|
before do
|
|
340
373
|
column[:column] = "value_date"
|
|
@@ -389,6 +422,39 @@ EOT
|
|
|
389
422
|
end
|
|
390
423
|
end
|
|
391
424
|
|
|
425
|
+
context 'with datetimetz column def' do
|
|
426
|
+
before do
|
|
427
|
+
column[:column] = "value_datetimetz"
|
|
428
|
+
column[:type] = "datetimetz"
|
|
429
|
+
end
|
|
430
|
+
let(:type_sql) { %Q|"value_datetimetz" timestamp| }
|
|
431
|
+
let(:not_null_default_sql) { " DEFAULT '0000-01-01'" }
|
|
432
|
+
|
|
433
|
+
context 'when default_value is normal' do
|
|
434
|
+
let(:default_value) { "'2014-10-17 22:22:22+00'::timestamp with time zone" }
|
|
435
|
+
let(:default_value_sql) { "'2014-10-17 22:22:22.000000'" }
|
|
436
|
+
it_behaves_like *examples
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
context 'when default_value is current_timestamp' do
|
|
440
|
+
let(:default_value) { 'current_timestamp' }
|
|
441
|
+
let(:default_value_sql) { "SYSDATE" }
|
|
442
|
+
it_behaves_like *examples
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
context 'when default_value is now()' do
|
|
446
|
+
let(:default_value) { 'now()' }
|
|
447
|
+
let(:default_value_sql) { "SYSDATE" }
|
|
448
|
+
it_behaves_like *examples
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
context 'when default_value is 0000-00-00 00:00:00-07' do
|
|
452
|
+
let(:default_value) { "'0000-00-00 00:00:00-07'" }
|
|
453
|
+
let(:default_value_sql) { "'0001-01-01 07:00:00.000000'" }
|
|
454
|
+
it_behaves_like *examples
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
|
|
392
458
|
context 'with decimal column def' do
|
|
393
459
|
context 'when precision exceeds max allowed' do
|
|
394
460
|
let(:default_value) { "'4'" }
|
|
@@ -402,19 +468,33 @@ EOT
|
|
|
402
468
|
|
|
403
469
|
it_behaves_like *examples
|
|
404
470
|
end
|
|
405
|
-
context 'when scale exceeds max allowed' do #
|
|
471
|
+
context 'when scale exceeds max allowed' do #possible in postgresql
|
|
406
472
|
let(:default_value) { "'4'" }
|
|
407
473
|
let(:default_value_sql) { default_value }
|
|
408
474
|
let(:not_null_default_sql) { " DEFAULT '0'" }
|
|
409
475
|
before do
|
|
410
476
|
column[:column] = "value"
|
|
411
|
-
column[:type] = "numeric(
|
|
477
|
+
column[:type] = "numeric(100,44)"
|
|
412
478
|
end
|
|
479
|
+
#this column accepts only 1 digit above decimal point. Other values such as 10 cause DDE.
|
|
413
480
|
let(:type_sql) { %Q|"value" numeric(38,37)| }
|
|
414
481
|
|
|
415
482
|
it_behaves_like *examples
|
|
416
483
|
end
|
|
417
484
|
|
|
485
|
+
context 'when precision and scale are not given' do #possible in postgresql
|
|
486
|
+
let(:default_value) { "'4'" }
|
|
487
|
+
let(:default_value_sql) { default_value }
|
|
488
|
+
let(:not_null_default_sql) { " DEFAULT '0'" }
|
|
489
|
+
before do
|
|
490
|
+
column[:column] = "value"
|
|
491
|
+
column[:type] = "numeric"
|
|
492
|
+
end
|
|
493
|
+
let(:type_sql) { %Q|"value" numeric(18,8)| }
|
|
494
|
+
|
|
495
|
+
it_behaves_like *examples
|
|
496
|
+
end
|
|
497
|
+
|
|
418
498
|
context 'when precision and scale exceeds max allowed (for unsigned)' do
|
|
419
499
|
let(:default_value) { "'4'" }
|
|
420
500
|
let(:default_value_sql) { default_value }
|
|
@@ -462,6 +542,18 @@ EOT
|
|
|
462
542
|
it_behaves_like *examples
|
|
463
543
|
end
|
|
464
544
|
|
|
545
|
+
context 'when default_value uses the capital B prefix' do
|
|
546
|
+
let(:default_value) { "B'1'" }
|
|
547
|
+
let(:default_value_sql) { "1" }
|
|
548
|
+
it_behaves_like *examples
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
context 'when default_value has a type cast' do
|
|
552
|
+
let(:default_value) { %Q|B'1'::"bit"| }
|
|
553
|
+
let(:default_value_sql) { "1" }
|
|
554
|
+
it_behaves_like *examples
|
|
555
|
+
end
|
|
556
|
+
|
|
465
557
|
# it's not real case
|
|
466
558
|
context "when default_value is x'' format" do
|
|
467
559
|
let(:default_value) { "x'12'" }
|
|
@@ -488,6 +580,40 @@ EOT
|
|
|
488
580
|
end
|
|
489
581
|
end
|
|
490
582
|
|
|
583
|
+
context 'with timetz column def' do
|
|
584
|
+
before do
|
|
585
|
+
column[:column] = "value_timetz"
|
|
586
|
+
column[:type] = "timetz"
|
|
587
|
+
end
|
|
588
|
+
let(:type_sql) { %Q|"value_timetz" timestamp| }
|
|
589
|
+
let(:not_null_default_sql) { " DEFAULT '0000-01-01'" }
|
|
590
|
+
|
|
591
|
+
context 'when default_value is normal' do
|
|
592
|
+
let(:default_value) { "'22:22:22+00'::time with time zone" }
|
|
593
|
+
let(:default_value_sql) { "'0001-01-01 22:22:22.000000'" }
|
|
594
|
+
it_behaves_like *examples
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
context 'when default_value is current_time' do
|
|
598
|
+
let(:default_value) { 'current_time' }
|
|
599
|
+
let(:default_value_sql) { "SYSDATE" }
|
|
600
|
+
it_behaves_like *examples
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
context 'when default_value is 00:00:00-07' do
|
|
604
|
+
let(:default_value) { "'00:00:00-07'" }
|
|
605
|
+
let(:default_value_sql) { "'0001-01-01 07:00:00.000000'" }
|
|
606
|
+
it_behaves_like *examples
|
|
607
|
+
end
|
|
608
|
+
|
|
609
|
+
context 'when default_value is 00:00:00+07' do
|
|
610
|
+
let(:default_value) { "'00:00:00+07'" }
|
|
611
|
+
# Per ISO 8601, year 0000 is year 1 BC
|
|
612
|
+
let(:default_value_sql) { "'0000-12-31 17:00:00.000000'" }
|
|
613
|
+
it_behaves_like *examples
|
|
614
|
+
end
|
|
615
|
+
end
|
|
616
|
+
|
|
491
617
|
context 'with year column def' do
|
|
492
618
|
before do
|
|
493
619
|
column[:column] = "value_year"
|
|
@@ -531,6 +657,52 @@ EOT
|
|
|
531
657
|
end
|
|
532
658
|
end
|
|
533
659
|
end
|
|
660
|
+
context 'with money column def' do
|
|
661
|
+
before do
|
|
662
|
+
column[:column] = "value_money"
|
|
663
|
+
column[:type] = "money(19,2)"
|
|
664
|
+
end
|
|
665
|
+
let(:type_sql) { %Q|"value_money" numeric(19,2)| }
|
|
666
|
+
let(:not_null_default_sql) { " DEFAULT '0'" }
|
|
667
|
+
|
|
668
|
+
context 'when default_value is normal' do
|
|
669
|
+
let(:default_value) { "'10.40'" }
|
|
670
|
+
let(:default_value_sql) { "'10.40'" }
|
|
671
|
+
it_behaves_like *examples
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
context 'when default_value is in a monetary format' do
|
|
675
|
+
let(:default_value) { "'$1,430.00'" }
|
|
676
|
+
let(:default_value_sql) { "'1430.00'" }
|
|
677
|
+
it_behaves_like *examples
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
context 'when default_value is in Japanese yen' do
|
|
681
|
+
let(:default_value) { "'143,000 yen'" }
|
|
682
|
+
let(:default_value_sql) { "'143000'" }
|
|
683
|
+
it_behaves_like *examples
|
|
684
|
+
end
|
|
685
|
+
end
|
|
686
|
+
context 'with unsupported column def' do
|
|
687
|
+
before do
|
|
688
|
+
column[:column] = "value_unsupported"
|
|
689
|
+
column[:type] = "_unsupported"
|
|
690
|
+
end
|
|
691
|
+
let(:type_sql) { %Q|"value_unsupported" varchar(max)| }
|
|
692
|
+
let(:not_null_default_sql) { " DEFAULT ''" }
|
|
693
|
+
|
|
694
|
+
context 'when default_value is normal' do
|
|
695
|
+
let(:default_value) { "'happy'" }
|
|
696
|
+
let(:default_value_sql) { "'happy'" }
|
|
697
|
+
it_behaves_like *examples
|
|
698
|
+
end
|
|
699
|
+
|
|
700
|
+
context 'when default value has a PostgreSQL-style type cast' do
|
|
701
|
+
let(:default_value) { "'ok'::mood" }
|
|
702
|
+
let(:default_value_sql) { "'ok'" }
|
|
703
|
+
it_behaves_like *examples
|
|
704
|
+
end
|
|
705
|
+
end
|
|
534
706
|
end
|
|
535
707
|
|
|
536
708
|
context 'for create table' do
|
|
@@ -684,6 +856,16 @@ EOS
|
|
|
684
856
|
let(:value) { '2012-1-23 10:40:5.243 +0230' }
|
|
685
857
|
it { is_expected.to eq('2012-01-23 08:10:05.243000') }
|
|
686
858
|
end
|
|
859
|
+
|
|
860
|
+
context 'with colon separated timezone value' do
|
|
861
|
+
let(:value) { '2012-01-23 19:20:15 +01:00' }
|
|
862
|
+
it { is_expected.to eq('2012-01-23 18:20:15.000000') }
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
context 'without space before imezone value' do
|
|
866
|
+
let(:value) { '2012-01-23 19:20:15+01:00' }
|
|
867
|
+
it { is_expected.to eq('2012-01-23 18:20:15.000000') }
|
|
868
|
+
end
|
|
687
869
|
end
|
|
688
870
|
|
|
689
871
|
context 'with unix epoch time' do
|
|
@@ -779,6 +961,21 @@ EOS
|
|
|
779
961
|
it { is_expected.to eq('0000-12-31 20:58:35.876543') } # floating-point arithmetic(only negative value)
|
|
780
962
|
end
|
|
781
963
|
end
|
|
964
|
+
|
|
965
|
+
context 'when value has timezone' do
|
|
966
|
+
context 'with no-colon timezone value' do
|
|
967
|
+
let(:value) { '13:01:24 +0800' }
|
|
968
|
+
it { is_expected.to eq('0001-01-01 05:01:24.000000') }
|
|
969
|
+
end
|
|
970
|
+
context 'with colon separated timezone value' do
|
|
971
|
+
let(:value) { '13:01:24 -08:00' }
|
|
972
|
+
it { is_expected.to eq('0001-01-01 21:01:24.000000') }
|
|
973
|
+
end
|
|
974
|
+
context 'with a timezone whose corresponding UTC goes negative' do
|
|
975
|
+
let(:value) { '03:01:24 +0800' }
|
|
976
|
+
it { is_expected.to eq('0000-12-31 19:01:24.000000') }
|
|
977
|
+
end
|
|
978
|
+
end
|
|
782
979
|
end
|
|
783
980
|
|
|
784
981
|
context 'with nil value' do
|
data/flydata.gemspec
CHANGED
|
Binary file
|
data/lib/flydata.rb
CHANGED
|
@@ -21,6 +21,7 @@ require 'flydata/heroku'
|
|
|
21
21
|
module Flydata
|
|
22
22
|
FLYDATA_DEBUG = !!(ENV['FLYDATA_DEBUG'])
|
|
23
23
|
FLYDATA_HOME = ENV['FLYDATA_HOME'] || "#{ENV['HOME']}/.flydata"
|
|
24
|
+
FLYDATA_TABLE_POSITIONS_DIR = ENV['FLYDATA_TABLE_POSITIONS'] || File.join(FLYDATA_HOME, 'positions')
|
|
24
25
|
FLYDATA_GEM_HOME = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
25
26
|
FLYDATA_GEM_BIN = File.join(FLYDATA_GEM_HOME, 'bin')
|
|
26
27
|
FLYDATA_TMPL_DIR = File.join(FLYDATA_GEM_HOME, 'tmpl')
|
|
@@ -66,7 +66,7 @@ module Flydata
|
|
|
66
66
|
start_fluentd.call unless fluentd_started
|
|
67
67
|
if options[:show_final_message] && !options[:quiet]
|
|
68
68
|
data_port = flydata.data_port.get
|
|
69
|
-
log_info_stdout("Go to your Dashboard! #{flydata.flydata_api_host}/
|
|
69
|
+
log_info_stdout("Go to your Dashboard! #{flydata.flydata_api_host}/dashboard")
|
|
70
70
|
log_info_stdout <<EOF
|
|
71
71
|
Please Note: Records and Total Size are updated every 10-20 minutes.
|
|
72
72
|
EOF
|
|
@@ -83,7 +83,7 @@ EOF
|
|
|
83
83
|
log_info_stdout('Done.') unless options[:quiet]
|
|
84
84
|
return true
|
|
85
85
|
end
|
|
86
|
-
raise '
|
|
86
|
+
raise 'Failed to stop sender process.'
|
|
87
87
|
end
|
|
88
88
|
def flush_client_buffer(options = {})
|
|
89
89
|
force_flush = options.has_key?(:force) ? options[:force] : true
|
|
@@ -103,7 +103,7 @@ EOF
|
|
|
103
103
|
Kernel.sleep 5
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
-
raise '
|
|
106
|
+
raise 'Unable to flush client buffer'
|
|
107
107
|
end
|
|
108
108
|
def restart(options = {})
|
|
109
109
|
if process_exist?
|
|
@@ -111,7 +111,7 @@ EOF
|
|
|
111
111
|
begin
|
|
112
112
|
stop(options)
|
|
113
113
|
rescue => e
|
|
114
|
-
log_warn_stderr "
|
|
114
|
+
log_warn_stderr "Force stopping the FlyData process. error:#{e.to_s}"
|
|
115
115
|
kill_all(options)
|
|
116
116
|
end
|
|
117
117
|
else
|
|
@@ -136,7 +136,7 @@ EOF
|
|
|
136
136
|
log_info_stdout("Done.") unless options[:quiet]
|
|
137
137
|
return true
|
|
138
138
|
else
|
|
139
|
-
raise '
|
|
139
|
+
raise 'Could not terminate FlyData process.'
|
|
140
140
|
end
|
|
141
141
|
end
|
|
142
142
|
# call the method only when no legit process is running.
|
|
@@ -217,7 +217,7 @@ EOF
|
|
|
217
217
|
log_info_stdout("Waiting logs uploading... (#{i}/#{retry_count})") unless options[:quiet]
|
|
218
218
|
Kernel.sleep 30
|
|
219
219
|
end
|
|
220
|
-
raise 'Cannot confirm that your logs exist on the FlyData server.
|
|
220
|
+
raise 'Cannot confirm that your logs exist on the FlyData server.'
|
|
221
221
|
end
|
|
222
222
|
|
|
223
223
|
def server_ready?
|
|
@@ -238,8 +238,11 @@ EOF
|
|
|
238
238
|
def client_buffer_empty?(options = {})
|
|
239
239
|
client_buffer = File.join(FLYDATA_HOME, 'buffer')
|
|
240
240
|
log_info_stdout("Checking the client buffer #{client_buffer}") unless options[:quiet]
|
|
241
|
-
Dir.glob("#{client_buffer}/*")
|
|
241
|
+
buffer_files = Dir.glob("#{client_buffer}/*")
|
|
242
|
+
#there can be empty buffer files
|
|
243
|
+
buffer_files.empty? || buffer_files.all? {|f| File.stat(f).size == 0 }
|
|
242
244
|
end
|
|
245
|
+
|
|
243
246
|
def pid_file
|
|
244
247
|
"#{FLYDATA_HOME}/flydata.pid"
|
|
245
248
|
end
|
data/lib/flydata/command/sync.rb
CHANGED
|
@@ -241,6 +241,7 @@ EOS
|
|
|
241
241
|
on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
|
|
242
242
|
on 's', 'skip-primary-key-check', 'Skip primary key check when generating DDL'
|
|
243
243
|
on 'all-tables', 'Generate all table schema'
|
|
244
|
+
on 'drop-append-only', 'Include queries to drop append-only tables'
|
|
244
245
|
#no 'force-run' option. because stdout is often redirected to a file.
|
|
245
246
|
end
|
|
246
247
|
end
|
|
@@ -1169,7 +1170,9 @@ EOM
|
|
|
1169
1170
|
create_flydata_ctl_table = true
|
|
1170
1171
|
append_only = tables & @append_only_tables
|
|
1171
1172
|
flydata_tabledefs.each do |flydata_tabledef|
|
|
1172
|
-
|
|
1173
|
+
skip_drop_table = opts.drop_append_only? ? false : append_only.include?(flydata_tabledef[:table_name])
|
|
1174
|
+
puts FlydataCore::TableDef::SyncRedshiftTableDef.from_flydata_tabledef(flydata_tabledef,
|
|
1175
|
+
flydata_ctl_table: create_flydata_ctl_table, schema_name: schema_name, ctl_only: opts.ctl_only?, skip_drop_table: skip_drop_table)
|
|
1173
1176
|
create_flydata_ctl_table = false
|
|
1174
1177
|
end
|
|
1175
1178
|
table_validity_hash = {}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module Fluent
|
|
2
|
+
|
|
3
|
+
# 1. patch to avoid writing the configuration dump
|
|
4
|
+
# until suppress config dump option will be supported.
|
|
5
|
+
# https://github.com/fluent/fluentd/pull/186
|
|
6
|
+
# 2. patch to support custom depth_offset
|
|
7
|
+
class Log
|
|
8
|
+
# This is used for checking if patched
|
|
9
|
+
# flydata-core/logger.rb uses this
|
|
10
|
+
attr_accessor :flydata_patched
|
|
11
|
+
|
|
12
|
+
def trace(*args, &block)
|
|
13
|
+
return if @level > LEVEL_TRACE
|
|
14
|
+
args << block.call if block
|
|
15
|
+
depth_offset = extract_depth_offset(args)
|
|
16
|
+
time, msg = event(:trace, args)
|
|
17
|
+
puts [@color_trace, caller_line(time, depth_offset, LEVEL_TRACE), msg, @color_reset].join
|
|
18
|
+
rescue
|
|
19
|
+
# logger should not raise an exception. This rescue prevents unexpected behaviour.
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def debug(*args, &block)
|
|
23
|
+
return if @level > LEVEL_DEBUG
|
|
24
|
+
args << block.call if block
|
|
25
|
+
depth_offset = extract_depth_offset(args)
|
|
26
|
+
time, msg = event(:debug, args)
|
|
27
|
+
puts [@color_debug, caller_line(time, depth_offset, LEVEL_DEBUG), msg, @color_reset].join
|
|
28
|
+
rescue
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def warn(*args, &block)
|
|
32
|
+
return if @level > LEVEL_WARN
|
|
33
|
+
args << block.call if block
|
|
34
|
+
depth_offset = extract_depth_offset(args)
|
|
35
|
+
time, msg = event(:warn, args)
|
|
36
|
+
if msg and m = /^parameter '(?<param>[^']+)' in/.match(msg.strip)
|
|
37
|
+
msg = "parameter '#{m[:param]}' is not used."
|
|
38
|
+
end
|
|
39
|
+
puts [@color_warn, caller_line(time, depth_offset, LEVEL_WARN), msg, @color_reset].join
|
|
40
|
+
rescue
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def info(*args, &block)
|
|
44
|
+
return if @level > LEVEL_INFO
|
|
45
|
+
args << block.call if block
|
|
46
|
+
depth_offset = extract_depth_offset(args)
|
|
47
|
+
time, msg = event(:info, args)
|
|
48
|
+
puts [@color_info, caller_line(time, depth_offset, LEVEL_INFO), msg, @color_reset].join
|
|
49
|
+
rescue
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def error(*args, &block)
|
|
53
|
+
return if @level > LEVEL_ERROR
|
|
54
|
+
args << block.call if block
|
|
55
|
+
depth_offset = extract_depth_offset(args)
|
|
56
|
+
time, msg = event(:error, args)
|
|
57
|
+
puts [@color_error, caller_line(time, depth_offset, LEVEL_ERROR), msg, @color_reset].join
|
|
58
|
+
rescue
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def extract_depth_offset(args)
|
|
64
|
+
opt = args.last
|
|
65
|
+
if opt.kind_of?(Hash) and opt[:depth_offset].kind_of?(Integer)
|
|
66
|
+
return opt.delete(:depth_offset)
|
|
67
|
+
end
|
|
68
|
+
@depth_offset
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
|
73
|
+
|