flydata 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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.35"
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"
@@ -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.1.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.35)
34
- cool.io (~> 1.1.0)
35
- http_parser.rb (~> 0.5.1)
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.5.3)
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.0)
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.6)
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.1.0)
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.35)
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
1
+ 0.1.3
@@ -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
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "flydata"
8
- s.version = "0.1.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-01"
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.23"
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.35"])
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.35"])
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.35"])
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"])
@@ -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.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-01 00:00:00.000000000 Z
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.35
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.35
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: -2999852327908013183
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.23
402
+ rubygems_version: 1.8.24
403
403
  signing_key:
404
404
  specification_version: 3
405
405
  summary: FlyData CLI