flydata 0.2.7 → 0.2.8

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: bfd589bd9943f41f8e817ec796aa74aef758d1f9
4
- data.tar.gz: dc62b1dde189197fb3552abde072b40697e92dd5
3
+ metadata.gz: c5fda2fb95c38692e1a0995b3ee7430ea706ec09
4
+ data.tar.gz: 5028033ad26d7399e7bcb091257540f1fb4ab46a
5
5
  SHA512:
6
- metadata.gz: 34006fd5e1f6052f901b92df572ae71c64e3deea4449d3c92aded6cf7013ecf5cd142e2d875c800c5778a5962af5d8add5627e315c3a46806df5980e8bbabceb
7
- data.tar.gz: 9a7b312e2c03d2048878f211a6c0233d5d9d31bf7cce0cf655a75bc14287e226094779a45d0dd67df81d1b9f6d19aca1f74a4c04870da4fe6a969bcb4fa34ac5
6
+ metadata.gz: dbcb9055ead8575095ef96d378d2817743f0c03cb629d6d7ef5d46bc99f04fd22e420f2c8011c28a97a3c5041ec683ed57045d59bd86c31fdb6ec680dbb81769
7
+ data.tar.gz: 1e77c0720dd22cad760cd00f11eef55514bb768937acb5b6970027f352d5cf97d9f2177b6d904aeb74c8716ab6f9f374757f3ce09780e3c166f79ad3b6a7360d
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.7
1
+ 0.2.8
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.7 ruby lib
5
+ # stub: flydata 0.2.8 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "flydata"
9
- s.version = "0.2.7"
9
+ s.version = "0.2.8"
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-10-07"
14
+ s.date = "2014-10-15"
15
15
  s.description = "FlyData Agent"
16
16
  s.email = "sysadmin@flydata.com"
17
17
  s.executables = ["fdmysqldump", "flydata", "serverinfo"]
@@ -35,8 +35,14 @@ module Flydata
35
35
  end
36
36
  def ask_yes_no(message, default_yes=true)
37
37
  suffix = default_yes ? "(Y/n)" : "(y/n)"
38
+ prompt = "#{message} #{suffix}: "
39
+ if opts && opts.yes? # Yes option
40
+ puts "#{prompt}Yes"
41
+ return true
42
+ end
43
+
38
44
  loop do
39
- ans = ask("#{message} #{suffix}: ")
45
+ ans = ask(prompt)
40
46
  return true if default_yes and ans == ''
41
47
  if ans.size > 0
42
48
  case ans[0].downcase
@@ -21,6 +21,7 @@ module Flydata
21
21
  def self.slop
22
22
  Slop.new do
23
23
  on 'c', 'skip-cleanup', 'Skip server cleanup'
24
+ on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
24
25
  end
25
26
  end
26
27
 
@@ -42,6 +43,12 @@ module Flydata
42
43
  sync_mysql_to_redshift(de)
43
44
  end
44
45
 
46
+ def self.slop_flush
47
+ Slop.new do
48
+ on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
49
+ end
50
+ end
51
+
45
52
  def flush
46
53
  flush_buffer_and_stop
47
54
  puts "Buffers have been flushed and the sender process has been stopped."
@@ -50,6 +57,7 @@ module Flydata
50
57
  def self.slop_reset
51
58
  Slop.new do
52
59
  on 'c', 'client', 'Resets client only.'
60
+ on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
53
61
  end
54
62
  end
55
63
 
@@ -134,6 +142,7 @@ module Flydata
134
142
  def self.slop_generate_table_ddl
135
143
  Slop.new do
136
144
  on 'c', 'ctl-only', 'Only generate FlyData Control definitions'
145
+ on 'y', 'yes', 'Skip command prompt assuming yes to all questions. Use this for batch operation.'
137
146
  end
138
147
  end
139
148
 
@@ -14,14 +14,16 @@ module Mysql
14
14
  end
15
15
 
16
16
  def process(record, normalized_query)
17
- emit_record(:alter_table, record, increment_table_rev: true) do
17
+ emit_record(:alter_table, record) do |opt|
18
18
  ret = nil
19
19
  begin
20
20
  result = ParserProvider.parser(:mysql, :mysql_alter_table).new.parse(record['query'])
21
21
  if result.nil?
22
- $log.warn("Received unsupported alter table query. query:'#{record['query']}'")
22
+ $log.error("Received unsupported alter table query. query:'#{record['query']}'")
23
23
  else
24
24
  ret = result.tree
25
+ breaking_query = ret[:actions].any?{|action| !action.has_key?(:support_level) || action[:support_level] != :nonbreaking}
26
+ opt[:increment_table_rev] = true if breaking_query
25
27
  end
26
28
  rescue => e
27
29
  msg = <<EOS
@@ -54,13 +54,14 @@ module Mysql
54
54
  @context.omit_events[table].nil? || !@context.omit_events[table].include?(type)
55
55
  end
56
56
 
57
- def emit_record(type, record, opt = {})
57
+ def emit_record(type, record)
58
58
  return unless acceptable_db?(record)
59
59
  return unless record["table_name"].nil? or acceptable_table?(record, record["table_name"])
60
60
 
61
61
  check_empty_binlog
62
62
 
63
- records = yield
63
+ opt = {}
64
+ records = yield(opt) # The block may set options as necessary
64
65
  return if records.nil? # skip
65
66
  records = [records] unless records.kind_of?(Array)
66
67
 
@@ -41,7 +41,7 @@ module Mysql
41
41
  end
42
42
 
43
43
  def emit_rows(type, record)
44
- emit_record(type, record) do |table|
44
+ emit_record(type, record) do |opt|
45
45
  records = record["rows"].collect do |row|
46
46
  row = yield(row) if block_given? # Give the caller a chance to generate the correct row
47
47
  { ROW => convert_to_flydata_row_format(row) }
@@ -20,10 +20,10 @@ grammar MysqlAlterTable
20
20
  def tree
21
21
  value = {
22
22
  type: :alter_table,
23
- table_name: tbl_name.table_part.text_value,
23
+ table_name: tbl_name.table_part.value,
24
24
  actions: alter_specs.actions
25
25
  }
26
- value[:schema_name] = tbl_name.schema_part.text_value if tbl_name.has_schema?
26
+ value[:schema_name] = tbl_name.schema_part.value if tbl_name.has_schema?
27
27
  value
28
28
  end
29
29
  }
@@ -41,27 +41,34 @@ grammar MysqlAlterTable
41
41
  alter_spec ( comma alter_spec )* {
42
42
  def actions
43
43
  ret = []
44
- concat_action!(ret, alter_spec.action)
44
+ ret.concat(actions_with_query(alter_spec))
45
45
  0.upto(elements[1].elements.size - 1) do |i|
46
- action = elements[1].elements[i].elements[1].action
47
- concat_action!(ret, action)
46
+ ret.concat(actions_with_query(elements[1].elements[i].elements[1]))
48
47
  end
49
48
  ret
50
49
  end
51
50
 
52
- def concat_action!(array, action)
51
+ def actions_with_query(alter_spec)
52
+ action = alter_spec.action
53
53
  if action.kind_of?(Array)
54
54
  actions = action
55
55
  else
56
56
  actions = [action]
57
57
  end
58
- array.concat(actions)
58
+ actions.each {|a| a[:query] = alter_spec.text_value }
59
+ actions
59
60
  end
60
61
  }
61
62
  end
62
63
 
63
64
  rule alter_spec
64
- add_key (sp col_key)? sp col_name_def ( sp pos_def )? {
65
+ add_key sp key_def {
66
+ def action
67
+ action_hash = key_def.action
68
+ action_hash
69
+ end
70
+ }
71
+ / add_key (sp col_key)? sp col_name_def ( sp pos_def )? {
65
72
  def action
66
73
  ret = { action: :add_column }
67
74
  ret.merge!(col_name_def.column_def)
@@ -71,7 +78,7 @@ grammar MysqlAlterTable
71
78
  ret
72
79
  end
73
80
  }
74
- / add_key (sp col_key)? sp '(' nsp col_name_def ( comma col_name_def )* nsp ')' {
81
+ / add_key (sp col_key)? nsp '(' nsp col_name_def ( comma col_name_def )* nsp ')' {
75
82
  def action
76
83
  ret = [col_name_def.column_def]
77
84
  ret += 0.upto(elements[6].elements.count - 1).collect do |i|
@@ -80,19 +87,423 @@ grammar MysqlAlterTable
80
87
  ret.collect{|v| {action: :add_column}.merge(v) }
81
88
  end
82
89
  }
90
+ / drop_key sp primary_sym sp key_sym {
91
+ def action
92
+ { action: :drop_primary_key }
93
+ end
94
+ }
95
+ / drop_key sp foreign_sym sp key_sym sp field_ident {
96
+ def action
97
+ { action: :drop_foreign_key,
98
+ support_level: :nonbreaking
99
+ }
100
+ end
101
+ }
102
+ / drop_key sp key_or_index sp field_ident {
103
+ def action
104
+ { action: "drop_#{key_or_index.text_value.downcase}".to_sym,
105
+ support_level: :nonbreaking
106
+ }
107
+ end
108
+ }
83
109
  / drop_key (sp col_key)? sp col_name {
84
110
  def action
85
111
  { action: :drop_column,
86
- column: col_name.text_value, }
112
+ column: col_name.value, }
113
+ end
114
+ }
115
+ / enable_sym sp keys_sym {
116
+ def action
117
+ { action: :enable_keys,
118
+ support_level: :nonbreaking,
119
+ }
120
+ end
121
+ }
122
+ / [^,]+ {
123
+ def action
124
+ raise "unsupported ALTER TABLE query. Contact FlyData Support"
87
125
  end
88
126
  }
89
- / [^,]+
127
+ end
128
+
129
+ rule key_def
130
+ normal_key_type key_alg nsp '(' key_list ')' normal_key_options {
131
+ def action
132
+ { action: :add_index,
133
+ support_level: :nonbreaking,
134
+ }
135
+ end
136
+ }
137
+ / normal_key_type opt_ident key_alg nsp '(' key_list ')' normal_key_options {
138
+ def action
139
+ { action: :add_index,
140
+ support_level: :nonbreaking,
141
+ }
142
+ end
143
+ }
144
+ / fulltext opt_key_or_index opt_ident init_key_options nsp '(' key_list ')' fulltext_key_options {
145
+ def action
146
+ { action: :add_index,
147
+ support_level: :nonbreaking,
148
+ }
149
+ end
150
+ }
151
+ / spatial opt_key_or_index opt_ident init_key_options nsp '(' key_list ')' spatial_key_options {
152
+ def action
153
+ { action: :add_index,
154
+ support_level: :nonbreaking,
155
+ }
156
+ end
157
+ }
158
+ / constraint_sym sp constraint_key_type key_alg nsp '(' key_list ')' normal_key_options {
159
+ def action
160
+ case constraint_key_type.value
161
+ when :unique
162
+ { action: :add_unique_constraint,
163
+ support_level: :nonbreaking
164
+ }
165
+ when :primary_key
166
+ { action: :add_primary_key_constraint,
167
+ keys: key_list.value
168
+ }
169
+ else
170
+ raise "Unsupported constraint key type `#{constraint_key_type.value}"
171
+ end
172
+ end
173
+ }
174
+ / constraint_sym sp constraint_key_type opt_ident key_alg nsp '(' key_list ')' normal_key_options {
175
+ def action
176
+ case constraint_key_type.value
177
+ when :unique
178
+ { action: :add_unique_constraint,
179
+ support_level: :nonbreaking
180
+ }
181
+ when :primary_key
182
+ { action: :add_primary_key_constraint,
183
+ keys: key_list.value
184
+ }
185
+ else
186
+ raise "Unsupported constraint key type `#{constraint_key_type.value}"
187
+ end
188
+ end
189
+ }
190
+ / opt_constraint constraint_key_type key_alg nsp '(' key_list ')' normal_key_options {
191
+ def action
192
+ case constraint_key_type.value
193
+ when :unique
194
+ { action: :add_unique_constraint,
195
+ support_level: :nonbreaking
196
+ }
197
+ when :primary_key
198
+ { action: :add_primary_key_constraint,
199
+ keys: key_list.value
200
+ }
201
+ else
202
+ raise "Unsupported constraint key type `#{constraint_key_type.value}"
203
+ end
204
+ end
205
+ }
206
+ / opt_constraint constraint_key_type opt_ident key_alg nsp '(' key_list ')' normal_key_options {
207
+ def action
208
+ case constraint_key_type.value
209
+ when :unique
210
+ { action: :add_unique_constraint,
211
+ support_level: :nonbreaking
212
+ }
213
+ when :primary_key
214
+ { action: :add_primary_key_constraint,
215
+ keys: key_list.value
216
+ }
217
+ else
218
+ raise "Unsupported constraint key type `#{constraint_key_type.value}"
219
+ end
220
+ end
221
+ }
222
+ / opt_constraint 'foreign'i key_sym opt_ident nsp '(' key_list ')' sp references
223
+ / constraint_sym sp check_constraint {
224
+ def action
225
+ { action: :add_check_constraint,
226
+ support_level: :nonbreaking,
227
+ }
228
+ end
229
+ }
230
+ / opt_constraint check_constraint {
231
+ def action
232
+ { action: :add_check_constraint,
233
+ support_level: :nonbreaking,
234
+ }
235
+ end
236
+ }
237
+ end
238
+
239
+ rule check_constraint
240
+ 'check'i nsp '(' nsp expr nsp ')'
241
+ end
242
+
243
+ rule expr
244
+ ( !')' . )+
245
+ end
246
+
247
+ rule references
248
+ 'references'i sp table_ident opt_ref_list opt_match_clause opt_on_update_delete
249
+ end
250
+
251
+ rule table_ident
252
+ ident '.' ident
253
+ / '.' ident
254
+ / ident
255
+ end
256
+
257
+ rule opt_ref_list
258
+ ( nsp '(' nsp ref_list nsp ')' )?
259
+ end
260
+
261
+ rule ref_list
262
+ ident comma ref_list
263
+ / ident
264
+ end
265
+
266
+ rule opt_match_clause
267
+ ( sp ( 'match'i sp 'full'i / 'match'i sp 'partial'i / 'match'i sp 'simple'i ) )?
268
+ end
269
+
270
+ rule opt_on_update_delete
271
+ ( sp (
272
+ 'on'i sp 'update'i delete_option sp 'on'i sp 'delete'i sp delete_option
273
+ / 'on'i sp 'delete'i delete_option sp 'on'i sp 'update'i sp delete_option
274
+ / 'on'i sp 'update'i sp delete_option
275
+ / 'on'i sp 'delete'i sp delete_option
276
+ )
277
+ )?
278
+ end
279
+
280
+ rule delete_option
281
+ 'restrict'i
282
+ / 'cascade'i
283
+ / 'set'i sp 'null'i
284
+ / 'no'i sp 'action'i
285
+ / 'set'i sp 'default'i
286
+ end
287
+
288
+ rule opt_constraint
289
+ ( constraint sp )?
290
+ end
291
+
292
+ rule constraint
293
+ constraint_sym opt_ident
294
+ end
295
+
296
+ rule constraint_sym
297
+ 'constraint'i
298
+ end
299
+
300
+ rule constraint_key_type
301
+ primary_sym sp key_sym {
302
+ # #value returns a normalized value of the element while #text_value
303
+ # returns its text as is
304
+ def value
305
+ :primary_key
306
+ end
307
+ }
308
+ / unique_sym opt_key_or_index {
309
+ def value
310
+ :unique
311
+ end
312
+ }
313
+ end
314
+
315
+ rule primary_sym
316
+ 'primary'i
317
+ end
318
+
319
+ rule key_sym
320
+ 'key'i
321
+ end
322
+
323
+ rule keys_sym
324
+ 'keys'i
325
+ end
326
+
327
+ rule unique_sym
328
+ 'unique'i
329
+ end
330
+
331
+ rule index_sym
332
+ 'index'i
333
+ end
334
+
335
+ rule enable_sym
336
+ 'enable'i
337
+ end
338
+
339
+ rule foreign_sym
340
+ 'foreign'i
341
+ end
342
+
343
+ rule fulltext
344
+ 'fulltext'i
345
+ end
346
+
347
+ rule fulltext_key_options
348
+ ( sp fulltext_key_opts )?
349
+ end
350
+
351
+ rule fulltext_key_opts
352
+ fulltext_key_opt sp fulltext_key_opts
353
+ / fulltext_key_opt
354
+ end
355
+
356
+ rule fulltext_key_opt
357
+ all_key_opt
358
+ / 'with parser'i sp ident_sys
359
+ end
360
+
361
+ rule spatial
362
+ 'spatial'i
363
+ end
364
+
365
+ rule spatial_key_options
366
+ ( sp spatial_key_opts )?
367
+ end
368
+
369
+ rule spatial_key_opts
370
+ spatial_key_opt sp spatial_key_opts
371
+ / spatial_key_opt
372
+ end
373
+
374
+ rule spatial_key_opt
375
+ all_key_opt
376
+ end
377
+
378
+ rule opt_key_or_index
379
+ ( sp key_or_index )?
380
+ end
381
+
382
+ rule normal_key_type
383
+ key_or_index
384
+ end
385
+
386
+ rule key_or_index
387
+ key_sym / index_sym
388
+ end
389
+
390
+ rule opt_ident
391
+ ( sp field_ident )?
392
+ end
393
+
394
+ rule field_ident
395
+ ident '.' ident '.' ident
396
+ / ident '.' ident
397
+ / '.' ident
398
+ / ident
399
+ end
400
+
401
+ rule key_alg
402
+ sp init_key_options key_using_alg
403
+ / init_key_options
404
+ end
405
+
406
+ rule init_key_options
407
+ '' # In original, this is doing some initialization
408
+ end
409
+
410
+ rule key_using_alg
411
+ 'using'i sp btree_or_rtree
412
+ / type_sym sp btree_or_rtree
413
+ end
414
+
415
+ rule btree_or_rtree
416
+ 'btree'i / 'rtree'i / 'hash'i
417
+ end
418
+
419
+ rule type_sym
420
+ 'type'i
421
+ end
422
+
423
+ rule key_list
424
+ nsp key_part order_dir nsp ',' nsp key_list nsp {
425
+ # #value returns a normalized value of the element while #text_value
426
+ # returns its text as is
427
+ def value
428
+ order_dir_value = order_dir.value
429
+ if order_dir_value && !order_dir_value.empty?
430
+ order_dir_value = " " + order_dir_value
431
+ end
432
+ [ "#{key_part.value}#{order_dir_value}" ] + key_list.value
433
+ end
434
+ }
435
+ / nsp key_part order_dir nsp {
436
+ def value
437
+ order_dir_value = order_dir.value
438
+ if order_dir_value && !order_dir_value.empty?
439
+ order_dir_value = " " + order_dir_value
440
+ end
441
+ [ "#{key_part.value}#{order_dir_value}" ]
442
+ end
443
+ }
444
+ end
445
+
446
+ rule key_part
447
+ ident nsp '(' nsp num nsp ')' {
448
+ # #value returns a normalized value of the element while #text_value
449
+ # returns its text as is
450
+ def value
451
+ "#{ident.value}(#{num.text_value})"
452
+ end
453
+ }
454
+ / ident
455
+ end
456
+
457
+ rule order_dir
458
+ # Treetop creates an empty SyntaxNode if the rule results in "match none"
459
+ # The SyntaxNode instance does not have a custom method as deinfed here,
460
+ # so it causes an issue to other nodes expecting the method.
461
+ # 1..1 is a magic trick to force Treetop creating a SyntaxNode with
462
+ # the custom method.
463
+ (( sp ('asc'i / 'desc'i) )?) 1..1 {
464
+ def value
465
+ text_value.strip.downcase
466
+ end
467
+ }
468
+ end
469
+
470
+ rule normal_key_options
471
+ ( sp normal_key_opts )?
472
+ end
473
+
474
+ rule normal_key_opts
475
+ normal_key_opt sp normal_key_opts
476
+ / normal_key_opt
477
+ end
478
+
479
+ rule normal_key_opt
480
+ all_key_opt
481
+ / key_using_alg
482
+ end
483
+
484
+ rule all_key_opt
485
+ key_block_size nsp equal nsp ulong_num
486
+ / key_block_size sp ulong_num
487
+ / comment_opt
488
+ end
489
+
490
+ rule opt_equal
491
+ ( nsp equal )?
492
+ end
493
+
494
+ rule equal
495
+ '='
496
+ / ':='
497
+ end
498
+
499
+ rule key_block_size
500
+ 'key_block_size'i
90
501
  end
91
502
 
92
503
  rule col_name_def
93
504
  col_name sp col_def {
94
505
  def column_def
95
- {column: col_name.text_value}.merge(col_def.column_def)
506
+ {column: col_name.value}.merge(col_def.column_def)
96
507
  end
97
508
  }
98
509
  end
@@ -105,7 +516,7 @@ grammar MysqlAlterTable
105
516
  }
106
517
  / 'after'i sp col_name {
107
518
  def pos_def_option
108
- { after: col_name.text_value, }
519
+ { after: col_name.value, }
109
520
  end
110
521
  }
111
522
  end
@@ -158,7 +569,7 @@ grammar MysqlAlterTable
158
569
  end
159
570
 
160
571
  rule data_type_name
161
- ident ''
572
+ ident_sym ''
162
573
  end
163
574
 
164
575
  rule meta_text
@@ -248,6 +659,14 @@ grammar MysqlAlterTable
248
659
  [0-9]* '.' [0-9]+ { def text_value; v = super; v.start_with?('.') ? "0#{v}" : v; end }
249
660
  / [0-9]+
250
661
  end
662
+ rule num
663
+ [0-9]+
664
+ end
665
+
666
+ rule ulong_num
667
+ [0-9]+ # TODO May not be the correct definition
668
+ end
669
+
251
670
  rule auto_increment_opt
252
671
  'auto_increment'i
253
672
  end
@@ -325,7 +744,7 @@ grammar MysqlAlterTable
325
744
 
326
745
  rule value
327
746
  quoted_value { def raw_value; text_raw_value; end }
328
- / ident { def raw_value; text_value; end }
747
+ / ident_sym { def raw_value; text_value; end }
329
748
  end
330
749
 
331
750
  rule quoted_value
@@ -333,21 +752,41 @@ grammar MysqlAlterTable
333
752
  end
334
753
 
335
754
  rule text
336
- ("\\\\" / "\\'" / !"'" .)*
755
+ ("\\\\" / "\\'" / !"'" . )*
756
+ end
757
+
758
+ rule ident
759
+ ident_sys / keyword
760
+ end
761
+
762
+ rule keyword
763
+ ([a-zA-Z_]+) 1..1 { # TODO list all keywords
764
+ def value
765
+ text_value
766
+ end
767
+ }
337
768
  end
338
769
 
339
770
  rule ident_sys
340
- ident / ident_quoted
771
+ ident_sym / ident_quoted
341
772
  end
342
773
 
343
- rule ident
344
- [0-9a-zA-Z_]+
774
+ rule ident_sym
775
+ # 1..1 prevents Treetop from embedding the SyntaxNode to an upper node
776
+ # without the custom method.
777
+ ([0-9a-zA-Z_]+) 1..1 {
778
+ def value
779
+ text_value
780
+ end
781
+ }
345
782
  end
346
783
 
347
784
  rule ident_quoted
348
- '`' ident '`' {
349
- def text_value
350
- ident.text_value
785
+ '`' ident_sym '`' {
786
+ # #value returns a normalized value of the element while #text_value
787
+ # returns its text as is
788
+ def value
789
+ ident_sym.value
351
790
  end
352
791
  }
353
792
  end