home *** CD-ROM | disk | FTP | other *** search
- /* LLOCK.PRG - Logical File/Record Locking functions for Clipper 5.0
-
- This file contains LRLOCK(), LFLOCK(), LUNLOCK(), and LUNLOCKALL()
- which provide logical record and file locking and unlocking,
- respectively. Their purpose is to allow you to lock a record or
- file by convention without any of the limitations of RLOCK() and
- FLOCK() when you need to ignore the lock (as in transaction
- processing). In other words, the give the programmer complete
- control to screw up.
-
- The other functions FINDELEMENT(), LLOCK(), PUTLLOCKINLIST(), and
- REMOVELLOCKFROMLIST() are internal support functions (and thus
- STATIC).
-
- SWITCHES: /n /m /w
-
- REQUIRES: DBFHAND.PRG, ASCANNIL.PRG
-
- Copyright (c) 1990; The DSW Group, Ltd.
-
- */
- #define BEGIN_OFFSET (2147483648) // 2^31
- #define LOCK_IT (.T.)
- #define UNLOCK_IT (.F.)
-
- #define FileOffSet() BEGIN_OFFSET
- #define RecordOffSet() BEGIN_OFFSET+32*(1+FCount())+1+(RecSize()*(RecNo()-1))
-
- #define FileBytes() (1073741823)
- #define RecordBytes() (RecSize())
- #define FindFree() AScanNil(aLockList)
-
- #define AreaNo(a) a[1]
- #define AreaOfs(a) a[2]
- #define AreaBytes(a) a[3]
-
- STATIC aLockList:= {}
-
- //...........................................................
- STATIC FUNC FindElement() // -> nElementForCurrentSelectArea
- LOCAL nEle:= 0
- IF (Len(aLockList)>0)
- nEle:= AScan(aLockList,{|e| IIf(ValType(e)=="A",AreaNo(e)==Select(),.F.)})
- ENDIF
- RETURN (nEle)
-
- //..........................................................
- STATIC PROC PutLLockInList(nOffSet,nBytesToLock)
- LOCAL nEle:= FindElement(),aEle
- aEle:= { Select(), nOffSet, nBytesToLock }
- IF (nEle==0) // SELECT area not already listed
- IF (nEle:= FindFree())==0 // No free elements
- AAdd(aLockList,NIL) // Add a new element
- nEle:= Len(aLockList) // Get it's element number
- ENDIF
- ENDIF
- aLockList[nEle]:= aEle // Store that element
- RETURN
-
- //..........................................................
- STATIC PROC RemoveLLockFromList(nEle)
- aLockList[nEle]:= NIL
- RETURN
-
- //..........................................................
- STATIC FUNC LLock(nOfs,nBytes)
- LOCAL lLocked
- LUnLock()
- IF (lLocked:= FLockRange(DbfHand(),nOfs,nBytes,LOCK_IT))
- PutLLockInList(nOfs,nBytes)
- ENDIF
- RETURN(lLocked)
-
- //..........................................................
- FUNC LFLock()
- RETURN(LLock(FileOffSet(),FileBytes()))
-
- //..........................................................
- FUNC LRLock()
- RETURN(LLock(RecordOffSet(),RecordBytes()))
-
- //..........................................................
- PROC LUnLock()
- LOCAL nEle:= FindElement(), aArea
- IF (nEle>0)
- IF ValType(aArea:= aLockList[nEle])=="A"
- FLockRange(DbfHand(),AreaOfs(aArea),AreaBytes(aArea),UNLOCK_IT)
- RemoveLLockFromList(nEle)
- ENDIF
- ENDIF
- RETURN
-
- //..........................................................
- PROC LUnLockAll()
- STATIC aLockList:= {}
- RETURN
-
- //..........................................................
- // EOF: LLOCK.PRG
-
-