Navigation: Language Reference > 13 - Built-in Functions >====== CALLBACK (register or unregister a FileCallBackInterface) ====== | |
CALLBACK(entity, FileCallBackInterface, [flag])
CALLBACK | Register or unregister a FileCallBackInterface. |
Entity | The label of a FILE or VIEW. |
FileCallBackInterface | The label of the interface that implements the FileCallBackInterface. The methods of the FileCallbackInterface are called automatically before (method FunctionCalled) and after (method FunctionDone) each file operation. |
Flag | An integer constant, variable, EQUATE, or expression that indicates whether or not to unregister an interface associated with a FILE or VIEW. A value of one (1 or TRUE) unregisters the interface. If omitted, the interface is registered with the entity. |
The CALLBACK method registers a callback interface with the specified entity. The methods of the registered interface are called whenever a file operation is done. Multiple interfaces can be registered with an entity.
To unregister an interface, set the flag to TRUE. Any registered interfaces must be unregistered before the object that implements the interface is removed.
If a VIEW has callbacks registered with it and the primary FILE of that VIEW also has callbacks registered, then all the callbacks registered for the VIEW are called before the callbacks for the primary FILE.
To distinguish if a callback method is being called by a FILE operation or a VIEW operation you need to check the new Params.View field. It will be NULL for FILE operations and equal to the VIEW that is being used for VIEW operations.
Example:
PROGRAM
MAP
END
INCLUDE ('FILECB.INC'),ONCE
!Data file
People FILE,DRIVER('TOPSPEED'),PRE(PEO),CREATE,BINDABLE,THREAD
KeyId KEY(PEO:Id),NOCASE,OPT
KeyLastName KEY(PEO:LastName),DUP,NOCASE
Record RECORD,PRE()
Id LONG
FirstName STRING(30)
LastName STRING(30)
Gender LONG
END
END
!Log File
LogFile FILE,DRIVER('BASIC','/ALWAYSQUOTE=OFF /COMMA=1,1'),CREATE,NAME('logfile.txt')
Record RECORD
Operation STRING(200)
END
END
!FileCallBack Class
FCB CLASS,IMPLEMENTS(FileCallBackInterface)
END
CODE
CALLBACK(People, FCB.FileCallBackInterface) !Register FCB interface
CREATE(Logfile) !Create log file
OPEN(Logfile) !Open log file
OPEN(People) !Open data file
SET(PEO:KeyId, PEO:KeyID) !Set and
LOOP !loop thru
NEXT(People) !data until
IF ERRORCODE()
BREAK !end of file
END
END
CLOSE(People) !Close data file
!Unregister FCB interface:
CALLBACK(People, FCB.FileCallBackInterface, TRUE)
!This method is called prior to each operation of the data file.
!The log file is updated with the file operation that is being executed.
FCB.FileCallBackInterface.FunctionCalled |
PROCEDURE(SIGNED opCode, *Params Parameters, *CSTRING ErrCode, *CSTRING ErrMsg)
p LIKE(Params)
CODE
p = Parameters
IF p.View &= NULL !used to detect VIEW or FILE callback
f = 'FILE'
ELSE
f = 'VIEW'
END
CASE opCode
OF DriverOp:ADD
logFile.Operation = 'ADD(f)'
OF DriverOp:APPEND
logFile.Operation = 'APPEND(f)'
OF DriverOp:CLOSE
logFile.Operation = 'CLOSE(f)'
OF DriverOp:COPY
logFile.Operation = 'COPY(f,'&CLIP(Parameters.Text)&
')'
OF DriverOp:CREATE
logFile.Operation = 'CREATE(f)'
OF DriverOp:DELETE
logFile.Operation = 'DELETE(f)'
OF DriverOp:NEXT
logFile.Operation = 'NEXT(f)'
OF DriverOp:OPEN
logFile.Operation = 'OPEN(f,'&Parameters.openMode&')'
OF DriverOp:PUT
logFile.Operation = 'PUT(f)'
OF DriverOp:SETkeykey
logFile.Operation = 'SET(k,k)'
END
ADD(logFile)
RETURN TRUE
!This method is called after each operation to the data file.
!This simply returns a TRUE according to the rules of the FileCallBackInterface.
FCB.FileCallBackInterface.FunctionDone |
PROCEDURE(SIGNED opCode, Params Parameters, *CSTRING ErrCode, *CSTRING ErrMsg)
CODE
RETURN TRUE
Additional Example:
PROGRAM
INCLUDE('FILECB.INC')
MAP
viewTest(VIEW v)
check(STRING msg)
Test(STRING Name, FILE log, FILE f, VIEW v1, VIEW v2)
END
Dept FILE,DRIVER('Memory'),NAME('DEPT'),PRE(DEP),CREATE
PK_DEPT KEY(DEP:DEPTNO),PRIMARY
Record RECORD
DEPTNO BYTE
DNAME CSTRING(15)
LOC CSTRING(14)
END
END
LogFile FILE,DRIVER('ASCII'),CREATE,NAME('CB.LOG')
Record RECORD
Line STRING(100)
END
END
MyClass CLASS,IMPLEMENTS(FileCallBackInterface),TYPE
Name CSTRING(30),PRIVATE
logf &FILE,PRIVATE
baseF &FILE,PRIVATE
line ANY,PRIVATE
inView BOOL,PRIVATE
Init PROCEDURE(STRING n, FILE f, FILE log)
Kill PROCEDURE()
END
MemoryFile MyClass
ISAMView MyClass
iView1 VIEW(Dept).
iView2 VIEW(Dept).
CODE
CREATE(LogFile)
Check('Create LogFile')
OPEN(LogFile)
Check('OPEN LogFile')
MemoryFile.Init('Memory', Dept, LogFile)
ISAMView.Init('ISAMView', iView1, LogFile)
CREATE(Dept)
Check('Create Dept')
Test('Memory', LogFile, Dept, iView1, iView2)
MemoryFile.Kill()
ISAMView.Kill()
MESSAGE('Done')
viewTest PROCEDURE(VIEW v)
CODE
OPEN(v)
SET(v)
NEXT(v)
CLOSE(v)
Check PROCEDURE(STRING msg)
CODE
IF ERRORCODE()
IF ERRORCODE() = 90
HALT(1, msg & ' caused system error ' & FILEERRORCODE() & ' : ' |
& FILEERROR())
END
HALT(1, msg & ' caused error ' & ERRORCODE() & ' : ' & ERROR())
END
Test PROCEDURE(STRING msg, FILE log, FILE f, VIEW v1, VIEW v2)
g &GROUP
l ANY
CODE
g &= log{PROP:Record}
l &= WHAT(g, 1)
l = '!File Operations'
ADD(log)
OPEN(f)
Check(msg & ' OPEN')
SET(f)
NEXT(f)
l = '!View 1 Operations'
ADD(log)
viewTest(v1)
l = '!View 2 Operations'
ADD(log)
viewTest(v2)
l = '!Done'
ADD(log)
CLOSE(f)
MyClass.Init PROCEDURE(STRING n, FILE f, FILE log)
g &GROUP
CODE
CALLBACK(f, SELF.FileCallBackInterface)
SELF.logf &= log
SELF.basef &= f
SELF.Name = CLIP(n)
g &= SELF.logf{PROP:Record}
SELF.line &= WHAT(g, 1)
MyClass.Kill PROCEDURE()
CODE
CALLBACK(SELF.baseF, SELF.FileCallBackInterface, TRUE)
Check('Uncallback ' & SELF.Name)
SELF.line &= NULL
MyClass.FileCallBackInterface.FunctionCalled PROCEDURE(SIGNED opCode, |
*Params Parameters, *CSTRING ErrCode, *CSTRING ErrMsg)
p LIKE(Params)
f CSTRING(5),AUTO
logit BOOL(true)
CODE
p = Parameters
IF p.View &= NULL
f = 'FILE'
ELSE
f = 'VIEW'
END
CASE opCode
OF DriverOp:Create
SELF.line = 'CREATE(' & f & ' ' & SELF.Name & ')'
OF DriverOp:NEXT
SELF.line = 'NEXT(' & f & ' ' & SELF.Name & ')'
OF DriverOp:OPEN
SELF.line = 'OPEN(' & f & ' ' & SELF.Name & ','&Parameters.openMode&')'
OF DriverOp:PUT
SELF.line = 'PUT(' & f & ' ' & SELF.Name & ')'
OF DriverOp:VIEWSTART
SELF.InView = TRUE
logit = FALSE
OF DriverOp:VIEWSTOP
SELF.InView = FALSE
logit = FALSE
ELSE
logit = FALSE
END
IF logit AND ~SELF.InView
ADD(SELF.logF)
END
RETURN TRUE
MyClass.FileCallBackInterface.FunctionDone |
PROCEDURE(SIGNED opCode, Params Parameters, *CSTRING ErrCode, |
*CSTRING ErrMsg)
CODE
RETURN TRUE
The program above will produce a log file that looks like this:
CREATE(FILE Memory)
!File Operations
OPEN(FILE Memory,34)
NEXT(FILE Memory)
!View 1 Operations
OPEN(FILE ISAMView,34)
OPEN(VIEW Memory,34)
NEXT(FILE ISAMView)
NEXT(VIEW Memory)
!View 2 Operations
OPEN(VIEW Memory,34)
NEXT(VIEW Memory)
!Done
See Also: