flydata 0.1.1 → 0.1.3
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.
- data/Gemfile +1 -1
- data/Gemfile.lock +11 -11
- data/VERSION +1 -1
- data/bin/fdmysqldump +3 -0
- data/flydata.gemspec +6 -6
- data/lib/flydata/command/sync.rb +43 -0
- data/spec/flydata/command/sync_spec.rb +120 -0
- metadata +6 -6
data/Gemfile
CHANGED
|
@@ -6,7 +6,7 @@ gem "i18n", "~> 0.6.5"
|
|
|
6
6
|
gem "activesupport", "~> 4.0.0"
|
|
7
7
|
gem "json", "~> 1.8.0"
|
|
8
8
|
gem "highline", "~> 1.6.19"
|
|
9
|
-
gem "fluentd", "0.10.
|
|
9
|
+
gem "fluentd", "0.10.46"
|
|
10
10
|
gem "ruby-binlog", ">= 1.0.0"
|
|
11
11
|
gem "fluent-plugin-mysql-binlog", "~> 0.0.2"
|
|
12
12
|
gem "mysql2", "~> 0.3.11"
|
data/Gemfile.lock
CHANGED
|
@@ -21,8 +21,7 @@ GEM
|
|
|
21
21
|
arel (4.0.2)
|
|
22
22
|
atomic (1.1.14)
|
|
23
23
|
builder (3.1.4)
|
|
24
|
-
cool.io (1.
|
|
25
|
-
iobuffer (>= 1.0.0)
|
|
24
|
+
cool.io (1.2.3)
|
|
26
25
|
diff-lcs (1.2.4)
|
|
27
26
|
faraday (0.8.8)
|
|
28
27
|
multipart-post (~> 1.2.0)
|
|
@@ -30,11 +29,12 @@ GEM
|
|
|
30
29
|
activesupport
|
|
31
30
|
fluentd
|
|
32
31
|
kodama
|
|
33
|
-
fluentd (0.10.
|
|
34
|
-
cool.io (
|
|
35
|
-
http_parser.rb (
|
|
32
|
+
fluentd (0.10.46)
|
|
33
|
+
cool.io (>= 1.1.1, < 2.0.0, != 1.2.0)
|
|
34
|
+
http_parser.rb (>= 0.5.1, < 0.7.0)
|
|
36
35
|
json (>= 1.4.3)
|
|
37
36
|
msgpack (>= 0.4.4, < 0.6.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
|
|
37
|
+
sigdump (~> 0.2.2)
|
|
38
38
|
yajl-ruby (~> 1.0)
|
|
39
39
|
git (1.2.6)
|
|
40
40
|
github_api (0.10.1)
|
|
@@ -46,10 +46,9 @@ GEM
|
|
|
46
46
|
oauth2
|
|
47
47
|
hashie (2.0.5)
|
|
48
48
|
highline (1.6.19)
|
|
49
|
-
http_parser.rb (0.
|
|
49
|
+
http_parser.rb (0.6.0)
|
|
50
50
|
httpauth (0.2.0)
|
|
51
51
|
i18n (0.6.5)
|
|
52
|
-
iobuffer (1.1.2)
|
|
53
52
|
jeweler (1.8.8)
|
|
54
53
|
builder
|
|
55
54
|
bundler (~> 1.0)
|
|
@@ -59,14 +58,14 @@ GEM
|
|
|
59
58
|
nokogiri (= 1.5.10)
|
|
60
59
|
rake
|
|
61
60
|
rdoc
|
|
62
|
-
json (1.8.
|
|
61
|
+
json (1.8.1)
|
|
63
62
|
jwt (0.1.8)
|
|
64
63
|
multi_json (>= 1.5)
|
|
65
64
|
kodama (0.1.1)
|
|
66
65
|
ruby-binlog (>= 0.1.9)
|
|
67
66
|
mime-types (1.25)
|
|
68
67
|
minitest (4.7.5)
|
|
69
|
-
msgpack (0.5.
|
|
68
|
+
msgpack (0.5.8)
|
|
70
69
|
multi_json (1.8.2)
|
|
71
70
|
multi_xml (0.5.5)
|
|
72
71
|
multipart-post (1.2.0)
|
|
@@ -97,12 +96,13 @@ GEM
|
|
|
97
96
|
rspec-mocks (2.14.3)
|
|
98
97
|
ruby-binlog (1.0.0)
|
|
99
98
|
ruby-prof (0.14.2)
|
|
99
|
+
sigdump (0.2.2)
|
|
100
100
|
sqlite3 (1.3.8)
|
|
101
101
|
thread_safe (0.1.3)
|
|
102
102
|
atomic
|
|
103
103
|
timecop (0.7.1)
|
|
104
104
|
tzinfo (0.3.38)
|
|
105
|
-
yajl-ruby (1.
|
|
105
|
+
yajl-ruby (1.2.0)
|
|
106
106
|
|
|
107
107
|
PLATFORMS
|
|
108
108
|
ruby
|
|
@@ -113,7 +113,7 @@ DEPENDENCIES
|
|
|
113
113
|
activesupport (~> 4.0.0)
|
|
114
114
|
bundler
|
|
115
115
|
fluent-plugin-mysql-binlog (~> 0.0.2)
|
|
116
|
-
fluentd (= 0.10.
|
|
116
|
+
fluentd (= 0.10.46)
|
|
117
117
|
highline (~> 1.6.19)
|
|
118
118
|
i18n (~> 0.6.5)
|
|
119
119
|
jeweler
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.3
|
data/bin/fdmysqldump
CHANGED
|
@@ -7,6 +7,9 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
7
7
|
|
|
8
8
|
require 'flydata/table_def'
|
|
9
9
|
|
|
10
|
+
# Deprecation warning
|
|
11
|
+
$stderr.puts "WARNING: Use 'flydata sync:generate_table_ddl' command instead"
|
|
12
|
+
|
|
10
13
|
if `which mysqldump`.empty?
|
|
11
14
|
abort "mysqldump is not installed."
|
|
12
15
|
end
|
data/flydata.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = "flydata"
|
|
8
|
-
s.version = "0.1.
|
|
8
|
+
s.version = "0.1.3"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Koichi Fujikawa"]
|
|
12
|
-
s.date = "2014-05-
|
|
12
|
+
s.date = "2014-05-10"
|
|
13
13
|
s.description = "FlyData Command Line Interface"
|
|
14
14
|
s.email = "sysadmin@flydata.co"
|
|
15
15
|
s.executables = ["fdmysqldump", "flydata"]
|
|
@@ -86,7 +86,7 @@ Gem::Specification.new do |s|
|
|
|
86
86
|
s.homepage = "http://flydata.co/"
|
|
87
87
|
s.licenses = ["All right reserved."]
|
|
88
88
|
s.require_paths = ["lib"]
|
|
89
|
-
s.rubygems_version = "1.8.
|
|
89
|
+
s.rubygems_version = "1.8.24"
|
|
90
90
|
s.summary = "FlyData CLI"
|
|
91
91
|
|
|
92
92
|
if s.respond_to? :specification_version then
|
|
@@ -98,7 +98,7 @@ Gem::Specification.new do |s|
|
|
|
98
98
|
s.add_runtime_dependency(%q<activesupport>, ["~> 4.0.0"])
|
|
99
99
|
s.add_runtime_dependency(%q<json>, ["~> 1.8.0"])
|
|
100
100
|
s.add_runtime_dependency(%q<highline>, ["~> 1.6.19"])
|
|
101
|
-
s.add_runtime_dependency(%q<fluentd>, ["= 0.10.
|
|
101
|
+
s.add_runtime_dependency(%q<fluentd>, ["= 0.10.46"])
|
|
102
102
|
s.add_runtime_dependency(%q<ruby-binlog>, [">= 1.0.0"])
|
|
103
103
|
s.add_runtime_dependency(%q<fluent-plugin-mysql-binlog>, ["~> 0.0.2"])
|
|
104
104
|
s.add_runtime_dependency(%q<mysql2>, ["~> 0.3.11"])
|
|
@@ -117,7 +117,7 @@ Gem::Specification.new do |s|
|
|
|
117
117
|
s.add_dependency(%q<activesupport>, ["~> 4.0.0"])
|
|
118
118
|
s.add_dependency(%q<json>, ["~> 1.8.0"])
|
|
119
119
|
s.add_dependency(%q<highline>, ["~> 1.6.19"])
|
|
120
|
-
s.add_dependency(%q<fluentd>, ["= 0.10.
|
|
120
|
+
s.add_dependency(%q<fluentd>, ["= 0.10.46"])
|
|
121
121
|
s.add_dependency(%q<ruby-binlog>, [">= 1.0.0"])
|
|
122
122
|
s.add_dependency(%q<fluent-plugin-mysql-binlog>, ["~> 0.0.2"])
|
|
123
123
|
s.add_dependency(%q<mysql2>, ["~> 0.3.11"])
|
|
@@ -137,7 +137,7 @@ Gem::Specification.new do |s|
|
|
|
137
137
|
s.add_dependency(%q<activesupport>, ["~> 4.0.0"])
|
|
138
138
|
s.add_dependency(%q<json>, ["~> 1.8.0"])
|
|
139
139
|
s.add_dependency(%q<highline>, ["~> 1.6.19"])
|
|
140
|
-
s.add_dependency(%q<fluentd>, ["= 0.10.
|
|
140
|
+
s.add_dependency(%q<fluentd>, ["= 0.10.46"])
|
|
141
141
|
s.add_dependency(%q<ruby-binlog>, [">= 1.0.0"])
|
|
142
142
|
s.add_dependency(%q<fluent-plugin-mysql-binlog>, ["~> 0.0.2"])
|
|
143
143
|
s.add_dependency(%q<mysql2>, ["~> 0.3.11"])
|
data/lib/flydata/command/sync.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'msgpack'
|
|
2
2
|
require 'open3'
|
|
3
3
|
require 'flydata/sync_file_manager'
|
|
4
|
+
require 'flydata/table_def'
|
|
4
5
|
#require 'ruby-prof'
|
|
5
6
|
|
|
6
7
|
module Flydata
|
|
@@ -68,12 +69,54 @@ module Flydata
|
|
|
68
69
|
puts "Run 'flydata start' to start continuous sync."
|
|
69
70
|
end
|
|
70
71
|
|
|
72
|
+
def generate_table_ddl
|
|
73
|
+
de = retrieve_data_entries.first
|
|
74
|
+
raise "There are no data entry." unless de
|
|
75
|
+
case de['type']
|
|
76
|
+
when 'RedshiftMysqlDataEntry'
|
|
77
|
+
do_generate_table_ddl(de)
|
|
78
|
+
else
|
|
79
|
+
raise "No supported data entry. Only mysql-redshift sync is supported."
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
71
83
|
private
|
|
72
84
|
|
|
73
85
|
def do_check(de)
|
|
74
86
|
flydata.data_entry.buffer_stat(de['id'], env_mode)
|
|
75
87
|
end
|
|
76
88
|
|
|
89
|
+
DDL_DUMP_CMD_TEMPLATE = "mysqldump -d -h %s -P %s -u %s %s %s %s"
|
|
90
|
+
def do_generate_table_ddl(de)
|
|
91
|
+
if `which mysqldump`.empty?
|
|
92
|
+
raise "mysqldump is not installed. mysqldump is required to run the command"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
mp = de['mysql_data_entry_preference']
|
|
96
|
+
params = []
|
|
97
|
+
if mp['host'] then params << mp['host'] else raise "MySQL `host` is not defined in the data entry" end
|
|
98
|
+
params << (mp['port'] or '3306')
|
|
99
|
+
if mp['username'] then params << mp['username'] else raise "MySQL `username` is not defined is not defined in the data entry" end
|
|
100
|
+
params << (mp['password'] ? "-p#{mp['password']}" : "")
|
|
101
|
+
if mp['database'] then params << mp['database'] else raise "`database` is not defined in the data entry" end
|
|
102
|
+
if mp['tables'] then params << mp['tables'].gsub(/,/, ' ') else raise "`tables` is not defined in the data entry" end
|
|
103
|
+
command = DDL_DUMP_CMD_TEMPLATE % params
|
|
104
|
+
|
|
105
|
+
IO.popen(command, 'r') do |io|
|
|
106
|
+
create_flydata_ctl_table = true
|
|
107
|
+
while !io.eof?
|
|
108
|
+
mysql_tabledef = Flydata::TableDef::MysqlTableDef.create(io)
|
|
109
|
+
if mysql_tabledef.nil?
|
|
110
|
+
# stream had no more create table definition
|
|
111
|
+
break
|
|
112
|
+
end
|
|
113
|
+
flydata_tabledef = mysql_tabledef.to_flydata_tabledef
|
|
114
|
+
puts Flydata::TableDef::RedshiftTableDef.from_flydata_tabledef(flydata_tabledef, flydata_ctl_table: create_flydata_ctl_table)
|
|
115
|
+
create_flydata_ctl_table = false
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
77
120
|
def sync_mysql_to_redshift(de)
|
|
78
121
|
dp = flydata.data_port.get
|
|
79
122
|
sync_fm = Flydata::FileUtil::SyncFileManager.new(de)
|
|
@@ -5,6 +5,126 @@ require 'socket'
|
|
|
5
5
|
module Flydata
|
|
6
6
|
module Command
|
|
7
7
|
describe Sync do
|
|
8
|
+
let(:default_mysqldump_dir) do
|
|
9
|
+
File.join('/tmp', "sync_dump_#{Time.now.to_i}")
|
|
10
|
+
end
|
|
11
|
+
let(:default_data_entry) do
|
|
12
|
+
{"id"=>93,
|
|
13
|
+
"name"=>"flydata_sync_mysql",
|
|
14
|
+
"data_port_id"=>52,
|
|
15
|
+
"display_name"=>"flydata_sync_mysql",
|
|
16
|
+
"enabled"=>true,
|
|
17
|
+
"heroku_log_type"=>nil,
|
|
18
|
+
"heroku_resource_id"=>nil,
|
|
19
|
+
"log_deletion"=>nil,
|
|
20
|
+
"log_file_delimiter"=>nil,
|
|
21
|
+
"log_file_type"=>nil,
|
|
22
|
+
"log_path"=>nil,
|
|
23
|
+
"redshift_schema_name"=>"",
|
|
24
|
+
"redshift_table_name"=>nil,
|
|
25
|
+
"created_at"=>"2014-01-22T18:58:43Z",
|
|
26
|
+
"updated_at"=>"2014-01-30T02:42:26Z",
|
|
27
|
+
"type"=>"RedshiftMysqlDataEntry",
|
|
28
|
+
"tag_name"=>"flydata.a458c641_dp52.flydata_mysql",
|
|
29
|
+
"tag_name_dev"=>"flydata.a458c641_dp52.flydata_mysql.dev",
|
|
30
|
+
"data_port_key"=>"a458c641",
|
|
31
|
+
"mysql_data_entry_preference" =>
|
|
32
|
+
{ "host"=>"localhost", "port"=>3306, "username"=>"masashi",
|
|
33
|
+
"password"=>"welcome", "database"=>"sync_test", "tables"=>"table1, table2",
|
|
34
|
+
"mysqldump_dir"=>default_mysqldump_dir, "forwarder" => "tcpforwarder",
|
|
35
|
+
"data_servers"=>"localhost:9905" }
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
after :each do
|
|
40
|
+
if Dir.exists?(default_mysqldump_dir)
|
|
41
|
+
Dir.delete(default_mysqldump_dir) rescue nil
|
|
42
|
+
end
|
|
43
|
+
if File.exists?(default_mysqldump_dir)
|
|
44
|
+
File.delete(default_mysqldump_dir) rescue nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe '#do_generate_table_ddl' do
|
|
49
|
+
subject { Sync.new }
|
|
50
|
+
context 'with full options' do
|
|
51
|
+
it 'issues mysqldump command with expected parameters' do
|
|
52
|
+
expect(IO).to receive(:popen).with(
|
|
53
|
+
'mysqldump -d -h localhost -P 3306 -u masashi -pwelcome sync_test table1 table2', 'r').and_call_original
|
|
54
|
+
subject.send(:do_generate_table_ddl, default_data_entry)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
context 'without_host' do
|
|
58
|
+
before do
|
|
59
|
+
default_data_entry['mysql_data_entry_preference'].delete('host')
|
|
60
|
+
end
|
|
61
|
+
it "throws an error" do
|
|
62
|
+
expect {
|
|
63
|
+
subject.send(:do_generate_table_ddl, default_data_entry)
|
|
64
|
+
}.to raise_error
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
context 'without_port' do
|
|
68
|
+
before do
|
|
69
|
+
default_data_entry['mysql_data_entry_preference'].delete('port')
|
|
70
|
+
end
|
|
71
|
+
it "uses the default port" do
|
|
72
|
+
expect(IO).to receive(:popen).with(
|
|
73
|
+
'mysqldump -d -h localhost -P 3306 -u masashi -pwelcome sync_test table1 table2', 'r').and_call_original
|
|
74
|
+
subject.send(:do_generate_table_ddl, default_data_entry)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
context 'with_port_override' do
|
|
78
|
+
before do
|
|
79
|
+
default_data_entry['mysql_data_entry_preference']['port'] = 1234
|
|
80
|
+
end
|
|
81
|
+
it "uses the specified port" do
|
|
82
|
+
expect(IO).to receive(:popen).with(
|
|
83
|
+
'mysqldump -d -h localhost -P 1234 -u masashi -pwelcome sync_test table1 table2', 'r').and_call_original
|
|
84
|
+
subject.send(:do_generate_table_ddl, default_data_entry)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
context 'without_username' do
|
|
88
|
+
before do
|
|
89
|
+
default_data_entry['mysql_data_entry_preference'].delete('username')
|
|
90
|
+
end
|
|
91
|
+
it "throws an error" do
|
|
92
|
+
expect {
|
|
93
|
+
subject.send(:do_generate_table_ddl, default_data_entry)
|
|
94
|
+
}.to raise_error
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
context 'without_password' do
|
|
98
|
+
before do
|
|
99
|
+
default_data_entry['mysql_data_entry_preference'].delete('password')
|
|
100
|
+
end
|
|
101
|
+
it "call mysqldump without -p option" do
|
|
102
|
+
expect(IO).to receive(:popen).with(
|
|
103
|
+
'mysqldump -d -h localhost -P 3306 -u masashi sync_test table1 table2', 'r').and_call_original
|
|
104
|
+
subject.send(:do_generate_table_ddl, default_data_entry)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
context 'without_database' do
|
|
108
|
+
before do
|
|
109
|
+
default_data_entry['mysql_data_entry_preference'].delete('database')
|
|
110
|
+
end
|
|
111
|
+
it "throws an error" do
|
|
112
|
+
expect {
|
|
113
|
+
subject.send(:do_generate_table_ddl, default_data_entry)
|
|
114
|
+
}.to raise_error
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
context 'without_tables' do
|
|
118
|
+
before do
|
|
119
|
+
default_data_entry['mysql_data_entry_preference'].delete('tables')
|
|
120
|
+
end
|
|
121
|
+
it "throws an error" do
|
|
122
|
+
expect {
|
|
123
|
+
subject.send(:do_generate_table_ddl, default_data_entry)
|
|
124
|
+
}.to raise_error
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
8
128
|
end
|
|
9
129
|
end
|
|
10
130
|
|
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.1.
|
|
4
|
+
version: 0.1.3
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2014-05-
|
|
12
|
+
date: 2014-05-10 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rest-client
|
|
@@ -98,7 +98,7 @@ dependencies:
|
|
|
98
98
|
requirements:
|
|
99
99
|
- - '='
|
|
100
100
|
- !ruby/object:Gem::Version
|
|
101
|
-
version: 0.10.
|
|
101
|
+
version: 0.10.46
|
|
102
102
|
type: :runtime
|
|
103
103
|
prerelease: false
|
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -106,7 +106,7 @@ dependencies:
|
|
|
106
106
|
requirements:
|
|
107
107
|
- - '='
|
|
108
108
|
- !ruby/object:Gem::Version
|
|
109
|
-
version: 0.10.
|
|
109
|
+
version: 0.10.46
|
|
110
110
|
- !ruby/object:Gem::Dependency
|
|
111
111
|
name: ruby-binlog
|
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -390,7 +390,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
390
390
|
version: '0'
|
|
391
391
|
segments:
|
|
392
392
|
- 0
|
|
393
|
-
hash: -
|
|
393
|
+
hash: -1932242309607756156
|
|
394
394
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
395
395
|
none: false
|
|
396
396
|
requirements:
|
|
@@ -399,7 +399,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
399
399
|
version: '0'
|
|
400
400
|
requirements: []
|
|
401
401
|
rubyforge_project:
|
|
402
|
-
rubygems_version: 1.8.
|
|
402
|
+
rubygems_version: 1.8.24
|
|
403
403
|
signing_key:
|
|
404
404
|
specification_version: 3
|
|
405
405
|
summary: FlyData CLI
|