Module: Dynamoid::Adapter
- Extended by:
- Adapter
- Included in:
- Adapter
- Defined in:
- lib/dynamoid/adapter.rb,
lib/dynamoid/adapter/local.rb,
lib/dynamoid/adapter/aws_sdk.rb
Overview
Adapter provides a generic, write-through class that abstracts variations in the underlying connections to provide a uniform response to Dynamoid.
Defined Under Namespace
Instance Attribute Summary (collapse)
-
- (Object) tables
Returns the value of attribute tables.
Instance Method Summary (collapse)
-
- (Object) adapter
The actual adapter currently in use: presently, either AwsSdk or Local.
-
- (Object) benchmark(method, *args) { ... }
Shows how long it takes a method to run on the adapter.
-
- (Object) delete(table, id, options = {})
Delete an item from a table.
-
- (Object) id_with_partitions(ids)
Takes a list of ids and returns them with partitioning added.
-
- (Object) method_missing(method, *args)
Delegate all methods that aren't defind here to the underlying adapter.
-
- (Object) read(table, ids, options = {})
Read one or many keys from the selected table.
-
- (Object) reconnect!
Establishes a connection to the underyling adapter and caches all its tables for speedier future lookups.
-
- (Object) result_for_partition(results)
Takes an array of results that are partitioned, find the most recently updated one, and return only it.
-
- (Object) scan(table, query, opts = {})
Scans a table.
-
- (Object) write(table, object)
Write an object to the adapter.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
- (Object) method_missing(method, *args)
Delegate all methods that aren't defind here to the underlying adapter.
169 170 171 172 |
# File 'lib/dynamoid/adapter.rb', line 169 def method_missing(method, *args) return benchmark(method, *args) {adapter.send(method, *args)} if @adapter.respond_to?(method) super end |
Instance Attribute Details
- (Object) tables
Returns the value of attribute tables
8 9 10 |
# File 'lib/dynamoid/adapter.rb', line 8 def tables @tables end |
Instance Method Details
- (Object) adapter
The actual adapter currently in use: presently, either AwsSdk or Local.
13 14 15 16 |
# File 'lib/dynamoid/adapter.rb', line 13 def adapter reconnect! unless @adapter @adapter end |
- (Object) benchmark(method, *args) { ... }
Shows how long it takes a method to run on the adapter. Useful for generating logged output.
37 38 39 40 41 42 |
# File 'lib/dynamoid/adapter.rb', line 37 def benchmark(method, *args) start = Time.now result = yield Dynamoid.logger.info "(#{((Time.now - start) * 1000.0).round(2)} ms) #{method.to_s.split('_').collect(&:upcase).join(' ')}#{ " - #{args.inspect}" unless args.nil? || args.empty? }" return result end |
- (Object) delete(table, id, options = {})
Delete an item from a table. If partitioning is turned on, deletes all partitioned keys as well.
98 99 100 101 102 103 104 105 106 |
# File 'lib/dynamoid/adapter.rb', line 98 def delete(table, id, = {}) if Dynamoid::Config.partitioning? benchmark('Delete Item', id) do id_with_partitions(id).each {|i| delete_item(table, i, )} end else benchmark('Delete Item', id) {delete_item(table, id, )} end end |
- (Object) id_with_partitions(ids)
Takes a list of ids and returns them with partitioning added. If an array of arrays is passed, we assume the second key is the range key and pass it in unchanged.
143 144 145 |
# File 'lib/dynamoid/adapter.rb', line 143 def id_with_partitions(ids) Array(ids).collect {|id| (0...Dynamoid::Config.partition_size).collect{|n| id.is_a?(Array) ? ["#{id.first}.#{n}", id.last] : "#{id}.#{n}"}}.flatten(1) end |
- (Object) read(table, ids, options = {})
Read one or many keys from the selected table. This method intelligently calls batch_get or get on the underlying adapter depending on whether ids is a range or a single key: additionally, if partitioning is enabled, it batch_gets all keys in the partition space automatically. Finally, if a range key is present, it will also interpolate that into the ids so that the batch get will acquire the correct record.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/dynamoid/adapter.rb', line 70 def read(table, ids, = {}) range_key = [:range_key] if ids.respond_to?(:each) ids = ids.collect{|id| range_key ? [id, range_key] : id} if Dynamoid::Config.partitioning? results = benchmark('Partitioned Batch Get Item', ids) {batch_get_item(table => id_with_partitions(ids))} {table => result_for_partition(results[table])} else benchmark('Batch Get Item', ids) {batch_get_item(table => ids)} end else if Dynamoid::Config.partitioning? ids = range_key ? [[ids, range_key]] : ids results = benchmark('Partitioned Get Item', ids) {batch_get_item(table => id_with_partitions(ids))} result_for_partition(results[table]).first else benchmark('Get Item', ids) {get_item(table, ids, )} end end end |
- (Object) reconnect!
Establishes a connection to the underyling adapter and caches all its tables for speedier future lookups. Issued when the adapter is first called.
21 22 23 24 25 26 |
# File 'lib/dynamoid/adapter.rb', line 21 def reconnect! require "dynamoid/adapter/#{Dynamoid::Config.adapter}" unless Dynamoid::Adapter.const_defined?(Dynamoid::Config.adapter.camelcase) @adapter = Dynamoid::Adapter.const_get(Dynamoid::Config.adapter.camelcase) @adapter.connect! if @adapter.respond_to?(:connect!) self.tables = benchmark('Cache Tables') {list_tables} end |
- (Object) result_for_partition(results)
Takes an array of results that are partitioned, find the most recently updated one, and return only it. Compares each result by their id and updated_at attributes; if the updated_at is the greatest, then it must be the correct result.
153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/dynamoid/adapter.rb', line 153 def result_for_partition(results) {}.tap do |hash| Array(results).each do |result| next if result.nil? id = result[:id].split('.').first if !hash[id] || (result[:updated_at] > hash[id][:updated_at]) result[:id] = id hash[id] = result end end end.values end |
- (Object) scan(table, query, opts = {})
Scans a table. Generally quite slow; try to avoid using scan if at all possible.
114 115 116 117 118 119 120 121 |
# File 'lib/dynamoid/adapter.rb', line 114 def scan(table, query, opts = {}) if Dynamoid::Config.partitioning? results = benchmark('Scan', table, query) {adapter.scan(table, query, opts)} result_for_partition(results) else adapter.scan(table, query, opts) end end |
- (Object) write(table, object)
Write an object to the adapter. Partition it to a randomly selected key first if necessary.
52 53 54 55 56 57 58 |
# File 'lib/dynamoid/adapter.rb', line 52 def write(table, object) if Dynamoid::Config.partitioning? && object[:id] object[:id] = "#{object[:id]}.#{Random.rand(Dynamoid::Config.partition_size)}" object[:updated_at] = Time.now.to_f end benchmark('Put Item', object) {put_item(table, object)} end |