Merge branch 'master' of https://github.com/spulec/moto into 0.4.1-threadsafe

* 'master' of https://github.com/spulec/moto: (25 commits)
  Add @zkourouma to authors.
  0.4.2
  Fix bug where listener certificate was not being saved correctly when creating an elb. Added test to cover that case.
  [dynamodb2] adds lookup method to Table class
  Add IAM list_groups and list_groups_for_user. Closes #343.
  Fix for deleting Route53 record sets with set identifiers. Closes #342.
  Use dummy date instead of an invalid date
  Adding support for comments on hosted zones.
  Add availability zone support to Subnets created via CloudFormation
  Make availability zone dynamic in Subnet Response templates
  Add filter "availabilityZone" to DescribeSubnets and add availability zone support too
  allow starting without reseting
  Fix bug with empty string for instance vpc_id. Closes #337.
  Fix default security group description.
  Update responses.py
  Add @mrucci to authors.
  Fix merge conflicts.
  Add support for ELB attributes.
  cast to int when doing math.
  General cleanup.
  ...
This commit is contained in:
Jeffrey Gelens 2015-05-29 11:35:14 +02:00
commit e722b67f36
33 changed files with 1381 additions and 167 deletions

View file

@ -122,7 +122,7 @@ class Item(object):
class Table(object):
def __init__(self, table_name, schema=None, attr=None, throughput=None, indexes=None):
def __init__(self, table_name, schema=None, attr=None, throughput=None, indexes=None, global_indexes=None):
self.name = table_name
self.attr = attr
self.schema = schema
@ -143,6 +143,7 @@ class Table(object):
self.throughput = throughput
self.throughput["NumberOfDecreasesToday"] = 0
self.indexes = indexes
self.global_indexes = global_indexes if global_indexes else []
self.created_at = datetime.datetime.now()
self.items = defaultdict(dict)
@ -158,6 +159,7 @@ class Table(object):
'KeySchema': self.schema,
'ItemCount': len(self),
'CreationDateTime': unix_time(self.created_at),
'GlobalSecondaryIndexes': [index for index in self.global_indexes],
}
}
return results
@ -171,6 +173,24 @@ class Table(object):
count += 1
return count
@property
def hash_key_names(self):
keys = [self.hash_key_attr]
for index in self.global_indexes:
for key in index['KeySchema']:
if key['KeyType'] == 'HASH':
keys.append(key['AttributeName'])
return keys
@property
def range_key_names(self):
keys = [self.range_key_attr]
for index in self.global_indexes:
for key in index['KeySchema']:
if key['KeyType'] == 'RANGE':
keys.append(key['AttributeName'])
return keys
def put_item(self, item_attrs):
hash_value = DynamoType(item_attrs.get(self.hash_key_attr))
if self.has_range_key:
@ -268,6 +288,16 @@ class Table(object):
results.append(result)
return results, scanned_count, last_page
def lookup(self, *args, **kwargs):
if not self.schema:
self.describe()
for x, arg in enumerate(args):
kwargs[self.schema[x].name] = arg
ret = self.get_item(**kwargs)
if not ret.keys():
return None
return ret
class DynamoDBBackend(BaseBackend):
@ -293,12 +323,21 @@ class DynamoDBBackend(BaseBackend):
return None
return table.put_item(item_attrs)
def get_table_keys_name(self, table_name):
def get_table_keys_name(self, table_name, keys):
"""
Given a set of keys, extracts the key and range key
"""
table = self.tables.get(table_name)
if not table:
return None, None
else:
return table.hash_key_attr, table.range_key_attr
hash_key = range_key = None
for key in keys:
if key in table.hash_key_names:
hash_key = key
elif key in table.range_key_names:
range_key = key
return hash_key, range_key
def get_keys_value(self, table, keys):
if table.hash_key_attr not in keys or (table.has_range_key and table.range_key_attr not in keys):

View file

@ -99,10 +99,12 @@ class DynamoHandler(BaseResponse):
# getting attribute definition
attr = body["AttributeDefinitions"]
# getting the indexes
global_indexes = body.get("GlobalSecondaryIndexes", [])
table = dynamodb_backend2.create_table(table_name,
schema=key_schema,
throughput=throughput,
attr=attr)
attr=attr,
global_indexes=global_indexes)
return dynamo_json_dump(table.describe)
def delete_table(self):
@ -216,13 +218,14 @@ class DynamoHandler(BaseResponse):
def query(self):
name = self.body['TableName']
keys = self.body['KeyConditions']
hash_key_name, range_key_name = dynamodb_backend2.get_table_keys_name(name)
key_conditions = self.body['KeyConditions']
hash_key_name, range_key_name = dynamodb_backend2.get_table_keys_name(name, key_conditions.keys())
# hash_key_name, range_key_name = dynamodb_backend2.get_table_keys_name(name)
if hash_key_name is None:
er = "'com.amazonaws.dynamodb.v20120810#ResourceNotFoundException"
return self.error(er)
hash_key = keys[hash_key_name]['AttributeValueList'][0]
if len(keys) == 1:
hash_key = key_conditions[hash_key_name]['AttributeValueList'][0]
if len(key_conditions) == 1:
range_comparison = None
range_values = []
else:
@ -230,7 +233,7 @@ class DynamoHandler(BaseResponse):
er = "com.amazon.coral.validate#ValidationException"
return self.error(er)
else:
range_condition = keys[range_key_name]
range_condition = key_conditions[range_key_name]
if range_condition:
range_comparison = range_condition['ComparisonOperator']
range_values = range_condition['AttributeValueList']