flydata 0.2.13 → 0.2.15

Sign up to get free protection for your applications and to get access to all the features.
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