flydata 0.6.14 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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