server/schemaserial.py
changeset 8945 ba9e3fbfa5a5
parent 8748 f5027f8d2478
child 8986 f094b72d3a6c
--- a/server/schemaserial.py	Tue Apr 23 14:13:58 2013 +0200
+++ b/server/schemaserial.py	Fri Apr 26 17:46:56 2013 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -21,16 +21,18 @@
 
 import os
 from itertools import chain
+import json
 
 from logilab.common.shellutils import ProgressBar
 
 from yams import BadSchemaDefinition, schema as schemamod, buildobjs as ybo
 
-from cubicweb import CW_SOFTWARE_ROOT
-from cubicweb.schema import (CONSTRAINTS, ETYPE_NAME_MAP,
+from cubicweb import CW_SOFTWARE_ROOT, Binary
+from cubicweb.schema import (KNOWN_RPROPERTIES, CONSTRAINTS, ETYPE_NAME_MAP,
                              VIRTUAL_RTYPES, PURE_VIRTUAL_RTYPES)
 from cubicweb.server import sqlutils
 
+
 def group_mapping(cursor, interactive=True):
     """create a group mapping from an rql cursor
 
@@ -195,7 +197,12 @@
             if rdefs is not None:
                 ertidx[rdefeid] = rdefs
                 set_perms(rdefs, permsidx)
-
+    # Get the type parameters for additional base types.
+    try:
+        extra_props = dict(session.execute('Any X, XTP WHERE X is CWAttribute, '
+                                           'X extra_props XTP'))
+    except Exception:
+        extra_props = {} # not yet in the schema (introduced by 3.17 migration)
     for values in session.execute(
         'Any X,SE,RT,OE,CARD,ORD,DESC,IDX,FTIDX,I18N,DFLT WHERE X is CWAttribute,'
         'X relation_type RT, X cardinality CARD, X ordernum ORD, X indexed IDX,'
@@ -203,10 +210,12 @@
         'X fulltextindexed FTIDX, X from_entity SE, X to_entity OE',
         build_descr=False):
         rdefeid, seid, reid, oeid, card, ord, desc, idx, ftidx, i18n, default = values
+        typeparams = extra_props.get(rdefeid)
+        typeparams = json.load(typeparams) if typeparams else {}
         _add_rdef(rdefeid, seid, reid, oeid,
                   cardinality=card, description=desc, order=ord,
                   indexed=idx, fulltextindexed=ftidx, internationalizable=i18n,
-                  default=default)
+                  default=default, **typeparams)
     for values in session.execute(
         'Any X,SE,RT,OE,CARD,ORD,DESC,C WHERE X is CWRelation, X relation_type RT,'
         'X cardinality CARD, X ordernum ORD, X description DESC, '
@@ -509,10 +518,14 @@
 def _rdef_values(rdef):
     amap = {'order': 'ordernum', 'default': 'defaultval'}
     values = {}
-    for prop, default in rdef.rproperty_defs(rdef.object).iteritems():
+    extra = {}
+    for prop in rdef.rproperty_defs(rdef.object):
         if prop in ('eid', 'constraints', 'uid', 'infered', 'permissions'):
             continue
         value = getattr(rdef, prop)
+        if prop not in KNOWN_RPROPERTIES:
+            extra[prop] = value
+            continue
         # XXX type cast really necessary?
         if prop in ('indexed', 'fulltextindexed', 'internationalizable'):
             value = bool(value)
@@ -526,6 +539,8 @@
             if not isinstance(value, unicode):
                 value = unicode(value)
         values[amap.get(prop, prop)] = value
+    if extra:
+        values['extra_props'] = Binary(json.dumps(extra))
     relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)]
     return relations, values