diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2006-06-16 19:21:57 +0000 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2006-06-16 19:21:57 +0000 |
commit | 26e348634444bf4142b42ad484d89161634c344d (patch) | |
tree | 64b00a5b891b2c5adc6dbe8bc7aa4c1705d46205 /lib/sqlalchemy/attributes.py | |
parent | bcc4f63a0790cd95a32dd334230656867e9a6b9e (diff) | |
download | sqlalchemy-26e348634444bf4142b42ad484d89161634c344d.tar.gz |
more intelligent "removal" of list items when a list attribute is replaced, doesnt actually "remove" the items from teh replaced list just marks them as "removed" from the parent object for history purposes
Diffstat (limited to 'lib/sqlalchemy/attributes.py')
-rw-r--r-- | lib/sqlalchemy/attributes.py | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/lib/sqlalchemy/attributes.py b/lib/sqlalchemy/attributes.py index 60cbecec1..b7ad5249b 100644 --- a/lib/sqlalchemy/attributes.py +++ b/lib/sqlalchemy/attributes.py @@ -179,9 +179,9 @@ class InstrumentedAttribute(object): for ext in self.extensions: ext.set(event or self, obj, value, old) else: - # set the deleted event for the old item - old[:] = [] - + # mark all the old elements as detached from the parent + old.list_replaced() + def delete(self, event, obj): """deletes a value from the given object. 'event' is the InstrumentedAttribute that initiated the delete() operation and is used to control the depth of a circular delete @@ -256,16 +256,39 @@ class InstrumentedList(object): self.key = attr.key self.data = data or attr._blank_list() - # adapt to lists or sets automatically + # adapt to lists or sets + # TODO: make three subclasses of InstrumentedList that come off from a + # metaclass, based on the type of data sent in if hasattr(self.data, 'append'): self._data_appender = self.data.append + self._clear_data = self._clear_list elif hasattr(self.data, 'add'): self._data_appender = self.data.add + self._clear_data = self._clear_set + if isinstance(self.data, dict): + self._clear_data = self._clear_dict if init: for x in self.data: self.__setrecord(x) - + + def list_replaced(self): + """fires off delete event handlers for each item in the list but + doesnt affect the original data list""" + [self.__delrecord(x) for x in self.data] + + def clear(self): + """clears all items in this InstrumentedList and fires off delete event handlers for each item""" + self._clear_data() + def _clear_dict(self): + [self.__delrecord(x) for x in self.data.values()] + self.data.clear() + def _clear_set(self): + [self.__delrecord(x) for x in self.data] + self.data.clear() + def _clear_list(self): + self[:] = [] + def __getstate__(self): """implemented to allow pickling, since __obj is a weakref.""" return {'key':self.key, 'obj':self.obj, 'data':self.data, 'attr':self.attr} @@ -326,11 +349,6 @@ class InstrumentedList(object): self.__setrecord(item) self._data_appender(item) - def clear(self): - if isinstance(self.data, dict): - self.data.clear() - else: - self.data[:] = self.attr._blank_list() def __getitem__(self, i): return self.data[i] |