sdbcli 0.2.8 → 0.2.9
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 +84 -75
- data/bin/sdbcli +6 -4
- data/lib/sdbcli/sdb-client.rb +132 -128
- data/lib/sdbcli/sdb-driver.rb +184 -173
- data/lib/sdbcli/sdb-parser.tab.rb +149 -118
- data/lib/sdbcli/sdb-parser.y +253 -242
- data/lib/sdbcli/sdb-runner.rb +81 -79
- data/lib/sdbcli.rb +3 -3
- metadata +49 -33
data/README
CHANGED
@@ -1,75 +1,84 @@
|
|
1
|
-
= sdbcli
|
2
|
-
|
3
|
-
== Description
|
4
|
-
|
5
|
-
sdbcli is an interactive command-line client of Amazon SimpleDB.
|
6
|
-
|
7
|
-
== Source Code
|
8
|
-
|
9
|
-
https://bitbucket.org/winebarrel/sdbcli
|
10
|
-
|
11
|
-
== Install
|
12
|
-
|
13
|
-
shell> gem install sdbcli
|
14
|
-
shell>
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
ap-northeast-1> select * from test
|
62
|
-
---
|
63
|
-
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
1
|
+
= sdbcli
|
2
|
+
|
3
|
+
== Description
|
4
|
+
|
5
|
+
sdbcli is an interactive command-line client of Amazon SimpleDB.
|
6
|
+
|
7
|
+
== Source Code
|
8
|
+
|
9
|
+
https://bitbucket.org/winebarrel/sdbcli
|
10
|
+
|
11
|
+
== Install
|
12
|
+
|
13
|
+
shell> gem install sdbcli
|
14
|
+
shell> sdbcli -h
|
15
|
+
Usage: sdbcli [options]
|
16
|
+
-k, --access-key=ACCESS_KEY
|
17
|
+
-s, --secret-key=SECRET_KEY
|
18
|
+
-r, --region=REGION
|
19
|
+
-e, --eval=COMMAND
|
20
|
+
shell> export AWS_ACCESS_KEY_ID='...'
|
21
|
+
shell> export AWS_SECRET_ACCESS_KEY='...'
|
22
|
+
shell> export SDB_ENDPOINT='sdb.ap-northeast-1.amazonaws.com' # or REGION_NAME=ap-northeast-1
|
23
|
+
shell> sdbcli -e 'show domains'
|
24
|
+
---
|
25
|
+
- test
|
26
|
+
- test-2
|
27
|
+
shell> sdbcli # show prompt
|
28
|
+
|
29
|
+
== Example
|
30
|
+
|
31
|
+
ap-northeast-1> help
|
32
|
+
SHOW domains
|
33
|
+
displays a domain list
|
34
|
+
|
35
|
+
CREATE domain domain_name
|
36
|
+
creates a domain
|
37
|
+
|
38
|
+
DROP DOMAIN domain_name
|
39
|
+
deletes a domain
|
40
|
+
|
41
|
+
GET [attr_list] FROM domain_name WHERE itemName = '...'
|
42
|
+
gets the attribute of an item
|
43
|
+
|
44
|
+
INSERT INTO domain_name (itemName, attr1, ...) values ('name', 'val1', ...)
|
45
|
+
creates an item
|
46
|
+
|
47
|
+
UPDATE domain_name set attr1 = 'val1', ... where itemName = '...'
|
48
|
+
updates an item
|
49
|
+
|
50
|
+
DELETE [attr1, ...] FROM domain_name itemName = '...'
|
51
|
+
deletes the attribute of an item or an item
|
52
|
+
|
53
|
+
SELECT output_list FROM domain_name [where expression] [sort_instructions] [limit limit]
|
54
|
+
queries using the SELECT statement
|
55
|
+
|
56
|
+
ap-northeast-1> select * from test;
|
57
|
+
---
|
58
|
+
- [itemname1, {attr1: val1, attr2: val2}]
|
59
|
+
- [itemname2, {attr1: val1, attr2: val2}]
|
60
|
+
|
61
|
+
ap-northeast-1> select count(*) from `test-2`;
|
62
|
+
---
|
63
|
+
- [Domain, {Count: "100"}]
|
64
|
+
|
65
|
+
Attribute and domain names may appear without quotes if they contain only letters, numbers, underscores (_),
|
66
|
+
or dollar symbols ($) and do not start with a number.
|
67
|
+
You must quote all other attribute and domain names with the backtick (`).
|
68
|
+
see http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/QuotingRulesSelect.html
|
69
|
+
|
70
|
+
ap-northeast-1> select * from test \G
|
71
|
+
---
|
72
|
+
- - itemname1
|
73
|
+
- attr1: val1
|
74
|
+
attr2: val2
|
75
|
+
- itemname2
|
76
|
+
- attr1: val1
|
77
|
+
attr2: val2
|
78
|
+
|
79
|
+
|
80
|
+
shell> echo 'select * from test' | sdbcli
|
81
|
+
---
|
82
|
+
- [itemname1, {attr1: val1, attr2: val2}]
|
83
|
+
- [itemname2, {attr1: val1, attr2: val2}]
|
84
|
+
|
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.2.
|
4
|
+
Version = '0.2.9'
|
5
5
|
HISTORY_FILE = File.join((ENV['HOME'] || ENV['USERPROFILE'] || '.'), '.sdbcli_history')
|
6
6
|
|
7
7
|
require 'rubygems'
|
@@ -16,11 +16,13 @@ require 'yaml'
|
|
16
16
|
access_key_id = ENV['AWS_ACCESS_KEY_ID']
|
17
17
|
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
|
18
18
|
sdb_endpoint = ENV['SDB_ENDPOINT'] || ENV['REGION_NAME'] || 'sdb.amazonaws.com'
|
19
|
+
command = nil
|
19
20
|
|
20
21
|
ARGV.options do |opt|
|
21
22
|
opt.on('-k', '--access-key=ACCESS_KEY') {|v| access_key_id = v }
|
22
23
|
opt.on('-s', '--secret-key=SECRET_KEY') {|v| secret_access_key = v }
|
23
|
-
opt.on('-
|
24
|
+
opt.on('-r', '--region=REGION') {|v| sdb_endpoint = v }
|
25
|
+
opt.on('-e', '--eval=COMMAND') {|v| command = v }
|
24
26
|
opt.parse!
|
25
27
|
|
26
28
|
unless access_key_id and secret_access_key and sdb_endpoint
|
@@ -75,8 +77,8 @@ def execute(src)
|
|
75
77
|
ss.rest.strip
|
76
78
|
end
|
77
79
|
|
78
|
-
|
79
|
-
src = $stdin.read.strip
|
80
|
+
if not $stdin.tty? or command
|
81
|
+
src = command || $stdin.read.strip
|
80
82
|
|
81
83
|
unless src =~ /\s*(?:;|\\G)\Z/i
|
82
84
|
src << ';'
|
data/lib/sdbcli/sdb-client.rb
CHANGED
@@ -1,128 +1,132 @@
|
|
1
|
-
require 'cgi'
|
2
|
-
require 'base64'
|
3
|
-
require 'net/https'
|
4
|
-
require 'openssl'
|
5
|
-
require 'nokogiri'
|
6
|
-
|
7
|
-
module SimpleDB
|
8
|
-
class Error < StandardError; end
|
9
|
-
|
10
|
-
class Client
|
11
|
-
API_VERSION = '2009-04-15'
|
12
|
-
SIGNATURE_VERSION = 2
|
13
|
-
SIGNATURE_ALGORITHM = :SHA256
|
14
|
-
|
15
|
-
attr_accessor :endpoint
|
16
|
-
|
17
|
-
def initialize(accessKeyId, secretAccessKey, endpoint = 'sdb.amazonaws.com')
|
18
|
-
@accessKeyId = accessKeyId
|
19
|
-
@secretAccessKey = secretAccessKey
|
20
|
-
@endpoint = endpoint
|
21
|
-
end
|
22
|
-
|
23
|
-
# domain action
|
24
|
-
|
25
|
-
def create_domain(domain_name, params = {})
|
26
|
-
params = params.merge(:DomainName => domain_name)
|
27
|
-
query('CreateDomain', params)
|
28
|
-
end
|
29
|
-
|
30
|
-
def list_domains(params = {})
|
31
|
-
query('ListDomains', params)
|
32
|
-
end
|
33
|
-
|
34
|
-
def delete_domain(domain_name, params = {})
|
35
|
-
params = params.merge(:DomainName => domain_name)
|
36
|
-
query('DeleteDomain', params)
|
37
|
-
end
|
38
|
-
|
39
|
-
# attr action
|
40
|
-
|
41
|
-
def put_attributes(domain_name, item_name, params = {})
|
42
|
-
params = params.merge(:DomainName => domain_name, :ItemName => item_name)
|
43
|
-
query('PutAttributes', params)
|
44
|
-
end
|
45
|
-
|
46
|
-
def get_attributes(domain_name, item_name, params = {})
|
47
|
-
params = params.merge(:DomainName => domain_name, :ItemName => item_name)
|
48
|
-
query('GetAttributes', params)
|
49
|
-
end
|
50
|
-
|
51
|
-
def select(params = {})
|
52
|
-
query('Select', params)
|
53
|
-
end
|
54
|
-
|
55
|
-
def delete_attributes(domain_name, item_name, params = {})
|
56
|
-
params = params.merge(:DomainName => domain_name, :ItemName => item_name)
|
57
|
-
query('DeleteAttributes', params)
|
58
|
-
end
|
59
|
-
|
60
|
-
# batch attr action
|
61
|
-
|
62
|
-
def batch_put_attributes(domain_name, params = {})
|
63
|
-
params = params.merge(:DomainName => domain_name)
|
64
|
-
query('BatchPutAttributes', params)
|
65
|
-
end
|
66
|
-
|
67
|
-
def batch_delete_attributes(domain_name, params = {})
|
68
|
-
params = params.merge(:DomainName => domain_name)
|
69
|
-
query('BatchDeleteAttributes', params)
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
:
|
81
|
-
:
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
|
1
|
+
require 'cgi'
|
2
|
+
require 'base64'
|
3
|
+
require 'net/https'
|
4
|
+
require 'openssl'
|
5
|
+
require 'nokogiri'
|
6
|
+
|
7
|
+
module SimpleDB
|
8
|
+
class Error < StandardError; end
|
9
|
+
|
10
|
+
class Client
|
11
|
+
API_VERSION = '2009-04-15'
|
12
|
+
SIGNATURE_VERSION = 2
|
13
|
+
SIGNATURE_ALGORITHM = :SHA256
|
14
|
+
|
15
|
+
attr_accessor :endpoint
|
16
|
+
|
17
|
+
def initialize(accessKeyId, secretAccessKey, endpoint = 'sdb.amazonaws.com')
|
18
|
+
@accessKeyId = accessKeyId
|
19
|
+
@secretAccessKey = secretAccessKey
|
20
|
+
@endpoint = endpoint
|
21
|
+
end
|
22
|
+
|
23
|
+
# domain action
|
24
|
+
|
25
|
+
def create_domain(domain_name, params = {})
|
26
|
+
params = params.merge(:DomainName => domain_name)
|
27
|
+
query('CreateDomain', params)
|
28
|
+
end
|
29
|
+
|
30
|
+
def list_domains(params = {})
|
31
|
+
query('ListDomains', params)
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete_domain(domain_name, params = {})
|
35
|
+
params = params.merge(:DomainName => domain_name)
|
36
|
+
query('DeleteDomain', params)
|
37
|
+
end
|
38
|
+
|
39
|
+
# attr action
|
40
|
+
|
41
|
+
def put_attributes(domain_name, item_name, params = {})
|
42
|
+
params = params.merge(:DomainName => domain_name, :ItemName => item_name)
|
43
|
+
query('PutAttributes', params)
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_attributes(domain_name, item_name, params = {})
|
47
|
+
params = params.merge(:DomainName => domain_name, :ItemName => item_name)
|
48
|
+
query('GetAttributes', params)
|
49
|
+
end
|
50
|
+
|
51
|
+
def select(params = {})
|
52
|
+
query('Select', params)
|
53
|
+
end
|
54
|
+
|
55
|
+
def delete_attributes(domain_name, item_name, params = {})
|
56
|
+
params = params.merge(:DomainName => domain_name, :ItemName => item_name)
|
57
|
+
query('DeleteAttributes', params)
|
58
|
+
end
|
59
|
+
|
60
|
+
# batch attr action
|
61
|
+
|
62
|
+
def batch_put_attributes(domain_name, params = {})
|
63
|
+
params = params.merge(:DomainName => domain_name)
|
64
|
+
query('BatchPutAttributes', params)
|
65
|
+
end
|
66
|
+
|
67
|
+
def batch_delete_attributes(domain_name, params = {})
|
68
|
+
params = params.merge(:DomainName => domain_name)
|
69
|
+
query('BatchDeleteAttributes', params)
|
70
|
+
end
|
71
|
+
|
72
|
+
def domain_metadata(domain_name)
|
73
|
+
query('DomainMetadata', :DomainName => domain_name)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def query(action, params = {})
|
79
|
+
params = {
|
80
|
+
:Action => action,
|
81
|
+
:Version => API_VERSION,
|
82
|
+
:Timestamp => Time.now.getutc.strftime('%Y-%m-%dT%H:%M:%SZ'),
|
83
|
+
:SignatureVersion => SIGNATURE_VERSION,
|
84
|
+
:SignatureMethod => "Hmac#{SIGNATURE_ALGORITHM}",
|
85
|
+
:AWSAccessKeyId => @accessKeyId,
|
86
|
+
}.merge(params)
|
87
|
+
|
88
|
+
signature = aws_sign(params)
|
89
|
+
params[:Signature] = signature
|
90
|
+
|
91
|
+
Net::HTTP.version_1_2
|
92
|
+
https = Net::HTTP.new(@endpoint, 443)
|
93
|
+
https.use_ssl = true
|
94
|
+
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
95
|
+
|
96
|
+
doc = https.start do |w|
|
97
|
+
req = Net::HTTP::Post.new('/',
|
98
|
+
'Host' => @endpoint,
|
99
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
100
|
+
)
|
101
|
+
|
102
|
+
req.set_form_data(params)
|
103
|
+
res = w.request(req)
|
104
|
+
|
105
|
+
Nokogiri::XML(res.body)
|
106
|
+
end
|
107
|
+
|
108
|
+
validate(doc)
|
109
|
+
return doc
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
def aws_sign(params)
|
114
|
+
params = params.sort_by {|a, b| a.to_s }.map {|k, v| "#{escape(k)}=#{escape(v)}" }.join('&')
|
115
|
+
string_to_sign = "POST\n#{@endpoint}\n/\n#{params}"
|
116
|
+
digest = OpenSSL::HMAC.digest(OpenSSL::Digest.const_get(SIGNATURE_ALGORITHM).new, @secretAccessKey, string_to_sign)
|
117
|
+
Base64.encode64(digest).gsub("\n", '')
|
118
|
+
end
|
119
|
+
|
120
|
+
def validate(doc)
|
121
|
+
if (error = doc.at_css('Errors Error'))
|
122
|
+
code = error.at_css('Code').content
|
123
|
+
message = error.at_css('Message').content
|
124
|
+
raise Error, "#{code}: #{message}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def escape(str)
|
129
|
+
CGI.escape(str.to_s).gsub('+', '%20')
|
130
|
+
end
|
131
|
+
end # Client
|
132
|
+
end # SimpleDB
|