[SQL-CVS] r1178 - SQLObject/trunk/sqlobject
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
|
From: <sub...@co...> - 2005-10-31 17:46:13
|
Author: ianb
Date: 2005-10-31 17:45:56 +0000 (Mon, 31 Oct 2005)
New Revision: 1178
Modified:
SQLObject/trunk/sqlobject/events.py
Log:
Some changed names for the event signals, and a few signature changes. Also some routines using PyDispatcher for handling subclassing (and listening to classes and their subclasses); actual use of these events will come about in a later commit
Modified: SQLObject/trunk/sqlobject/events.py
===================================================================
--- SQLObject/trunk/sqlobject/events.py 2005-10-31 17:15:43 UTC (rev 1177)
+++ SQLObject/trunk/sqlobject/events.py 2005-10-31 17:45:56 UTC (rev 1178)
@@ -1,4 +1,18 @@
-class Event(object):
+from dispatch import dispatcher
+from weakref import ref
+
+
+subclassClones = {}
+
+def listen(receiver, soClass, signal, alsoSubclasses=True):
+ dispatcher.connect(receiver, signal=signal, sender=soClass)
+ weakSOClass = ref(soClass)
+ weakReceiver = ref(receiver)
+ subclassClones.setdefault(weakSOClass, []).append((weakReceiver, signal))
+
+send = dispatcher.send
+
+class Signal(object):
"""
Base event for all SQLObject events.
@@ -6,9 +20,9 @@
instance.
"""
-class ClassCreateEvent(Event):
+class ClassCreateSignal(Signal):
"""
- Event raised before class creation. The sender is the superclass
+ Signal raised before class creation. The sender is the superclass
(in case of multiple superclasses, the first superclass). The
arguments are ``(new_class_name, bases, new_attrs, post_funcs)``.
``new_attrs`` is a dictionary and may be modified (but
@@ -21,30 +35,41 @@
``(new_class)``.
"""
+def _makeSubclassConnections(new_class_name, bases, new_attrs, post_funcs):
+ post_funcs.append(_makeSubclassConnectionsPost)
+
+def _makeSubclassConnectionsPost(new_class):
+ for cls in new_class.__bases__:
+ for weakReceiver, signal in subclassClones.get(cls, []):
+ receiver = weakReceiver()
+ if not receiver:
+ continue
+ dispatcher.connect(receiver, signal=signal, sender=new_class)
+
+dispatcher.connect(_makeSubclassConnections, signal=ClassCreateSignal)
+
# @@: Should there be a class reload event? This would allow modules
# to be reloaded, possibly. Or it could even be folded into
-# ClassCreateEvent, since anything that listens to that needs to pay
+# ClassCreateSignal, since anything that listens to that needs to pay
# attention to reloads (or else it is probably buggy).
-class InstanceCreateEvent(Event):
+class RowCreateSignal(Signal):
"""
Called before an instance is created, with the class as the
- sender. Called with the arguments ``(varargs, kwargs,
- post_funcs)``. Both ``kwargs`` and ``varargs`` may be usefully
- modified (``varargs`` is converted from a tuple to a list before
- calling). ``post_funcs`` is a list of callbacks, intended to have
+ sender. Called with the arguments ``(kwargs, post_funcs)``.
+ There may be a ``connection`` argument. ``kwargs``may be usefully
+ modified. ``post_funcs`` is a list of callbacks, intended to have
functions appended to it, and are called with the arguments
``(new_instance)``.
Note: this is not called when an instance is created from an
- existing database row. (@@: Show the name be RowCreateEvent, or
- RowInsertEvent?)
+ existing database row.
"""
# @@: An event for getting a row? But for each row, when doing a
# select? For .sync, .syncUpdate, .expire?
-class InstanceDestroyEvent(Event):
+class RowDestroySignal(Signal):
"""
Called before an instance is deleted. Sender is the instance's
class. Arguments are ``(instance)``. You cannot cancel the delete,
@@ -52,14 +77,13 @@
delete, but also cause an uncaught exception if not expected).
Note: this is not called when an instance is destroyed through
- garbage collection (@@: Should this be called RowDestroyEvent or
- RowDeleteEvent?)
+ garbage collection.
@@: Should this allow ``instance`` to be a primary key, so that a
row can be deleted without first fetching it?
"""
-class InstanceUpdateEvent(Event):
+class RowUpdateSignal(Signal):
"""
Called when an instance is updated through a call to ``.set()``.
The arguments are ``(instance, kwargs)``. ``kwargs`` can be
@@ -68,45 +92,57 @@
@@: Should this also catch single-column updates? Should this
only be run before updates go to the server? Should this be
- called RowUpdateEvent?
+ called RowUpdateSignal?
"""
-class AddColumnEvent(Event):
+class AddColumnSignal(Signal):
"""
Called when a column is added to a class, with arguments ``(cls,
- column_name, column_definition)``. This is called *after* the
- column has been added, and is called for each column after class
- creation.
+ connection, column_name, column_definition, changeSchema,
+ post_funcs)``. This is called *after* the column has been added,
+ and is called for each column after class creation.
+
+ post_funcs are called with ``(cls, so_column_obj)``
"""
-class DeleteColumnEvent(Event):
+class DeleteColumnSignal(Signal):
"""
Called when a column is removed from a class, with the arguments
- ``(cls, column_name, column_definition)``. Like
- ``AddColumnEvent`` this is called after the action has been
+ ``(cls, connection, column_name, so_column_obj, post_funcs)``.
+ Like ``AddColumnSignal`` this is called after the action has been
performed, and is called for subclassing (when a column is
implicitly removed by setting it to ``None``).
+
+ post_funcs are called with ``(cls, so_column_obj)``
"""
-# @@: Events for indexes and joins? These are mostly event consumers,
+# @@: Signals for indexes and joins? These are mostly event consumers,
# though.
-class CreateTableEvent(Event):
+class CreateTableSignal(Signal):
"""
Called when a table is created. If ``ifNotExists==True`` and the
table exists, this event is not called.
- Called with ``(cls, connection, post_funcs)``. ``post_funcs``
+ Called with ``(cls, connection, extra_sql, post_funcs)``.
+ ``extra_sql`` is a list (which can be appended to) of extra SQL
+ statements to be run after the table is created. ``post_funcs``
functions are called with ``(cls, connection)`` after the table
- has been created.
+ has been created. Those functions are *not* called simply when
+ constructing the SQL.
"""
-class DropTableEvent(Event):
+class DropTableSignal(Signal):
"""
Called when a table is dropped. If ``ifExists==True`` and the
table doesn't exist, this event is not called.
- Called with ``(cls, connection, post_funcs)``. ``post_funcs``
- functions are called with ``(cls, connection)`` after the table
- has been dropped.
+ Called with ``(cls, connection, extra_sql, post_funcs)``.
+ ``post_funcs`` functions are called with ``(cls, connection)``
+ after the table has been dropped.
"""
+
+__all__ = ['listen', 'send']
+for name, value in globals().items():
+ if isinstance(value, type) and issubclass(value, Signal):
+ __all__.append('value')
|