[AWS|DynamoDB] first pass at query/scan requests

This commit is contained in:
geemus 2012-02-05 12:00:04 -06:00
parent cbd2a4e1dd
commit 2d22c8bda6
6 changed files with 128 additions and 18 deletions

View File

@ -16,8 +16,8 @@ module Fog
request :get_item
request :list_tables
request :put_item
#request :query
#request :scan
request :query
request :scan
request :update_item
request :update_table

View File

@ -0,0 +1,44 @@
module Fog
module AWS
class DynamoDB
class Real
# Query DynamoDB items
#
# ==== Parameters
# * 'table_name'<~String> - name of table to query
# * 'hash_key'<~Hash> - hash key to query
# * options<~Hash>:
# * 'AttributesToGet'<~Array> - Array of attributes to get for each item, defaults to all
# * 'ConsistentRead'<~Boolean> - Whether to wait for consistency, defaults to false
# * 'Count'<~Boolean> - If true, returns only a count of such items rather than items themselves, defaults to false
# * 'Limit'<~Integer> - limit of total items to return
# * 'RangeKeyCondition'<~Hash>: value to compare against range key
# * 'AttributeValueList'<~Hash>: one or more values to compare against
# * 'ComparisonOperator'<~String>: comparison operator to use with attribute value list, in %w{BETWEEN BEGINS_WITH EQ LE LT GE GT}
# * 'ScanIndexForward'<~Boolean>: Whether to scan from start or end of index, defaults to start
# * 'ExclusiveStartKey'<~Hash>: Key to start listing from, can be taken from LastEvaluatedKey in response
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'ConsumedCapacityUnits'<~Integer> - number of capacity units used for query
# * 'Count'<~Integer> - number of items in response
# * 'Items'<~Array> - array of items returned
# * 'LastEvaluatedKey'<~Hash> - last key scanned, can be passed to ExclusiveStartKey for pagination
def query(table_name, hash_key, options = {})
body = {
'TableName' => table_name,
'HashKeyValue' => hash_key
}.merge(options)
request(
:body => MultiJson.encode(body),
:headers => {'x-amz-target' => 'DynamoDB_20111205.Query'}
)
end
end
end
end
end

View File

@ -0,0 +1,44 @@
module Fog
module AWS
class DynamoDB
class Real
# Scan DynamoDB items
#
# ==== Parameters
# * 'table_name'<~String> - name of table to query
# * options<~Hash>:
# * 'AttributesToGet'<~Array> - Array of attributes to get for each item, defaults to all
# * 'ConsistentRead'<~Boolean> - Whether to wait for consistency, defaults to false
# * 'Count'<~Boolean> - If true, returns only a count of such items rather than items themselves, defaults to false
# * 'Limit'<~Integer> - limit of total items to return
# * 'ScanFilter'<~Hash>: value to compare against
# * attribute_name<~Hash>:
# * 'AttributeValueList'<~Hash>: one or more values to compare against
# * 'ComparisonOperator'<~String>: comparison operator to use with attribute value list, in %w{BETWEEN BEGINS_WITH EQ LE LT GE GT}
# * 'ScanIndexForward'<~Boolean>: Whether to scan from start or end of index, defaults to start
# * 'ExclusiveStartKey'<~Hash>: Key to start listing from, can be taken from LastEvaluatedKey in response
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'ConsumedCapacityUnits'<~Integer> - number of capacity units used for scan
# * 'Count'<~Integer> - number of items in response
# * 'Items'<~Array> - array of items returned
# * 'LastEvaluatedKey'<~Hash> - last key scanned, can be passed to ExclusiveStartKey for pagination
# * 'ScannedCount'<~Integer> - number of items scanned before applying filters
def scan(table_name, options = {})
body = {
'TableName' => table_name
}.merge(options)
request(
:body => MultiJson.encode(body),
:headers => {'x-amz-target' => 'DynamoDB_20111205.Scan'}
)
end
end
end
end
end

View File

@ -37,12 +37,9 @@ module Fog
'TableName' => table_name
}.merge(options)
idempotent = attribute_updates.has_key?('Action')
request(
:body => MultiJson.encode(body),
:headers => {'x-amz-target' => 'DynamoDB_20111205.UpdateItem'},
:idempotent => idempotent
:body => MultiJson.encode(body),
:headers => {'x-amz-target' => 'DynamoDB_20111205.UpdateItem'}
)
end

View File

@ -60,6 +60,29 @@ Shindo.tests('Fog::AWS[:dynamodb] | item requests', ['aws']) do
Fog::AWS[:dynamodb].get_item(@table_name, {'HashKeyElement' => {'S' => 'notakey'}}).body
end
@query_format = {
'ConsumedCapacityUnits' => Integer,
'Count' => Integer,
'Items' => [{
'key' => { 'S' => String },
'value' => { 'S' => String }
}],
'LastEvaluatedKey' => NilClass
}
tests("#query('#{@table_name}', {'S' => 'key'}").formats(@query_format) do
pending if Fog.mocking?
pending # requires a table with range key
Fog::AWS[:dynamodb].query(@table_name, {'S' => 'key'}).body
end
@scan_format = @query_format.merge('ScannedCount' => Integer)
tests("scan('#{@table_name}')").formats(@scan_format) do
pending if Fog.mocking?
Fog::AWS[:dynamodb].scan(@table_name).body
end
tests("#delete_item('#{@table_name}', {'HashKeyElement' => {'S' => 'key'}})").formats('ConsumedCapacityUnits' => Float) do
pending if Fog.mocking?
Fog::AWS[:dynamodb].delete_item(@table_name, {'HashKeyElement' => {'S' => 'key'}}).body

View File

@ -1,17 +1,19 @@
module Fog
module Vcloud
class Fog::Connection
def request(params, &block)
path = File.expand_path(File.join(File.dirname(__FILE__),'..','..','data',params[:path].gsub(/^\//,'').gsub('/','_+_')))
if File.exists?(path)
body = File.read(path)
else
''
if false
class Fog::Connection
def request(params, &block)
path = File.expand_path(File.join(File.dirname(__FILE__),'..','..','data',params[:path].gsub(/^\//,'').gsub('/','_+_')))
if File.exists?(path)
body = File.read(path)
else
''
end
Excon::Response.new(
:body => body,
:status => 200,
:header => '')
end
Excon::Response.new(
:body => body,
:status => 200,
:header => '')
end
end
end