--- a/.hgtags Tue Apr 01 14:46:55 2014 +0200
+++ b/.hgtags Tue Apr 01 18:09:46 2014 +0200
@@ -326,6 +326,9 @@
09b4ebb9b0f179009491410c07cd013a60258fc6 cubicweb-version-3.17.13
09b4ebb9b0f179009491410c07cd013a60258fc6 cubicweb-debian-version-3.17.13-1
09b4ebb9b0f179009491410c07cd013a60258fc6 cubicweb-centos-version-3.17.13-1
+fa00fc251d57f61e619d9c905502745fae21c58c cubicweb-centos-version-3.17.14-1
+fa00fc251d57f61e619d9c905502745fae21c58c cubicweb-version-3.17.14
+fa00fc251d57f61e619d9c905502745fae21c58c cubicweb-debian-version-3.17.14-1
db37bf35a1474843ded0a537f9cb4838f4a78cda cubicweb-version-3.18.0
db37bf35a1474843ded0a537f9cb4838f4a78cda cubicweb-debian-version-3.18.0-1
db37bf35a1474843ded0a537f9cb4838f4a78cda cubicweb-centos-version-3.18.0-1
--- a/debian/changelog Tue Apr 01 14:46:55 2014 +0200
+++ b/debian/changelog Tue Apr 01 18:09:46 2014 +0200
@@ -28,6 +28,12 @@
-- Julien Cristau <julien.cristau@logilab.fr> Fri, 10 Jan 2014 17:14:18 +0100
+cubicweb (3.17.14-1) unstable; urgency=low
+
+ * new upstream release
+
+ -- Aurelien Campeas <aurelien.campeas@logilab.fr> Wed, 05 Mar 2014 15:48:38 +0100
+
cubicweb (3.17.13-1) unstable; urgency=low
* new upstream release
--- a/devtools/__init__.py Tue Apr 01 14:46:55 2014 +0200
+++ b/devtools/__init__.py Tue Apr 01 18:09:46 2014 +0200
@@ -108,6 +108,7 @@
repo._needs_refresh = True
repo._has_started = False
+
def turn_repo_on(repo):
"""Idea: this is less costly than a full re-creation of the repo object.
on:
@@ -820,7 +821,22 @@
# XXX a class method on Test ?
+
+_CONFIG = None
def get_test_db_handler(config):
+ global _CONFIG
+ if _CONFIG is not None and config is not _CONFIG:
+ from logilab.common.modutils import cleanup_sys_modules
+ # cleanup all dynamically loaded modules and everything in the instance
+ # directory
+ apphome = _CONFIG.apphome
+ if apphome: # may be unset in tests
+ cleanup_sys_modules([apphome])
+ # also cleanup sys.path
+ if apphome in sys.path:
+ sys.path.remove(apphome)
+ _CONFIG = config
+ config.adjust_sys_path()
handler = HCACHE.get(config)
if handler is not None:
return handler
--- a/hooks/syncschema.py Tue Apr 01 14:46:55 2014 +0200
+++ b/hooks/syncschema.py Tue Apr 01 18:09:46 2014 +0200
@@ -650,7 +650,11 @@
rdef = self.rdef
# in-place modification of in-memory schema first
_set_modifiable_constraints(rdef)
- rdef.constraints.remove(self.oldcstr)
+ if self.oldcstr in rdef.constraints:
+ rdef.constraints.remove(self.oldcstr)
+ else:
+ self.critical('constraint %s for rdef %s was missing or already removed',
+ self.oldcstr, rdef)
# then update database: alter the physical schema on size/unique
# constraint changes
syssource = session.cnxset.source('system')
@@ -1132,12 +1136,11 @@
if self._cw.deleted_in_transaction(self.eidfrom):
return
schema = self._cw.vreg.schema
- entity = self._cw.entity_from_eid(self.eidto)
rdef = schema.schema_by_eid(self.eidfrom)
try:
- cstr = rdef.constraint_by_type(entity.type)
- except IndexError:
- self._cw.critical('constraint type no more accessible')
+ cstr = rdef.constraint_by_eid(self.eidto)
+ except ValueError:
+ self._cw.critical('constraint no more accessible')
else:
CWConstraintDelOp(self._cw, rdef=rdef, oldcstr=cstr)
--- a/schema.py Tue Apr 01 14:46:55 2014 +0200
+++ b/schema.py Tue Apr 01 18:09:46 2014 +0200
@@ -350,6 +350,13 @@
return self._check(_cw, x=eid, **kwargs)
return self._check(_cw, **kwargs)
+def constraint_by_eid(self, eid):
+ for cstr in self.constraints:
+ if cstr.eid == eid:
+ return cstr
+ raise ValueError('No constraint with eid %d' % eid)
+RelationDefinitionSchema.constraint_by_eid = constraint_by_eid
+
def vargraph(rqlst):
""" builds an adjacency graph of variables from the rql syntax tree, e.g:
--- a/server/migractions.py Tue Apr 01 14:46:55 2014 +0200
+++ b/server/migractions.py Tue Apr 01 18:09:46 2014 +0200
@@ -618,12 +618,18 @@
self.rqlexecall(ss.updaterdef2rql(rdef, repordef.eid),
ask_confirm=confirm)
# constraints
- newconstraints = list(rdef.constraints)
+ # 0. eliminate the set of unmodified constraints from the sets of
+ # old/new constraints
+ newconstraints = set(rdef.constraints)
+ oldconstraints = set(repordef.constraints)
+ unchanged_constraints = newconstraints & oldconstraints
+ newconstraints -= unchanged_constraints
+ oldconstraints -= unchanged_constraints
# 1. remove old constraints and update constraints of the same type
# NOTE: don't use rschema.constraint_by_type because it may be
# out of sync with newconstraints when multiple
# constraints of the same type are used
- for cstr in repordef.constraints:
+ for cstr in oldconstraints:
for newcstr in newconstraints:
if newcstr.type() == cstr.type():
break
--- a/server/test/data/migratedapp/schema.py Tue Apr 01 14:46:55 2014 +0200
+++ b/server/test/data/migratedapp/schema.py Tue Apr 01 18:09:46 2014 +0200
@@ -22,6 +22,7 @@
RichString, String, Int, Boolean, Datetime, Date)
from yams.constraints import SizeConstraint, UniqueConstraint
from cubicweb.schema import (WorkflowableEntityType, RQLConstraint,
+ RQLVocabularyConstraint,
ERQLExpression, RRQLExpression)
class Affaire(EntityType):
@@ -177,4 +178,3 @@
class same_as(RelationDefinition):
subject = ('Societe',)
object = 'ExternalUri'
-
--- a/server/test/data/schema.py Tue Apr 01 14:46:55 2014 +0200
+++ b/server/test/data/schema.py Tue Apr 01 18:09:46 2014 +0200
@@ -22,6 +22,7 @@
from yams.constraints import SizeConstraint
from cubicweb.schema import (WorkflowableEntityType,
RQLConstraint, RQLUniqueConstraint,
+ RQLVocabularyConstraint,
ERQLExpression, RRQLExpression)
class Affaire(WorkflowableEntityType):
@@ -157,6 +158,8 @@
}
subject = 'Personne'
object = 'Societe'
+ constraints = [RQLVocabularyConstraint('S owned_by U'),
+ RQLVocabularyConstraint('S created_by U')]
class comments(RelationDefinition):
subject = 'Comment'
@@ -195,6 +198,10 @@
class evaluee(RelationDefinition):
subject = ('Personne', 'CWUser', 'Societe')
object = ('Note')
+ constraints = [
+ RQLVocabularyConstraint('S created_by U'),
+ RQLVocabularyConstraint('S owned_by U'),
+ ]
class ecrit_par(RelationType):
inlined = True
--- a/server/test/unittest_migractions.py Tue Apr 01 14:46:55 2014 +0200
+++ b/server/test/unittest_migractions.py Tue Apr 01 18:09:46 2014 +0200
@@ -364,6 +364,26 @@
self.mh.cmd_change_relation_props('Personne', 'adel', 'String',
fulltextindexed=False)
+ def test_sync_schema_props_perms_rqlconstraints(self):
+ # Drop one of the RQLConstraint.
+ rdef = self.schema['evaluee'].rdefs[('Personne', 'Note')]
+ oldconstraints = rdef.constraints
+ self.assertIn('S created_by U',
+ [cstr.expression for cstr in oldconstraints])
+ self.mh.cmd_sync_schema_props_perms('evaluee', commit=True)
+ newconstraints = rdef.constraints
+ self.assertNotIn('S created_by U',
+ [cstr.expression for cstr in newconstraints])
+
+ # Drop all RQLConstraint.
+ rdef = self.schema['travaille'].rdefs[('Personne', 'Societe')]
+ oldconstraints = rdef.constraints
+ self.assertEqual(len(oldconstraints), 2)
+ self.mh.cmd_sync_schema_props_perms('travaille', commit=True)
+ rdef = self.schema['travaille'].rdefs[('Personne', 'Societe')]
+ newconstraints = rdef.constraints
+ self.assertEqual(len(newconstraints), 0)
+
@tag('longrun')
def test_sync_schema_props_perms(self):
cursor = self.mh.session