From 449b15d4ad0f678fbc46a1168fd57f2cffcd4d6a Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Fri, 17 Oct 2014 10:47:11 -0400 Subject: [PATCH 1/6] Add assertion that query cursor is copied during '_clone'. --- gcloud/datastore/test_query.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gcloud/datastore/test_query.py b/gcloud/datastore/test_query.py index 219b63c1e28cb..6d0e42aab236c 100644 --- a/gcloud/datastore/test_query.py +++ b/gcloud/datastore/test_query.py @@ -33,14 +33,17 @@ def test__clone(self): _DATASET = 'DATASET' _KIND = 'KIND' + _CURSOR = 'DEADBEEF' dataset = Dataset(_DATASET) query = self._makeOne(_KIND, dataset) + query._cursor = _CURSOR clone = query._clone() self.assertFalse(clone is query) self.assertTrue(isinstance(clone, self._getTargetClass())) self.assertTrue(clone.dataset() is dataset) kq_pb, = list(clone.kind()) self.assertEqual(kq_pb.name, _KIND) + self.assertEqual(clone._cursor, _CURSOR) def test_to_protobuf_empty(self): query = self._makeOne() From 137bfe27fb567ef513bd727a58614da8486646f2 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Fri, 17 Oct 2014 10:48:21 -0400 Subject: [PATCH 2/6] Rework Query._clone to avoid spurious copy of dataset. Fixes #171. --- gcloud/datastore/query.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gcloud/datastore/query.py b/gcloud/datastore/query.py index 46b2dedb780fd..8439d0b458697 100644 --- a/gcloud/datastore/query.py +++ b/gcloud/datastore/query.py @@ -67,8 +67,9 @@ def _clone(self): :rtype: :class:`gcloud.datastore.query.Query` :returns: a copy of 'self'. """ - clone = copy.deepcopy(self) - clone._dataset = self._dataset # Shallow copy the dataset. + clone = self.__class__(dataset=self._dataset) + clone._pb.CopyFrom(self._pb) + clone._cursor = self._cursor return clone def to_protobuf(self): From ef535364d257714fe37b1cb8e1e0ef278493cc18 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Fri, 17 Oct 2014 12:03:43 -0400 Subject: [PATCH 3/6] Update docstring for 'Connection.save_entity'. Indicate that upsert clears existing properties before applying those passed to the API. Fixes #167. --- gcloud/datastore/connection.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gcloud/datastore/connection.py b/gcloud/datastore/connection.py index cf52e5b51eafc..74b2626750733 100644 --- a/gcloud/datastore/connection.py +++ b/gcloud/datastore/connection.py @@ -338,6 +338,10 @@ def commit(self, dataset_id, mutation_pb): def save_entity(self, dataset_id, key_pb, properties): """Save an entity to the Cloud Datastore with the provided properties. + .. note:: + Any existing properties for the entity will be cleared before + applying those passed in 'properties'. + :type dataset_id: string :param dataset_id: The dataset in which to save the entity. From 7eae97f5f6e6556f69d8d74e8310bfd2df3e0ed5 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Fri, 17 Oct 2014 13:06:43 -0400 Subject: [PATCH 4/6] Unused import. Incorporate feedback from @dhermes. --- gcloud/datastore/query.py | 1 - 1 file changed, 1 deletion(-) diff --git a/gcloud/datastore/query.py b/gcloud/datastore/query.py index 8439d0b458697..bc829ccfa69ff 100644 --- a/gcloud/datastore/query.py +++ b/gcloud/datastore/query.py @@ -1,7 +1,6 @@ """Create / interact with gcloud datastore queries.""" import base64 -import copy from gcloud.datastore import datastore_v1_pb2 as datastore_pb from gcloud.datastore import _helpers From 8e40313abf0bb1b0d07dd35baf134c7049b29ddd Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Fri, 17 Oct 2014 13:17:21 -0400 Subject: [PATCH 5/6] Update doctstrings for 'Entity.save' and 'Connection.save_entity'. Reinforce that previously-stored properties which don't have values set in the current entity instance will be removed. --- gcloud/datastore/connection.py | 5 +++-- gcloud/datastore/entity.py | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/gcloud/datastore/connection.py b/gcloud/datastore/connection.py index 74b2626750733..f11c528b27276 100644 --- a/gcloud/datastore/connection.py +++ b/gcloud/datastore/connection.py @@ -339,8 +339,9 @@ def save_entity(self, dataset_id, key_pb, properties): """Save an entity to the Cloud Datastore with the provided properties. .. note:: - Any existing properties for the entity will be cleared before - applying those passed in 'properties'. + Any existing properties for the entity identified by 'key_pb' + will be replaced by those passed in 'properties'; properties + not passed in 'properties' no longer be set for the entity. :type dataset_id: string :param dataset_id: The dataset in which to save the entity. diff --git a/gcloud/datastore/entity.py b/gcloud/datastore/entity.py index 59948084fa7a5..bbce5012f4442 100644 --- a/gcloud/datastore/entity.py +++ b/gcloud/datastore/entity.py @@ -187,6 +187,12 @@ def reload(self): def save(self): """Save the entity in the Cloud Datastore. + .. note:: + Any existing properties for the entity will be replaced by those + currently set on this instance. Already-stored properties which do + not correspond to keys set on this instance will be removed from + the datastore. + :rtype: :class:`gcloud.datastore.entity.Entity` :returns: The entity with a possibly updated Key. """ From 961e6954f8666a8a9cb01a1534e039fb9531169d Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Fri, 17 Oct 2014 13:20:49 -0400 Subject: [PATCH 6/6] Clarify docstring for 'Entity._must_key'. Incorporates feedback from @dhermes. --- gcloud/datastore/entity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud/datastore/entity.py b/gcloud/datastore/entity.py index 59db2e3641203..4f8b877792a8e 100644 --- a/gcloud/datastore/entity.py +++ b/gcloud/datastore/entity.py @@ -168,7 +168,7 @@ def from_protobuf(cls, pb, dataset=None): # pylint: disable=invalid-name @property def _must_key(self): - """Return our key. + """Return our key, or raise NoKey if not set. :rtype: :class:`gcloud.datastore.key.Key`. :returns: our key