server/checkintegrity.py
changeset 1251 af40e615dc89
parent 1161 936c311010fc
child 1263 01152fffd593
equal deleted inserted replaced
1250:5c20a7f13c84 1251:af40e615dc89
     1 """Check integrity of a CubicWeb repository. Hum actually only the system database
     1 """Check integrity of a CubicWeb repository. Hum actually only the system database
     2 is checked.
     2 is checked.
     3 
     3 
     4 :organization: Logilab
     4 :organization: Logilab
     5 :copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     5 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     7 """
     7 """
     8 __docformat__ = "restructuredtext en"
     8 __docformat__ = "restructuredtext en"
     9 
     9 
    10 import sys
    10 import sys
    11 
    11 
    12 from mx.DateTime import now
    12 from mx.DateTime import now
    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:
   152                 print >> sys.stderr
   155                 print >> sys.stderr
   153     print 'Checking entities tables'
   156     print 'Checking entities tables'
   154     for eschema in schema.entities():
   157     for eschema in schema.entities():
   155         if eschema.is_final():
   158         if eschema.is_final():
   156             continue
   159             continue
   157         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))
   158         for row in cursor.fetchall():
   163         for row in cursor.fetchall():
   159             eid = row[0]
   164             eid = row[0]
   160             # 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,
   161             # no need to call has_eid
   166             # no need to call has_eid
   162             if not eid in eids or not eids[eid]:
   167             if not eid in eids or not eids[eid]:
   163                 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'
   164                 print >> sys.stderr, msg % (eid, eschema.type),
   169                 print >> sys.stderr, msg % (eid, eschema.type),
   165                 if fix:
   170                 if fix:
   166                     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))
   167                     print >> sys.stderr, ' [FIXED]'
   172                     print >> sys.stderr, ' [FIXED]'
   168                 else:
   173                 else:
   169                     print >> sys.stderr
   174                     print >> sys.stderr
   170                 
   175                 
   171             
   176             
   182     """check all relations registered in the repo system table"""
   187     """check all relations registered in the repo system table"""
   183     print 'Checking relations'
   188     print 'Checking relations'
   184     for rschema in schema.relations():
   189     for rschema in schema.relations():
   185         if rschema.is_final():
   190         if rschema.is_final():
   186             continue
   191             continue
   187         rtype = rschema.type
   192         if rschema == 'identity':
   188         if rtype == 'identity':
       
   189             continue
   193             continue
   190         if rschema.inlined:
   194         if rschema.inlined:
   191             for subjtype in rschema.subjects():
   195             for subjtype in rschema.subjects():
       
   196                 table = SQL_PREFIX + str(subjtype)
       
   197                 column = SQL_PREFIX +  str(rschema)
   192                 sql = 'SELECT %s FROM %s WHERE %s IS NOT NULL;' % (
   198                 sql = 'SELECT %s FROM %s WHERE %s IS NOT NULL;' % (
   193                     rtype, subjtype, rtype)
   199                     column, table, column)
   194                 cursor = session.system_sql(sql)
   200                 cursor = session.system_sql(sql)
   195                 for row in cursor.fetchall():
   201                 for row in cursor.fetchall():
   196                     eid = row[0]
   202                     eid = row[0]
   197                     if not has_eid(cursor, eid, eids):
   203                     if not has_eid(cursor, eid, eids):
   198                         bad_related_msg(rtype, 'object', eid, fix)
   204                         bad_related_msg(rschema, 'object', eid, fix)
   199                         if fix:
   205                         if fix:
   200                             sql = 'UPDATE %s SET %s = NULL WHERE eid=%s;' % (
   206                             sql = 'UPDATE %s SET %s = NULL WHERE %seid=%s;' % (
   201                                 subjtype, rtype, eid)
   207                                 table, column, SQL_PREFIX, eid)
   202                             session.system_sql(sql)
   208                             session.system_sql(sql)
   203             continue
   209             continue
   204         cursor = session.system_sql('SELECT eid_from FROM %s_relation;' % rtype)
   210         cursor = session.system_sql('SELECT eid_from FROM %s_relation;' % rschema)
   205         for row in cursor.fetchall():
   211         for row in cursor.fetchall():
   206             eid = row[0]
   212             eid = row[0]
   207             if not has_eid(cursor, eid, eids):
   213             if not has_eid(cursor, eid, eids):
   208                 bad_related_msg(rtype, 'subject', eid, fix)
   214                 bad_related_msg(rschema, 'subject', eid, fix)
   209                 if fix:
   215                 if fix:
   210                     sql = 'DELETE FROM %s_relation WHERE eid_from=%s;' % (
   216                     sql = 'DELETE FROM %s_relation WHERE eid_from=%s;' % (
   211                         rtype, eid)
   217                         rschema, eid)
   212                     session.system_sql(sql)
   218                     session.system_sql(sql)
   213         cursor = session.system_sql('SELECT eid_to FROM %s_relation;' % rtype)
   219         cursor = session.system_sql('SELECT eid_to FROM %s_relation;' % rschema)
   214         for row in cursor.fetchall():
   220         for row in cursor.fetchall():
   215             eid = row[0]
   221             eid = row[0]
   216             if not has_eid(cursor, eid, eids):
   222             if not has_eid(cursor, eid, eids):
   217                 bad_related_msg(rtype, 'object', eid, fix)
   223                 bad_related_msg(rschema, 'object', eid, fix)
   218                 if fix:
   224                 if fix:
   219                     sql = 'DELETE FROM %s_relation WHERE eid_to=%s;' % (
   225                     sql = 'DELETE FROM %s_relation WHERE eid_to=%s;' % (
   220                         rtype, eid)
   226                         rschema, eid)
   221                     session.system_sql(sql)
   227                     session.system_sql(sql)
   222 
   228 
   223 
   229 
   224 def check_metadata(schema, session, eids, fix=1):
   230 def check_metadata(schema, session, eids, fix=1):
   225     """check entities has required metadata
   231     """check entities has required metadata
   226 
   232 
   227     FIXME: rewrite using RQL queries ?
   233     FIXME: rewrite using RQL queries ?
   228     """
   234     """
   229     print 'Checking metadata'
   235     print 'Checking metadata'
   230     cursor = session.system_sql("SELECT DISTINCT type FROM entities;")
   236     cursor = session.system_sql("SELECT DISTINCT type FROM entities;")
       
   237     eidcolumn = SQL_PREFIX + 'eid'
   231     for etype, in cursor.fetchall():
   238     for etype, in cursor.fetchall():
       
   239         table = SQL_PREFIX + etype
   232         for rel, default in ( ('creation_date', now()),
   240         for rel, default in ( ('creation_date', now()),
   233                               ('modification_date', now()), ):
   241                               ('modification_date', now()), ):
   234             cursor = session.system_sql("SELECT eid FROM %s "
   242             column = SQL_PREFIX + rel
   235                                         "WHERE %s is NULL" % (etype, rel))
   243             cursor = session.system_sql("SELECT %s FROM %s WHERE %s is NULL"
       
   244                                         % (eidcolumn, table, column))
   236             for eid, in cursor.fetchall():
   245             for eid, in cursor.fetchall():
   237                 msg = '  %s with eid %s has no %s'
   246                 msg = '  %s with eid %s has no %s'
   238                 print >> sys.stderr, msg % (etype, eid, rel),
   247                 print >> sys.stderr, msg % (etype, eid, rel),
   239                 if fix:
   248                 if fix:
   240                     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 ;"
   241                                        % (etype, rel, eid), {'default': default})
   250                                        % (table, column, eidcolumn, eid),
       
   251                                        {'v': default})
   242                     print >> sys.stderr, ' [FIXED]'
   252                     print >> sys.stderr, ' [FIXED]'
   243                 else:
   253                 else:
   244                     print >> sys.stderr
   254                     print >> sys.stderr
   245     cursor = session.system_sql('SELECT MIN(eid) FROM euser;')
   255     cursor = session.system_sql('SELECT MIN(%s) FROM %sEUser;' % (eidcolumn,
       
   256                                                                   SQL_PREFIX))
   246     default_user_eid = cursor.fetchone()[0]
   257     default_user_eid = cursor.fetchone()[0]
   247     assert default_user_eid is not None, 'no user defined !'
   258     assert default_user_eid is not None, 'no user defined !'
   248     for rel, default in ( ('owned_by', default_user_eid), ):
   259     for rel, default in ( ('owned_by', default_user_eid), ):
   249         cursor = session.system_sql("SELECT eid, type FROM entities "
   260         cursor = session.system_sql("SELECT eid, type FROM entities "
   250                                     "WHERE NOT EXISTS "
   261                                     "WHERE NOT EXISTS "