>try >begin transaction > *long update command >endtry > >if no error > end transaction >else > rollback >endif>
>** These commands are not supported by Ole DB >#define cnERR_TRIGGER_FAILED 1539 && Trigger failed error number >#define cnDeleteCode 10 >#define cnInsertCode 20 >#define cnUpdateCode 30 >#define cL_USE_AGAIN _triggerlevel > 1 >#define nMaxTrxnLimit 5 >*#define lNoSwitch m.lcKeyExp == chrtran(m.lcKeyExp,"+(-"," ") && Simple field > >* If the trigger was passed, use it. >if vartype(m.tcTriggerType) = 'C' and not empty(m.tcTriggerType) >*!* lnTriggerType = ICASE( ; >*!* upper(m.tcTriggerType)="DELETE", cnDeleteCode, ; >*!* upper(m.tcTriggerType)="INSERT", cnInsertCode, ; >*!* upper(m.tcTriggerType)="UPDATE", cnUpdateCode ) > lnTriggerType = iif( ; > upper(m.tcTriggerType)="DELETE", cnDeleteCode, ; > iif(upper(m.tcTriggerType)="INSERT", cnInsertCode, ; > cnUpdateCode )) >else > local lcRecordState > lcRecordState = getfldstate(-1) >* If the deletion status was changed and the record is deleted, this is a >* "DELETE" trigger. >* Define some constants that'll make the code easier to read. > local ccFLDSTATE_UNCHANGED, ccFLDSTATE_EDITDEL, ccFLDSTATE_NEWUNCHANGED, ccFLDSTATE_NEWCHANGED > ccFLDSTATE_UNCHANGED = '1' >* GETFLDSTATE() 1 = the field is unchanged > ccFLDSTATE_EDITDEL = '2' >* GETFLDSTATE() 2 = the record was edited or deletion status changed > ccFLDSTATE_NEWUNCHANGED = '3' >* GETFLDSTATE() 3 = a new unchanged field or new undeleted record > ccFLDSTATE_NEWCHANGED = '4' >* GETFLDSTATE() 3 = a new changed field or new deleted record > do case > case left(m.lcRecordState, 1) = ccFLDSTATE_EDITDEL and deleted() > lnTriggerType = cnDeleteCode > >* If the deletion status was changed and the record is not deleted, it was >* just recalled, so this is an "INSERT" trigger. > > case left(m.lcRecordState, 1) = ccFLDSTATE_EDITDEL > lnTriggerType = cnInsertCode > >* If this is a new record, this is an "INSERT" trigger. > > case ccFLDSTATE_NEWUNCHANGED $ m.lcRecordState or ; > ccFLDSTATE_NEWCHANGED $ m.lcRecordState > lnTriggerType = cnInsertCode > >* Some field in the table has been changed, so this is an "UPDATE" trigger. > > case ccFLDSTATE_EDITDEL $ m.lcRecordState > lnTriggerType = cnUpdateCode > >* Carl Karsten found a weird bug in VFP: if you have a table with a memo field >* and delete a record such that the subsequent records have to be physically >* moved when you PACK, the "UPDATE" trigger for the table fires when you move >* the record pointer or close the table. In that case, we'll ignore it. > > case m.lcRecordState = replicate(ccFLDSTATE_NEWUNCHANGED, len(m.lcRecordState)) > return > endcase >endif > >* If we're at the top trigger level, start a transaction, create an error flag >* and array variables, get a snapshot of open tables, and set up the >* environment the way we need it. >local lnSelRIDefi, lcDBC >lcDBC = cursorgetprop('Database') > >if cL_USE_AGAIN >** Second or more level of the trigger > select 0 > use (m.lcDBC + "!RIDefinitions") > lnSelRIDefi = select() >else > release gaErrors > public gaErrors[1, 12] > > private paUsed[1], ; > pcExact, ; > pcANSI, ; > pcDeleted, ; > pcOnEscape, ; > pcError, ; > pcOldDBC, plError, plTrxnStarted, plEscaped, pcAlias > pcAlias = alias() > plTrxnStarted = .f. > plError = .f. > plEscaped = .f. > aused(paUsed) > pcExact = set('EXACT') > pcANSI = set('ANSI') > pcDeleted = set('DELETED') > pcError = on('ERROR') > pcOnEscape = on('escape') > pcOldDBC = iif(empty(dbc()), '', '"' + dbc() + '"') > >* this command is not supported in Ole Db > on escape RICleanUp(.t.) > > set exact on > set ansi on > set deleted on > on error LogRIError(error(), message(), message(1),"",.f.,"",.f.,"",0,"",.f.) > > set database to (m.lcDBC) > if not used('RIDefinitions') > use (m.lcDBC + "!RIDefinitions") in 0 && Open table with RI Definitions > endif > lnSelRIDefi = select('RiDefinitions') > if txnlevel() < nMaxTrxnLimit > begin transaction > plTrxnStarted = .t. > endif >endif > >if not m.plError >>