Skip to content

Commit

Permalink
Support indexing of ListOf fields in Riak models.
Browse files Browse the repository at this point in the history
  • Loading branch information
jerith committed Oct 23, 2014
1 parent cd01344 commit 321d893
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 6 deletions.
25 changes: 19 additions & 6 deletions vumi/persist/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,31 +509,44 @@ def get_list_item(self, modelobj, list_idx):
raw_item = raw_list[list_idx]
return self.field.subfield_from_riak(raw_item)

def _set_model_data(self, modelobj, raw_values):
modelobj._riak_object.set_data_field(self.key, raw_values)
if self.index_name is not None:
field_list = modelobj._riak_object.get_data().get(self.key, [])
modelobj._riak_object.remove_index(self.index_name)
for value in field_list:
self._add_index(modelobj, value)

def set_value(self, modelobj, values):
map(self.field.validate_subfield, values)
raw_values = [self.field.subfield_to_riak(value) for value in values]
self._set_model_data(modelobj, raw_values)

def set_list_item(self, modelobj, list_idx, value):
self.field.validate_subfield(value)
raw_value = self.field.subfield_to_riak(value)
field_list = modelobj._riak_object.get_data().get(self.key, [])
field_list[list_idx] = raw_value
modelobj._riak_object.set_data_field(self.key, field_list)
self._set_model_data(modelobj, field_list)

def del_list_item(self, modelobj, list_idx):
field_list = modelobj._riak_object.get_data().get(self.key, [])
del field_list[list_idx]
modelobj._riak_object.set_data_field(self.key, field_list)
self._set_model_data(modelobj, field_list)

def append_list_item(self, modelobj, value):
self.field.validate_subfield(value)
raw_value = self.field.subfield_to_riak(value)
field_list = modelobj._riak_object.get_data().get(self.key, [])
field_list.append(raw_value)
modelobj._riak_object.set_data_field(self.key, field_list)
self._set_model_data(modelobj, field_list)

def extend_list(self, modelobj, values):
map(self.field.validate_subfield, values)
raw_values = [self.field.subfield_to_riak(value) for value in values]
field_list = modelobj._riak_object.get_data().get(self.key, [])
field_list.extend(raw_values)
modelobj._riak_object.set_data_field(self.key, field_list)
self._set_model_data(modelobj, field_list)

def iter_list(self, modelobj):
raw_list = modelobj._riak_object.get_data().get(self.key, [])
Expand Down Expand Up @@ -573,8 +586,8 @@ class ListOf(FieldWithSubtype):
"""
descriptor_class = ListOfDescriptor

def __init__(self, field_type=None):
super(ListOf, self).__init__(field_type=field_type, default=list)
def __init__(self, field_type=None, **kw):
super(ListOf, self).__init__(field_type=field_type, default=list, **kw)

def custom_validate(self, valuelist):
if not isinstance(valuelist, list):
Expand Down
38 changes: 38 additions & 0 deletions vumi/persist/tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class ListOfModel(Model):
items = ListOf(Integer())


class IndexedListOfModel(Model):
items = ListOf(Integer(), index=True)


class ForeignKeyModel(Model):
simple = ForeignKey(SimpleModel, null=True)

Expand Down Expand Up @@ -795,6 +799,40 @@ def test_listof_fields(self):
l2.items = [1]
self.assertEqual(list(l2.items), [1])

@Manager.calls_manager
def test_listof_fields_indexes(self):
list_model = self.manager.proxy(IndexedListOfModel)
l1 = list_model("foo")
l1.items.append(1)
l1.items.append(2)
yield l1.save()

assert_indexes = lambda mdl, values: self.assertEqual(
mdl._riak_object.get_indexes(),
set(('items_bin', str(v)) for v in values))

l2 = yield list_model.load("foo")
self.assertEqual(l2.items[0], 1)
self.assertEqual(l2.items[1], 2)
self.assertEqual(list(l2.items), [1, 2])
assert_indexes(l2, [1, 2])

l2.items[0] = 5
self.assertEqual(l2.items[0], 5)
assert_indexes(l2, [2, 5])

del l2.items[0]
self.assertEqual(list(l2.items), [2])
assert_indexes(l2, [2])

l2.items.extend([3, 4, 5])
self.assertEqual(list(l2.items), [2, 3, 4, 5])
assert_indexes(l2, [2, 3, 4, 5])

l2.items = [1]
self.assertEqual(list(l2.items), [1])
assert_indexes(l2, [1])

def test_listof_setting(self):
list_model = self.manager.proxy(ListOfModel)
l1 = list_model("foo")
Expand Down

0 comments on commit 321d893

Please sign in to comment.