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,DBStartQuery
andDBGetQueryResults
, 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 theDBStartQuery
function has displayed a dialog box.You provide a pointer to your status routine in the
statusProc
parameter to theDBStartQuery
andDBGetQueryResults
functions.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 ofTRUE
if you want to continue execution of theDBStartQuery
orDBGetQueryResults
function, or a value ofFALSE
if you want to cancel execution of the function. In the latter case, the high-level function returns theuserCanceledErr
result code.
The
- Note
- If you call the
DBStartQuery
orDBGetQueryResults
function 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.message
parameter tells your status routine the current status of the high-level function that called it. The possible values for themessage
parameter depend on which function called your routine.The value of the
result
parameter depends on the value of themessage
parameter, as summarized in the following list:
Message Result kDBUpdateWind 0 kDBAboutToInit 0 kDBInitComplete Result of DBInit
kDBSendComplete Result of DBSend
kDBExecComplete Result of DBExec
kDBStartQueryComplete Result of DBStartQuery
kDBGetItemComplete Result of DBGetItem
kDBGetQueryResultsComplete Result of DBGetQueryResults
The
dataLen
,dataPlaces
,dataFlags
,dataType
, anddataPtr
parameters are returned only by theDBGetQueryResults
function, and only when themessage
parameter equalskDBGetItemComplete
. When theDBGetQueryResults
function calls your status routine with this message, thedataLen
,dataPlaces
, anddataType
parameters contain the length, decimal places, and type of the data item retrieved, respectively, and thedataPtr
parameter contains a pointer to the data item.The least significant bit of the
dataFlags
parameter is set to1
if the data item is in the last column of the row. The third bit of thedataFlags
parameter is set to1
if 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 theDBGetItem
function receives it. You can use the constantskDBLastColFlag
andkDBNullFlag
to test for these flag bits.The
DBGetQueryResults
function returns a results record, which contains a handle to the retrieved data. The address in thedataPtr
parameter points inside the array specified by this handle. Because thedataPtr
parameter 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 theGetPtrSize
function). Note also that you cannot rely on this pointer remaining valid after you return control to theDBGetQueryResults
function.The
DBStartQuery
function can send to your status routine the following constants in themessage
parameter:
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}TheDBGetQueryResults
function can send to your status routine the following constants in themessage
parameter:
CONST {DBGetQueryResults status messages} kDBGetItemComplete = 6; {DBGetItem has completed} kDBGetQueryResultsComplete = 7; {DBGetQueryResults has } { completed}Listing 12-3 shows a status routine for theDBStartQuery
function. This routine updates the application's windows in response to thekDBUpdateWind
message, 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
, andDBExec
functions. 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;