ddbcli 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +148 -0
- data/bin/ddbcli +66 -0
- data/lib/ddbcli.rb +13 -0
- data/lib/ddbcli/cli/evaluate.rb +51 -0
- data/lib/ddbcli/cli/functions.rb +160 -0
- data/lib/ddbcli/cli/help.rb +116 -0
- data/lib/ddbcli/cli/options.rb +45 -0
- data/lib/ddbcli/ddb-binary.rb +15 -0
- data/lib/ddbcli/ddb-client.rb +239 -0
- data/lib/ddbcli/ddb-driver.rb +646 -0
- data/lib/ddbcli/ddb-endpoint.rb +31 -0
- data/lib/ddbcli/ddb-error.rb +10 -0
- data/lib/ddbcli/ddb-iteratorable.rb +11 -0
- data/lib/ddbcli/ddb-parser.tab.rb +1383 -0
- data/lib/ddbcli/ddb-parser.y +598 -0
- data/lib/ddbcli/ddb-rubyext.rb +43 -0
- metadata +77 -0
data/README
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
= sdbcli
|
2
|
+
|
3
|
+
== Description
|
4
|
+
|
5
|
+
ddbcli is an interactive command-line client of Amazon DynamoDB.
|
6
|
+
|
7
|
+
== Source Code
|
8
|
+
|
9
|
+
https://bitbucket.org/winebarrel/ddbcli
|
10
|
+
|
11
|
+
== Install
|
12
|
+
|
13
|
+
shell> gem install ddbcli
|
14
|
+
shell> export AWS_ACCESS_KEY_ID='...'
|
15
|
+
shell> export AWS_SECRET_ACCESS_KEY='...'
|
16
|
+
shell> export DDB_REGION=ap-northeast-1
|
17
|
+
shell> ddbcli -e 'show tables'
|
18
|
+
[
|
19
|
+
"employees"
|
20
|
+
]
|
21
|
+
|
22
|
+
shell> ddbcli -h
|
23
|
+
Usage: ddbcli [options]
|
24
|
+
-k, --access-key=ACCESS_KEY
|
25
|
+
-s, --secret-key=SECRET_KEY
|
26
|
+
-r, --region=REGION_OR_ENDPOINT
|
27
|
+
-e, --eval=COMMAND
|
28
|
+
-t, --timeout=SECOND
|
29
|
+
--consistent-read
|
30
|
+
--retry=NUM
|
31
|
+
--retry-interval=SECOND
|
32
|
+
--debug
|
33
|
+
-h, --help
|
34
|
+
|
35
|
+
##### Query #####
|
36
|
+
|
37
|
+
SHOW TABLES
|
38
|
+
displays a table list
|
39
|
+
|
40
|
+
SHOW REGIONS
|
41
|
+
displays a region list
|
42
|
+
|
43
|
+
SHOW CREATE TABLE table_name
|
44
|
+
displays a CREATE TABLE statement
|
45
|
+
|
46
|
+
CREATE TABLES table_name (
|
47
|
+
key_name {STRING|NUMBER|BINARY} HASH
|
48
|
+
[, key_name {STRING|NUMBER|BINARY} RANGE]
|
49
|
+
[, INDEX index1_name (attr1 {STRING|NUMBER|BINARY}) {ALL|KEYS_ONLY|INCLUDE (attr, ...)}
|
50
|
+
, INDEX index2_name (attr2 {STRING|NUMBER|BINARY}) {ALL|KEYS_ONLY|INCLUDE (attr, ...)}
|
51
|
+
, ...]
|
52
|
+
)
|
53
|
+
creates a table
|
54
|
+
|
55
|
+
DROP TABLE table_name
|
56
|
+
deletes a table
|
57
|
+
|
58
|
+
GET {*|attrs} FROM table_name WHERE key1 = '...' AND ...
|
59
|
+
gets items
|
60
|
+
|
61
|
+
INSERT INTO table_name (attr1, attr2, ...) VALUES ('val1', 'val2', ...), ('val3', 'val4', ...), ...
|
62
|
+
creates items
|
63
|
+
|
64
|
+
UPDATE table_name {SET|ADD} attr1 = 'val1', ... WHERE key1 = '...' AND ...
|
65
|
+
UPDATE ALL table_name {SET|ADD} attr1 = 'val1', ... [WHERE attr1 = '...' AND ...] [LIMIT limit]
|
66
|
+
updates items
|
67
|
+
|
68
|
+
DELETE FROM table_name WHERE key1 = '...' AND ..
|
69
|
+
DELETE ALL FROM table_name WHERE [WHERE attr1 = '...' AND ...] [ORDER {ASC|DESC}] [LIMIT limit]
|
70
|
+
deletes items
|
71
|
+
|
72
|
+
SELECT {*|attrs|COUNT(*)} FROM table_name [USE INDEX (index_name)] [WHERE key1 = '...' AND ...] [ORDER {ASC|DESC}] [LIMIT limit]
|
73
|
+
SELECT ALL {*|attrs|COUNT(*)} FROM table_name [WHERE attr1 = '...' AND ...] [LIMIT limit]
|
74
|
+
queries using the Query/Scan action
|
75
|
+
see http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html
|
76
|
+
|
77
|
+
DESC[RIBE] table_name
|
78
|
+
displays information about the table
|
79
|
+
|
80
|
+
USE region_or_endpoint
|
81
|
+
changes an endpoint
|
82
|
+
|
83
|
+
NEXT
|
84
|
+
displays a continuation of a result
|
85
|
+
(NEXT statement is published after SELECT statement)
|
86
|
+
|
87
|
+
|
88
|
+
##### Type #####
|
89
|
+
|
90
|
+
String
|
91
|
+
'London Bridge is...', "is broken down..." ...
|
92
|
+
|
93
|
+
Number
|
94
|
+
10, 100, 0.3 ...
|
95
|
+
|
96
|
+
Binary
|
97
|
+
x'123456789abcd...', x"123456789abcd..." ...
|
98
|
+
|
99
|
+
Identifier
|
100
|
+
`ABCD...` or Non-keywords
|
101
|
+
|
102
|
+
|
103
|
+
##### Operator #####
|
104
|
+
|
105
|
+
Query (SELECT)
|
106
|
+
= | <= | < | >= | > | BEGINS_WITH | BETWEEN
|
107
|
+
see http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html#DDB-Query-request-KeyConditions
|
108
|
+
|
109
|
+
Scan (SELECT ALL)
|
110
|
+
= | <> | != | <= | < | >= | > | NOT NULL | NULL | CONTAINS | NOT CONTAINS | BEGINS_WITH | IN | BETWEEN
|
111
|
+
see http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html#DDB-Scan-request-ScanFilter
|
112
|
+
|
113
|
+
|
114
|
+
##### Pass to Ruby/Shell #####
|
115
|
+
|
116
|
+
Ryby
|
117
|
+
query | ruby_script
|
118
|
+
|
119
|
+
ex) SELECT ALL * FROM employees WHERE gender = 'M' | birth_date.map {|i| Time.parse(i) };
|
120
|
+
[
|
121
|
+
"1957-09-16 00:00:00 +0900",
|
122
|
+
"1954-12-16 00:00:00 +0900",
|
123
|
+
"1964-05-23 00:00:00 +0900",
|
124
|
+
...
|
125
|
+
|
126
|
+
Shell
|
127
|
+
query ! shell_command
|
128
|
+
|
129
|
+
ex) SELECT ALL * FROM employees LIMIT 10 ! sort;
|
130
|
+
{"birth_date"=>"1957-09-16", "emp_no"=>452020,...
|
131
|
+
{"birth_date"=>"1963-07-14", "emp_no"=>16998, ...
|
132
|
+
{"birth_date"=>"1964-04-30", "emp_no"=>225407,...
|
133
|
+
...
|
134
|
+
|
135
|
+
|
136
|
+
##### Command #####
|
137
|
+
|
138
|
+
.help displays this message
|
139
|
+
.quit | .exit exits sdbcli
|
140
|
+
.consistent (true|false)? displays ConsistentRead parameter or changes it
|
141
|
+
.debug (true|false)? displays a debug status or changes it
|
142
|
+
.retry NUM? displays number of times of a retry or changes it
|
143
|
+
.retry_interval SECOND? displays a retry interval second or changes it
|
144
|
+
.timeout SECOND? displays a timeout second or changes it
|
145
|
+
.version displays a version
|
146
|
+
|
147
|
+
shell> ddbcli # show prompt
|
148
|
+
|
data/bin/ddbcli
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
|
4
|
+
Version = '0.1.0'
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'ddbcli'
|
8
|
+
require 'readline'
|
9
|
+
|
10
|
+
options = parse_options
|
11
|
+
|
12
|
+
driver = DynamoDB::Driver.new(
|
13
|
+
options.access_key_id,
|
14
|
+
options.secret_access_key,
|
15
|
+
options.ddb_endpoint_or_region)
|
16
|
+
|
17
|
+
driver.timeout = options.timeout
|
18
|
+
driver.consistent = !!options.consistent
|
19
|
+
driver.retry_num = options.retry_num
|
20
|
+
driver.retry_intvl = options.retry_intvl
|
21
|
+
driver.debug = options.debug
|
22
|
+
|
23
|
+
if not $stdin.tty? or options.command
|
24
|
+
# run mode
|
25
|
+
src = options.command || $stdin.read.strip
|
26
|
+
|
27
|
+
# complements separator
|
28
|
+
unless src =~ /\s*(?:;|\\G)\s*\Z/i
|
29
|
+
src << ';'
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
evaluate_query(driver, src)
|
34
|
+
rescue => e
|
35
|
+
print_error(e.message)
|
36
|
+
print_error(e.backtrace) if driver.debug
|
37
|
+
exit 1
|
38
|
+
end
|
39
|
+
else
|
40
|
+
# interactive mode
|
41
|
+
src = ''
|
42
|
+
prompt1 = lambda { "#{driver.region || 'unknown'}> " }
|
43
|
+
prompt2 = lambda { "#{' ' * (prompt1.call.length - 3)}-> " }
|
44
|
+
|
45
|
+
while buf = Readline.readline((src.empty? ? prompt1.call : prompt2.call), true)
|
46
|
+
# ignore blank lines
|
47
|
+
if /\A\s*\Z/ =~ buf
|
48
|
+
Readline::HISTORY.pop
|
49
|
+
next
|
50
|
+
end
|
51
|
+
|
52
|
+
if src.empty? and buf =~ /\A\.(.+)/
|
53
|
+
evaluate_command(driver, $1)
|
54
|
+
else
|
55
|
+
begin
|
56
|
+
src << (src.empty? ? buf : ("\n" + buf))
|
57
|
+
evaluate_query(driver, src, :show_rows => true)
|
58
|
+
rescue => e
|
59
|
+
print_error(e.message)
|
60
|
+
print_error(e.backtrace) if driver.debug
|
61
|
+
end
|
62
|
+
|
63
|
+
prompt = src.empty? ? prompt1.call : prompt2.call
|
64
|
+
end
|
65
|
+
end # end of while
|
66
|
+
end
|
data/lib/ddbcli.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'ddbcli/ddb-binary'
|
2
|
+
require 'ddbcli/ddb-client'
|
3
|
+
require 'ddbcli/ddb-driver'
|
4
|
+
require 'ddbcli/ddb-endpoint'
|
5
|
+
require 'ddbcli/ddb-error'
|
6
|
+
require 'ddbcli/ddb-iteratorable'
|
7
|
+
require 'ddbcli/ddb-rubyext'
|
8
|
+
|
9
|
+
# CLI
|
10
|
+
require 'ddbcli/cli/functions'
|
11
|
+
require 'ddbcli/cli/evaluate'
|
12
|
+
require 'ddbcli/cli/help'
|
13
|
+
require 'ddbcli/cli/options'
|
@@ -0,0 +1,51 @@
|
|
1
|
+
def evaluate_query(driver, src, opts = {})
|
2
|
+
ss = StringScanner.new(src.dup)
|
3
|
+
buf = ''
|
4
|
+
|
5
|
+
until ss.eos?
|
6
|
+
if (tok = ss.scan %r{[^`'";\\/#]+}) #'
|
7
|
+
buf << tok
|
8
|
+
elsif (tok = ss.scan /`(?:[^`]|``)*`/)
|
9
|
+
buf << tok
|
10
|
+
elsif (tok = ss.scan /'(?:[^']|'')*'/) #'
|
11
|
+
buf << tok
|
12
|
+
elsif (tok = ss.scan /"(?:[^"]|"")*"/) #"
|
13
|
+
buf << tok
|
14
|
+
elsif (tok = ss.scan %r{/\*/?(?:\n|[^/]|[^*]/)*\*/})
|
15
|
+
# nothing to do
|
16
|
+
elsif (tok = ss.scan /--[^\r\n]*(?:\r\n|\r|\n|\Z)/)
|
17
|
+
# nothing to do
|
18
|
+
elsif (tok = ss.scan /#[^\r\n]*(?:\r\n|\r|\n|\Z)/)
|
19
|
+
# nothing to do
|
20
|
+
elsif (tok = ss.scan /(?:\\;)/)
|
21
|
+
buf << ';' # escape of ';'
|
22
|
+
elsif (tok = ss.scan /(?:;|\\G)/)
|
23
|
+
src.replace(ss.rest)
|
24
|
+
query = buf
|
25
|
+
buf = ''
|
26
|
+
|
27
|
+
if query.strip.empty?
|
28
|
+
print_error('No query specified')
|
29
|
+
next
|
30
|
+
end
|
31
|
+
|
32
|
+
start_time = Time.new
|
33
|
+
out = driver.execute(query)
|
34
|
+
elapsed = Time.now - start_time
|
35
|
+
|
36
|
+
if out.kind_of?(DynamoDB::Driver::Rownum)
|
37
|
+
print_rownum(out, :time => elapsed)
|
38
|
+
elsif out.kind_of?(String)
|
39
|
+
puts out
|
40
|
+
elsif out
|
41
|
+
opts = opts.merge(:inline => (tok != '\G'), :time => elapsed)
|
42
|
+
print_json(out, opts)
|
43
|
+
end
|
44
|
+
elsif (tok = ss.scan /./)
|
45
|
+
buf << tok # 落ち穂拾い
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
src.replace(buf.strip)
|
50
|
+
buf
|
51
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
def print_error(errmsg, opts = {})
|
2
|
+
errmsg = errmsg.join("\n") if errmsg.kind_of?(Array)
|
3
|
+
errmsg = errmsg.strip.split("\n").map {|i| "// #{i.strip}" }.join("\n")
|
4
|
+
errmsg += "\n\n" unless opts[:strip]
|
5
|
+
$stderr.puts errmsg
|
6
|
+
end
|
7
|
+
|
8
|
+
def print_rownum(data, opts = {})
|
9
|
+
rownum = data.to_i
|
10
|
+
msg = "// #{rownum} #{rownum > 1 ? 'rows' : 'row'} changed"
|
11
|
+
msg << " (%.2f sec)" % opts[:time] if opts[:time]
|
12
|
+
puts msg
|
13
|
+
end
|
14
|
+
|
15
|
+
def print_version
|
16
|
+
puts "#{File.basename($0)} #{Version}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def print_json(data, opts = {})
|
20
|
+
str = nil
|
21
|
+
last_evaluated_key = nil
|
22
|
+
|
23
|
+
if data.kind_of?(DynamoDB::Iteratorable)
|
24
|
+
last_evaluated_key = data.last_evaluated_key
|
25
|
+
data = data.data
|
26
|
+
end
|
27
|
+
|
28
|
+
if data.kind_of?(Array) and opts[:inline]
|
29
|
+
str = "[\n"
|
30
|
+
|
31
|
+
data.each_with_index do |item, i|
|
32
|
+
str << " #{item.to_json}"
|
33
|
+
str << ',' if i < (data.length - 1)
|
34
|
+
str << "\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
str << "]"
|
38
|
+
else
|
39
|
+
if data.kind_of?(Array) or data.kind_of?(Hash)
|
40
|
+
str = JSON.pretty_generate(data)
|
41
|
+
else
|
42
|
+
str = data.to_json
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
str.sub!(/(?:\r\n|\r|\n)*\Z/, "\n")
|
47
|
+
|
48
|
+
if opts[:show_rows] and data.kind_of?(Array)
|
49
|
+
str << "// #{data.length} #{data.length > 1 ? 'rows' : 'row'} in set"
|
50
|
+
str << " (%.2f sec)" % opts[:time] if opts[:time]
|
51
|
+
str << "\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
if last_evaluated_key
|
55
|
+
str << "// has more\n"
|
56
|
+
end
|
57
|
+
|
58
|
+
str << "\n"
|
59
|
+
puts str
|
60
|
+
end
|
61
|
+
|
62
|
+
def evaluate_command(driver, cmd_arg)
|
63
|
+
cmd, arg = cmd_arg.split(/\s+/, 2).map {|i| i.strip }
|
64
|
+
arg = nil if (arg || '').strip.empty?
|
65
|
+
|
66
|
+
r = /\A#{Regexp.compile(cmd)}/i
|
67
|
+
|
68
|
+
commands = {
|
69
|
+
'help' => lambda {
|
70
|
+
print_help
|
71
|
+
},
|
72
|
+
|
73
|
+
['exit', 'quit'] => lambda {
|
74
|
+
exit 0
|
75
|
+
},
|
76
|
+
|
77
|
+
'timeout' => lambda {
|
78
|
+
case arg
|
79
|
+
when nil
|
80
|
+
puts driver.timeout
|
81
|
+
when /\d+/
|
82
|
+
driver.timeout = arg.to_i
|
83
|
+
else
|
84
|
+
print_error('Invalid argument')
|
85
|
+
end
|
86
|
+
},
|
87
|
+
|
88
|
+
'consistent' => lambda {
|
89
|
+
if arg
|
90
|
+
r_arg = /\A#{Regexp.compile(arg)}/i
|
91
|
+
|
92
|
+
if r_arg =~ 'true'
|
93
|
+
driver.consistent = true
|
94
|
+
elsif r_arg =~ 'false'
|
95
|
+
driver.consistent = false
|
96
|
+
else
|
97
|
+
print_error('Invalid argument')
|
98
|
+
end
|
99
|
+
else
|
100
|
+
puts driver.consistent
|
101
|
+
end
|
102
|
+
},
|
103
|
+
|
104
|
+
'retry' => lambda {
|
105
|
+
case arg
|
106
|
+
when nil
|
107
|
+
puts driver.retry_num
|
108
|
+
when /\d+/
|
109
|
+
driver.retry_num = arg.to_i
|
110
|
+
else
|
111
|
+
print_error('Invalid argument')
|
112
|
+
end
|
113
|
+
},
|
114
|
+
|
115
|
+
'retry_interval' => lambda {
|
116
|
+
case arg
|
117
|
+
when nil
|
118
|
+
puts driver.retry_intvl
|
119
|
+
when /\d+/
|
120
|
+
driver.retry_intvl = arg.to_i
|
121
|
+
else
|
122
|
+
print_error('Invalid argument')
|
123
|
+
end
|
124
|
+
},
|
125
|
+
|
126
|
+
'debug' => lambda {
|
127
|
+
if arg
|
128
|
+
r_arg = /\A#{Regexp.compile(arg)}/i
|
129
|
+
|
130
|
+
if r_arg =~ 'true'
|
131
|
+
driver.debug = true
|
132
|
+
elsif r_arg =~ 'false'
|
133
|
+
driver.debug = false
|
134
|
+
else
|
135
|
+
print_error('Invalid argument')
|
136
|
+
end
|
137
|
+
else
|
138
|
+
puts driver.debug
|
139
|
+
end
|
140
|
+
},
|
141
|
+
|
142
|
+
'version' => lambda {
|
143
|
+
print_version
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
cmd_name, cmd_proc = commands.find do |name, proc|
|
148
|
+
if name.kind_of?(Array)
|
149
|
+
name.any? {|i| r =~ i }
|
150
|
+
else
|
151
|
+
r =~ name
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
if cmd_proc
|
156
|
+
cmd_proc.call
|
157
|
+
else
|
158
|
+
print_error('Unknown command')
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
def print_help
|
2
|
+
puts <<'EOS'
|
3
|
+
##### Query #####
|
4
|
+
|
5
|
+
SHOW TABLES
|
6
|
+
displays a table list
|
7
|
+
|
8
|
+
SHOW REGIONS
|
9
|
+
displays a region list
|
10
|
+
|
11
|
+
SHOW CREATE TABLE table_name
|
12
|
+
displays a CREATE TABLE statement
|
13
|
+
|
14
|
+
CREATE TABLES table_name (
|
15
|
+
key_name {STRING|NUMBER|BINARY} HASH
|
16
|
+
[, key_name {STRING|NUMBER|BINARY} RANGE]
|
17
|
+
[, INDEX index1_name (attr1 {STRING|NUMBER|BINARY}) {ALL|KEYS_ONLY|INCLUDE (attr, ...)}
|
18
|
+
, INDEX index2_name (attr2 {STRING|NUMBER|BINARY}) {ALL|KEYS_ONLY|INCLUDE (attr, ...)}
|
19
|
+
, ...]
|
20
|
+
)
|
21
|
+
creates a table
|
22
|
+
|
23
|
+
DROP TABLE table_name
|
24
|
+
deletes a table
|
25
|
+
|
26
|
+
GET {*|attrs} FROM table_name WHERE key1 = '...' AND ...
|
27
|
+
gets items
|
28
|
+
|
29
|
+
INSERT INTO table_name (attr1, attr2, ...) VALUES ('val1', 'val2', ...), ('val3', 'val4', ...), ...
|
30
|
+
creates items
|
31
|
+
|
32
|
+
UPDATE table_name {SET|ADD} attr1 = 'val1', ... WHERE key1 = '...' AND ...
|
33
|
+
UPDATE ALL table_name {SET|ADD} attr1 = 'val1', ... [WHERE attr1 = '...' AND ...] [LIMIT limit]
|
34
|
+
updates items
|
35
|
+
|
36
|
+
DELETE FROM table_name WHERE key1 = '...' AND ..
|
37
|
+
DELETE ALL FROM table_name WHERE [WHERE attr1 = '...' AND ...] [ORDER {ASC|DESC}] [LIMIT limit]
|
38
|
+
deletes items
|
39
|
+
|
40
|
+
SELECT {*|attrs|COUNT(*)} FROM table_name [USE INDEX (index_name)] [WHERE key1 = '...' AND ...] [ORDER {ASC|DESC}] [LIMIT limit]
|
41
|
+
SELECT ALL {*|attrs|COUNT(*)} FROM table_name [WHERE attr1 = '...' AND ...] [LIMIT limit]
|
42
|
+
queries using the Query/Scan action
|
43
|
+
see http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html
|
44
|
+
|
45
|
+
DESC[RIBE] table_name
|
46
|
+
displays information about the table
|
47
|
+
|
48
|
+
USE region_or_endpoint
|
49
|
+
changes an endpoint
|
50
|
+
|
51
|
+
NEXT
|
52
|
+
displays a continuation of a result
|
53
|
+
(NEXT statement is published after SELECT statement)
|
54
|
+
|
55
|
+
|
56
|
+
##### Type #####
|
57
|
+
|
58
|
+
String
|
59
|
+
'London Bridge is...', "is broken down..." ...
|
60
|
+
|
61
|
+
Number
|
62
|
+
10, 100, 0.3 ...
|
63
|
+
|
64
|
+
Binary
|
65
|
+
x'123456789abcd...', x"123456789abcd..." ...
|
66
|
+
|
67
|
+
Identifier
|
68
|
+
`ABCD...` or Non-keywords
|
69
|
+
|
70
|
+
|
71
|
+
##### Operator #####
|
72
|
+
|
73
|
+
Query (SELECT)
|
74
|
+
= | <= | < | >= | > | BEGINS_WITH | BETWEEN
|
75
|
+
see http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html#DDB-Query-request-KeyConditions
|
76
|
+
|
77
|
+
Scan (SELECT ALL)
|
78
|
+
= | <> | != | <= | < | >= | > | NOT NULL | NULL | CONTAINS | NOT CONTAINS | BEGINS_WITH | IN | BETWEEN
|
79
|
+
see http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html#DDB-Scan-request-ScanFilter
|
80
|
+
|
81
|
+
|
82
|
+
##### Pass to Ruby/Shell #####
|
83
|
+
|
84
|
+
Ryby
|
85
|
+
query | ruby_script
|
86
|
+
|
87
|
+
ex) SELECT ALL * FROM employees WHERE gender = 'M' | birth_date.map {|i| Time.parse(i) };
|
88
|
+
[
|
89
|
+
"1957-09-16 00:00:00 +0900",
|
90
|
+
"1954-12-16 00:00:00 +0900",
|
91
|
+
"1964-05-23 00:00:00 +0900",
|
92
|
+
...
|
93
|
+
|
94
|
+
Shell
|
95
|
+
query ! shell_command
|
96
|
+
|
97
|
+
ex) SELECT ALL * FROM employees LIMIT 10 ! sort;
|
98
|
+
{"birth_date"=>"1957-09-16", "emp_no"=>452020,...
|
99
|
+
{"birth_date"=>"1963-07-14", "emp_no"=>16998, ...
|
100
|
+
{"birth_date"=>"1964-04-30", "emp_no"=>225407,...
|
101
|
+
...
|
102
|
+
|
103
|
+
|
104
|
+
##### Command #####
|
105
|
+
|
106
|
+
.help displays this message
|
107
|
+
.quit | .exit exits sdbcli
|
108
|
+
.consistent (true|false)? displays ConsistentRead parameter or changes it
|
109
|
+
.debug (true|false)? displays a debug status or changes it
|
110
|
+
.retry NUM? displays number of times of a retry or changes it
|
111
|
+
.retry_interval SECOND? displays a retry interval second or changes it
|
112
|
+
.timeout SECOND? displays a timeout second or changes it
|
113
|
+
.version displays a version
|
114
|
+
|
115
|
+
EOS
|
116
|
+
end
|