CALLBACK (register or unregister a FileCallBackInterface)

Top  Previous  Next

 

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:

FileCallbackInterface

Trigger Properties