server/schemaserial.py
branchstable
changeset 5994 97c55baefa0c
parent 5970 fb8acdab4e12
child 6080 d0cb8fde4957
equal deleted inserted replaced
5976:00b1b6b906cf 5994:97c55baefa0c
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
    14 # details.
    14 # details.
    15 #
    15 #
    16 # You should have received a copy of the GNU Lesser General Public License along
    16 # You should have received a copy of the GNU Lesser General Public License along
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    18 """functions for schema / permissions (de)serialization using RQL
    18 """functions for schema / permissions (de)serialization using RQL"""
    19 
    19 
    20 """
       
    21 __docformat__ = "restructuredtext en"
    20 __docformat__ = "restructuredtext en"
    22 
    21 
    23 import os
    22 import os
    24 from itertools import chain
    23 from itertools import chain
    25 
    24 
    26 from logilab.common.shellutils import ProgressBar
    25 from logilab.common.shellutils import ProgressBar
    27 
    26 
    28 from yams import schema as schemamod, buildobjs as ybo
    27 from yams import schema as schemamod, buildobjs as ybo
    29 
    28 
    30 from cubicweb.schema import CONSTRAINTS, ETYPE_NAME_MAP, VIRTUAL_RTYPES
    29 from cubicweb import CW_SOFTWARE_ROOT, typed_eid
       
    30 from cubicweb.schema import (CONSTRAINTS, ETYPE_NAME_MAP,
       
    31                              VIRTUAL_RTYPES, PURE_VIRTUAL_RTYPES)
    31 from cubicweb.server import sqlutils
    32 from cubicweb.server import sqlutils
    32 
    33 
    33 def group_mapping(cursor, interactive=True):
    34 def group_mapping(cursor, interactive=True):
    34     """create a group mapping from an rql cursor
    35     """create a group mapping from an rql cursor
    35 
    36 
    55             while True:
    56             while True:
    56                 value = raw_input('eid for group %s: ' % group).strip()
    57                 value = raw_input('eid for group %s: ' % group).strip()
    57                 if not value:
    58                 if not value:
    58                     continue
    59                     continue
    59                 try:
    60                 try:
    60                     res[group] = int(value)
    61                     eid = typed_eid(value)
    61                 except ValueError:
    62                 except ValueError:
    62                     print 'eid should be an integer'
    63                     print 'eid should be an integer'
    63                     continue
    64                     continue
       
    65                 for eid_ in res.values():
       
    66                     if eid == eid_:
       
    67                         break
       
    68                 else:
       
    69                     print 'eid is not a group eid'
       
    70                     continue
       
    71                 res[name] = eid
       
    72                 break
    64     return res
    73     return res
    65 
    74 
    66 def cstrtype_mapping(cursor):
    75 def cstrtype_mapping(cursor):
    67     """cached constraint types mapping"""
    76     """cached constraint types mapping"""
    68     map = dict(cursor.execute('Any T, X WHERE X is CWConstraintType, X name T'))
    77     map = dict(cursor.execute('Any T, X WHERE X is CWConstraintType, X name T'))
    98             eschema = schema.eschema(etype)
   107             eschema = schema.eschema(etype)
    99             eschema.eid = eid
   108             eschema.eid = eid
   100             sidx[eid] = eschema
   109             sidx[eid] = eschema
   101             continue
   110             continue
   102         if etype in ETYPE_NAME_MAP:
   111         if etype in ETYPE_NAME_MAP:
       
   112             needcopy = False
   103             netype = ETYPE_NAME_MAP[etype]
   113             netype = ETYPE_NAME_MAP[etype]
   104             # can't use write rql queries at this point, use raw sql
   114             # can't use write rql queries at this point, use raw sql
   105             session.system_sql('UPDATE %(p)sCWEType SET %(p)sname=%%(n)s WHERE %(p)seid=%%(x)s'
   115             sqlexec = session.system_sql
   106                                % {'p': sqlutils.SQL_PREFIX},
   116             if sqlexec('SELECT 1 FROM %(p)sCWEType WHERE %(p)sname=%%(n)s'
   107                                {'x': eid, 'n': netype})
   117                        % {'p': sqlutils.SQL_PREFIX}, {'n': netype}).fetchone():
   108             session.system_sql('UPDATE entities SET type=%(n)s WHERE type=%(x)s',
   118                 # the new type already exists, we should merge
   109                                {'x': etype, 'n': netype})
   119                 assert etype.lower() != netype.lower()
       
   120                 needcopy = True
       
   121             else:
       
   122                 # the new type doesn't exist, we should rename
       
   123                 sqlexec('UPDATE %(p)sCWEType SET %(p)sname=%%(n)s WHERE %(p)seid=%%(x)s'
       
   124                         % {'p': sqlutils.SQL_PREFIX}, {'x': eid, 'n': netype})
       
   125                 if etype.lower() != netype.lower():
       
   126                     sqlexec('ALTER TABLE %s%s RENAME TO %s%s' % (
       
   127                         sqlutils.SQL_PREFIX, etype, sqlutils.SQL_PREFIX, netype))
       
   128             sqlexec('UPDATE entities SET type=%(n)s WHERE type=%(x)s',
       
   129                     {'x': etype, 'n': netype})
   110             session.commit(False)
   130             session.commit(False)
   111             try:
   131             try:
   112                 session.system_sql('UPDATE deleted_entities SET type=%(n)s WHERE type=%(x)s',
   132                 sqlexec('UPDATE deleted_entities SET type=%(n)s WHERE type=%(x)s',
   113                                    {'x': etype, 'n': netype})
   133                         {'x': etype, 'n': netype})
   114             except:
   134             except:
   115                 pass
   135                 pass
   116             tocleanup = [eid]
   136             tocleanup = [eid]
   117             tocleanup += (eid for eid, (eidetype, uri, extid) in repo._type_source_cache.items()
   137             tocleanup += (eid for eid, (eidetype, uri, extid) in repo._type_source_cache.items()
   118                           if etype == eidetype)
   138                           if etype == eidetype)
   119             repo.clear_caches(tocleanup)
   139             repo.clear_caches(tocleanup)
   120             session.commit(False)
   140             session.commit(False)
       
   141             if needcopy:
       
   142                 from logilab.common.testlib import mock_object
       
   143                 sidx[eid] = mock_object(type=netype)
       
   144                 # copy / CWEType entity removal expected to be done through
       
   145                 # rename_entity_type in a migration script
       
   146                 continue
   121             etype = netype
   147             etype = netype
   122         etype = ybo.EntityType(name=etype, description=desc, eid=eid)
   148         etype = ybo.EntityType(name=etype, description=desc, eid=eid)
   123         eschema = schema.add_entity_type(etype)
   149         eschema = schema.add_entity_type(etype)
   124         sidx[eid] = eschema
   150         sidx[eid] = eschema
   125         set_perms(eschema, permsdict)
   151         set_perms(eschema, permsdict)