cubicweb/server/checkintegrity.py
changeset 11952 9dbb0af82628
parent 11894 ec29989fba13
child 11953 f24b115cca74
equal deleted inserted replaced
11951:330f240435b0 11952:9dbb0af82628
   138             pb.update()
   138             pb.update()
   139     if withpb:
   139     if withpb:
   140         pb.finish()
   140         pb.finish()
   141 
   141 
   142 
   142 
       
   143 _CHECKERS = {}
       
   144 
       
   145 
       
   146 def _checker(func):
       
   147     """Decorator to register a function as a checker for check()."""
       
   148     fname = func.__name__
       
   149     prefix = 'check_'
       
   150     assert fname.startswith(prefix), 'cannot register %s as a checker' % func
       
   151     _CHECKERS[fname[len(prefix):]] = func
       
   152     return func
       
   153 
       
   154 
       
   155 @_checker
   143 def check_schema(schema, cnx, eids, fix=1):
   156 def check_schema(schema, cnx, eids, fix=1):
   144     """check serialized schema"""
   157     """check serialized schema"""
   145     print('Checking serialized schema')
   158     print('Checking serialized schema')
   146     rql = ('Any COUNT(X),RN,SN,ON,CTN GROUPBY RN,SN,ON,CTN ORDERBY 1 '
   159     rql = ('Any COUNT(X),RN,SN,ON,CTN GROUPBY RN,SN,ON,CTN ORDERBY 1 '
   147            'WHERE X is CWConstraint, R constrained_by X, '
   160            'WHERE X is CWConstraint, R constrained_by X, '
   155                 count, cstrname, sn, rn, on))
   168                 count, cstrname, sn, rn, on))
   156             if fix:
   169             if fix:
   157                 print('dunno how to fix, do it yourself')
   170                 print('dunno how to fix, do it yourself')
   158 
   171 
   159 
   172 
       
   173 @_checker
   160 def check_text_index(schema, cnx, eids, fix=1):
   174 def check_text_index(schema, cnx, eids, fix=1):
   161     """check all entities registered in the text index"""
   175     """check all entities registered in the text index"""
   162     print('Checking text index')
   176     print('Checking text index')
   163     msg = '  Entity with eid %s exists in the text index but in no source (autofix will remove from text index)'
   177     msg = '  Entity with eid %s exists in the text index but in no source (autofix will remove from text index)'
   164     cursor = cnx.system_sql('SELECT uid FROM appears;')
   178     cursor = cnx.system_sql('SELECT uid FROM appears;')
   169             if fix:
   183             if fix:
   170                 cnx.system_sql('DELETE FROM appears WHERE uid=%s;' % eid)
   184                 cnx.system_sql('DELETE FROM appears WHERE uid=%s;' % eid)
   171             notify_fixed(fix)
   185             notify_fixed(fix)
   172 
   186 
   173 
   187 
       
   188 @_checker
   174 def check_entities(schema, cnx, eids, fix=1):
   189 def check_entities(schema, cnx, eids, fix=1):
   175     """check all entities registered in the repo system table"""
   190     """check all entities registered in the repo system table"""
   176     print('Checking entities system table')
   191     print('Checking entities system table')
   177     # system table but no source
   192     # system table but no source
   178     msg = '  Entity %s with eid %s exists in the system table but in no source (autofix will delete the entity)'
   193     msg = '  Entity %s with eid %s exists in the system table but in no source (autofix will delete the entity)'
   257            'entity does not exist')
   272            'entity does not exist')
   258     sys.stderr.write(msg % (rtype, parent_eid, eid))
   273     sys.stderr.write(msg % (rtype, parent_eid, eid))
   259     notify_fixed(fix)
   274     notify_fixed(fix)
   260 
   275 
   261 
   276 
       
   277 @_checker
   262 def check_relations(schema, cnx, eids, fix=1):
   278 def check_relations(schema, cnx, eids, fix=1):
   263     """check that eids referenced by relations are registered in the repo system
   279     """check that eids referenced by relations are registered in the repo system
   264     table
   280     table
   265     """
   281     """
   266     print('Checking relations')
   282     print('Checking relations')
   306                     sql = 'DELETE FROM %s_relation WHERE eid_to=%s;' % (
   322                     sql = 'DELETE FROM %s_relation WHERE eid_to=%s;' % (
   307                         rschema, eid)
   323                         rschema, eid)
   308                     cnx.system_sql(sql)
   324                     cnx.system_sql(sql)
   309 
   325 
   310 
   326 
       
   327 @_checker
   311 def check_mandatory_relations(schema, cnx, eids, fix=1):
   328 def check_mandatory_relations(schema, cnx, eids, fix=1):
   312     """check entities missing some mandatory relation"""
   329     """check entities missing some mandatory relation"""
   313     print('Checking mandatory relations')
   330     print('Checking mandatory relations')
   314     msg = '%s #%s is missing mandatory %s relation %s (autofix will delete the entity)'
   331     msg = '%s #%s is missing mandatory %s relation %s (autofix will delete the entity)'
   315     for rschema in schema.relations():
   332     for rschema in schema.relations():
   333                     if fix:
   350                     if fix:
   334                         entity.cw_delete() # XXX this is BRUTAL!
   351                         entity.cw_delete() # XXX this is BRUTAL!
   335                     notify_fixed(fix)
   352                     notify_fixed(fix)
   336 
   353 
   337 
   354 
       
   355 @_checker
   338 def check_mandatory_attributes(schema, cnx, eids, fix=1):
   356 def check_mandatory_attributes(schema, cnx, eids, fix=1):
   339     """check for entities stored in the system source missing some mandatory
   357     """check for entities stored in the system source missing some mandatory
   340     attribute
   358     attribute
   341     """
   359     """
   342     print('Checking mandatory attributes')
   360     print('Checking mandatory attributes')
   353                     if fix:
   371                     if fix:
   354                         entity.cw_delete()
   372                         entity.cw_delete()
   355                     notify_fixed(fix)
   373                     notify_fixed(fix)
   356 
   374 
   357 
   375 
       
   376 @_checker
   358 def check_metadata(schema, cnx, eids, fix=1):
   377 def check_metadata(schema, cnx, eids, fix=1):
   359     """check entities has required metadata
   378     """check entities has required metadata
   360 
   379 
   361     FIXME: rewrite using RQL queries ?
   380     FIXME: rewrite using RQL queries ?
   362     """
   381     """
   395     # yo, launch checks
   414     # yo, launch checks
   396     if checks:
   415     if checks:
   397         eids_cache = {}
   416         eids_cache = {}
   398         with cnx.security_enabled(read=False, write=False): # ensure no read security
   417         with cnx.security_enabled(read=False, write=False): # ensure no read security
   399             for check in checks:
   418             for check in checks:
   400                 check_func = globals()['check_%s' % check]
   419                 check_func = _CHECKERS[check]
   401                 check_func(repo.schema, cnx, eids_cache, fix=fix)
   420                 check_func(repo.schema, cnx, eids_cache, fix=fix)
   402         if fix:
   421         if fix:
   403             cnx.commit()
   422             cnx.commit()
   404         else:
   423         else:
   405             print()
   424             print()