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_delete_item(options) ⇒ Object

Delete many items at once from DynamoDB. More efficient than delete each item individually.

or

Dynamoid::Adapter::AwsSdk.batch_delete_item('table1' => [['hk1', 'rk2'], ['hk1', 'rk2']]]))

Examples:

Delete IDs 1 and 2 from the table testtable

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

Parameters:

  • options (Hash)

    the hash of tables and IDs to delete

Returns:

  • nil



69
70
71
72
73
74
75
76
77
78
79
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 69

def batch_delete_item(options)
  return nil if options.all?{|k, v| v.empty?}
  options.each do |t, ids|
    Array(ids).in_groups_of(25, false) do |group|
      batch = AWS::DynamoDB::BatchWrite.new(:config => @@connection.config)
      batch.delete(t,group)
      batch.process!          
    end
  end
  nil
end

#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



88
89
90
91
92
93
94
95
96
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 88

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



105
106
107
108
109
110
111
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 105

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



119
120
121
122
123
124
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 119

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 = {}) ⇒ Hash

Fetches an item from DynamoDB.

Parameters:

  • table_name (String)

    the name of the table

  • key (String)

    the hash key of the item to find

  • range_key (Number)

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

Returns:

  • (Hash)

    a hash representing the raw item in DynamoDB

Since:

  • 0.2.0



137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 137

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.



229
230
231
232
233
234
235
236
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 229

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



163
164
165
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 163

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



173
174
175
176
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 173

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



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

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



216
217
218
219
220
221
222
223
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 216

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



238
239
240
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 238

def table_cache
  @table_cache ||= {}
end

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



150
151
152
153
154
155
156
157
158
# File 'lib/dynamoid/adapter/aws_sdk.rb', line 150

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