Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Interapplication Communication /
Chapter 12 - Data Access Manager / Creating a Query Document


Writing a Query Definition Function

Before the DBStartQuery function sends a query to a data server, it calls the query definition function specified by the queryProc field in the query record. The purpose of the query definition function is to modify the query and the query record before the query is sent to the data server. The query definition function can use dialog boxes to request information from the user. Because a query document is most useful if it can be used by many different applications, no query definition function should depend on the presence of a particular application.

If you want to include a query definition function, you must make it the first piece of code in a resource of type 'qdef' in the query document.

Here is a function declaration for a query definition function.

FUNCTION MyQDef (VAR sessID: LongInt; query: QueryHandle): OSErr;
If the application has already initiated a session with the data server, the DBStartQuery function passes the session ID for that session in the sessID parameter to the query definition function. If the query definition function receives a 0 in this parameter, then the Data Access Manager has not initiated a session. In this case, the query definition function can return a 0 in the sessID parameter, or it can call the DBInit function to initiate a session and then return the session ID in this parameter.

If the query definition function returns a 0 in the sessID parameter, the DBStartQuery function calls the DBInit function and then calls the DBSend function to send a query to the data server. If the query definition function returns a session ID in this parameter, the DBStartQuery function calls the DBSend function immediately.

The query parameter to the query definition function specifies a handle to the query record. The query definition function can modify any of the fields in the query record, including the currQuery field that specifies which query is to be sent to the data server. In addition, the query definition function can modify an existing query or create a new query, adding the handle to the new query to the query list. Note that, because a query in memory consists only of a 2-byte length value followed by a character string, the query definition function has to know the exact contents and structure of a query in order to modify it.

The query definition function must return the noErr result code as the function result if the function executed successfully. If it returns any other value, the DBStartQuery function does not call the DBSend function. The query definition function can return any result code, including noErr, userCanceledErr, or rcDBError.

When the DBStartQuery function calls the query definition function, the current resource file is the file that contains the 'qrsc' resource from which the Data Access Manager created the query record. When the query definition function returns control to the Data Access Manager, the current resource file must be unchanged. See the chapter "Resource Manager" in Inside Macintosh: More Macintosh Toolbox for more information on the current resource file.

The query definition function can allocate memory and use the dataHandle field in the query record to store a handle to it. The query definition function must free any memory it allocates before terminating.

Listing 12-7 shows a query definition function that uses a dialog box to prompt the user for a user name and password and then modifies the query record accordingly.

Listing 12-7 A query definition function

FUNCTION MyQDef(VAR sessID: LongInt; query: QueryHandle): OSErr;
CONST
   myNameItem        =  7;
   myPassWordItem    =  8;
VAR
   myNumRes:         Integer;
   myResList:        ResListHandle;
   myResLPtr:        ResListPtr;
   myIndex:          Integer;
   myDialog:         DialogPtr;
   myDlogID:         Integer;
   itemType:         Integer;
   itemHName:        Handle;
   itemHPasswd:      Handle;
   itemBox:          Rect;
   mySTR:            ARRAY[1..2] OF Str255;
   itemHit:          Integer;
   myQErr:           OsErr;
BEGIN
   {If sessID = 0 no session has been initiated. Your qdef may }
   { optionally initiate a session, or it can let DBStartQuery }
   { take care of this.  In this example, the qdef doesn't }
   { check the sessID parameter.}
   HLock(Handle(query));
   myNumRes := query^^.numRes;
   myResList := query^^.resList;
   HLock(Handle(myResList));
   myResLPtr := myResList^;
   myIndex := 0;
   {look for a 'DLOG' resource}
   WHILE (myIndex < myNumRes) AND
         (myResLPtr^[myIndex].theType <> 'DLOG') DO
   BEGIN
      myIndex := myIndex + 1;
   END;
   IF (myIndex < myNumRes) THEN  {found the 'DLOG' resource}
      myDlogID := myResLPtr^[myIndex].id
   ELSE
   BEGIN
      {The 'DLOG' wasn't found; exit with no error.  This }
      { is probably OK; it just means that the query }
      { and the query record don't get modified.}
      MyQDEF := noErr;
      HUnlock(Handle(query));
      HUnlock(Handle(myResList));
      EXIT(MyQDef);
   END;
   {found the 'DLOG' and its ID; now display the dialog box}
   myDialog := GetNewDialog(myDlogID, Ptr(NIL), WindowPtr(-1));
   SetPort(GrafPtr(myDialog));
   REPEAT
      ModalDialog(@MyEventFilter, itemHit);
   UNTIL ((itemHit = kOK) OR (itemHit = kCancel));
   IF itemHit = kOK THEN
   BEGIN
      {The user clicked the OK button. Update the user }
      { and password fields of the query record.}
      GetDialogItem(myDialog, myNameItem, itemType, itemHName,
                    itemBox);
      GetDialogItemText(itemHName, mySTR[1]);
      GetDialogItem(myDialog, myPassWordItem, itemType, 
                  itemHPasswd, itemBox);
      GetDialogItemText(itemHPasswd, mySTR[2]);
      {Now you can change the query record or the query itself. }
      { What you change is entirely up to you. In this example, }
      { the qdef changes only the user and password fields }
      { of the query record.}
      query^^.user := mySTR[1];
      query^^.password := mySTR[2];
      MyQDef := noErr;
   END
   ELSE 
      MyQDef := userCanceledErr;
   HUnlock(Handle(query));
   HUnlock(Handle(myResList));
   DisposDialog(myDialog);
END;

Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996