From 57f92c0777d1fe3d48141b5b947f897b1e2ddc76 Mon Sep 17 00:00:00 2001 From: Danny Cosson Date: Sun, 9 Feb 2014 15:42:28 -0500 Subject: [PATCH] Adds ability to blind append and prepend to a list --- cqlengine/query.py | 3 +-- cqlengine/statements.py | 13 ++++++++++--- cqlengine/tests/query/test_updates.py | 23 +++++++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/cqlengine/query.py b/cqlengine/query.py index f226a70e..5f32a87c 100644 --- a/cqlengine/query.py +++ b/cqlengine/query.py @@ -681,9 +681,8 @@ class ModelQuerySet(AbstractQuerySet): if isinstance(col, Counter): # TODO: implement counter updates raise NotImplementedError - elif isinstance(col, BaseContainerColumn): + elif isinstance(col, (List, Set)): if isinstance(col, List): klass = ListUpdateClause - elif isinstance(col, Map): klass = MapUpdateClause elif isinstance(col, Set): klass = SetUpdateClause else: raise RuntimeError us.add_assignment_clause(klass( diff --git a/cqlengine/statements.py b/cqlengine/statements.py index 111574c1..d53e0cd0 100644 --- a/cqlengine/statements.py +++ b/cqlengine/statements.py @@ -215,8 +215,8 @@ class SetUpdateClause(ContainerUpdateClause): class ListUpdateClause(ContainerUpdateClause): """ updates a list collection """ - def __init__(self, field, value, previous=None, column=None): - super(ListUpdateClause, self).__init__(field, value, previous, column=column) + def __init__(self, field, value, operation=None, previous=None, column=None): + super(ListUpdateClause, self).__init__(field, value, operation, previous, column=column) self._append = None self._prepend = None @@ -261,6 +261,14 @@ class ListUpdateClause(ContainerUpdateClause): if self.value is None or self.value == self.previous: pass + elif self._operation == "append": + self._append = self.value + + elif self._operation == "prepend": + # self.value is a Quoter but we reverse self._prepend later as if + # it's a list, so we have to set it to the underlying list + self._prepend = self.value.value + elif self.previous is None: self._assignments = self.value @@ -269,7 +277,6 @@ class ListUpdateClause(ContainerUpdateClause): # rewrite the whole list self._assignments = self.value - elif len(self.previous) == 0: # if we're updating from an empty # list, do a complete insert diff --git a/cqlengine/tests/query/test_updates.py b/cqlengine/tests/query/test_updates.py index 65f8f572..1f62e8ce 100644 --- a/cqlengine/tests/query/test_updates.py +++ b/cqlengine/tests/query/test_updates.py @@ -14,6 +14,7 @@ class TestQueryUpdateModel(Model): count = columns.Integer(required=False) text = columns.Text(required=False, index=True) text_set = columns.Set(columns.Text, required=False) + text_list = columns.List(columns.Text, required=False) class QueryUpdateTests(BaseCassEngTestCase): @@ -159,3 +160,25 @@ class QueryUpdateTests(BaseCassEngTestCase): text_set__remove={'afsd'}) obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster) self.assertEqual(obj.text_set, {"foo"}) + + def test_list_append_updates(self): + partition = uuid4() + cluster = 1 + TestQueryUpdateModel.objects.create( + partition=partition, cluster=cluster, text_list=["foo"]) + TestQueryUpdateModel.objects( + partition=partition, cluster=cluster).update( + text_list__append=['bar']) + obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster) + self.assertEqual(obj.text_list, ["foo", "bar"]) + + def test_list_prepend_updates(self): + partition = uuid4() + cluster = 1 + TestQueryUpdateModel.objects.create( + partition=partition, cluster=cluster, text_list=["foo"]) + TestQueryUpdateModel.objects( + partition=partition, cluster=cluster).update( + text_list__prepend=['bar']) + obj = TestQueryUpdateModel.objects.get(partition=partition, cluster=cluster) + self.assertEqual(obj.text_list, ["bar", "foo"])