Skip to content

Commit

Permalink
Implement 'allocate_ids' RPC on Connection.
Browse files Browse the repository at this point in the history
Fixes #272.
  • Loading branch information
tseaver committed Oct 27, 2014
1 parent d5882e3 commit eff498d
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
20 changes: 20 additions & 0 deletions gcloud/datastore/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,26 @@ def rollback(self, dataset_id):
self._rpc(dataset_id, 'rollback', request,
datastore_pb.RollbackResponse)

def allocate_ids(self, dataset_id, key_pbs):
"""Obtain backend-generated IDs for a set of keys.
:type dataset_id: string
:param dataset_id: The dataset to which the transaction belongs.
:type key_pbs: list of :class:`gcloud.datastore.datastore_v1_pb2.Key`
:param key_pbs: The keys for which the backend should allocate IDs.
:rtype: list of :class:`gcloud.datastore.datastore_v1_pb2.Key`
:returns: An equal number of keys, with IDs filled in by the backend.
"""
request = datastore_pb.AllocateIdsRequest()
for key_pb in key_pbs:
request.key.add().CopyFrom(key_pb)
# Nothing to do with this response, so just execute the method.
response = self._rpc(dataset_id, 'allocateIds', request,
datastore_pb.AllocateIdsResponse)
return list(response.key)

#
# Entity-related helper methods.
#
Expand Down
66 changes: 66 additions & 0 deletions gcloud/datastore/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,72 @@ def id(self):
request.ParseFromString(cw['body'])
self.assertEqual(request.transaction, TRANSACTION)

def test_allocate_ids_empty(self):
from gcloud.datastore.connection import datastore_pb

DATASET_ID = 'DATASET'
rsp_pb = datastore_pb.AllocateIdsResponse()
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
'datastore',
conn.API_VERSION,
'datasets',
DATASET_ID,
'allocateIds',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
self.assertEqual(conn.allocate_ids(DATASET_ID, []), [])
cw = http._called_with
self.assertEqual(cw['uri'], URI)
self.assertEqual(cw['method'], 'POST')
self.assertEqual(cw['headers']['Content-Type'],
'application/x-protobuf')
self.assertEqual(cw['headers']['User-Agent'], conn.USER_AGENT)
rq_class = datastore_pb.AllocateIdsRequest
request = rq_class()
request.ParseFromString(cw['body'])
self.assertEqual(list(request.key), [])

def test_allocate_ids_non_empty(self):
from gcloud.datastore.connection import datastore_pb
from gcloud.datastore.key import Key

DATASET_ID = 'DATASET'
before_key_pbs = [
Key(path=[{'kind': 'Kind'}]).to_protobuf(),
Key(path=[{'kind': 'Kind'}]).to_protobuf(),
]
after_key_pbs = [
Key(path=[{'kind': 'Kind', 'id': 1234}]).to_protobuf(),
Key(path=[{'kind': 'Kind', 'id': 2345}]).to_protobuf(),
]
rsp_pb = datastore_pb.AllocateIdsResponse()
rsp_pb.key.add().CopyFrom(after_key_pbs[0])
rsp_pb.key.add().CopyFrom(after_key_pbs[1])
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
'datastore',
conn.API_VERSION,
'datasets',
DATASET_ID,
'allocateIds',
])
http = conn._http = Http({'status': '200'}, rsp_pb.SerializeToString())
self.assertEqual(conn.allocate_ids(DATASET_ID, before_key_pbs),
after_key_pbs)
cw = http._called_with
self.assertEqual(cw['uri'], URI)
self.assertEqual(cw['method'], 'POST')
self.assertEqual(cw['headers']['Content-Type'],
'application/x-protobuf')
self.assertEqual(cw['headers']['User-Agent'], conn.USER_AGENT)
rq_class = datastore_pb.AllocateIdsRequest
request = rq_class()
request.ParseFromString(cw['body'])
self.assertEqual(list(request.key), before_key_pbs)

def test_save_entity_wo_transaction_w_upsert(self):
from gcloud.datastore.connection import datastore_pb
from gcloud.datastore.key import Key
Expand Down

0 comments on commit eff498d

Please sign in to comment.