sdbcli 1.1.4 → 1.2.0

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.
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: