@@ -166,15 +166,8 @@
first INTEGER REFERENCES revision, -- First revision committed to the branch
bra TEXT NOT NULL -- branch number
}
- # It is in principle possible to collapse the four tables
- # above (from item to barnch) into a single table, with
- # similar columns merged, and unused columns allowing NULL,
- # the use determined by the type. We may do that if the
- # performance is not good enough, but for now clarity of
- # structure over efficiency.
-
# Project level ...
# pLineOfDevelopment, pSymbol, pBranch, pTag, pTrunk
#
# pTrunk <- pLineOfDevelopment
@@ -297,8 +290,9 @@
repository printrevstatistics
repository persistrev
log write 1 collrev "Scan completed"
+ Paranoia
return
}
typemethod discard {} {
@@ -314,8 +308,242 @@
state discard parent
state discard meta
state discard author
state discard cmessage
+ return
+ }
+
+ proc Paranoia {} {
+ # This code performs a number of paranoid checks of the
+ # database for inconsistent cross-references.
+ log write 4 collrev {Check database consistency}
+
+ #
+ # +-> Symbol ------------------+
+ # | ^ | [1]
+ # | | V
+ # | Revision --> File --> Project
+ # | [3] | ^
+ # | V | [2]
+ # +--- Meta -------------------+
+ #
+
+ set n 0
+
+ # Find all revisions which disagree with their line of
+ # development about the project they are owned by.
+ Check \
+ {Revisions and their LODs have to be in the same project} \
+ {disagrees with its LOD about owning project} {
+ SELECT F.name, R.rev
+ FROM revision R, file F, symbol S
+ WHERE R.fid = F.fid
+ AND R.lod = S.sid
+ AND F.pid != S.pid
+ ;
+ }
+ # Find all revisions which disgree with their meta data about
+ # the project they are owned by.
+ Check \
+ {Revisions and their meta data have to be in the same project} \
+ {disagrees with its meta data about owning project} {
+ SELECT F.name, R.rev
+ FROM revision R, file F, meta M
+ WHERE R.fid = F.fid
+ AND R.mid = M.mid
+ AND F.pid != M.pid
+ ;
+ }
+ # Find all revisions which disgree with their meta data about
+ # the branch/line of development they belong to.
+ Check \
+ {Revisions and their meta data have to be in the same LOD} \
+ {disagrees with its meta data about owning LOD} {
+ SELECT F.name, R.rev
+ FROM revision R, meta M, file F
+ WHERE R.mid = M.mid
+ AND R.lod != M.bid
+ AND R.fid = F.fid
+ ;
+ }
+ # Find all revisions with a child which disagrees about the
+ # file they belong to.
+ Check \
+ {Revisions and their children have to be in the same file} \
+ {disagrees with its child about the owning file} {
+ SELECT F.name, R.rev
+ FROM revision R, revision C, file F
+ WHERE R.fid = F.fid
+ AND R.child IS NOT NULL
+ AND R.child = C.rid
+ AND C.fid != R.fid
+ ;
+ }
+ # Find all revisions with a non-NTDB child which disagrees
+ # about the file they belong to.
+ Check \
+ {Revisions and their non-NTDB children have to be in the same file} \
+ {disagrees with its non-NTDB child about the owning file} {
+ SELECT F.name, R.rev
+ FROM revision R, revision C, file F
+ WHERE R.fid = F.fid
+ AND R.dbchild IS NOT NULL
+ AND R.dbchild = C.rid
+ AND C.fid != R.fid
+ ;
+ }
+ # Find all revisions which have a child, but the child does
+ # not have them as parent.
+ Check \
+ {Revisions have to be parents of their children} \
+ {is not the parent of its child} {
+ SELECT F.name, R.rev
+ FROM revision R, revision C, file F
+ WHERE R.fid = F.fid
+ AND R.child IS NOT NULL
+ AND R.child = C.rid
+ AND C.parent != R.rid
+ ;
+ }
+ # Find all revisions which have a child, but the child has a
+ # branch parent.
+ Check \
+ {Revision's children must not be branch starters} \
+ {is parent of a child which is the beginning of a branch} {
+ SELECT F.name, R.rev
+ FROM revision R, revision C, file F
+ WHERE R.fid = F.fid
+ AND R.child IS NOT NULL
+ AND R.child = C.rid
+ AND C.bparent IS NOT NULL
+ ;
+ }
+ # Find all revisions without branch parent which have a
+ # parent, but the parent does not have them as child.
+ Check \
+ {Revisions have to be children of their parents} \
+ {is not the child of its parent} {
+ SELECT F.name, R.rev
+ FROM revision R, revision P, file F
+ WHERE R.fid = F.fid
+ AND R.bparent IS NULL
+ AND R.parent IS NOT NULL
+ AND R.parent = P.rid
+ AND P.child != R.rid
+ ;
+ }
+ # Find all revisions with a branch parent which do not have a
+ # parent.
+ Check \
+ {Branch starting revisions have to have a parent} \
+ {at the beginning of its branch has no parent} {
+ SELECT F.name, R.rev
+ FROM revision R, file F
+ WHERE R.fid = F.fid
+ AND R.bparent IS NOT NULL
+ AND R.parent IS NULL
+ ;
+ }
+ # Find all revisions with a branch parent whose parent has
+ # them as child.
+ Check \
+ {Branch starting revisions must not be children of their parents} \
+ {at the beginning of its branch is the child of its parent} {
+ SELECT F.name, R.rev
+ FROM revision R, revision P, file F
+ WHERE R.fid = F.fid
+ AND R.bparent IS NOT NULL
+ AND R.parent IS NOT NULL
+ AND R.parent = P.child
+ ;
+ }
+ # Find all revisions with a non-NTDB child which are not on
+ # the NTDB.
+ Check \
+ {NTDB to trunk transition has to begin on NTDB} \
+ {has a non-NTDB child, yet is not on the NTDB} {
+ SELECT F.name, R.rev
+ FROM revision R, file F
+ WHERE R.fid = F.fid
+ AND R.dbchild IS NOT NULL
+ AND NOT R.isdefault
+ ;
+ }
+ # Find all revisions with a NTDB parent which are on the NTDB.
+ Check \
+ {NTDB to trunk transition has to end on non-NTDB} \
+ {has a NTDB parent, yet is on the NTDB} {
+ SELECT F.name, R.rev
+ FROM revision R, file F
+ WHERE R.fid = F.fid
+ AND R.dbparent IS NOT NULL
+ AND R.isdefault
+ ;
+ }
+ # Find all revisions with a child which disagrees about the
+ # line of development they belong to.
+ Check \
+ {Revisions and their children have to be in the same LOD} \
+ {and its child disagree about their LOD} {
+
+ SELECT F.name, R.rev
+ FROM revision R, revision C, file F
+ WHERE R.fid = F.fid
+ AND R.child IS NOT NULL
+ AND R.child = C.rid
+ AND C.lod != R.lod
+ ;
+ }
+ # Find all revisions with a non-NTDB child which agrees about
+ # the line of development they belong to.
+ Check \
+ {NTDB and trunk revisions have to be in different LODs} \
+ {on NTDB and its non-NTDB child wrongly agree about their LOD} {
+
+ SELECT F.name, R.rev
+ FROM revision R, revision C, file F
+ WHERE R.fid = F.fid
+ AND R.dbchild IS NOT NULL
+ AND R.dbchild = C.rid
+ AND C.lod = R.lod
+ ;
+ }
+ # Find all revisions with a branch parent which is not their
+ # line of development.
+ Check \
+ {Branch starting revisions have to have their LOD as branch parent} \
+ {at the beginning of its branch does not have the branch as its LOD} {
+ SELECT F.name, R.rev
+ FROM revision R, file F
+ WHERE R.fid = F.fid
+ AND R.bparent IS NOT NULL
+ AND R.lod != R.bparent
+ ;
+ }
+ # Find all revisions with a branch parent whose parent is in
+ # the same line of development.
+ Check \
+ {Revisions and their branch children have to be in different LODs} \
+ {at the beginning of its branch and its parent wrongly agree about their LOD} {
+ SELECT F.name, R.rev
+ FROM revision R, revision P, file F
+ WHERE R.fid = F.fid
+ AND R.bparent IS NOT NULL
+ AND R.parent = P.rid
+ AND R.lod = P.lod
+ ;
+ }
+ return
+ }
+
+ proc Check {header label sql} {
+ upvar 1 n n
+ set ok 1
+ foreach {fname revnr} [state run $sql] {
+ set ok 0
+ trouble fatal "$fname <$revnr> $label"
+ }
+ log write 5 collrev "\[[format %02d [incr n]]\] [expr {$ok ? "Ok " : "Failed"}] ... $header"
return
}
# # ## ### ##### ######## #############