server/schemaserial.py
changeset 8945 ba9e3fbfa5a5
parent 8748 f5027f8d2478
child 8986 f094b72d3a6c
equal deleted inserted replaced
8944:b167f039b6cb 8945:ba9e3fbfa5a5
     1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     1 # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     3 #
     3 #
     4 # This file is part of CubicWeb.
     4 # This file is part of CubicWeb.
     5 #
     5 #
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
    19 
    19 
    20 __docformat__ = "restructuredtext en"
    20 __docformat__ = "restructuredtext en"
    21 
    21 
    22 import os
    22 import os
    23 from itertools import chain
    23 from itertools import chain
       
    24 import json
    24 
    25 
    25 from logilab.common.shellutils import ProgressBar
    26 from logilab.common.shellutils import ProgressBar
    26 
    27 
    27 from yams import BadSchemaDefinition, schema as schemamod, buildobjs as ybo
    28 from yams import BadSchemaDefinition, schema as schemamod, buildobjs as ybo
    28 
    29 
    29 from cubicweb import CW_SOFTWARE_ROOT
    30 from cubicweb import CW_SOFTWARE_ROOT, Binary
    30 from cubicweb.schema import (CONSTRAINTS, ETYPE_NAME_MAP,
    31 from cubicweb.schema import (KNOWN_RPROPERTIES, CONSTRAINTS, ETYPE_NAME_MAP,
    31                              VIRTUAL_RTYPES, PURE_VIRTUAL_RTYPES)
    32                              VIRTUAL_RTYPES, PURE_VIRTUAL_RTYPES)
    32 from cubicweb.server import sqlutils
    33 from cubicweb.server import sqlutils
       
    34 
    33 
    35 
    34 def group_mapping(cursor, interactive=True):
    36 def group_mapping(cursor, interactive=True):
    35     """create a group mapping from an rql cursor
    37     """create a group mapping from an rql cursor
    36 
    38 
    37     A group mapping has standard group names as key (managers, owners at least)
    39     A group mapping has standard group names as key (managers, owners at least)
   193             # e.g. if the relation type is marked as beeing symmetric)
   195             # e.g. if the relation type is marked as beeing symmetric)
   194             rdefs = schema.add_relation_def(rdef)
   196             rdefs = schema.add_relation_def(rdef)
   195             if rdefs is not None:
   197             if rdefs is not None:
   196                 ertidx[rdefeid] = rdefs
   198                 ertidx[rdefeid] = rdefs
   197                 set_perms(rdefs, permsidx)
   199                 set_perms(rdefs, permsidx)
   198 
   200     # Get the type parameters for additional base types.
       
   201     try:
       
   202         extra_props = dict(session.execute('Any X, XTP WHERE X is CWAttribute, '
       
   203                                            'X extra_props XTP'))
       
   204     except Exception:
       
   205         extra_props = {} # not yet in the schema (introduced by 3.17 migration)
   199     for values in session.execute(
   206     for values in session.execute(
   200         'Any X,SE,RT,OE,CARD,ORD,DESC,IDX,FTIDX,I18N,DFLT WHERE X is CWAttribute,'
   207         'Any X,SE,RT,OE,CARD,ORD,DESC,IDX,FTIDX,I18N,DFLT WHERE X is CWAttribute,'
   201         'X relation_type RT, X cardinality CARD, X ordernum ORD, X indexed IDX,'
   208         'X relation_type RT, X cardinality CARD, X ordernum ORD, X indexed IDX,'
   202         'X description DESC, X internationalizable I18N, X defaultval DFLT,'
   209         'X description DESC, X internationalizable I18N, X defaultval DFLT,'
   203         'X fulltextindexed FTIDX, X from_entity SE, X to_entity OE',
   210         'X fulltextindexed FTIDX, X from_entity SE, X to_entity OE',
   204         build_descr=False):
   211         build_descr=False):
   205         rdefeid, seid, reid, oeid, card, ord, desc, idx, ftidx, i18n, default = values
   212         rdefeid, seid, reid, oeid, card, ord, desc, idx, ftidx, i18n, default = values
       
   213         typeparams = extra_props.get(rdefeid)
       
   214         typeparams = json.load(typeparams) if typeparams else {}
   206         _add_rdef(rdefeid, seid, reid, oeid,
   215         _add_rdef(rdefeid, seid, reid, oeid,
   207                   cardinality=card, description=desc, order=ord,
   216                   cardinality=card, description=desc, order=ord,
   208                   indexed=idx, fulltextindexed=ftidx, internationalizable=i18n,
   217                   indexed=idx, fulltextindexed=ftidx, internationalizable=i18n,
   209                   default=default)
   218                   default=default, **typeparams)
   210     for values in session.execute(
   219     for values in session.execute(
   211         'Any X,SE,RT,OE,CARD,ORD,DESC,C WHERE X is CWRelation, X relation_type RT,'
   220         'Any X,SE,RT,OE,CARD,ORD,DESC,C WHERE X is CWRelation, X relation_type RT,'
   212         'X cardinality CARD, X ordernum ORD, X description DESC, '
   221         'X cardinality CARD, X ordernum ORD, X description DESC, '
   213         'X from_entity SE, X to_entity OE, X composite C', build_descr=False):
   222         'X from_entity SE, X to_entity OE, X composite C', build_descr=False):
   214         rdefeid, seid, reid, oeid, card, ord, desc, comp = values
   223         rdefeid, seid, reid, oeid, card, ord, desc, comp = values
   507             yield rql, args
   516             yield rql, args
   508 
   517 
   509 def _rdef_values(rdef):
   518 def _rdef_values(rdef):
   510     amap = {'order': 'ordernum', 'default': 'defaultval'}
   519     amap = {'order': 'ordernum', 'default': 'defaultval'}
   511     values = {}
   520     values = {}
   512     for prop, default in rdef.rproperty_defs(rdef.object).iteritems():
   521     extra = {}
       
   522     for prop in rdef.rproperty_defs(rdef.object):
   513         if prop in ('eid', 'constraints', 'uid', 'infered', 'permissions'):
   523         if prop in ('eid', 'constraints', 'uid', 'infered', 'permissions'):
   514             continue
   524             continue
   515         value = getattr(rdef, prop)
   525         value = getattr(rdef, prop)
       
   526         if prop not in KNOWN_RPROPERTIES:
       
   527             extra[prop] = value
       
   528             continue
   516         # XXX type cast really necessary?
   529         # XXX type cast really necessary?
   517         if prop in ('indexed', 'fulltextindexed', 'internationalizable'):
   530         if prop in ('indexed', 'fulltextindexed', 'internationalizable'):
   518             value = bool(value)
   531             value = bool(value)
   519         elif prop == 'ordernum':
   532         elif prop == 'ordernum':
   520             value = int(value)
   533             value = int(value)
   524             if value is False:
   537             if value is False:
   525                 value = u''
   538                 value = u''
   526             if not isinstance(value, unicode):
   539             if not isinstance(value, unicode):
   527                 value = unicode(value)
   540                 value = unicode(value)
   528         values[amap.get(prop, prop)] = value
   541         values[amap.get(prop, prop)] = value
       
   542     if extra:
       
   543         values['extra_props'] = Binary(json.dumps(extra))
   529     relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)]
   544     relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)]
   530     return relations, values
   545     return relations, values
   531 
   546 
   532 def constraints2rql(cstrtypemap, constraints, rdefeid=None):
   547 def constraints2rql(cstrtypemap, constraints, rdefeid=None):
   533     for constraint in constraints:
   548     for constraint in constraints: