Skip to content

Commit e2f44fb

Browse files
committed
Moving get_entities() and allocate_ids() to designated module.
This is a pre-cursor to designated put(), delete() and get() methods in this module (inspired by #421).
1 parent 6c5b311 commit e2f44fb

File tree

5 files changed

+486
-448
lines changed

5 files changed

+486
-448
lines changed

gcloud/datastore/__init__.py

Lines changed: 2 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@
5454

5555
from gcloud import credentials
5656
from gcloud.datastore import _implicit_environ
57+
from gcloud.datastore.api import allocate_ids
58+
from gcloud.datastore.api import get_entities
5759
from gcloud.datastore.connection import Connection
58-
from gcloud.datastore import helpers
5960

6061

6162
SCOPE = ('https://www.googleapis.com/auth/datastore',
@@ -115,131 +116,3 @@ def get_connection():
115116
implicit_credentials = credentials.get_credentials()
116117
scoped_credentials = implicit_credentials.create_scoped(SCOPE)
117118
return Connection(credentials=scoped_credentials)
118-
119-
120-
def _require_dataset_id(dataset_id=None):
121-
"""Infer a dataset ID from the environment, if not passed explicitly.
122-
123-
:type dataset_id: string
124-
:param dataset_id: Optional.
125-
126-
:rtype: string
127-
:returns: A dataset ID based on the current environment.
128-
:raises: :class:`EnvironmentError` if ``dataset_id`` is ``None``,
129-
and cannot be inferred from the environment.
130-
"""
131-
if dataset_id is None:
132-
if _implicit_environ.DATASET_ID is None:
133-
raise EnvironmentError('Dataset ID could not be inferred.')
134-
dataset_id = _implicit_environ.DATASET_ID
135-
return dataset_id
136-
137-
138-
def _require_connection(connection=None):
139-
"""Infer a connection from the environment, if not passed explicitly.
140-
141-
:type connection: :class:`gcloud.datastore.connection.Connection`
142-
:param connection: Optional.
143-
144-
:rtype: :class:`gcloud.datastore.connection.Connection`
145-
:returns: A connection based on the current environment.
146-
:raises: :class:`EnvironmentError` if ``connection`` is ``None``, and
147-
cannot be inferred from the environment.
148-
"""
149-
if connection is None:
150-
if _implicit_environ.CONNECTION is None:
151-
raise EnvironmentError('Connection could not be inferred.')
152-
connection = _implicit_environ.CONNECTION
153-
return connection
154-
155-
156-
def get_entities(keys, missing=None, deferred=None, connection=None):
157-
"""Retrieves entities, along with their attributes.
158-
159-
:type keys: list of :class:`gcloud.datastore.key.Key`
160-
:param keys: The name of the item to retrieve.
161-
162-
:type missing: an empty list or None.
163-
:param missing: If a list is passed, the key-only entities returned
164-
by the backend as "missing" will be copied into it.
165-
Use only as a keyword param.
166-
167-
:type deferred: an empty list or None.
168-
:param deferred: If a list is passed, the keys returned
169-
by the backend as "deferred" will be copied into it.
170-
Use only as a keyword param.
171-
172-
:type connection: :class:`gcloud.datastore.connection.Connection`
173-
:param connection: Optional. The connection used to connect to datastore.
174-
175-
:rtype: list of :class:`gcloud.datastore.entity.Entity`
176-
:returns: The requested entities.
177-
:raises: :class:`ValueError` if the key dataset IDs don't agree.
178-
"""
179-
if not keys:
180-
return []
181-
182-
connection = _require_connection(connection)
183-
dataset_id = keys[0].dataset_id
184-
# Rather than creating a list or set of all dataset IDs, we iterate
185-
# and check. We could allow the backend to check this for us if IDs
186-
# with no prefix worked (GoogleCloudPlatform/google-cloud-datastore#59)
187-
# or if we made sure that a prefix s~ or e~ was on each key.
188-
for key in keys[1:]:
189-
if key.dataset_id != dataset_id:
190-
raise ValueError('All keys in get_entities must be from the '
191-
'same dataset.')
192-
193-
entity_pbs = connection.lookup(
194-
dataset_id=dataset_id,
195-
key_pbs=[k.to_protobuf() for k in keys],
196-
missing=missing, deferred=deferred,
197-
)
198-
199-
if missing is not None:
200-
missing[:] = [
201-
helpers.entity_from_protobuf(missed_pb)
202-
for missed_pb in missing]
203-
204-
if deferred is not None:
205-
deferred[:] = [
206-
helpers.key_from_protobuf(deferred_pb)
207-
for deferred_pb in deferred]
208-
209-
entities = []
210-
for entity_pb in entity_pbs:
211-
entities.append(helpers.entity_from_protobuf(entity_pb))
212-
213-
return entities
214-
215-
216-
def allocate_ids(incomplete_key, num_ids, connection=None):
217-
"""Allocates a list of IDs from a partial key.
218-
219-
:type incomplete_key: A :class:`gcloud.datastore.key.Key`
220-
:param incomplete_key: Partial key to use as base for allocated IDs.
221-
222-
:type num_ids: integer
223-
:param num_ids: The number of IDs to allocate.
224-
225-
:type connection: :class:`gcloud.datastore.connection.Connection`
226-
:param connection: Optional. The connection used to connect to datastore.
227-
228-
:rtype: list of :class:`gcloud.datastore.key.Key`
229-
:returns: The (complete) keys allocated with ``incomplete_key`` as root.
230-
:raises: :class:`ValueError` if ``incomplete_key`` is not a partial key.
231-
"""
232-
connection = _require_connection(connection)
233-
234-
if not incomplete_key.is_partial:
235-
raise ValueError(('Key is not partial.', incomplete_key))
236-
237-
incomplete_key_pb = incomplete_key.to_protobuf()
238-
incomplete_key_pbs = [incomplete_key_pb] * num_ids
239-
240-
allocated_key_pbs = connection.allocate_ids(incomplete_key.dataset_id,
241-
incomplete_key_pbs)
242-
allocated_ids = [allocated_key_pb.path_element[-1].id
243-
for allocated_key_pb in allocated_key_pbs]
244-
return [incomplete_key.completed_key(allocated_id)
245-
for allocated_id in allocated_ids]

gcloud/datastore/api.py

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# Copyright 2014 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Methods for interacting with Google Cloud Datastore.
16+
17+
Allows interacting with the datastore via user-friendly Key, Entity and
18+
Query objects rather than via protobufs.
19+
"""
20+
21+
from gcloud.datastore import _implicit_environ
22+
from gcloud.datastore import helpers
23+
24+
25+
def _require_dataset_id(dataset_id=None):
26+
"""Infer a dataset ID from the environment, if not passed explicitly.
27+
28+
:type dataset_id: string
29+
:param dataset_id: Optional.
30+
31+
:rtype: string
32+
:returns: A dataset ID based on the current environment.
33+
:raises: :class:`EnvironmentError` if ``dataset_id`` is ``None``,
34+
and cannot be inferred from the environment.
35+
"""
36+
if dataset_id is None:
37+
if _implicit_environ.DATASET_ID is None:
38+
raise EnvironmentError('Dataset ID could not be inferred.')
39+
dataset_id = _implicit_environ.DATASET_ID
40+
return dataset_id
41+
42+
43+
def _require_connection(connection=None):
44+
"""Infer a connection from the environment, if not passed explicitly.
45+
46+
:type connection: :class:`gcloud.datastore.connection.Connection`
47+
:param connection: Optional.
48+
49+
:rtype: :class:`gcloud.datastore.connection.Connection`
50+
:returns: A connection based on the current environment.
51+
:raises: :class:`EnvironmentError` if ``connection`` is ``None``, and
52+
cannot be inferred from the environment.
53+
"""
54+
if connection is None:
55+
if _implicit_environ.CONNECTION is None:
56+
raise EnvironmentError('Connection could not be inferred.')
57+
connection = _implicit_environ.CONNECTION
58+
return connection
59+
60+
61+
def get_entities(keys, missing=None, deferred=None, connection=None):
62+
"""Retrieves entities, along with their attributes.
63+
64+
:type keys: list of :class:`gcloud.datastore.key.Key`
65+
:param keys: The name of the item to retrieve.
66+
67+
:type missing: an empty list or None.
68+
:param missing: If a list is passed, the key-only entities returned
69+
by the backend as "missing" will be copied into it.
70+
Use only as a keyword param.
71+
72+
:type deferred: an empty list or None.
73+
:param deferred: If a list is passed, the keys returned
74+
by the backend as "deferred" will be copied into it.
75+
Use only as a keyword param.
76+
77+
:type connection: :class:`gcloud.datastore.connection.Connection`
78+
:param connection: Optional. The connection used to connect to datastore.
79+
80+
:rtype: list of :class:`gcloud.datastore.entity.Entity`
81+
:returns: The requested entities.
82+
:raises: :class:`ValueError` if the key dataset IDs don't agree.
83+
"""
84+
if not keys:
85+
return []
86+
87+
connection = _require_connection(connection)
88+
dataset_id = keys[0].dataset_id
89+
# Rather than creating a list or set of all dataset IDs, we iterate
90+
# and check. We could allow the backend to check this for us if IDs
91+
# with no prefix worked (GoogleCloudPlatform/google-cloud-datastore#59)
92+
# or if we made sure that a prefix s~ or e~ was on each key.
93+
for key in keys[1:]:
94+
if key.dataset_id != dataset_id:
95+
raise ValueError('All keys in get_entities must be from the '
96+
'same dataset.')
97+
98+
entity_pbs = connection.lookup(
99+
dataset_id=dataset_id,
100+
key_pbs=[k.to_protobuf() for k in keys],
101+
missing=missing, deferred=deferred,
102+
)
103+
104+
if missing is not None:
105+
missing[:] = [
106+
helpers.entity_from_protobuf(missed_pb)
107+
for missed_pb in missing]
108+
109+
if deferred is not None:
110+
deferred[:] = [
111+
helpers.key_from_protobuf(deferred_pb)
112+
for deferred_pb in deferred]
113+
114+
entities = []
115+
for entity_pb in entity_pbs:
116+
entities.append(helpers.entity_from_protobuf(entity_pb))
117+
118+
return entities
119+
120+
121+
def allocate_ids(incomplete_key, num_ids, connection=None):
122+
"""Allocates a list of IDs from a partial key.
123+
124+
:type incomplete_key: A :class:`gcloud.datastore.key.Key`
125+
:param incomplete_key: Partial key to use as base for allocated IDs.
126+
127+
:type num_ids: integer
128+
:param num_ids: The number of IDs to allocate.
129+
130+
:type connection: :class:`gcloud.datastore.connection.Connection`
131+
:param connection: Optional. The connection used to connect to datastore.
132+
133+
:rtype: list of :class:`gcloud.datastore.key.Key`
134+
:returns: The (complete) keys allocated with ``incomplete_key`` as root.
135+
:raises: :class:`ValueError` if ``incomplete_key`` is not a partial key.
136+
"""
137+
connection = _require_connection(connection)
138+
139+
if not incomplete_key.is_partial:
140+
raise ValueError(('Key is not partial.', incomplete_key))
141+
142+
incomplete_key_pb = incomplete_key.to_protobuf()
143+
incomplete_key_pbs = [incomplete_key_pb] * num_ids
144+
145+
allocated_key_pbs = connection.allocate_ids(incomplete_key.dataset_id,
146+
incomplete_key_pbs)
147+
allocated_ids = [allocated_key_pb.path_element[-1].id
148+
for allocated_key_pb in allocated_key_pbs]
149+
return [incomplete_key.completed_key(allocated_id)
150+
for allocated_id in allocated_ids]

gcloud/datastore/key.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,12 @@ def get(self, connection=None):
227227
:returns: The requested entity, or ``None`` if there was no
228228
match found.
229229
"""
230-
# Temporary import hack until Dataset is removed in #477.
231-
from gcloud import datastore
230+
# Temporary cylic import, needs to be removed.
231+
from gcloud.datastore import api
232232

233233
# We allow partial keys to attempt a get, the backend will fail.
234234
connection = connection or _implicit_environ.CONNECTION
235-
entities = datastore.get_entities([self], connection=connection)
235+
entities = api.get_entities([self], connection=connection)
236236

237237
if entities:
238238
result = entities[0]

0 commit comments

Comments
 (0)