flydata 0.2.13 → 0.2.15

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: 7d20120a45eeb0e80acb2738e924ff664454d8bf
4
- data.tar.gz: 96aadd0c65100102b2e659d063fbc1d9a391f56d
3
+ metadata.gz: f6cd04787878b2914745754010d02ec5f9abafae
4
+ data.tar.gz: dc7750c6a4cc5d5891cade50d5b3f8d2fd67ad6c
5
5
  SHA512:
6
- metadata.gz: be0a985f146c83e734435c5a84d38d32b0daf8e0c32a59f8774c6b1570d360cfcab3b42fc327cd01b8a54ba4229718b6e7049cc9c635f11c1bf333d163d02e79
7
- data.tar.gz: 09f3b5918fbe79bbdf86d0570f73524a646d7f507a89c3fe0ae4df9d846e3724577b52da4ee73dcd0f10172128664f2c9121b9d0f5d513ba38f5a5f84f4229d9
6
+ metadata.gz: c4dfb4894039ef88f6763a618151a714d3bdc02d7373c35d4ad3791f9f91fd33d959a435e1b4f50dc711ba1587bd8396dcb2b8b5b496e97200c1557cf919634d
7
+ data.tar.gz: 661851497f9b3b7e5c842a1e0341e3ce79b9040b2f29d53c229c0bd084e2895fed080be86e00ea4b9212d8c8fce62cfbfecf88078309c68226ea5450f6b17e8e
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.13
1
+ 0.2.15
@@ -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.13 ruby lib
5
+ # stub: flydata 0.2.15 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "flydata"
9
- s.version = "0.2.13"
9
+ s.version = "0.2.15"
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-11-08"
14
+ s.date = "2014-11-18"
15
15
  s.description = "FlyData Agent"
16
16
  s.email = "sysadmin@flydata.com"
17
17
  s.executables = ["fdmysqldump", "flydata", "serverinfo"]
@@ -99,6 +99,7 @@ Gem::Specification.new do |s|
99
99
  "spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb",
100
100
  "spec/flydata/fluent-plugins/mysql/alter_table_query_handler_spec.rb",
101
101
  "spec/flydata/fluent-plugins/mysql/binlog_position_spec.rb",
102
+ "spec/flydata/fluent-plugins/mysql/binlog_query_dispatcher_spec.rb",
102
103
  "spec/flydata/heroku_spec.rb",
103
104
  "spec/flydata/output/forwarder_spec.rb",
104
105
  "spec/flydata/parser/mysql/alter_table_parser_spec.rb",
@@ -113,6 +114,7 @@ Gem::Specification.new do |s|
113
114
  "spec/flydata/table_def/mysqldump_test_table_no_pk.dump",
114
115
  "spec/flydata/table_def/mysqldump_test_unique_key.dump",
115
116
  "spec/flydata/table_def/mysqldump_test_unique_key2.dump",
117
+ "spec/flydata/table_def/mysqldump_test_unique_key3.dump",
116
118
  "spec/flydata/table_def/mysqldump_test_unsigned.dump",
117
119
  "spec/flydata/table_def/redshift_table_def_spec.rb",
118
120
  "spec/flydata/util/encryptor_spec.rb",
@@ -118,9 +118,9 @@ EOF
118
118
  private
119
119
  # Return a list of fluentd parent processes run by the same user for the
120
120
  # same flydata.pid file but not the process managed by the file itself.
121
- CMD = %Q{ps -u `whoami` -o ppid,pid,args | grep '^ *1 ' | grep '\\%s' | egrep -v "\\b`cat %s`\\b"}
121
+ CMD = %Q{test -f %s && ps -u `whoami` -o ppid,pid,args | grep '^ *1 ' | grep '\\%s' | egrep -v "\\b`cat %s`\\b"}
122
122
  def orphan_processes
123
- cmd = CMD % [ daemon_option, pid_file ]
123
+ cmd = CMD % [ pid_file, daemon_option, pid_file ]
124
124
  result = `#{cmd}`
125
125
  orphan_pids = []
126
126
  result.each_line do |line|
@@ -341,7 +341,8 @@ EOM
341
341
  puts "Checking database size(not same as mysqldump data size)..."
342
342
  db_bytesize = Flydata::Parser::Mysql::DatabaseSizeCheck.new(de['mysql_data_entry_preference']).get_db_bytesize
343
343
  puts " -> #{as_size(db_bytesize)} (#{db_bytesize} byte)"
344
- puts "Exporting data from database..."
344
+ puts "Exporting data from database."
345
+ puts "This process can take hours depending on data size and load on your database. Please be patient..."
345
346
  Flydata::MysqlCompatibilityCheck.new(dp, de['mysql_data_entry_preference'], fp).check
346
347
  if file_dump
347
348
  Flydata::Parser::Mysql::MysqlDumpGeneratorNoMasterData.
@@ -17,9 +17,9 @@ module Mysql
17
17
  emit_record(:alter_table, record) do |opt|
18
18
  ret = nil
19
19
  begin
20
- result = ParserProvider.parser(:mysql, :mysql_alter_table).new.parse(record['query'])
20
+ result = ParserProvider.parser(:mysql, :mysql_alter_table).new.parse(normalized_query)
21
21
  if result.nil?
22
- $log.error("Received unsupported alter table query. query:'#{record['query']}'")
22
+ $log.error("Received unsupported alter table query. normalized query:'#{normalized_query}', raw query: '#{record['query']}'")
23
23
  else
24
24
  ret = result.tree
25
25
  breaking_query = ret[:actions].any?{|action| !action.has_key?(:support_level) || action[:support_level] != :nonbreaking}
@@ -27,8 +27,7 @@ module Mysql
27
27
  end
28
28
  rescue => e
29
29
  msg = <<EOS
30
- Received unsupported alter table query. query:'#{record['query']}'
31
- Caused by error '#{e.to_s}'
30
+ Received unsupported alter table query. normalized query:'#{normalized_query}', raw query: '#{record['query']}' Caused by error '#{e.to_s}'
32
31
  Stacktrace :
33
32
  #{e.backtrace.join("\n")}
34
33
  EOS
@@ -7,25 +7,47 @@ module Mysql
7
7
  end
8
8
 
9
9
  def dispatch(record)
10
- @handlers.each do |handler|
11
- query = normalize_query(record["query"])
12
- if (handler.pattern.match(query))
13
- handler.process(record, query)
14
- break
10
+ normalize_query(record["query"]) do |query|
11
+ @handlers.each do |handler|
12
+ if (handler.pattern.match(query))
13
+ handler.process(record, query)
14
+ break
15
+ end
15
16
  end
16
17
  end
17
18
  end
18
19
 
19
20
  private
20
21
 
21
- def normalize_query(query)
22
- query = strip_comments(query)
22
+ def normalize_query(queries)
23
+ queries = strip_comments(queries)
24
+ queries = queries.gsub(/\s+/, ' ') # replace multiple spaces with a space
25
+ queries.split(';').each do |query|
26
+ query = query.lstrip
27
+ yield(query + ";") if block_given? && !query.empty?
28
+ end
23
29
  end
24
30
 
25
31
  def strip_comments(query)
26
- query = query.gsub(/--\s.*\n/, ' ') # -- style comments
27
- query = query.gsub(/\/\*[^\*].*\*\//, ' ') # /* */ style comments
28
- query = query.gsub(/\s+/, ' ') # replace multiple spaces with a space
32
+ q = query.dup
33
+ # \/\*.*?\*\/ /* */ style comment
34
+ # `.*?` `resource_name`
35
+ # '(?:\\.|.)*?' 'string'
36
+ # "(?:\\.|.)*?" "string"
37
+ # --\s+.*?(?:\n|$) -- style comment
38
+ # #\s+.*?(?:\n|$) # style comment
39
+ query.scan(/(\/\*.*?\*\/|`.*?`|'(?:\\.|.)*?'|"(?:\\.|.)*?"|--\s+.*?(?:\n|$)|#.*?(?:\n|$))/m) do |m|
40
+ comment_or_quoted = m.first
41
+ if comment_or_quoted.start_with?("/*") || comment_or_quoted.start_with?("--") ||
42
+ comment_or_quoted.start_with?("#")
43
+ # comment. replace with spaces of the same length
44
+ idx_from = $~.offset(0)[0]
45
+ idx_to = $~.offset(0)[1]
46
+ len = idx_to - idx_from
47
+ q[idx_from...idx_to] = ' ' * len
48
+ end
49
+ end
50
+ q
29
51
  end
30
52
  end
31
53
 
@@ -16,7 +16,7 @@ grammar MysqlAlterTable
16
16
 
17
17
  rule alter_table
18
18
  alter_key sp online_option ignore_option table_key sp tbl_name
19
- sp alter_commands {
19
+ sp alter_commands (nsp ';')? {
20
20
  def tree
21
21
  value = {
22
22
  type: :alter_table,
@@ -217,7 +217,7 @@ class MysqlTableDef
217
217
  private
218
218
 
219
219
  def self.parse_key(line, columns, type = :primary_key)
220
- line = /\((?:`.*?`(?:,\s*)?)+\)/.match(line)[0]
220
+ line = /\((?:`.*?`(?:\(.*?\))?(?:,\s*)?)+\)/.match(line)[0]
221
221
  keys = line.scan(/`(.*?)`/).collect{|item| item[0]}
222
222
 
223
223
  keys.each do |key|
@@ -108,7 +108,7 @@ EOT
108
108
  EOT
109
109
  # QUERY: alter table add index
110
110
  TEST_EVENT_QUERY_ALTER_TABLE_ADD_INDEX = <<EOT
111
- {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>2, "server_id"=>1, "event_length"=>217, "next_position"=>337, "flags"=>0, "event_type"=>"Query", "thread_id"=>10097, "exec_time"=>0, "error_code"=>0, "variables"=>[0, 0, 0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 8, 0, 12, 1, 109, 97, 107, 95, 100, 101, 118, 101, 108, 111, 112, 109, 101, 110, 116, 0], "db_name"=>"test_db", "query"=>"ALTER TABLE `test_db`.`test_table` \nADD INDEX `my_index` USING HASH (`extra` ASC) COMMENT 'How does this look in binlog?'"}
111
+ {"marker"=>0, "timestamp"=>#{TEST_TIMESTAMP}, "type_code"=>2, "server_id"=>1, "event_length"=>217, "next_position"=>337, "flags"=>0, "event_type"=>"Query", "thread_id"=>10097, "exec_time"=>0, "error_code"=>0, "variables"=>[0, 0, 0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0, 0, 6, 3, 115, 116, 100, 4, 33, 0, 33, 0, 8, 0, 12, 1, 109, 97, 107, 95, 100, 101, 118, 101, 108, 111, 112, 109, 101, 110, 116, 0], "db_name"=>"test_db", "query"=>"ALTER TABLE `test_db`.`test_table` \nADD INDEX `my_index` USING HASH (`extra` ASC) COMMENT 'How does this look in binlog?'"}
112
112
  EOT
113
113
  # - 03 STOP_EVENT
114
114
  TEST_EVENT_STOP = <<EOT
@@ -349,7 +349,7 @@ EOT
349
349
  actions: [{
350
350
  action: :add_index,
351
351
  support_level: :nonbreaking,
352
- query: "ADD INDEX `my_index` USING HASH (`extra` ASC) COMMENT 'How does this look in binlog?'",
352
+ query: "ADD INDEX `my_index` USING HASH (`extra` ASC) COMMENT 'How does this look in binlog?'",
353
353
  }],
354
354
  })
355
355
  end
@@ -69,7 +69,7 @@ module Mysql
69
69
  expect(parser).to receive(:parse).and_return(nil)
70
70
  end
71
71
  it "returns nil with a warn log" do
72
- expect($log).to receive(:error).with(/Received unsupported alter table query\. query:'#{query}'/)
72
+ expect($log).to receive(:error).with(/Received unsupported alter table query\./)
73
73
 
74
74
  expect(subject.process(record, normalized_query)).to eq(nil)
75
75
  end
@@ -0,0 +1,176 @@
1
+ require_relative '../../../spec_helper'
2
+ require 'flydata/fluent-plugins/mysql/binlog_query_dispatcher'
3
+
4
+ module Mysql
5
+
6
+ QUERY_WITH_COMMENTS = <<EOT
7
+ -- ALTER TABLE QUERY comment
8
+ ALTER TABLE test_table
9
+ ADD /* test-comment */ COLUMN value10 -- aaaaa
10
+ -- bbbbb
11
+ VARCHAR(512) DEFAULT NULL
12
+ -- flydata
13
+ -- hapyrus
14
+ ;
15
+ EOT
16
+ NORMALIZED_QUERY_WITH_COMMENTS = "ALTER TABLE test_table ADD COLUMN value10 VARCHAR(512) DEFAULT NULL ;"
17
+
18
+ QUERY_WITH_LEADING_NEWLINE = <<EOT
19
+
20
+ ALTER TABLE test_table
21
+ ADD /* test-comment */ COLUMN
22
+ value10 -- aaaaa
23
+ -- bbbbb
24
+ VARCHAR(512) DEFAULT NULL
25
+ -- flydata
26
+ -- hapyrus
27
+
28
+ ;
29
+
30
+ EOT
31
+
32
+ CUSTOMER_QUERY = <<EOT
33
+ -- ALTER TABLE UserPaymentMethods DROP COLUMN GoogleWallet;
34
+ ALTER TABLE UserPaymentMethods ADD COLUMN GoogleWallet VARCHAR(512) DEFAULT NULL
35
+ /*!*/;
36
+ EOT
37
+
38
+ NORMALIZED_CUSTOMER_QUERY = "ALTER TABLE UserPaymentMethods ADD COLUMN GoogleWallet VARCHAR(512) DEFAULT NULL ;"
39
+
40
+ QUERY_WITH_SPECIAL_CHARS_IN_DEFAULT = <<EOT
41
+ alter table test_table add (value1 varchar(26) not null default 'flydata -- special', value2 int auto_increment); -- real comment
42
+ EOT
43
+ NORMALIZED_QUERY_WITH_SPECIAL_CHARS = "alter table test_table add (value1 varchar(26) not null default 'flydata -- special', value2 int auto_increment);"
44
+
45
+ describe FlydataBinlogQueryDispatcher do
46
+ let(:record) do
47
+ r = double('record')
48
+ allow(r).to receive(:[]).with("query").and_return(query)
49
+ r
50
+ end
51
+ let(:query_handler) do
52
+ r = double('query_handler')
53
+ allow(r).to receive(:pattern).and_return(/^ALTER TABLE/i)
54
+ expect(r).to receive(:process).with(record, normalized_query)
55
+ r
56
+ end
57
+ let(:context) { double('context') }
58
+ subject { described_class.new(context) }
59
+
60
+ shared_examples "a dispatcher that calls query handler with correct query" do
61
+ it do
62
+ expect(AlterTableQueryHandler).to receive(:new).with(context).and_return(query_handler)
63
+ expect(subject.dispatch(record))
64
+ end
65
+ end
66
+
67
+ describe '#dispatch' do
68
+ context "query with comments" do
69
+ let(:query) { QUERY_WITH_COMMENTS }
70
+ let(:normalized_query) { NORMALIZED_QUERY_WITH_COMMENTS }
71
+ it_behaves_like "a dispatcher that calls query handler with correct query"
72
+ end
73
+ context "customer query" do
74
+ let(:query) { CUSTOMER_QUERY }
75
+ let(:normalized_query) { NORMALIZED_CUSTOMER_QUERY }
76
+ it_behaves_like "a dispatcher that calls query handler with correct query"
77
+ end
78
+ context "query with leading newline" do
79
+ let(:query) { QUERY_WITH_LEADING_NEWLINE }
80
+ let(:normalized_query) { NORMALIZED_QUERY_WITH_COMMENTS }
81
+ it_behaves_like "a dispatcher that calls query handler with correct query"
82
+ end
83
+ context "query with special characters in DEFAULT" do
84
+ let(:query) { QUERY_WITH_SPECIAL_CHARS_IN_DEFAULT }
85
+ let(:normalized_query) { NORMALIZED_QUERY_WITH_SPECIAL_CHARS }
86
+ it_behaves_like "a dispatcher that calls query handler with correct query"
87
+ end
88
+ context "query with preceding commands" do
89
+ let(:query) { <<EOS }
90
+ use `mydatabase`/*!*/;
91
+ ALTER TABLE `apps` ADD `created_by_existing_admin` tinyint(1) DEFAULT 0 /*application:MyApp,line:/usr/local/lib/ruby/2.0.0/benchmark.rb:281:in `measure'*/
92
+ /*!*/;
93
+ SET TIMESTAMP=1415925954/*!*/;
94
+ EOS
95
+ let(:normalized_query) { <<EOS.gsub(/\n$/, '') }
96
+ ALTER TABLE `apps` ADD `created_by_existing_admin` tinyint(1) DEFAULT 0 ;
97
+ EOS
98
+ it_behaves_like "a dispatcher that calls query handler with correct query"
99
+ end
100
+ context "query with a comment with no space" do
101
+ let(:query) { <<EOS.gsub(/\n$/, '') }
102
+ alter table test add/* adding a column */test varchar(4);
103
+ EOS
104
+ let(:normalized_query) { <<EOS.gsub(/\n$/, '') }
105
+ alter table test add test varchar(4);
106
+ EOS
107
+ it_behaves_like "a dispatcher that calls query handler with correct query"
108
+ end
109
+ context "query with strings including comment quotes" do
110
+ let(:query) { <<EOS.gsub(/\n$/, '') }
111
+ alter table test add test varchar(256) DEFAULT ' /* ' COMMENT ' */ -- a part of COMMENT string';
112
+ EOS
113
+ let(:normalized_query) { <<EOS.gsub(/\n$/, '') }
114
+ alter table test add test varchar(256) DEFAULT ' /* ' COMMENT ' */ -- a part of COMMENT string';
115
+ EOS
116
+ it_behaves_like "a dispatcher that calls query handler with correct query"
117
+ end
118
+ context "query with comments including string quotes and ending without a line feed" do
119
+ let(:query) { <<EOS.gsub(/\n$/, '') }
120
+ alter table /* /* ' */ test add test varchar(256) -- this is a comment';
121
+ EOS
122
+ let(:normalized_query) { <<EOS.gsub(/\n$/, '') }
123
+ alter table test add test varchar(256) ;
124
+ EOS
125
+ it_behaves_like "a dispatcher that calls query handler with correct query"
126
+ end
127
+ context "query with DEFAULT using double-quote" do
128
+ let(:query) { <<EOS.gsub(/\n$/, '') }
129
+ alter table test add test varchar(256) DEFAULT "This # is default -- with \\\" in it";
130
+ EOS
131
+ let(:normalized_query) { <<EOS.gsub(/\n$/, '') }
132
+ alter table test add test varchar(256) DEFAULT "This # is default -- with \\\" in it";
133
+ EOS
134
+ it_behaves_like "a dispatcher that calls query handler with correct query"
135
+ end
136
+ context "query with # style comment" do
137
+ let(:query) { <<EOS.gsub(/\n$/, '') }
138
+ alter table test add test varchar(256) # You never know this works in MySQL '"
139
+ DEFAULT "This is default with \\\" in it"
140
+ EOS
141
+ let(:normalized_query) { <<EOS.gsub(/\n$/, '') }
142
+ alter table test add test varchar(256) DEFAULT "This is default with \\\" in it";
143
+ EOS
144
+ it_behaves_like "a dispatcher that calls query handler with correct query"
145
+ end
146
+ context "query with single quote string with escape" do
147
+ let(:query) { <<EOS.gsub(/\n$/, '') }
148
+ alter table test add test varchar(256) COMMENT 'Stave\\'s # -- diner'
149
+ EOS
150
+ let(:normalized_query) { <<EOS.gsub(/\n$/, '') }
151
+ alter table test add test varchar(256) COMMENT 'Stave\\'s # -- diner';
152
+ EOS
153
+ it_behaves_like "a dispatcher that calls query handler with correct query"
154
+ end
155
+ context "query with quoted string with UTF8 3 byte chars" do
156
+ let(:query) { <<EOS.gsub(/\n$/, '') }
157
+ alter table test add test varchar(256) DEFAULT "無国籍" COMMENT 'SJIS is トラブルメーカー'
158
+ EOS
159
+ let(:normalized_query) { <<EOS.gsub(/\n$/, '') }
160
+ alter table test add test varchar(256) DEFAULT "無国籍" COMMENT 'SJIS is トラブルメーカー';
161
+ EOS
162
+ it_behaves_like "a dispatcher that calls query handler with correct query"
163
+ end
164
+ context "query with comments with UTF8 3 byte chars" do
165
+ let(:query) { <<EOS.gsub(/\n$/, '') }
166
+ alter table test add test varchar(256) /* 無国籍 */ -- 'SJIS is トラブルメーカー'
167
+ DEFAULT NULL;
168
+ EOS
169
+ let(:normalized_query) { <<EOS.gsub(/\n$/, '') }
170
+ alter table test add test varchar(256) DEFAULT NULL;
171
+ EOS
172
+ it_behaves_like "a dispatcher that calls query handler with correct query"
173
+ end
174
+ end
175
+ end
176
+ end
@@ -130,21 +130,21 @@ describe MysqlTableDef do
130
130
  )
131
131
  end
132
132
  end
133
-
133
+
134
134
  context 'when table has unsigned column' do
135
135
  let(:dump_file_io) { file_io('mysqldump_test_unsigned.dump')}
136
136
  it 'should include unsigned in column type' do
137
137
  expect(subject[:columns]).to eq(
138
138
  [
139
- {:column=>"id", :type=>"int4(11)", :auto_increment=>true, :not_null=>true, :primary_key=>true},
139
+ {:column=>"id", :type=>"int4(11)", :auto_increment=>true, :not_null=>true, :primary_key=>true},
140
140
  {:column=>"value_int", :type=>"int4(10) unsigned", :default=>nil},
141
- {:column=>"value_float", :type=>"float4 unsigned", :default=>nil},
142
- {:column=>"value_dec", :type=>"numeric(10,2) unsigned", :default=>nil},
143
- {:column=>"value_double", :type=>"float8 unsigned", :default=>nil},
144
- {:column=>"name", :type=>"varchar(768)", :default=>nil},
141
+ {:column=>"value_float", :type=>"float4 unsigned", :default=>nil},
142
+ {:column=>"value_dec", :type=>"numeric(10,2) unsigned", :default=>nil},
143
+ {:column=>"value_double", :type=>"float8 unsigned", :default=>nil},
144
+ {:column=>"name", :type=>"varchar(768)", :default=>nil},
145
145
  {:column=>"value_small_int", :type=>"int2(5) unsigned", :default=>nil}
146
146
  ]
147
- )
147
+ )
148
148
  end
149
149
  end
150
150
 
@@ -156,11 +156,11 @@ describe MysqlTableDef do
156
156
  {:column=>"id", :type=>"int4(11)", :auto_increment=>true, :not_null=>true, :primary_key=>true},
157
157
  {:column=>"title", :type=>"varchar(768)", :unique=>true, :default=>nil},
158
158
  {:column=>"name", :type=>"text"},
159
- {:column=>"num", :type=>"int4(11)", :unique=>true, :default=>nil}
159
+ {:column=>"num", :type=>"int4(11)", :unique=>true, :default=>nil}
160
160
  ]
161
- )
161
+ )
162
162
  end
163
- end
163
+ end
164
164
 
165
165
  context 'when table has an unique key with a key name different than the column name' do
166
166
  let(:dump_file_io) { file_io('mysqldump_test_unique_key2.dump')}
@@ -170,11 +170,20 @@ describe MysqlTableDef do
170
170
  {:column=>"id", :type=>"int4(11)", :auto_increment=>true, :not_null=>true, :primary_key=>true},
171
171
  {:column=>"title", :type=>"varchar(768)", :unique=>true, :default=>nil},
172
172
  {:column=>"name", :type=>"text"},
173
- {:column=>"num", :type=>"int4(11)", :unique=>true, :default=>nil}
173
+ {:column=>"num", :type=>"int4(11)", :unique=>true, :default=>nil}
174
174
  ]
175
- )
175
+ )
176
176
  end
177
- end
177
+ end
178
+
179
+ context 'when table has unique keys with length specified' do
180
+ let(:dump_file_io) { file_io('mysqldump_test_unique_key3.dump')}
181
+ it 'should include unique in column def' do
182
+ subject[:columns].each { |col|
183
+ expect(col[:unique]).to eq(true) if ['app_id','overage_id','item_name'].include? col[:column]
184
+ }
185
+ end
186
+ end
178
187
  end
179
188
  end
180
189
 
@@ -0,0 +1,58 @@
1
+ -- MySQL dump 10.13 Distrib 5.5.40, for debian-linux-gnu (x86_64)
2
+ --
3
+ -- Host: localhost Database: flydata_sync
4
+ -- ------------------------------------------------------
5
+ -- Server version 5.5.40-0ubuntu0.12.04.1-log
6
+
7
+ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
8
+ /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
9
+ /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
10
+ /*!40101 SET NAMES utf8 */;
11
+ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
12
+ /*!40103 SET TIME_ZONE='+00:00' */;
13
+ /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
14
+ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
15
+ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
16
+ /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
17
+
18
+ --
19
+ -- Table structure for table `invoice_items`
20
+ --
21
+
22
+ DROP TABLE IF EXISTS `invoice_items`;
23
+ /*!40101 SET @saved_cs_client = @@character_set_client */;
24
+ /*!40101 SET character_set_client = utf8 */;
25
+ CREATE TABLE `invoice_items` (
26
+ `id` int(11) NOT NULL AUTO_INCREMENT,
27
+ `app_id` int(11) NOT NULL,
28
+ `subscription_id` int(11) NOT NULL,
29
+ `overage_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
30
+ `stripe_invoice_item_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
31
+ `stripe_error` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
32
+ `synced_to_stripe` tinyint(1) NOT NULL DEFAULT '0',
33
+ `description` text COLLATE utf8mb4_unicode_ci,
34
+ `item_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
35
+ `item_cost` int(11) NOT NULL,
36
+ `item_count` int(11) NOT NULL,
37
+ `total_cost` int(11) NOT NULL,
38
+ `created_at` datetime DEFAULT NULL,
39
+ `updated_at` datetime DEFAULT NULL,
40
+ `bill_ahead` tinyint(1) DEFAULT '0',
41
+ `bill_ahead_resolved_at` datetime DEFAULT NULL,
42
+ `stripe_invoice_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
43
+ `is_vat` tinyint(1) NOT NULL DEFAULT '0',
44
+ PRIMARY KEY (`id`),
45
+ UNIQUE KEY `index_invoice_items_on_app_id_and_overage_id_and_item_name` (`app_id`,`overage_id`(32),`item_name`(32)) USING BTREE
46
+ ) ENGINE=InnoDB AUTO_INCREMENT=16654 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
47
+ /*!40101 SET character_set_client = @saved_cs_client */;
48
+ /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
49
+
50
+ /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
51
+ /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
52
+ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
53
+ /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
54
+ /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
55
+ /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
56
+ /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
57
+
58
+ -- Dump completed on 2014-11-14 9:55:46
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.13
4
+ version: 0.2.15
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-11-08 00:00:00.000000000 Z
15
+ date: 2014-11-18 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rest-client
@@ -482,6 +482,7 @@ files:
482
482
  - spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb
483
483
  - spec/flydata/fluent-plugins/mysql/alter_table_query_handler_spec.rb
484
484
  - spec/flydata/fluent-plugins/mysql/binlog_position_spec.rb
485
+ - spec/flydata/fluent-plugins/mysql/binlog_query_dispatcher_spec.rb
485
486
  - spec/flydata/heroku_spec.rb
486
487
  - spec/flydata/output/forwarder_spec.rb
487
488
  - spec/flydata/parser/mysql/alter_table_parser_spec.rb
@@ -496,6 +497,7 @@ files:
496
497
  - spec/flydata/table_def/mysqldump_test_table_no_pk.dump
497
498
  - spec/flydata/table_def/mysqldump_test_unique_key.dump
498
499
  - spec/flydata/table_def/mysqldump_test_unique_key2.dump
500
+ - spec/flydata/table_def/mysqldump_test_unique_key3.dump
499
501
  - spec/flydata/table_def/mysqldump_test_unsigned.dump
500
502
  - spec/flydata/table_def/redshift_table_def_spec.rb
501
503
  - spec/flydata/util/encryptor_spec.rb