// BDE - (C) Copyright 1995 by Borland International // Callback.C #include "snipit.h" static const DBIPATH szTblName = "contacts"; static const DBIPATH szRstrctTblName= "TempRest"; static const char szTblType[] = szPARADOX; pCHAR CallBackData; #define NUMOFFIELDS 3 static DBIResult getFieldDescs(hDBICur hCur, UINT16 *uNumFields, FLDDesc **fldDesc); static DBIResult changeFieldDescs(UINT16 *uNumFields, FLDDesc *fldDescSrc, FLDDesc *fldDescDest, CROpType *ecrFldOp); CBRType DBIFN _export CallBackFunc(CBType ecbType, UINT32 iClientData, pVOID pCbInfo); //===================================================================== // Function: // TBRestructureCallBack(); // // Description: // This example shows how to register and use a callback for a table // restructure. The restructure will simply drop fields. // // The following steps are followed: // Getting the existing field descriptors // Modifying the field descriptors to the new table structure // Initializing the CRTblDesc (create table descriptor) // Registering the callback // Restructuring the table // Unregistering the callback //===================================================================== void TBRestructureCallBack (void) { hDBIDb hDb; // Handle to the database hDBICur hCur; // Handle to the table CRTblDesc crTblDesc; // Table descriptor UINT16 uNumFields; // Number of fields UINT16 uNumOfRecs = 5; // No. of records to display FLDDesc *fldDescSrc; // Array of field descriptors FLDDesc fldDescDest[NUMOFFIELDS]; // Restructure field descriptors CROpType ecrFldOp[NUMOFFIELDS]; // Restructure operations RESTCbDesc CbInfo; // Variable which is used within // the callback DBIResult rslt; // Return value from IDAPI // functions DBIPATH szKeyViol = "KEYVIOL"; // Name for the key violation table Screen("*** Restructure CallBack Example ***\r\n"); BREAK_IN_DEBUGGER(); Screen(" Initializing IDAPI..."); if (InitAndConnect(&hDb) != DBIERR_NONE) { Screen("*** End of Example ***"); return; } Screen(" Setting the database directory... "); rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory); ChkRslt(rslt, "SetDirectory"); Screen(" Open the %s table....", szTblName); rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType, NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, NULL, &hCur); if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } rslt = DbiSetToBegin(hCur); ChkRslt(rslt, "SetToBegin"); Screen(" Display the %s table...", szTblName); DisplayTable(hCur, uNumOfRecs); // Get the field descriptors for the existing table. if (getFieldDescs(hCur, &uNumFields, &fldDescSrc) != DBIERR_NONE) { rslt = DbiCloseCursor(&hCur); ChkRslt(rslt, "CloseCursor"); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } Screen("\r\n Close the %s table...", szTblName); DbiCloseCursor(&hCur); // Allocate enough space for the data passed to the callback function. CallBackData = (pCHAR)malloc(100 * sizeof(CHAR)); if (CallBackData == NULL) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } // Register the callback. rslt = DbiRegisterCallBack(NULL, cbRESTRUCTURE, (UINT32) CallBackData, sizeof(RESTCbDesc), &CbInfo, CallBackFunc); if(rslt!=DBIERR_NONE) { free(CallBackData); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } Screen(" Initialize the table descriptor..."); memset(&crTblDesc, 0, sizeof(CRTblDesc)); strcpy(crTblDesc.szTblName, szTblName); strcpy(crTblDesc.szTblType, szTblType); crTblDesc.bPack = TRUE; changeFieldDescs(&uNumFields, fldDescSrc, fldDescDest, ecrFldOp); crTblDesc.iFldCount = uNumFields; crTblDesc.pecrFldOp = ecrFldOp; crTblDesc.pfldDesc = fldDescDest; Screen(" Restructure the %s table to the %s table...", szTblName, szRstrctTblName); rslt = DbiDoRestructure(hDb, 1, &crTblDesc, (pCHAR) szRstrctTblName, szKeyViol, NULL, FALSE); if (ChkRslt(rslt, "DoRestructure") != DBIERR_NONE) { free(CallBackData); free(fldDescSrc); DbiRegisterCallBack(hCur, cbRESTRUCTURE, NULL, 0, NULL, NULL); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } // Unregister the callback by passing in NULL for the function. rslt = DbiRegisterCallBack(hCur, cbRESTRUCTURE, NULL, 0, NULL, NULL); if (ChkRslt(rslt, "RegisterCallBack") != DBIERR_NONE) { free(CallBackData); free(fldDescSrc); rslt = DbiDeleteTable(hDb, (pCHAR) szRstrctTblName, (pCHAR) szTblType); ChkRslt(rslt, "DeleteTable"); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } Screen(" Open the %s table...", szRstrctTblName); rslt = DbiOpenTable(hDb, (pCHAR) szRstrctTblName, (pCHAR) szTblType, NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED, xltFIELD, FALSE, NULL, &hCur); if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE) { free(CallBackData); free(fldDescSrc); rslt = DbiDeleteTable(hDb, (pCHAR) szRstrctTblName, (pCHAR) szTblType); ChkRslt(rslt, "DeleteTable"); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } rslt = DbiSetToBegin(hCur); ChkRslt(rslt, "SetToBegin"); Screen(" Display the %s table...", szRstrctTblName); DisplayTable(hCur, uNumOfRecs); Screen("\r\n Close the %s table...", szRstrctTblName); rslt = DbiCloseCursor(&hCur); ChkRslt(rslt, "CloseCursor"); Screen(" Delete the %s restructured table...", szRstrctTblName); rslt = DbiDeleteTable(hDb, (pCHAR) szRstrctTblName, (pCHAR) szTblType); ChkRslt(rslt, "DeleteTable"); free(fldDescSrc); free(CallBackData); Screen(" Close the database and exit IDAPI..."); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); } //=============================================================== // Function: // getFieldDescs(hCur, *uNumFields, **fldDescSrc) // // Input: hCur - Handle to the cursor // uNumFields - Number of fields in the field descriptor // (Returned) // fldDescSrc - Existing field descriptor (Input) // // Return: IDAPI return code // // Description: // This function gets the field descriptor for an existing cursor //================================================================ DBIResult getFieldDescs (hDBICur hCur, UINT16 *uNumFields, FLDDesc **fldDesc) { DBIResult rslt; CURProps curProps; // Change the translation mode to xltNONE to get the physical // field descriptors. rslt = DbiSetProp(hCur, curXLTMODE, xltNONE); ChkRslt(rslt, "SetProp"); rslt = DbiGetCursorProps(hCur, &curProps); if (ChkRslt(rslt, "GetCursorProps") != DBIERR_NONE) { return rslt; } *uNumFields = curProps.iFields; *fldDesc = (FLDDesc *) malloc(curProps.iFields * sizeof(FLDDesc)); if (fldDesc == NULL) { return DBIERR_NOMEMORY; } rslt = DbiGetFieldDescs(hCur, *fldDesc); if (ChkRslt(rslt, "GetFIeldDescs") != DBIERR_NONE) { return rslt; } // Change the translation mode back to xltFIELD. rslt = DbiSetProp(hCur, curXLTMODE, xltFIELD); ChkRslt(rslt, "SetProp"); return DBIERR_NONE; } //=============================================================== // Function: // changeFieldDescs(uNumFields, FldDescSrc, // fldDescDest, ecrFldOp); // // Input: uNumFields - Number of fields in the existing field descriptor // Also returns the number of fields in the new // field descriptor (Input and Returned) // fldDescSrc - Existing field descriptor (Input) // fldDescDest - New field descriptor to use (Returned) // ecrFldOp - Array of operations on the fields in // fldDescDest (Returned) // // Return: IDAPI return code // // Description: // This function sets up the field structure for the new table. //================================================================ DBIResult changeFieldDescs (UINT16 *uNumFields, FLDDesc *fldDescSrc, FLDDesc *fldDescDest, CROpType *ecrFldOp) { UINT16 i; for (i=0; i < NUMOFFIELDS; i++) { fldDescDest[i] = fldDescSrc[i]; ecrFldOp[i] = crNOOP; } *uNumFields = NUMOFFIELDS; return DBIERR_NONE; } //====================================================================== // Name: CallBackFunc(ecbType, iClientData, pCbInfo) // // Input: ecbType - Callback type // iClientData - Pointer to client information that is passed into // the callback function // pCbInfo - The callback structure that holds the information // about the current state // // Return: The action that should be taken // // Description: // This function will be called from the BDE during the processing // of the restructure. //====================================================================== CBRType DBIFN CallBackFunc (CBType ecbType, UINT32 iClientData, pVOID pCbInfo) { RESTCbDesc *eCBRestDesc; // Variable to contain passed-in // information pCHAR pszMsg; // Information to be displayed. // Set to stop an unused variable warning. iClientData = iClientData; switch (ecbType) { // In case this is a restructure progress callback, display the // information. case cbRESTRUCTURE: eCBRestDesc = (RESTCbDesc far *)pCbInfo; // Restructuring the old field. if(eCBRestDesc->eRestrObjType == restrOLDFLD) { pszMsg = (pCHAR)malloc(DBIMAXMSGLEN * sizeof(CHAR) + 1); if (!pszMsg) { return cbrUSEDEF; } strcpy(pszMsg, eCBRestDesc->uObjDesc.fldDesc.szName); Screen("\r\n### CallBack information: Deleting the %s " "field...", pszMsg); free(pszMsg); } else { // Restructuring the new table's index. if(eCBRestDesc->eRestrObjType == restrNEWINDEX) { Screen("### CallBack information: Recreating the " "Primary index...\r\n"); } // Not one we are expecting. else { Screen("### In the callback function"); } } break; default: Screen("### In the callback function"); } return cbrUSEDEF; }