# HG changeset patch # User Sylvain Thénault # Date 1250783876 -7200 # Node ID 17224e90a1c40fccb3c8ed756121e9d8883b02b0 # Parent b5aadbd3fc5ba9be9ad5553600a38d5be16c07dc# Parent d7c23b2c75383cb7a3671f74e039a58e8ad4d9f5 backport stable branch diff -r b5aadbd3fc5b -r 17224e90a1c4 cwvreg.py --- a/cwvreg.py Thu Aug 20 17:52:22 2009 +0200 +++ b/cwvreg.py Thu Aug 20 17:57:56 2009 +0200 @@ -47,7 +47,10 @@ def __init__(self, vreg): super(CWRegistry, self).__init__(vreg.config) self.vreg = vreg - self.schema = vreg.schema + + @property + def schema(self): + return self.vreg.schema def initialization_completed(self): # call vreg_initialization_completed on appobjects and print diff -r b5aadbd3fc5b -r 17224e90a1c4 debian.hardy/control --- a/debian.hardy/control Thu Aug 20 17:52:22 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -Source: cubicweb -Section: web -Priority: optional -Maintainer: Logilab S.A. -Uploaders: Sylvain Thenault , - Julien Jehannet , - Aurélien Campéas -Build-Depends: debhelper (>= 5), python-dev (>=2.4), python-central (>= 0.5) -Standards-Version: 3.8.0 -Homepage: http://www.cubicweb.org -XS-Python-Version: >= 2.4, << 2.6 - - -Package: cubicweb -Architecture: all -XB-Python-Version: ${python:Versions} -Depends: ${python:Depends}, cubicweb-server (= ${source:Version}), cubicweb-twisted (= ${source:Version}), cubicweb-client (= ${source:Version}) -XB-Recommends: (postgresql, postgresql-plpython, postgresql-contrib) | mysql | sqlite3 -Recommends: postgresql | mysql | sqlite3 -Description: the complete CubicWeb framework - CubicWeb is a semantic web application framework. - . - This package will install all the components you need to run cubicweb on - a single machine. You can also deploy cubicweb by running the different - process on different computers, in which case you need to install the - corresponding packages on the different hosts. - - -Package: cubicweb-server -Architecture: all -XB-Python-Version: ${python:Versions} -Conflicts: cubicweb-multisources -Replaces: cubicweb-multisources -Provides: cubicweb-multisources -Depends: ${python:Depends}, cubicweb-common (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-indexer (>= 0.6.1), python-psycopg2 | python-mysqldb | python-pysqlite2 -Recommends: pyro, cubicweb-documentation (= ${source:Version}) -Description: server part of the CubicWeb framework - CubicWeb is a semantic web application framework. - . - This package provides the repository server part of the system. - . - This package provides the repository server part of the library and - necessary shared data files such as the schema library. - - -Package: cubicweb-twisted -Architecture: all -XB-Python-Version: ${python:Versions} -Provides: cubicweb-web-frontend -Depends: ${python:Depends}, cubicweb-web (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-twisted-web2 -Recommends: pyro, cubicweb-documentation (= ${source:Version}) -Description: twisted-based web interface for the CubicWeb framework - CubicWeb is a semantic web application framework. - . - This package provides a twisted based HTTP server to serve - the adaptative web interface (see cubicweb-web package). - . - This package provides only the twisted server part of the library. - - -Package: cubicweb-web -Architecture: all -XB-Python-Version: ${python:Versions} -Depends: ${python:Depends}, cubicweb-common (= ${source:Version}), python-docutils, python-vobject, python-elementtree -Recommends: fckeditor -Description: web interface library for the CubicWeb framework - CubicWeb is a semantic web application framework. - . - This package provides an adaptative web interface to the CubicWeb server. - Install the cubicweb-twisted package to serve this interface via HTTP. - . - This package provides the web interface part of the library and - necessary shared data files such as defaut views, images... - - -Package: cubicweb-common -Architecture: all -XB-Python-Version: ${python:Versions} -Depends: ${python:Depends}, python-logilab-mtconverter (>= 0.6.0), python-simpletal (>= 4.0), graphviz, gettext, python-lxml, python-logilab-common (>= 0.38.1), python-yams (>= 0.20.2), python-rql (>= 0.20.2), python-simplejson (>= 1.3) -Recommends: python-psyco -Conflicts: cubicweb-core -Replaces: cubicweb-core -Description: common library for the CubicWeb framework - CubicWeb is a semantic web application framework. - . - This package provides the common parts of the library used by both server - code and web application code. - - -Package: cubicweb-ctl -Architecture: all -XB-Python-Version: ${python:Versions} -Depends: ${python:Depends}, cubicweb-common (= ${source:Version}) -Description: tool to manage the CubicWeb framework - CubicWeb is a semantic web application framework. - . - This package provides a control script to manage (create, upgrade, start, - stop, etc) CubicWeb applications. It also include the init.d script - to automatically start and stop CubicWeb applications on boot or shutdown. - - -Package: cubicweb-client -Architecture: all -XB-Python-Version: ${python:Versions} -Depends: ${python:Depends}, cubicweb-ctl (= ${source:Version}), pyro -Description: RQL command line client for the CubicWeb framework - CubicWeb is a semantic web application framework. - . - This package provides a RQL (Relation Query Language) command line client using - pyro to connect to a repository server. - - -Package: cubicweb-dev -Architecture: all -XB-Python-Version: ${python:Versions} -Depends: ${python:Depends}, cubicweb-server (= ${source:Version}), cubicweb-web (= ${source:Version}), python-pysqlite2 -Suggests: w3c-dtd-xhtml -Description: tests suite and development tools for the CubicWeb framework - CubicWeb is a semantic web application framework. - . - This package provides the CubicWeb tests suite and some development tools - helping in the creation of application. - - -Package: cubicweb-documentation -Architecture: all -Recommends: doc-base -Description: documentation for the CubicWeb framework - CubicWeb is a semantic web application framework. - . - This package provides the system's documentation. diff -r b5aadbd3fc5b -r 17224e90a1c4 debian.hardy/rules --- a/debian.hardy/rules Thu Aug 20 17:52:22 2009 +0200 +++ b/debian.hardy/rules Thu Aug 20 17:57:56 2009 +0200 @@ -39,13 +39,20 @@ # Put all the python library and data in cubicweb-common # and scripts in cubicweb-server dh_install -vi - #dh_lintian XXX not before debhelper 7 + # cwctl in the cubicweb-ctl package + rm -f debian/cubicweb-common/usr/share/pyshared/cubicweb/cwctl.py + # hercule in the cubicweb-client package + rm -f debian/cubicweb-common/usr/share/pyshared/cubicweb/hercule.py + # Remove unittests directory (should be available in cubicweb-dev only) rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/site-packages/cubicweb/server/test rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/site-packages/cubicweb/sobjects/test rm -rf debian/cubicweb-web/usr/lib/${PY_VERSION}/site-packages/cubicweb/web/test + rm -rf debian/cubicweb-twisted/usr/lib/${PY_VERSION}/site-packages/cubicweb/etwist/test + rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/ext/test rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/common/test + rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/entities/test # cubes directory must be managed as a valid python module touch debian/cubicweb-common/usr/share/cubicweb/cubes/__init__.py diff -r b5aadbd3fc5b -r 17224e90a1c4 debian/control --- a/debian/control Thu Aug 20 17:52:22 2009 +0200 +++ b/debian/control Thu Aug 20 17:57:56 2009 +0200 @@ -6,7 +6,7 @@ Julien Jehannet , Aurélien Campéas , Nicolas Chauvat -Build-Depends: debhelper (>= 7), python-dev (>=2.4), python-central (>= 0.5) +Build-Depends: debhelper (>= 5), python-dev (>=2.4), python-central (>= 0.5) Standards-Version: 3.8.0 Homepage: http://www.cubicweb.org XS-Python-Version: >= 2.4, << 2.6 diff -r b5aadbd3fc5b -r 17224e90a1c4 entity.py --- a/entity.py Thu Aug 20 17:52:22 2009 +0200 +++ b/entity.py Thu Aug 20 17:57:56 2009 +0200 @@ -251,8 +251,8 @@ desttype = rschema.objects(eschema.type)[0] card = rschema.rproperty(eschema, desttype, 'cardinality')[0] if card not in '?1': - self.warning('bad relation %s specified in fetch attrs for %s', - attr, self.__class__) + cls.warning('bad relation %s specified in fetch attrs for %s', + attr, cls) selection.pop() restrictions.pop() continue diff -r b5aadbd3fc5b -r 17224e90a1c4 schema.py --- a/schema.py Thu Aug 20 17:52:22 2009 +0200 +++ b/schema.py Thu Aug 20 17:57:56 2009 +0200 @@ -16,6 +16,7 @@ from logilab.common.decorators import cached, clear_cache, monkeypatch from logilab.common.logging_ext import set_log_methods from logilab.common.deprecation import deprecated +from logilab.common.graph import get_cycles from logilab.common.compat import any from yams import BadSchemaDefinition, buildobjs as ybo @@ -59,6 +60,38 @@ ybo.RTYPE_PROPERTIES += ('eid',) ybo.RDEF_PROPERTIES += ('eid',) + +# XXX same algorithm as in reorder_cubes and probably other place, +# may probably extract a generic function +def order_eschemas(eschemas): + """return entity schemas ordered such that entity types which specializes an + other one appears after that one + """ + graph = {} + for eschema in eschemas: + if eschema.specializes(): + graph[eschema] = set((eschema.specializes(),)) + else: + graph[eschema] = set() + cycles = get_cycles(graph) + if cycles: + cycles = '\n'.join(' -> '.join(cycle) for cycle in cycles) + raise Exception('cycles in entity schema specialization: %s' + % cycles) + eschemas = [] + while graph: + # sorted to get predictable results + for eschema, deps in sorted(graph.items()): + if not deps: + eschemas.append(eschema) + del graph[eschema] + for deps in graph.itervalues(): + try: + deps.remove(eschema) + except KeyError: + continue + return eschemas + def bw_normalize_etype(etype): if etype in ETYPE_NAME_MAP: msg = '%s has been renamed to %s, please update your code' % ( @@ -804,6 +837,7 @@ PyFileReader.context['RRQLExpression'] = yobsolete(RRQLExpression) # workflow extensions ######################################################### + from yams.buildobjs import _add_relation as yams_add_relation class workflowable_definition(ybo.metadefinition): diff -r b5aadbd3fc5b -r 17224e90a1c4 server/migractions.py --- a/server/migractions.py Thu Aug 20 17:52:22 2009 +0200 +++ b/server/migractions.py Thu Aug 20 17:57:56 2009 +0200 @@ -33,7 +33,8 @@ from yams.schema2sql import eschema2sql, rschema2sql from cubicweb import AuthenticationError, ETYPE_NAME_MAP -from cubicweb.schema import META_RTYPES, VIRTUAL_RTYPES, CubicWebRelationSchema +from cubicweb.schema import (META_RTYPES, VIRTUAL_RTYPES, + CubicWebRelationSchema, order_eschemas) from cubicweb.dbapi import get_repository, repo_connect from cubicweb.common.migration import MigrationHelper, yes @@ -518,10 +519,11 @@ if not rschema in self.repo.schema: self.cmd_add_relation_type(rschema.type) new.add(rschema.type) - for eschema in newcubes_schema.entities(): - if not eschema in self.repo.schema: - self.cmd_add_entity_type(eschema.type) - new.add(eschema.type) + toadd = [eschema for eschema in newcubes_schema.entities() + if not eschema in self.repo.schema] + for eschema in order_eschemas(toadd): + self.cmd_add_entity_type(eschema.type) + new.add(eschema.type) # check if attributes has been added to existing entities for rschema in newcubes_schema.relations(): existingschema = self.repo.schema.rschema(rschema.type) @@ -553,9 +555,11 @@ for rschema in fsschema.relations(): if not rschema in removedcubes_schema and rschema in reposchema: self.cmd_drop_relation_type(rschema.type) - for eschema in fsschema.entities(): - if not eschema in removedcubes_schema and eschema in reposchema: - self.cmd_drop_entity_type(eschema.type) + toremove = [eschema for eschema in fsschema.entities() + if not eschema in removedcubes_schema + and eschema in reposchema] + for eschema in reversed(order_eschemas(toremove)): + self.cmd_drop_entity_type(eschema.type) for rschema in fsschema.relations(): if rschema in removedcubes_schema and rschema in reposchema: # check if attributes/relations has been added to entities from diff -r b5aadbd3fc5b -r 17224e90a1c4 server/repository.py --- a/server/repository.py Thu Aug 20 17:52:22 2009 +0200 +++ b/server/repository.py Thu Aug 20 17:57:56 2009 +0200 @@ -998,15 +998,16 @@ print 'ADD entity', etype, entity.eid, dict(entity) entity._is_saved = False # entity has an eid but is not yet saved relations = [] - # if inlined relations are specified, fill entity's related cache to - # avoid unnecessary queries + # init edited_attributes before calling before_add_entity hooks + entity.edited_attributes = set(entity) + if source.should_call_hooks: + self.hm.call_hooks('before_add_entity', etype, session, entity) + # XXX use entity.keys here since edited_attributes is not updated for + # inline relations for attr in entity.keys(): rschema = eschema.subject_relation(attr) if not rschema.is_final(): # inlined relation relations.append((attr, entity[attr])) - if source.should_call_hooks: - self.hm.call_hooks('before_add_entity', etype, session, entity) - entity.edited_attributes = set(entity) entity.set_defaults() entity.check(creation=True) source.add_entity(session, entity) diff -r b5aadbd3fc5b -r 17224e90a1c4 server/test/unittest_migractions.py --- a/server/test/unittest_migractions.py Thu Aug 20 17:52:22 2009 +0200 +++ b/server/test/unittest_migractions.py Thu Aug 20 17:57:56 2009 +0200 @@ -272,7 +272,7 @@ 'Any N ORDERBY O WHERE X is CWAttribute, X relation_type RT, RT name N,' 'X from_entity FE, FE name "Personne",' 'X ordernum O')] - expected = [u'nom', u'prenom', u'promo', u'ass', u'adel', u'titre', + expected = [u'nom', u'prenom', u'sexe', u'promo', u'ass', u'adel', u'titre', u'web', u'tel', u'fax', u'datenaiss', u'test', 'description', u'firstname', u'creation_date', 'cwuri', u'modification_date'] self.assertEquals(rinorder, expected) diff -r b5aadbd3fc5b -r 17224e90a1c4 test/unittest_entity.py --- a/test/unittest_entity.py Thu Aug 20 17:52:22 2009 +0200 +++ b/test/unittest_entity.py Thu Aug 20 17:57:56 2009 +0200 @@ -161,7 +161,8 @@ ) # testing symetric relation Personne.fetch_attrs = ('nom', 'connait') - self.assertEquals(Personne.fetch_rql(user), 'Any X,AA,AB ORDERBY AA ASC WHERE X is Personne, X nom AA, X connait AB') + self.assertEquals(Personne.fetch_rql(user), 'Any X,AA,AB ORDERBY AA ASC ' + 'WHERE X is Personne, X nom AA, X connait AB?') # testing optional relation peschema.subject_relation('travaille').set_rproperty(peschema, seschema, 'cardinality', '?*') Personne.fetch_attrs = ('nom', 'prenom', 'travaille') diff -r b5aadbd3fc5b -r 17224e90a1c4 test/unittest_schema.py --- a/test/unittest_schema.py Thu Aug 20 17:52:22 2009 +0200 +++ b/test/unittest_schema.py Thu Aug 20 17:57:56 2009 +0200 @@ -20,7 +20,7 @@ from cubicweb.schema import CubicWebSchema, CubicWebEntitySchema, \ RQLConstraint, CubicWebSchemaLoader, ERQLExpression, RRQLExpression, \ - normalize_expression + normalize_expression, order_eschemas from cubicweb.devtools import TestServerConfiguration as TestConfiguration DATADIR = join(dirname(__file__), 'data') @@ -126,12 +126,18 @@ expr = RRQLExpression('U has_update_permission O') self.assertEquals(str(expr), 'Any O WHERE U has_update_permission O, O eid %(o)s, U eid %(u)s') - loader = CubicWebSchemaLoader() config = TestConfiguration('data') config.bootstrap_cubes() -class SQLSchemaReaderClassTest(TestCase): +class SchemaReaderClassTest(TestCase): + + def test_order_eschemas(self): + schema = loader.load(config) + self.assertEquals(order_eschemas([schema['Note'], schema['SubNote']]), + [schema['Note'], schema['SubNote']]) + self.assertEquals(order_eschemas([schema['SubNote'], schema['Note']]), + [schema['Note'], schema['SubNote']]) def test_knownValues_load_schema(self): schema = loader.load(config)