def attribute_registry(self):
return self.manager
def property(self, key, uselist, **kwargs):
+ print "NEW SMART PROP", key, repr(kwargs)
def set_prop(obj, value):
if uselist:
self.attribute_registry().set_list_attribute(obj, key, value, **kwargs)
return m.attribute_history(self.obj)[self.key]
else:
if not self.obj.__dict__.has_key(self.key) or len(self.obj.__dict__[self.key]) == 0:
+ if passive:
+ print "HI YES"
+ return None
+ print "doing CALLABLE for key", self.key
value = self.callable_()
else:
value = None
+ print "WHATEVER THING", self.key
p = self.manager.create_list(self.obj, self.key, value, **self.kwargs)
self.manager.attribute_history(self.obj)[self.key] = p
self.manager = None
def set_callable(self, obj, key, func, uselist, **kwargs):
self.attribute_history(obj)[key] = CallableProp(self, func, obj, key, uselist, **kwargs)
+
+ def create_callable(self, obj, key, func, uselist, **kwargs):
+ return CallableProp(self, func, obj, key, uselist, **kwargs)
def delete_list_attribute(self, obj, key, **kwargs):
pass
def remove(self, obj):
pass
- def get_history(self, obj, key, **kwargs):
+ def get_history(self, obj, key, create_prop = None, **kwargs):
try:
return self.attribute_history(obj)[key].gethistory(**kwargs)
except KeyError, e:
- p = PropHistory(obj, key, **kwargs)
- self.attribute_history(obj)[key] = p
- return p
+ if create_prop is not None:
+ p = self.create_callable(obj, key, create_prop(obj), uselist=False, **kwargs)
+ self.attribute_history(obj)[key] = p
+ return p.gethistory(**kwargs)
+ else:
+ p = PropHistory(obj, key, **kwargs)
+ self.attribute_history(obj)[key] = p
+ return p
- def get_list_history(self, obj, key, passive = False, **kwargs):
+ def get_list_history(self, obj, key, passive = False, create_prop = None, **kwargs):
try:
return self.attribute_history(obj)[key].gethistory(passive)
except KeyError, e:
+ print "GETLISTHISTORY", key, repr(passive), repr(create_prop)
# TODO: when an callable is re-set on an existing list element
- list_ = obj.__dict__.get(key, None)
- p = self.create_list(obj, key, list_, **kwargs)
- self.attribute_history(obj)[key] = p
- return p
+ if create_prop is not None:
+ p = self.create_callable(obj, key, create_prop(obj), uselist=True, **kwargs)
+ self.attribute_history(obj)[key] = p
+ return p.gethistory(passive)
+ else:
+ list_ = obj.__dict__.get(key, None)
+ p = self.create_list(obj, key, list_, **kwargs)
+ self.attribute_history(obj)[key] = p
+ return p
def attribute_history(self, obj):
try:
if not self.props.has_key(key):
self.props[key] = prop._copy()
- if not hasattr(self.class_, '_mapper') or self.is_primary or not _mappers.has_key(self.class_._mapper):
+ if not hasattr(self.class_, '_mapper') or self.is_primary or not _mappers.has_key(self.class_._mapper) or (inherits is not None and inherits._is_primary_mapper()):
self._init_class()
engines = property(lambda s: [t.engine for t in s.tables])
def hash_key(self):
return self.hashkey
+ def _is_primary_mapper(self):
+# return True
+ return getattr(self.class_, '_mapper') == self.hashkey
+
def _init_class(self):
"""sets up our classes' overridden __init__ method, this mappers hash key as its
'_mapper' property, and our columns as its 'c' property. if the class already had a
def init(self, key, parent):
self.key = key
# establish a SmartProperty property manager on the object for this key
- if not hasattr(parent.class_, key):
+ if parent._is_primary_mapper():
#print "regiser col on class %s key %s" % (parent.class_.__name__, key)
objectstore.uow().register_attribute(parent.class_, key, uselist = False)
self._compile_synchronizers()
- if not hasattr(parent.class_, key):
+ #if not hasattr(parent.class_, key):
#print "regiser list col on class %s key %s" % (parent.class_.__name__, key)
- objectstore.uow().register_attribute(parent.class_, key, uselist = self.uselist, deleteremoved = self.private)
-
+ if parent._is_primary_mapper():
+ self._set_class_attribute(parent.class_, key)
+ #objectstore.uow().register_attribute(parent.class_, key, uselist = self.uselist, deleteremoved = self.private)
+
+ def _set_class_attribute(self, class_, key):
+ print "SET NORMAL CA", key
+ objectstore.uow().register_attribute(class_, key, uselist = self.uselist, deleteremoved = self.private)
+
def _get_direction(self):
if self.parent.primarytable is self.target:
if self.foreignkey.primary_key:
return
if self.uselist:
+ print repr(obj), "deleted, getting listm, right now its", repr(obj.__dict__.get(self.key, None))
childlist = uow.attributes.get_list_history(obj, self.key, passive = False)
+ print "and its", repr(childlist)
else:
childlist = uow.attributes.get_history(obj, self.key)
for child in childlist.deleted_items() + childlist.unchanged_items():
uowcommit.register_deleted_list(childlist)
else:
for obj in deplist:
+ #print "PROCESS:", repr(obj)
if self.direction == PropertyLoader.RIGHT:
uowcommit.register_object(obj)
- childlist = getlist(obj)
+ childlist = getlist(obj, passive=True)
if childlist is None: continue
uowcommit.register_saved_list(childlist)
for child in childlist.added_items():
+ #print "parent", repr(obj), "child", repr(child), "EOF"
self._synchronize(obj, child, None, False)
if self.direction == PropertyLoader.LEFT:
uowcommit.register_object(child)
PropertyLoader.init(self, key, parent)
(self.lazywhere, self.lazybinds) = create_lazy_clause(self.parent.table, self.primaryjoin, self.secondaryjoin, self.foreignkey)
- def execute(self, instance, row, identitykey, imap, isnew):
- if isnew:
- def lazyload():
- params = {}
- for key in self.lazybinds.keys():
- params[key] = row[key]
+ def _set_class_attribute(self, class_, key):
+ print "SET DYNAMIC CA,", key
+ objectstore.uow().register_attribute(class_, key, uselist = self.uselist, deleteremoved = self.private, create_prop=lambda i: self.setup_loader(i))
+
+ def setup_loader(self, instance):
+ def lazyload():
+ params = {}
+ allparams = True
+ #print "setting up loader, lazywhere", str(self.lazywhere)
+ for col, bind in self.lazybinds.iteritems():
+ if self.direction == PropertyLoader.RIGHT:
+ params[bind.key] = self.mapper._getattrbycolumn(instance, col)
+ #print "getting attr", col.table.name + "." + col.key, "off instance", repr(instance), "and its", params[bind.key]
+ else:
+ params[bind.key] = self.parent._getattrbycolumn(instance, col)
+ if params[bind.key] is None:
+ allparams = False
+ break
+ if allparams:
if self.secondary is not None:
order_by = [self.secondary.rowid_column]
else:
order_by = []
result = self.mapper.select(self.lazywhere, order_by=order_by,**params)
- if self.uselist:
- return result
+ else:
+ result = []
+ if self.uselist:
+ return result
+ else:
+ if len(result):
+ return result[0]
else:
- if len(result):
- return result[0]
- else:
- return None
- objectstore.uow().register_callable(instance, self.key, lazyload, uselist=self.uselist, deleteremoved = self.private)
+ return None
+ return lazyload
+# objectstore.uow().register_callable(instance, self.key, lazyload, uselist=self.uselist, deleteremoved = self.private)
+
+ def execute(self, instance, row, identitykey, imap, isnew):
+ if isnew:
+ return
+ # lazyload = self.setup_loader(instance)
+ # objectstore.uow().register_callable(instance, self.key, lazyload, uselist=self.uselist, deleteremoved = self.private)
+ # self.setup_loader(instance)
def create_lazy_clause(table, primaryjoin, secondaryjoin, foreignkey):
binds = {}
def visit_binary(binary):
circular = binary.left.table is binary.right.table
if isinstance(binary.left, schema.Column) and ((not circular and binary.left.table is table) or foreignkey is binary.right):
- binary.left = binds.setdefault(table.name + "_" + binary.left.name,
+# binary.left = binds.setdefault(table.name + "_" + binary.left.name,
+ binary.left = binds.setdefault(binary.left,
sql.BindParamClause(table.name + "_" + binary.left.name, None, shortname = binary.left.name))
binary.swap()
if isinstance(binary.right, schema.Column) and ((not circular and binary.right.table is table) or foreignkey is binary.left):
- binary.right = binds.setdefault(table.name + "_" + binary.right.name,
+# binary.right = binds.setdefault(table.name + "_" + binary.right.name,
+ binary.right = binds.setdefault(binary.right,
sql.BindParamClause(table.name + "_" + binary.right.name, None, shortname = binary.right.name))
if secondaryjoin is not None: