backport stable branch 3.5
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 20 Aug 2009 17:57:56 +0200
branch3.5
changeset 2931 17224e90a1c4
parent 2924 b5aadbd3fc5b (current diff)
parent 2930 d7c23b2c7538 (diff)
child 2938 e5cef8ff5857
backport stable branch
debian.hardy/control
entity.py
schema.py
server/migractions.py
server/repository.py
server/test/unittest_migractions.py
test/unittest_entity.py
test/unittest_schema.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
--- 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. <contact@logilab.fr>
-Uploaders: Sylvain Thenault <sylvain.thenault@logilab.fr>,
-           Julien Jehannet <julien.jehannet@logilab.fr>,
-           Aurélien Campéas <aurelien.campeas@logilab.fr>
-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.
--- 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
--- 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 <julien.jehannet@logilab.fr>,
            Aurélien Campéas <aurelien.campeas@logilab.fr>,
            Nicolas Chauvat <nicolas.chauvat@logilab.fr>
-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
--- 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
--- 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):
--- 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
--- 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)
--- 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)
--- 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')
--- 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)