flydata 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/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
|