Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
A diagnostic tool to detect a corrupted table
Message
From
21/07/2002 14:19:29
 
General information
Forum:
Visual FoxPro
Category:
Databases,Tables, Views, Indexing and SQL syntax
Miscellaneous
Thread ID:
00680870
Message ID:
00680902
Views:
18
Hi Reygie, I agree with Craig that if you are having problems with corrupted tables, you should determine what is causing it. In our case, we have hundreds of clients and the typical cause of a corrupted table is power outages when the battery backups are no longer working or the user has disconnected the workstations and server from them for some unknown reason. When our app opens any file, we check it and if it is corrupted, we attempt to repair it on the fly using foxfix (the version and commands for foxfix depends on the version of foxpro). The program below is called everytime we open a file. Note that the code is for both FPD26 and VFP6/7. Maybe it will give you some ideas.
***********************************************************************
* PROC:    UseFile
*
* PURPOSE: Open table and correct any detected problems.
*
* USAGE:   =UseFile("INSURED",ddir,"NAME", [expC], [expC], [expC] )
*
* PARAMETERS:
* ufile    = File to open
* udir     = Directory
* uorder   = Index Tag Name
* ualias   = Alias
* uparm1, uparm2, uparm3 = AGAIN, EXCLU or NOINDEX
*
* VERSION: FPD26 and VFP6/7
*
PARAMETERS ufile,udir,uorder,ualias,uparm1,uparm2,uparm3

PRIVATE xreturn
xreturn = .F.

IF EMPTY(ufile)
	WAIT WINDOW 'Error in USEFILE.PRG - File name is missing.'
	RETURN xreturn
ENDIF
IF '.' $ uFile
	uFile = LEFT(uFile,AT('.',uFile)-1)
ENDIF

IF EMPTY(udir)
	udir = ''
ELSE
	IF RIGHT(udir,1) <> '\'
		udir = udir + '\'
	ENDIF
ENDIF

IF EMPTY(ualias)
	ualias = ufile
ENDIF

uagain = .F.
uexclu = .F.
ureindex = .T.
unoselect = .F.

IF !EMPTY(uparm1)
	DO setparms WITH uparm1
ENDIF
IF !EMPTY(uparm2)
	DO setparms WITH uparm2
ENDIF
IF !EMPTY(uparm3)
	DO setparms WITH uparm3
ENDIF

errnum = 0
ON ERROR errnum = ERROR()

DO openfile

DO CASE
CASE errnum = 0								&& No Error
	xreturn = .T.
CASE errnum = 1								&& File "<file>" does not exist.
	=okay("The file "+udir+ufile+".DBF is missing.  Run ATIFIX to recreate or restore from backup.")
CASE errnum = 3								&& File is in use.
	=okay("The file "+ufile+".DBF is in use.  Please check other workstations.")
CASE errnum = 41 AND !FILE((udir+ufile+'.FPT'))	&& MEMO file is missing/invalid.
	=okay("The file "+ufile+".FPT is missing.  Run ATIFIX to recreate or restore from backup.")
CASE errnum = 108							&& File is in use by another.
	=okay("The file "+ufile+".DBF is in use by another.  Please check other workstations.")
CASE errnum = 1705							&& File access denied.
	=okay("File access denied on "+ufile+".DBF.  Please check other workstations.")
CASE INLIST(errnum,19,114,1707)
	*---19   Index file does not match table.
	*---114  Index does not match table.  Recreate index.
	*---1707 Structural CDX file not found.

	IF ureindex AND yesno("The index file "+ufile+".CDX is corrupted or missing.  Reindex?")
		DO idxfiles WITH ufile,.F.,.F.
		RELEASE WINDOW showidx
	ENDIF

	DO openfile

	xreturn = IIF(errnum=0,.T.,.F.)
OTHERWISE
	IF yesno("The file "+ufile+".DBF is corrupted.  Attempt to repair?")

		*--TCH 10/8/2001 Visual Foxpro and FoxFix 5.1 Modifications
		#IF 'VISUAL' $ UPPER(VERSION())
			*--FOXFIX5.1 commands to fix table
			* #include \profiler\progs\lib\FoxFix5.inc
			DO loadff5									&& declares env varialbles for dll
			=FF_SCAN(udir+ufile+'.DBF',-1)		&& -1 = fix all errors
		#ELSE									&& DOS 2.6 Version
			SET LIBRARY TO FOXFIX.PLB
			=FIXDBF(udir+ufile+'.DBF',1)
			SET LIBRARY TO
		#ENDIF
		
		DO openfile

		IF errnum = 0
			xreturn = .T.

			IF ureindex
				USE

				DO idxfiles WITH ufile,.F.,.F.
				RELEASE WINDOW showidx

				DO openfile
			ENDIF
		ELSE
			=okay("The file "+ufile+".DBF can NOT be fixed.  Run ATIFIX to recreate or restore from backup.")
		ENDIF
	ENDIF
ENDCASE

IF xreturn AND !EMPTY(uorder)
	errnum = 0
	SET ORDER TO TAG (uorder) IN (ualias)
	IF INLIST(errnum,26,19,114,1707,1683)
		xreturn = .F.
		IF yesno("The "+ufile+" file cannot be ordered. Try to Reindex?")
			USE

			DO idxfiles WITH ufile,.F.,.F.
			*(DD - Added ON ERROR statement
			ON ERROR errnum = ERROR()
			RELEASE WINDOW showidx

			DO openfile

			SET ORDER TO TAG (uorder) IN (ualias)

			IF INLIST(errnum,26,19,114,1707,1683)
				xreturn = .F.
				DO OKAY WITH uorder+' index not defined in '+ualias+'! Have all users; exit and reindex all data/system files.'
			ELSE
				xreturn = .T.
			ENDIF
		ENDIF
	ENDIF
ENDIF

ON ERROR DO errors WITH PROGRAM()

RETURN xreturn

*---------------------------------------
PROCEDURE openfile

errnum = 0

IF USED(ualias) AND !uagain
	IF !unoselect
		SELECT (ualias)
	ENDIF
ELSE
	IF unoselect
		IF uexclu
			USE (udir+ufile) ALIAS (ualias) IN SELECT(1) EXCLU
		ELSE
			USE (udir+ufile) ALIAS (ualias) IN SELECT(1)
		ENDIF
	ELSE
		SELECT 0
		IF uexclu
			USE (udir+ufile) ALIAS (ualias) EXCLU
		ELSE
			USE (udir+ufile) ALIAS (ualias)
		ENDIF
	ENDIF
ENDIF

*---------------------------------------
PROCEDURE setparms
PARAMETERS xparm

DO CASE
CASE TYPE('xparm') <> 'C'
CASE UPPER(xparm) = 'AGAIN'
	uagain = .T.
CASE UPPER(xparm) = 'EXCLU'
	uexclu = .T.
CASE UPPER(xparm) = 'NOINDEX'
	ureindex = .F.
CASE UPPER(xparm) = 'NOSELECT'
	unoselect = .T.
ENDCASE

*-----------------
*--FoxFix 5.0 Error Message Determination
Function DecodeErrors
#IF 'VISUAL' $ UPPER(VERSION())			&& VFP3 or above version
	Parameter FFError
	Msg = ""
    Msg = Msg + IIF( BITAND(FFError, BAD_DBF_VERSION_ID) != 0, "Version ID"+chr(13), "" )
	Msg = Msg + IIF( BITAND(FFError, BAD_DBF_DATE) != 0, "Last Updated"+chr(13), "" )
   	Msg = Msg + IIF( BITAND(FFError, BAD_DBF_RECORD_CNT) != 0, "Record Count"+chr(13), "" )
    Msg = Msg + IIF( BITAND(FFError, BAD_DBF_HEADER_LEN) != 0, "Header Length"+chr(13), "" )
	Msg = Msg + IIF( BITAND(FFError, BAD_DBF_RECORD_LEN) != 0, "Record Length"+chr(13), "" )
   	Msg = Msg + IIF( BITAND(FFError, BAD_DBF_FLAGS) != 0, "Flags"+chr(13), "" )
    Msg = Msg + IIF( BITAND(FFError, BAD_DBF_CODEPAGE) != 0, "Code Page"+chr(13), "" )
	Msg = Msg + IIF( BITAND(FFError, BAD_DBF_FIELD_DESCRIPTORS) != 0, "Field Descriptors"+chr(13), "" )
   	Msg = Msg + IIF( BITAND(FFError, BAD_DBF_FLT_MARKER) != 0, "Field List Terminator (FLT)"+chr(13), "" )
   	Msg = Msg + IIF( BITAND(FFError, BAD_DBF_DBC_BACKLINK) != 0, "DBC Backlink"+chr(13), "" )
   	Msg = Msg + IIF( BITAND(FFError, BAD_DBF_DELETE_FLAG) != 0, "Delete Flag"+chr(13), "" )
   	Msg = Msg + IIF( BITAND(FFError, BAD_DBF_FIELD_DATA) != 0, "Field Data"+chr(13), "" )
   	Msg = Msg + IIF( BITAND(FFError, BAD_DBF_MEMO_POINTERS) != 0, "Memo Pointers"+chr(13), "" )
    Msg = Msg + IIF( BITAND(FFError, BAD_DBF_FILE_LENGTH) != 0, "File Length"+chr(13), "" )
	Msg = Msg + IIF( BITAND(FFError, BAD_DBF_FIELDS_AUTO_SHIFTED) != 0, "Fields Auto Shifted"+chr(13), "" )
   	Msg = Msg + IIF( BITAND(FFError, BAD_FPT_NEXTBLOCK) != 0, "FPT Next Available Block"+chr(13), "" )
    Msg = Msg + IIF( BITAND(FFError, BAD_FPT_CORRUPT_BLOCK_HEADERS) != 0, "Corrupt memo block header"+chr(13), "" )
    Msg = Msg + IIF( BITAND(FFError, BAD_FPT_BLOCKSIZE) != 0, "Block Size"+chr(13), "" )
	Msg = Msg + IIF( BITAND(FFError, BAD_FPT_FILE_LENGTH) != 0, "FPT File Length"+chr(13), "" )
   	Msg = Msg + IIF( BITAND(FFError, BAD_CDX_STRUCTURE) != 0, "CDX Structure"+chr(13), "" )
    Msg = Msg + IIF( BITAND(FFError, BAD_CDX_EXPRESSIONS) != 0, "CDX Expressions"+chr(13), "" )
	Msg = Msg + IIF( BITAND(FFError, BAD_CDX_FILE_LENGTH) != 0, "CDX File Length"+chr(13), "" )
#ENDIF
return Msg

*--------------
*
* FoxFix 5.0 DLL Total Function declarations
*
PROCEDURE loadff5


#IF 'VISUAL' $ UPPER(VERSION())			&& VFP3 or above version
	DECLARE Integer FF_Scan 					in FoxFix5.DLL String Filename, Integer FixMode
	DECLARE Integer FF_Initialize 				in FoxFix5.DLL String ModuleName
	DECLARE Integer FF_WatchDLL 				in FoxFix5.DLL String ModuleName
	DECLARE Integer FF_SetConfigFile            in FoxFix5.DLL String ConfigName
	DECLARE Integer FF_GetLastErrorCode 		in FoxFix5.DLL Integer bFixed
	DECLARE String  FF_GetLastErrorFile 		in FoxFix5.DLL
	DECLARE String  FF_GetLastLogFile           in FoxFix5.DLL
	DECLARE         FF_SetStealthFixMode 		in FoxFix5.DLL Integer FixMode
	DECLARE Integer FF_GetStealthFixMode 		in FoxFix5.DLL
	DECLARE         FF_SetEnableStealth 		in FoxFix5.DLL Integer Setting
	DECLARE Integer FF_GetEnableStealth 		in FoxFix5.DLL
	DECLARE         FF_SetGenerateAccessDenied 	in FoxFix5.DLL Integer Setting
	DECLARE Integer FF_GetGenerateAccessDenied 	in FoxFix5.DLL
#ENDIF
RETURN

*: EOF: USEFILE.PRG
.·*´¨)
.·`TCH
(..·*

010000110101001101101000011000010111001001110000010011110111001001000010011101010111001101110100
"When the debate is lost, slander becomes the tool of the loser." - Socrates
Vita contingit, Vive cum eo. (Life Happens, Live With it.)
"Life is not measured by the number of breaths we take, but by the moments that take our breath away." -- author unknown
"De omnibus dubitandum"
Previous
Reply
Map
View

Click here to load this message in the networking platform