Important: The information in this document is obsolete and should not be used for new development.
Writing a Status Routine for High-Level Functions
Both of the two main high-level functions,DBStartQueryandDBGetQueryResults, call low-level functions repeatedly. After each time they call a low-level function, these high-level functions call a routine that you provide, called a status routine. Your status routine can check the result code returned by the low-level function and can cancel execution of the high-level function before it calls the next low-level function. Your status routine can also update your application's windows after theDBStartQueryfunction has displayed a dialog box.You provide a pointer to your status routine in the
statusProcparameter to theDBStartQueryandDBGetQueryResultsfunctions.Here is a function declaration for a status routine:
FUNCTION MyStatusFunc (message: Integer; result: OSErr; dataLen: Integer; dataPlaces: Integer; dataFlags: Integer; dataType: DBType; dataPtr: Ptr): Boolean;Your status routine should return a value ofTRUEif you want to continue execution of theDBStartQueryorDBGetQueryResultsfunction, or a value ofFALSEif you want to cancel execution of the function. In the latter case, the high-level function returns theuserCanceledErrresult code.
The
- Note
- If you call the
DBStartQueryorDBGetQueryResultsfunction asynchronously, you cannot depend on the A5 register containing a pointer to your application's global variables when the Data Access Manager calls your status routine.![]()
messageparameter tells your status routine the current status of the high-level function that called it. The possible values for themessageparameter depend on which function called your routine.The value of the
resultparameter depends on the value of themessageparameter, as summarized in the following list:
Message Result kDBUpdateWind 0 kDBAboutToInit 0 kDBInitComplete Result of DBInitkDBSendComplete Result of DBSendkDBExecComplete Result of DBExeckDBStartQueryComplete Result of DBStartQuerykDBGetItemComplete Result of DBGetItemkDBGetQueryResultsComplete Result of DBGetQueryResultsThe
dataLen,dataPlaces,dataFlags,dataType, anddataPtrparameters are returned only by theDBGetQueryResultsfunction, and only when themessageparameter equalskDBGetItemComplete. When theDBGetQueryResultsfunction calls your status routine with this message, thedataLen,dataPlaces, anddataTypeparameters contain the length, decimal places, and type of the data item retrieved, respectively, and thedataPtrparameter contains a pointer to the data item.The least significant bit of the
dataFlagsparameter is set to1if the data item is in the last column of the row. The third bit of thedataFlagsparameter is set to1if the data item isNULL. You can use this information, for example, to check whether the data meets some criteria of interest to the user, or to display each data item as theDBGetItemfunction receives it. You can use the constantskDBLastColFlagandkDBNullFlagto test for these flag bits.The
DBGetQueryResultsfunction returns a results record, which contains a handle to the retrieved data. The address in thedataPtrparameter points inside the array specified by this handle. Because thedataPtrparameter is not a pointer to a block of memory allocated by the Memory Manager, but just a pointer to a location inside such a block, you cannot use this pointer in any Memory Manager routines (such as theGetPtrSizefunction). Note also that you cannot rely on this pointer remaining valid after you return control to theDBGetQueryResultsfunction.The
DBStartQueryfunction can send to your status routine the following constants in themessageparameter:
CONST {DBStartQuery status messages} kDBUpdateWind = 0; {update windows} kDBAboutToInit = 1; {about to call DBInit} kDBInitComplete = 2; {DBInit has completed} kDBSendComplete = 3; {DBSend has completed} kDBExecComplete = 4; {DBExec has completed} kDBStartQueryComplete = 5; {DBStartQuery is about to } { complete}TheDBGetQueryResultsfunction can send to your status routine the following constants in themessageparameter:
CONST {DBGetQueryResults status messages} kDBGetItemComplete = 6; {DBGetItem has completed} kDBGetQueryResultsComplete = 7; {DBGetQueryResults has } { completed}Listing 12-3 shows a status routine for theDBStartQueryfunction. This routine updates the application's windows in response to thekDBUpdateWindmessage, displays a dialog box giving the user the option of canceling before the data access is initiated, and checks the results of calls to theDBInit,DBSend, andDBExecfunctions. If one of these functions returns an error, the status routine displays a dialog box describing the error.Listing 12-3 A sample status routine
FUNCTION MyStartStatus(message: Integer; result: OSErr; dataLen: Integer; dataPlaces: Integer; dataFlags: Integer; dataType: DBType; dataPtr: Ptr): Boolean; VAR myString: Str255; continue: Boolean; BEGIN continue := TRUE; {assume user wants to continue with query} CASE message OF kDBUpdateWind: {a qdef function has just been called; } BEGIN { handle activate and update events} MyDoActivate; {find and handle activate events} MyDoUpdate; {find and handle update events} END; {kDBUpdateWind} kDBAboutToInit: {about to initiate a session} BEGIN {MyDisplayDialog displays a dialog box. The value } { returned in the continue variable indicates } { whether DBStartQuery should continue.} myString := 'The Data Access Manager is about to open a session. This could take a while. Do you want to continue?'; MyDisplayDialog(@myString, continue); END; {kDBAboutToInit} kDBInitComplete: {the DBInit function has completed execution} BEGIN IF result <> noErr THEN {if there's an error, } BEGIN { let the user know what it is} CASE result OF rcDBError: BEGIN myString := 'The Data Access Manager was unable to open the session. Please check your connections and try again later.'; MyDisplayString(@myString); END; {rcDBError} rcDBBadDDev: BEGIN myString := 'The Data Access Manager cannot find the database extension file it needs to open a session. Check with your system administrator for a copy of the file.'; MyDisplayString(@myString); END; {rcDBBadDDev} OTHERWISE BEGIN myString := 'The Data Access Manager was unable to open the session. The error code returned was'; MyDisplayError(@myString, result); END; {of otherwise} END; {of CASE result} END; {of result <> noErr} END; {kDBInitComplete} kDBSendComplete: {the DBSend function has completed execution} BEGIN {if there's an error, let the user know what it is} IF result <> noErr THEN BEGIN IF result = rcDBError THEN BEGIN myString := 'An error occurred while the Data Access Manager was trying to send the query. Please try again later.'; MyDisplayString(@myString); END ELSE BEGIN myString := 'An error occurred while the Data Access Manager was trying to send the query. The error code returned was'; MyDisplayError(@myString, result); END; END; {of result <> noErr} END; {kDBSendComplete} kDBExecComplete: {the DBExec function has completed execution} BEGIN IF result <> noErr THEN {if there's an error, } BEGIN { let the user know what it is} IF result = rcDBError THEN BEGIN myString := 'The Data Access Manager was unable to execute the query. There may be a problem with the query document or the database. Check with your system administrator.'; MyDisplayString(@myString); END ELSE BEGIN myString := 'An error occurred while the Data Access Manager was trying to execute the query. The error code returned was'; MyDisplayError(@myString, result); END; END; {of result <> noErr} END; {kDBExecComplete} kDBStartQueryComplete:{the DBStartQuery function is about } BEGIN { to return control to your application} {clean up memory and any dialog boxes left on the screen} MyCleanUpWindows; END; {kDBStartQueryComplete} END; {CASE message} MyStartStatus := continue; END;