Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
RLOCK with Tableupdate
Message
De
03/03/2003 11:50:08
 
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Divers
Thread ID:
00759719
Message ID:
00760399
Vues:
23
Here's the VPP Update Code. I really think it needs to be changed.


#DEFINE E_FAIL_LOC "Failed to update table: "
#DEFINE E_TRIGGERFAIL_LOC "Trigger failed."
#DEFINE E_FIELDNULL_LOC "Field doesn't accept NULL"
#DEFINE E_FIELDRULE_LOC "Field rule violated"
#DEFINE E_RECORDLOCK_LOC "Record in use by another user"
#DEFINE E_ROWRULE_LOC "Row rule violated"
#DEFINE E_UNIQUEINDEX_LOC "Unique index violation"
#DEFINE E_DIRTYREC_LOC "Data has been changed by another user. Overwrite changes with your edits?"
#DEFINE E_NOFORCE_LOC "Could not force table updates."
#DEFINE E_PROMPT_LOC "Error: "
#DEFINE MSGBOX_YES 6

LOCAL aErrors,cErrorMessage,aTablesUsed,nTablesUsed,nTotErr
LOCAL nFld,i,nOldArea,lSuccess,lInDBC,lOverwrite,lHadMessage

DIMENSION aTablesUsed[1]
DIMENSION aErrors[1]
m.cErrorMessage=""
m.lSuccess = .T.
m.nOldArea = SELECT()
m.nTablesUsed = AUSED(aTablesUsed)

* Can wrap everything in transaction if using strictly DBCs
*activate window debug
*suspend
FOR i = 1 TO m.nTablesUsed

SELECT (aTablesUsed[m.i,1])

m.lInDBC = !EMPTY(CURSORGETPROP("Database"))
m.cErrorMessage = ""
m.lOverwrite = .F.
m.lHadMessage = .F.

DO CASE
CASE CURSORGETPROP("Buffering") = 1
* Skip if buffering not on
LOOP
CASE GetFldState(0) = 2 &&deleted record
* Only delete current record and force it
m.lSuccess = TableUpdate(.F.,.T.)
IF m.lSuccess &&successful update
LOOP
ENDIF
CASE !m.lInDBC .AND. GetNextMod(0) <> 0
** old code assumes we are on the same record, but we are adding records and moving
*(ATC("2",GetFldState(-1))#0 OR;
* ATC("3",GetFldState(-1))#0)
** end old code
* Field was edited - in Free Table
* Since free tables are not supported by transactions,
* we must process record by record
m.nModRecord = GetNextMod(0)
DO WHILE m.nModRecord # 0 &&loop locks all records
GO m.nModRecord
m.lSuccess = RLOCK() &&try to lock record
IF !m.lSuccess &&failed to lock record
m.cErrorMessage = E_RECORDLOCK_LOC
UNLOCK ALL
EXIT
ENDIF
IF !m.lHadMessage &&so we don't repeat alert
* See if record(s) modified by another user
FOR m.nFld = 1 TO FCOUNT()
IF TYPE(FIELD(m.nFld)) = "G" &&skip for General fields
LOOP
ENDIF
IF OLDVAL(FIELD(m.nFld)) # CURVAL(FIELD(m.nFld))
m.lHadMessage = .T.

IF MESSAGEBOX(E_DIRTYREC_LOC,4+48) = MSGBOX_YES
m.lOverwrite = .T.
ELSE
m.lSuccess = .F.
UNLOCK ALL
EXIT
ENDIF
ENDIF
ENDFOR
ENDIF
m.nModRecord = GetNextMod(m.nModRecord)
ENDDO
IF m.lSuccess &&was able to lock all records
m.lSuccess = TableUpdate(.T.,m.lOverwrite)
IF m.lSuccess &&was able to update all records
LOOP
ENDIF
UNLOCK ALL
ENDIF
CASE m.lInDBC
BEGIN TRANSACTION
* Try to update all records in selected table
m.lSuccess = TableUpdate(.T.,.F.) &&successful update
IF m.lSuccess
END TRANSACTION
LOOP
ENDIF
ROLLBACK
ENDCASE

* Handle errors
nTotErr =AERROR(aErrors)
DO CASE
CASE nTotErr = 0

CASE aErrors[1,1] = 1539 && Trigger failed
m.cErrorMessage = E_TRIGGERFAIL_LOC
CASE aErrors[1,1] = 1581 && Field doesn't accept NULL
m.cErrorMessage = E_FIELDNULL_LOC
CASE aErrors[1,1] = 1582 && Field rule violated
m.cErrorMessage = E_FIELDRULE_LOC
CASE aErrors[1,1] = 1700 && Record in use by another user
m.cErrorMessage = E_RECORDLOCK_LOC
CASE aErrors[1,1] = 1583 && Row rule violated
m.cErrorMessage = E_ROWRULE_LOC
CASE aErrors[1,1] = 1884 && Unique index violation
m.cErrorMessage = E_UNIQUEINDEX_LOC
CASE aErrors[1,1] = 1585 && Record changed by another user

IF m.lInDBC &&handle free tables above
* Dislpay conflict alert

IF MESSAGEBOX(E_DIRTYREC_LOC,4+48) = MSGBOX_YES
*Try to force update
BEGIN TRANSACTION
m.lSuccess = TABLEUPDATE(.T.,.T.)
IF m.lSuccess
END TRANSACTION
LOOP
ELSE
ROLLBACK
=MESSAGEBOX(E_NOFORCE_LOC)
ENDIF
ENDIF
ENDIF

OTHERWISE
IF !EMPTY(m.cErrorMessage) &&for free table handling above
m.cErrorMessage = E_PROMPT_LOC+aErrors[1,2]
ENDIF
ENDCASE

* Had an error we couldn't handle
=TABLEREVERT(.T.) &&revert all records
m.lSuccess = .F.
IF !EMPTY(m.cErrorMessage)
=MESSAGEBOX(E_FAIL_LOC+m.cErrorMessage)
ENDIF

ENDFOR

SELECT (m.nOldArea)
RETURN m.lSuccess



Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform