server/checkintegrity.py
branchtls-sprint
changeset 1263 01152fffd593
parent 1016 26387b836099
parent 1251 af40e615dc89
child 1398 5fe84a5f7035
equal deleted inserted replaced
1246:76b3cd5d4f31 1263:01152fffd593
     9 
     9 
    10 import sys
    10 import sys
    11 from datetime import datetime
    11 from datetime import datetime
    12 
    12 
    13 from logilab.common.shellutils import ProgressBar
    13 from logilab.common.shellutils import ProgressBar
       
    14 
       
    15 from cubicweb.server.sqlutils import SQL_PREFIX
    14 
    16 
    15 def has_eid(sqlcursor, eid, eids):
    17 def has_eid(sqlcursor, eid, eids):
    16     """return true if the eid is a valid eid"""
    18     """return true if the eid is a valid eid"""
    17     if eids.has_key(eid):
    19     if eids.has_key(eid):
    18         return eids[eid]
    20         return eids[eid]
    24         return False
    26         return False
    25     if source and source != 'system':
    27     if source and source != 'system':
    26         # XXX what to do...
    28         # XXX what to do...
    27         eids[eid] = True
    29         eids[eid] = True
    28         return True
    30         return True
    29     sqlcursor.execute('SELECT * FROM %s WHERE eid=%s' % (etype, eid))
    31     sqlcursor.execute('SELECT * FROM %s%s WHERE %seid=%s' % (SQL_PREFIX, etype,
       
    32                                                              SQL_PREFIX, eid))
    30     result = sqlcursor.fetchall()
    33     result = sqlcursor.fetchall()
    31     if len(result) == 0:
    34     if len(result) == 0:
    32         eids[eid] = False
    35         eids[eid] = False
    33         return False
    36         return False
    34     elif len(result) > 1:
    37     elif len(result) > 1:
    69     repo = session.repo
    72     repo = session.repo
    70     repo.hm.unregister_hook(setmtime_before_update_entity,
    73     repo.hm.unregister_hook(setmtime_before_update_entity,
    71                             'before_update_entity', '')
    74                             'before_update_entity', '')
    72     repo.hm.unregister_hook(uniquecstrcheck_before_modification,
    75     repo.hm.unregister_hook(uniquecstrcheck_before_modification,
    73                             'before_update_entity', '')
    76                             'before_update_entity', '')
       
    77     repo.do_fti = True  # ensure full-text indexation is activated
    74     etypes = set()
    78     etypes = set()
    75     for eschema in schema.entities():
    79     for eschema in schema.entities():
    76         if eschema.is_final():
    80         if eschema.is_final():
    77             continue
    81             continue
    78         indexable_attrs = tuple(eschema.indexable_attributes()) # generator
    82         indexable_attrs = tuple(eschema.indexable_attributes()) # generator
   151                 print >> sys.stderr
   155                 print >> sys.stderr
   152     print 'Checking entities tables'
   156     print 'Checking entities tables'
   153     for eschema in schema.entities():
   157     for eschema in schema.entities():
   154         if eschema.is_final():
   158         if eschema.is_final():
   155             continue
   159             continue
   156         cursor = session.system_sql('SELECT eid FROM %s;' % eschema.type)
   160         table = SQL_PREFIX + eschema.type
       
   161         column = SQL_PREFIX +  'eid'
       
   162         cursor = session.system_sql('SELECT %s FROM %s;' % (column, table))
   157         for row in cursor.fetchall():
   163         for row in cursor.fetchall():
   158             eid = row[0]
   164             eid = row[0]
   159             # eids is full since we have fetched everyting from the entities table,
   165             # eids is full since we have fetched everyting from the entities table,
   160             # no need to call has_eid
   166             # no need to call has_eid
   161             if not eid in eids or not eids[eid]:
   167             if not eid in eids or not eids[eid]:
   162                 msg = '  Entity with eid %s exists in the %s table but not in the system table'
   168                 msg = '  Entity with eid %s exists in the %s table but not in the system table'
   163                 print >> sys.stderr, msg % (eid, eschema.type),
   169                 print >> sys.stderr, msg % (eid, eschema.type),
   164                 if fix:
   170                 if fix:
   165                     session.system_sql('DELETE FROM %s WHERE eid=%s;' % (eschema.type, eid))
   171                     session.system_sql('DELETE FROM %s WHERE %s=%s;' % (table, column, eid))
   166                     print >> sys.stderr, ' [FIXED]'
   172                     print >> sys.stderr, ' [FIXED]'
   167                 else:
   173                 else:
   168                     print >> sys.stderr
   174                     print >> sys.stderr
   169                 
   175                 
   170             
   176             
   181     """check all relations registered in the repo system table"""
   187     """check all relations registered in the repo system table"""
   182     print 'Checking relations'
   188     print 'Checking relations'
   183     for rschema in schema.relations():
   189     for rschema in schema.relations():
   184         if rschema.is_final():
   190         if rschema.is_final():
   185             continue
   191             continue
   186         rtype = rschema.type
   192         if rschema == 'identity':
   187         if rtype == 'identity':
       
   188             continue
   193             continue
   189         if rschema.inlined:
   194         if rschema.inlined:
   190             for subjtype in rschema.subjects():
   195             for subjtype in rschema.subjects():
       
   196                 table = SQL_PREFIX + str(subjtype)
       
   197                 column = SQL_PREFIX +  str(rschema)
   191                 sql = 'SELECT %s FROM %s WHERE %s IS NOT NULL;' % (
   198                 sql = 'SELECT %s FROM %s WHERE %s IS NOT NULL;' % (
   192                     rtype, subjtype, rtype)
   199                     column, table, column)
   193                 cursor = session.system_sql(sql)
   200                 cursor = session.system_sql(sql)
   194                 for row in cursor.fetchall():
   201                 for row in cursor.fetchall():
   195                     eid = row[0]
   202                     eid = row[0]
   196                     if not has_eid(cursor, eid, eids):
   203                     if not has_eid(cursor, eid, eids):
   197                         bad_related_msg(rtype, 'object', eid, fix)
   204                         bad_related_msg(rschema, 'object', eid, fix)
   198                         if fix:
   205                         if fix:
   199                             sql = 'UPDATE %s SET %s = NULL WHERE eid=%s;' % (
   206                             sql = 'UPDATE %s SET %s = NULL WHERE %seid=%s;' % (
   200                                 subjtype, rtype, eid)
   207                                 table, column, SQL_PREFIX, eid)
   201                             session.system_sql(sql)
   208                             session.system_sql(sql)
   202             continue
   209             continue
   203         cursor = session.system_sql('SELECT eid_from FROM %s_relation;' % rtype)
   210         cursor = session.system_sql('SELECT eid_from FROM %s_relation;' % rschema)
   204         for row in cursor.fetchall():
   211         for row in cursor.fetchall():
   205             eid = row[0]
   212             eid = row[0]
   206             if not has_eid(cursor, eid, eids):
   213             if not has_eid(cursor, eid, eids):
   207                 bad_related_msg(rtype, 'subject', eid, fix)
   214                 bad_related_msg(rschema, 'subject', eid, fix)
   208                 if fix:
   215                 if fix:
   209                     sql = 'DELETE FROM %s_relation WHERE eid_from=%s;' % (
   216                     sql = 'DELETE FROM %s_relation WHERE eid_from=%s;' % (
   210                         rtype, eid)
   217                         rschema, eid)
   211                     session.system_sql(sql)
   218                     session.system_sql(sql)
   212         cursor = session.system_sql('SELECT eid_to FROM %s_relation;' % rtype)
   219         cursor = session.system_sql('SELECT eid_to FROM %s_relation;' % rschema)
   213         for row in cursor.fetchall():
   220         for row in cursor.fetchall():
   214             eid = row[0]
   221             eid = row[0]
   215             if not has_eid(cursor, eid, eids):
   222             if not has_eid(cursor, eid, eids):
   216                 bad_related_msg(rtype, 'object', eid, fix)
   223                 bad_related_msg(rschema, 'object', eid, fix)
   217                 if fix:
   224                 if fix:
   218                     sql = 'DELETE FROM %s_relation WHERE eid_to=%s;' % (
   225                     sql = 'DELETE FROM %s_relation WHERE eid_to=%s;' % (
   219                         rtype, eid)
   226                         rschema, eid)
   220                     session.system_sql(sql)
   227                     session.system_sql(sql)
   221 
   228 
   222 
   229 
   223 def check_metadata(schema, session, eids, fix=1):
   230 def check_metadata(schema, session, eids, fix=1):
   224     """check entities has required metadata
   231     """check entities has required metadata
   225 
   232 
   226     FIXME: rewrite using RQL queries ?
   233     FIXME: rewrite using RQL queries ?
   227     """
   234     """
   228     print 'Checking metadata'
   235     print 'Checking metadata'
   229     cursor = session.system_sql("SELECT DISTINCT type FROM entities;")
   236     cursor = session.system_sql("SELECT DISTINCT type FROM entities;")
       
   237     eidcolumn = SQL_PREFIX + 'eid'
   230     for etype, in cursor.fetchall():
   238     for etype, in cursor.fetchall():
       
   239         table = SQL_PREFIX + etype
   231         for rel, default in ( ('creation_date', datetime.now()),
   240         for rel, default in ( ('creation_date', datetime.now()),
   232                               ('modification_date', datetime.now()), ):
   241                               ('modification_date', datetime.now()), ):
   233             cursor = session.system_sql("SELECT eid FROM %s "
   242             column = SQL_PREFIX + rel
   234                                         "WHERE %s is NULL" % (etype, rel))
   243             cursor = session.system_sql("SELECT %s FROM %s WHERE %s is NULL"
       
   244                                         % (eidcolumn, table, column))
   235             for eid, in cursor.fetchall():
   245             for eid, in cursor.fetchall():
   236                 msg = '  %s with eid %s has no %s'
   246                 msg = '  %s with eid %s has no %s'
   237                 print >> sys.stderr, msg % (etype, eid, rel),
   247                 print >> sys.stderr, msg % (etype, eid, rel),
   238                 if fix:
   248                 if fix:
   239                     session.system_sql("UPDATE %s SET %s=%(default)s WHERE eid=%s ;"
   249                     session.system_sql("UPDATE %s SET %s=%%(v)s WHERE %s=%s ;"
   240                                        % (etype, rel, eid), {'default': default})
   250                                        % (table, column, eidcolumn, eid),
       
   251                                        {'v': default})
   241                     print >> sys.stderr, ' [FIXED]'
   252                     print >> sys.stderr, ' [FIXED]'
   242                 else:
   253                 else:
   243                     print >> sys.stderr
   254                     print >> sys.stderr
   244     cursor = session.system_sql('SELECT MIN(eid) FROM euser;')
   255     cursor = session.system_sql('SELECT MIN(%s) FROM %sEUser;' % (eidcolumn,
       
   256                                                                   SQL_PREFIX))
   245     default_user_eid = cursor.fetchone()[0]
   257     default_user_eid = cursor.fetchone()[0]
   246     assert default_user_eid is not None, 'no user defined !'
   258     assert default_user_eid is not None, 'no user defined !'
   247     for rel, default in ( ('owned_by', default_user_eid), ):
   259     for rel, default in ( ('owned_by', default_user_eid), ):
   248         cursor = session.system_sql("SELECT eid, type FROM entities "
   260         cursor = session.system_sql("SELECT eid, type FROM entities "
   249                                     "WHERE NOT EXISTS "
   261                                     "WHERE NOT EXISTS "