Diff
Not logged in

Differences From:

File tools/cvs2fossil/lib/c2f_pcollrev.tcl part of check-in [2c08006d9d] - Changed the coding of trunk symbols. Using NULL makes for difficult comparisons later when doing integrity checks. Each trunk now has a regular unique id as a symbol. Added documentation to the table definitions, about references, constraints, etc. by aku on 2007-10-25 05:13:41. [view]

To:

File tools/cvs2fossil/lib/c2f_pcollrev.tcl part of check-in [2434ad3bfe] - Added lots of checks looking for inconsistent references between the various objects, mainly revisions. by aku on 2007-10-26 05:29:46. [view]

@@ -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
     }
 
     # # ## ### ##### ######## #############