sdbcli 0.4.0 → 0.4.1
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 +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
|
+
|