Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address fifth part of 451: Implement Key.complete_key for auto_id on partial keys. #461

Merged
merged 2 commits into from
Dec 31, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions gcloud/datastore/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,5 @@ def allocate_ids(self, incomplete_key, num_ids):
self.id(), incomplete_key_pbs)
allocated_ids = [allocated_key_pb.path_element[-1].id
for allocated_key_pb in allocated_key_pbs]

# This method is temporary and will move over to Key in
# part 5 of #451.
def create_new_key(new_id):
"""Temporary method to complete `incomplete_key`.

Uses `incomplete_key` from outside scope.
"""
clone = incomplete_key._clone()
clone._path[-1]['id'] = new_id
return clone

return [create_new_key(allocated_id)
return [incomplete_key.completed_key(allocated_id)
for allocated_id in allocated_ids]
26 changes: 26 additions & 0 deletions gcloud/datastore/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,32 @@ def _clone(self):
"""
return copy.deepcopy(self)

def completed_key(self, id_or_name):
"""Creates new key from existing partial key by adding final ID/name.

:rtype: :class:`gcloud.datastore.key.Key`
:returns: A new `Key` instance with the same data as the current one
and an extra ID or name added.
:raises: `ValueError` if the current key is not partial or if
`id_or_name` is not a string or integer.
"""
if not self.is_partial:
raise ValueError('Only a partial key can be completed.')

id_or_name_key = None
if isinstance(id_or_name, six.string_types):
id_or_name_key = 'name'
elif isinstance(id_or_name, six.integer_types):
id_or_name_key = 'id'
else:
raise ValueError(id_or_name,
'ID/name was not a string or integer.')

new_key = self._clone()
new_key._path[-1][id_or_name_key] = id_or_name
new_key._flat_path += (id_or_name,)
return new_key

def to_protobuf(self):
"""Return a protobuf corresponding to the key.

Expand Down
24 changes: 24 additions & 0 deletions gcloud/datastore/test_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,30 @@ def test__clone(self):
self.assertEqual(clone.kind, _KIND)
self.assertEqual(clone.path, _PATH)

def test_completed_key_on_partial_w_id(self):
key = self._makeOne('KIND')
_ID = 1234
new_key = key.completed_key(_ID)
self.assertFalse(key is new_key)
self.assertEqual(new_key.id, _ID)
self.assertEqual(new_key.name, None)

def test_completed_key_on_partial_w_name(self):
key = self._makeOne('KIND')
_NAME = 'NAME'
new_key = key.completed_key(_NAME)
self.assertFalse(key is new_key)
self.assertEqual(new_key.id, None)
self.assertEqual(new_key.name, _NAME)

def test_completed_key_on_partial_w_invalid(self):
key = self._makeOne('KIND')
self.assertRaises(ValueError, key.completed_key, object())

def test_completed_key_on_complete(self):
key = self._makeOne('KIND', 1234)
self.assertRaises(ValueError, key.completed_key, 5678)

def test_to_protobuf_defaults(self):
from gcloud.datastore.datastore_v1_pb2 import Key as KeyPB
_KIND = 'KIND'
Expand Down
4 changes: 2 additions & 2 deletions regression/datastore.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ def _get_post(self, name=None, key_id=None, post_content=None):
# Update the entity key.
key = None
if name is not None:
key = datastore.key.Key('Post', name)
key = entity.key().completed_key(name)
if key_id is not None:
key = datastore.key.Key('Post', key_id)
key = entity.key().completed_key(key_id)
if key is not None:
entity.key(key)

Expand Down