Module: Dynamoid::Adapter::AwsSdk

Extended by:
AwsSdk
Included in:
AwsSdk
Defined in:
lib/dynamoid/adapter/aws_sdk.rb

Overview

The AwsSdk adapter provides support for the AWS-SDK for Ruby gem. More information is available at that Gem’s Github page: github.com/amazonwebservices/aws-sdk-for-ruby

Constant Summary collapse

@@connection =
nil

Instance Method Summary collapse

Instance Method Details

#batch_get_item(options) ⇒ Hash

Get many items at once from DynamoDB. More efficient than getting each item individually.

Examples:

Retrieve IDs 1 and 2 from the table testtable

Dynamoid::Adapter::AwsSdk.batch_get_item('table1' => ['1', '2'])

Parameters:

  • options (Hash)

    the hash of tables and IDs to retrieve

Returns:

  • (Hash)

    a hash where keys are the table names and the values are the retrieved items

Since:

  • 0.2.0



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 43

def batch_get_item(options)
  hash = Hash.new{|h, k| h[k] = []}
  return hash if options.all?{|k, v| v.empty?}
  options.each do |t, ids|
    Array(ids).in_groups_of(100, false) do |group|
      batch = AWS::DynamoDB::BatchGet.new(:config => @@connection.config)
      batch.table(t, :all, Array(group)) unless group.nil? || group.empty?
      batch.each do |table_name, attributes|
        hash[table_name] << attributes.symbolize_keys!
      end
    end
  end
  hash
end

#connect!AWS::DynamoDB::Connection

Establish the connection to DynamoDB.

Returns:

  • (AWS::DynamoDB::Connection)

    the raw DynamoDB connection

Since:

  • 0.2.0



20
21
22
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 20

def connect!
  @@connection = AWS::DynamoDB.new(:access_key_id => Dynamoid::Config.access_key, :secret_access_key => Dynamoid::Config.secret_key, :dynamo_db_endpoint => Dynamoid::Config.endpoint, :use_ssl => Dynamoid::Config.use_ssl, :dynamo_db_port => Dynamoid::Config.port)
end

#connectionAWS::DynamoDB::Connection

Return the established connection.

Returns:

  • (AWS::DynamoDB::Connection)

    the raw DynamoDB connection

Since:

  • 0.2.0



29
30
31
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 29

def connection
  @@connection
end

#create_table(table_name, key = :id, options = {}) ⇒ Object

Create a table on DynamoDB. This usually takes a long time to complete.

Parameters:

  • table_name (String)

    the name of the table to create

  • key (Symbol) (defaults to: :id)

    the table’s primary key (defaults to :id)

  • options (Hash) (defaults to: {})

    provide a range_key here if you want one for the table

Since:

  • 0.2.0



65
66
67
68
69
70
71
72
73
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 65

def create_table(table_name, key = :id, options = {})
  Dynamoid.logger.info "Creating #{table_name} table. This could take a while."
  options[:hash_key] ||= {key.to_sym => :string}
  read_capacity = options[:read_capacity] || Dynamoid::Config.read_capacity
  write_capacity = options[:write_capacity] || Dynamoid::Config.write_capacity
  table = @@connection.tables.create(table_name, read_capacity, write_capacity, options)
  sleep 0.5 while table.status == :creating
  return table
end

#delete_item(table_name, key, options = {}) ⇒ Object

Removes an item from DynamoDB.

Parameters:

  • table_name (String)

    the name of the table

  • key (String)

    the hash key of the item to delete

  • range_key (Number)

    the range key of the item to delete, required if the table has a composite key

Since:

  • 0.2.0



82
83
84
85
86
87
88
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 82

def delete_item(table_name, key, options = {})
  range_key = options.delete(:range_key)
  table = get_table(table_name)
  result = table.items.at(key, range_key)
  result.delete unless result.attributes.to_h.empty?
  true
end

#delete_table(table_name) ⇒ Object

Deletes an entire table from DynamoDB. Only 10 tables can be in the deleting state at once, so if you have more this method may raise an exception.

Parameters:

  • table_name (String)

    the name of the table to destroy

Since:

  • 0.2.0



96
97
98
99
100
101
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 96

def delete_table(table_name)
  Dynamoid.logger.info "Deleting #{table_name} table. This could take a while."
  table = @@connection.tables[table_name]
  table.delete
  sleep 0.5 while table.exists? == true
end

#get_item(table_name, key, options = {}) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 117

def get_item(table_name, key, options = {})
  range_key = options.delete(:range_key)
  table = get_table(table_name)

  result = table.items.at(key, range_key).attributes.to_h(options)

  if result.empty?
    nil
  else
    result.symbolize_keys!
  end
end

#get_table(table_name) ⇒ Object

TODO:

Add an UpdateTable method.



209
210
211
212
213
214
215
216
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 209

def get_table(table_name)
  unless table = table_cache[table_name]
    table = @@connection.tables[table_name]
    table.load_schema
    table_cache[table_name] = table
  end
  table
end

#list_tablesObject

List all tables on DynamoDB.

Since:

  • 0.2.0



143
144
145
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 143

def list_tables
  @@connection.tables.collect(&:name)
end

#put_item(table_name, object) ⇒ Object

Persists an item on DynamoDB.

Parameters:

  • table_name (String)

    the name of the table

  • object (Object)

    a hash or Dynamoid object to persist

Since:

  • 0.2.0



153
154
155
156
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 153

def put_item(table_name, object)
  table = get_table(table_name)
  table.items.create(object.delete_if{|k, v| v.nil? || (v.respond_to?(:empty?) && v.empty?)})
end

#query(table_name, opts = {}) ⇒ Array

Query the DynamoDB table. This employs DynamoDB’s indexes so is generally faster than scanning, but is only really useful for range queries, since it can only find by one hash key at once. Only provide one range key to the hash.

Parameters:

  • table_name (String)

    the name of the table

  • opts (Hash) (defaults to: {})

    the options to query the table with

Options Hash (opts):

  • :hash_value (String)

    the value of the hash key to find

  • :range_value (Range)

    find the range key within this range

  • :range_greater_than (Number)

    find range keys greater than this

  • :range_less_than (Number)

    find range keys less than this

  • :range_gte (Number)

    find range keys greater than or equal to this

  • :range_lte (Number)

    find range keys less than or equal to this

Returns:

  • (Array)

    an array of all matching items

Since:

  • 0.2.0



174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 174

def query(table_name, opts = {})
  table = get_table(table_name)

  consistent_opts = { :consistent_read => opts[:consistent_read] || false }
  if table.composite_key?
    results = []
    table.items.query(opts).each {|data| results << data.attributes.to_h(consistent_opts).symbolize_keys!}
    results
  else
    get_item(table_name, opts[:hash_value])
  end
end

#scan(table_name, scan_hash, select_opts) ⇒ Array

Scan the DynamoDB table. This is usually a very slow operation as it naively filters all data on the DynamoDB servers.

Parameters:

  • table_name (String)

    the name of the table

  • scan_hash (Hash)

    a hash of attributes: matching records will be returned by the scan

Returns:

  • (Array)

    an array of all matching items

Since:

  • 0.2.0



196
197
198
199
200
201
202
203
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 196

def scan(table_name, scan_hash, select_opts)
  table = get_table(table_name)
  results = []
  table.items.where(scan_hash).select(select_opts) do |data|
    results << data.attributes.symbolize_keys!
  end
  results
end

#table_cacheObject



218
219
220
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 218

def table_cache
  @table_cache ||= {}
end

#update_item(table_name, key, options = {}, &block) ⇒ Object



130
131
132
133
134
135
136
137
138
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 130

def update_item(table_name, key, options = {}, &block)
  range_key = options.delete(:range_key)
  conditions = options.delete(:conditions) || {}
  table = get_table(table_name)
  item = table.items.at(key, range_key)
  item.attributes.update(conditions.merge(:return => :all_new), &block)
rescue AWS::DynamoDB::Errors::ConditionalCheckFailedException
  raise Dynamoid::Errors::ConditionalCheckFailedException
end