sdbcli 1.1.4 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -70,7 +70,7 @@ https://bitbucket.org/winebarrel/sdbcli
70
70
  DELETE [attr1, ...] FROM domain_name WHERE [WHERE expression] [sort_instructions] [LIMIT limit]
71
71
  deletes the attribute of an item or an item
72
72
 
73
- SELECT output_list FROM domain_name [WHERE expression] [sort_instructions] [LIMIT limit]
73
+ SELECT output_list FROM domain_name [WHERE expression] [sort_instructions] [LIMIT limit] [ | ruby script ]
74
74
  queries using the SELECT statement
75
75
  see http://docs.aws.amazon.com/AmazonSimpleDB/latest/DeveloperGuide/UsingSelect.html
76
76
 
@@ -134,3 +134,26 @@ see http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/Quoti
134
134
  // 7500 rows was inputted...
135
135
 
136
136
  If '-' is specified as a file name, the input/output of data will become a standard input/output.
137
+
138
+ == Pipe to ruby
139
+
140
+ ap-northeast-1> select * from employees limit 3;
141
+ ---
142
+ - ["100000", {first_name: Hiroyasu, hire_date: "1991-07-02", birth_date: "1956-01-11", last_name: Emden}]
143
+ - ["100001", {first_name: Jasminko, hire_date: "1994-12-25", birth_date: "1953-02-07", last_name: Antonakopoulos}]
144
+ - ["100002", {first_name: Claudi, hire_date: "1988-02-20", birth_date: "1957-03-04", last_name: Kolinko}]
145
+ # 3 rows in set
146
+
147
+ ap-northeast-1> select * from employees limit 3 | hire_date.max;
148
+ --- "1994-12-25"
149
+
150
+ ap-northeast-1> select * from employees limit 3 | hire_date.to_i;
151
+ ---
152
+ - 1991
153
+ - 1994
154
+ - 1988
155
+ # 3 rows in set
156
+ ap-northeast-1> select * from employees limit 3 | hire_date.to_f.avg;
157
+ --- 1991.0
158
+
159
+ 'sum' method and 'avg' method are added to the Array class.
data/bin/sdbcli CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
3
3
 
4
- Version = '1.1.4'
4
+ Version = '1.2.0'
5
5
  HISTORY_FILE = File.join((ENV['HOME'] || ENV['USERPROFILE'] || '.'), '.sdbcli_history')
6
6
  HISTSIZE = 500
7
7
  SELECT_LIMIT = 2500
@@ -16,6 +16,7 @@ require 'strscan'
16
16
  require 'syck' if /\A1\.9/ =~ RUBY_VERSION
17
17
  require 'yaml'
18
18
  require 'json'
19
+ require 'time'
19
20
 
20
21
  access_key_id = ENV['AWS_ACCESS_KEY_ID']
21
22
  secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
@@ -72,7 +73,7 @@ def execute(src, show_rows = false)
72
73
  buf = ''
73
74
 
74
75
  until ss.eos?
75
- if (tok = ss.scan %r{[^-`'";\\/#]+})
76
+ if (tok = ss.scan %r{[^-`'";\\/#]+}) #'
76
77
  buf << tok
77
78
  elsif (tok = ss.scan /`(?:[^`]|``)*`/)
78
79
  buf << tok
@@ -108,14 +109,15 @@ def execute(src, show_rows = false)
108
109
  out = $runner.execute(query, inline, $consistent)
109
110
  end
110
111
 
111
- if out.kind_of?(Integer)
112
+ if out.kind_of?(SimpleDB::Runner::Rownum)
113
+ rownum = out.to_i
112
114
  puts case $format
113
115
  when :yaml
114
- "# #{out} #{out > 1 ? 'rows' : 'row'} changed"
116
+ "# #{rownum} #{rownum > 1 ? 'rows' : 'row'} changed"
115
117
  when :json
116
- "// #{out} #{out > 1 ? 'rows' : 'row'} changed"
118
+ "// #{rownum} #{rownum > 1 ? 'rows' : 'row'} changed"
117
119
  else
118
- "# #{out} #{out > 1 ? 'rows' : 'row'} changed"
120
+ "# #{rownum} #{rownum > 1 ? 'rows' : 'row'} changed"
119
121
  end
120
122
  elsif out
121
123
  str = nil
@@ -374,6 +376,7 @@ DELETE [attr1, ...] FROM domain_name WHERE [WHERE expression] [sort_instructions
374
376
  deletes the attribute of an item or an item
375
377
 
376
378
  SELECT output_list FROM domain_name [WHERE expression] [sort_instructions] [LIMIT limit]
379
+ SELECT output_list FROM domain_name [WHERE expression] [sort_instructions] [LIMIT limit] [ | ruby script ]
377
380
  queries using the SELECT statement
378
381
  see http://docs.aws.amazon.com/AmazonSimpleDB/latest/DeveloperGuide/UsingSelect.html
379
382
 
@@ -13,7 +13,7 @@ module SimpleDB
13
13
 
14
14
  class Parser < Racc::Parser
15
15
 
16
- module_eval(<<'...end sdb-parser.y/module_eval...', 'sdb-parser.y', 228)
16
+ module_eval(<<'...end sdb-parser.y/module_eval...', 'sdb-parser.y', 249)
17
17
 
18
18
  KEYWORDS = %w(
19
19
  ADD
@@ -609,82 +609,103 @@ module_eval(<<'.,.,', 'sdb-parser.y', 162)
609
609
 
610
610
  module_eval(<<'.,.,', 'sdb-parser.y', 168)
611
611
  def _reduce_41(val, _values)
612
- struct(:SELECT, :query => val[0])
612
+ query = ''
613
+ ruby = nil
614
+
615
+ ss = StringScanner.new(val[0])
616
+
617
+ until ss.eos?
618
+ if (tok = ss.scan %r{[^-`'";\\/#|]+}) #'
619
+ query << tok
620
+ elsif (tok = ss.scan /`(?:[^`]|``)*`/)
621
+ query << tok
622
+ elsif (tok = ss.scan /'(?:[^']|'')*'/) #'
623
+ query << tok
624
+ elsif (tok = ss.scan /"(?:[^"]|"")*"/) #"
625
+ query << tok
626
+ elsif (tok = ss.scan /\|/)
627
+ ruby = ss.scan_until(/\Z/)
628
+ elsif (tok = ss.scan /./)
629
+ query << tok
630
+ end
631
+ end
632
+
633
+ struct(:SELECT, :query => query, :ruby => ruby)
613
634
 
614
635
  end
615
636
  .,.,
616
637
 
617
- module_eval(<<'.,.,', 'sdb-parser.y', 173)
638
+ module_eval(<<'.,.,', 'sdb-parser.y', 194)
618
639
  def _reduce_42(val, _values)
619
640
  struct(:CREATE, :domain => val[2])
620
641
 
621
642
  end
622
643
  .,.,
623
644
 
624
- module_eval(<<'.,.,', 'sdb-parser.y', 178)
645
+ module_eval(<<'.,.,', 'sdb-parser.y', 199)
625
646
  def _reduce_43(val, _values)
626
647
  struct(:DROP, :domain => val[2])
627
648
 
628
649
  end
629
650
  .,.,
630
651
 
631
- module_eval(<<'.,.,', 'sdb-parser.y', 183)
652
+ module_eval(<<'.,.,', 'sdb-parser.y', 204)
632
653
  def _reduce_44(val, _values)
633
654
  struct(:SHOW, :operand => :domains)
634
655
 
635
656
  end
636
657
  .,.,
637
658
 
638
- module_eval(<<'.,.,', 'sdb-parser.y', 187)
659
+ module_eval(<<'.,.,', 'sdb-parser.y', 208)
639
660
  def _reduce_45(val, _values)
640
661
  struct(:SHOW, :operand => :regions)
641
662
 
642
663
  end
643
664
  .,.,
644
665
 
645
- module_eval(<<'.,.,', 'sdb-parser.y', 191)
666
+ module_eval(<<'.,.,', 'sdb-parser.y', 212)
646
667
  def _reduce_46(val, _values)
647
668
  struct(:USE, :endpoint => val[1])
648
669
 
649
670
  end
650
671
  .,.,
651
672
 
652
- module_eval(<<'.,.,', 'sdb-parser.y', 195)
673
+ module_eval(<<'.,.,', 'sdb-parser.y', 216)
653
674
  def _reduce_47(val, _values)
654
675
  struct(:DESCRIBE, :domain => val[1])
655
676
 
656
677
  end
657
678
  .,.,
658
679
 
659
- module_eval(<<'.,.,', 'sdb-parser.y', 199)
680
+ module_eval(<<'.,.,', 'sdb-parser.y', 220)
660
681
  def _reduce_48(val, _values)
661
682
  struct(:DESCRIBE, :domain => val[1])
662
683
 
663
684
  end
664
685
  .,.,
665
686
 
666
- module_eval(<<'.,.,', 'sdb-parser.y', 204)
687
+ module_eval(<<'.,.,', 'sdb-parser.y', 225)
667
688
  def _reduce_49(val, _values)
668
689
  [val[0]]
669
690
 
670
691
  end
671
692
  .,.,
672
693
 
673
- module_eval(<<'.,.,', 'sdb-parser.y', 208)
694
+ module_eval(<<'.,.,', 'sdb-parser.y', 229)
674
695
  def _reduce_50(val, _values)
675
696
  val[0] + [val[2]]
676
697
 
677
698
  end
678
699
  .,.,
679
700
 
680
- module_eval(<<'.,.,', 'sdb-parser.y', 213)
701
+ module_eval(<<'.,.,', 'sdb-parser.y', 234)
681
702
  def _reduce_51(val, _values)
682
703
  [val[0]]
683
704
 
684
705
  end
685
706
  .,.,
686
707
 
687
- module_eval(<<'.,.,', 'sdb-parser.y', 217)
708
+ module_eval(<<'.,.,', 'sdb-parser.y', 238)
688
709
  def _reduce_52(val, _values)
689
710
  [val[0], val[2]].flatten
690
711
 
@@ -166,7 +166,28 @@ rule
166
166
 
167
167
  select_stmt : SELECT
168
168
  {
169
- struct(:SELECT, :query => val[0])
169
+ query = ''
170
+ ruby = nil
171
+
172
+ ss = StringScanner.new(val[0])
173
+
174
+ until ss.eos?
175
+ if (tok = ss.scan %r{[^-`'";\\/#|]+}) #'
176
+ query << tok
177
+ elsif (tok = ss.scan /`(?:[^`]|``)*`/)
178
+ query << tok
179
+ elsif (tok = ss.scan /'(?:[^']|'')*'/) #'
180
+ query << tok
181
+ elsif (tok = ss.scan /"(?:[^"]|"")*"/) #"
182
+ query << tok
183
+ elsif (tok = ss.scan /\|/)
184
+ ruby = ss.scan_until(/\Z/)
185
+ elsif (tok = ss.scan /./)
186
+ query << tok
187
+ end
188
+ end
189
+
190
+ struct(:SELECT, :query => query, :ruby => ruby)
170
191
  }
171
192
 
172
193
  create_stmt : CREATE DOMAIN IDENTIFIER
@@ -1,6 +1,29 @@
1
1
  require 'sdbcli/sdb-driver'
2
2
  require 'sdbcli/sdb-parser.tab'
3
3
 
4
+ # XXX:
5
+ class Array
6
+ def to_s
7
+ self.map {|i| i.to_s }
8
+ end
9
+
10
+ def to_i
11
+ self.map {|i| i.to_i }
12
+ end
13
+
14
+ def to_f
15
+ self.map {|i| i.to_f }
16
+ end
17
+
18
+ def sum
19
+ self.inject {|r, i| r + i }
20
+ end
21
+
22
+ def avg
23
+ self.sum / self.length
24
+ end
25
+ end
26
+
4
27
  module SimpleDB
5
28
  class Error < StandardError; end
6
29
 
@@ -16,6 +39,16 @@ module SimpleDB
16
39
  }
17
40
 
18
41
  class Runner
42
+ class Rownum
43
+ def initialize(rownum)
44
+ @rownum = rownum
45
+ end
46
+
47
+ def to_i
48
+ @rownum
49
+ end
50
+ end
51
+
19
52
  attr_reader :driver
20
53
 
21
54
  def initialize(accessKeyId, secretAccessKey, endpoint = 'sdb.amazonaws.com')
@@ -60,43 +93,69 @@ module SimpleDB
60
93
  when :INSERT
61
94
  rownum = parsed.items.length
62
95
  @driver.insert(parsed.domain, parsed.items)
63
- rownum
96
+ Rownum.new(rownum)
64
97
  when :UPDATE
65
98
  rownum = parsed.items.length
66
99
  @driver.update(parsed.domain, parsed.items)
67
- rownum
100
+ Rownum.new(rownum)
68
101
  when :UPDATE_WITH_EXPR
69
102
  query = "SELECT itemName FROM #{parsed.domain} #{parsed.expr}"
70
103
  items = @driver.select(query, consistent).map {|i| [i[0], parsed.attrs] }
71
104
  rownum = items.length
72
105
  @driver.update(parsed.domain, items)
73
- rownum
106
+ Rownum.new(rownum)
74
107
  when :MERGE
75
108
  rownum = parsed.items.length
76
109
  @driver.insert(parsed.domain, parsed.items)
77
- rownum
110
+ Rownum.new(rownum)
78
111
  when :MERGE_WITH_EXPR
79
112
  query = "SELECT itemName FROM #{parsed.domain} #{parsed.expr}"
80
113
  items = @driver.select(query, consistent).map {|i| [i[0], parsed.attrs] }
81
114
  rownum = items.length
82
115
  @driver.insert(parsed.domain, items)
83
- rownum
116
+ Rownum.new(rownum)
84
117
  when :DELETE
85
118
  rownum = parsed.items.length
86
119
  @driver.delete(parsed.domain, parsed.items)
87
- rownum
120
+ Rownum.new(rownum)
88
121
  when :DELETE_WITH_EXPR
89
122
  query = "SELECT itemName FROM #{parsed.domain} #{parsed.expr}"
90
123
  items = @driver.select(query, consistent).map {|i| [i[0], parsed.attrs] }
91
124
  rownum = items.length
92
125
  @driver.delete(parsed.domain, items)
93
- rownum
126
+ Rownum.new(rownum)
94
127
  when :SELECT
95
128
  items = @driver.select(parsed.query, consistent)
96
129
 
97
- if inline
130
+ def items.method_missing(method_name)
131
+ case method_name.to_s
132
+ when /itemName/i
133
+ self.map {|i| i[0] }
134
+ else
135
+ self.map {|i| i[1][method_name.to_s] }
136
+ end
137
+ end
138
+
139
+ items.each do |item|
140
+ def item.method_missing(method_name)
141
+ case method_name.to_s
142
+ when /itemName/i
143
+ self[0]
144
+ else
145
+ self[1][method_name.to_s]
146
+ end
147
+ end
148
+ end
149
+
150
+ if parsed.ruby
151
+ items = items.instance_eval(parsed.ruby.strip)
152
+ end
153
+
154
+ if inline and items.kind_of?(Array)
98
155
  items.each do |item|
99
- def item.to_yaml_style; :inline; end
156
+ if item.kind_of?(Array)
157
+ def item.to_yaml_style; :inline; end
158
+ end
100
159
  end
101
160
  end
102
161
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sdbcli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: