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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/flydata-core/Gemfile +1 -0
  4. data/flydata-core/Gemfile.lock +5 -0
  5. data/flydata-core/lib/flydata-core/errors.rb +4 -2
  6. data/flydata-core/lib/flydata-core/mysql/binlog_pos.rb +4 -0
  7. data/flydata-core/lib/flydata-core/postgresql/compatibility_checker.rb +119 -0
  8. data/flydata-core/lib/flydata-core/postgresql/config.rb +58 -0
  9. data/flydata-core/lib/flydata-core/postgresql/pg_client.rb +170 -0
  10. data/flydata-core/lib/flydata-core/postgresql/snapshot.rb +49 -0
  11. data/flydata-core/lib/flydata-core/postgresql/source_pos.rb +71 -10
  12. data/flydata-core/lib/flydata-core/table_def/mysql_table_def.rb +1 -1
  13. data/flydata-core/lib/flydata-core/table_def/postgresql_table_def.rb +76 -17
  14. data/flydata-core/lib/flydata-core/table_def/redshift_table_def.rb +59 -10
  15. data/flydata-core/spec/mysql/binlog_pos_spec.rb +10 -2
  16. data/flydata-core/spec/postgresql/compatibility_checker_spec.rb +148 -0
  17. data/flydata-core/spec/postgresql/config_spec.rb +85 -0
  18. data/flydata-core/spec/postgresql/pg_client_spec.rb +195 -0
  19. data/flydata-core/spec/postgresql/snapshot_spec.rb +55 -0
  20. data/flydata-core/spec/postgresql/source_pos_spec.rb +70 -8
  21. data/flydata-core/spec/table_def/postgresql_table_def_spec.rb +80 -19
  22. data/flydata-core/spec/table_def/redshift_table_def_spec.rb +211 -14
  23. data/flydata.gemspec +0 -0
  24. data/lib/flydata.rb +1 -0
  25. data/lib/flydata/command/sender.rb +10 -7
  26. data/lib/flydata/command/sync.rb +4 -1
  27. data/lib/flydata/fluent-plugins/flydata_plugin_ext/base.rb +1 -0
  28. data/lib/flydata/fluent-plugins/flydata_plugin_ext/fluent_log_ext.rb +73 -0
  29. data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync.rb +35 -10
  30. data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_diff_based.rb +29 -0
  31. data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_query_based.rb +26 -0
  32. data/lib/flydata/fluent-plugins/flydata_plugin_ext/preference.rb +29 -13
  33. data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +10 -18
  34. data/lib/flydata/fluent-plugins/in_postgresql_query_based_flydata.rb +64 -0
  35. data/lib/flydata/helpers.rb +1 -3
  36. data/lib/flydata/plugin_support/context.rb +14 -2
  37. data/lib/flydata/plugin_support/source_position_file.rb +35 -0
  38. data/lib/flydata/plugin_support/sync_record_emittable.rb +2 -1
  39. data/lib/flydata/query_based_sync/client.rb +101 -0
  40. data/lib/flydata/query_based_sync/record_size_estimator.rb +39 -0
  41. data/lib/flydata/query_based_sync/resource_requester.rb +70 -0
  42. data/lib/flydata/query_based_sync/response.rb +122 -0
  43. data/lib/flydata/query_based_sync/response_handler.rb +30 -0
  44. data/lib/flydata/source/sync_generate_table_ddl.rb +1 -1
  45. data/lib/flydata/source_mysql/plugin_support/binlog_record_dispatcher.rb +2 -2
  46. data/lib/flydata/source_mysql/plugin_support/binlog_record_handler.rb +3 -9
  47. data/lib/flydata/source_mysql/plugin_support/context.rb +26 -2
  48. data/lib/flydata/source_mysql/plugin_support/source_position_file.rb +14 -0
  49. data/lib/flydata/source_mysql/table_ddl.rb +3 -3
  50. data/lib/flydata/source_mysql/{plugin_support/table_meta.rb → table_meta.rb} +3 -10
  51. data/lib/flydata/source_postgresql/generate_source_dump.rb +44 -63
  52. data/lib/flydata/source_postgresql/parse_dump_and_send.rb +2 -0
  53. data/lib/flydata/source_postgresql/plugin_support/context.rb +13 -0
  54. data/lib/flydata/source_postgresql/plugin_support/source_position_file.rb +14 -0
  55. data/lib/flydata/source_postgresql/query_based_sync/client.rb +16 -0
  56. data/lib/flydata/source_postgresql/query_based_sync/diff_query_generator.rb +135 -0
  57. data/lib/flydata/source_postgresql/query_based_sync/resource_requester.rb +86 -0
  58. data/lib/flydata/source_postgresql/query_based_sync/response.rb +12 -0
  59. data/lib/flydata/source_postgresql/query_based_sync/response_handler.rb +12 -0
  60. data/lib/flydata/source_postgresql/sync_generate_table_ddl.rb +25 -79
  61. data/lib/flydata/source_postgresql/table_meta.rb +168 -0
  62. data/lib/flydata/sync_file_manager.rb +5 -5
  63. data/lib/flydata/table_meta.rb +19 -0
  64. data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_context.rb +85 -0
  65. data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_diff_based_shared_examples.rb +36 -0
  66. data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_query_based_shared_examples.rb +37 -0
  67. data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_shared_examples.rb +67 -0
  68. data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +119 -96
  69. data/spec/flydata/fluent-plugins/in_postgresql_query_based_flydata_spec.rb +82 -0
  70. data/spec/flydata/fluent-plugins/sync_source_plugin_context.rb +29 -0
  71. data/spec/flydata/plugin_support/context_spec.rb +37 -3
  72. data/spec/flydata/query_based_sync/client_spec.rb +79 -0
  73. data/spec/flydata/query_based_sync/query_based_sync_context.rb +116 -0
  74. data/spec/flydata/query_based_sync/record_size_estimator_spec.rb +54 -0
  75. data/spec/flydata/query_based_sync/resource_requester_spec.rb +58 -0
  76. data/spec/flydata/query_based_sync/response_handler_spec.rb +36 -0
  77. data/spec/flydata/query_based_sync/response_spec.rb +157 -0
  78. data/spec/flydata/source_mysql/plugin_support/context_spec.rb +7 -1
  79. data/spec/flydata/source_mysql/plugin_support/dml_record_handler_spec.rb +2 -15
  80. data/spec/flydata/source_mysql/plugin_support/drop_database_query_handler_spec.rb +1 -1
  81. data/spec/flydata/source_mysql/plugin_support/shared_query_handler_context.rb +12 -11
  82. data/spec/flydata/source_mysql/plugin_support/source_position_file_spec.rb +53 -0
  83. data/spec/flydata/source_mysql/plugin_support/truncate_query_handler_spec.rb +1 -1
  84. data/spec/flydata/source_mysql/table_ddl_spec.rb +5 -5
  85. data/spec/flydata/source_mysql/{plugin_support/table_meta_spec.rb → table_meta_spec.rb} +6 -7
  86. data/spec/flydata/source_postgresql/generate_source_dump_spec.rb +165 -77
  87. data/spec/flydata/source_postgresql/query_based_sync/diff_query_generator_spec.rb +213 -0
  88. data/spec/flydata/source_postgresql/query_based_sync/query_based_sync_postgresql_context.rb +76 -0
  89. data/spec/flydata/source_postgresql/query_based_sync/resource_requester_spec.rb +70 -0
  90. data/spec/flydata/source_postgresql/table_meta_spec.rb +77 -0
  91. metadata +49 -6
  92. data/lib/flydata/source_mysql/plugin_support/binlog_position_file.rb +0 -23
  93. data/lib/flydata/source_postgresql/pg_client.rb +0 -43
@@ -0,0 +1,213 @@
1
+ require 'spec_helper'
2
+ require 'flydata/source_postgresql/query_based_sync/diff_query_generator'
3
+
4
+ module Flydata
5
+ module SourcePostgresql
6
+ module QueryBasedSync
7
+
8
+ describe DiffQueryGenerator do
9
+ let(:table) { 'test_table' }
10
+ let(:schema) { 'public' }
11
+ let(:from_sid) { '0001:0001:' }
12
+ let(:to_sid) { '0002:0002:' }
13
+ let(:columns) { [
14
+ { column: 'id', type: 'int4' },
15
+ { column: 'value', type: value_data_type},
16
+ ] }
17
+ let(:value_data_type) { 'varchar(48)' }
18
+ let(:last_pks) { ['1000'] }
19
+ let(:pk_columns) { ['id'] }
20
+ let(:limit) { 100 }
21
+ let(:query_cond) { {
22
+ from_sid: from_sid,
23
+ to_sid: to_sid,
24
+ columns: columns,
25
+ pk_columns: pk_columns,
26
+ last_pks: last_pks,
27
+ limit: limit,
28
+ } }
29
+ let(:subject_object) { described_class.new(table, schema, query_cond) }
30
+
31
+ describe '#initialize' do
32
+ subject { subject_object }
33
+ context 'when no required option is missing' do
34
+ it { expect{subject}.not_to raise_error }
35
+ end
36
+
37
+ context 'when to_sid is missing' do
38
+ before { query_cond.delete(:to_sid) }
39
+ it { expect{subject}.to raise_error(ArgumentError, /to_sid is required/) }
40
+ end
41
+
42
+ context 'when pk_columns is missing' do
43
+ before { query_cond.delete(:pk_columns) }
44
+ it { expect{subject}.to raise_error(ArgumentError, /pk_columns is required/) }
45
+ end
46
+
47
+ context 'when columns is missing' do
48
+ before { query_cond.delete(:columns) }
49
+ it { expect{subject}.to raise_error(ArgumentError, /columns is required/) }
50
+ end
51
+ end
52
+
53
+ describe '#build_query' do
54
+ let(:binding_param_enabled) { true }
55
+ subject { subject_object.build_query(binding_param_enabled) }
56
+
57
+ context 'when all options are given' do
58
+ it { is_expected.to eq(<<EOS)
59
+ SELECT "id", "value" FROM "public"."test_table" WHERE txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0002:0002:') AND NOT txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0001:0001:') AND ("id" > $1) ORDER BY "id" LIMIT 100;
60
+ EOS
61
+ }
62
+ end
63
+
64
+ context 'when schema is not given' do
65
+ let(:schema) { nil }
66
+ it { is_expected.to eq(<<EOS)
67
+ SELECT "id", "value" FROM "test_table" WHERE txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0002:0002:') AND NOT txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0001:0001:') AND ("id" > $1) ORDER BY "id" LIMIT 100;
68
+ EOS
69
+ }
70
+ end
71
+
72
+ context 'when columns includes a money type' do
73
+ let(:value_data_type) { 'money(19,2)' }
74
+ it 'returns money values as numeric' do
75
+ is_expected.to eq(<<EOS)
76
+ SELECT "id", "value"::numeric FROM "public"."test_table" WHERE txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0002:0002:') AND NOT txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0001:0001:') AND ("id" > $1) ORDER BY "id" LIMIT 100;
77
+ EOS
78
+ end
79
+ end
80
+
81
+ context 'when columns includes a bit type' do
82
+ let(:value_data_type) { 'bit(4)' }
83
+ it 'returns a query with an overrider proc for bit' do
84
+ result = subject
85
+ expect(result).to eq(<<EOS)
86
+ SELECT "id", "value" FROM "public"."test_table" WHERE txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0002:0002:') AND NOT txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0001:0001:') AND ("id" > $1) ORDER BY "id" LIMIT 100;
87
+ EOS
88
+ expect(result.value_overriders).to eq({"value" => DiffQueryGenerator::VALUE_OVERRIDERS['bit']})
89
+ end
90
+ end
91
+
92
+ context 'when columns includes a varbit type' do
93
+ let(:value_data_type) { 'varbit' }
94
+ it 'returns a query with an overrider proc for varbit' do
95
+ result = subject
96
+ expect(result).to eq(<<EOS)
97
+ SELECT "id", "value" FROM "public"."test_table" WHERE txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0002:0002:') AND NOT txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0001:0001:') AND ("id" > $1) ORDER BY "id" LIMIT 100;
98
+ EOS
99
+ expect(result.value_overriders).to eq({"value" => DiffQueryGenerator::VALUE_OVERRIDERS['varbit']})
100
+ end
101
+ end
102
+
103
+ context 'when from_sid is not given' do
104
+ let(:from_sid) { nil }
105
+ it { is_expected.to eq(<<EOS)
106
+ SELECT "id", "value" FROM "public"."test_table" WHERE txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0002:0002:') AND ("id" > $1) ORDER BY "id" LIMIT 100;
107
+ EOS
108
+ }
109
+ end
110
+
111
+ context 'when binding_param_enabled is false' do
112
+ let(:binding_param_enabled) { false }
113
+ it { is_expected.to eq(<<EOS)
114
+ SELECT "id", "value" FROM "public"."test_table" WHERE txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0002:0002:') AND NOT txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0001:0001:') AND ("id" > '1000') ORDER BY "id" LIMIT 100;
115
+ EOS
116
+ }
117
+ it { expect(subject.binding_params).to be_nil }
118
+ end
119
+
120
+ context 'when binding_param_enabled is true ' do
121
+ let(:binding_param_enabled) { true }
122
+ it { is_expected.to eq(<<EOS)
123
+ SELECT "id", "value" FROM "public"."test_table" WHERE txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0002:0002:') AND NOT txid_visible_in_snapshot(xmin::TEXT::BIGINT, '0001:0001:') AND ("id" > $1) ORDER BY "id" LIMIT 100;
124
+ EOS
125
+ }
126
+ it { expect(subject.binding_params).to eq(last_pks)}
127
+ end
128
+ end
129
+
130
+ describe 'VALUE_OVERRIDERS' do
131
+ subject { DiffQueryGenerator::VALUE_OVERRIDERS[type].call(value) }
132
+
133
+ context 'when type is bit' do
134
+ let(:type) { 'bit' }
135
+ let(:value) { '0110000010' }
136
+ it { is_expected.to eq '386' }
137
+ end
138
+
139
+ context 'when type is varbit' do
140
+ let(:type) { 'varbit' }
141
+ let(:value) { '1111111111111111111111111111111111111111111111111111111111111101' }
142
+
143
+ it { is_expected.to eq "18446744073709551613" }
144
+ end
145
+
146
+ context 'when value is nil' do
147
+ let(:type) { 'bit' }
148
+ let(:value) { nil }
149
+ it { is_expected.to eq nil }
150
+ end
151
+ end
152
+
153
+ describe '#pk_conditions' do
154
+ let(:binding_param_enabled) { true }
155
+ subject { subject_object.send(:pk_conditions, pk_columns, last_pks, binding_param_enabled) }
156
+
157
+ context 'with a single primary key' do
158
+ let(:pk_columns) { [ 'id' ] }
159
+
160
+ it { is_expected.to eq %Q| AND ("id" > $1)| }
161
+ end
162
+
163
+ context 'with two primary keys' do
164
+ let(:pk_columns) { [ 'pk1', 'pk2' ] }
165
+
166
+ it { is_expected.to eq %Q| AND ("pk1" > $1 OR ("pk1" = $1 AND ("pk2" > $2)))| }
167
+ end
168
+ context 'with three primary keys' do
169
+ let(:pk_columns) { [ 'pk1', 'pk2', 'pk3' ] }
170
+
171
+ it { is_expected.to eq %Q| AND ("pk1" > $1 OR ("pk1" = $1 AND ("pk2" > $2 OR ("pk2" = $2 AND ("pk3" > $3)))))| }
172
+ end
173
+
174
+ context 'with binding_param_enabled option' do
175
+ let(:pk_columns) { [ 'pk1', 'pk2', 'pk3' ] }
176
+ let(:last_pks) { [ 1000, 2000, 'apple' ] }
177
+ let(:binding_param_enabled) { false }
178
+ it { is_expected.to eq %Q| AND ("pk1" > '1000' OR ("pk1" = '1000' AND ("pk2" > '2000' OR ("pk2" = '2000' AND ("pk3" > 'apple')))))| }
179
+ end
180
+ end
181
+
182
+ describe '#column_list' do
183
+ subject { subject_object.send(:column_list, columns, types) }
184
+
185
+ let(:columns) { [ 'id', 'value' ] }
186
+ let(:types) { [ 'int4', value_data_type ] }
187
+ let(:value_data_type) { 'varchar' }
188
+
189
+ context 'an ordinary case' do
190
+ it 'builds a column list string off of the given columns' do
191
+ is_expected.to eq %Q["id", "value"]
192
+ end
193
+ end
194
+
195
+ context 'with a binary column' do
196
+ let(:value_data_type) { 'bytea' } # FlyData data type not PostgreSQL
197
+ it 'generates a list which outputs binary values in the FlyData binary format' do
198
+ is_expected.to eq %Q["id", '0x' || encode("value", 'hex') AS "value"]
199
+ end
200
+ end
201
+
202
+ context 'with a money column' do
203
+ let(:value_data_type) { 'money' }
204
+ it 'generates a list which outputs money values as numeric' do
205
+ is_expected.to eq %Q["id", "value"::numeric]
206
+ end
207
+ end
208
+ end
209
+ end
210
+
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ require 'flydata-core/postgresql/snapshot'
3
+ require 'flydata/source_postgresql/plugin_support/context'
4
+ require 'flydata/source_postgresql/plugin_support/source_position_file'
5
+ require 'flydata/query_based_sync/query_based_sync_context'
6
+
7
+ module Flydata
8
+ module SourcePostgresql
9
+ module QueryBasedSync
10
+
11
+ shared_context 'query based sync postgresql context' do
12
+ include_context 'query based sync context'
13
+
14
+ def create_src_pos_file(fp, snapshot, to_snapshot=nil, pk_values=nil)
15
+ spf = Flydata::SourcePostgresql::PluginSupport::SourcePositionFile.new(fp)
16
+ spf.save(snapshot, to_snapshot, pk_values)
17
+ spf
18
+ end
19
+
20
+ def create_ss(snapshot_txt)
21
+ FlydataCore::Postgresql::Snapshot.new(snapshot_txt)
22
+ end
23
+
24
+ let(:previous_snapshot) { create_ss('1010:1010:') }
25
+ let(:current_snapshot) { create_ss('1020:1020:') }
26
+ let(:cur_src_pos_file_path) { "test_position.binlog.pos" }
27
+ let(:cur_src_pos_file) { create_src_pos_file(cur_src_pos_file_path, previous_snapshot) }
28
+
29
+ let(:table_1_src_pos_file_path) { File.join(FLYDATA_TABLE_POSITIONS_DIR, 'test_1.binlog.pos') }
30
+ let(:table_1_snapshot) { create_ss('1010:1010:') }
31
+ let(:table_1_to_snapshot) { nil }
32
+ let(:table_1_pk_values) { nil }
33
+ let(:table_1_src_pos_file) {
34
+ create_src_pos_file(table_1_src_pos_file_path,
35
+ table_1_snapshot, table_1_to_snapshot, table_1_pk_values) }
36
+
37
+ let(:context) {
38
+ Flydata::SourcePostgresql::PluginSupport::Context.new(
39
+ cur_src_pos_file: cur_src_pos_file,
40
+ tables: %w(table_1 table_2 table_3),
41
+ tag: 'test_tag',
42
+ sync_fm: sync_fm,
43
+
44
+ omit_events: { 'table_3' => [:delete, :truncate] },
45
+ table_revs: { 'table_1' => 1, 'table_2' => 1, 'table_3' => 1 },
46
+ table_meta: table_meta,
47
+ table_src_pos_files: {
48
+ table_1: table_1_src_pos_file,
49
+ table_2: table_2_src_pos_file,
50
+ table_3: table_3_src_pos_file,
51
+ },
52
+ params: {
53
+ fetch_interval: 10,
54
+ retry_interval: 5,
55
+ },
56
+ dbconf: {
57
+ host: 'test-host',
58
+ port: 5555,
59
+ username: 'test-user',
60
+ password: 'test-password',
61
+ database: 'test-db',
62
+ schema: 'test-schema',
63
+ },
64
+ database: 'test-db',
65
+ )
66
+ }
67
+
68
+ # Override
69
+ def setup_dummy_objects
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+ require 'flydata/source_postgresql/query_based_sync/query_based_sync_postgresql_context'
3
+ require 'flydata/source_postgresql/query_based_sync/resource_requester'
4
+
5
+
6
+ module Flydata
7
+ module SourcePostgresql
8
+ module QueryBasedSync
9
+
10
+ describe ResourceRequester do
11
+ include_context 'query based sync postgresql context'
12
+
13
+ let(:subject_object) { described_class.new(context) }
14
+
15
+ describe '#create_resource_client' do
16
+ subject { subject_object.create_resource_client(context) }
17
+ it { is_expected.to be_kind_of(FlydataCore::Postgresql::PGClient) }
18
+ end
19
+
20
+ describe '#fetch_responses_once' do
21
+ let(:table_name) { 'table_1' }
22
+ let(:result) { double('result') }
23
+ let(:response) { double('response') }
24
+ let(:query_cond) { {} }
25
+ let(:latest_src_pos) { FlydataCore::Postgresql::SourcePos.new(current_snapshot) }
26
+
27
+ subject { subject_object.fetch_responses_once(table_name, latest_src_pos) }
28
+
29
+ shared_examples 'returning expected responses' do
30
+ it 'runs a query and return responses' do
31
+ expect_any_instance_of(FlydataCore::Postgresql::PGClient).
32
+ to receive(:query).and_return(result)
33
+ expect(Response).to receive(:create_responses).with(context, table_name, result, query_cond).and_return([response])
34
+ expect(subject).to eq([response])
35
+ end
36
+ end
37
+
38
+ context 'when table_src_pos file exists but does not have pk_values' do
39
+ let(:table_1_snapshot) { create_ss('1015:1015:') }
40
+ let(:query_cond) { {from_sid: create_ss('1015:1015:'), to_sid: create_ss('1020:1020:'), pk_values: nil} }
41
+ it_behaves_like 'returning expected responses'
42
+ end
43
+
44
+ context 'when table_src_pos file does not exist' do
45
+ before do
46
+ FileUtils.rm(table_1_src_pos_file.path)
47
+ end
48
+ let(:query_cond) { {from_sid: create_ss('1010:1010:'), to_sid: create_ss('1020:1020:'), pk_values: nil} }
49
+ it_behaves_like 'returning expected responses'
50
+ end
51
+
52
+ context 'when table_src_pos has pk_values' do
53
+ let(:table_1_snapshot) { create_ss('1012:1012:') }
54
+ let(:table_1_to_snapshot) { create_ss('1020:1020:') }
55
+ let(:table_1_pk_values) { [{"id"=>2}] }
56
+
57
+ let(:query_cond) { {from_sid: create_ss('1012:1012:'), to_sid: create_ss('1020:1020:'), pk_values: [{"id"=>2}]} }
58
+ it_behaves_like 'returning expected responses'
59
+ end
60
+
61
+ context 'when table_src_pos snapshot is up to date' do
62
+ let(:table_1_snapshot) { current_snapshot }
63
+ it { is_expected.to be_nil }
64
+ end
65
+ end
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,77 @@
1
+ require 'fluent_plugins_spec_helper'
2
+ require 'flydata/source_postgresql/table_meta'
3
+
4
+ module Flydata::SourcePostgresql
5
+ describe TableMeta do
6
+ let(:dbconf) { { host: 'test-host', port: 3306, username: 'test-user', password: 'test-pswd', database: 'test-db', schema: 'test-schema' } }
7
+ let(:database) { 'test-db' }
8
+ let(:schema) { 'test-schema' }
9
+ let(:tables) { %w(a_table b_table c_table) }
10
+
11
+ let(:conn) { double('conn') }
12
+ let(:subject_object) { described_class.new(dbconf, tables, schema) }
13
+
14
+
15
+ def build_column(table_name,column_name,column_default,is_nullable,is_primary,data_type,character_octet_length,numeric_precision,numeric_scale)
16
+ {'table_name'=>table_name,
17
+ 'column_name'=>column_name,
18
+ 'column_default'=>column_default,
19
+ 'is_nullable'=>is_nullable,
20
+ 'is_primary'=>is_primary,
21
+ 'data_type'=>data_type,
22
+ 'character_octet_length'=>character_octet_length,
23
+ 'numeric_precision'=>numeric_precision,
24
+ 'numeric_scale'=>numeric_scale,
25
+ }
26
+ end
27
+
28
+ let(:raw_columns) { [
29
+ build_column('table_a', 'id', nil, 'NO', true, 'int', nil, 4, 0),
30
+ build_column('table_a', 'val', nil, 'YES', false, 'character varying', 24, nil, nil),
31
+ build_column('table_b', 'name', nil, 'NO', true, 'character varying', 36, nil, nil),
32
+ build_column('table_b', 'count', nil, 'YES', false, 'int', nil, 4, 0),
33
+ ] }
34
+ let(:current_snapshots) { [{'txid_current_snapshot'=>'1010:1010:'}] }
35
+
36
+ before do
37
+ allow(conn).to receive(:close)
38
+ allow(FlydataCore::Postgresql::PGClient).to receive(:new).and_return(conn)
39
+ end
40
+
41
+ describe '.reload' do
42
+ subject { subject_object.reload(input_cli) }
43
+
44
+ context 'when params is nil' do
45
+ let(:input_cli) { nil }
46
+ before do
47
+ expect(conn).to receive(:query).and_return(raw_columns, current_snapshots)
48
+ expect(conn).to receive(:close)
49
+ end
50
+ it do
51
+ expect(subject[:table_a][:table_name]).to eq('table_a')
52
+ expect(subject[:table_a][:primary_keys]).to eq(%w(id))
53
+ expect(subject[:table_a][:pk_positions]).to eq(%w(1))
54
+ expect(subject[:table_a][:max_num_rows_per_query]).to be_kind_of(Integer)
55
+ expect(subject[:table_a][:columns]).to be_kind_of(Array)
56
+ expect(subject[:table_a][:table_def]).to be_kind_of(FlydataCore::TableDef::Base)
57
+ end
58
+ end
59
+
60
+ context 'when params is not nil' do
61
+ let(:input_cli) { conn }
62
+ before do
63
+ expect(conn).to receive(:query).and_return(raw_columns, current_snapshots)
64
+ expect(conn).to receive(:close).never
65
+ end
66
+ it do
67
+ expect(subject[:table_a][:table_name]).to eq('table_a')
68
+ expect(subject[:table_a][:primary_keys]).to eq(%w(id))
69
+ expect(subject[:table_a][:pk_positions]).to eq(%w(1))
70
+ expect(subject[:table_a][:max_num_rows_per_query]).to be_kind_of(Integer)
71
+ expect(subject[:table_a][:columns]).to be_kind_of(Array)
72
+ expect(subject[:table_a][:table_def]).to be_kind_of(FlydataCore::TableDef::Base)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
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.6.14
4
+ version: 0.7.0
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: 2016-03-24 00:00:00.000000000 Z
15
+ date: 2016-04-01 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rest-client
@@ -544,6 +544,10 @@ files:
544
544
  - flydata-core/lib/flydata-core/mysql/config.rb
545
545
  - flydata-core/lib/flydata-core/mysql/ssl.rb
546
546
  - flydata-core/lib/flydata-core/option_validator.rb
547
+ - flydata-core/lib/flydata-core/postgresql/compatibility_checker.rb
548
+ - flydata-core/lib/flydata-core/postgresql/config.rb
549
+ - flydata-core/lib/flydata-core/postgresql/pg_client.rb
550
+ - flydata-core/lib/flydata-core/postgresql/snapshot.rb
547
551
  - flydata-core/lib/flydata-core/postgresql/source_pos.rb
548
552
  - flydata-core/lib/flydata-core/query_job.rb
549
553
  - flydata-core/lib/flydata-core/record/record.rb
@@ -572,6 +576,10 @@ files:
572
576
  - flydata-core/spec/mysql/compatibility_checker_spec.rb
573
577
  - flydata-core/spec/mysql/config_spec.rb
574
578
  - flydata-core/spec/option_validator_spec.rb
579
+ - flydata-core/spec/postgresql/compatibility_checker_spec.rb
580
+ - flydata-core/spec/postgresql/config_spec.rb
581
+ - flydata-core/spec/postgresql/pg_client_spec.rb
582
+ - flydata-core/spec/postgresql/snapshot_spec.rb
575
583
  - flydata-core/spec/postgresql/source_pos_spec.rb
576
584
  - flydata-core/spec/redshift/string_spec.rb
577
585
  - flydata-core/spec/spec_helper.rb
@@ -638,12 +646,16 @@ files:
638
646
  - lib/flydata/errors.rb
639
647
  - lib/flydata/event/api_event_sender.rb
640
648
  - lib/flydata/fluent-plugins/flydata_plugin_ext/base.rb
649
+ - lib/flydata/fluent-plugins/flydata_plugin_ext/fluent_log_ext.rb
641
650
  - lib/flydata/fluent-plugins/flydata_plugin_ext/flush_support.rb
642
651
  - lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync.rb
652
+ - lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_diff_based.rb
653
+ - lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_query_based.rb
643
654
  - lib/flydata/fluent-plugins/flydata_plugin_ext/idle_event_detector.rb
644
655
  - lib/flydata/fluent-plugins/flydata_plugin_ext/preference.rb
645
656
  - lib/flydata/fluent-plugins/flydata_plugin_ext/transaction_support.rb
646
657
  - lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb
658
+ - lib/flydata/fluent-plugins/in_postgresql_query_based_flydata.rb
647
659
  - lib/flydata/fluent-plugins/out_forward_ssl.rb
648
660
  - lib/flydata/flydata_crontab.sh
649
661
  - lib/flydata/helper/action/agent_action.rb
@@ -672,9 +684,15 @@ files:
672
684
  - lib/flydata/parser/parser_provider.rb
673
685
  - lib/flydata/parser/source_table.rb
674
686
  - lib/flydata/plugin_support/context.rb
687
+ - lib/flydata/plugin_support/source_position_file.rb
675
688
  - lib/flydata/plugin_support/sync_record_emittable.rb
676
689
  - lib/flydata/preference/data_entry_preference.rb
677
690
  - lib/flydata/proxy.rb
691
+ - lib/flydata/query_based_sync/client.rb
692
+ - lib/flydata/query_based_sync/record_size_estimator.rb
693
+ - lib/flydata/query_based_sync/resource_requester.rb
694
+ - lib/flydata/query_based_sync/response.rb
695
+ - lib/flydata/query_based_sync/response_handler.rb
678
696
  - lib/flydata/queueable_thread.rb
679
697
  - lib/flydata/source.rb
680
698
  - lib/flydata/source/component.rb
@@ -701,7 +719,6 @@ files:
701
719
  - lib/flydata/source_mysql/parser/dump_parser.rb
702
720
  - lib/flydata/source_mysql/parser/mysql_alter_table.treetop
703
721
  - lib/flydata/source_mysql/plugin_support/alter_table_query_handler.rb
704
- - lib/flydata/source_mysql/plugin_support/binlog_position_file.rb
705
722
  - lib/flydata/source_mysql/plugin_support/binlog_query_dispatcher.rb
706
723
  - lib/flydata/source_mysql/plugin_support/binlog_query_handler.rb
707
724
  - lib/flydata/source_mysql/plugin_support/binlog_record_dispatcher.rb
@@ -710,26 +727,35 @@ files:
710
727
  - lib/flydata/source_mysql/plugin_support/ddl_query_handler.rb
711
728
  - lib/flydata/source_mysql/plugin_support/dml_record_handler.rb
712
729
  - lib/flydata/source_mysql/plugin_support/drop_database_query_handler.rb
713
- - lib/flydata/source_mysql/plugin_support/table_meta.rb
730
+ - lib/flydata/source_mysql/plugin_support/source_position_file.rb
714
731
  - lib/flydata/source_mysql/plugin_support/truncate_table_query_handler.rb
715
732
  - lib/flydata/source_mysql/setup.rb
716
733
  - lib/flydata/source_mysql/source_pos.rb
717
734
  - lib/flydata/source_mysql/sync.rb
718
735
  - lib/flydata/source_mysql/sync_generate_table_ddl.rb
719
736
  - lib/flydata/source_mysql/table_ddl.rb
737
+ - lib/flydata/source_mysql/table_meta.rb
720
738
  - lib/flydata/source_postgresql/data_entry.rb
721
739
  - lib/flydata/source_postgresql/generate_source_dump.rb
722
740
  - lib/flydata/source_postgresql/parse_dump_and_send.rb
723
- - lib/flydata/source_postgresql/pg_client.rb
741
+ - lib/flydata/source_postgresql/plugin_support/context.rb
742
+ - lib/flydata/source_postgresql/plugin_support/source_position_file.rb
724
743
  - lib/flydata/source_postgresql/postgresql_component.rb
744
+ - lib/flydata/source_postgresql/query_based_sync/client.rb
745
+ - lib/flydata/source_postgresql/query_based_sync/diff_query_generator.rb
746
+ - lib/flydata/source_postgresql/query_based_sync/resource_requester.rb
747
+ - lib/flydata/source_postgresql/query_based_sync/response.rb
748
+ - lib/flydata/source_postgresql/query_based_sync/response_handler.rb
725
749
  - lib/flydata/source_postgresql/setup.rb
726
750
  - lib/flydata/source_postgresql/source_pos.rb
727
751
  - lib/flydata/source_postgresql/sync.rb
728
752
  - lib/flydata/source_postgresql/sync_generate_table_ddl.rb
753
+ - lib/flydata/source_postgresql/table_meta.rb
729
754
  - lib/flydata/source_zendesk/sync_generate_table_ddl.rb
730
755
  - lib/flydata/source_zendesk/zendesk_flydata_tabledefs.rb
731
756
  - lib/flydata/sync_file_manager.rb
732
757
  - lib/flydata/table_ddl.rb
758
+ - lib/flydata/table_meta.rb
733
759
  - lib/flydata/util/encryptor.rb
734
760
  - lib/flydata/util/file_util.rb
735
761
  - lib/flydata/util/shell.rb
@@ -757,8 +783,14 @@ files:
757
783
  - spec/flydata/command/sync_spec.rb
758
784
  - spec/flydata/command/version_spec.rb
759
785
  - spec/flydata/compatibility_check_spec.rb
786
+ - spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_context.rb
787
+ - spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_diff_based_shared_examples.rb
788
+ - spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_query_based_shared_examples.rb
789
+ - spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_shared_examples.rb
760
790
  - spec/flydata/fluent-plugins/flydata_plugin_ext/idle_event_detector_spec.rb
761
791
  - spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb
792
+ - spec/flydata/fluent-plugins/in_postgresql_query_based_flydata_spec.rb
793
+ - spec/flydata/fluent-plugins/sync_source_plugin_context.rb
762
794
  - spec/flydata/helper/action/check_abnormal_shutdown_spec.rb
763
795
  - spec/flydata/helper/action/check_remote_actions_spec.rb
764
796
  - spec/flydata/helper/action/restart_agent_spec.rb
@@ -774,6 +806,12 @@ files:
774
806
  - spec/flydata/json/json_ext_spec.rb
775
807
  - spec/flydata/output/forwarder_spec.rb
776
808
  - spec/flydata/plugin_support/context_spec.rb
809
+ - spec/flydata/query_based_sync/client_spec.rb
810
+ - spec/flydata/query_based_sync/query_based_sync_context.rb
811
+ - spec/flydata/query_based_sync/record_size_estimator_spec.rb
812
+ - spec/flydata/query_based_sync/resource_requester_spec.rb
813
+ - spec/flydata/query_based_sync/response_handler_spec.rb
814
+ - spec/flydata/query_based_sync/response_spec.rb
777
815
  - spec/flydata/source_mysql/generate_source_dump_spec.rb
778
816
  - spec/flydata/source_mysql/mysql_compatibility_check_spec.rb
779
817
  - spec/flydata/source_mysql/parser/alter_table_parser_spec.rb
@@ -785,11 +823,16 @@ files:
785
823
  - spec/flydata/source_mysql/plugin_support/dml_record_handler_spec.rb
786
824
  - spec/flydata/source_mysql/plugin_support/drop_database_query_handler_spec.rb
787
825
  - spec/flydata/source_mysql/plugin_support/shared_query_handler_context.rb
788
- - spec/flydata/source_mysql/plugin_support/table_meta_spec.rb
826
+ - spec/flydata/source_mysql/plugin_support/source_position_file_spec.rb
789
827
  - spec/flydata/source_mysql/plugin_support/truncate_query_handler_spec.rb
790
828
  - spec/flydata/source_mysql/sync_generate_table_ddl_spec.rb
791
829
  - spec/flydata/source_mysql/table_ddl_spec.rb
830
+ - spec/flydata/source_mysql/table_meta_spec.rb
792
831
  - spec/flydata/source_postgresql/generate_source_dump_spec.rb
832
+ - spec/flydata/source_postgresql/query_based_sync/diff_query_generator_spec.rb
833
+ - spec/flydata/source_postgresql/query_based_sync/query_based_sync_postgresql_context.rb
834
+ - spec/flydata/source_postgresql/query_based_sync/resource_requester_spec.rb
835
+ - spec/flydata/source_postgresql/table_meta_spec.rb
793
836
  - spec/flydata/source_spec.rb
794
837
  - spec/flydata/source_zendesk/sync_generate_table_ddl_spec.rb
795
838
  - spec/flydata/sync_file_manager_spec.rb