flydata 0.3.18 → 0.3.19

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3241033fa80c1499392963ab77db563fdb091edf
4
- data.tar.gz: 8181f5f09d622da94e2bb28d84ec6b74818327b9
3
+ metadata.gz: fb027d1283d4bc0ba51a57444fd0c864d8611675
4
+ data.tar.gz: 2d2b13d509dfffb4903b5d47291c8d981c166148
5
5
  SHA512:
6
- metadata.gz: abb67f659a55b01c1aeb726ba4602d430cebe83d0177f3c40e7db646895a39e4db63b9a7619cf8010e7c266e4f2d956d6809f92097b37ed09f685446041feb54
7
- data.tar.gz: a549a175a8a383f15d02999d739c98e6023134e58e047608e4fe3d68af40a9c80c7c01bfcef6dccaab08812e3ac5b3c5148e1fa61667a9f2a0ab90aaf836d00f
6
+ metadata.gz: 7fb220f5741f887dbef704517432a62a7843bdfc26918a7cfd2553e3bea49fdd93a346aac977dacf5ccf97ddb4a010704f15eea1ef0644dca4ec35d5027b097b
7
+ data.tar.gz: 302b30c6205a8289b1ef4ad6ed983bc0f5f6b13b7486426276f8f9efe3f99dfd2dc225067db6464a69974c72fbf1f5aeb25264e80ec645250405fb16c146e708
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.18
1
+ 0.3.19
@@ -0,0 +1,25 @@
1
+ module FlydataCore
2
+ module Redshift
3
+
4
+ class String
5
+ # Redshift supports UTF-8 but it enforces stricter rule than other
6
+ # implementations such as MySQL or Ruby. This method returns a
7
+ # Redshift-safe string from the given string.
8
+ def self.encode(string, options = {})
9
+ result = string.encoding == Encoding::UTF_8 ?
10
+ string.encode(Encoding::UTF_16, options).encode(Encoding::UTF_8) :
11
+ string.encode(Encoding::UTF_8, options)
12
+ rep_str = options[:replace] || "\uFFFD"
13
+ result.each_codepoint.with_index(0) do |cp, i|
14
+ # Per Redshift document
15
+ # http://docs.aws.amazon.com/redshift/latest/dg/multi-byte-character-load-errors.html
16
+ if cp >= 0xFDD0 && cp <= 0xFDEF || cp == 0xFFFE || cp == 0xFFFF
17
+ result[i] = rep_str
18
+ end
19
+ end
20
+ result
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -322,11 +322,13 @@ EOS
322
322
  end
323
323
 
324
324
  def self.parse_date(value)
325
- dt = Date.parse(convert_year_into_date(value))
325
+ return nil if value.nil?
326
+ value_str = value.to_s
327
+ dt = Date.parse(convert_year_into_date(value_str))
326
328
  dt.strftime('%Y-%m-%d')
327
329
  rescue ArgumentError => ae
328
330
  # '0000-00-00' is valid for mysql date column
329
- return '0001-01-01' if value == '0000-00-00'
331
+ return '0001-01-01' if value_str == '0000-00-00'
330
332
  raise ae
331
333
  end
332
334
 
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+ require 'flydata-core/redshift/string'
3
+
4
+ module FlydataCore
5
+ module Redshift
6
+
7
+ describe String do
8
+ let(:subject_object) { described_class }
9
+
10
+ describe '.encode' do
11
+ subject { subject_object.encode(string, options) }
12
+ let(:result) { string.encode(Encoding::UTF_8) }
13
+
14
+ shared_examples "converting string to a Redshift friendly string" do
15
+ before do
16
+ string.encode!(src_encoding)
17
+ end
18
+ it do
19
+ is_expected.to eq result
20
+ end
21
+ end
22
+ shared_examples "converting an invalid string to raise an error" do
23
+ before do
24
+ string.encode!(src_encoding)
25
+ end
26
+ it do
27
+ expect{subject}.to raise_error error
28
+ end
29
+ end
30
+
31
+ context "with replace option" do
32
+ let(:options) { { invalid: :replace, undef: :replace } }
33
+ context 'UTF-8 string' do
34
+ let(:src_encoding) { Encoding::UTF_8 }
35
+ context 'valid char' do
36
+ let(:string) { "Straße" }
37
+
38
+ it_behaves_like "converting string to a Redshift friendly string"
39
+ end
40
+ context 'invalid char' do
41
+ let(:string) { "\xeb\x13\x00" }
42
+ let(:result) { "\uFFFD\u0013\u0000".encode(Encoding::UTF_8) }
43
+
44
+ it_behaves_like "converting string to a Redshift friendly string"
45
+ end
46
+ context 'invalid char for Redshift (error 6)' do
47
+ let(:string) { "\xef\xb7\x91" }
48
+ let(:result) { "\uFFFD".encode(Encoding::UTF_8) }
49
+
50
+ it_behaves_like "converting string to a Redshift friendly string"
51
+ end
52
+ context 'invalid char for Redshift (error 7)' do
53
+ let(:string) { "\xef\xbf\xbf" }
54
+ let(:result) { "\uFFFD".encode(Encoding::UTF_8) }
55
+
56
+ it_behaves_like "converting string to a Redshift friendly string"
57
+ end
58
+ end
59
+ context 'Shift JIS string' do
60
+ let(:src_encoding) { Encoding::SHIFT_JIS }
61
+ let(:string) { "テスト" }
62
+ it_behaves_like "converting string to a Redshift friendly string"
63
+ end
64
+ end
65
+ context 'without replace option' do
66
+ let(:options) { {} }
67
+ context 'UTF-8 string' do
68
+ let(:src_encoding) { Encoding::UTF_8 }
69
+ context 'valid char' do
70
+ let(:string) { "Straße" }
71
+
72
+ it_behaves_like "converting string to a Redshift friendly string"
73
+ end
74
+ context 'invalid char' do
75
+ let(:string) { "\xeb\x13\x00" }
76
+ let(:error) { Encoding::InvalidByteSequenceError }
77
+
78
+ it_behaves_like "converting an invalid string to raise an error"
79
+ end
80
+ context 'invalid char for Redshift (error 6)' do
81
+ let(:string) { "\xef\xb7\x91" }
82
+ let(:result) { "\uFFFD".encode(Encoding::UTF_8) }
83
+
84
+ # Redshift invalid characters are replaced regardless of options
85
+ it_behaves_like "converting string to a Redshift friendly string"
86
+ end
87
+ context 'invalid char for Redshift (error 7)' do
88
+ let(:string) { "\xef\xbf\xbf" }
89
+ let(:result) { "\uFFFD".encode(Encoding::UTF_8) }
90
+
91
+ # Redshift invalid characters are replaced regardless of options
92
+ it_behaves_like "converting string to a Redshift friendly string"
93
+ end
94
+ end
95
+ context 'Shift JIS string' do
96
+ let(:src_encoding) { Encoding::SHIFT_JIS }
97
+ let(:string) { "テスト" }
98
+ it_behaves_like "converting string to a Redshift friendly string"
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ end
105
+ end
106
+
@@ -625,16 +625,21 @@ EOT
625
625
  end
626
626
  end
627
627
 
628
- describe '.convert_year_into_date' do
628
+ describe '.parse_date' do
629
629
  let(:value) { nil }
630
- subject { described_class.convert_year_into_date(value) }
630
+ subject { described_class.parse_date(value) }
631
631
 
632
632
  context 'with year values' do
633
- context 'with value 0' do
633
+ context 'with value string 0' do
634
634
  let(:value){ '0' }
635
635
  it { is_expected.to eq('0001-01-01') }
636
636
  end
637
637
 
638
+ context 'with value int 0' do
639
+ let(:value){ 0 }
640
+ it { is_expected.to eq('0001-01-01') }
641
+ end
642
+
638
643
  context 'with value 0000' do
639
644
  let(:value){ '0000' }
640
645
  it { is_expected.to eq('0001-01-01') }
@@ -672,9 +677,13 @@ EOT
672
677
 
673
678
  context 'with zero date' do
674
679
  let(:value){ '0000-00-00' }
675
- it_behaves_like "returning the input value as is"
680
+ it { is_expected.to eq('0001-01-01') }
676
681
  end
677
682
  end
683
+
684
+ context 'with nil' do
685
+ it { is_expected.to eq(nil) }
686
+ end
678
687
  end
679
688
  end
680
689
 
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.3.18 ruby lib
5
+ # stub: flydata 0.3.19 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "flydata"
9
- s.version = "0.3.18"
9
+ s.version = "0.3.19"
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-04-24"
14
+ s.date = "2015-05-12"
15
15
  s.description = "FlyData Agent"
16
16
  s.email = "sysadmin@flydata.com"
17
17
  s.executables = ["fdmysqldump", "flydata", "serverinfo"]
@@ -48,6 +48,7 @@ Gem::Specification.new do |s|
48
48
  "flydata-core/lib/flydata-core/fluent/config_helper.rb",
49
49
  "flydata-core/lib/flydata-core/logger.rb",
50
50
  "flydata-core/lib/flydata-core/record/record.rb",
51
+ "flydata-core/lib/flydata-core/redshift/string.rb",
51
52
  "flydata-core/lib/flydata-core/table_def.rb",
52
53
  "flydata-core/lib/flydata-core/table_def/mysql_table_def.rb",
53
54
  "flydata-core/lib/flydata-core/table_def/redshift_table_def.rb",
@@ -55,6 +56,7 @@ Gem::Specification.new do |s|
55
56
  "flydata-core/spec/config/user_maintenance_spec.rb",
56
57
  "flydata-core/spec/fluent/config_helper_spec.rb",
57
58
  "flydata-core/spec/logger_spec.rb",
59
+ "flydata-core/spec/redshift/string_spec.rb",
58
60
  "flydata-core/spec/spec_helper.rb",
59
61
  "flydata-core/spec/table_def/mysql_table_def_spec.rb",
60
62
  "flydata-core/spec/table_def/mysql_to_redshift_table_def_spec.rb",
@@ -420,7 +420,7 @@ EOM
420
420
  end
421
421
  end
422
422
 
423
- log_info_stdout("Exporting data from the database.")
423
+ log_info_stdout("Setting binary log position and exporting data from the database.")
424
424
  log_info_stdout("This process can take hours depending on data size and load on your database. Please be patient...")
425
425
  if file_dump
426
426
  begin
@@ -100,26 +100,43 @@ module Flydata
100
100
  end
101
101
 
102
102
  def check_mysql_user_compat
103
- client = Mysql2::Client.new(@db_opts)
103
+ databases = ['mysql', @db_opts[:database]]
104
+ get_grant_regex = /GRANT (?<privs>.*) ON (`)?(?<db_name>[^`]*)(`)?\.\* TO '#{@db_opts[:username]}/
105
+ necessary_permission_fields = ["SELECT","RELOAD","LOCK TABLES","REPLICATION SLAVE","REPLICATION CLIENT"]
106
+ all_privileges_field = ["ALL PRIVILEGES"]
107
+
108
+ # Do not catch MySQL connection problem because check should stop if no MySQL connection can be made.
104
109
  grants_sql = "SHOW GRANTS"
105
- correct_db = ["ON (\\*|(`)?#{@db_opts[:database]}(`)?).","TO '#{@db_opts[:username]}"]
106
- necessary_permission_fields= ["SELECT","RELOAD","LOCK TABLES","REPLICATION SLAVE","REPLICATION CLIENT"]
107
- all_privileges_field= ["ALL PRIVILEGES"]
110
+ client = Mysql2::Client.new(@db_opts)
108
111
  result = client.query(grants_sql)
109
- # Do not catch MySQL connection problem because check should stop if no MySQL connection can be made.
110
112
  client.close
111
- found_priv = []
113
+
114
+ found_priv = Hash[databases.map {|d| [d,[]]}]
115
+ missing_priv = {}
116
+
112
117
  result.each do |res|
113
118
  # SHOW GRANTS should only return one column
114
119
  res_value = res.values.first
115
- if correct_db.all? {|perm| res_value.match(perm)}
116
- necessary_permission_fields.each do |priv|
117
- found_priv << priv if res_value.match(priv)
120
+ matched_values = res_value.match(get_grant_regex)
121
+ next unless matched_values
122
+ line_priv = matched_values["privs"].split(", ")
123
+ if matched_values["db_name"] == "*"
124
+ return true if (all_privileges_field - line_priv).empty?
125
+ databases.each {|d| found_priv[d] << line_priv }
126
+ elsif databases.include? matched_values["db_name"]
127
+ if (all_privileges_field - line_priv).empty?
128
+ found_priv[matched_values["db_name"]] = necessary_permission_fields
129
+ else
130
+ found_priv[matched_values["db_name"]] << line_priv
118
131
  end
119
- return true if (necessary_permission_fields-found_priv).empty? or all_privileges_field.all? {|d| res_value.match(d)}
120
132
  end
133
+ missing_priv = get_missing_privileges(found_priv, necessary_permission_fields)
134
+ return true if missing_priv.empty?
121
135
  end
122
- raise MysqlCompatibilityError, "The user '#{@db_opts[:username]}' does not have the correct permissions to run FlyData Sync\n * These privileges are missing: #{(necessary_permission_fields-found_priv).join(", ")}"
136
+ error_text = "The user '#{@db_opts[:username]}' does not have the correct permissions to run FlyData Sync\n"
137
+ error_text << " * These privileges are missing...\n"
138
+ missing_priv.each_key {|db| error_text << " for the database '#{db}': #{missing_priv[db].join(", ")}\n"}
139
+ raise MysqlCompatibilityError, error_text
123
140
  end
124
141
 
125
142
  def check_mysql_protocol_tcp_compat
@@ -221,6 +238,15 @@ module Flydata
221
238
  end
222
239
  end
223
240
 
241
+ def get_missing_privileges(found_priv, all_priv)
242
+ return_hash = {}
243
+ found_priv.each_key do |key|
244
+ missing_priv = all_priv - found_priv[key].flatten.uniq
245
+ return_hash[key] = missing_priv unless missing_priv.empty?
246
+ end
247
+ return_hash
248
+ end
249
+
224
250
  def run_mysql_retention_check(mysql_client)
225
251
  expire_logs_days_limit = BINLOG_RETENTION_HOURS / 24
226
252
  sel_query = SELECT_QUERY_TMPLT % '@@expire_logs_days'
@@ -80,8 +80,16 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
80
80
 
81
81
  $log.info "mysql host:\"#{@host}\" port:\"#{@port}\" username:\"#{@username}\" database:\"#{@database}\" tables:\"#{@tables}\" tables_append_only:\"#{tables_append_only}\""
82
82
  $log.info "mysql client version: #{`mysql -V`}"
83
- server_version = `echo 'select version();' | #{Flydata::Mysql::MysqlUtil.generate_mysql_cmd(@db_opts)} 2>/dev/null`
84
- $log.info "mysql server version: #{server_version}"
83
+ server_msg = `echo 'select version();' | #{Flydata::Mysql::MysqlUtil.generate_mysql_cmd(@db_opts)} 2>&1`
84
+ server_msg = server_msg.each_line.select{|l| l.start_with?('ERROR ')}.join("\n")
85
+ if ($?.exitstatus == 0)
86
+ $log.info "mysql server version: #{server_msg.strip}"
87
+ else
88
+ err_msg = "Failed to access mysql server... #{server_msg.strip}"
89
+ $log.error err_msg
90
+ $stderr.puts err_msg
91
+ #exit 1 # causes retry loop
92
+ end
85
93
 
86
94
  @tables = @tables.split(/,\s*/)
87
95
  @omit_events = Hash.new
@@ -33,6 +33,7 @@ Received unsupported alter table query. normalized query:'#{record['normalized_q
33
33
  EOS
34
34
  $log.error(msg)
35
35
  end
36
+ $log.info(ret) # log all alter table events even if the table is not subject to sync. This is for troubleshooting purpose.
36
37
  ret
37
38
  end
38
39
  end
@@ -217,7 +217,7 @@ EOS
217
217
 
218
218
  def initialize(db_opts)
219
219
  #TODO : Pass timeout in as a setting from the data entry
220
- super(db_opts.merge(read_timeout: 1800))
220
+ super(db_opts.merge(read_timeout: 3600))
221
221
  end
222
222
 
223
223
  def query(sql, options = {})
@@ -35,6 +35,12 @@ module Flydata
35
35
  end
36
36
 
37
37
  describe MysqlCompatibilityCheck do
38
+ let(:default_data_port) do
39
+ {
40
+ "servers"=>["sample-test-site.com"]
41
+ }
42
+ end
43
+
38
44
  let(:default_mysql_cred) do
39
45
  {
40
46
  "host" => "test",
@@ -44,69 +50,84 @@ module Flydata
44
50
  "database" => "test_db"
45
51
  }
46
52
  end
53
+
47
54
  describe "#check_mysql_user_compat" do
48
55
  let(:client) { double('client') }
49
- subject { MysqlCompatibilityCheck.new({},:default_mysql_cred) }
56
+ subject { MysqlCompatibilityCheck.new(default_data_port, default_mysql_cred) }
50
57
  before do
51
58
  allow(Mysql2::Client).to receive(:new).and_return(client)
52
59
  allow(client).to receive(:close)
53
60
  end
54
61
 
55
- context "with all privileges for privileges all in one database" do
62
+ context "with all privileges in all databases" do
56
63
  before do
57
- allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT SELECT, LOCK TABLES, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT ON `test_db`.* TO 'test'@'host"}])
64
+ allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT ALL PRIVILEGES ON *.* TO 'test'@'host"}])
58
65
  end
59
66
  it do
60
- expect{subject.check_mysql_user_compat}
67
+ expect{subject.check_mysql_user_compat}.to_not raise_error
61
68
  end
62
69
  end
63
- context "with missing privileges for privileges all in one database" do
70
+ context "with missing privileges in one database" do
64
71
  before do
65
- allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT SELECT, RELOAD, REPLICATION CLIENT ON `test_db`.* TO 'test'@'host"}])
72
+ allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT ALL PRIVILEGES ON 'mysql'.* TO 'test'@'host"},
73
+ {"Grants for test"=>"GRANT SELECT, RELOAD, REPLICATION CLIENT ON `test_db`.* TO 'test'@'host"}])
66
74
  end
67
75
  it do
68
- expect{subject.check_mysql_user_compat}.to raise_error(Flydata::MysqlCompatibilityCheck::MysqlCompatibilityError, /LOCK TABLES, REPLICATION SLAVE/)
76
+ expect{subject.check_mysql_user_compat}.to raise_error(Flydata::MysqlCompatibilityCheck::MysqlCompatibilityError, /test_db': LOCK TABLES, REPLICATION SLAVE/)
69
77
  end
70
78
  end
71
- context "with all privileges for privileges in between all and specific databases" do
79
+ context "with all required privileges in between all and specific databases" do
72
80
  before do
73
81
  allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT RELOAD, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'test'@'host"},
74
- {"Grants for test"=>"GRANT SELECT, LOCK TABLES ON `test_db`.* TO 'test'@'host"}])
82
+ {"Grants for test"=>"GRANT SELECT, LOCK TABLES ON `test_db`.* TO 'test'@'host"},
83
+ {"Grants for test"=>"GRANT SELECT, LOCK TABLES ON `mysql`.* TO 'test'@'host"}])
75
84
  end
76
85
  it do
77
- expect{subject.check_mysql_user_compat}
86
+ expect{subject.check_mysql_user_compat}.to_not raise_error
78
87
  end
79
88
  end
80
- context "with missing privileges for privileges in between all and specific databases" do
89
+ context "with missing privileges in each database" do
81
90
  before do
82
91
  allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'test'@'host"},
83
- {"Grants for test"=>"GRANT SELECT, LOCK TABLES ON `test_db`.* TO 'test'@'host"}])
92
+ {"Grants for test"=>"GRANT SELECT, LOCK TABLES ON `test_db`.* TO 'test'@'host"},
93
+ {"Grants for test"=>"GRANT SELECT, LOCK TABLES ON `mysql`.* TO 'test'@'host"}])
84
94
  end
85
95
  it do
86
- expect{subject.check_mysql_user_compat}.to raise_error(Flydata::MysqlCompatibilityCheck::MysqlCompatibilityError, /RELOAD/)
96
+ expect{subject.check_mysql_user_compat}.to raise_error(Flydata::MysqlCompatibilityCheck::MysqlCompatibilityError, /mysql': RELOAD\n.*test_db': RELOAD/)
87
97
  end
88
98
  end
89
- context "with all privileges for privileges in all databases" do
99
+ context "with all required privileges in all databases" do
90
100
  before do
91
101
  allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT SELECT, LOCK TABLES, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'test'@'host"}])
92
102
  end
93
103
  it do
94
- expect{subject.check_mysql_user_compat}
104
+ expect{subject.check_mysql_user_compat}.to_not raise_error
95
105
  end
96
106
  end
97
- context "with missing privileges for privileges in all databases" do
107
+ context "with missing privileges in all databases" do
98
108
  before do
99
109
  allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT RELOAD, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'test'@'host"}])
100
110
  end
101
111
  it do
102
- expect{subject.check_mysql_user_compat}.to raise_error(Flydata::MysqlCompatibilityCheck::MysqlCompatibilityError, /SELECT, LOCK TABLES/)
112
+ expect{subject.check_mysql_user_compat}.to raise_error(Flydata::MysqlCompatibilityCheck::MysqlCompatibilityError, /mysql': SELECT, LOCK TABLES\n.*test_db': SELECT, LOCK TABLES/)
113
+ end
114
+ end
115
+ context "with privileges for other databases only" do
116
+ before do
117
+ allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT REPLICATION CLIENT ON `test_db_01`.* TO 'test'@'host"},
118
+ {"Grants for test"=>"GRANT LOCK TABLES ON `test_db_02`.* TO 'test'@'host"},
119
+ {"Grants for test"=>"GRANT SELECT ON `text_db_03`.* TO 'test'@'host"}])
120
+ end
121
+ it do
122
+ expect{subject.check_mysql_user_compat}.to raise_error(Flydata::MysqlCompatibilityCheck::MysqlCompatibilityError, /mysql': SELECT, RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT\n.*test_db': SELECT, RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT/)
103
123
  end
104
124
  end
105
125
 
106
126
  end
127
+
107
128
  describe "#check_mysql_binlog_retention" do
108
129
  context "on on-premise mysql server" do
109
- subject { MysqlCompatibilityCheck.new({},:default_mysql_cred) }
130
+ subject { MysqlCompatibilityCheck.new(default_data_port, default_mysql_cred) }
110
131
  context "where retention is below limit" do
111
132
  let(:client) { double('client') }
112
133
  before do
@@ -124,10 +145,11 @@ module Flydata
124
145
  before do
125
146
  allow(Mysql2::Client).to receive(:new).and_return(client)
126
147
  allow(client).to receive(:query).and_return([{"@@expire_logs_days"=>0}])
148
+ allow(client).to receive(:close)
127
149
  allow(subject).to receive(:is_rds?).and_return(false)
128
150
  end
129
151
  it do
130
- expect{subject.check_mysql_binlog_retention}
152
+ expect{subject.check_mysql_binlog_retention}.to_not raise_error
131
153
  end
132
154
  end
133
155
  context "where retention is above limit" do
@@ -135,15 +157,16 @@ module Flydata
135
157
  before do
136
158
  allow(Mysql2::Client).to receive(:new).and_return(client)
137
159
  allow(client).to receive(:query).and_return([{"@@expire_logs_days"=>11}])
160
+ allow(client).to receive(:close)
138
161
  allow(subject).to receive(:is_rds?).and_return(false)
139
162
  end
140
163
  it do
141
- expect{subject.check_mysql_binlog_retention}
164
+ expect{subject.check_mysql_binlog_retention}.to_not raise_error
142
165
  end
143
166
  end
144
167
  end
145
168
  context "on RDS" do
146
- subject { MysqlCompatibilityCheck.new({},:default_mysql_cred) }
169
+ subject { MysqlCompatibilityCheck.new(default_data_port, default_mysql_cred) }
147
170
  context "where retention period is nil" do
148
171
  let(:client) { double('client') }
149
172
  before do
@@ -180,7 +203,7 @@ module Flydata
180
203
  allow(subject).to receive(:is_rds?).and_return(true)
181
204
  end
182
205
  it do
183
- expect{subject.check_mysql_binlog_retention}
206
+ expect{subject.check_mysql_binlog_retention}.to_not raise_error
184
207
  end
185
208
  end
186
209
  context "where user has no access to rds configuration" do
@@ -193,7 +216,7 @@ module Flydata
193
216
  allow(subject).to receive(:is_rds?).and_return(true)
194
217
  end
195
218
  it do
196
- expect{subject.check_mysql_binlog_retention}
219
+ expect{subject.check_mysql_binlog_retention}.to_not raise_error
197
220
  end
198
221
  end
199
222
  end
@@ -212,7 +235,7 @@ module Flydata
212
235
  let(:engine_table) { {"table_name"=>"engine_table", "table_type"=>"BASE TABLE", "engine"=>"MEMORY"} }
213
236
  let(:view) { {"table_name"=>"view_table", "table_type"=>"VIEW", "engine"=>nil} }
214
237
  let(:client) { double('client') }
215
- let(:subject_object) { MysqlCompatibilityCheck.new(:default_data_port,test_data_entry, {}) }
238
+ let(:subject_object) { MysqlCompatibilityCheck.new(default_data_port,test_data_entry, {}) }
216
239
  let(:error) { Flydata::MysqlCompatibilityCheck::MysqlCompatibilityError }
217
240
  let(:base_error_msg) { "FlyData does not support VIEW and MEMORY ENGINE table. Remove following tables from data entry: %s" }
218
241
  subject { subject_object.check_mysql_table_types }
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.3.18
4
+ version: 0.3.19
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-04-24 00:00:00.000000000 Z
15
+ date: 2015-05-12 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rest-client
@@ -471,6 +471,7 @@ files:
471
471
  - flydata-core/lib/flydata-core/fluent/config_helper.rb
472
472
  - flydata-core/lib/flydata-core/logger.rb
473
473
  - flydata-core/lib/flydata-core/record/record.rb
474
+ - flydata-core/lib/flydata-core/redshift/string.rb
474
475
  - flydata-core/lib/flydata-core/table_def.rb
475
476
  - flydata-core/lib/flydata-core/table_def/mysql_table_def.rb
476
477
  - flydata-core/lib/flydata-core/table_def/redshift_table_def.rb
@@ -478,6 +479,7 @@ files:
478
479
  - flydata-core/spec/config/user_maintenance_spec.rb
479
480
  - flydata-core/spec/fluent/config_helper_spec.rb
480
481
  - flydata-core/spec/logger_spec.rb
482
+ - flydata-core/spec/redshift/string_spec.rb
481
483
  - flydata-core/spec/spec_helper.rb
482
484
  - flydata-core/spec/table_def/mysql_table_def_spec.rb
483
485
  - flydata-core/spec/table_def/mysql_to_redshift_table_def_spec.rb