author | Sylvain Thénault <sylvain.thenault@logilab.fr> |
Wed, 10 Feb 2010 13:58:11 +0100 | |
changeset 4546 | f8ac61376b2b |
parent 4252 | 6c4f109c2b03 |
child 4675 | 9233a8350420 |
permissions | -rw-r--r-- |
0 | 1 |
"""Check integrity of a CubicWeb repository. Hum actually only the system database |
2 |
is checked. |
|
3 |
||
4 |
:organization: Logilab |
|
4212
ab6573088b4a
update copyright: welcome 2010
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3689
diff
changeset
|
5 |
:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. |
0 | 6 |
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
1977
606923dff11b
big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1802
diff
changeset
|
7 |
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
0 | 8 |
""" |
9 |
__docformat__ = "restructuredtext en" |
|
10 |
||
11 |
import sys |
|
1016
26387b836099
use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents:
713
diff
changeset
|
12 |
from datetime import datetime |
0 | 13 |
|
14 |
from logilab.common.shellutils import ProgressBar |
|
15 |
||
2596
d02eed70937f
[R repo, schema] use VIRTUAL_RTYPES const
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2476
diff
changeset
|
16 |
from cubicweb.schema import PURE_VIRTUAL_RTYPES |
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
17 |
from cubicweb.server.sqlutils import SQL_PREFIX |
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
18 |
|
0 | 19 |
def has_eid(sqlcursor, eid, eids): |
20 |
"""return true if the eid is a valid eid""" |
|
21 |
if eids.has_key(eid): |
|
22 |
return eids[eid] |
|
23 |
sqlcursor.execute('SELECT type, source FROM entities WHERE eid=%s' % eid) |
|
24 |
try: |
|
25 |
etype, source = sqlcursor.fetchone() |
|
26 |
except: |
|
27 |
eids[eid] = False |
|
28 |
return False |
|
29 |
if source and source != 'system': |
|
30 |
# XXX what to do... |
|
31 |
eids[eid] = True |
|
32 |
return True |
|
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
33 |
sqlcursor.execute('SELECT * FROM %s%s WHERE %seid=%s' % (SQL_PREFIX, etype, |
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
34 |
SQL_PREFIX, eid)) |
0 | 35 |
result = sqlcursor.fetchall() |
36 |
if len(result) == 0: |
|
37 |
eids[eid] = False |
|
38 |
return False |
|
39 |
elif len(result) > 1: |
|
40 |
msg = ' More than one entity with eid %s exists in source !' |
|
41 |
print >> sys.stderr, msg % eid |
|
42 |
print >> sys.stderr, ' WARNING : Unable to fix this, do it yourself !' |
|
43 |
eids[eid] = True |
|
44 |
return True |
|
45 |
||
46 |
# XXX move to yams? |
|
47 |
def etype_fti_containers(eschema, _done=None): |
|
48 |
if _done is None: |
|
49 |
_done = set() |
|
50 |
_done.add(eschema) |
|
51 |
containers = tuple(eschema.fulltext_containers()) |
|
52 |
if containers: |
|
53 |
for rschema, target in containers: |
|
54 |
if target == 'object': |
|
55 |
targets = rschema.objects(eschema) |
|
56 |
else: |
|
57 |
targets = rschema.subjects(eschema) |
|
58 |
for targeteschema in targets: |
|
59 |
if targeteschema in _done: |
|
60 |
continue |
|
61 |
_done.add(targeteschema) |
|
62 |
for container in etype_fti_containers(targeteschema, _done): |
|
63 |
yield container |
|
64 |
else: |
|
65 |
yield eschema |
|
1802
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
66 |
|
0 | 67 |
def reindex_entities(schema, session): |
68 |
"""reindex all entities in the repository""" |
|
69 |
# deactivate modification_date hook since we don't want them |
|
70 |
# to be updated due to the reindexation |
|
71 |
from cubicweb.server.repository import FTIndexEntityOp |
|
72 |
repo = session.repo |
|
2248
cbf043a2134a
try to create fti table if not existant on rebuild-fti
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
73 |
cursor = session.pool['system'] |
cbf043a2134a
try to create fti table if not existant on rebuild-fti
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
74 |
if not repo.system_source.indexer.has_fti_table(cursor): |
cbf043a2134a
try to create fti table if not existant on rebuild-fti
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
75 |
from indexer import get_indexer |
cbf043a2134a
try to create fti table if not existant on rebuild-fti
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
76 |
print 'no text index table' |
cbf043a2134a
try to create fti table if not existant on rebuild-fti
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
77 |
indexer = get_indexer(repo.system_source.dbdriver) |
cbf043a2134a
try to create fti table if not existant on rebuild-fti
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
78 |
# XXX indexer.init_fti(cursor) once index 0.7 is out |
cbf043a2134a
try to create fti table if not existant on rebuild-fti
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
79 |
indexer.init_extensions(cursor) |
cbf043a2134a
try to create fti table if not existant on rebuild-fti
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
80 |
cursor.execute(indexer.sql_init_fti()) |
3417
fb17a54b358c
unregister hooks by using category
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3374
diff
changeset
|
81 |
repo.config.disabled_hooks_categories.add('metadata') |
fb17a54b358c
unregister hooks by using category
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3374
diff
changeset
|
82 |
repo.config.disabled_hooks_categories.add('integrity') |
1161
936c311010fc
ensure do_fti is true in reindex_entities
sylvain.thenault@logilab.fr
parents:
381
diff
changeset
|
83 |
repo.do_fti = True # ensure full-text indexation is activated |
0 | 84 |
etypes = set() |
85 |
for eschema in schema.entities(): |
|
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3374
diff
changeset
|
86 |
if eschema.final: |
0 | 87 |
continue |
88 |
indexable_attrs = tuple(eschema.indexable_attributes()) # generator |
|
89 |
if not indexable_attrs: |
|
90 |
continue |
|
91 |
for container in etype_fti_containers(eschema): |
|
92 |
etypes.add(container) |
|
93 |
print 'Reindexing entities of type %s' % \ |
|
94 |
', '.join(sorted(str(e) for e in etypes)) |
|
95 |
pb = ProgressBar(len(etypes) + 1) |
|
96 |
# first monkey patch Entity.check to disable validation |
|
713
5adb6d8e5fa7
update imports of "cubicweb.common.entity" and use the new module path "cubicweb.entity"
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
381
diff
changeset
|
97 |
from cubicweb.entity import Entity |
0 | 98 |
_check = Entity.check |
99 |
Entity.check = lambda self, creation=False: True |
|
100 |
# clear fti table first |
|
101 |
session.system_sql('DELETE FROM %s' % session.repo.system_source.dbhelper.fti_table) |
|
102 |
pb.update() |
|
103 |
# reindex entities by generating rql queries which set all indexable |
|
104 |
# attribute to their current value |
|
105 |
for eschema in etypes: |
|
106 |
for entity in session.execute('Any X WHERE X is %s' % eschema).entities(): |
|
107 |
FTIndexEntityOp(session, entity=entity) |
|
108 |
pb.update() |
|
109 |
# restore Entity.check |
|
110 |
Entity.check = _check |
|
111 |
||
1802
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
112 |
|
380 | 113 |
def check_schema(schema, session, eids, fix=1): |
0 | 114 |
"""check serialized schema""" |
115 |
print 'Checking serialized schema' |
|
116 |
unique_constraints = ('SizeConstraint', 'FormatConstraint', |
|
117 |
'VocabularyConstraint', 'RQLConstraint', |
|
118 |
'RQLVocabularyConstraint') |
|
119 |
rql = ('Any COUNT(X),RN,EN,ECTN GROUPBY RN,EN,ECTN ORDERBY 1 ' |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
1263
diff
changeset
|
120 |
'WHERE X is CWConstraint, R constrained_by X, ' |
0 | 121 |
'R relation_type RT, R from_entity ET, RT name RN, ' |
122 |
'ET name EN, X cstrtype ECT, ECT name ECTN') |
|
123 |
for count, rn, en, cstrname in session.execute(rql): |
|
124 |
if count == 1: |
|
125 |
continue |
|
126 |
if cstrname in unique_constraints: |
|
127 |
print "ERROR: got %s %r constraints on relation %s.%s" % ( |
|
128 |
count, cstrname, en, rn) |
|
129 |
||
130 |
||
1802
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
131 |
|
0 | 132 |
def check_text_index(schema, session, eids, fix=1): |
133 |
"""check all entities registered in the text index""" |
|
134 |
print 'Checking text index' |
|
135 |
cursor = session.system_sql('SELECT uid FROM appears;') |
|
136 |
for row in cursor.fetchall(): |
|
137 |
eid = row[0] |
|
138 |
if not has_eid(cursor, eid, eids): |
|
139 |
msg = ' Entity with eid %s exists in the text index but in no source' |
|
140 |
print >> sys.stderr, msg % eid, |
|
141 |
if fix: |
|
142 |
session.system_sql('DELETE FROM appears WHERE uid=%s;' % eid) |
|
143 |
print >> sys.stderr, ' [FIXED]' |
|
144 |
else: |
|
145 |
print >> sys.stderr |
|
146 |
||
147 |
||
148 |
def check_entities(schema, session, eids, fix=1): |
|
149 |
"""check all entities registered in the repo system table""" |
|
150 |
print 'Checking entities system table' |
|
151 |
cursor = session.system_sql('SELECT eid FROM entities;') |
|
152 |
for row in cursor.fetchall(): |
|
153 |
eid = row[0] |
|
154 |
if not has_eid(cursor, eid, eids): |
|
155 |
msg = ' Entity with eid %s exists in the system table but in no source' |
|
156 |
print >> sys.stderr, msg % eid, |
|
157 |
if fix: |
|
158 |
session.system_sql('DELETE FROM entities WHERE eid=%s;' % eid) |
|
159 |
print >> sys.stderr, ' [FIXED]' |
|
160 |
else: |
|
161 |
print >> sys.stderr |
|
162 |
print 'Checking entities tables' |
|
163 |
for eschema in schema.entities(): |
|
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3374
diff
changeset
|
164 |
if eschema.final: |
0 | 165 |
continue |
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
166 |
table = SQL_PREFIX + eschema.type |
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
167 |
column = SQL_PREFIX + 'eid' |
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
168 |
cursor = session.system_sql('SELECT %s FROM %s;' % (column, table)) |
0 | 169 |
for row in cursor.fetchall(): |
170 |
eid = row[0] |
|
171 |
# eids is full since we have fetched everyting from the entities table, |
|
172 |
# no need to call has_eid |
|
173 |
if not eid in eids or not eids[eid]: |
|
174 |
msg = ' Entity with eid %s exists in the %s table but not in the system table' |
|
175 |
print >> sys.stderr, msg % (eid, eschema.type), |
|
176 |
if fix: |
|
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
177 |
session.system_sql('DELETE FROM %s WHERE %s=%s;' % (table, column, eid)) |
0 | 178 |
print >> sys.stderr, ' [FIXED]' |
179 |
else: |
|
180 |
print >> sys.stderr |
|
1802
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
181 |
|
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
182 |
|
0 | 183 |
def bad_related_msg(rtype, target, eid, fix): |
184 |
msg = ' A relation %s with %s eid %s exists but no such entity in sources' |
|
185 |
print >> sys.stderr, msg % (rtype, target, eid), |
|
186 |
if fix: |
|
187 |
print >> sys.stderr, ' [FIXED]' |
|
188 |
else: |
|
189 |
print >> sys.stderr |
|
1802
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
190 |
|
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
191 |
|
0 | 192 |
def check_relations(schema, session, eids, fix=1): |
193 |
"""check all relations registered in the repo system table""" |
|
194 |
print 'Checking relations' |
|
195 |
for rschema in schema.relations(): |
|
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3374
diff
changeset
|
196 |
if rschema.final or rschema in PURE_VIRTUAL_RTYPES: |
0 | 197 |
continue |
198 |
if rschema.inlined: |
|
199 |
for subjtype in rschema.subjects(): |
|
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
200 |
table = SQL_PREFIX + str(subjtype) |
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
201 |
column = SQL_PREFIX + str(rschema) |
380 | 202 |
sql = 'SELECT %s FROM %s WHERE %s IS NOT NULL;' % ( |
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
203 |
column, table, column) |
380 | 204 |
cursor = session.system_sql(sql) |
0 | 205 |
for row in cursor.fetchall(): |
206 |
eid = row[0] |
|
207 |
if not has_eid(cursor, eid, eids): |
|
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
208 |
bad_related_msg(rschema, 'object', eid, fix) |
0 | 209 |
if fix: |
3374
d5bd1b659ce8
[db-check] fix sql to fix bad eid referenced by inlined relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2596
diff
changeset
|
210 |
sql = 'UPDATE %s SET %s=NULL WHERE %s=%s;' % ( |
d5bd1b659ce8
[db-check] fix sql to fix bad eid referenced by inlined relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2596
diff
changeset
|
211 |
table, column, column, eid) |
381 | 212 |
session.system_sql(sql) |
0 | 213 |
continue |
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
214 |
cursor = session.system_sql('SELECT eid_from FROM %s_relation;' % rschema) |
0 | 215 |
for row in cursor.fetchall(): |
216 |
eid = row[0] |
|
217 |
if not has_eid(cursor, eid, eids): |
|
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
218 |
bad_related_msg(rschema, 'subject', eid, fix) |
0 | 219 |
if fix: |
380 | 220 |
sql = 'DELETE FROM %s_relation WHERE eid_from=%s;' % ( |
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
221 |
rschema, eid) |
380 | 222 |
session.system_sql(sql) |
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
223 |
cursor = session.system_sql('SELECT eid_to FROM %s_relation;' % rschema) |
0 | 224 |
for row in cursor.fetchall(): |
225 |
eid = row[0] |
|
226 |
if not has_eid(cursor, eid, eids): |
|
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
227 |
bad_related_msg(rschema, 'object', eid, fix) |
0 | 228 |
if fix: |
380 | 229 |
sql = 'DELETE FROM %s_relation WHERE eid_to=%s;' % ( |
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
230 |
rschema, eid) |
380 | 231 |
session.system_sql(sql) |
0 | 232 |
|
233 |
||
234 |
def check_metadata(schema, session, eids, fix=1): |
|
235 |
"""check entities has required metadata |
|
236 |
||
237 |
FIXME: rewrite using RQL queries ? |
|
238 |
""" |
|
239 |
print 'Checking metadata' |
|
240 |
cursor = session.system_sql("SELECT DISTINCT type FROM entities;") |
|
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
241 |
eidcolumn = SQL_PREFIX + 'eid' |
0 | 242 |
for etype, in cursor.fetchall(): |
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
243 |
table = SQL_PREFIX + etype |
1016
26387b836099
use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents:
713
diff
changeset
|
244 |
for rel, default in ( ('creation_date', datetime.now()), |
26387b836099
use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents:
713
diff
changeset
|
245 |
('modification_date', datetime.now()), ): |
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
246 |
column = SQL_PREFIX + rel |
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
247 |
cursor = session.system_sql("SELECT %s FROM %s WHERE %s is NULL" |
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
248 |
% (eidcolumn, table, column)) |
0 | 249 |
for eid, in cursor.fetchall(): |
250 |
msg = ' %s with eid %s has no %s' |
|
251 |
print >> sys.stderr, msg % (etype, eid, rel), |
|
252 |
if fix: |
|
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
253 |
session.system_sql("UPDATE %s SET %s=%%(v)s WHERE %s=%s ;" |
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
254 |
% (table, column, eidcolumn, eid), |
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
255 |
{'v': default}) |
0 | 256 |
print >> sys.stderr, ' [FIXED]' |
257 |
else: |
|
258 |
print >> sys.stderr |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
1263
diff
changeset
|
259 |
cursor = session.system_sql('SELECT MIN(%s) FROM %sCWUser;' % (eidcolumn, |
1251
af40e615dc89
introduce a 'cw_' prefix on entity table and column names so we don't conflict with sql or DBMS specific keywords
sylvain.thenault@logilab.fr
parents:
1161
diff
changeset
|
260 |
SQL_PREFIX)) |
0 | 261 |
default_user_eid = cursor.fetchone()[0] |
262 |
assert default_user_eid is not None, 'no user defined !' |
|
263 |
for rel, default in ( ('owned_by', default_user_eid), ): |
|
264 |
cursor = session.system_sql("SELECT eid, type FROM entities " |
|
265 |
"WHERE NOT EXISTS " |
|
266 |
"(SELECT 1 FROM %s_relation WHERE eid_from=eid);" |
|
267 |
% rel) |
|
268 |
for eid, etype in cursor.fetchall(): |
|
269 |
msg = ' %s with eid %s has no %s relation' |
|
270 |
print >> sys.stderr, msg % (etype, eid, rel), |
|
271 |
if fix: |
|
272 |
session.system_sql('INSERT INTO %s_relation VALUES (%s, %s) ;' |
|
273 |
% (rel, eid, default)) |
|
274 |
print >> sys.stderr, ' [FIXED]' |
|
275 |
else: |
|
276 |
print >> sys.stderr |
|
277 |
||
278 |
||
279 |
def check(repo, cnx, checks, reindex, fix): |
|
2476
1294a6bdf3bf
application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2248
diff
changeset
|
280 |
"""check integrity of instance's repository, |
0 | 281 |
using given user and password to locally connect to the repository |
282 |
(no running cubicweb server needed) |
|
283 |
""" |
|
284 |
session = repo._get_session(cnx.sessionid, setpool=True) |
|
285 |
# yo, launch checks |
|
286 |
if checks: |
|
287 |
eids_cache = {} |
|
288 |
for check in checks: |
|
289 |
check_func = globals()['check_%s' % check] |
|
290 |
check_func(repo.schema, session, eids_cache, fix=fix) |
|
291 |
if fix: |
|
292 |
cnx.commit() |
|
293 |
else: |
|
294 |
print |
|
295 |
if not fix: |
|
296 |
print 'WARNING: Diagnostic run, nothing has been corrected' |
|
297 |
if reindex: |
|
298 |
cnx.rollback() |
|
299 |
session.set_pool() |
|
300 |
reindex_entities(repo.schema, session) |
|
301 |
cnx.commit() |