sdbcli 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +14 -1
- data/bin/sdbcli +24 -2
- data/bin/sdbcli.orig +188 -0
- data/lib/sdbcli/sdb-runner.rb.orig +109 -0
- metadata +62 -46
data/README
CHANGED
@@ -35,6 +35,8 @@ https://bitbucket.org/winebarrel/sdbcli
|
|
35
35
|
== Example
|
36
36
|
|
37
37
|
ap-northeast-1> .help
|
38
|
+
# Explanatory notes of a query
|
39
|
+
|
38
40
|
SHOW DOMAINS
|
39
41
|
displays a domain list
|
40
42
|
|
@@ -69,14 +71,24 @@ https://bitbucket.org/winebarrel/sdbcli
|
|
69
71
|
USE region_or_endpoint
|
70
72
|
changes an endpoint
|
71
73
|
|
74
|
+
|
75
|
+
# List of commands
|
76
|
+
|
77
|
+
.help displays this message
|
78
|
+
.quit | .exit exits sdbcli
|
79
|
+
.format (yaml|json)? displays a format or changes it
|
80
|
+
.version displays a version
|
81
|
+
|
72
82
|
ap-northeast-1> select * from test;
|
73
83
|
---
|
74
84
|
- [itemname1, {attr1: val1, attr2: val2}]
|
75
85
|
- [itemname2, {attr1: val1, attr2: val2}]
|
76
|
-
|
86
|
+
# 2 rows in set
|
87
|
+
|
77
88
|
ap-northeast-1> select count(*) from `test-2`;
|
78
89
|
---
|
79
90
|
- [Domain, {Count: "100"}]
|
91
|
+
# 1 row in set
|
80
92
|
|
81
93
|
Attribute and domain names may appear without quotes if they contain only letters, numbers, underscores (_),
|
82
94
|
or dollar symbols ($) and do not start with a number.
|
@@ -91,6 +103,7 @@ see http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/Quoti
|
|
91
103
|
- itemname2
|
92
104
|
- attr1: val1
|
93
105
|
attr2: val2
|
106
|
+
# 2 rows in set
|
94
107
|
|
95
108
|
shell> echo 'select * from test' | sdbcli
|
96
109
|
---
|
data/bin/sdbcli
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
$LOAD_PATH << File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
|
3
3
|
|
4
|
-
Version = '0.4.
|
4
|
+
Version = '0.4.1'
|
5
5
|
HISTORY_FILE = File.join((ENV['HOME'] || ENV['USERPROFILE'] || '.'), '.sdbcli_history')
|
6
6
|
HISTSIZE = 500
|
7
7
|
|
@@ -146,6 +146,8 @@ end
|
|
146
146
|
|
147
147
|
def help
|
148
148
|
<<-EOS
|
149
|
+
# Explanatory notes of a query
|
150
|
+
|
149
151
|
SHOW DOMAINS
|
150
152
|
displays a domain list
|
151
153
|
|
@@ -180,6 +182,14 @@ DESC domain_name
|
|
180
182
|
USE region_or_endpoint
|
181
183
|
changes an endpoint
|
182
184
|
|
185
|
+
|
186
|
+
# List of commands
|
187
|
+
|
188
|
+
.help displays this message
|
189
|
+
.quit | .exit exits sdbcli
|
190
|
+
.format (yaml|json)? displays a format or changes it
|
191
|
+
.version displays a version
|
192
|
+
|
183
193
|
EOS
|
184
194
|
end
|
185
195
|
|
@@ -215,12 +225,24 @@ while buf = Readline.readline(prompt, true)
|
|
215
225
|
end
|
216
226
|
|
217
227
|
if src.empty? and buf =~ /\A\.(.+)/
|
218
|
-
|
228
|
+
cmd, arg = $1.split(/\s+/i, 2)
|
229
|
+
r = /\A#{Regexp.compile(cmd.downcase)}/
|
219
230
|
|
220
231
|
if r =~ 'help'
|
221
232
|
puts help
|
222
233
|
elsif r =~ 'exit' or r =~ 'quit'
|
223
234
|
exit
|
235
|
+
elsif r =~ 'format'
|
236
|
+
case arg
|
237
|
+
when nil
|
238
|
+
puts $format
|
239
|
+
when 'yaml'
|
240
|
+
$format = :yaml
|
241
|
+
when 'json'
|
242
|
+
$format = :json
|
243
|
+
else
|
244
|
+
output_error('Unknown format')
|
245
|
+
end
|
224
246
|
elsif r =~ 'version'
|
225
247
|
puts "sdbcli #{Version}"
|
226
248
|
else
|
data/bin/sdbcli.orig
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH << File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
|
3
|
+
|
4
|
+
Version = '0.3.8'
|
5
|
+
HISTORY_FILE = File.join((ENV['HOME'] || ENV['USERPROFILE'] || '.'), '.sdbcli_history')
|
6
|
+
HISTSIZE = 500
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'sdbcli'
|
10
|
+
|
11
|
+
require 'optparse'
|
12
|
+
require 'readline'
|
13
|
+
require 'strscan'
|
14
|
+
require 'syck' if /\A1\.9/ =~ RUBY_VERSION
|
15
|
+
require 'yaml'
|
16
|
+
|
17
|
+
access_key_id = ENV['AWS_ACCESS_KEY_ID']
|
18
|
+
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
|
19
|
+
sdb_endpoint = ENV['SDB_ENDPOINT'] || ENV['REGION_NAME'] || 'sdb.amazonaws.com'
|
20
|
+
command = nil
|
21
|
+
|
22
|
+
ARGV.options do |opt|
|
23
|
+
opt.on('-k', '--access-key=ACCESS_KEY') {|v| access_key_id = v }
|
24
|
+
opt.on('-s', '--secret-key=SECRET_KEY') {|v| secret_access_key = v }
|
25
|
+
opt.on('-r', '--region=REGION') {|v| sdb_endpoint = v }
|
26
|
+
opt.on('-e', '--eval=COMMAND') {|v| command = v }
|
27
|
+
opt.parse!
|
28
|
+
|
29
|
+
unless access_key_id and secret_access_key and sdb_endpoint
|
30
|
+
puts opt.help
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
$runner = SimpleDB::Runner.new(access_key_id, secret_access_key, sdb_endpoint)
|
36
|
+
|
37
|
+
def output_error(msg)
|
38
|
+
$stderr.puts "# #{msg}\n\n"
|
39
|
+
end
|
40
|
+
|
41
|
+
def execute(src, show_rows = false)
|
42
|
+
ss = StringScanner.new(src.gsub(%r{/\*/?(?:(?:\r\n|\r|\n)|[^/]|[^*]/)*\*/}m, ''))
|
43
|
+
|
44
|
+
while query = ss.scan_until(/(?:;|\\G)/i)
|
45
|
+
src.replace(ss.rest.strip)
|
46
|
+
query.strip!
|
47
|
+
|
48
|
+
if query =~ /\s*\\G\Z/i
|
49
|
+
query = query.sub(/\s*\\G\Z/i, '')
|
50
|
+
inline = false
|
51
|
+
else
|
52
|
+
query = query.strip.sub(/\s*;\Z/, '')
|
53
|
+
inline = true
|
54
|
+
end
|
55
|
+
|
56
|
+
if query.empty?
|
57
|
+
output_error('No query specified')
|
58
|
+
next
|
59
|
+
end
|
60
|
+
|
61
|
+
out = $runner.execute(query, inline)
|
62
|
+
|
63
|
+
if out
|
64
|
+
str = YAML.dump(out).sub(/(?:\r\n|\r|\n)*\Z/, "\n")
|
65
|
+
|
66
|
+
if show_rows and out.kind_of?(Array)
|
67
|
+
str << "# #{out.length} rows in set\n"
|
68
|
+
end
|
69
|
+
|
70
|
+
str << "\n"
|
71
|
+
puts str
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
ss.rest.strip
|
76
|
+
end
|
77
|
+
|
78
|
+
if not $stdin.tty? or command
|
79
|
+
src = command || $stdin.read.strip
|
80
|
+
|
81
|
+
unless src =~ /\s*(?:;|\\G)\Z/i
|
82
|
+
src << ';'
|
83
|
+
end
|
84
|
+
|
85
|
+
begin
|
86
|
+
execute(src)
|
87
|
+
exit 0
|
88
|
+
rescue => e
|
89
|
+
output_error e.message.strip
|
90
|
+
exit 1
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def help
|
95
|
+
<<-EOS
|
96
|
+
SHOW DOMAINS
|
97
|
+
displays a domain list
|
98
|
+
|
99
|
+
SHOW REGIONS
|
100
|
+
displays a region list
|
101
|
+
|
102
|
+
CREATE domain domain_name
|
103
|
+
creates a domain
|
104
|
+
|
105
|
+
DROP DOMAIN domain_name
|
106
|
+
deletes a domain
|
107
|
+
|
108
|
+
GET [attr_list] FROM domain_name WHERE itemName = '...'
|
109
|
+
gets the attribute of an item
|
110
|
+
|
111
|
+
INSERT INTO domain_name (itemName, attr1, ...) VALUES ('name', 'val1', ...)
|
112
|
+
creates an item
|
113
|
+
|
114
|
+
UPDATE domain_name set attr1 = 'val1', ... WHERE itemName = '...'
|
115
|
+
updates an item
|
116
|
+
|
117
|
+
DELETE [attr1, ...] FROM domain_name WHERE itemName = '...'
|
118
|
+
deletes the attribute of an item or an item
|
119
|
+
|
120
|
+
SELECT output_list FROM domain_name [WHERE expression] [sort_instructions] [LIMIT limit]
|
121
|
+
queries using the SELECT statement
|
122
|
+
see http://docs.aws.amazon.com/AmazonSimpleDB/latest/DeveloperGuide/UsingSelect.html
|
123
|
+
|
124
|
+
DESC domain_name
|
125
|
+
displays information about the domain
|
126
|
+
|
127
|
+
USE region_or_endpoint
|
128
|
+
changes an endpoint
|
129
|
+
|
130
|
+
EOS
|
131
|
+
end
|
132
|
+
|
133
|
+
if File.exist?(HISTORY_FILE)
|
134
|
+
open(HISTORY_FILE) do |f|
|
135
|
+
f.each_line do |line|
|
136
|
+
line = line.strip
|
137
|
+
Readline::HISTORY.push(line) unless line.empty?
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
at_exit do
|
143
|
+
unless Readline::HISTORY.empty?
|
144
|
+
open(HISTORY_FILE, 'wb') do |f|
|
145
|
+
(Readline::HISTORY.to_a.slice(-(Readline::HISTORY.length < HISTSIZE ? Readline::HISTORY.length : HISTSIZE)..-1) || []).each do |line|
|
146
|
+
next if /\A\s*\Z/ =~ line
|
147
|
+
f.puts line
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
src = ''
|
154
|
+
prompt1 = lambda { "#{$runner.region || 'unknown'}> " }
|
155
|
+
prompt2 = lambda { "#{' ' * (($runner.region || 'unknown').length - 1)}-> " }
|
156
|
+
prompt = prompt1.call
|
157
|
+
|
158
|
+
while buf = Readline.readline(prompt, true)
|
159
|
+
if /\A\s*\Z/ =~ buf
|
160
|
+
Readline::HISTORY.pop
|
161
|
+
next
|
162
|
+
end
|
163
|
+
|
164
|
+
if src.empty? and buf =~ /\A\.(.+)/
|
165
|
+
r = /\A#{Regexp.compile($1.downcase)}/
|
166
|
+
|
167
|
+
if r =~ 'help'
|
168
|
+
puts help
|
169
|
+
elsif r =~ 'exit' or r =~ 'quit'
|
170
|
+
exit
|
171
|
+
elsif r =~ 'version'
|
172
|
+
puts "sdbcli #{Version}"
|
173
|
+
else
|
174
|
+
output_error('Unknown command')
|
175
|
+
end
|
176
|
+
else
|
177
|
+
rv = nil
|
178
|
+
|
179
|
+
begin
|
180
|
+
src << (' ' + buf)
|
181
|
+
execute(src, true)
|
182
|
+
rescue => e
|
183
|
+
output_error e.message.strip
|
184
|
+
end
|
185
|
+
|
186
|
+
prompt = src.empty? ? prompt1.call : prompt2.call
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'sdbcli/sdb-driver'
|
2
|
+
require 'sdbcli/sdb-parser.tab'
|
3
|
+
|
4
|
+
module SimpleDB
|
5
|
+
class Error < StandardError; end
|
6
|
+
|
7
|
+
REGIONS = {
|
8
|
+
'sdb.amazonaws.com' => 'us-east-1',
|
9
|
+
'sdb.us-west-1.amazonaws.com' => 'us-west-1',
|
10
|
+
'sdb.us-west-2.amazonaws.com' => 'us-west-2',
|
11
|
+
'sdb.eu-west-1.amazonaws.com' => 'eu-west-1',
|
12
|
+
'sdb.ap-southeast-1.amazonaws.com' => 'ap-southeast-1',
|
13
|
+
'sdb.ap-southeast-2.amazonaws.com' => 'ap-southeast-2',
|
14
|
+
'sdb.ap-northeast-1.amazonaws.com' => 'ap-northeast-1',
|
15
|
+
'sdb.sa-east-1.amazonaws.com' => 'sa-east-1',
|
16
|
+
}
|
17
|
+
|
18
|
+
class Runner
|
19
|
+
def initialize(accessKeyId, secretAccessKey, endpoint = 'sdb.amazonaws.com')
|
20
|
+
endpoint = region_to_endpoint(endpoint)
|
21
|
+
@driver = Driver.new(accessKeyId, secretAccessKey, endpoint)
|
22
|
+
end
|
23
|
+
|
24
|
+
def endpoint
|
25
|
+
@driver.endpoint
|
26
|
+
end
|
27
|
+
|
28
|
+
def endpoint=(v)
|
29
|
+
v = region_to_endpoint(v)
|
30
|
+
@driver.endpoint = v
|
31
|
+
end
|
32
|
+
|
33
|
+
def region
|
34
|
+
REGIONS[endpoint]
|
35
|
+
end
|
36
|
+
|
37
|
+
def execute(query, inline = true)
|
38
|
+
parsed = Parser.parse(query)
|
39
|
+
p parsed
|
40
|
+
command = parsed.class.name.split('::').last.to_sym
|
41
|
+
|
42
|
+
case command
|
43
|
+
when :GET
|
44
|
+
item = @driver.get(parsed.domain, parsed.item_name, parsed.attr_names)
|
45
|
+
|
46
|
+
if inline
|
47
|
+
def item.to_yaml_style; :inline; end
|
48
|
+
end
|
49
|
+
|
50
|
+
item
|
51
|
+
when :INSERT
|
52
|
+
@driver.insert(parsed.domain, parsed.item_name, parsed.attrs)
|
53
|
+
nil
|
54
|
+
when :UPDATE
|
55
|
+
@driver.update(parsed.domain, parsed.items)
|
56
|
+
nil
|
57
|
+
when :DELETE
|
58
|
+
@driver.delete(parsed.domain, parsed.items)
|
59
|
+
nil
|
60
|
+
when :SELECT
|
61
|
+
items = @driver.select(parsed.query)
|
62
|
+
|
63
|
+
if inline
|
64
|
+
items.each do |item|
|
65
|
+
def item.to_yaml_style; :inline; end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
items
|
70
|
+
when :CREATE
|
71
|
+
@driver.create_domain(parsed.domain)
|
72
|
+
nil
|
73
|
+
when :DROP
|
74
|
+
@driver.drop_domain(parsed.domain)
|
75
|
+
nil
|
76
|
+
when :SHOW
|
77
|
+
case parsed.operand
|
78
|
+
when :domains
|
79
|
+
@driver.show_domains
|
80
|
+
when :regions
|
81
|
+
SimpleDB::REGIONS.values.sort
|
82
|
+
else
|
83
|
+
raise 'must not happen'
|
84
|
+
end
|
85
|
+
when :USE
|
86
|
+
self.endpoint = parsed.endpoint
|
87
|
+
nil
|
88
|
+
when :DESCRIBE
|
89
|
+
@driver.describe(parsed.domain)
|
90
|
+
else
|
91
|
+
raise 'must not happen'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def region_to_endpoint(region)
|
98
|
+
if /\A[^.]+\Z/ =~ region
|
99
|
+
region = SimpleDB::REGIONS.find {|k, v| v == region }
|
100
|
+
raise SimpleDB::Error, 'Unknown region' unless region
|
101
|
+
region = region.first
|
102
|
+
end
|
103
|
+
|
104
|
+
raise SimpleDB::Error, 'Unknown endpoint' unless SimpleDB::REGIONS[region]
|
105
|
+
|
106
|
+
return region
|
107
|
+
end
|
108
|
+
end # Runner
|
109
|
+
end # SimpleDB
|
metadata
CHANGED
@@ -1,85 +1,101 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: sdbcli
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 13
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 4
|
9
|
+
- 1
|
10
|
+
version: 0.4.1
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- winebarrel
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2013-01-22 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
15
21
|
name: nokogiri
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :runtime
|
23
22
|
prerelease: false
|
24
|
-
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: json
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
33
24
|
none: false
|
34
|
-
requirements:
|
35
|
-
- -
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
38
32
|
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: json
|
39
36
|
prerelease: false
|
40
|
-
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
38
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
46
48
|
description:
|
47
49
|
email: sgwr_dts@yahoo.co.jp
|
48
|
-
executables:
|
50
|
+
executables:
|
49
51
|
- sdbcli
|
50
52
|
extensions: []
|
53
|
+
|
51
54
|
extra_rdoc_files: []
|
52
|
-
|
55
|
+
|
56
|
+
files:
|
53
57
|
- README
|
54
58
|
- bin/sdbcli
|
59
|
+
- bin/sdbcli.orig
|
55
60
|
- lib/sdbcli/sdb-client.rb
|
56
61
|
- lib/sdbcli/sdb-driver.rb
|
57
62
|
- lib/sdbcli/sdb-parser.tab.rb
|
58
63
|
- lib/sdbcli/sdb-parser.y
|
59
64
|
- lib/sdbcli/sdb-runner.rb
|
65
|
+
- lib/sdbcli/sdb-runner.rb.orig
|
60
66
|
- lib/sdbcli.rb
|
61
67
|
homepage: https://bitbucket.org/winebarrel/sdbcli
|
62
68
|
licenses: []
|
69
|
+
|
63
70
|
post_install_message:
|
64
71
|
rdoc_options: []
|
65
|
-
|
72
|
+
|
73
|
+
require_paths:
|
66
74
|
- lib
|
67
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
76
|
none: false
|
69
|
-
requirements:
|
70
|
-
- -
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
|
73
|
-
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
hash: 3
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
85
|
none: false
|
75
|
-
requirements:
|
76
|
-
- -
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 3
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
version: "0"
|
79
93
|
requirements: []
|
94
|
+
|
80
95
|
rubyforge_project:
|
81
|
-
rubygems_version: 1.8.
|
96
|
+
rubygems_version: 1.8.24
|
82
97
|
signing_key:
|
83
98
|
specification_version: 3
|
84
99
|
summary: sdbcli is an interactive command-line client of Amazon SimpleDB.
|
85
100
|
test_files: []
|
101
|
+
|