flydata 0.2.6 → 0.2.7

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: 197b34bb3ccfc2ed09015f6a13413ecdbda4f5ed
4
- data.tar.gz: 0f04fd5270dee95ac4fe648ab5a8b2716302c5ce
3
+ metadata.gz: bfd589bd9943f41f8e817ec796aa74aef758d1f9
4
+ data.tar.gz: dc62b1dde189197fb3552abde072b40697e92dd5
5
5
  SHA512:
6
- metadata.gz: ff9fc62260afc8ce527de57edb70052f5cb35357e87f7db5ad12207ea2f0237c672bf3667eea92a79a8dc4b882ec2e484ca9e3e6aa58d52dcae24a56377e87a3
7
- data.tar.gz: 98a99de769067b51ce61f92a4bc6bc40e2651dbf5886aa0c4006cc1121136869984d0d97e50c27b409e4cfa1bd84c5a5c96406831cfd5496bcfb1839b11a800b
6
+ metadata.gz: 34006fd5e1f6052f901b92df572ae71c64e3deea4449d3c92aded6cf7013ecf5cd142e2d875c800c5778a5962af5d8add5627e315c3a46806df5980e8bbabceb
7
+ data.tar.gz: 9a7b312e2c03d2048878f211a6c0233d5d9d31bf7cce0cf655a75bc14287e226094779a45d0dd67df81d1b9f6d19aca1f74a4c04870da4fe6a969bcb4fa34ac5
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.6
1
+ 0.2.7
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.2.6 ruby lib
5
+ # stub: flydata 0.2.7 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "flydata"
9
- s.version = "0.2.6"
9
+ s.version = "0.2.7"
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 = "2014-09-26"
14
+ s.date = "2014-10-07"
15
15
  s.description = "FlyData Agent"
16
16
  s.email = "sysadmin@flydata.com"
17
17
  s.executables = ["fdmysqldump", "flydata", "serverinfo"]
@@ -52,6 +52,7 @@ Gem::Specification.new do |s|
52
52
  "lib/flydata/command/version.rb",
53
53
  "lib/flydata/credentials.rb",
54
54
  "lib/flydata/cron.rb",
55
+ "lib/flydata/errors.rb",
55
56
  "lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb",
56
57
  "lib/flydata/fluent-plugins/mysql/alter_table_query_handler.rb",
57
58
  "lib/flydata/fluent-plugins/mysql/binlog_position.rb",
@@ -3,6 +3,7 @@ require 'msgpack'
3
3
  require 'open3'
4
4
  require 'mysql2'
5
5
  require 'flydata/sync_file_manager'
6
+ require 'flydata/errors'
6
7
  require 'flydata/table_def'
7
8
  #require 'ruby-prof'
8
9
 
@@ -179,24 +180,32 @@ module Flydata
179
180
  raise "mysqldump is not installed. mysqldump is required to run the command"
180
181
  end
181
182
 
183
+ error_list = []
184
+
182
185
  schema_name = (de['schema_name'] || nil)
183
186
 
184
187
  mp = de['mysql_data_entry_preference']
185
188
  params = []
186
- if mp['host'] then params << mp['host'] else raise "MySQL `host` is not defined in the data entry" end
189
+ if !mp['host'].empty? then params << mp['host'] else raise "MySQL `host` is neither defined in the data entry nor the local config file" end
187
190
  params << (mp['port'] or '3306')
188
- if mp['username'] then params << mp['username'] else raise "MySQL `username` is not defined is not defined in the data entry" end
191
+ if !mp['username'].empty? then params << mp['username'] else raise "MySQL `username` is neither defined in the data entry nor the local config file" end
189
192
  params << (mp['password'].to_s.empty? ? "" : "-p#{mp['password']}")
190
- if mp['database'] then params << mp['database'] else raise "`database` is not defined in the data entry" end
191
- if mp['tables'] then params << mp['tables'].gsub(/,/, ' ') else raise "`tables` is not defined in the data entry" end
193
+ if !mp['database'].empty? then params << mp['database'] else raise "`database` is neither defined in the data entry nor the local config file" end
194
+ if !mp['tables'].empty? then params << mp['tables'].gsub(/,/, ' ') else raise "`tables` (or `tables_append_only`) is neither defined in the data entry nor the local config file" end
192
195
 
193
196
  command = DDL_DUMP_CMD_TEMPLATE % params
194
197
 
195
198
  Open3.popen3(command) do |stdin, stdout, stderr|
196
199
  stdin.close
200
+ stdout.set_encoding("utf-8") # mysqldump output must be in UTF-8
197
201
  create_flydata_ctl_table = mp['initial_sync']
198
202
  while !stdout.eof?
199
- mysql_tabledef = Flydata::TableDef::MysqlTableDef.create(stdout)
203
+ begin
204
+ mysql_tabledef = Flydata::TableDef::MysqlTableDef.create(stdout)
205
+ rescue TableDefError => e
206
+ error_list << e.err_hash
207
+ next
208
+ end
200
209
  if mysql_tabledef.nil?
201
210
  # stream had no more create table definition
202
211
  break
@@ -205,10 +214,23 @@ module Flydata
205
214
  puts Flydata::TableDef::RedshiftTableDef.from_flydata_tabledef(flydata_tabledef, flydata_ctl_table: create_flydata_ctl_table, schema_name: schema_name, ctl_only: opts.ctl_only?)
206
215
  create_flydata_ctl_table = false
207
216
  end
217
+ errors = ""
208
218
  while !stderr.eof?
209
- line = stderr.gets
210
- $stderr.print line unless /Warning: Using a password on the command line interface can be insecure./ === line
219
+ line = stderr.gets.gsub('mysqldump: ', '')
220
+ errors << line unless /Warning: Using a password on the command line interface can be insecure./ === line
221
+ end
222
+ raise errors unless errors.empty?
223
+ end
224
+ unless error_list.empty?
225
+ $stderr.puts "We have noticed the following error(s):"
226
+ group_error = error_list.group_by {|d| d[:error]}
227
+ group_error.each_key do |a|
228
+ $stderr.puts "The following table(s) have #{a}:"
229
+ group_error[a].each do |hash|
230
+ $stderr.puts " - #{hash[:table]}" if hash[:table]
231
+ end
211
232
  end
233
+ $stderr.puts "Please fix the above error(s) and try again."
212
234
  end
213
235
  end
214
236
 
@@ -851,7 +873,7 @@ EOT
851
873
  class MysqlDumpGeneratorMasterData < MysqlDumpGenerator
852
874
  EXTRA_MYSQLDUMP_PARAMS = "--flush-logs --master-data=2"
853
875
  def dump(file_path)
854
- cmd = "#{@dump_cmd} > #{file_path}"
876
+ cmd = "#{@dump_cmd} -r #{file_path}"
855
877
  o, e, s = Open3.capture3(cmd)
856
878
  e.to_s.each_line {|l| puts l unless /^Warning:/ =~ l } unless e.to_s.empty?
857
879
  unless s.exitstatus == 0
@@ -913,7 +935,8 @@ EOS
913
935
  # start dump
914
936
  Open3.popen3 @dump_cmd do |cmd_in, cmd_out, cmd_err|
915
937
  cmd_in.close_write
916
- File.open(file_path, "w") do |f|
938
+ cmd_out.set_encoding("utf-8") # mysqldump output must be in UTF-8
939
+ File.open(file_path, "w", encoding: "utf-8") do |f|
917
940
  find_insert_pos = :not_started
918
941
  cmd_out.each_line do |line|
919
942
  if find_insert_pos == :not_started && /^-- Server version/ === line
@@ -1111,7 +1134,7 @@ EOS
1111
1134
  end
1112
1135
 
1113
1136
  # Start reading file from top
1114
- File.open(@file_path, 'r') do |f|
1137
+ File.open(@file_path, 'r', encoding: "utf-8") do |f|
1115
1138
  last_saved_pos = 0
1116
1139
 
1117
1140
  # resume
@@ -0,0 +1,8 @@
1
+ module Flydata
2
+ class TableDefError < StandardError
3
+ attr_reader :err_hash
4
+ def initialize(err_hash)
5
+ @err_hash = err_hash
6
+ end
7
+ end
8
+ end
@@ -121,7 +121,7 @@ class MysqlTableDef
121
121
 
122
122
  when :after_create_table
123
123
  unless columns.any? {|column| column[:primary_key]}
124
- raise "Primary key must be defined."
124
+ raise TableDefError, {error: "no primary key defined", table: table_name}
125
125
  end
126
126
  break
127
127
  end
@@ -46,10 +46,17 @@ module Flydata
46
46
 
47
47
  describe '#do_generate_table_ddl' do
48
48
  subject { Sync.new }
49
+ shared_examples 'throws an error' do
50
+ it "throws an error" do
51
+ expect {
52
+ subject.send(:do_generate_table_ddl, default_data_entry)
53
+ }.to raise_error
54
+ end
55
+ end
49
56
  context 'with full options' do
50
57
  it 'issues mysqldump command with expected parameters' do
51
58
  expect(Open3).to receive(:popen3).with(
52
- 'mysqldump --protocol=tcp -d -h localhost -P 3306 -u masashi -pwelcome sync_test table1 table2').and_call_original
59
+ 'mysqldump --protocol=tcp -d -h localhost -P 3306 -u masashi -pwelcome sync_test table1 table2')
53
60
  subject.send(:do_generate_table_ddl, default_data_entry)
54
61
  end
55
62
  end
@@ -57,11 +64,13 @@ module Flydata
57
64
  before do
58
65
  default_data_entry['mysql_data_entry_preference'].delete('host')
59
66
  end
60
- it "throws an error" do
61
- expect {
62
- subject.send(:do_generate_table_ddl, default_data_entry)
63
- }.to raise_error
67
+ include_examples 'throws an error'
68
+ end
69
+ context 'with empty host' do
70
+ before do
71
+ default_data_entry['mysql_data_entry_preference']['host'] = ""
64
72
  end
73
+ include_examples 'throws an error'
65
74
  end
66
75
  context 'without_port' do
67
76
  before do
@@ -69,7 +78,7 @@ module Flydata
69
78
  end
70
79
  it "uses the default port" do
71
80
  expect(Open3).to receive(:popen3).with(
72
- 'mysqldump --protocol=tcp -d -h localhost -P 3306 -u masashi -pwelcome sync_test table1 table2').and_call_original
81
+ 'mysqldump --protocol=tcp -d -h localhost -P 3306 -u masashi -pwelcome sync_test table1 table2')
73
82
  subject.send(:do_generate_table_ddl, default_data_entry)
74
83
  end
75
84
  end
@@ -79,7 +88,7 @@ module Flydata
79
88
  end
80
89
  it "uses the specified port" do
81
90
  expect(Open3).to receive(:popen3).with(
82
- 'mysqldump --protocol=tcp -d -h localhost -P 1234 -u masashi -pwelcome sync_test table1 table2').and_call_original
91
+ 'mysqldump --protocol=tcp -d -h localhost -P 1234 -u masashi -pwelcome sync_test table1 table2')
83
92
  subject.send(:do_generate_table_ddl, default_data_entry)
84
93
  end
85
94
  end
@@ -87,11 +96,13 @@ module Flydata
87
96
  before do
88
97
  default_data_entry['mysql_data_entry_preference'].delete('username')
89
98
  end
90
- it "throws an error" do
91
- expect {
92
- subject.send(:do_generate_table_ddl, default_data_entry)
93
- }.to raise_error
99
+ include_examples 'throws an error'
100
+ end
101
+ context 'with empty username' do
102
+ before do
103
+ default_data_entry['mysql_data_entry_preference']['username'] = ""
94
104
  end
105
+ include_examples 'throws an error'
95
106
  end
96
107
  context 'without_password' do
97
108
  before do
@@ -99,7 +110,7 @@ module Flydata
99
110
  end
100
111
  it "call mysqldump without -p option" do
101
112
  expect(Open3).to receive(:popen3).with(
102
- 'mysqldump --protocol=tcp -d -h localhost -P 3306 -u masashi sync_test table1 table2').and_call_original
113
+ 'mysqldump --protocol=tcp -d -h localhost -P 3306 -u masashi sync_test table1 table2')
103
114
  subject.send(:do_generate_table_ddl, default_data_entry)
104
115
  end
105
116
  end
@@ -107,21 +118,25 @@ module Flydata
107
118
  before do
108
119
  default_data_entry['mysql_data_entry_preference'].delete('database')
109
120
  end
110
- it "throws an error" do
111
- expect {
112
- subject.send(:do_generate_table_ddl, default_data_entry)
113
- }.to raise_error
121
+ include_examples 'throws an error'
122
+ end
123
+ context 'with empty database' do
124
+ before do
125
+ default_data_entry['mysql_data_entry_preference']['database'] = ""
114
126
  end
127
+ include_examples 'throws an error'
115
128
  end
116
129
  context 'without_tables' do
117
130
  before do
118
131
  default_data_entry['mysql_data_entry_preference'].delete('tables')
119
132
  end
120
- it "throws an error" do
121
- expect {
122
- subject.send(:do_generate_table_ddl, default_data_entry)
123
- }.to raise_error
133
+ include_examples 'throws an error'
134
+ end
135
+ context 'with empty tables' do
136
+ before do
137
+ default_data_entry['mysql_data_entry_preference']['tables'] = ""
124
138
  end
139
+ include_examples 'throws an error'
125
140
  end
126
141
  end
127
142
  end
@@ -73,7 +73,7 @@ describe MysqlTableDef do
73
73
  context 'when table does not have primary key' do
74
74
  let(:dump_file_io) { file_io('mysqldump_test_table_no_pk.dump') }
75
75
  it 'should raise an error' do
76
- expect{subject}.to raise_error('Primary key must be defined.')
76
+ expect{subject}.to raise_error(Flydata::TableDefError)
77
77
  end
78
78
  end
79
79
 
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.2.6
4
+ version: 0.2.7
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: 2014-09-26 00:00:00.000000000 Z
15
+ date: 2014-10-07 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rest-client
@@ -421,6 +421,7 @@ files:
421
421
  - lib/flydata/command/version.rb
422
422
  - lib/flydata/credentials.rb
423
423
  - lib/flydata/cron.rb
424
+ - lib/flydata/errors.rb
424
425
  - lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb
425
426
  - lib/flydata/fluent-plugins/mysql/alter_table_query_handler.rb
426
427
  - lib/flydata/fluent-plugins/mysql/binlog_position.rb