PRIVATE StrtRecCnt, CorrRecCnt, DoneRecCnt, ; StrtLogSiz, CorrLogSiz, DoneLogSiz, ; StrtPhySiz, CorrPhySiz, DonePhySiz, ; nHandler, i, ErrorCode PRIVATE TVsetting, CorrRecVal, RunDescrip PRIVATE Buffering, LastRecNo, LastRecVal StrtRecCnt = 0 CorrRecCnt = 0 DoneRecCnt = 0 StrtLogSiz = 0 CorrLogSiz = 0 DoneLogSiz = 0 StrtPhySiz = 0 CorrPhySiz = 0 DonePhySiz = 0 nHandler = 0 ErrorCode = 0 LastRecNo = 0 LastRecVal = 0 TVsetting = 2 && <-------- TABLEVALIDATE value CorrRecVal = 3 && <-------- Rec cnt from 5 to this value && - used in CorruptTbl procedure RunDescrip = "Non-TR NO check of TBLUPD" * change content of two fields below to vary execution ChkTBLUPD = .F. && <-------- check return from TABLEUPDATE Buffering = "row" && <------ 'none' or 'row' or 'table' * ^- applies to attempted INSERT only ON ERROR SET TABLEVALIDATE TO TVsetting && <================== *-*-*-*-*-*-* SET MULTILOCKS ON DO Setup1Tbl ? 'BEFORE CORRUPTION' ? 'Record count: ', StrtRecCnt ? 'Logical size: ', StrtLogSiz ? 'Physical size:', StrtPhySiz DO CorruptTbl ? ? 'AFTER CORRUPTION' ? 'Record count: ', CorrRecCnt ? 'Logical size: ', CorrLogSiz ? 'Physical size:', CorrPhySiz ? ? RunDescrip ? 'Inserting new record...' *----- code between dashes is relevant ------------ ON ERROR do TellError with ERROR() USE c:\VFP8new\test_tbl IF Buffering = "none" ELSE IF Buffering = "row" =CURSORSETPROP("Buffering", 3, "test_tbl") ELSE =CURSORSETPROP("Buffering", 5, "test_tbl") ENDIF ENDIF INSERT INTO c:\VFP8new\test_tbl VALUES (6) IF Buffering = "none" ELSE IF ChkTBLUPD IF TABLEUPDATE(.T.) ELSE =AERROR(ErrArray) ErrorCode = ErrArray(1) ENDIF ELSE =TABLEUPDATE(.T., .T., "test_tbl") ENDIF ENDIF FLUSH ? 'error No :', ERRORcode ON ERROR *---------- end relevant code ------------------- DO FinalCnts ? ? 'AFTER CORRUPTION' ? 'Record count: ', DoneRecCnt ? 'Logical size: ', DoneLogSiz ? 'Physical size:', DonePhySiz DO ReportCnts ****DO SaveResult && writes record to free tbl. RETURN PROCEDURE Setup1Tbl *-----------------------------------------*********** CLOSE TABLES all CLOSE DATABASES ALL DELETE FILE c:\VFP8new\test_tbl.dbf DELETE FILE c:\VFP8new\test_db.dbc DELETE FILE c:\VFP8new\test_db.dct DELETE FILE c:\VFP8new\test_db.dcx CLEAR CREATE DATABASE c:\VFP8new\test_db CREATE TABLE c:\VFP8new\test_tbl (one_field N(1,0)) FOR i = 1 TO 5 INSERT INTO test_tbl (one_field) VALUES (i) ENDfor * Check size before corruption. SELECT test_tbl StrtRecCnt = RECCOUNT() StrtLogSiz = HEADER() + (StrtRecCnt * RECSIZE()) + 1 USE IN test_tbl nHandler = FOPEN('c:\VFP8new\test_tbl.dbf', 2) StrtPhySiz = FSEEK(nHandler, 0, 2) FCLOSE(nHandler) PROCEDURE CorruptTbl *-------------------------------------------*********** * Manually decrease the record count in the table header. * Normally it would happen accidentally after some power * or network failures. ? ? 'Simulating table corruption...' nHandler = FOPEN('c:\VFP8new\test_tbl.dbf', 2) FSEEK(nHandler, 4) FWRITE(nHandler, CHR(CorrRecVal)) FCLOSE(nHandler) * Check size after corruption USE c:\VFP8new\test_tbl CorrRecCnt = RECCOUNT() CorrLogSiz = HEADER() + (CorrRecCnt * RECSIZE()) + 1 USE IN test_tbl nHandler = FOPEN('c:\VFP8new\test_tbl.dbf', 2) CorrPhySiz = FSEEK(nHandler, 0, 2) FCLOSE(nHandler) PROCEDURE FinalCnts *-------------------------------------------*********** * Check size after insert DoneRecCnt = RECCOUNT() DoneLogSiz = HEADER() + (DoneRecCnt * RECSIZE()) + 1 USE IN test_tbl nHandler = FOPEN('c:\VFP8new\test_tbl.dbf', 2) DonePhySiz = FSEEK(nHandler, 0, 2) FCLOSE(nHandler) PROCEDURE ReportCnts *-------------------------------------------*********** USE c:\VFP8new\test_tbl SHARED LIST GO BOTTOM LastRecNo = RECNO("test_tbl") LastRecVal = test_tbl.One_Field CLOSE DATA ALL PROCEDURE SaveResult *-------------------------------------------*********** USE c:\VFP8New\TVtests1 EXCLUSIVE IN 0 SELECT TVtests1 INSERT INTO TVtests1 FROM memvar USE IN TVtests1 PROCEDURE TellError (nERRORcode) *-------------------------------------------*********** ErrorCode = nERRORcode ? 'Error encountered, code ', nERRORcode RETURN