flydata 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +4 -4
- data/VERSION +1 -1
- data/flydata-core/.gitignore +1 -0
- data/flydata-core/Gemfile +4 -1
- data/flydata-core/Gemfile.lock +10 -0
- data/flydata-core/lib/flydata-core/mysql/compatibility_checker.rb +66 -15
- data/flydata-core/lib/flydata-core/table_def/redshift_table_def.rb +13 -0
- data/flydata-core/lib/flydata-core/wrapper_forwardable.rb +28 -0
- data/flydata-core/spec/mysql/compatibility_checker.rb +178 -1
- data/flydata-core/spec/table_def/redshift_table_def_spec.rb +37 -0
- data/flydata-core/spec/wrapper_forwardable_spec.rb +67 -0
- data/flydata.gemspec +8 -9
- data/lib/flydata/command/sender.rb +3 -3
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +54 -19
- data/lib/flydata/parser/mysql/mysql_alter_table.treetop +1 -1
- data/spec/flydata/parser/mysql/alter_table_parser_spec.rb +44 -13
- metadata +6 -7
- data/flydata-core/lib/flydata-core/query_job/redshift.rb +0 -27
- data/flydata-core/lib/flydata-core/query_job/table_status.rb +0 -44
- data/flydata-core/spec/query_job/redshift_spec.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3363c696e28b167255482e1d6b7352d5e3989786
|
4
|
+
data.tar.gz: 57d1039674d07396d58b2cf32d25c5c38db703ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24e8879e214ec3b0cfa21d7b725e05bca66b4c668f59d3bfc5869285e70d1a92f97971002566f9d7e65332d91897561a20ffab26916ee7ce35c163e25066546a
|
7
|
+
data.tar.gz: 6303e50004f8d927867892a94e309d8e578cee1ed633f2768bae4470aca808cd9945ff2694ac220a07d4e20bea35df2df194963475ee971417910c22bdc6914b
|
data/Gemfile
CHANGED
@@ -13,7 +13,7 @@ gem "slop", '~> 3.4', '>= 3.4.6'
|
|
13
13
|
gem "treetop", '~> 1.5', '>= 1.5.3'
|
14
14
|
gem "sys-filesystem", '~> 1.1', '>= 1.1.3'
|
15
15
|
gem "io-console", '~> 0.4.2', '>= 0.4.2'
|
16
|
-
gem "kodama", '~> 0.1.2', '>= 0.1.
|
16
|
+
gem "kodama", '~> 0.1.2', '>= 0.1.7'
|
17
17
|
gem "serverengine", '~> 1.5'
|
18
18
|
|
19
19
|
group :development do
|
data/Gemfile.lock
CHANGED
@@ -61,8 +61,8 @@ GEM
|
|
61
61
|
rdoc
|
62
62
|
json (1.8.1)
|
63
63
|
jwt (1.0.0)
|
64
|
-
kodama (0.1.
|
65
|
-
ruby-binlog (~> 1.0, >= 1.0.
|
64
|
+
kodama (0.1.7)
|
65
|
+
ruby-binlog (~> 1.0, >= 1.0.6)
|
66
66
|
method_source (0.8.2)
|
67
67
|
mime-types (2.3)
|
68
68
|
minitest (4.7.5)
|
@@ -105,7 +105,7 @@ GEM
|
|
105
105
|
rspec-mocks (3.0.3)
|
106
106
|
rspec-support (~> 3.0.0)
|
107
107
|
rspec-support (3.0.3)
|
108
|
-
ruby-binlog (1.0.
|
108
|
+
ruby-binlog (1.0.6)
|
109
109
|
ruby-prof (0.15.1)
|
110
110
|
serverengine (1.5.10)
|
111
111
|
sigdump (~> 0.2.2)
|
@@ -135,7 +135,7 @@ DEPENDENCIES
|
|
135
135
|
io-console (~> 0.4.2, >= 0.4.2)
|
136
136
|
jeweler (~> 1.8, >= 1.8.8)
|
137
137
|
json (~> 1.8, >= 1.8.0)
|
138
|
-
kodama (~> 0.1.2, >= 0.1.
|
138
|
+
kodama (~> 0.1.2, >= 0.1.7)
|
139
139
|
mysql2 (~> 0.3, >= 0.3.17)
|
140
140
|
protected_attributes (~> 1.0, >= 1.0.8)
|
141
141
|
pry
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.1
|
data/flydata-core/.gitignore
CHANGED
data/flydata-core/Gemfile
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
+
|
3
4
|
# for dependencies
|
5
|
+
gem 'aws-sdk', "1.18.0"
|
6
|
+
|
4
7
|
group :development, :test do
|
5
8
|
gem 'timecop'
|
6
9
|
gem 'ruby-prof'
|
7
10
|
gem 'rubocop'
|
11
|
+
gem 'mysql2'
|
8
12
|
gem 'rspec', '~> 3.1'
|
9
13
|
gem 'simplecov', :require => false
|
10
14
|
end
|
11
|
-
|
data/flydata-core/Gemfile.lock
CHANGED
@@ -4,9 +4,16 @@ GEM
|
|
4
4
|
ast (2.0.0)
|
5
5
|
astrolabe (1.3.0)
|
6
6
|
parser (>= 2.2.0.pre.3, < 3.0)
|
7
|
+
aws-sdk (1.18.0)
|
8
|
+
json (~> 1.4)
|
9
|
+
nokogiri (< 1.6.0)
|
10
|
+
uuidtools (~> 2.1)
|
7
11
|
diff-lcs (1.2.5)
|
8
12
|
docile (1.1.5)
|
13
|
+
json (1.8.2)
|
9
14
|
multi_json (1.10.1)
|
15
|
+
mysql2 (0.3.18)
|
16
|
+
nokogiri (1.5.11)
|
10
17
|
parser (2.2.0.pre.8)
|
11
18
|
ast (>= 1.1, < 3.0)
|
12
19
|
slop (~> 3.4, >= 3.4.5)
|
@@ -39,11 +46,14 @@ GEM
|
|
39
46
|
simplecov-html (0.8.0)
|
40
47
|
slop (3.6.0)
|
41
48
|
timecop (0.7.1)
|
49
|
+
uuidtools (2.1.5)
|
42
50
|
|
43
51
|
PLATFORMS
|
44
52
|
ruby
|
45
53
|
|
46
54
|
DEPENDENCIES
|
55
|
+
aws-sdk (= 1.18.0)
|
56
|
+
mysql2
|
47
57
|
rspec (~> 3.1)
|
48
58
|
rubocop
|
49
59
|
ruby-prof
|
@@ -118,34 +118,57 @@ module FlydataCore
|
|
118
118
|
'binlog_format'=>'ROW',
|
119
119
|
'binlog_checksum'=>'NONE',
|
120
120
|
'log_bin_use_v1_row_events'=>'ON',
|
121
|
-
'log_slave_updates'=>'ON'
|
121
|
+
'log_slave_updates'=>'ON',
|
122
|
+
# parameter => {"comparison sign"=>minimum value}
|
123
|
+
# TODO: Handled the error message of following items as warning
|
124
|
+
#'net_read_timeout'=>{'>'=>600},
|
125
|
+
#'net_write_timeout'=>{'>'=>600},
|
126
|
+
#'wait_timeout'=>{'>'=>60}
|
122
127
|
}
|
128
|
+
OPTIONAL_SYS_VAR = %w(binlog_checksum log_bin_use_v1_row_events)
|
123
129
|
|
124
130
|
def check_result(result, option = @option)
|
125
131
|
errors = {}
|
126
132
|
param_hash = convert_result_to_hash(result)
|
127
133
|
|
128
|
-
SYS_VAR_TO_CHECK
|
129
|
-
if param_hash.has_key?(sys_var)
|
130
|
-
actual_val = param_hash[sys_var]
|
131
|
-
expected_val = SYS_VAR_TO_CHECK[sys_var]
|
132
|
-
unless actual_val == expected_val
|
133
|
-
errors[sys_var] = actual_val
|
134
|
-
end
|
135
|
-
elsif not %w(binlog_checksum log_bin_use_v1_row_events).include?(sys_var)
|
136
|
-
# Mark variables that do not exist as error
|
137
|
-
errors[sys_var] = false
|
138
|
-
end
|
139
|
-
end
|
134
|
+
compare_sys_var_values(param_hash, SYS_VAR_TO_CHECK, errors, OPTIONAL_SYS_VAR)
|
140
135
|
|
141
136
|
unless errors.empty?
|
142
137
|
error_explanation = ""
|
143
138
|
errors.each_key do |err_key|
|
144
|
-
|
139
|
+
if SYS_VAR_TO_CHECK[err_key].is_a?(Hash)
|
140
|
+
error_explanation << "\n * #{err_key} is #{errors[err_key]} but should be at least #{SYS_VAR_TO_CHECK[err_key].values.first}"
|
141
|
+
else
|
142
|
+
error_explanation << "\n * #{err_key} is #{errors[err_key]} but should be #{SYS_VAR_TO_CHECK[err_key]}"
|
143
|
+
end
|
145
144
|
end
|
146
145
|
raise FlydataCore::MysqlCompatibilityError,
|
147
146
|
"These system variable(s) are not the correct value: #{error_explanation}\n" +
|
148
|
-
" Please change these system variables for FlyData Sync to run
|
147
|
+
" Please change these system variables for FlyData Sync to run"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
def compare_sys_var_values(input_value_hash, expected_value_hash, errors, exception_arr)
|
153
|
+
expected_value_hash.each_key do |exp_val|
|
154
|
+
if input_value_hash.has_key?(exp_val)
|
155
|
+
actual_val = input_value_hash[exp_val]
|
156
|
+
compare_sym = expected_value_hash[exp_val].is_a?(Hash) ? expected_value_hash[exp_val].keys.first : "="
|
157
|
+
case compare_sym
|
158
|
+
when "="
|
159
|
+
expected_val = expected_value_hash[exp_val]
|
160
|
+
unless actual_val == expected_val
|
161
|
+
errors[exp_val] = actual_val
|
162
|
+
end
|
163
|
+
when ">"
|
164
|
+
expected_val = expected_value_hash[exp_val].values.first
|
165
|
+
unless actual_val.to_i >= expected_val.to_i
|
166
|
+
errors[exp_val] = actual_val
|
167
|
+
end
|
168
|
+
end
|
169
|
+
elsif not exception_arr.include?(exp_val)
|
170
|
+
errors[exp_val] = false
|
171
|
+
end
|
149
172
|
end
|
150
173
|
end
|
151
174
|
end
|
@@ -181,6 +204,34 @@ module FlydataCore
|
|
181
204
|
end
|
182
205
|
end
|
183
206
|
|
207
|
+
class PrimaryKeyChecker < MysqlCompatibilityChecker
|
208
|
+
PK_CHECK_QUERY_TMPLT = <<EOT
|
209
|
+
SELECT k.table_name as table_name
|
210
|
+
FROM information_schema.table_constraints t
|
211
|
+
JOIN information_schema.key_column_usage k
|
212
|
+
USING(constraint_name,table_schema,table_name)
|
213
|
+
WHERE t.constraint_type='PRIMARY KEY'
|
214
|
+
AND t.table_schema='%{database}'
|
215
|
+
AND t.table_name in (%{table_names})
|
216
|
+
GROUP BY k.table_name;
|
217
|
+
EOT
|
218
|
+
def create_query(option = @option)
|
219
|
+
PK_CHECK_QUERY_TMPLT % {database: option[:database], table_names: option[:tables].collect{|tn| "'#{tn}'"}.join(',')}
|
220
|
+
end
|
221
|
+
|
222
|
+
def check_result(result, option = @option)
|
223
|
+
pk_tables = []
|
224
|
+
result.each {|r| pk_tables << r['table_name']}
|
225
|
+
missing_pk_tables = option[:tables] - pk_tables
|
226
|
+
|
227
|
+
unless missing_pk_tables.empty?
|
228
|
+
raise FlydataCore::MysqlCompatibilityError,
|
229
|
+
"Primary key is required for tables to sync. " +
|
230
|
+
"Add primary key or remove following tables from data entry: #{missing_pk_tables.join(", ")}"
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
184
235
|
class NonRdsRetentionChecker < MysqlCompatibilityChecker
|
185
236
|
include MysqlVariablesHandling
|
186
237
|
|
@@ -87,6 +87,19 @@ EOS
|
|
87
87
|
schema_name.to_s.empty? ? "\"#{table_name}\"" : "\"#{schema_name}\".\"#{table_name}\""
|
88
88
|
end
|
89
89
|
|
90
|
+
def self.fq_table_name(table_name, schema_name)
|
91
|
+
idx = table_name.rindex('.')
|
92
|
+
if (idx)
|
93
|
+
# table name has schame qualifier. Remove it.
|
94
|
+
table_name = table_name[idx+1..-1]
|
95
|
+
end
|
96
|
+
|
97
|
+
result =
|
98
|
+
schema_name.to_s.empty? ? table_name : "#{schema_name}.#{table_name}"
|
99
|
+
|
100
|
+
convert_to_valid_table_name(result)
|
101
|
+
end
|
102
|
+
|
90
103
|
def self.flydata_ctl_table_for_ddl(schema_name, ctl_table_type = :columns)
|
91
104
|
table_name = case ctl_table_type
|
92
105
|
when :columns; FLYDATA_CTL_COLUMNS_TABLE
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module FlydataCore
|
2
|
+
|
3
|
+
module WrapperSingleForwardable
|
4
|
+
# Delegates a method call `delegator` to the given `accessor` like the
|
5
|
+
# original `def_single_delegator` does. In addition, it wraps the returned
|
6
|
+
# object (or each object in an array) with the caller's own instance.
|
7
|
+
def def_wrapper_single_delegator(accessor, delegator)
|
8
|
+
self.define_singleton_method(delegator) do |*args|
|
9
|
+
result = accessor.send(delegator, *args)
|
10
|
+
case result
|
11
|
+
when Array
|
12
|
+
result.collect{|res| self.new(res)}
|
13
|
+
when NilClass
|
14
|
+
nil
|
15
|
+
else
|
16
|
+
self.new(result)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def def_wrapper_single_delegators(accessor, *delegators)
|
22
|
+
delegators.each do |delegator|
|
23
|
+
def_wrapper_single_delegator(accessor, delegator)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -1,9 +1,186 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'flydata-core/mysql/compatibility_checker'
|
2
3
|
|
3
4
|
module FlydataCore
|
4
5
|
module Mysql
|
5
|
-
describe
|
6
|
+
describe CompatibilityChecker do
|
7
|
+
let(:database) { 'test_db' }
|
8
|
+
let(:tables) { %w(table_1 table_2 table_3) }
|
9
|
+
let(:option) do
|
10
|
+
{ database: database, tables: tables }
|
11
|
+
end
|
6
12
|
|
13
|
+
describe PrimaryKeyChecker do
|
14
|
+
let(:subject_object) { described_class.new(option) }
|
15
|
+
|
16
|
+
describe '#create_query' do
|
17
|
+
subject { subject_object.create_query }
|
18
|
+
it { is_expected.to eq <<EOT
|
19
|
+
SELECT k.table_name as table_name
|
20
|
+
FROM information_schema.table_constraints t
|
21
|
+
JOIN information_schema.key_column_usage k
|
22
|
+
USING(constraint_name,table_schema,table_name)
|
23
|
+
WHERE t.constraint_type='PRIMARY KEY'
|
24
|
+
AND t.table_schema='test_db'
|
25
|
+
AND t.table_name in ('table_1','table_2','table_3')
|
26
|
+
GROUP BY k.table_name;
|
27
|
+
EOT
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#check_reesult' do
|
32
|
+
let(:result) { [] }
|
33
|
+
subject { subject_object.check_result(result) }
|
34
|
+
|
35
|
+
context 'when all tables have pk' do
|
36
|
+
let(:result) do
|
37
|
+
[ {"table_name" => "table_1"},
|
38
|
+
{"table_name" => "table_2"},
|
39
|
+
{"table_name" => "table_3"}, ]
|
40
|
+
end
|
41
|
+
it { expect{subject}.not_to raise_error }
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when some tables does not have pk' do
|
45
|
+
let(:result) { [{"table_name" => "table_2"} ] }
|
46
|
+
it do
|
47
|
+
expect{subject}.to raise_error {|e|
|
48
|
+
expect(e).to be_kind_of(FlydataCore::MysqlCompatibilityError)
|
49
|
+
expect(e.to_s.include?("table_1")).to be_truthy
|
50
|
+
expect(e.to_s.include?("table_2")).to be_falsey
|
51
|
+
expect(e.to_s.include?("table_3")).to be_truthy
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe BinlogParameterChecker do
|
60
|
+
let(:subject_object) { BinlogParameterChecker.new({}) }
|
61
|
+
|
62
|
+
describe "#check_result" do
|
63
|
+
let(:sys_var) do
|
64
|
+
[
|
65
|
+
{'Variable_name'=>'binlog_format','Value'=>'ROW'},
|
66
|
+
{'Variable_name'=>'binlog_checksum','Value'=>'NONE'},
|
67
|
+
{'Variable_name'=>'log_bin_use_v1_row_events','Value'=>'ON'},
|
68
|
+
{'Variable_name'=>'log_slave_updates','Value'=>'ON'},
|
69
|
+
{'Variable_name'=>'net_read_timeout','Value'=>600},
|
70
|
+
{'Variable_name'=>'net_write_timeout','Value'=>600},
|
71
|
+
{'Variable_name'=>'wait_timeout','Value'=>60}
|
72
|
+
]
|
73
|
+
end
|
74
|
+
subject { subject_object.check_result(sys_var, {}) }
|
75
|
+
|
76
|
+
context "where parameters are valid" do
|
77
|
+
it do
|
78
|
+
expect{subject}.to_not raise_error
|
79
|
+
end
|
80
|
+
end
|
81
|
+
context "where parameters are invalid" do
|
82
|
+
let(:sys_var) do
|
83
|
+
[
|
84
|
+
{'Variable_name'=>'binlog_format','Value'=>'MIXED'},
|
85
|
+
{'Variable_name'=>'binlog_checksum','Value'=>'NONE'},
|
86
|
+
{'Variable_name'=>'log_bin_use_v1_row_events','Value'=>'ON'},
|
87
|
+
{'Variable_name'=>'log_slave_updates','Value'=>'ON'},
|
88
|
+
{'Variable_name'=>'net_read_timeout','Value'=>600},
|
89
|
+
{'Variable_name'=>'net_write_timeout','Value'=>600},
|
90
|
+
{'Variable_name'=>'wait_timeout','Value'=>30}
|
91
|
+
]
|
92
|
+
end
|
93
|
+
it do
|
94
|
+
expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /binlog_format.*\n.*wait_timeout/)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
describe "#compare_sys_var_values" do
|
99
|
+
let(:expected_val) do
|
100
|
+
{
|
101
|
+
:value_1 => 'foo',
|
102
|
+
:value_2 => 50,
|
103
|
+
:value_3 => {">"=>100}
|
104
|
+
}
|
105
|
+
end
|
106
|
+
let(:errors) { {} }
|
107
|
+
let(:exception_arr) { [] }
|
108
|
+
subject { subject_object.send(:compare_sys_var_values, input_val, expected_val, errors, exception_arr) }
|
109
|
+
|
110
|
+
shared_examples "expect correct errors from values" do
|
111
|
+
it do
|
112
|
+
subject
|
113
|
+
expect(errors).to eq( expecting_errors )
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when getting valid parameters" do
|
118
|
+
let(:input_val) do
|
119
|
+
{
|
120
|
+
:value_1 => 'foo',
|
121
|
+
:value_2 => 50,
|
122
|
+
:value_3 => 200
|
123
|
+
}
|
124
|
+
end
|
125
|
+
let(:expecting_errors) { {} }
|
126
|
+
it_behaves_like "expect correct errors from values"
|
127
|
+
end
|
128
|
+
context "when getting one invalid exact parameters for int" do
|
129
|
+
let(:input_val) do
|
130
|
+
{
|
131
|
+
:value_1 => 'foo',
|
132
|
+
:value_2 => 20,
|
133
|
+
:value_3 => 100
|
134
|
+
}
|
135
|
+
end
|
136
|
+
let(:expecting_errors) { {value_2:20} }
|
137
|
+
it_behaves_like "expect correct errors from values"
|
138
|
+
end
|
139
|
+
context "when getting one invalid exact parameter for string" do
|
140
|
+
let(:input_val) do
|
141
|
+
{
|
142
|
+
:value_1 => 'fo',
|
143
|
+
:value_2 => 50,
|
144
|
+
:value_3 => 100
|
145
|
+
}
|
146
|
+
end
|
147
|
+
let(:expecting_errors) { {value_1:'fo'} }
|
148
|
+
it_behaves_like "expect correct errors from values"
|
149
|
+
end
|
150
|
+
context "when getting one invalid comparitive parameter that's lower than required" do
|
151
|
+
let(:input_val) do
|
152
|
+
{
|
153
|
+
:value_1 => 'foo',
|
154
|
+
:value_2 => 50,
|
155
|
+
:value_3 => 1
|
156
|
+
}
|
157
|
+
end
|
158
|
+
let(:expecting_errors) { {value_3:1} }
|
159
|
+
it_behaves_like "expect correct errors from values"
|
160
|
+
end
|
161
|
+
context "when getting a valid comparitive parameter that's higher than required" do
|
162
|
+
let(:input_val) do
|
163
|
+
{
|
164
|
+
:value_1 => 'foo',
|
165
|
+
:value_2 => 50,
|
166
|
+
:value_3 => 101
|
167
|
+
}
|
168
|
+
end
|
169
|
+
let(:expecting_errors) { {} }
|
170
|
+
it_behaves_like "expect correct errors from values"
|
171
|
+
end
|
172
|
+
context "when getting muliple invalid parameters" do
|
173
|
+
let(:input_val) do
|
174
|
+
{
|
175
|
+
:value_1 => 'fo',
|
176
|
+
:value_2 => 50,
|
177
|
+
:value_3 => 15
|
178
|
+
}
|
179
|
+
end
|
180
|
+
let(:expecting_errors) { {value_1:'fo', value_3:15} }
|
181
|
+
it_behaves_like "expect correct errors from values"
|
182
|
+
end
|
183
|
+
end
|
7
184
|
end
|
8
185
|
end
|
9
186
|
end
|
@@ -896,6 +896,43 @@ EOS
|
|
896
896
|
|
897
897
|
it_behaves_like "expecting no underscore in front of numbers"
|
898
898
|
end
|
899
|
+
|
900
|
+
describe ".fq_table_name" do
|
901
|
+
subject { subject_object.fq_table_name(table_name, schema_name) }
|
902
|
+
context "with no schema name" do
|
903
|
+
let(:schema_name) { nil }
|
904
|
+
context "with a table name with no schema prefix" do
|
905
|
+
let(:table_name) { "test_table" }
|
906
|
+
it { is_expected.to eq "test_table" }
|
907
|
+
end
|
908
|
+
context "with a table name with a schema prefix" do
|
909
|
+
let(:table_name) { "some_schema.test_table" }
|
910
|
+
it { is_expected.to eq "test_table" }
|
911
|
+
end
|
912
|
+
context "with a mixed-case table name" do
|
913
|
+
let(:table_name) { "Test_Table" }
|
914
|
+
it { is_expected.to eq "test_table" }
|
915
|
+
end
|
916
|
+
end
|
917
|
+
context "with a schema name" do
|
918
|
+
let(:schema_name) { "test_schema" }
|
919
|
+
context "with a table name with no schema prefix" do
|
920
|
+
let(:table_name) { "test_table" }
|
921
|
+
it { is_expected.to eq "test_schema.test_table" }
|
922
|
+
end
|
923
|
+
context "with a table name with a schema prefix" do
|
924
|
+
let(:table_name) { "some_schema.test_table" }
|
925
|
+
it { is_expected.to eq "test_schema.test_table" }
|
926
|
+
end
|
927
|
+
end
|
928
|
+
context "with a mixed-case schema name" do
|
929
|
+
let(:schema_name) { "Test_Schema" }
|
930
|
+
context "with a table name with no schema prefix" do
|
931
|
+
let(:table_name) { "test_table" }
|
932
|
+
it { is_expected.to eq "test_schema.test_table" }
|
933
|
+
end
|
934
|
+
end
|
935
|
+
end
|
899
936
|
end
|
900
937
|
|
901
938
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata-core/wrapper_forwardable'
|
3
|
+
|
4
|
+
module FlydataCore
|
5
|
+
|
6
|
+
describe WrapperSingleForwardable do
|
7
|
+
class Target
|
8
|
+
def self.foo(a, b)
|
9
|
+
target_foo_result
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Test
|
14
|
+
extend WrapperSingleForwardable
|
15
|
+
|
16
|
+
def_wrapper_single_delegator Target, :foo
|
17
|
+
|
18
|
+
def initialize(item)
|
19
|
+
@item = item
|
20
|
+
end
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
@item == other.item
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :item
|
27
|
+
end
|
28
|
+
let(:subject_object) { Test }
|
29
|
+
let(:args) { [ 'arg1', 'arg2' ] }
|
30
|
+
|
31
|
+
describe '.def_wrapper_single_delegator' do
|
32
|
+
it 'defines a class method of the given name to the subject class' do
|
33
|
+
expect(subject_object.respond_to?(:foo)).to eq true
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'the method defined by it' do
|
37
|
+
subject { subject_object.foo(*args) }
|
38
|
+
before do
|
39
|
+
expect(Target).to receive(:foo).with(*args).
|
40
|
+
and_return(target_foo_result)
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when the target method returns an object' do
|
44
|
+
let(:target_foo_result) { double('single_object') }
|
45
|
+
|
46
|
+
it 'returns an object of the subject class containing the target result' do
|
47
|
+
is_expected.to eq subject_object.new(target_foo_result)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
context 'when the target method returns nil' do
|
51
|
+
let(:target_foo_result) { nil }
|
52
|
+
|
53
|
+
it 'returns nil' do
|
54
|
+
is_expected.to eq nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
context 'when the target method returns an array' do
|
58
|
+
let(:target_foo_result) { [ double('object1'), double('object2') ] }
|
59
|
+
it 'returns an array of instances of the subject class. Each instance contains an object returned from the target' do
|
60
|
+
is_expected.to eq target_foo_result.collect{|item| subject_object.new(item) }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/flydata.gemspec
CHANGED
@@ -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.5.
|
5
|
+
# stub: flydata 0.5.1 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "flydata"
|
9
|
-
s.version = "0.5.
|
9
|
+
s.version = "0.5.1"
|
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-
|
14
|
+
s.date = "2015-08-04"
|
15
15
|
s.description = "FlyData Agent"
|
16
16
|
s.email = "sysadmin@flydata.com"
|
17
17
|
s.executables = ["fdmysqldump", "flydata", "serverinfo"]
|
@@ -51,8 +51,6 @@ Gem::Specification.new do |s|
|
|
51
51
|
"flydata-core/lib/flydata-core/mysql/compatibility_checker.rb",
|
52
52
|
"flydata-core/lib/flydata-core/option_validator.rb",
|
53
53
|
"flydata-core/lib/flydata-core/query_job.rb",
|
54
|
-
"flydata-core/lib/flydata-core/query_job/redshift.rb",
|
55
|
-
"flydata-core/lib/flydata-core/query_job/table_status.rb",
|
56
54
|
"flydata-core/lib/flydata-core/record/record.rb",
|
57
55
|
"flydata-core/lib/flydata-core/redshift/string.rb",
|
58
56
|
"flydata-core/lib/flydata-core/table_def.rb",
|
@@ -61,13 +59,13 @@ Gem::Specification.new do |s|
|
|
61
59
|
"flydata-core/lib/flydata-core/table_def/redshift_table_def.rb",
|
62
60
|
"flydata-core/lib/flydata-core/table_def/sync_redshift_table_def.rb",
|
63
61
|
"flydata-core/lib/flydata-core/thread_context.rb",
|
62
|
+
"flydata-core/lib/flydata-core/wrapper_forwardable.rb",
|
64
63
|
"flydata-core/spec/config/user_maintenance_spec.rb",
|
65
64
|
"flydata-core/spec/fluent/config_helper_spec.rb",
|
66
65
|
"flydata-core/spec/logger_spec.rb",
|
67
66
|
"flydata-core/spec/mysql/command_generator_spec.rb",
|
68
67
|
"flydata-core/spec/mysql/compatibility_checker.rb",
|
69
68
|
"flydata-core/spec/option_validator_spec.rb",
|
70
|
-
"flydata-core/spec/query_job/redshift_spec.rb",
|
71
69
|
"flydata-core/spec/redshift/string_spec.rb",
|
72
70
|
"flydata-core/spec/spec_helper.rb",
|
73
71
|
"flydata-core/spec/table_def/autoload_redshift_table_def_spec.rb",
|
@@ -88,6 +86,7 @@ Gem::Specification.new do |s|
|
|
88
86
|
"flydata-core/spec/table_def/mysqldump_test_unsigned.dump",
|
89
87
|
"flydata-core/spec/table_def/redshift_table_def_spec.rb",
|
90
88
|
"flydata-core/spec/table_def/sync_redshift_table_def_spec.rb",
|
89
|
+
"flydata-core/spec/wrapper_forwardable_spec.rb",
|
91
90
|
"flydata.gemspec",
|
92
91
|
"lib/fly_data_model.rb",
|
93
92
|
"lib/flydata.rb",
|
@@ -243,7 +242,7 @@ Gem::Specification.new do |s|
|
|
243
242
|
s.add_runtime_dependency(%q<treetop>, [">= 1.5.3", "~> 1.5"])
|
244
243
|
s.add_runtime_dependency(%q<sys-filesystem>, [">= 1.1.3", "~> 1.1"])
|
245
244
|
s.add_runtime_dependency(%q<io-console>, [">= 0.4.2", "~> 0.4.2"])
|
246
|
-
s.add_runtime_dependency(%q<kodama>, [">= 0.1.
|
245
|
+
s.add_runtime_dependency(%q<kodama>, [">= 0.1.7", "~> 0.1.2"])
|
247
246
|
s.add_runtime_dependency(%q<serverengine>, ["~> 1.5"])
|
248
247
|
s.add_development_dependency(%q<jeweler>, [">= 1.8.8", "~> 1.8"])
|
249
248
|
s.add_development_dependency(%q<rspec>, ["~> 3.0"])
|
@@ -267,7 +266,7 @@ Gem::Specification.new do |s|
|
|
267
266
|
s.add_dependency(%q<treetop>, [">= 1.5.3", "~> 1.5"])
|
268
267
|
s.add_dependency(%q<sys-filesystem>, [">= 1.1.3", "~> 1.1"])
|
269
268
|
s.add_dependency(%q<io-console>, [">= 0.4.2", "~> 0.4.2"])
|
270
|
-
s.add_dependency(%q<kodama>, [">= 0.1.
|
269
|
+
s.add_dependency(%q<kodama>, [">= 0.1.7", "~> 0.1.2"])
|
271
270
|
s.add_dependency(%q<serverengine>, ["~> 1.5"])
|
272
271
|
s.add_dependency(%q<jeweler>, [">= 1.8.8", "~> 1.8"])
|
273
272
|
s.add_dependency(%q<rspec>, ["~> 3.0"])
|
@@ -292,7 +291,7 @@ Gem::Specification.new do |s|
|
|
292
291
|
s.add_dependency(%q<treetop>, [">= 1.5.3", "~> 1.5"])
|
293
292
|
s.add_dependency(%q<sys-filesystem>, [">= 1.1.3", "~> 1.1"])
|
294
293
|
s.add_dependency(%q<io-console>, [">= 0.4.2", "~> 0.4.2"])
|
295
|
-
s.add_dependency(%q<kodama>, [">= 0.1.
|
294
|
+
s.add_dependency(%q<kodama>, [">= 0.1.7", "~> 0.1.2"])
|
296
295
|
s.add_dependency(%q<serverengine>, ["~> 1.5"])
|
297
296
|
s.add_dependency(%q<jeweler>, [">= 1.8.8", "~> 1.8"])
|
298
297
|
s.add_dependency(%q<rspec>, ["~> 3.0"])
|
@@ -37,7 +37,7 @@ module Flydata
|
|
37
37
|
# Start sender(fluentd) process
|
38
38
|
log_info_stdout("Starting FlyData Agent sender process.") unless options[:quiet]
|
39
39
|
raw_start(options)
|
40
|
-
|
40
|
+
|
41
41
|
wait_until_client_ready(options)
|
42
42
|
#wait_until_logs_uploaded
|
43
43
|
fluentd_started = true
|
@@ -117,7 +117,7 @@ EOF
|
|
117
117
|
`[ -f #{pid_file} ] && pgrep -P \`cat #{pid_file}\``.to_i > 0
|
118
118
|
end
|
119
119
|
def kill_all(options = {})
|
120
|
-
if Kernel.system("ps ax | grep 'flydata' | grep -v grep | awk '{print \"kill \" $1}' | sh")
|
120
|
+
if Kernel.system("ps ax | grep 'flydata' | grep -v grep | grep fluentd | awk '{print \"kill \" $1}' | sh")
|
121
121
|
log_info_stdout("Done.") unless options[:quiet]
|
122
122
|
return true
|
123
123
|
else
|
@@ -172,7 +172,7 @@ EOF
|
|
172
172
|
raise "Somthing has gone wrong... Please try setup command again."
|
173
173
|
end
|
174
174
|
def wait_until_client_stop(options = {})
|
175
|
-
retry_count =
|
175
|
+
retry_count = 10
|
176
176
|
1.upto(retry_count) do |i|
|
177
177
|
return true unless process_exist?
|
178
178
|
log_info_stdout("Waiting for the client to stop... (#{i}/#{retry_count})") unless options[:quiet]
|
@@ -57,6 +57,23 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
|
|
57
57
|
config_param :idle_timeout, :time, :default => 1800 # 30 min
|
58
58
|
config_param :check_interval, :integer, :default => 5 # 5 sec
|
59
59
|
config_param :ssl_ca_content, :string, :default => ''
|
60
|
+
config_param :ssl_cipher, :string, :default => nil
|
61
|
+
|
62
|
+
# Secondary ssl cipher is for a workaround to handle 'dh key too small' error
|
63
|
+
# If mysql-server is v5.6.25 or older, and client openssl is
|
64
|
+
# 1.0.1f-1ubuntu-2.15(for ubuntu) or later, client will get the above error because.
|
65
|
+
# the key length returned from mysql-server is only 512 bits.
|
66
|
+
#
|
67
|
+
# In case of dh key error, we retry with non-DH cipher.
|
68
|
+
#
|
69
|
+
# * SECURITY IMPROVEMENT: reject dh keys smaller than 768 bits
|
70
|
+
# https://launchpad.net/ubuntu/+source/openssl/1.0.1f-1ubuntu2.15
|
71
|
+
#
|
72
|
+
# Supported ssl cipher list for mysql(openssl)
|
73
|
+
# https://dev.mysql.com/doc/refman/5.6/en/ssl-options.html
|
74
|
+
|
75
|
+
NON_DH_SSL_CIPHER = "AES256-GCM-SHA384:AES256-SHA:AES256-SHA256:CAMELLIA256-SHA:DES-CBC3-SHA:PSK-3DES-EDE-CBC-SHA:PSK-AES256-CBC-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-RSA-AES-128-CBC-S:SRP-RSA-AES-256-CBC-SHA"
|
76
|
+
config_param :secondary_ssl_cipher, :string, :default => NON_DH_SSL_CIPHER
|
60
77
|
|
61
78
|
def configure(conf)
|
62
79
|
super
|
@@ -110,7 +127,6 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
|
|
110
127
|
h
|
111
128
|
end
|
112
129
|
|
113
|
-
|
114
130
|
# Set context
|
115
131
|
@context = Mysql::Context.new(
|
116
132
|
database: @database, tables: @tables,
|
@@ -162,29 +178,48 @@ EOS
|
|
162
178
|
@context) do |event|
|
163
179
|
@record_dispatcher.dispatch(event)
|
164
180
|
end
|
165
|
-
start_kodama(mysql_url) do |c|
|
166
|
-
c.binlog_position_file = @position_file
|
167
|
-
if @ssl_ca_path.to_s != '' && c.respond_to?(:ssl_ca=)
|
168
|
-
$log.info "SSL is enabled. (ssl_ca: #{@ssl_ca_path})"
|
169
|
-
c.ssl_ca = @ssl_ca_path
|
170
|
-
end
|
171
181
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
182
|
+
current_ssl_cipher = @ssl_cipher
|
183
|
+
retried = false
|
184
|
+
begin
|
185
|
+
start_kodama(mysql_url) do |c|
|
186
|
+
c.binlog_position_file = @position_file
|
187
|
+
if @ssl_ca_path.to_s != '' && c.respond_to?(:ssl_ca=)
|
188
|
+
$log.info "SSL is enabled. (ssl_ca: #{@ssl_ca_path})"
|
189
|
+
c.ssl_ca = @ssl_ca_path
|
190
|
+
unless current_ssl_cipher.to_s.empty?
|
191
|
+
$log.info "SSL cipher is set. (ssl_cipher: #{current_ssl_cipher})"
|
192
|
+
c.ssl_cipher = current_ssl_cipher
|
193
|
+
end
|
194
|
+
end
|
176
195
|
|
177
|
-
|
178
|
-
|
196
|
+
if c.respond_to?(:sent_binlog_position_file=)
|
197
|
+
$log.info "Sent position feature is enabled. sent_position_file:#{@sent_position_file_path}"
|
198
|
+
c.sent_binlog_position_file = @sent_position_file_path
|
199
|
+
end
|
179
200
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
c.
|
201
|
+
$log.info("Binlog position - resume_pos:'#{IO.read(@position_file) rescue IOError}' " +
|
202
|
+
"sent_pos:'#{IO.read(@sent_position_file_path) rescue IOError}'")
|
203
|
+
|
204
|
+
c.connection_retry_limit = @retry_limit
|
205
|
+
c.connection_retry_wait = @retry_wait
|
206
|
+
c.log_level = @log_level.to_sym
|
207
|
+
@listen_events.each do |event_type|
|
208
|
+
$log.trace { "registered binlog event listener '#{event_type}'" }
|
209
|
+
c.send("on_#{event_type}", &method(:event_listener))
|
210
|
+
end
|
211
|
+
end
|
212
|
+
rescue Binlog::Error => e
|
213
|
+
if /dh key too small/.match(e.to_s) && !retried && !@secondary_ssl_cipher.to_s.empty?
|
214
|
+
retried = true
|
215
|
+
current_ssl_cipher = @secondary_ssl_cipher
|
216
|
+
$log.warn("Retry with secondary ssl cipher list due to '#{e}' - secondary_ssl_cipher: '#{@secondary_ssl_cipher}'")
|
217
|
+
retry
|
218
|
+
else
|
219
|
+
raise e
|
186
220
|
end
|
187
221
|
end
|
222
|
+
|
188
223
|
rescue => e
|
189
224
|
# HACK: mysql-replication-listener has a network connection leak bug which doesn't release a connection
|
190
225
|
# to MySQL. Rather than fixing the bug, restarting the fluentd process for now.
|
@@ -185,19 +185,50 @@ describe 'MysqlAlterTableParser' do
|
|
185
185
|
end
|
186
186
|
|
187
187
|
context 'with after option' do
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
188
|
+
context 'without charset' do
|
189
|
+
let(:query) { "alter table test_table add column value varchar(26) after id" }
|
190
|
+
it do
|
191
|
+
expect(subject).to eq({
|
192
|
+
type: :alter_table,
|
193
|
+
table_name: "test_table",
|
194
|
+
actions: [{
|
195
|
+
action: :add_column,
|
196
|
+
column: "value",
|
197
|
+
type: "varchar(78)",
|
198
|
+
after: 'id',
|
199
|
+
query: "add column value varchar(26) after id"
|
200
|
+
}]
|
201
|
+
})
|
202
|
+
end
|
203
|
+
end
|
204
|
+
context 'with charset and collate' do
|
205
|
+
shared_examples "parse character set correctly" do
|
206
|
+
let(:query) { "alter table `kiikplan`.`plan` add column `email_header` varchar(1024) #{charset} utf8 COLLATE utf8_general_ci NULL after `color`" }
|
207
|
+
it do
|
208
|
+
expect(subject).to eq({
|
209
|
+
type: :alter_table,
|
210
|
+
table_name: "plan",
|
211
|
+
actions: [{
|
212
|
+
action: :add_column,
|
213
|
+
column: "email_header",
|
214
|
+
type: "varchar(3072)",
|
215
|
+
cs: "UTF_8",
|
216
|
+
after: 'color',
|
217
|
+
query: "add column `email_header` varchar(1024) #{charset} utf8 COLLATE utf8_general_ci NULL after `color`"
|
218
|
+
}],
|
219
|
+
schema_name: "kiikplan"
|
220
|
+
})
|
221
|
+
end
|
222
|
+
end
|
223
|
+
context "with character set" do
|
224
|
+
let(:charset) { "character set" }
|
225
|
+
include_examples "parse character set correctly"
|
226
|
+
end
|
227
|
+
|
228
|
+
context "with charset" do
|
229
|
+
let(:charset) { "CHARSET" }
|
230
|
+
include_examples "parse character set correctly"
|
231
|
+
end
|
201
232
|
end
|
202
233
|
end
|
203
234
|
shared_examples "generating a flydata record for the given query" do
|
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.5.
|
4
|
+
version: 0.5.1
|
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-
|
15
|
+
date: 2015-08-04 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rest-client
|
@@ -248,7 +248,7 @@ dependencies:
|
|
248
248
|
requirements:
|
249
249
|
- - '>='
|
250
250
|
- !ruby/object:Gem::Version
|
251
|
-
version: 0.1.
|
251
|
+
version: 0.1.7
|
252
252
|
- - ~>
|
253
253
|
- !ruby/object:Gem::Version
|
254
254
|
version: 0.1.2
|
@@ -258,7 +258,7 @@ dependencies:
|
|
258
258
|
requirements:
|
259
259
|
- - '>='
|
260
260
|
- !ruby/object:Gem::Version
|
261
|
-
version: 0.1.
|
261
|
+
version: 0.1.7
|
262
262
|
- - ~>
|
263
263
|
- !ruby/object:Gem::Version
|
264
264
|
version: 0.1.2
|
@@ -488,8 +488,6 @@ files:
|
|
488
488
|
- flydata-core/lib/flydata-core/mysql/compatibility_checker.rb
|
489
489
|
- flydata-core/lib/flydata-core/option_validator.rb
|
490
490
|
- flydata-core/lib/flydata-core/query_job.rb
|
491
|
-
- flydata-core/lib/flydata-core/query_job/redshift.rb
|
492
|
-
- flydata-core/lib/flydata-core/query_job/table_status.rb
|
493
491
|
- flydata-core/lib/flydata-core/record/record.rb
|
494
492
|
- flydata-core/lib/flydata-core/redshift/string.rb
|
495
493
|
- flydata-core/lib/flydata-core/table_def.rb
|
@@ -498,13 +496,13 @@ files:
|
|
498
496
|
- flydata-core/lib/flydata-core/table_def/redshift_table_def.rb
|
499
497
|
- flydata-core/lib/flydata-core/table_def/sync_redshift_table_def.rb
|
500
498
|
- flydata-core/lib/flydata-core/thread_context.rb
|
499
|
+
- flydata-core/lib/flydata-core/wrapper_forwardable.rb
|
501
500
|
- flydata-core/spec/config/user_maintenance_spec.rb
|
502
501
|
- flydata-core/spec/fluent/config_helper_spec.rb
|
503
502
|
- flydata-core/spec/logger_spec.rb
|
504
503
|
- flydata-core/spec/mysql/command_generator_spec.rb
|
505
504
|
- flydata-core/spec/mysql/compatibility_checker.rb
|
506
505
|
- flydata-core/spec/option_validator_spec.rb
|
507
|
-
- flydata-core/spec/query_job/redshift_spec.rb
|
508
506
|
- flydata-core/spec/redshift/string_spec.rb
|
509
507
|
- flydata-core/spec/spec_helper.rb
|
510
508
|
- flydata-core/spec/table_def/autoload_redshift_table_def_spec.rb
|
@@ -525,6 +523,7 @@ files:
|
|
525
523
|
- flydata-core/spec/table_def/mysqldump_test_unsigned.dump
|
526
524
|
- flydata-core/spec/table_def/redshift_table_def_spec.rb
|
527
525
|
- flydata-core/spec/table_def/sync_redshift_table_def_spec.rb
|
526
|
+
- flydata-core/spec/wrapper_forwardable_spec.rb
|
528
527
|
- flydata.gemspec
|
529
528
|
- lib/fly_data_model.rb
|
530
529
|
- lib/flydata.rb
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'flydata-core/table_def/redshift_table_def'
|
2
|
-
|
3
|
-
module FlydataCore
|
4
|
-
module QueryJob
|
5
|
-
|
6
|
-
class Redshift
|
7
|
-
# returns a list of table names used in the Query Job system.
|
8
|
-
def self.target_table_names(flydata_table_names)
|
9
|
-
flydata_table_names = [ flydata_table_names ] unless flydata_table_names.kind_of?(Array)
|
10
|
-
|
11
|
-
flydata_table_names.collect {|flydata_table_name|
|
12
|
-
redshift_table_name = TableDef::RedshiftTableDef.convert_to_valid_table_name(flydata_table_name)
|
13
|
-
table_names = [ redshift_table_name ]
|
14
|
-
if redshift_table_name != flydata_table_name
|
15
|
-
# for backward compatibility
|
16
|
-
# Old implementation used FlyData table names. To support it, the
|
17
|
-
# method adds the flydata_table_name as well.
|
18
|
-
table_names << flydata_table_name
|
19
|
-
end
|
20
|
-
|
21
|
-
table_names
|
22
|
-
}.flatten
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
require 'flydata-core/query_job/redshift'
|
2
|
-
require 'flydata-core/table_def/redshift_table_def'
|
3
|
-
|
4
|
-
module FlydataCore
|
5
|
-
module QueryJob
|
6
|
-
|
7
|
-
class TableStatus
|
8
|
-
@@domain = 'flydata_redshift_table_status'
|
9
|
-
|
10
|
-
def self.domain=(domain)
|
11
|
-
@@domain = domain
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.sdb=(sdb)
|
15
|
-
@@sdb = sdb
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.where(*args)
|
19
|
-
table_status_items = {}
|
20
|
-
@@sdb.domains[@@domain].items.where(*args).each(select: :all) do |item|
|
21
|
-
class << item
|
22
|
-
# returns the corect (Redshift) table name
|
23
|
-
def table_name
|
24
|
-
FlydataCore::TableDef::RedshiftTableDef.convert_to_valid_table_name(attributes['table_name'].first)
|
25
|
-
end
|
26
|
-
|
27
|
-
def target_table_names
|
28
|
-
FlydataCore::QueryJob::Redshift.target_table_names(attributes['table_name'].first)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
tn = item.attributes['table_name'].first
|
32
|
-
redshift_table_name = FlydataCore::TableDef::RedshiftTableDef.convert_to_valid_table_name(tn)
|
33
|
-
if redshift_table_name == tn
|
34
|
-
table_status_items[redshift_table_name] ||= item
|
35
|
-
else
|
36
|
-
table_status_items[redshift_table_name] = item
|
37
|
-
end
|
38
|
-
end
|
39
|
-
table_status_items.values
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'flydata-core/query_job/redshift'
|
3
|
-
|
4
|
-
module FlydataCore::QueryJob
|
5
|
-
|
6
|
-
describe Redshift do
|
7
|
-
describe '.target_table_names' do
|
8
|
-
subject { described_class.target_table_names(flydata_table_names) }
|
9
|
-
|
10
|
-
context 'with a single table name' do
|
11
|
-
let(:flydata_table_names) { "my_table" }
|
12
|
-
|
13
|
-
it { is_expected.to eq [ flydata_table_names ] }
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'with multiples table names' do
|
17
|
-
let(:flydata_table_names) { %w(my_table1 my_table2) }
|
18
|
-
|
19
|
-
it { is_expected.to eq flydata_table_names }
|
20
|
-
end
|
21
|
-
context 'with a mixed case table name' do
|
22
|
-
let(:flydata_table_names) { "MyTable" }
|
23
|
-
|
24
|
-
it { is_expected.to eq [ flydata_table_names.downcase, flydata_table_names ] }
|
25
|
-
end
|
26
|
-
context 'with table names including mixed case one' do
|
27
|
-
let(:flydata_table_names) { %w(MyTable my_table2) }
|
28
|
-
|
29
|
-
it { is_expected.to eq %w(mytable MyTable my_table2) }
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|