Top Level Namespace
Defined Under Namespace
Modules: DynamoDB Classes: Array
Instance Method Summary collapse
- #evaluate_command(driver, cmd_arg) ⇒ Object
- #evaluate_query(driver, src, opts = {}) ⇒ Object
- #parse_options ⇒ Object
- #print_error(errmsg, opts = {}) ⇒ Object
- #print_help(options = {}) ⇒ Object
- #print_json(data, out, opts = {}) ⇒ Object
- #print_rownum(data, opts = {}) ⇒ Object
- #print_version ⇒ Object
Instance Method Details
#evaluate_command(driver, cmd_arg) ⇒ Object
69 70 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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/ddbcli/cli/functions.rb', line 69 def evaluate_command(driver, cmd_arg) cmd, arg = cmd_arg.split(/\s+/, 2).map {|i| i.strip } arg = nil if (arg || '').strip.empty? r = /\A#{Regexp.compile(cmd)}/i commands = { 'help' => lambda { print_help(:pagerize => true) }, ['exit', 'quit'] => lambda { exit 0 }, 'timeout' => lambda { case arg when nil puts driver.timeout when /\d+/ driver.timeout = arg.to_i else print_error('Invalid argument') end }, 'consistent' => lambda { if arg r_arg = /\A#{Regexp.compile(arg)}/i if r_arg =~ 'true' driver.consistent = true elsif r_arg =~ 'false' driver.consistent = false else print_error('Invalid argument') end else puts driver.consistent end }, 'iteratable' => lambda { if arg r_arg = /\A#{Regexp.compile(arg)}/i if r_arg =~ 'true' driver.iteratable = true elsif r_arg =~ 'false' driver.iteratable = false else print_error('Invalid argument') end else puts driver.iteratable end }, 'retry' => lambda { case arg when nil puts driver.retry_num when /\d+/ driver.retry_num = arg.to_i else print_error('Invalid argument') end }, 'retry_interval' => lambda { case arg when nil puts driver.retry_intvl when /\d+/ driver.retry_intvl = arg.to_i else print_error('Invalid argument') end }, 'debug' => lambda { if arg r_arg = /\A#{Regexp.compile(arg)}/i if r_arg =~ 'true' driver.debug = true elsif r_arg =~ 'false' driver.debug = false else print_error('Invalid argument') end else puts driver.debug end }, 'version' => lambda { print_version } } cmd_name, cmd_proc = commands.find do |name, proc| if name.kind_of?(Array) name.any? {|i| r =~ i } else r =~ name end end if cmd_proc cmd_proc.call else print_error('Unknown command') end end |
#evaluate_query(driver, src, opts = {}) ⇒ Object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 |
# File 'lib/ddbcli/cli/evaluate.rb', line 1 def evaluate_query(driver, src, opts = {}) ss = StringScanner.new(src.dup) buf = '' until ss.eos? if (tok = ss.scan %r{[^`'";\\/#]+}) #' buf << tok elsif (tok = ss.scan /`(?:[^`]|``)*`/) buf << tok elsif (tok = ss.scan /'(?:[^']|'')*'/) #' buf << tok elsif (tok = ss.scan /"(?:[^"]|"")*"/) #" buf << tok elsif (tok = ss.scan %r{/\*/?(?:\n|[^/]|[^*]/)*\*/}) # nothing to do elsif (tok = ss.scan /--[^\r\n]*(?:\r\n|\r|\n|\Z)/) # nothing to do elsif (tok = ss.scan /#[^\r\n]*(?:\r\n|\r|\n|\Z)/) # nothing to do elsif (tok = ss.scan /(?:\\;)/) buf << ';' # escape of ';' elsif (tok = ss.scan /(?:;|\\G)/) src.replace(ss.rest) query = buf buf = '' if query.strip.empty? print_error('No query specified') next end start_time = Time.new out = driver.execute(query, opts.merge(:inline => (tok != '\G'))) elapsed = Time.now - start_time if out.kind_of?(DynamoDB::Driver::Rownum) print_rownum(out, opts.merge(:time => elapsed)) elsif out.kind_of?(String) puts out elsif out opts = opts.merge(:inline => (tok != '\G'), :time => elapsed) print_json(out, $stdout, opts) end elsif (tok = ss.scan /./) buf << tok # 落ち穂拾い end end src.replace(buf.strip) buf end |
#parse_options ⇒ Object
5 6 7 8 9 10 11 12 13 14 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 62 63 64 65 66 67 68 69 70 |
# File 'lib/ddbcli/cli/options.rb', line 5 def = OpenStruct.new .access_key_id = ENV['AWS_ACCESS_KEY_ID'] .secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] .ddb_endpoint_or_region = ENV['AWS_REGION'] || ENV['DDB_ENDPOINT'] || ENV['DDB_REGION'] || 'dynamodb.us-east-1.amazonaws.com' # default value .timeout = 60 .consistent = false .iteratable = false .retry_num = 3 .retry_intvl = 10 .debug = false ARGV. do |opt| opt.on('-k', '--access-key=ACCESS_KEY') {|v| .access_key_id = v } opt.on('-s', '--secret-key=SECRET_KEY') {|v| .secret_access_key = v } opt.on('-r', '--region=REGION_OR_ENDPOINT') {|v| .ddb_endpoint_or_region = v } url_opt = proc do |v| uri = v uri = "http://#{uri}" unless uri =~ %r|\A\w+://| uri = URI.parse(uri) raise URI::InvalidURIError, "invalid shceme: #{v}" unless /\Ahttps?\Z/ =~ uri.scheme .ddb_endpoint_or_region = uri end opt.on('', '--url=URL', &url_opt) opt.on('', '--uri=URL (DEPRECATION)', &url_opt) opt.on('-e', '--eval=COMMAND') {|v| .command = v } opt.on('-t', '--timeout=SECOND', Integer) {|v| .timeout = v.to_i } opt.on('', '--import=TABLE,JSON_FILE') {|v| v = v.split(/\s*,\s*/, 2) .import = {:table => v[0], :file => v[1]} } opt.on('', '--consistent-read') { .consistent = true } opt.on('', '--iteratable') { .iteratable = true } opt.on('', '--retry=NUM', Integer) {|v| .retry_num = v.to_i } opt.on('', '--retry-interval=SECOND', Integer) {|v| .retry_intvl = v.to_i } opt.on('', '--debug') { .debug = true } opt.on('-h', '--help') { puts opt.help exit } opt.parse! if .ddb_endpoint_or_region.kind_of?(URI) and not (.access_key_id and .secret_access_key) .access_key_id = 'scott' .secret_access_key = 'tiger' puts 'Warning: dummy auth key was set because ACCESS_KEY/SECRET_KEY is not set' end unless .access_key_id and .secret_access_key and .ddb_endpoint_or_region puts opt.help exit 1 end end end |
#print_error(errmsg, opts = {}) ⇒ Object
1 2 3 4 5 6 |
# File 'lib/ddbcli/cli/functions.rb', line 1 def print_error(errmsg, opts = {}) errmsg = errmsg.join("\n") if errmsg.kind_of?(Array) errmsg = errmsg.strip.split("\n").map {|i| "// #{i.strip}" }.join("\n") errmsg += "\n\n" unless opts[:strip] $stderr.puts errmsg end |
#print_help(options = {}) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 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 62 63 64 65 66 67 68 69 70 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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/ddbcli/cli/help.rb', line 3 def print_help( = {}) doc =<<EOS ##### Query ##### SHOW TABLES [LIMIT num] [LIKE '...'] display a table list SHOW TABLE STATUS [LIKE '...'] display table statues SHOW REGIONS display a region list SHOW CREATE TABLE table_name display a CREATE TABLE statement CREATE TABLE table_name ( key_name {STRING|NUMBER|BINARY} HASH [, key_name {STRING|NUMBER|BINARY} RANGE] [, INDEX index1_name (attr1 {STRING|NUMBER|BINARY}) {ALL|KEYS_ONLY|INCLUDE (attr, ...)} , INDEX index2_name (attr2 {STRING|NUMBER|BINARY}) {ALL|KEYS_ONLY|INCLUDE (attr, ...)} , ...] [, GLOBAL INDEX index1_name (hash_attr1 {STRING|NUMBER|BINARY} [, range_attr1 {STRING|NUMBER|BINARY}]) {ALL|KEYS_ONLY|INCLUDE (attr, ...)} [READ = num WRITE = num] , GLOBAL INDEX index2_name (hash_attr2 {STRING|NUMBER|BINARY} [, range_attr2 {STRING|NUMBER|BINARY}]) {ALL|KEYS_ONLY|INCLUDE (attr, ...)} [READ = num WRITE = num] , ...] ) READ = num WRITE = num [STREAM = {true|false|NEW_IMAGE|OLD_IMAGE|NEW_AND_OLD_IMAGES|KEYS_ONLY}] create a table CREATE TABLE table_name LIKE another_table_name [READ = num WRITE = num] [STREAM = {true|false|NEW_IMAGE|OLD_IMAGE|NEW_AND_OLD_IMAGES|KEYS_ONLY}] create a table like another table DROP TABLE table_name [, table_name2, ...] delete tables ALTER TABLE table_name {READ = num WRITE = num|STREAM = {true|false|NEW_IMAGE|OLD_IMAGE|NEW_AND_OLD_IMAGES|KEYS_ONLY}} update the provisioned throughput ALTER TABLE table_name CHANGE GLOBAL INDEX index_name READ = num WRITE = num update GSI provisioned throughput ALTER TABLE table_name ADD GLOBAL INDEX index_name (hash_attr1 {STRING|NUMBER|BINARY} [, range_attr1 {STRING|NUMBER|BINARY}]) {ALL|KEYS_ONLY|INCLUDE (attr, ...)} READ = num WRITE = num add GSI ALTER TABLE table_name DROP GLOBAL INDEX index_name delete GSI GET {*|attr1,attr2,...} FROM table_name WHERE key1 = '...' AND ... get items INSERT INTO table_name (attr1, attr2, ...) VALUES ('val1', 'val2', ...), ('val3', 'val4', ...), ... INSERT INTO table_name SELECT ... INSERT INTO table_name SELECT ALL ... create items UPDATE table_name {SET|ADD} attr1 = 'val1', ... WHERE key1 = '...' AND ... UPDATE ALL table_name {SET|ADD} attr1 = 'val1', ... [WHERE attr1 = '...' AND ...] [LIMIT limit] update items ("UPDATE" can update only one record. Please use "UPDATE ALL", when you update more than one.) UPDATE table_name DEL[ETE] attr1, ... WHERE key1 = '...' AND ... UPDATE ALL table_name DEL[ETE] attr1, ... [WHERE attr1 = '...' AND ...] [LIMIT limit] update items (delete attribute) DELETE FROM table_name WHERE key1 = '...' AND .. DELETE ALL FROM table_name WHERE [WHERE attr1 = '...' AND ...] [ORDER {ASC|DESC}] [LIMIT limit] delete items ("DELETE" can delete only one record. Please use "DELETE ALL", when you update more than one.) SELECT {*|attr1,attr2,...|COUNT(*)} FROM table_name [USE INDEX (index_name)] [WHERE key1 = '...' AND ...] [HAVING attr1 = '...' AND ...] [ORDER {ASC|DESC}] [LIMIT limit] SELECT ALL {*|attr1,attr2,...|COUNT(*)} FROM table_name [USE INDEX (index_name)] [WHERE attr1 = '...' AND ...] [LIMIT limit] SELECT segment/total_segments {*|attr1,attr2,...|COUNT(*)} FROM table_name [USE INDEX (index_name)] [WHERE attr1 = '...' AND ...] [LIMIT limit] query using the Query/Scan action see http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html DESC[RIBE] table_name display information about the table USE region_or_endpoint change an endpoint NEXT display a continuation of a result (NEXT statement is published after SELECT statement) ##### Type ##### String 'London Bridge is...', "is broken down..." ... Number 10, 100, 0.3 ... Binary x'123456789abcd...', x"123456789abcd..." ... Identifier `ABCD...` or Non-keywords Set ('String', 'String', ...), (1, 2, 3, ...) List ['String', (1, 2, 3), {foo: 'FOO', bar: 'BAR'}, ...] Map {key1:'String', "key2":(1, 2, 3), key3: ['FOO', 'BAR'], ...} Bool true, false Null null ##### Operator ##### Query (SELECT) = | <= | < | >= | > | BEGINS_WITH | BETWEEN see http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html#DDB-Query-request-KeyConditions Scan (SELECT ALL), QueryFilter (HAVING) = | <> | != | <= | < | >= | > | IS NOT NULL | IS NULL | CONTAINS | NOT CONTAINS | BEGINS_WITH | IN | BETWEEN see http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html#DDB-Scan-request-ScanFilter, http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html#DDB-Query-request-QueryFilter ##### Pass to Ruby/Shell ##### Ryby query | ruby_script ex) SELECT ALL * FROM employees WHERE gender = 'M' | birth_date.map {|i| Time.parse(i) }; [ "1957-09-16 00:00:00 +0900", "1954-12-16 00:00:00 +0900", "1964-05-23 00:00:00 +0900", ... Shell query ! shell_command ex) SELECT ALL * FROM employees LIMIT 10 ! sort; {"birth_date"=>"1957-09-16", "emp_no"=>452020,... {"birth_date"=>"1963-07-14", "emp_no"=>16998, ... {"birth_date"=>"1964-04-30", "emp_no"=>225407,... ... ##### Output to a file ##### Overwrite SELECT ALL * FROM employees > 'foo.json'; Append SELECT ALL * FROM employees >> 'foo.json'; ##### Command ##### .help display this message .quit | .exit exit ddbcli .consistent (true|false)? display ConsistentRead parameter or changes it .iteratable (true|false)? display iteratable option or changes it all results are displayed if true .debug (true|false)? display a debug status or changes it .retry NUM? display number of times of a retry or changes it .retry_interval SECOND? display a retry interval second or changes it .timeout SECOND? display a timeout second or changes it .version display a version EOS if [:pagerize] Tempfile.open("ddbcli.#{$$}.#{Time.now.to_i}") do |f| f.puts(doc) f.flush unless system("less #{f.path}") puts doc end end else puts doc end end |
#print_json(data, out, opts = {}) ⇒ Object
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 62 63 64 65 66 67 |
# File 'lib/ddbcli/cli/functions.rb', line 21 def print_json(data, out, opts = {}) str = nil last_evaluated_key = nil if data.kind_of?(DynamoDB::Iteratorable) last_evaluated_key = data.last_evaluated_key data = data.data end if data.kind_of?(Array) and opts[:inline] str = "[\n" data.each_with_index do |item, i| str << " #{item.to_json}" str << ',' if i < (data.length - 1) str << "\n" end str << "]" else if data.kind_of?(Array) or data.kind_of?(Hash) str = JSON.pretty_generate(data) else str = data.to_json end end str.sub!(/(?:\r\n|\r|\n)*\Z/, "\n") if opts[:show_rows] if [Array, Hash].any? {|i| data.kind_of?(i) } str << "// #{data.length} #{data.length > 1 ? 'rows' : 'row'} in set" else str << '// 1 row in set' end str << " (%.2f sec)" % opts[:time] if opts[:time] str << "\n" end if last_evaluated_key str << "// has more\n" end str << "\n" unless opts[:strip] out.puts(str) end |
#print_rownum(data, opts = {}) ⇒ Object
8 9 10 11 12 13 14 15 |
# File 'lib/ddbcli/cli/functions.rb', line 8 def print_rownum(data, opts = {}) rownum = data.to_i msg = "// #{rownum} #{rownum > 1 ? 'rows' : 'row'} changed" msg << " (%.2f sec)" % opts[:time] if opts[:time] msg << "\n" msg << "\n" unless opts[:strip] puts msg end |
#print_version ⇒ Object
17 18 19 |
# File 'lib/ddbcli/cli/functions.rb', line 17 def print_version puts "#{File.basename($0)} #{Version}" end |