// Use TableUpd.nui // Class for updating table data use dfallent Use Base.nui // Item_Property command, Various macros (FOR_EX...), cArray, cSet and cStack classes (No User Interface) Use Spec0008.utl // Small arrays with integer Codes (Dictionaries) Use DBMS.nui // Basic DBMS functions (No User Interface) Use ErrorHnd.nui // cErrorHandlerRedirector class and oErrorHandlerQuiet object (No User Interface) Use API_Attr.nui // Functions for querying API attributes (No User Interface) Use ApiIndex.nui // Switch indices offline and online desktop_section object oTableUpdateLockModes is a cIntegerCodeToText IntegerCodeList Define_IntegerCode TUPD_LOCK_MODE_OPEN_EXCLUSIVE "Lock mode" Define_IntegerCode TUPD_LOCK_MODE_ONE_TRANSACTION "All in one transaction" Define_IntegerCode TUPD_LOCK_MODE_UNLOCK_EVERY "Transaction size" Define_IntegerCode TUPD_LOCK_MODE_NO_LOCK "No locking" End_IntegerCodeList end_object object oTableUpdateParameterList is a cIntegerCodeToText IntegerCodeList Define_IntegerCode TUPD_CREATE_NEW_TABLE "Create new table" Define_IntegerCode TUPD_ZEROFILE_TABLE "Reset table before reading" Define_IntegerCode TUPD_OVERWRITE_EXISTING "Overwrite existing data" Define_IntegerCode TUPD_DO_NOT_CHECK_INDEX "Do not check for existing records" Define_IntegerCode TUPD_SWITCH_INDEX_OFFLINE "Switch indices off-line" Define_IntegerCode TUPD_LOCK_MODE "Lock mode" Define_IntegerCode TUPD_UNLOCK_COUNT "Unlock every # record" End_IntegerCodeList end_object end_desktop_section class cTableUpdateParameters is a cArray procedure construct_object integer liImage forward send construct_object liImage set value item TUPD_CREATE_NEW_TABLE to DFFALSE set value item TUPD_ZEROFILE_TABLE to DFFALSE set value item TUPD_OVERWRITE_EXISTING to DFFALSE set value item TUPD_DO_NOT_CHECK_INDEX to DFFALSE set value item TUPD_SWITCH_INDEX_OFFLINE to DFFALSE set value item TUPD_LOCK_MODE to TUPD_LOCK_MODE_UNLOCK_EVERY // Transaction chunk size. Setting TUPD_LOCK_MODE to // TUPD_LOCK_MODE_UNLOCK_EVERY and TUPD_UNLOCK_COUNT to 1 // will make the cTableUpdater respond to every lock request. // Setting it to 500 will make the cTable updater unlock // for every 500 update set value item TUPD_UNLOCK_COUNT to 500 end_procedure end_class // cTableUpdateParameters desktop_section // Return values for iBeginTransaction function object oTableUpdateLockRtnVal is a cIntegerCodeToText IntegerCodeList Define_IntegerCode TUPD_ILOCK_RTN_OK "OK" Define_IntegerCode TUPD_ILOCK_RTN_MISSING_PARAM_OBJECT "Control object not found" Define_IntegerCode TUPD_ILOCK_RTN_TABLE_COULDNT_OPEN "Table could not be opened" End_IntegerCodeList end_object end_desktop_section class cTableUpdater is a cArray procedure construct_object integer liImage forward send construct_object liImage property integer phTableUpdateParameters public 0 property integer piFile public 0 // The name of the table including path. If the table should be opened // via FileList only, this property should be left empty. property string psFilePathName public "" property integer piRequestSaveCount public 0 property integer piErrorCount public 0 property integer piLockRequestCount public 0 // This property holds the transaction chunk size from the setup object // once the transaction is started. property integer piPrv.LockResponse public 0 property integer piPrv.LockMode public 0 property string psPrv.Indices public "" end_procedure // If file is already open when this function os called // no attempt is made to interpret the contents of property // psFilePathName. In that case the file will remain open in its // current mode. function iOpen returns integer local integer liLockMode liRval liFile liOpenMode liOpenRes local string lsFilePathName move TUPD_ILOCK_RTN_OK to liRval // No errors, default return value get piFile to liFile get psFilePathName to lsFilePathName get value of (phTableUpdateParameters(self)) item TUPD_LOCK_MODE to liLockMode // If the file is not already open: ifnot (integer(API_AttrValue_FILE(DF_FILE_OPENED,liFile))) begin if (liLockMode=TUPD_LOCK_MODE_OPEN_EXCLUSIVE) move DF_EXCLUSIVE to liOpenMode else move DF_SHARE to liOpenMode if (lsFilePathName="") move (DBMS_OpenFile(liFile,liOpenMode,0)) to liOpenRes else move (DBMS_OpenFileAs(lsFilePathName,liFile,liOpenMode,0)) to liOpenRes ifnot liOpenRes move TUPD_ILOCK_RTN_TABLE_COULDNT_OPEN to liRval end set piLockRequestCount to 0 set piRequestSaveCount to 0 set piErrorCount to 0 set piPrv.LockResponse to (value(phTableUpdateParameters(self),TUPD_UNLOCK_COUNT)) set piPrv.LockMode to (value(phTableUpdateParameters(self),TUPD_LOCK_MODE)) function_return liRval end_function procedure SwitchIndicesOffLine local integer liFile local string lsIndices get piFile to liFile get DoSwitchIndicesOffLine liFile to lsIndices set psPrv.Indices to lsIndices end_procedure procedure SwitchIndicesOnLine local integer liFile local string lsIndices get piFile to liFile get psPrv.Indices to lsIndices send DoSwitchIndicesOnline liFile lsIndices end_procedure function iBeginTransaction returns integer local integer lhTableUpdateParameters liRval liLockMode lbZerofile liFile local integer IbIndicesOffline get piFile to liFile get phTableUpdateParameters to lhTableUpdateParameters if lhTableUpdateParameters begin get iOpen to liRval if (liRval=TUPD_ILOCK_RTN_OK) begin // It opened OK get value of lhTableUpdateParameters item TUPD_ZEROFILE_TABLE to lbZerofile if lbZerofile zerofile liFile get value of lhTableUpdateParameters item TUPD_SWITCH_INDEX_OFFLINE to IbIndicesOffline if IbIndicesOffline send SwitchIndicesOffLine // If it has been specified that all should be done in one // transaction, we lock the file here: get value of lhTableUpdateParameters item TUPD_LOCK_MODE to liLockMode if liLockMode eq TUPD_LOCK_MODE_ONE_TRANSACTION lock end end else move TUPD_ILOCK_RTN_MISSING_PARAM_OBJECT to liRval function_return liRval end_function function iEndTransaction returns integer local integer liLockMode IbIndicesOffline lhTableUpdateParameters get phTableUpdateParameters to lhTableUpdateParameters get piPrv.LockMode to liLockMode if (liLockMode=TUPD_LOCK_MODE_ONE_TRANSACTION) unlock if (liLockMode=TUPD_LOCK_MODE_UNLOCK_EVERY and piLockRequestCount(self)<>0) unlock get value of lhTableUpdateParameters item TUPD_SWITCH_INDEX_OFFLINE to IbIndicesOffline if IbIndicesOffline send SwitchIndicesOnLine function_return 0 // All is well end_function procedure DoLock local integer liLockRequestCount // We lock only if lock mode has been set to TUPD_LOCK_MODE_UNLOCK_EVERY if (piPrv.LockMode(self)=TUPD_LOCK_MODE_UNLOCK_EVERY) begin get piLockRequestCount to liLockRequestCount ifnot liLockRequestCount lock set piLockRequestCount to (liLockRequestCount+1) end end_procedure procedure DoUnlock local integer liLockRequestCount liTransactionChunkSize get piLockRequestCount to liLockRequestCount get piPrv.LockResponse to liTransactionChunkSize if (liLockRequestCount>=liTransactionChunkSize) begin unlock set piLockRequestCount to 0 end end_procedure // The function returns the number of errors generated by the // saverecord command. function iSaveRecord returns integer local integer liFile liRval get piFile to liFile set piRequestSaveCount to (piRequestSaveCount(self)+1) // send ErrorHnd_Quiet_Activate // Transfer error handling to quiet handler saverecord liFile // send ErrorHnd_Quiet_Deactivate // Reset to normal error handling // move (ErrorHnd_Quiet_ErrorCount()) to liRval if liRval set piErrorCount to (piErrorCount(self)+1) function_return liRval end_function end_class