class Stax::Cmd::DynamoDB
Constants
- COLORS
Public Instance Methods
backup(id = nil)
click to toggle source
# File lib/stax/mixin/dynamodb/backup.rb, line 24 def backup(id = nil) name = my.resource(id) if options[:create] create_backup(name, options[:create]) else list_backups(name) end end
client(port)
click to toggle source
client for dynamodb-local endpoint on given port
# File lib/stax/mixin/dynamodb/local.rb, line 21 def client(port) @_client ||= ::Aws::DynamoDB::Client.new(endpoint: "http://localhost:#{port}") end
count(id)
click to toggle source
# File lib/stax/mixin/dynamodb.rb, line 81 def count(id) puts Aws::DynamoDB.count(table_name: my.resource(id)) end
create_backup(table_name, backup_name)
click to toggle source
# File lib/stax/mixin/dynamodb/backup.rb, line 13 def create_backup(table_name, backup_name) backup_name = Time.now.utc.strftime("#{table_name}-%Y%m%d%H%M%S") if backup_name == 'create' # thor option empty debug("Creating backup #{backup_name} from #{table_name}") Aws::DynamoDB.create_backup(table_name, backup_name).tap do |b| puts YAML.dump(stringify_keys(b.to_hash)) end end
dynamo_local_create(payload, port)
click to toggle source
create table
# File lib/stax/mixin/dynamodb/local.rb, line 51 def dynamo_local_create(payload, port) client(port).create_table(dynamo_ruby_payload(payload)) rescue ::Aws::DynamoDB::Errors::ResourceInUseException => e warn(e.message) # table exists rescue Seahorse::Client::NetworkingError => e warn(e.message) # dynamodb-local probably not running end
dynamo_local_tables()
click to toggle source
get CFN template and return hash of table configs
# File lib/stax/mixin/dynamodb/local.rb, line 26 def dynamo_local_tables JSON.parse(my.cfn_template).fetch('Resources', {}).select do |_, v| v['Type'] == 'AWS::DynamoDB::Table' end end
dynamo_payload_from_template(id, template)
click to toggle source
convert some CFN properties to their SDK equivalents
# File lib/stax/mixin/dynamodb/local.rb, line 33 def dynamo_payload_from_template(id, template) template['Properties'].tap do |p| p['TableName'] ||= id # use logical id if no name in template p['StreamSpecification']&.merge!( 'StreamEnabled' => true ) p['SSESpecification'] &&= { 'Enabled' => p.dig('SSESpecification', 'SSEEnabled') } p.delete('TimeToLiveSpecification') p.delete('Tags') end end
dynamo_ruby_payload(payload)
click to toggle source
convert property names to ruby SDK form
# File lib/stax/mixin/dynamodb/local.rb, line 44 def dynamo_ruby_payload(payload) payload&.deep_transform_keys do |key| key.to_s.underscore.to_sym end end
gsi(id)
click to toggle source
# File lib/stax/mixin/dynamodb.rb, line 53 def gsi(id) print_table Aws::DynamoDB.gsi(my.resource(id)).map { |i| hash = i.key_schema.find{ |k| k.key_type == 'HASH' }&.attribute_name range = i.key_schema.find{ |k| k.key_type == 'RANGE' }&.attribute_name [i.index_name, hash, range, i.projection.projection_type, i.index_size_bytes, i.item_count] }.sort end
keys(id)
click to toggle source
# File lib/stax/mixin/dynamodb.rb, line 71 def keys(id) print_table Aws::DynamoDB.keys(my.resource(id)) end
list_backups(name)
click to toggle source
# File lib/stax/mixin/dynamodb/backup.rb, line 6 def list_backups(name) debug("Backups for #{name}") print_table Aws::DynamoDB.list_backups(table_name: name).map { |b| [b.backup_name, color(b.backup_status, COLORS), b.table_name, b.backup_creation_date_time, human_bytes(b.backup_size_bytes)] } end
local_create()
click to toggle source
# File lib/stax/mixin/dynamodb/local.rb, line 64 def local_create tables = dynamo_local_tables tables.slice!(*options[:tables]) if options[:tables] tables.each do |id, value| payload = dynamo_payload_from_template(id, value) payload = my.dynamo_local_payload_hacks(id, payload) # apply user-supplied hacks if options[:payload] puts JSON.pretty_generate(payload) else puts "create table #{id}" dynamo_local_create(payload, options[:port]) end end end
local_delete()
click to toggle source
# File lib/stax/mixin/dynamodb/local.rb, line 83 def local_delete tables = dynamo_local_tables tables.slice!(*options[:tables]) if options[:tables] tables.each do |id,_value| puts "deleting table #{id}" client(options[:port]).delete_table(table_name: id) end end
lsi(id)
click to toggle source
# File lib/stax/mixin/dynamodb.rb, line 62 def lsi(id) print_table Aws::DynamoDB.lsi(my.resource(id)).map { |i| hash = i.key_schema.find{ |k| k.key_type == 'HASH' }&.attribute_name range = i.key_schema.find{ |k| k.key_type == 'RANGE' }&.attribute_name [i.index_name, hash, range, i.projection.projection_type, i.index_size_bytes, i.item_count] }.sort end
print_throughput(ids)
click to toggle source
# File lib/stax/mixin/dynamodb/throughput.rb, line 6 def print_throughput(ids) output = [['NAME', 'INDEX NAME', 'READ CAPACITY', 'WRITE CAPACITY', 'DECREASES TODAY']] stack_table_names(ids).each do |name| table = Aws::DynamoDB.table(name) t = table.provisioned_throughput output << [table.table_name, nil, t.read_capacity_units, t.write_capacity_units, t.number_of_decreases_today] (table.global_secondary_indexes || []).each do |gsi| t = gsi.provisioned_throughput output << [table.table_name, gsi.index_name, t.read_capacity_units, t.write_capacity_units, t.number_of_decreases_today] end end print_table(output) end
put(id)
click to toggle source
# File lib/stax/mixin/dynamodb.rb, line 104 def put(id) table = my.resource(id) count = 0 $stdin.each do |line| Aws::DynamoDB.put(table_name: table, item: JSON.parse(line)) print '.' if options[:verbose] count += 1 end print "\n" if options[:verbose] puts "put #{count} items to #{table}" end
query(id, hash_value, range_value = nil)
click to toggle source
# File lib/stax/mixin/dynamodb.rb, line 86 def query(id, hash_value, range_value = nil) name = my.resource(id) k = Aws::DynamoDB.keys(name) Aws::DynamoDB.query( table_name: name, expression_attribute_values: { ':h' => hash_value, ':r' => range_value, }.compact, key_condition_expression: [ "#{k[:hash]} = :h", range_value ? "#{k[:range]} = :r" : nil, ].compact.join(' and '), ) end
restore(arn, table)
click to toggle source
# File lib/stax/mixin/dynamodb/backup.rb, line 34 def restore(arn, table) debug("Creating table #{table} from backup #{arn}") Aws::DynamoDB.restore_backup(table, arn) end
scan(id)
click to toggle source
# File lib/stax/mixin/dynamodb.rb, line 76 def scan(id) Aws::DynamoDB.scan(table_name: my.resource(id)) end
stack_table_names(logical_ids)
click to toggle source
get table names from logical IDs, return all tables if nil
# File lib/stax/mixin/dynamodb.rb, line 34 def stack_table_names(logical_ids) stack_tables.tap do |tables| tables.select! { |t| logical_ids.include?(t.logical_resource_id) } if logical_ids end.map(&:physical_resource_id) end
stack_tables()
click to toggle source
# File lib/stax/mixin/dynamodb.rb, line 29 def stack_tables Aws::Cfn.resources_by_type(my.stack_name, 'AWS::DynamoDB::Table') end
tables()
click to toggle source
# File lib/stax/mixin/dynamodb.rb, line 42 def tables debug("Dynamo tables for stack #{my.stack_name}") print_table stack_tables.map { |r| t = Aws::DynamoDB.table(r.physical_resource_id) g = Aws::DynamoDB.global_table(r.physical_resource_id) regions = g.nil? ? '-' : g.replication_group.map(&:region_name).sort.join(',') [ t.table_name, color(t.table_status, COLORS), t.item_count, t.table_size_bytes, t.creation_date_time, regions ] } end
throughput()
click to toggle source
# File lib/stax/mixin/dynamodb/throughput.rb, line 57 def throughput if options[:write] || options[:read] update_throughput(options[:tables], options[:read], options[:write]) else print_throughput(options[:tables]) end end
update_throughput(ids, read, write)
click to toggle source
# File lib/stax/mixin/dynamodb/throughput.rb, line 20 def update_throughput(ids, read, write) debug("Updating throughput on #{ids ? ids.count : 'all'} tables") stack_table_names(ids).each do |name| puts name table = Aws::DynamoDB.table(name) begin Aws::DynamoDB.client.update_table( table_name: name, provisioned_throughput: { read_capacity_units: read || table.provisioned_throughput.read_capacity_units, write_capacity_units: write || table.provisioned_throughput.write_capacity_units, }, global_secondary_index_updates: table.global_secondary_indexes&.map do |gsi| { update: { index_name: gsi.index_name, provisioned_throughput: { read_capacity_units: read || gsi.provisioned_throughput.read_capacity_units, write_capacity_units: write || gsi.provisioned_throughput.write_capacity_units, } } } end ) rescue ::Aws::DynamoDB::Errors::ValidationException puts 'no change' rescue ::Aws::DynamoDB::Errors::ResourceInUseException => e warn(e.message) end end end