server/schemaserial.py
branchtls-sprint
changeset 1630 41aadba8b29f
parent 1398 5fe84a5f7035
child 1869 642a1a120a92
equal deleted inserted replaced
1629:cfbcf96ea054 1630:41aadba8b29f
    30         return res
    30         return res
    31     missing = [g for g in ('owners', 'managers', 'users', 'guests') if not g in res]
    31     missing = [g for g in ('owners', 'managers', 'users', 'guests') if not g in res]
    32     if missing:
    32     if missing:
    33         print 'some native groups are missing but the following groups have been found:'
    33         print 'some native groups are missing but the following groups have been found:'
    34         print '\n'.join('* %s (%s)' % (n, eid) for n, eid in res.items())
    34         print '\n'.join('* %s (%s)' % (n, eid) for n, eid in res.items())
    35         print 
    35         print
    36         print 'enter the eid of a to group to map to each missing native group'
    36         print 'enter the eid of a to group to map to each missing native group'
    37         print 'or just type enter to skip permissions granted to a group'
    37         print 'or just type enter to skip permissions granted to a group'
    38         for group in missing:
    38         for group in missing:
    39             while True:
    39             while True:
    40                 value = raw_input('eid for group %s: ' % group).strip()
    40                 value = raw_input('eid for group %s: ' % group).strip()
    54         try:
    54         try:
    55             sys.modules['cubicweb.server.%s' % module].SQL_PREFIX = prefix
    55             sys.modules['cubicweb.server.%s' % module].SQL_PREFIX = prefix
    56             print 'changed SQL_PREFIX for %s' % module
    56             print 'changed SQL_PREFIX for %s' % module
    57         except KeyError:
    57         except KeyError:
    58             pass
    58             pass
    59         
    59 
    60 def _update_database(schema, sqlcu):
    60 def _update_database(schema, sqlcu):
    61     """3.2.0 migration function: update database schema by adding SQL_PREFIX to
    61     """3.2.0 migration function: update database schema by adding SQL_PREFIX to
    62     entity type tables and columns
    62     entity type tables and columns
    63     """
    63     """
    64     for etype in schema.entities():
    64     for etype in schema.entities():
    88     """
    88     """
    89     #
    89     #
    90     repo = session.repo
    90     repo = session.repo
    91     sqlcu = session.pool['system']
    91     sqlcu = session.pool['system']
    92     _3_2_migration = False
    92     _3_2_migration = False
    93     if 'eetype' in [t.lower() for t in repo.system_source.dbhelper.list_tables(sqlcu)]:
    93     tables = set(t.lower() for t in repo.system_source.dbhelper.list_tables(sqlcu))
       
    94     if 'eetype' in tables:
    94         _3_2_migration = True
    95         _3_2_migration = True
    95         # 3.2 migration
    96         # 3.2 migration
    96         _set_sql_prefix('')
    97         _set_sql_prefix('')
    97         # first rename entity types whose name changed in 3.2 without adding the
    98         # first rename entity types whose name changed in 3.2 without adding the
    98         # cw_ prefix
    99         # cw_ prefix
    99         for etype in ('EFRDef', 'ENFRDef', 'ERType', 'EEType',
   100         for etype in ('EFRDef', 'ENFRDef', 'ERType', 'EEType',
   100                       'EConstraintType', 'EConstraint', 'EGroup', 'EUser',
   101                       'EConstraintType', 'EConstraint', 'EGroup', 'EUser',
   101                       'ECache', 'EPermission', 'EProperty'):
   102                       'ECache', 'EPermission', 'EProperty'):
   102             sql = 'ALTER TABLE %s RENAME TO %s' % (etype, ETYPE_NAME_MAP[etype])
   103             if etype.lower() in tables:
   103             print sql
   104                 sql = 'ALTER TABLE %s RENAME TO %s' % (etype,
   104             sqlcu.execute(sql)
   105                                                        ETYPE_NAME_MAP[etype])
       
   106                 print sql
       
   107                 sqlcu.execute(sql)
   105         # other table renaming done once schema has been readen
   108         # other table renaming done once schema has been readen
   106     # print 'reading schema from the database...'
   109     # print 'reading schema from the database...'
   107     index = {}
   110     index = {}
   108     permsdict = deserialize_ertype_permissions(session)
   111     permsdict = deserialize_ertype_permissions(session)
   109     schema.reading_from_database = True
   112     schema.reading_from_database = True
   130                 session.system_sql('UPDATE deleted_entities SET type=%(n)s WHERE type=%(x)s',
   133                 session.system_sql('UPDATE deleted_entities SET type=%(n)s WHERE type=%(x)s',
   131                                    {'x': etype, 'n': ETYPE_NAME_MAP[etype]})
   134                                    {'x': etype, 'n': ETYPE_NAME_MAP[etype]})
   132             except:
   135             except:
   133                 pass
   136                 pass
   134             tocleanup = [eid]
   137             tocleanup = [eid]
   135             tocleanup += (eid for eid, (eidetype, uri, extid) in session.repo._type_source_cache.items()
   138             tocleanup += (eid for eid, (eidetype, uri, extid) in repo._type_source_cache.items()
   136                           if etype == eidetype)
   139                           if etype == eidetype)
   137             session.repo.clear_caches(tocleanup)
   140             repo.clear_caches(tocleanup)
   138             session.commit(False)
   141             session.commit(False)
   139             etype = ETYPE_NAME_MAP[etype]
   142             etype = ETYPE_NAME_MAP[etype]
   140         etype = ybo.EntityType(name=etype, description=desc, meta=meta, eid=eid)
   143         etype = ybo.EntityType(name=etype, description=desc, meta=meta, eid=eid)
   141         eschema = schema.add_entity_type(etype)
   144         eschema = schema.add_entity_type(etype)
   142         index[eid] = eschema
   145         index[eid] = eschema
   165         rtype = ybo.RelationType(name=rtype, description=desc, meta=bool(meta),
   168         rtype = ybo.RelationType(name=rtype, description=desc, meta=bool(meta),
   166                                  symetric=bool(sym), inlined=bool(il),
   169                                  symetric=bool(sym), inlined=bool(il),
   167                                  fulltext_container=ft_container, eid=eid)
   170                                  fulltext_container=ft_container, eid=eid)
   168         rschema = schema.add_relation_type(rtype)
   171         rschema = schema.add_relation_type(rtype)
   169         index[eid] = rschema
   172         index[eid] = rschema
   170         set_perms(rschema, permsdict.get(eid, {}))        
   173         set_perms(rschema, permsdict.get(eid, {}))
   171     cstrsdict = deserialize_rdef_constraints(session)
   174     cstrsdict = deserialize_rdef_constraints(session)
   172     for values in session.execute(
   175     for values in session.execute(
   173         'Any X,SE,RT,OE,CARD,ORD,DESC,IDX,FTIDX,I18N,DFLT WHERE X is CWAttribute,'
   176         'Any X,SE,RT,OE,CARD,ORD,DESC,IDX,FTIDX,I18N,DFLT WHERE X is CWAttribute,'
   174         'X relation_type RT, X cardinality CARD, X ordernum ORD, X indexed IDX,'
   177         'X relation_type RT, X cardinality CARD, X ordernum ORD, X indexed IDX,'
   175         'X description DESC, X internationalizable I18N, X defaultval DFLT,'
   178         'X description DESC, X internationalizable I18N, X defaultval DFLT,'
   179         constraints = cstrsdict.get(rdefeid, ())
   182         constraints = cstrsdict.get(rdefeid, ())
   180         frometype = index[seid].type
   183         frometype = index[seid].type
   181         rtype = index[reid].type
   184         rtype = index[reid].type
   182         toetype = index[teid].type
   185         toetype = index[teid].type
   183         rdef = ybo.RelationDefinition(frometype, rtype, toetype, cardinality=card,
   186         rdef = ybo.RelationDefinition(frometype, rtype, toetype, cardinality=card,
   184                                   order=ord, description=desc, 
   187                                   order=ord, description=desc,
   185                                   constraints=constraints,
   188                                   constraints=constraints,
   186                                   indexed=idx, fulltextindexed=ftidx,
   189                                   indexed=idx, fulltextindexed=ftidx,
   187                                   internationalizable=i18n,
   190                                   internationalizable=i18n,
   188                                   default=default, eid=rdefeid)
   191                                   default=default, eid=rdefeid)
   189         schema.add_relation_def(rdef)
   192         schema.add_relation_def(rdef)
   195         frometype = index[seid].type
   198         frometype = index[seid].type
   196         rtype = index[reid].type
   199         rtype = index[reid].type
   197         toetype = index[teid].type
   200         toetype = index[teid].type
   198         constraints = cstrsdict.get(rdefeid, ())
   201         constraints = cstrsdict.get(rdefeid, ())
   199         rdef = ybo.RelationDefinition(frometype, rtype, toetype, cardinality=card,
   202         rdef = ybo.RelationDefinition(frometype, rtype, toetype, cardinality=card,
   200                                   order=ord, description=desc, 
   203                                   order=ord, description=desc,
   201                                   composite=c, constraints=constraints,
   204                                   composite=c, constraints=constraints,
   202                                   eid=rdefeid)
   205                                   eid=rdefeid)
   203         schema.add_relation_def(rdef)
   206         schema.add_relation_def(rdef)
   204     schema.infer_specialization_rules()
   207     schema.infer_specialization_rules()
   205     if _3_2_migration:
   208     if _3_2_migration:
   239         for something in permsdict.get(action, ()):
   242         for something in permsdict.get(action, ()):
   240             if isinstance(something, tuple):
   243             if isinstance(something, tuple):
   241                 actperms.append(erschema.rql_expression(*something))
   244                 actperms.append(erschema.rql_expression(*something))
   242             else: # group name
   245             else: # group name
   243                 actperms.append(something)
   246                 actperms.append(something)
   244         erschema.set_permissions(action, actperms)            
   247         erschema.set_permissions(action, actperms)
   245 
   248 
   246 
   249 
   247 def deserialize_rdef_constraints(session):
   250 def deserialize_rdef_constraints(session):
   248     """return the list of relation definition's constraints as instances"""
   251     """return the list of relation definition's constraints as instances"""
   249     res = {}
   252     res = {}
   252         'X cstrtype T, T name TN, X value V', build_descr=False):
   255         'X cstrtype T, T name TN, X value V', build_descr=False):
   253         cstr = CONSTRAINTS[ct].deserialize(val)
   256         cstr = CONSTRAINTS[ct].deserialize(val)
   254         cstr.eid = ceid
   257         cstr.eid = ceid
   255         res.setdefault(rdefeid, []).append(cstr)
   258         res.setdefault(rdefeid, []).append(cstr)
   256     return res
   259     return res
   257         
   260 
   258         
   261 
   259 # schema / perms serialization ################################################
   262 # schema / perms serialization ################################################
   260 
   263 
   261 def serialize_schema(cursor, schema, verbose=False):
   264 def serialize_schema(cursor, schema, verbose=False):
   262     """synchronize schema and permissions in the database according to
   265     """synchronize schema and permissions in the database according to
   263     current schema
   266     current schema
   350             value = int(value)
   353             value = int(value)
   351         elif isinstance(value, str):
   354         elif isinstance(value, str):
   352             value = unicode(value)
   355             value = unicode(value)
   353         values[amap.get(prop, prop)] = value
   356         values[amap.get(prop, prop)] = value
   354     return values
   357     return values
   355     
   358 
   356 def nfrdef_relations_values(rschema, objtype, props):
   359 def nfrdef_relations_values(rschema, objtype, props):
   357     values = _rdef_values(rschema, objtype, props)
   360     values = _rdef_values(rschema, objtype, props)
   358     relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)]
   361     relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)]
   359     return relations, values
   362     return relations, values
   360     
   363 
   361 def frdef_relations_values(rschema, objtype, props):
   364 def frdef_relations_values(rschema, objtype, props):
   362     values = _rdef_values(rschema, objtype, props)
   365     values = _rdef_values(rschema, objtype, props)
   363     default = values['default']
   366     default = values['default']
   364     del values['default']
   367     del values['default']
   365     if default is not None:
   368     if default is not None:
   369             default = unicode(default)
   372             default = unicode(default)
   370     values['defaultval'] = default
   373     values['defaultval'] = default
   371     relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)]
   374     relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)]
   372     return relations, values
   375     return relations, values
   373 
   376 
   374     
   377 
   375 def __rdef2rql(genmap, rschema, subjtype=None, objtype=None, props=None):
   378 def __rdef2rql(genmap, rschema, subjtype=None, objtype=None, props=None):
   376     if subjtype is None:
   379     if subjtype is None:
   377         assert objtype is None
   380         assert objtype is None
   378         assert props is None
   381         assert props is None
   379         targets = rschema.iter_rdefs()
   382         targets = rschema.iter_rdefs()
   403     if skip is not None:
   406     if skip is not None:
   404         return chain(*[erschema2rql(schema[t]) for t in all if not t in skip])
   407         return chain(*[erschema2rql(schema[t]) for t in all if not t in skip])
   405     elif allow is not None:
   408     elif allow is not None:
   406         return chain(*[erschema2rql(schema[t]) for t in all if t in allow])
   409         return chain(*[erschema2rql(schema[t]) for t in all if t in allow])
   407     return chain(*[erschema2rql(schema[t]) for t in all])
   410     return chain(*[erschema2rql(schema[t]) for t in all])
   408         
   411 
   409 def erschema2rql(erschema):
   412 def erschema2rql(erschema):
   410     if isinstance(erschema, schemamod.EntitySchema):
   413     if isinstance(erschema, schemamod.EntitySchema):
   411         return eschema2rql(erschema)
   414         return eschema2rql(erschema)
   412     return rschema2rql(erschema)
   415     return rschema2rql(erschema)
   413 
   416 
   440     relations, values = rschema_relations_values(rschema)
   443     relations, values = rschema_relations_values(rschema)
   441     yield 'INSERT CWRType X: %s' % ','.join(relations), values
   444     yield 'INSERT CWRType X: %s' % ','.join(relations), values
   442     if addrdef:
   445     if addrdef:
   443         for rql, values in rdef2rql(rschema):
   446         for rql, values in rdef2rql(rschema):
   444             yield rql, values
   447             yield rql, values
   445             
   448 
   446 def rdef2rql(rschema, subjtype=None, objtype=None, props=None):
   449 def rdef2rql(rschema, subjtype=None, objtype=None, props=None):
   447     genmap = {True: frdef2rql, False: nfrdef2rql}
   450     genmap = {True: frdef2rql, False: nfrdef2rql}
   448     return __rdef2rql(genmap, rschema, subjtype, objtype, props)
   451     return __rdef2rql(genmap, rschema, subjtype, objtype, props)
   449 
   452 
   450 
   453 
   456     relations.append(_LOCATE_RDEF_RQL0)
   459     relations.append(_LOCATE_RDEF_RQL0)
   457     values.update({'se': str(subjtype), 'rt': str(rschema), 'oe': str(objtype)})
   460     values.update({'se': str(subjtype), 'rt': str(rschema), 'oe': str(objtype)})
   458     yield 'INSERT CWAttribute X: %s WHERE %s' % (','.join(relations), _LOCATE_RDEF_RQL1), values
   461     yield 'INSERT CWAttribute X: %s WHERE %s' % (','.join(relations), _LOCATE_RDEF_RQL1), values
   459     for rql, values in rdefrelations2rql(rschema, subjtype, objtype, props):
   462     for rql, values in rdefrelations2rql(rschema, subjtype, objtype, props):
   460         yield rql + ', EDEF is CWAttribute', values
   463         yield rql + ', EDEF is CWAttribute', values
   461             
   464 
   462 def nfrdef2rql(rschema, subjtype, objtype, props):
   465 def nfrdef2rql(rschema, subjtype, objtype, props):
   463     relations, values = nfrdef_relations_values(rschema, objtype, props)
   466     relations, values = nfrdef_relations_values(rschema, objtype, props)
   464     relations.append(_LOCATE_RDEF_RQL0)
   467     relations.append(_LOCATE_RDEF_RQL0)
   465     values.update({'se': str(subjtype), 'rt': str(rschema), 'oe': str(objtype)})
   468     values.update({'se': str(subjtype), 'rt': str(rschema), 'oe': str(objtype)})
   466     yield 'INSERT CWRelation X: %s WHERE %s' % (','.join(relations), _LOCATE_RDEF_RQL1), values
   469     yield 'INSERT CWRelation X: %s WHERE %s' % (','.join(relations), _LOCATE_RDEF_RQL1), values
   467     for rql, values in rdefrelations2rql(rschema, subjtype, objtype, props):
   470     for rql, values in rdefrelations2rql(rschema, subjtype, objtype, props):
   468         yield rql + ', EDEF is CWRelation', values
   471         yield rql + ', EDEF is CWRelation', values
   469                 
   472 
   470 def rdefrelations2rql(rschema, subjtype, objtype, props):
   473 def rdefrelations2rql(rschema, subjtype, objtype, props):
   471     iterators = []
   474     iterators = []
   472     for constraint in props['constraints']:
   475     for constraint in props['constraints']:
   473         iterators.append(constraint2rql(rschema, subjtype, objtype, constraint))
   476         iterators.append(constraint2rql(rschema, subjtype, objtype, constraint))
   474     return chain(*iterators)
   477     return chain(*iterators)
   523 
   526 
   524 def updaterschema2rql(rschema):
   527 def updaterschema2rql(rschema):
   525     relations, values = rschema_relations_values(rschema)
   528     relations, values = rschema_relations_values(rschema)
   526     values['rt'] = rschema.type
   529     values['rt'] = rschema.type
   527     yield 'SET %s WHERE X is CWRType, X name %%(rt)s' % ','.join(relations), values
   530     yield 'SET %s WHERE X is CWRType, X name %%(rt)s' % ','.join(relations), values
   528             
   531 
   529 def updaterdef2rql(rschema, subjtype=None, objtype=None, props=None):
   532 def updaterdef2rql(rschema, subjtype=None, objtype=None, props=None):
   530     genmap = {True: updatefrdef2rql, False: updatenfrdef2rql}
   533     genmap = {True: updatefrdef2rql, False: updatenfrdef2rql}
   531     return __rdef2rql(genmap, rschema, subjtype, objtype, props)
   534     return __rdef2rql(genmap, rschema, subjtype, objtype, props)
   532 
   535 
   533 def updatefrdef2rql(rschema, subjtype, objtype, props):
   536 def updatefrdef2rql(rschema, subjtype, objtype, props):
   534     relations, values = frdef_relations_values(rschema, objtype, props)
   537     relations, values = frdef_relations_values(rschema, objtype, props)
   535     values.update({'se': subjtype, 'rt': str(rschema), 'oe': objtype})
   538     values.update({'se': subjtype, 'rt': str(rschema), 'oe': objtype})
   536     yield 'SET %s WHERE %s, %s, X is CWAttribute' % (','.join(relations),
   539     yield 'SET %s WHERE %s, %s, X is CWAttribute' % (','.join(relations),
   537                                                  _LOCATE_RDEF_RQL0,
   540                                                  _LOCATE_RDEF_RQL0,
   538                                                  _LOCATE_RDEF_RQL1), values
   541                                                  _LOCATE_RDEF_RQL1), values
   539             
   542 
   540 def updatenfrdef2rql(rschema, subjtype, objtype, props):
   543 def updatenfrdef2rql(rschema, subjtype, objtype, props):
   541     relations, values = nfrdef_relations_values(rschema, objtype, props)
   544     relations, values = nfrdef_relations_values(rschema, objtype, props)
   542     values.update({'se': subjtype, 'rt': str(rschema), 'oe': objtype})
   545     values.update({'se': subjtype, 'rt': str(rschema), 'oe': objtype})
   543     yield 'SET %s WHERE %s, %s, X is CWRelation' % (','.join(relations),
   546     yield 'SET %s WHERE %s, %s, X is CWRelation' % (','.join(relations),
   544                                                  _LOCATE_RDEF_RQL0,
   547                                                  _LOCATE_RDEF_RQL0,