flydata 0.6.3 → 0.6.4
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/Rakefile +2 -2
- data/VERSION +1 -1
- data/bin/fdredshift +78 -0
- data/circle.yml +1 -1
- data/ext/flydata/{parser/mysql → source_mysql/parser}/.gitignore +0 -0
- data/ext/flydata/{parser/mysql → source_mysql/parser}/dump_parser_ext.cpp +3 -3
- data/ext/flydata/source_mysql/parser/extconf.rb +3 -0
- data/ext/flydata/{parser/mysql → source_mysql/parser}/parser.txt +0 -0
- data/ext/flydata/{parser/mysql → source_mysql/parser}/sql_parser.cpp +0 -0
- data/ext/flydata/{parser/mysql → source_mysql/parser}/sql_parser.h +0 -0
- data/flydata-core/lib/flydata-core/mysql/binlog_pos.rb +34 -32
- data/flydata-core/lib/flydata-core/mysql/compatibility_checker.rb +20 -0
- data/flydata-core/lib/flydata-core/table_def/mysql_table_def.rb +12 -4
- data/flydata-core/lib/flydata-core/table_def/redshift_table_def.rb +60 -6
- data/flydata-core/spec/mysql/binlog_pos_spec.rb +474 -0
- data/flydata-core/spec/table_def/mysql_table_def_spec.rb +57 -0
- data/flydata-core/spec/table_def/mysql_to_redshift_table_def_spec.rb +174 -20
- data/flydata-core/spec/table_def/mysqldump_test_col_comment_with_AUTO_INCREMENT_keyword.dump +43 -0
- data/flydata-core/spec/table_def/mysqldump_test_col_comment_with_not_null_keyword.dump +43 -0
- data/flydata-core/spec/table_def/mysqldump_test_col_comment_with_unique_keyword.dump +43 -0
- data/flydata-core/spec/table_def/mysqldump_test_col_comment_with_unsigned_keyword.dump +43 -0
- data/flydata-core/spec/table_def/redshift_table_def_spec.rb +41 -8
- data/flydata.gemspec +0 -0
- data/lib/flydata/cli.rb +11 -5
- data/lib/flydata/command/base.rb +14 -1
- data/lib/flydata/command/exclusive_runnable.rb +42 -12
- data/lib/flydata/command/helper.rb +6 -6
- data/lib/flydata/command/sender.rb +4 -3
- data/lib/flydata/command/setup.rb +30 -381
- data/lib/flydata/command/stop.rb +1 -0
- data/lib/flydata/command/sync.rb +273 -301
- data/lib/flydata/compatibility_check.rb +24 -117
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +3 -3
- data/lib/flydata/fluent-plugins/mysql/alter_table_query_handler.rb +2 -2
- data/lib/flydata/fluent-plugins/mysql/binlog_record_handler.rb +6 -6
- data/lib/flydata/fluent-plugins/mysql/truncate_table_query_handler.rb +0 -1
- data/lib/flydata/parser.rb +14 -0
- data/lib/flydata/{parser_provider.rb → parser/parser_provider.rb} +6 -4
- data/lib/flydata/parser/source_table.rb +33 -0
- data/lib/flydata/source.rb +105 -0
- data/lib/flydata/source/component.rb +21 -0
- data/lib/flydata/source/errors.rb +7 -0
- data/lib/flydata/source/generate_source_dump.rb +72 -0
- data/lib/flydata/source/parse_dump_and_send.rb +52 -0
- data/lib/flydata/source/setup.rb +31 -0
- data/lib/flydata/source/source_pos.rb +45 -0
- data/lib/flydata/source/sync.rb +56 -0
- data/lib/flydata/source/sync_generate_table_ddl.rb +43 -0
- data/lib/flydata/source_file/setup.rb +17 -0
- data/lib/flydata/source_file/sync.rb +14 -0
- data/lib/flydata/{command → source_mysql/command}/mysql.rb +2 -1
- data/lib/flydata/{command → source_mysql/command}/mysql_command_base.rb +2 -4
- data/lib/flydata/{command → source_mysql/command}/mysqlbinlog.rb +2 -1
- data/lib/flydata/{command → source_mysql/command}/mysqldump.rb +2 -1
- data/lib/flydata/source_mysql/generate_source_dump.rb +53 -0
- data/lib/flydata/source_mysql/mysql_compatibility_check.rb +114 -0
- data/lib/flydata/source_mysql/parse_dump_and_send.rb +28 -0
- data/lib/flydata/{parser/mysql → source_mysql/parser}/.gitignore +0 -0
- data/lib/flydata/{parser/mysql → source_mysql/parser}/dump_parser.rb +32 -67
- data/lib/flydata/{parser/mysql → source_mysql/parser}/mysql_alter_table.treetop +0 -0
- data/lib/flydata/source_mysql/setup.rb +24 -0
- data/lib/flydata/source_mysql/source_pos.rb +21 -0
- data/lib/flydata/source_mysql/sync.rb +45 -0
- data/lib/flydata/source_mysql/sync_generate_table_ddl.rb +40 -0
- data/lib/flydata/{mysql → source_mysql}/table_ddl.rb +6 -17
- data/lib/flydata/source_zendesk/sync_generate_table_ddl.rb +30 -0
- data/lib/flydata/source_zendesk/zendesk_flydata_tabledefs.rb +133 -0
- data/lib/flydata/sync_file_manager.rb +132 -73
- data/lib/flydata/table_ddl.rb +18 -0
- data/spec/flydata/cli_spec.rb +1 -0
- data/spec/flydata/command/exclusive_runnable_spec.rb +19 -8
- data/spec/flydata/command/sender_spec.rb +1 -1
- data/spec/flydata/command/setup_spec.rb +4 -4
- data/spec/flydata/command/sync_spec.rb +97 -134
- data/spec/flydata/compatibility_check_spec.rb +16 -289
- data/spec/flydata/fluent-plugins/mysql/alter_table_query_handler_spec.rb +3 -3
- data/spec/flydata/fluent-plugins/mysql/dml_record_handler_spec.rb +1 -1
- data/spec/flydata/fluent-plugins/mysql/shared_query_handler_context.rb +4 -2
- data/spec/flydata/fluent-plugins/mysql/truncate_query_handler_spec.rb +1 -1
- data/spec/flydata/source_mysql/generate_source_dump_spec.rb +69 -0
- data/spec/flydata/source_mysql/mysql_compatibility_check_spec.rb +280 -0
- data/spec/flydata/{parser/mysql → source_mysql/parser}/alter_table_parser_spec.rb +2 -2
- data/spec/flydata/{parser/mysql → source_mysql/parser}/dump_parser_spec.rb +75 -70
- data/spec/flydata/source_mysql/sync_generate_table_ddl_spec.rb +137 -0
- data/spec/flydata/{mysql → source_mysql}/table_ddl_spec.rb +2 -2
- data/spec/flydata/source_spec.rb +140 -0
- data/spec/flydata/source_zendesk/sync_generate_table_ddl_spec.rb +33 -0
- data/spec/flydata/sync_file_manager_spec.rb +157 -77
- data/tmpl/redshift_mysql_data_entry.conf.tmpl +1 -1
- metadata +56 -23
- data/ext/flydata/parser/mysql/extconf.rb +0 -3
- data/lib/flydata/mysql/binlog_position.rb +0 -22
- data/spec/flydata/mysql/binlog_position_spec.rb +0 -35
|
@@ -17,7 +17,7 @@ module Mysql
|
|
|
17
17
|
r
|
|
18
18
|
end
|
|
19
19
|
before do
|
|
20
|
-
parser_class = ParserProvider.parser(:mysql, :mysql_alter_table)
|
|
20
|
+
parser_class = Flydata::Parser::ParserProvider.parser(:mysql, :mysql_alter_table)
|
|
21
21
|
allow(parser_class).to receive(:new).and_return(parser)
|
|
22
22
|
allow_any_instance_of(described_class).to receive(:check_empty_binlog)
|
|
23
23
|
record.delete('table_name')
|
|
@@ -56,8 +56,8 @@ module Mysql
|
|
|
56
56
|
end
|
|
57
57
|
context "when event binlog is older than table binlog.pos" do
|
|
58
58
|
it 'skip sending event' do
|
|
59
|
-
expect(sync_fm).to receive(:
|
|
60
|
-
expect(ParserProvider).not_to receive(:parser)
|
|
59
|
+
expect(sync_fm).to receive(:get_table_source_raw_pos).and_return("mysql-bin.000067\t120").once
|
|
60
|
+
expect(Flydata::Parser::ParserProvider).not_to receive(:parser)
|
|
61
61
|
expect(subject.process(record)).to eq(nil)
|
|
62
62
|
end
|
|
63
63
|
end
|
|
@@ -12,7 +12,7 @@ describe DmlRecordHandler do
|
|
|
12
12
|
let(:tables) { ['items', 'orders'] }
|
|
13
13
|
let(:sync_fm) {
|
|
14
14
|
sfm = double('sync_fm')
|
|
15
|
-
allow(sfm).to receive(:
|
|
15
|
+
allow(sfm).to receive(:get_table_source_raw_pos).and_return nil
|
|
16
16
|
sfm
|
|
17
17
|
}
|
|
18
18
|
let(:context) {
|
|
@@ -4,11 +4,13 @@ module Mysql
|
|
|
4
4
|
let(:database) { target_database }
|
|
5
5
|
let(:table) { "foo" }
|
|
6
6
|
let(:seq) { 200 }
|
|
7
|
+
let(:binlog_pos_string) { "mysql-bin.000065\t120" }
|
|
8
|
+
let(:binlog_pos_object) { FlydataCore::Mysql::BinlogPos.new(binlog_pos_string) }
|
|
7
9
|
let(:sync_fm) do
|
|
8
10
|
r = double('sync_fm')
|
|
9
|
-
allow(r).to receive(:
|
|
11
|
+
allow(r).to receive(:get_table_source_raw_pos).and_return(binlog_pos_string)
|
|
10
12
|
allow(r).to receive(:increment_and_save_table_position).with(table).and_yield(seq).and_return(nil)
|
|
11
|
-
allow(r).to receive(:
|
|
13
|
+
allow(r).to receive(:delete_table_source_pos).with(table)
|
|
12
14
|
r
|
|
13
15
|
end
|
|
14
16
|
let(:table_meta) { double'table_meta' }
|
|
@@ -79,7 +79,7 @@ module Mysql
|
|
|
79
79
|
context 'when per-table binlog pos exists' do
|
|
80
80
|
let(:truncate_query) { "TRUNCATE #{table}" }
|
|
81
81
|
before do
|
|
82
|
-
allow(sync_fm).to receive(:
|
|
82
|
+
allow(sync_fm).to receive(:get_table_source_raw_pos).and_return("mysql-bin.000067\t120")
|
|
83
83
|
end
|
|
84
84
|
include_examples "skip processing queries"
|
|
85
85
|
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'flydata/source_mysql/generate_source_dump'
|
|
2
|
+
|
|
3
|
+
module Flydata
|
|
4
|
+
module SourceMysql
|
|
5
|
+
|
|
6
|
+
describe GenerateSourceDump do
|
|
7
|
+
let(:subject_object) { described_class.new(source, dp, options) }
|
|
8
|
+
|
|
9
|
+
let(:source) { double('source') }
|
|
10
|
+
before do
|
|
11
|
+
allow(source).to receive(:de).and_return(de)
|
|
12
|
+
end
|
|
13
|
+
let(:dp) { double('dp') }
|
|
14
|
+
let(:options) { double('options') }
|
|
15
|
+
|
|
16
|
+
let(:de) { {
|
|
17
|
+
"mysql_data_entry_preference" => {
|
|
18
|
+
"host" => "foo",
|
|
19
|
+
"port" => 1234,
|
|
20
|
+
"tables" => all_tables,
|
|
21
|
+
}
|
|
22
|
+
} }
|
|
23
|
+
|
|
24
|
+
let(:all_tables) { %w|a b c d| + partial_tables }
|
|
25
|
+
let(:partial_tables) { %w|e f| }
|
|
26
|
+
let(:file_path) { double('file_path') }
|
|
27
|
+
let(:src_pos_callback) { Proc.new{} }
|
|
28
|
+
let(:db_size_check) { double('db_size_check') }
|
|
29
|
+
let(:size) { double('size') }
|
|
30
|
+
|
|
31
|
+
let(:options_with_partial_tables) {
|
|
32
|
+
prefs = de['mysql_data_entry_preference'].clone
|
|
33
|
+
prefs["tables"] = partial_tables
|
|
34
|
+
prefs
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
describe '#dump_size' do
|
|
38
|
+
subject { subject_object.dump_size(partial_tables) }
|
|
39
|
+
|
|
40
|
+
it 'creates DatabaseSizeCheck object with correct parameter' do
|
|
41
|
+
expect(Parser::DatabaseSizeCheck).to receive(:new).
|
|
42
|
+
with(options_with_partial_tables).and_return(db_size_check)
|
|
43
|
+
expect(db_size_check).to receive(:get_db_bytesize).and_return(size)
|
|
44
|
+
|
|
45
|
+
expect(subject).to eq size
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe '#dump' do
|
|
50
|
+
subject { subject_object.dump(partial_tables, file_path, &src_pos_callback) }
|
|
51
|
+
|
|
52
|
+
let(:dump_generator) { double('dump_generator') }
|
|
53
|
+
before do
|
|
54
|
+
allow(dump_generator).to receive(:dump)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'creates dump_generator with correct parameters' do
|
|
58
|
+
expect(Parser::MysqlDumpGeneratorNoMasterData).to receive(:new).
|
|
59
|
+
with(options_with_partial_tables).and_return(dump_generator)
|
|
60
|
+
expect(dump_generator).to receive(:dump).
|
|
61
|
+
with(file_path, &src_pos_callback)
|
|
62
|
+
|
|
63
|
+
subject
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'flydata/source_mysql/mysql_compatibility_check'
|
|
3
|
+
|
|
4
|
+
module Flydata
|
|
5
|
+
module SourceMysql
|
|
6
|
+
|
|
7
|
+
describe MysqlCompatibilityCheck do
|
|
8
|
+
let(:subject_object) { described_class.new(dp_hash, de_hash, options) }
|
|
9
|
+
|
|
10
|
+
let(:dp_hash) { default_data_port }
|
|
11
|
+
let(:de_hash) { default_mysql_cred }
|
|
12
|
+
let(:options) { default_options }
|
|
13
|
+
|
|
14
|
+
let(:default_data_port) do
|
|
15
|
+
{
|
|
16
|
+
"servers"=>["sample-test-site.com"]
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
let(:default_mysql_cred) do
|
|
21
|
+
{
|
|
22
|
+
"host" => "test",
|
|
23
|
+
"port" => 1234,
|
|
24
|
+
"username" => "test",
|
|
25
|
+
"password" => "password",
|
|
26
|
+
"database" => "test_db"
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
let(:default_options) { {} }
|
|
31
|
+
|
|
32
|
+
let(:client) { double('client') }
|
|
33
|
+
before do
|
|
34
|
+
allow(Mysql2::Client).to receive(:new).and_return(client)
|
|
35
|
+
allow(client).to receive(:close)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe "#check" do
|
|
39
|
+
subject { subject_object.check }
|
|
40
|
+
|
|
41
|
+
it "calls all check methods" do
|
|
42
|
+
%w(compatibility56_variable mysql_user_compat mysql_protocol_tcp_compat
|
|
43
|
+
mysql_parameters_compat rds_master_status mysql_binlog_retention
|
|
44
|
+
mysql_table_types writing_permissions).each do |method_name|
|
|
45
|
+
expect(subject_object).to receive("check_#{method_name}".to_sym)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
subject
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe "#check_mysql_user_compat" do
|
|
53
|
+
subject { subject_object.check_mysql_user_compat }
|
|
54
|
+
|
|
55
|
+
context "with all privileges in all databases" do
|
|
56
|
+
before do
|
|
57
|
+
allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT ALL PRIVILEGES ON *.* TO 'test'@'host"}])
|
|
58
|
+
end
|
|
59
|
+
it do
|
|
60
|
+
expect{subject}.to_not raise_error
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
context "with missing privileges in one database" do
|
|
64
|
+
before do
|
|
65
|
+
allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT ALL PRIVILEGES ON 'mysql'.* TO 'test'@'host"},
|
|
66
|
+
{"Grants for test"=>"GRANT SELECT, RELOAD, REPLICATION CLIENT ON `test_db`.* TO 'test'@'host"}])
|
|
67
|
+
end
|
|
68
|
+
it do
|
|
69
|
+
expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /test_db': LOCK TABLES, REPLICATION SLAVE/)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
context "with all required privileges in between all and specific databases" do
|
|
73
|
+
before do
|
|
74
|
+
allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT RELOAD, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'test'@'host"},
|
|
75
|
+
{"Grants for test"=>"GRANT SELECT, LOCK TABLES ON `test_db`.* TO 'test'@'host"},
|
|
76
|
+
{"Grants for test"=>"GRANT SELECT, LOCK TABLES ON `mysql`.* TO 'test'@'host"}])
|
|
77
|
+
end
|
|
78
|
+
it do
|
|
79
|
+
expect{subject}.to_not raise_error
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
context "with missing privileges in each database" do
|
|
83
|
+
before do
|
|
84
|
+
allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'test'@'host"},
|
|
85
|
+
{"Grants for test"=>"GRANT SELECT, LOCK TABLES ON `test_db`.* TO 'test'@'host"},
|
|
86
|
+
{"Grants for test"=>"GRANT SELECT, LOCK TABLES ON `mysql`.* TO 'test'@'host"}])
|
|
87
|
+
end
|
|
88
|
+
it do
|
|
89
|
+
expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /mysql': RELOAD\n.*test_db': RELOAD/)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
context "with all required privileges in all databases" do
|
|
93
|
+
before do
|
|
94
|
+
allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT SELECT, LOCK TABLES, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'test'@'host"}])
|
|
95
|
+
end
|
|
96
|
+
it do
|
|
97
|
+
expect{subject}.to_not raise_error
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
context "with missing privileges in all databases" do
|
|
101
|
+
before do
|
|
102
|
+
allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT RELOAD, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'test'@'host"}])
|
|
103
|
+
end
|
|
104
|
+
it do
|
|
105
|
+
expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /mysql': SELECT, LOCK TABLES\n.*test_db': SELECT, LOCK TABLES/)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
context "with privileges for other databases only" do
|
|
109
|
+
before do
|
|
110
|
+
allow(client).to receive(:query).and_return([{"Grants for test"=>"GRANT REPLICATION CLIENT ON `test_db_01`.* TO 'test'@'host"},
|
|
111
|
+
{"Grants for test"=>"GRANT LOCK TABLES ON `test_db_02`.* TO 'test'@'host"},
|
|
112
|
+
{"Grants for test"=>"GRANT SELECT ON `text_db_03`.* TO 'test'@'host"}])
|
|
113
|
+
end
|
|
114
|
+
it do
|
|
115
|
+
expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /mysql': SELECT, RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT\n.*test_db': SELECT, RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT/)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
describe "#check_mysql_binlog_retention" do
|
|
122
|
+
subject { subject_object.check_mysql_binlog_retention }
|
|
123
|
+
context "on on-premise mysql server" do
|
|
124
|
+
before do
|
|
125
|
+
allow(subject_object).to receive(:is_rds?).and_return(false)
|
|
126
|
+
end
|
|
127
|
+
context "where retention is below limit" do
|
|
128
|
+
before do
|
|
129
|
+
allow(client).to receive(:query).and_return([{"Variable_name" => "expire_logs_days", "Value" => 1}])
|
|
130
|
+
end
|
|
131
|
+
it do
|
|
132
|
+
expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /expire_logs_days/)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
context "where retention is 0" do
|
|
136
|
+
before do
|
|
137
|
+
allow(client).to receive(:query).and_return([{"Variable_name" => "expire_logs_days", "Value" => 0}])
|
|
138
|
+
end
|
|
139
|
+
it do
|
|
140
|
+
expect{subject}.to_not raise_error
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
context "where retention is above limit" do
|
|
144
|
+
before do
|
|
145
|
+
allow(client).to receive(:query).and_return([{"expire_logs_days"=>11}])
|
|
146
|
+
allow(client).to receive(:query).and_return([{"Variable_name" => "expire_logs_days", "Value" => 11}])
|
|
147
|
+
end
|
|
148
|
+
it do
|
|
149
|
+
expect{subject}.to_not raise_error
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
context "on RDS" do
|
|
154
|
+
before do
|
|
155
|
+
allow(subject_object).to receive(:is_rds?).and_return(true)
|
|
156
|
+
end
|
|
157
|
+
before do
|
|
158
|
+
allow(client).to receive(:query).with("SELECT @@expire_logs_days").and_return([{"@@expire_logs_days"=>0}])
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
context "where retention period is nil" do
|
|
163
|
+
before do
|
|
164
|
+
allow(client).to receive(:query).with("call mysql.rds_show_configuration;").and_return([{"name"=>"binlog retention hours", "value"=>nil}])
|
|
165
|
+
end
|
|
166
|
+
it do
|
|
167
|
+
expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /rds_set_config/)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
context "where retention period is too low" do
|
|
171
|
+
before do
|
|
172
|
+
allow(client).to receive(:query).with("call mysql.rds_show_configuration;").and_return([{"name"=>"binlog retention hours", "value"=>4}])
|
|
173
|
+
end
|
|
174
|
+
it do
|
|
175
|
+
expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /rds_set_config/)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
context "where retention period is over recommended limit" do
|
|
179
|
+
before do
|
|
180
|
+
allow(client).to receive(:query).with("call mysql.rds_show_configuration;").and_return([{"name"=>"binlog retention hours", "value"=>120}])
|
|
181
|
+
end
|
|
182
|
+
it do
|
|
183
|
+
expect{subject}.to_not raise_error
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
context "where user has no access to rds configuration" do
|
|
187
|
+
before do
|
|
188
|
+
allow(client).to receive(:query).with("call mysql.rds_show_configuration;").and_raise(Mysql2::Error, "execute command denied to user")
|
|
189
|
+
end
|
|
190
|
+
it do
|
|
191
|
+
expect{subject}.to_not raise_error
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
describe "#check_mysql_table_types" do
|
|
198
|
+
subject { subject_object.check_mysql_table_types }
|
|
199
|
+
|
|
200
|
+
let(:de_hash) do
|
|
201
|
+
{ "host" => "test",
|
|
202
|
+
"port" => 1234,
|
|
203
|
+
"username" => "test",
|
|
204
|
+
"password" => "password",
|
|
205
|
+
"database" => "test_db",
|
|
206
|
+
"tables"=>["normal_table", "engine_table", "view_table"] }
|
|
207
|
+
end
|
|
208
|
+
let(:normal_table) { {"table_name"=>"normal_table", "table_type"=>"BASE TABLE", "engine"=>"InnoDB"} }
|
|
209
|
+
let(:engine_table) { {"table_name"=>"engine_table", "table_type"=>"BASE TABLE", "engine"=>"MEMORY"} }
|
|
210
|
+
let(:blackhole_table) { {"table_name"=>"blackhole_table", "table_type"=>"BASE TABLE", "engine"=>"BLACKHOLE"} }
|
|
211
|
+
let(:view) { {"table_name"=>"view_table", "table_type"=>"VIEW", "engine"=>nil} }
|
|
212
|
+
let(:error) { FlydataCore::MysqlCompatibilityError }
|
|
213
|
+
let(:base_error_msg) { "FlyData does not support VIEW and MEMORY,BLACKHOLE STORAGE ENGINE table. Remove following tables from data entry: %s" }
|
|
214
|
+
before do
|
|
215
|
+
allow(client).to receive(:query).and_return(table_list)
|
|
216
|
+
allow(client).to receive(:escape).and_return("aaa")
|
|
217
|
+
end
|
|
218
|
+
context "where data entry has VIEW and MEMORY engine table" do
|
|
219
|
+
let(:error_msg) { base_error_msg % engine_table['table_name'] + ', ' + view['table_name'] }
|
|
220
|
+
let(:table_list) { [ engine_table, view ] }
|
|
221
|
+
it { expect{subject}.to raise_error(error, /#{error_msg}/) }
|
|
222
|
+
end
|
|
223
|
+
context "where data entry has MEMORY engine table" do
|
|
224
|
+
let(:error_msg) { base_error_msg % engine_table['table_name'] }
|
|
225
|
+
let(:table_list) { [ engine_table ] }
|
|
226
|
+
it { expect{subject}.to raise_error(error, /#{error_msg}/) }
|
|
227
|
+
end
|
|
228
|
+
context "where data entry has BLACKHOLE engine table" do
|
|
229
|
+
let(:error_msg) { base_error_msg % blackhole_table['table_name'] }
|
|
230
|
+
let(:table_list) { [ blackhole_table ] }
|
|
231
|
+
it { expect{subject}.to raise_error(error, /#{error_msg}/) }
|
|
232
|
+
end
|
|
233
|
+
context "where data entry has the VIEW" do
|
|
234
|
+
let(:error_msg) { base_error_msg % view['table_name'] }
|
|
235
|
+
let(:table_list) { [ view ] }
|
|
236
|
+
it { expect{subject}.to raise_error(error, /#{error_msg}/) }
|
|
237
|
+
end
|
|
238
|
+
context "where data entry does not have either VIEW and ENGINE table" do
|
|
239
|
+
let(:table_list) { [ normal_table ] }
|
|
240
|
+
it { expect{subject}.to_not raise_error }
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
describe "#check_rds_master_status" do
|
|
245
|
+
subject { subject_object.check_rds_master_status }
|
|
246
|
+
|
|
247
|
+
let(:master_status) { [] }
|
|
248
|
+
|
|
249
|
+
before do
|
|
250
|
+
allow(client).to receive(:query).and_return(master_status)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
context 'when host is rds' do
|
|
254
|
+
before do
|
|
255
|
+
de_hash['host'] = 'rdrss.xxyyzz.rds.amazonaws.com'
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
context "where backup retention period is not set" do
|
|
259
|
+
let(:master_status) { [] }
|
|
260
|
+
it { expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /Backup Retention Period/) }
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
context "where backup retention period is set" do
|
|
264
|
+
let(:master_status) do
|
|
265
|
+
[{
|
|
266
|
+
'File' => 'mysql-bin-changelog.026292',
|
|
267
|
+
'Position' => '31300',
|
|
268
|
+
'Binlog_Do_DB' => '',
|
|
269
|
+
'Binlog_Ignore_DB' => '',
|
|
270
|
+
'Executed_Gtid_Set' => '',
|
|
271
|
+
}]
|
|
272
|
+
end
|
|
273
|
+
it { expect{subject}.not_to raise_error }
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
end
|
|
280
|
+
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
require 'flydata/parser_provider'
|
|
2
|
+
require 'flydata/parser/parser_provider'
|
|
3
3
|
|
|
4
4
|
describe 'MysqlAlterTableParser' do
|
|
5
5
|
before do
|
|
6
6
|
#load parser
|
|
7
|
-
@parser_class =
|
|
7
|
+
@parser_class = Flydata::Parser::ParserProvider.parser(:mysql, :mysql_alter_table)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
let(:query) { "" }
|
|
@@ -3,11 +3,12 @@ require 'spec_helper'
|
|
|
3
3
|
require 'open3'
|
|
4
4
|
require 'mysql2'
|
|
5
5
|
require 'flydata/command/sync'
|
|
6
|
-
require 'flydata/parser/
|
|
6
|
+
require 'flydata/source_mysql/parser/dump_parser'
|
|
7
|
+
require 'flydata-core/mysql/binlog_pos'
|
|
7
8
|
|
|
8
9
|
module Flydata
|
|
9
|
-
module
|
|
10
|
-
module
|
|
10
|
+
module SourceMysql
|
|
11
|
+
module Parser
|
|
11
12
|
context "Test Dump Generators" do
|
|
12
13
|
let(:stdin) do
|
|
13
14
|
s = double(:stdin)
|
|
@@ -153,8 +154,9 @@ EOT
|
|
|
153
154
|
content[0...content.index(string)].bytesize + string.bytesize + 1
|
|
154
155
|
end
|
|
155
156
|
|
|
156
|
-
let(:default_parser) { MysqlDumpParser.new(
|
|
157
|
+
let(:default_parser) { MysqlDumpParser.new(source_pos: default_binlog_pos_object) }
|
|
157
158
|
let(:default_binlog_pos) { {binfile: 'mysql-bin.000267', pos: 120 } }
|
|
159
|
+
let(:default_binlog_pos_object) { FlydataCore::Mysql::BinlogPos.new(default_binlog_pos) }
|
|
158
160
|
let(:dump_pos_after_binlog_pos) { index_after(DUMP_HEADER, '5.6.13-log') }
|
|
159
161
|
|
|
160
162
|
let(:create_table_block) { double('create_table_block') }
|
|
@@ -210,30 +212,30 @@ EOT
|
|
|
210
212
|
}
|
|
211
213
|
before { generate_dump_file(dump_content) }
|
|
212
214
|
it do
|
|
213
|
-
expect(create_table_block).to receive(:call) { |
|
|
214
|
-
expect(
|
|
215
|
+
expect(create_table_block).to receive(:call) { |source_table|
|
|
216
|
+
expect(source_table.table_name).to eq('users_login')
|
|
215
217
|
}.once
|
|
216
218
|
expect(insert_record_block).to receive(:call).never
|
|
217
|
-
expect(check_point_block).to receive(:call) { |
|
|
218
|
-
expect(
|
|
219
|
+
expect(check_point_block).to receive(:call) { |source_table, last_pos, bytesize, binlog_pos, state, substate|
|
|
220
|
+
expect(source_table).to be_nil
|
|
219
221
|
expect(last_pos).to eq(dump_pos_after_binlog_pos)
|
|
220
222
|
expect(binlog_pos).to eq(default_binlog_pos)
|
|
221
|
-
expect(state).to eq(
|
|
223
|
+
expect(state).to eq(Flydata::Parser::State::CREATE_TABLE)
|
|
222
224
|
expect(substate).to be_nil
|
|
223
225
|
}
|
|
224
|
-
expect(check_point_block).to receive(:call) { |
|
|
225
|
-
expect(
|
|
226
|
-
expect(
|
|
226
|
+
expect(check_point_block).to receive(:call) { |source_table, last_pos, bytesize, binlog_pos, state, substate|
|
|
227
|
+
expect(source_table.table_name).to eq('users_login')
|
|
228
|
+
expect(source_table.columns.keys).to eq([col_name, 'login_count', 'create_time', 'update_time'])
|
|
227
229
|
expect(last_pos).to eq(index_after(dump_content, 'ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=\'\';'))
|
|
228
230
|
expect(binlog_pos).to eq(default_binlog_pos)
|
|
229
|
-
expect(state).to eq(
|
|
231
|
+
expect(state).to eq(Flydata::Parser::State::INSERT_RECORD)
|
|
230
232
|
expect(substate).to be_nil
|
|
231
233
|
}
|
|
232
|
-
expect(check_point_block).to receive(:call) { |
|
|
233
|
-
expect(
|
|
234
|
+
expect(check_point_block).to receive(:call) { |source_table, last_pos, bytesize, binlog_pos, state, substate|
|
|
235
|
+
expect(source_table.table_name).to eq('users_login')
|
|
234
236
|
expect(last_pos).to eq(index_after(dump_content, 'UNLOCK TABLES;'))
|
|
235
237
|
expect(binlog_pos).to eq(default_binlog_pos)
|
|
236
|
-
expect(state).to eq(
|
|
238
|
+
expect(state).to eq(Flydata::Parser::State::CREATE_TABLE)
|
|
237
239
|
expect(substate).to be_nil
|
|
238
240
|
}
|
|
239
241
|
expect(check_point_block).to receive(:call).never
|
|
@@ -302,9 +304,9 @@ EOT
|
|
|
302
304
|
before { generate_dump_file(dump_content) }
|
|
303
305
|
it do
|
|
304
306
|
# create_table_block
|
|
305
|
-
expect(create_table_block).to receive(:call) { |
|
|
306
|
-
expect(
|
|
307
|
-
expect(
|
|
307
|
+
expect(create_table_block).to receive(:call) { |source_table|
|
|
308
|
+
expect(source_table.table_name).to eq('users_login')
|
|
309
|
+
expect(source_table.columns.keys).to eq(['user_id', 'login_count', 'comment', 'create_time', 'update_time'])
|
|
308
310
|
}.once
|
|
309
311
|
expect(create_table_block).to receive(:call).never
|
|
310
312
|
|
|
@@ -316,8 +318,8 @@ EOT
|
|
|
316
318
|
[ %w(373 31 out'swearing 1979-10-07\ 08:10:08 2006-02-22\ 16:26:04),
|
|
317
319
|
%w(493 8 schizophrenic 1979-07-06\ 07:34:07 1970-08-09\ 01:21:01),]
|
|
318
320
|
].each do |expected_values|
|
|
319
|
-
expect(insert_record_block).to receive(:call) { |
|
|
320
|
-
expect(
|
|
321
|
+
expect(insert_record_block).to receive(:call) { |source_table, values_set|
|
|
322
|
+
expect(source_table.table_name).to eq('users_login')
|
|
321
323
|
expect(values_set).to eq(expected_values)
|
|
322
324
|
nil
|
|
323
325
|
}.once
|
|
@@ -326,13 +328,13 @@ EOT
|
|
|
326
328
|
|
|
327
329
|
# insert_record_block
|
|
328
330
|
[
|
|
329
|
-
{state:
|
|
330
|
-
{state:
|
|
331
|
-
{state:
|
|
331
|
+
{state: Flydata::Parser::State::CREATE_TABLE},
|
|
332
|
+
{state: Flydata::Parser::State::INSERT_RECORD},
|
|
333
|
+
{state: Flydata::Parser::State::CREATE_TABLE,
|
|
332
334
|
last_pos: index_after(dump_content, 'UNLOCK TABLES;')}
|
|
333
335
|
].each do |expected_params|
|
|
334
|
-
expect(check_point_block).to receive(:call) { |
|
|
335
|
-
expect(
|
|
336
|
+
expect(check_point_block).to receive(:call) { |source_table, last_pos, bytesize, binlog_pos, state, substate|
|
|
337
|
+
expect(source_table.table_name).to eq('users_login') if source_table
|
|
336
338
|
expect(state).to eq(expected_params[:state])
|
|
337
339
|
if expected_params[:last_pos]
|
|
338
340
|
expect(last_pos).to eq(expected_params[:last_pos])
|
|
@@ -384,9 +386,9 @@ EOT
|
|
|
384
386
|
before { generate_dump_file(dump_content) }
|
|
385
387
|
it do
|
|
386
388
|
# create_table_block
|
|
387
|
-
expect(create_table_block).to receive(:call) { |
|
|
388
|
-
expect(
|
|
389
|
-
expect(
|
|
389
|
+
expect(create_table_block).to receive(:call) { |source_table|
|
|
390
|
+
expect(source_table.table_name).to eq('users_login')
|
|
391
|
+
expect(source_table.columns.keys).to eq(['user_id', 'login_count', 'comment', 'create_time', 'update_time'])
|
|
390
392
|
}.once
|
|
391
393
|
expect(create_table_block).to receive(:call).never
|
|
392
394
|
|
|
@@ -396,8 +398,8 @@ EOT
|
|
|
396
398
|
['35', '6', nil, '1991-10-15 19:38:07', '1970-10-01 22:03:10'],
|
|
397
399
|
%w(52 33 subfield 1972-08-23\ 20:16:08 1974-10-10\ 23:28:11),],
|
|
398
400
|
].each do |expected_values|
|
|
399
|
-
expect(insert_record_block).to receive(:call) { |
|
|
400
|
-
expect(
|
|
401
|
+
expect(insert_record_block).to receive(:call) { |source_table, values_set|
|
|
402
|
+
expect(source_table.table_name).to eq('users_login')
|
|
401
403
|
expect(values_set).to eq(expected_values)
|
|
402
404
|
nil
|
|
403
405
|
}.once
|
|
@@ -406,13 +408,13 @@ EOT
|
|
|
406
408
|
|
|
407
409
|
# insert_record_block
|
|
408
410
|
[
|
|
409
|
-
{state:
|
|
410
|
-
{state:
|
|
411
|
-
{state:
|
|
411
|
+
{state: Flydata::Parser::State::CREATE_TABLE},
|
|
412
|
+
{state: Flydata::Parser::State::INSERT_RECORD},
|
|
413
|
+
{state: Flydata::Parser::State::CREATE_TABLE,
|
|
412
414
|
last_pos: index_after(dump_content, 'UNLOCK TABLES;')}
|
|
413
415
|
].each do |expected_params|
|
|
414
|
-
expect(check_point_block).to receive(:call) { |
|
|
415
|
-
expect(
|
|
416
|
+
expect(check_point_block).to receive(:call) { |source_table, last_pos, bytesize, binlog_pos, state, substate|
|
|
417
|
+
expect(source_table.table_name).to eq('users_login') if source_table
|
|
416
418
|
expect(state).to eq(expected_params[:state])
|
|
417
419
|
if expected_params[:last_pos]
|
|
418
420
|
expect(last_pos).to eq(expected_params[:last_pos])
|
|
@@ -472,16 +474,16 @@ EOT
|
|
|
472
474
|
Proc.new{
|
|
473
475
|
raise "Should not be called"
|
|
474
476
|
},
|
|
475
|
-
Proc.new{ |
|
|
476
|
-
if
|
|
477
|
-
@
|
|
477
|
+
Proc.new{ |source_table, last_pos, bytesize, binlog_pos, state, substate|
|
|
478
|
+
if source_table
|
|
479
|
+
@source_table = source_table
|
|
478
480
|
@option = { status: Flydata::Command::Sync::STATUS_PARSING,
|
|
479
|
-
table_name:
|
|
481
|
+
table_name: source_table.table_name,
|
|
480
482
|
last_pos: last_pos,
|
|
481
483
|
binlog_pos: binlog_pos,
|
|
482
484
|
state: state,
|
|
483
485
|
substate: substate,
|
|
484
|
-
|
|
486
|
+
source_table: source_table }
|
|
485
487
|
end
|
|
486
488
|
}
|
|
487
489
|
)
|
|
@@ -490,15 +492,16 @@ EOT
|
|
|
490
492
|
table_name: 'users_login',
|
|
491
493
|
last_pos: index_after(dump_content_head, 'ENGINE=InnoDB DEFAULT CHARSET=utf8;'),
|
|
492
494
|
binlog_pos: default_binlog_pos,
|
|
493
|
-
state:
|
|
495
|
+
state: Flydata::Parser::State::INSERT_RECORD,
|
|
494
496
|
substate: nil,
|
|
495
|
-
|
|
497
|
+
source_table: @source_table
|
|
496
498
|
})
|
|
497
499
|
end
|
|
498
500
|
it do
|
|
499
501
|
generate_dump_file(dump_content_all)
|
|
502
|
+
@option.delete(:binlog_pos)
|
|
503
|
+
@option.merge!( {source_pos: default_binlog_pos_object} )
|
|
500
504
|
parser_for_resume = MysqlDumpParser.new(@option)
|
|
501
|
-
|
|
502
505
|
# create_table_block
|
|
503
506
|
expect(create_table_block).to receive(:call).never
|
|
504
507
|
|
|
@@ -508,8 +511,8 @@ EOT
|
|
|
508
511
|
%w(35 6 missteer 1991-10-15\ 19:38:07 1970-10-01\ 22:03:10),
|
|
509
512
|
%w(52 33 subfield 1972-08-23\ 20:16:08 1974-10-10\ 23:28:11),],
|
|
510
513
|
].each do |expected_values|
|
|
511
|
-
expect(insert_record_block).to receive(:call) { |
|
|
512
|
-
expect(
|
|
514
|
+
expect(insert_record_block).to receive(:call) { |source_table, values|
|
|
515
|
+
expect(source_table.table_name).to eq('users_login')
|
|
513
516
|
expect(values).to eq(expected_values)
|
|
514
517
|
nil
|
|
515
518
|
}.once
|
|
@@ -518,11 +521,11 @@ EOT
|
|
|
518
521
|
|
|
519
522
|
# check_point_block
|
|
520
523
|
[
|
|
521
|
-
{state:
|
|
524
|
+
{state: Flydata::Parser::State::CREATE_TABLE,
|
|
522
525
|
last_pos: index_after(dump_content_all, 'UNLOCK TABLES;')}
|
|
523
526
|
].each do |expected_params|
|
|
524
|
-
expect(check_point_block).to receive(:call) { |
|
|
525
|
-
expect(
|
|
527
|
+
expect(check_point_block).to receive(:call) { |source_table, last_pos, bytesize, binlog_pos, state, substate|
|
|
528
|
+
expect(source_table.table_name).to eq('users_login') if source_table
|
|
526
529
|
expect(state).to eq(expected_params[:state])
|
|
527
530
|
if expected_params[:last_pos]
|
|
528
531
|
expect(last_pos).to eq(expected_params[:last_pos])
|
|
@@ -582,16 +585,16 @@ EOT
|
|
|
582
585
|
dump_io,
|
|
583
586
|
Proc.new{},
|
|
584
587
|
insert_record_block_for_resume,
|
|
585
|
-
Proc.new{ |
|
|
588
|
+
Proc.new{ |source_table, last_pos, bytesize, binlog_pos, state, substate|
|
|
586
589
|
if last_pos == index_after(dump_content, "'1972-08-23 20:16:08','1974-10-10 23:28:11');")
|
|
587
|
-
@
|
|
590
|
+
@source_table = source_table
|
|
588
591
|
@option = { status: Flydata::Command::Sync::STATUS_PARSING,
|
|
589
|
-
table_name:
|
|
592
|
+
table_name: source_table.table_name,
|
|
590
593
|
last_pos: last_pos,
|
|
591
594
|
binlog_pos: binlog_pos,
|
|
592
595
|
state: state,
|
|
593
596
|
substate: substate,
|
|
594
|
-
|
|
597
|
+
source_table: source_table }
|
|
595
598
|
end
|
|
596
599
|
}
|
|
597
600
|
)
|
|
@@ -600,13 +603,15 @@ EOT
|
|
|
600
603
|
table_name: 'users_login',
|
|
601
604
|
last_pos: index_after(dump_content, "'1972-08-23 20:16:08','1974-10-10 23:28:11');"),
|
|
602
605
|
binlog_pos: default_binlog_pos,
|
|
603
|
-
state:
|
|
606
|
+
state: Flydata::Parser::State::INSERT_RECORD,
|
|
604
607
|
substate: nil,
|
|
605
|
-
|
|
608
|
+
source_table: @source_table
|
|
606
609
|
})
|
|
607
610
|
end
|
|
608
611
|
it do
|
|
609
612
|
generate_dump_file(dump_content)
|
|
613
|
+
@option.delete(:binlog_pos)
|
|
614
|
+
@option.merge!({source_pos: default_binlog_pos_object})
|
|
610
615
|
parser_for_resume = MysqlDumpParser.new(@option)
|
|
611
616
|
|
|
612
617
|
# create_table_block
|
|
@@ -617,8 +622,8 @@ EOT
|
|
|
617
622
|
[ %w(194 11 pandemonium 2008-01-22\ 22:15:10 1991-04-04\ 17:30:05),
|
|
618
623
|
%w(230 7 cloudburst 2010-12-28\ 11:46:11 1971-06-22\ 13:08:01),],
|
|
619
624
|
].each do |expected_values|
|
|
620
|
-
expect(insert_record_block).to receive(:call) { |
|
|
621
|
-
expect(
|
|
625
|
+
expect(insert_record_block).to receive(:call) { |source_table, values_set|
|
|
626
|
+
expect(source_table.table_name).to eq('users_login')
|
|
622
627
|
expect(values_set).to eq(expected_values)
|
|
623
628
|
nil
|
|
624
629
|
}.once
|
|
@@ -627,11 +632,11 @@ EOT
|
|
|
627
632
|
|
|
628
633
|
# check_point_block
|
|
629
634
|
[
|
|
630
|
-
{state:
|
|
635
|
+
{state: Flydata::Parser::State::CREATE_TABLE,
|
|
631
636
|
last_pos: index_after(dump_content, 'UNLOCK TABLES;')}
|
|
632
637
|
].each do |expected_params|
|
|
633
|
-
expect(check_point_block).to receive(:call) { |
|
|
634
|
-
expect(
|
|
638
|
+
expect(check_point_block).to receive(:call) { |source_table, last_pos, bytesize, binlog_pos, state, substate|
|
|
639
|
+
expect(source_table.table_name).to eq('users_login') if source_table
|
|
635
640
|
expect(state).to eq(expected_params[:state])
|
|
636
641
|
if expected_params[:last_pos]
|
|
637
642
|
expect(last_pos).to eq(expected_params[:last_pos])
|
|
@@ -684,9 +689,9 @@ EOT
|
|
|
684
689
|
before { generate_dump_file(dump_content) }
|
|
685
690
|
it do
|
|
686
691
|
# create_table_block
|
|
687
|
-
expect(create_table_block).to receive(:call) { |
|
|
688
|
-
expect(
|
|
689
|
-
expect(
|
|
692
|
+
expect(create_table_block).to receive(:call) { |source_table|
|
|
693
|
+
expect(source_table.table_name).to eq('users_login')
|
|
694
|
+
expect(source_table.columns.keys).to eq(['user_id', 'login_count', 'comment', 'create_time', 'update_time'])
|
|
690
695
|
}.once
|
|
691
696
|
expect(create_table_block).to receive(:call).never
|
|
692
697
|
|
|
@@ -698,8 +703,8 @@ EOT
|
|
|
698
703
|
[ ['373','31',"outs\nwearing",'1979-10-07 08:10:08','2006-02-22 16:26:04'],
|
|
699
704
|
['493','8',"schiz\tophrenic",'1979-07-06 07:34:07\'),','1970-08-09,01:21:01,\')'] ]
|
|
700
705
|
].each do |expected_values|
|
|
701
|
-
expect(insert_record_block).to receive(:call) { |
|
|
702
|
-
expect(
|
|
706
|
+
expect(insert_record_block).to receive(:call) { |source_table, values_set|
|
|
707
|
+
expect(source_table.table_name).to eq('users_login')
|
|
703
708
|
expect(values_set).to eq(expected_values)
|
|
704
709
|
nil
|
|
705
710
|
}.once
|
|
@@ -708,13 +713,13 @@ EOT
|
|
|
708
713
|
|
|
709
714
|
# insert_record_block
|
|
710
715
|
[
|
|
711
|
-
{state:
|
|
712
|
-
{state:
|
|
713
|
-
{state:
|
|
716
|
+
{state: Flydata::Parser::State::CREATE_TABLE},
|
|
717
|
+
{state: Flydata::Parser::State::INSERT_RECORD},
|
|
718
|
+
{state: Flydata::Parser::State::CREATE_TABLE,
|
|
714
719
|
last_pos: index_after(dump_content, 'UNLOCK TABLES;')}
|
|
715
720
|
].each do |expected_params|
|
|
716
|
-
expect(check_point_block).to receive(:call) { |
|
|
717
|
-
expect(
|
|
721
|
+
expect(check_point_block).to receive(:call) { |source_table, last_pos, bytesize, binlog_pos, state, substate|
|
|
722
|
+
expect(source_table.table_name).to eq('users_login') if source_table
|
|
718
723
|
expect(state).to eq(expected_params[:state])
|
|
719
724
|
if expected_params[:last_pos]
|
|
720
725
|
expect(last_pos).to eq(expected_params[:last_pos])
|