131f051880 2007-11-09 aku: ## -*- tcl -*- 131f051880 2007-11-09 aku: # # ## ### ##### ######## ############# ##################### 131f051880 2007-11-09 aku: ## Copyright (c) 2007 Andreas Kupries. 131f051880 2007-11-09 aku: # 131f051880 2007-11-09 aku: # This software is licensed as described in the file LICENSE, which 131f051880 2007-11-09 aku: # you should have received as part of this distribution. 131f051880 2007-11-09 aku: # 131f051880 2007-11-09 aku: # This software consists of voluntary contributions made by many 131f051880 2007-11-09 aku: # individuals. For exact contribution history, see the revision 131f051880 2007-11-09 aku: # history and logs, available at http://fossil-scm.hwaci.com/fossil 131f051880 2007-11-09 aku: # # ## ### ##### ######## ############# ##################### 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: ## This package holds a number of integrity checks done on the 131f051880 2007-11-09 aku: ## persistent state. This is used by the passes II and IV. 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: # # ## ### ##### ######## ############# ##################### 131f051880 2007-11-09 aku: ## Requirements 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: package require Tcl 8.4 ; # Required runtime. 131f051880 2007-11-09 aku: package require snit ; # OO system. 131f051880 2007-11-09 aku: package require vc::tools::trouble ; # Error reporting. 131f051880 2007-11-09 aku: package require vc::tools::log ; # User feedback. 131f051880 2007-11-09 aku: package require vc::fossil::import::cvs::state ; # State storage. 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: # # ## ### ##### ######## ############# ##################### 131f051880 2007-11-09 aku: ## 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: snit::type ::vc::fossil::import::cvs::integrity { 131f051880 2007-11-09 aku: # # ## ### ##### ######## ############# 131f051880 2007-11-09 aku: ## Public API 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: typemethod strict {} { 8c6488ded2 2007-11-27 aku: log write 4 integrity {Check database consistency} 8c6488ded2 2007-11-27 aku: 131f051880 2007-11-09 aku: set n 0 131f051880 2007-11-09 aku: AllButMeta 131f051880 2007-11-09 aku: Meta 131f051880 2007-11-09 aku: return 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: typemethod metarelaxed {} { 8c6488ded2 2007-11-27 aku: log write 4 integrity {Check database consistency} 8c6488ded2 2007-11-27 aku: 131f051880 2007-11-09 aku: set n 0 131f051880 2007-11-09 aku: AllButMeta b679ca3356 2007-11-25 aku: return b679ca3356 2007-11-25 aku: } b679ca3356 2007-11-25 aku: b679ca3356 2007-11-25 aku: typemethod changesets {} { 8c6488ded2 2007-11-27 aku: log write 4 integrity {Check database consistency} 8c6488ded2 2007-11-27 aku: b679ca3356 2007-11-25 aku: set n 0 8c6488ded2 2007-11-27 aku: AllChangesets b679ca3356 2007-11-25 aku: RevisionChangesets b679ca3356 2007-11-25 aku: SymbolChangesets 131f051880 2007-11-09 aku: return 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: # # ## ### ##### ######## ############# 131f051880 2007-11-09 aku: ## Internal methods 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: proc AllButMeta {} { 131f051880 2007-11-09 aku: # This code performs a number of paranoid checks of the 131f051880 2007-11-09 aku: # database, searching for inconsistent cross-references. 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: upvar 1 n n ; # Counter for the checks (we print an id before 131f051880 2007-11-09 aku: # the main label). 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: # Find all revisions which disagree with their line of 131f051880 2007-11-09 aku: # development about the project they are owned by. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Revisions and their LODs have to be in the same project} \ 131f051880 2007-11-09 aku: {disagrees with its LOD about owning project} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, file F, symbol S 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.lod = S.sid 131f051880 2007-11-09 aku: AND F.pid != S.pid 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions which disgree with their meta data about 131f051880 2007-11-09 aku: # the project they are owned by. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Revisions and their meta data have to be in the same project} \ 131f051880 2007-11-09 aku: {disagrees with its meta data about owning project} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, file F, meta M 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.mid = M.mid 131f051880 2007-11-09 aku: AND F.pid != M.pid 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions with a primary child which disagrees 131f051880 2007-11-09 aku: # about the file they belong to. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Revisions and their primary children have to be in the same file} \ 131f051880 2007-11-09 aku: {disagrees with its primary child about the owning file} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, revision C, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.child IS NOT NULL 131f051880 2007-11-09 aku: AND R.child = C.rid 131f051880 2007-11-09 aku: AND C.fid != R.fid 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: # Find all revisions with a branch parent symbol whose parent 131f051880 2007-11-09 aku: # disagrees about the file they belong to. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Revisions and their branch children have to be in the same file} \ 131f051880 2007-11-09 aku: {at the beginning of its branch and its parent disagree about the owning file} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, revision P, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.bparent IS NOT NULL 131f051880 2007-11-09 aku: AND R.parent = P.rid 131f051880 2007-11-09 aku: AND R.fid != P.fid 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions with a non-NTDB child which disagrees 131f051880 2007-11-09 aku: # about the file they belong to. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Revisions and their non-NTDB children have to be in the same file} \ 131f051880 2007-11-09 aku: {disagrees with its non-NTDB child about the owning file} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, revision C, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.dbchild IS NOT NULL 131f051880 2007-11-09 aku: AND R.dbchild = C.rid 131f051880 2007-11-09 aku: AND C.fid != R.fid 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions which have a primary child, but the child 131f051880 2007-11-09 aku: # does not have them as parent. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Revisions have to be parents of their primary children} \ 131f051880 2007-11-09 aku: {is not the parent of its primary child} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, revision C, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.child IS NOT NULL 131f051880 2007-11-09 aku: AND R.child = C.rid 131f051880 2007-11-09 aku: AND C.parent != R.rid 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions which have a primrary child, but the 131f051880 2007-11-09 aku: # child has a branch parent symbol making them brach starters. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Primary children of revisions must not start branches} \ 131f051880 2007-11-09 aku: {is parent of a primary child which is the beginning of a branch} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, revision C, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.child IS NOT NULL 131f051880 2007-11-09 aku: AND R.child = C.rid 131f051880 2007-11-09 aku: AND C.bparent IS NOT NULL 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions without branch parent symbol which have a 131f051880 2007-11-09 aku: # parent, but the parent does not have them as primary child. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Revisions have to be primary children of their parents, if any} \ 131f051880 2007-11-09 aku: {is not the child of its parent} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, revision P, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.bparent IS NULL 131f051880 2007-11-09 aku: AND R.parent IS NOT NULL 131f051880 2007-11-09 aku: AND R.parent = P.rid 131f051880 2007-11-09 aku: AND P.child != R.rid 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions with a branch parent symbol which do not 131f051880 2007-11-09 aku: # have a parent. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Branch starting revisions have to have a parent} \ 131f051880 2007-11-09 aku: {at the beginning of its branch has no parent} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.bparent IS NOT NULL 131f051880 2007-11-09 aku: AND R.parent IS NULL 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions with a branch parent symbol whose parent 131f051880 2007-11-09 aku: # has them as primary child. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Branch starting revisions must not be primary children of their parents} \ 131f051880 2007-11-09 aku: {at the beginning of its branch is the primary child of its parent} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, revision P, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.bparent IS NOT NULL 131f051880 2007-11-09 aku: AND R.parent IS NOT NULL 131f051880 2007-11-09 aku: AND R.parent = P.rid 131f051880 2007-11-09 aku: AND P.child = R.rid 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions with a non-NTDB child which are not on 131f051880 2007-11-09 aku: # the NTDB. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {NTDB to trunk transition has to begin on NTDB} \ 131f051880 2007-11-09 aku: {has a non-NTDB child, yet is not on the NTDB} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.dbchild IS NOT NULL 131f051880 2007-11-09 aku: AND NOT R.isdefault 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions with a NTDB parent which are on the NTDB. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {NTDB to trunk transition has to end on non-NTDB} \ 131f051880 2007-11-09 aku: {has a NTDB parent, yet is on the NTDB} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.dbparent IS NOT NULL 131f051880 2007-11-09 aku: AND R.isdefault 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions with a child which disagrees about the 131f051880 2007-11-09 aku: # line of development they belong to. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Revisions and their primary children have to be in the same LOD} \ 131f051880 2007-11-09 aku: {and its primary child disagree about their LOD} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, revision C, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.child IS NOT NULL 131f051880 2007-11-09 aku: AND R.child = C.rid 131f051880 2007-11-09 aku: AND C.lod != R.lod 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions with a non-NTDB child which agrees about 131f051880 2007-11-09 aku: # the line of development they belong to. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {NTDB and trunk revisions have to be in different LODs} \ 131f051880 2007-11-09 aku: {on NTDB and its non-NTDB child wrongly agree about their LOD} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, revision C, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.dbchild IS NOT NULL 131f051880 2007-11-09 aku: AND R.dbchild = C.rid 131f051880 2007-11-09 aku: AND C.lod = R.lod 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions with a branch parent symbol which is not 131f051880 2007-11-09 aku: # their LOD. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Branch starting revisions have to have their LOD as branch parent symbol} \ 131f051880 2007-11-09 aku: {at the beginning of its branch does not have the branch symbol as its LOD} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.bparent IS NOT NULL 131f051880 2007-11-09 aku: AND R.lod != R.bparent 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: # Find all revisions with a branch parent symbol whose parent 131f051880 2007-11-09 aku: # is in the same line of development. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Revisions and their branch children have to be in different LODs} \ 131f051880 2007-11-09 aku: {at the beginning of its branch and its parent wrongly agree about their LOD} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, revision P, file F 131f051880 2007-11-09 aku: WHERE R.fid = F.fid 131f051880 2007-11-09 aku: AND R.bparent IS NOT NULL 131f051880 2007-11-09 aku: AND R.parent = P.rid 131f051880 2007-11-09 aku: AND R.lod = P.lod 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: return 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: proc Meta {} { 131f051880 2007-11-09 aku: # This code performs a number of paranoid checks of the 131f051880 2007-11-09 aku: # database, searching for inconsistent cross-references. 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: upvar 1 n n ; # Counter for the checks (we print an id before 131f051880 2007-11-09 aku: # the main label). 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: # Find all revisions which disgree with their meta data about 131f051880 2007-11-09 aku: # the branch/line of development they belong to. 131f051880 2007-11-09 aku: Check \ 131f051880 2007-11-09 aku: {Revisions and their meta data have to be in the same LOD} \ 131f051880 2007-11-09 aku: {disagrees with its meta data about owning LOD} { 131f051880 2007-11-09 aku: SELECT F.name, R.rev 131f051880 2007-11-09 aku: FROM revision R, meta M, file F 131f051880 2007-11-09 aku: WHERE R.mid = M.mid 131f051880 2007-11-09 aku: AND R.lod != M.bid 131f051880 2007-11-09 aku: AND R.fid = F.fid 131f051880 2007-11-09 aku: ; 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: return 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: 8c6488ded2 2007-11-27 aku: proc AllChangesets {} { 8c6488ded2 2007-11-27 aku: # This code performs a number of paranoid checks of the 8c6488ded2 2007-11-27 aku: # database, searching for inconsistent changeset/revision 8c6488ded2 2007-11-27 aku: # information. 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: upvar 1 n n ; # Counter for the checks (we print an id before 8c6488ded2 2007-11-27 aku: # the main label). 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: # Find all revisions which are not used by at least one 8c6488ded2 2007-11-27 aku: # revision changeset. 8c6488ded2 2007-11-27 aku: Check \ 8c6488ded2 2007-11-27 aku: {All revisions have to be used by least one revision changeset} \ 8c6488ded2 2007-11-27 aku: {is not used by a revision changeset} { 8c6488ded2 2007-11-27 aku: -- Unused revisions = All revisions 8c6488ded2 2007-11-27 aku: -- - revisions used by revision changesets. 8c6488ded2 2007-11-27 aku: -- 8c6488ded2 2007-11-27 aku: -- Both sets can be computed easily, and subtracted 8c6488ded2 2007-11-27 aku: -- from each other. Then we can get the associated 8c6488ded2 2007-11-27 aku: -- file (name) for display. 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: SELECT F.name, R.rev 8c6488ded2 2007-11-27 aku: FROM revision R, file F 8c6488ded2 2007-11-27 aku: WHERE R.rid IN (SELECT rid FROM revision -- All revisions 8c6488ded2 2007-11-27 aku: EXCEPT -- subtract 8c6488ded2 2007-11-27 aku: SELECT CR.rid FROM csrevision CR, changeset C -- revisions used 8c6488ded2 2007-11-27 aku: WHERE C.cid = CR.cid -- by any revision 8c6488ded2 2007-11-27 aku: AND C.type = 0) -- changeset 8c6488ded2 2007-11-27 aku: AND R.fid = F.fid -- get file of unused revision 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: # Find all revisions which are used by more than one revision 8c6488ded2 2007-11-27 aku: # changeset. 8c6488ded2 2007-11-27 aku: Check \ 8c6488ded2 2007-11-27 aku: {All revisions have to be used by at most one revision changeset} \ 8c6488ded2 2007-11-27 aku: {is used by multiple revision changesets} { 8c6488ded2 2007-11-27 aku: -- Principle of operation: Get all revision/changeset 8c6488ded2 2007-11-27 aku: -- pairs for all revision changesets, group by 8c6488ded2 2007-11-27 aku: -- revision to aggregate the changeset, counting 8c6488ded2 2007-11-27 aku: -- them. From the resulting revision/count table 8c6488ded2 2007-11-27 aku: -- select those with more than one user, and get their 8c6488ded2 2007-11-27 aku: -- associated file (name) for display. 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: SELECT F.name, R.rev 8c6488ded2 2007-11-27 aku: FROM revision R, file F, 8c6488ded2 2007-11-27 aku: (SELECT CR.rid AS rid, count(CR.cid) AS count 8c6488ded2 2007-11-27 aku: FROM csrevision CR, changeset C 8c6488ded2 2007-11-27 aku: WHERE C.type = 0 8c6488ded2 2007-11-27 aku: AND C.cid = CR.cid 8c6488ded2 2007-11-27 aku: GROUP BY CR.rid ) AS U 8c6488ded2 2007-11-27 aku: WHERE U.count > 1 8c6488ded2 2007-11-27 aku: AND R.rid = U.rid 8c6488ded2 2007-11-27 aku: AND R.fid = F.fid 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: # All revisions in all changesets have to agree on the LOD 8c6488ded2 2007-11-27 aku: # their changeset belongs to. In other words, all revisions in 8c6488ded2 2007-11-27 aku: # a changeset have to refer to the same line of development. 8c6488ded2 2007-11-27 aku: # 8c6488ded2 2007-11-27 aku: # Instead of looking at all pairs of revisions in all 8c6488ded2 2007-11-27 aku: # changesets we generate the distinct set of all LODs 8c6488ded2 2007-11-27 aku: # referenced by the revisions of a changeset, look for those 8c6488ded2 2007-11-27 aku: # with cardinality > 1, and get the identifying information 8c6488ded2 2007-11-27 aku: # for the changesets found thusly. 8c6488ded2 2007-11-27 aku: CheckCS \ 8c6488ded2 2007-11-27 aku: {All revisions in a changeset have to belong to the same LOD} \ 8c6488ded2 2007-11-27 aku: {: Its revisions disagree about the LOD they belong to} { 8c6488ded2 2007-11-27 aku: SELECT T.name, C.cid 8c6488ded2 2007-11-27 aku: FROM changeset C, cstype T 8c6488ded2 2007-11-27 aku: WHERE C.cid IN (SELECT U.cid 8c6488ded2 2007-11-27 aku: FROM (SELECT DISTINCT CR.cid AS cid, R.lod AS lod 8c6488ded2 2007-11-27 aku: FROM csrevision CR, revision R 8c6488ded2 2007-11-27 aku: WHERE CR.rid = R.rid) AS U 8c6488ded2 2007-11-27 aku: GROUP BY U.cid HAVING COUNT(U.lod) > 1) 8c6488ded2 2007-11-27 aku: AND T.tid = C.type 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: # All revisions in all changesets have to agree on the project 8c6488ded2 2007-11-27 aku: # their changeset belongs to. In other words, all revisions in 8c6488ded2 2007-11-27 aku: # a changeset have to refer to the same project. 8c6488ded2 2007-11-27 aku: # 8c6488ded2 2007-11-27 aku: # Instead of looking at all pairs of revisions in all 8c6488ded2 2007-11-27 aku: # changesets we generate the distinct set of all projects 8c6488ded2 2007-11-27 aku: # referenced by the revisions of a changeset, look for those 8c6488ded2 2007-11-27 aku: # with cardinality > 1, and get the identifying information 8c6488ded2 2007-11-27 aku: # for the changesets found thusly. 8c6488ded2 2007-11-27 aku: CheckCS \ 8c6488ded2 2007-11-27 aku: {All revisions in a changeset have to belong to the same project} \ 8c6488ded2 2007-11-27 aku: {: Its revisions disagree about the project they belong to} { 8c6488ded2 2007-11-27 aku: SELECT T.name, C.cid 8c6488ded2 2007-11-27 aku: FROM changeset C, cstype T 8c6488ded2 2007-11-27 aku: WHERE C.cid IN (SELECT U.cid 8c6488ded2 2007-11-27 aku: FROM (SELECT DISTINCT CR.cid AS cid, F.pid AS pid 8c6488ded2 2007-11-27 aku: FROM csrevision CR, revision R, file F 8c6488ded2 2007-11-27 aku: WHERE CR.rid = R.rid 8c6488ded2 2007-11-27 aku: AND F.fid = R.fid) AS U 8c6488ded2 2007-11-27 aku: GROUP BY U.cid HAVING COUNT(U.pid) > 1) 8c6488ded2 2007-11-27 aku: AND T.tid = C.type 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: # All revisions in a single changeset have to belong to 8c6488ded2 2007-11-27 aku: # different files. Conversely: No two revisions of a single 8c6488ded2 2007-11-27 aku: # file are allowed to be in the same changeset. 8c6488ded2 2007-11-27 aku: # 8c6488ded2 2007-11-27 aku: # Instead of looking at all pairs of revisions in all 8c6488ded2 2007-11-27 aku: # changesets we generate the distinct set of all files 8c6488ded2 2007-11-27 aku: # referenced by the revisions of a changeset, and look for 8c6488ded2 2007-11-27 aku: # those with cardinality < the cardinality of the set of 8c6488ded2 2007-11-27 aku: # revisions, and get the identifying information for the 8c6488ded2 2007-11-27 aku: # changesets found thusly. 8c6488ded2 2007-11-27 aku: CheckCS \ 8c6488ded2 2007-11-27 aku: {All revisions in a changeset have to belong to different files} \ 8c6488ded2 2007-11-27 aku: {: Its revisions share files} { 8c6488ded2 2007-11-27 aku: SELECT T.name, C.cid 8c6488ded2 2007-11-27 aku: FROM changeset C, cstype T 8c6488ded2 2007-11-27 aku: WHERE C.cid IN (SELECT VV.cid 8c6488ded2 2007-11-27 aku: FROM (SELECT U.cid as cid, COUNT (U.fid) AS fcount 8c6488ded2 2007-11-27 aku: FROM (SELECT DISTINCT CR.cid AS cid, R.fid AS fid 8c6488ded2 2007-11-27 aku: FROM csrevision CR, revision R 8c6488ded2 2007-11-27 aku: WHERE CR.rid = R.rid) AS U 8c6488ded2 2007-11-27 aku: GROUP BY U.cid) AS UU, 8c6488ded2 2007-11-27 aku: (SELECT V.cid AS cid, COUNT (V.rid) AS rcount 8c6488ded2 2007-11-27 aku: FROM csrevision V 8c6488ded2 2007-11-27 aku: GROUP BY V.cid) AS VV 8c6488ded2 2007-11-27 aku: WHERE VV.cid = UU.cid 8c6488ded2 2007-11-27 aku: AND UU.fcount < VV.rcount) 8c6488ded2 2007-11-27 aku: AND T.tid = C.type 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: return bf83201c7f 2007-11-27 aku: } bf83201c7f 2007-11-27 aku: bf83201c7f 2007-11-27 aku: proc RevisionChangesets {} { 8c6488ded2 2007-11-27 aku: # This code performs a number of paranoid checks of the 8c6488ded2 2007-11-27 aku: # database, searching for inconsistent changeset/revision 8c6488ded2 2007-11-27 aku: # information. 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: upvar 1 n n ; # Counter for the checks (we print an id before 8c6488ded2 2007-11-27 aku: # the main label). 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: # All revisions used by revision changesets have to refer to 8c6488ded2 2007-11-27 aku: # the same meta information as their changeset. 8c6488ded2 2007-11-27 aku: CheckInCS \ 8c6488ded2 2007-11-27 aku: {All revisions have to agree with their revision changeset about the used meta information} \ 8c6488ded2 2007-11-27 aku: {disagrees with its revision changeset @ about the meta information} { 8c6488ded2 2007-11-27 aku: SELECT CT.name, C.cid, F.name, R.rev 8c6488ded2 2007-11-27 aku: FROM changeset C, cstype CT, revision R, file F, csrevision CR 8c6488ded2 2007-11-27 aku: WHERE C.type = 0 -- revision changesets only 8c6488ded2 2007-11-27 aku: AND C.cid = CR.cid -- changeset --> its revisions 8c6488ded2 2007-11-27 aku: AND R.rid = CR.rid -- look at them 8c6488ded2 2007-11-27 aku: AND R.mid != C.src -- Only those which disagree with changeset about the meta 8c6488ded2 2007-11-27 aku: AND R.fid = F.fid -- get file of the revision 8c6488ded2 2007-11-27 aku: AND CT.tid = C.type -- get changeset type, for labeling 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: return bf83201c7f 2007-11-27 aku: } bf83201c7f 2007-11-27 aku: bf83201c7f 2007-11-27 aku: proc SymbolChangesets {} { 8c6488ded2 2007-11-27 aku: # This code performs a number of paranoid checks of the 8c6488ded2 2007-11-27 aku: # database, searching for inconsistent changeset/revision 8c6488ded2 2007-11-27 aku: # information. 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: return ; # Disabled for now, bottlenecks ... 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: upvar 1 n n ; # Counter for the checks (we print an id before 8c6488ded2 2007-11-27 aku: # the main label). 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: # The next two checks are BOTTLENECKS. In essence we are 8c6488ded2 2007-11-27 aku: # checking each symbol changeset one by one. 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: # TODO: Try to rephrase the checks to make more use of 8c6488ded2 2007-11-27 aku: # indices, set and stream operations. 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: # All revisions used by tag symbol changesets have to have the 8c6488ded2 2007-11-27 aku: # changeset's tag associated with them. 8c6488ded2 2007-11-27 aku: CheckInCS \ 8c6488ded2 2007-11-27 aku: {All revisions used by tag symbol changesets have to have the changeset's tag attached to them} \ 8c6488ded2 2007-11-27 aku: {does not have the tag of its symbol changeset @ attached to it} { 8c6488ded2 2007-11-27 aku: SELECT CT.name, C.cid, F.name, R.rev 8c6488ded2 2007-11-27 aku: FROM changeset C, cstype CT, revision R, file F, csrevision CR, tag T 8c6488ded2 2007-11-27 aku: WHERE C.type = 1 -- symbol changesets only 8c6488ded2 2007-11-27 aku: AND C.src = T.sid -- tag only, linked by symbol id 8c6488ded2 2007-11-27 aku: AND C.cid = CR.cid -- changeset --> its revisions 8c6488ded2 2007-11-27 aku: AND R.rid = CR.rid -- look at the revisions 8c6488ded2 2007-11-27 aku: -- and look for the tag among the attached ones. 8c6488ded2 2007-11-27 aku: AND T.sid NOT IN (SELECT TB.sid 8c6488ded2 2007-11-27 aku: FROM tag TB 8c6488ded2 2007-11-27 aku: WHERE TB.rev = R.rid) 8c6488ded2 2007-11-27 aku: AND R.fid = F.fid -- get file of revision 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: # All revisions used by branch symbol changesets have to have 8c6488ded2 2007-11-27 aku: # the changeset's branch associated with them. 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: CheckInCS \ 8c6488ded2 2007-11-27 aku: {All revisions used by branch symbol changesets have to have the changeset's branch attached to them} \ 8c6488ded2 2007-11-27 aku: {does not have the branch of its symbol changeset @ attached to it} { 8c6488ded2 2007-11-27 aku: SELECT CT.name, C.cid, F.name, R.rev, C.cid 8c6488ded2 2007-11-27 aku: FROM changeset C, cstype CT, revision R, file F, csrevision CR, branch B 8c6488ded2 2007-11-27 aku: WHERE C.type = 1 -- symbol changesets only 8c6488ded2 2007-11-27 aku: AND C.src = B.sid -- branches only 8c6488ded2 2007-11-27 aku: AND C.cid = CR.cid -- changeset --> its revisions 8c6488ded2 2007-11-27 aku: AND R.rid = CR.rid -- look at the revisions 8c6488ded2 2007-11-27 aku: -- and look for the branch among the attached ones. 8c6488ded2 2007-11-27 aku: AND B.sid NOT IN (SELECT BB.sid 8c6488ded2 2007-11-27 aku: FROM branch BB 8c6488ded2 2007-11-27 aku: WHERE BB.root = R.rid) 8c6488ded2 2007-11-27 aku: AND R.fid = F.fid -- get file of revision 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: # TODO 8c6488ded2 2007-11-27 aku: # The state has to contain at least one tag symbol changeset 8c6488ded2 2007-11-27 aku: # for all known tags. 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: # TODO 8c6488ded2 2007-11-27 aku: # The state has to contain at least one branch symbol changeset 8c6488ded2 2007-11-27 aku: # for all known branches. 8c6488ded2 2007-11-27 aku: return bf83201c7f 2007-11-27 aku: } bf83201c7f 2007-11-27 aku: bf83201c7f 2007-11-27 aku: 131f051880 2007-11-09 aku: proc Check {header label sql} { 131f051880 2007-11-09 aku: upvar 1 n n 131f051880 2007-11-09 aku: set ok 1 131f051880 2007-11-09 aku: foreach {fname revnr} [state run $sql] { 131f051880 2007-11-09 aku: set ok 0 131f051880 2007-11-09 aku: trouble fatal "$fname <$revnr> $label" 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: log write 5 integrity "\[[format %02d [incr n]]\] [expr {$ok ? "Ok " : "Failed"}] ... $header" 8c6488ded2 2007-11-27 aku: return 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: proc CheckCS {header label sql} { 8c6488ded2 2007-11-27 aku: upvar 1 n n 8c6488ded2 2007-11-27 aku: set ok 1 8c6488ded2 2007-11-27 aku: foreach {ctype cid} [state run $sql] { 8c6488ded2 2007-11-27 aku: set ok 0 8c6488ded2 2007-11-27 aku: trouble fatal "<$ctype $cid> $label" 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: log write 5 integrity "\[[format %02d [incr n]]\] [expr {$ok ? "Ok " : "Failed"}] ... $header" 8c6488ded2 2007-11-27 aku: return 8c6488ded2 2007-11-27 aku: } 8c6488ded2 2007-11-27 aku: 8c6488ded2 2007-11-27 aku: proc CheckInCS {header label sql} { 8c6488ded2 2007-11-27 aku: upvar 1 n n 8c6488ded2 2007-11-27 aku: set ok 1 8c6488ded2 2007-11-27 aku: foreach {cstype csid fname revnr} [state run $sql] { 8c6488ded2 2007-11-27 aku: set ok 0 8c6488ded2 2007-11-27 aku: set b "<$cstype $csid>" 8c6488ded2 2007-11-27 aku: trouble fatal "$fname <$revnr> [string map [list @ $b] $label]" 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: log write 5 integrity "\[[format %02d [incr n]]\] [expr {$ok ? "Ok " : "Failed"}] ... $header" 131f051880 2007-11-09 aku: return 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: # # ## ### ##### ######## ############# 131f051880 2007-11-09 aku: ## Configuration 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: pragma -hasinstances no ; # singleton 131f051880 2007-11-09 aku: pragma -hastypeinfo no ; # no introspection 131f051880 2007-11-09 aku: pragma -hastypedestroy no ; # immortal 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: # # ## ### ##### ######## ############# 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: namespace eval ::vc::fossil::import::cvs { 131f051880 2007-11-09 aku: namespace export integrity 131f051880 2007-11-09 aku: namespace eval integrity { 131f051880 2007-11-09 aku: namespace import ::vc::fossil::import::cvs::state 131f051880 2007-11-09 aku: namespace import ::vc::tools::trouble 131f051880 2007-11-09 aku: namespace import ::vc::tools::log 131f051880 2007-11-09 aku: log register integrity 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: } 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: # # ## ### ##### ######## ############# ##################### 131f051880 2007-11-09 aku: ## Ready 131f051880 2007-11-09 aku: 131f051880 2007-11-09 aku: package provide vc::fossil::import::cvs::integrity 1.0 131f051880 2007-11-09 aku: return