Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Tablevalidate flaw?
Message
De
17/03/2003 20:44:01
 
 
À
17/03/2003 20:24:53
Information générale
Forum:
Visual FoxPro
Catégorie:
Autre
Divers
Thread ID:
00764400
Message ID:
00766839
Vues:
34
Aleksey
SNIP
>>
>>After the append has been saved, if record count in the header and the file size are not in sync then the error should be reported.
>>
>>I didn't try, but it looks like in your scenario will be no errors and append will NOT be lost.
>>
I get no error when a table is artifically corrupted and an INSERT INTO... is done when no TRANSACTION processing is in effect for either TABLEVALIDATE is 0 or 2. I have reproduced code at the bottom of this message.

The same code, with the same setting for TABLEVALIDATE, yields an error when the two transaction-related lines are de-commented!

Even more strange to me...

When I change the value modifying the record count from 4 (1 away from real) to 3 (2 less records than actual) I get different effects depending on the setting of TABLEVALIDATE!
When TABLEVALIDATE is set to 0 and the record count is 'corrupted' to be 3 instead of 5, then the result of the INSERT INTO produces:
- record count = 4
- logical size = 337 (from 335)
- physical size= 339
When TABLEVALIDATE is 2 the same test gives:
- record count = 5
- logical size = 339 (from 335)
- physical size= 339
yet the table actually only shows 4 records when BROWSEd!!!

I may well have a problem in the test code, but if I do it has eluded me.
LOCAL nRecCount, nLogicalSize, nPhysicalSize, nHandler, i

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

SET TABLEVALIDATE TO 2  &&  <-------- or 0
SET MULTILOCKS ON

CREATE DATABASE c:\VFP8new\test_db
CREATE TABLE    c:\VFP8new\test_tbl (one_field N(1,0))

? 'FileSize after create: ', HEADER() + 1
?

=CURSORSETPROP("Buffering",5)

FOR i = 1 TO 5
    INSERT INTO c:\VFP8new\test_tbl (one_field) VALUES (i)
ENDfor
=TABLEUPDATE(.T.)

* Check size before corruption.
*SELECT test_tbl

nRecCount = RECCOUNT()
nLogicalSize = HEADER() + (nRecCount * RECSIZE()) + 1
USE IN test_tbl

nHandler = FOPEN('c:\VFP8new\test_tbl.dbf', 2)
nPhysicalSize = FSEEK(nHandler, 0, 2)
FCLOSE(nHandler)

? 'BEFORE CORRUPTION'
? 'Record count: ', nRecCount
? 'Logical size: ', nLogicalSize
? 'Physical size:', nPhysicalSize

* Manually decrease the record count in the table header.
* Normally it would happen accidentally after some power 
* or network failures.

?
? 'Simulating table corruption...'

* Open table for R/W, buffered

nHandler = FOPEN('c:\VFP8new\test_tbl.dbf', 2) 
FSEEK(nHandler, 4)
FWRITE(nHandler, CHR(4))  &&  <------- or 3
FCLOSE(nHandler)

* Check size after corruption
USE c:\VFP8new\test_tbl
nRecCount = RECCOUNT()
nLogicalSize = HEADER() + (nRecCount * RECSIZE()) + 1
USE IN test_tbl

nHandler = FOPEN('c:\VFP8new\test_tbl.dbf', 2)
nPhysicalSize = FSEEK(nHandler, 0, 2)
FCLOSE(nHandler)

?
? 'AFTER CORRUPTION'
? 'Record count: ', nRecCount
? 'Logical size: ', nLogicalSize
? 'Physical size:', nPhysicalSize

* I will try inserting a record - NO transaction.
?
? 'Inserting new record...'

USE c:\VFP8new\test_tbl SHARED 
=CURSORSETPROP("Buffering",5)
*BEGIN TRANSACTION
    INSERT INTO c:\VFP8new\test_tbl VALUES (6)
    =TABLEUPDATE(.T.)
    FLUSH 
    WAIT TIMEOUT 5 "Waiting 5 seconds"
*END TRANSACTION
? 'No error:', ERROR()

* Check size after insert
nRecCount = RECCOUNT()
nLogicalSize = HEADER() + (nRecCount * RECSIZE()) + 1

USE IN test_tbl

nHandler = FOPEN('c:\VFP8new\test_tbl.dbf', 2)
nPhysicalSize = FSEEK(nHandler, 0, 2)
FCLOSE(nHandler)

?
? 'AFTER INSERTION'
? 'Record count: ', nRecCount
? 'Logical size: ', nLogicalSize
? 'Physical size:', nPhysicalSize

? 'VFP discarded insert operation.'
CLOSE DATA ALL
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform