[schema hooks] properly check for changes of schema properties avoid useless costly operation (such as full-text reindexing all entities of a type). Refactor inlined handling and fix a bug trying to reindex a final entity type on the way.
--- a/entities/schemaobjs.py Tue Mar 09 10:51:08 2010 +0100
+++ b/entities/schemaobjs.py Tue Mar 09 10:53:38 2010 +0100
@@ -56,30 +56,21 @@
return u'%s <<%s>>' % (self.dc_title(), ', '.join(stereotypes))
return self.dc_title()
- def inlined_changed(self, inlined):
- """check inlining is necessary and possible:
-
- * return False if nothing has changed
- * raise ValidationError if inlining is'nt possible
- * eventually return True
+ def check_inlined_allowed(self):
+ """check inlining is possible, raise ValidationError if not possible
"""
- rschema = self._cw.vreg.schema.rschema(self.name)
- if inlined == rschema.inlined:
- return False
- if inlined:
- # don't use the persistent schema, we may miss cardinality changes
- # in the same transaction
- for rdef in self.reverse_relation_type:
- card = rdef.cardinality[0]
- if not card in '?1':
- rtype = self.name
- stype = rdef.stype
- otype = rdef.otype
- msg = self._cw._("can't set inlined=%(inlined)s, "
- "%(stype)s %(rtype)s %(otype)s "
- "has cardinality=%(card)s")
- raise ValidationError(self.eid, {'inlined': msg % locals()})
- return True
+ # don't use the persistent schema, we may miss cardinality changes
+ # in the same transaction
+ for rdef in self.reverse_relation_type:
+ card = rdef.cardinality[0]
+ if not card in '?1':
+ rtype = self.name
+ stype = rdef.stype
+ otype = rdef.otype
+ msg = self._cw._("can't set inlined=%(inlined)s, "
+ "%(stype)s %(rtype)s %(otype)s "
+ "has cardinality=%(card)s")
+ raise ValidationError(self.eid, {'inlined': msg % locals()})
def db_key_name(self):
"""XXX goa specific"""
--- a/hooks/syncschema.py Tue Mar 09 10:51:08 2010 +0100
+++ b/hooks/syncschema.py Tue Mar 09 10:53:38 2010 +0100
@@ -226,25 +226,26 @@
class SourceDbCWRTypeUpdate(hook.Operation):
"""actually update some properties of a relation definition"""
- rschema = entity = None # make pylint happy
+ rschema = entity = values = None # make pylint happy
def precommit_event(self):
+ rschema = self.rschema
+ if rschema.final:
+ return
session = self.session
- rschema = self.rschema
- entity = self.entity
- if 'fulltext_container' in entity.edited_attributes:
+ if 'fulltext_container' in self.values:
ftiupdates = session.transaction_data.setdefault(
'fti_update_etypes', set())
for subjtype, objtype in rschema.rdefs:
ftiupdates.add(subjtype)
ftiupdates.add(objtype)
UpdateFTIndexOp(session)
- if rschema.final or not 'inlined' in entity.edited_attributes:
+ if not 'inlined' in self.values:
return # nothing to do
- inlined = entity.inlined
+ inlined = self.values['inlined']
# check in-lining is necessary / possible
- if not entity.inlined_changed(inlined):
- return # nothing to do
+ if inlined:
+ self.entity.check_inlined_allowed()
# inlined changed, make necessary physical changes!
sqlexec = self.session.system_sql
rtype = rschema.type
@@ -925,26 +926,22 @@
class BeforeUpdateCWRTypeHook(DelCWRTypeHook):
"""check name change, handle final"""
- __regid__ = 'checkupdatecwrtype'
+ __regid__ = 'syncupdatecwrtype'
events = ('before_update_entity',)
def __call__(self):
- check_valid_changes(self._cw, self.entity)
-
-
-class AfterUpdateCWRTypeHook(DelCWRTypeHook):
- __regid__ = 'syncupdatecwrtype'
- events = ('after_update_entity',)
-
- def __call__(self):
entity = self.entity
+ check_valid_changes(self._cw, entity)
newvalues = {}
for prop in ('symmetric', 'inlined', 'fulltext_container'):
if prop in entity.edited_attributes:
- newvalues[prop] = entity[prop]
+ old, new = hook.entity_oldnewvalue(entity, prop)
+ if old != new:
+ newvalues[prop] = entity[prop]
if newvalues:
rschema = self._cw.vreg.schema.rschema(entity.name)
- SourceDbCWRTypeUpdate(self._cw, rschema=rschema, entity=entity)
+ SourceDbCWRTypeUpdate(self._cw, rschema=rschema, entity=entity,
+ values=newvalues)
MemSchemaCWRTypeUpdate(self._cw, rschema=rschema, values=newvalues)
@@ -1024,8 +1021,8 @@
class AfterUpdateCWRDefHook(SyncSchemaHook):
__regid__ = 'syncaddcwattribute'
__select__ = SyncSchemaHook.__select__ & implements('CWAttribute',
- 'CWRelation')
- events = ('after_update_entity',)
+ 'CWRelation')
+ events = ('before_update_entity',)
def __call__(self):
entity = self.entity
@@ -1040,7 +1037,9 @@
if prop == 'order':
prop = 'ordernum'
if prop in entity.edited_attributes:
- newvalues[prop] = entity[prop]
+ old, new = hook.entity_oldnewvalue(entity, prop)
+ if old != new:
+ newvalues[prop] = entity[prop]
if newvalues:
subjtype = entity.stype.name
MemSchemaRDefUpdate(self._cw, kobj=(subjtype, desttype),