lib/dynamoid/adapter/local.rb in dynamoid-0.3.2 vs lib/dynamoid/adapter/local.rb in dynamoid-0.4.0
- old
+ new
@@ -36,11 +36,11 @@
Hash.new { |h, k| h[k] = Array.new }.tap do |hash|
options.each do |table_name, keys|
table = data[table_name]
if table[:range_key]
Array(keys).each do |hash_key, range_key|
- hash[table_name] << get_item(table_name, hash_key, range_key)
+ hash[table_name] << get_item(table_name, hash_key, :range_key => range_key)
end
else
Array(keys).each do |key|
hash[table_name] << get_item(table_name, key)
end
@@ -55,21 +55,23 @@
# @param [Symbol] key the table's primary key (defaults to :id)
# @param [Hash] options provide a range_key here if you want one for the table
#
# @since 0.2.0
def create_table(table_name, key, options = {})
- data[table_name] = {:hash_key => key, :range_key => options[:range_key], :data => {}}
+ range_key = options[:range_key] && options[:range_key].keys.first
+ data[table_name] = {:hash_key => key, :range_key => range_key, :data => {}}
end
# Removes an item from the hash.
#
# @param [String] table_name the name of the table
# @param [String] key the hash key of the item to delete
# @param [Number] range_key the range key of the item to delete, required if the table has a composite key
#
# @since 0.2.0
- def delete_item(table_name, key, range_key = nil)
+ def delete_item(table_name, key, options = {})
+ range_key = options.delete(:range_key)
data[table_name][:data].delete("#{key}.#{range_key}")
end
# Deletes an entire table from the hash.
#
@@ -89,11 +91,12 @@
# @param [Number] range_key the range key of the item to find, required if the table has a composite key
#
# @return [Hash] a hash representing the raw item
#
# @since 0.2.0
- def get_item(table_name, key, range_key = nil)
+ def get_item(table_name, key, options = {})
+ range_key = options[:range_key]
if data[table_name][:data]
data[table_name][:data]["#{key}.#{range_key}"]
else
nil
end
@@ -114,10 +117,12 @@
# @since 0.2.0
def put_item(table_name, object)
table = data[table_name]
table[:data][object[table[:hash_key]]]
table[:data]["#{object[table[:hash_key]]}.#{object[table[:range_key]]}"] = object.delete_if{|k, v| v.nil? || (v.respond_to?(:empty?) && v.empty?)}
+ rescue
+ raise data.inspect
end
# Query the hash.
#
# @param [String] table_name the name of the table
@@ -132,40 +137,60 @@
# @return [Array] an array of all matching items
#
# @since 0.2.0
def query(table_name, opts = {})
id = opts[:hash_value]
+ hash_key = data[table_name][:hash_key]
range_key = data[table_name][:range_key]
- if opts[:range_value]
- data[table_name][:data].values.find_all{|v| v[:id] == id && !v[range_key].nil? && opts[:range_value].include?(v[range_key])}
+
+ results = if opts[:range_value]
+ data[table_name][:data].values.find_all{|v| v[hash_key] == id && !v[range_key].nil? && opts[:range_value].include?(v[range_key])}
elsif opts[:range_greater_than]
- data[table_name][:data].values.find_all{|v| v[:id] == id && !v[range_key].nil? && v[range_key] > opts[:range_greater_than]}
+ data[table_name][:data].values.find_all{|v| v[hash_key] == id && !v[range_key].nil? && v[range_key] > opts[:range_greater_than]}
elsif opts[:range_less_than]
- data[table_name][:data].values.find_all{|v| v[:id] == id && !v[range_key].nil? && v[range_key] < opts[:range_less_than]}
+ data[table_name][:data].values.find_all{|v| v[hash_key] == id && !v[range_key].nil? && v[range_key] < opts[:range_less_than]}
elsif opts[:range_gte]
- data[table_name][:data].values.find_all{|v| v[:id] == id && !v[range_key].nil? && v[range_key] >= opts[:range_gte]}
+ data[table_name][:data].values.find_all{|v| v[hash_key] == id && !v[range_key].nil? && v[range_key] >= opts[:range_gte]}
elsif opts[:range_lte]
- data[table_name][:data].values.find_all{|v| v[:id] == id && !v[range_key].nil? && v[range_key] <= opts[:range_lte]}
+ data[table_name][:data].values.find_all{|v| v[hash_key] == id && !v[range_key].nil? && v[range_key] <= opts[:range_lte]}
else
- get_item(table_name, id)
+ data[table_name][:data].values.find_all{|v| v[hash_key] == id}
end
+
+ results = drop_till_start(results, opts[:next_token], range_key, hash_key)
+ results = results.take(opts[:limit]) if opts[:limit]
+ results
end
# Scan the hash.
#
# @param [String] table_name the name of the table
# @param [Hash] scan_hash a hash of attributes: matching records will be returned by the scan
#
# @return [Array] an array of all matching items
#
# @since 0.2.0
- def scan(table_name, scan_hash)
+ def scan(table_name, scan_hash, opts = {})
return [] if data[table_name].nil?
- data[table_name][:data].values.flatten.select{|d| scan_hash.all?{|k, v| !d[k].nil? && d[k] == v}}
+ results = data[table_name][:data].values.flatten.select{|d| scan_hash.all?{|k, v| !d[k].nil? && d[k] == v}}
+ results = drop_till_start(results, opts[:next_token], data[table_name][:range_key], data[table_name][:hash_key])
+ results = results.take(opts[:limit]) if opts[:limit]
+ results
end
+
+ def drop_till_start(results, next_token, range_key, hash_key)
+ return results unless next_token
+
+ hash_value = next_token[:hash_key_element].values.first
+ range_value = next_token[:range_key_element].values.first if next_token[:range_key_element]
+
+ results = results.drop_while do |r|
+ (r[hash_key] != hash_value or r[range_key] != range_value)
+ end.drop(1)
+ end
# @todo Add an UpdateItem method.
# @todo Add an UpdateTable method.
end
end
-end
\ No newline at end of file
+end