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 +24 -1
- data/bin/sdbcli +9 -6
- data/lib/sdbcli/sdb-parser.tab.rb +34 -13
- data/lib/sdbcli/sdb-parser.y +22 -1
- data/lib/sdbcli/sdb-runner.rb +68 -9
- metadata +1 -1
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.
|
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?(
|
112
|
+
if out.kind_of?(SimpleDB::Runner::Rownum)
|
113
|
+
rownum = out.to_i
|
112
114
|
puts case $format
|
113
115
|
when :yaml
|
114
|
-
"# #{
|
116
|
+
"# #{rownum} #{rownum > 1 ? 'rows' : 'row'} changed"
|
115
117
|
when :json
|
116
|
-
"// #{
|
118
|
+
"// #{rownum} #{rownum > 1 ? 'rows' : 'row'} changed"
|
117
119
|
else
|
118
|
-
"# #{
|
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',
|
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
|
-
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
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',
|
708
|
+
module_eval(<<'.,.,', 'sdb-parser.y', 238)
|
688
709
|
def _reduce_52(val, _values)
|
689
710
|
[val[0], val[2]].flatten
|
690
711
|
|
data/lib/sdbcli/sdb-parser.y
CHANGED
@@ -166,7 +166,28 @@ rule
|
|
166
166
|
|
167
167
|
select_stmt : SELECT
|
168
168
|
{
|
169
|
-
|
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
|
data/lib/sdbcli/sdb-runner.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
156
|
+
if item.kind_of?(Array)
|
157
|
+
def item.to_yaml_style; :inline; end
|
158
|
+
end
|
100
159
|
end
|
101
160
|
end
|
102
161
|
|