// BDE - (C) Copyright 1994 by Borland International #include "query.h" //=============================================================== // Name: QueryGetStandardConnection(void) // // Input: None // // Return: returns handle to standard database if successful, // zero otherwise // // Description: // Opens a standard (Paradox & dBase) database. //================================================================ hDBIDb QueryGetStandardConnection(void) { hDBIDb hDb; // Handle to the database // Open the standard database DBIErr(DbiOpenDatabase(NULL, NULL, dbiREADWRITE, dbiOPENSHARED, NULL, 0, NULL, NULL, &hDb)); // Point to the sample tables DBIErr(DbiSetDirectory(hDb, szTblDirectory)); return hDb; } //=============================================================== // Name: QueryQExec(hDb, eQryLang, szQuery, szOutputErrorString, // phCur) // // Input: hDb - Handle to the database // eQryLang - Query language (SQL or QBE) // szQuery - Query string // phCur - Pointer to a cursor handle to the result // set // // Return: DBIERR_NONE if successful, otherwise error encountered // // Description: // Prepares and executes an SQL or QBE query. //================================================================ DBIResult QueryQExec (hDBIDb hDb, DBIQryLang eQryLang, char* szQuery, char *szOutputErrorString, phDBICur phCur) { DBIResult rslt; // Return Value from Engine functions hDBIStmt hStmt; // Handle to the returned Statment (query) // Set up the query. if ((rslt = DbiQPrepare(hDb, eQryLang, szQuery, &hStmt)) != DBIERR_NONE) { GetErrorInformation(szOutputErrorString); return rslt; } // Execute the query. rslt = DbiQExec(hStmt, phCur); // Check if query failed. if (rslt != DBIERR_NONE) { GetErrorInformation(szOutputErrorString); DBIErr(DbiQFree(&hStmt)); return rslt; } // Free memory associated with the query. DBIErr(DbiQFree(&hStmt)); return rslt; } //=============================================================== // Name: QueryDBIInit(void) // // Input: None. // // Return: Result of attempt to use DbiInit. // // Description: // Calls DbiInit, notifies user if problem. //================================================================ DBIResult QueryDbiInit (void) { DBIResult rslt; // Return value from IDAPI functions. pCHAR pszMessage = NULL; // Initialize IDAPI. if (DBIErr(DbiInit(NULL)) != DBIERR_NONE) { return GlobalDBIErr; } // Enable trace info if the debugging layer is enabled. DbiDebugLayerOptions(DEBUGON | OUTPUTTOFILE, "QUERY.INF"); // Set the directory to use for temporary files. rslt = DbiSetPrivateDir(szPrivDirectory); if (rslt == DBIERR_DIRBUSY) { pszMessage = (pCHAR)malloc(((DBIMAXMSGLEN * 3) + 1) * sizeof(char)); if (pszMessage) { sprintf(pszMessage, "Directory is busy. Make certain no .LCK" " files exist in the %s directory and that the IDAPI" " DLLs are unloaded (Reboot Windows).", szPrivDirectory); MessageBox(NULL, pszMessage, "SetPrivateDir Error", MB_OK | MB_ICONHAND); free(pszMessage); } return rslt; } return DBIERR_NONE; } //=============================================================== // Name: QueryDbiExit(void) // // Input: None // // Return: Result of attempt to use DbiExit. // // Descrption: // Calls DbiExit, notifies user if problem. //================================================================ DBIResult QueryDbiExit (void) { // Turn off debugging (if Debug layer DLL selected). DbiDebugLayerOptions(0, NULL); // Close the engine. return DBIErr(DbiExit()); } //=============================================================== // Name: QueryDbiCloseDatabase(phDb); // // Input: phDb -- pointer to database handle to close // // Return: None // // Description: // Calls DbiCloseDatabase, displays error message if // DBI error is encountered and bDisplayError is TRUE. //================================================================ void QueryDbiCloseDatabase (phDBIDb phDb) { // Close the standard database. DBIErr(DbiCloseDatabase(phDb)); } //=============================================================== // Name: QueryResetConnectDialog(hWnd, dbarray, iSelected); // // Input: hWnd - Handle to the connect dialog // dbarray - The array of database handles, which is used // to fill the connection listbox // iSelected - Currently selected database // // Return: None // // Description: // Resets the "connect to the database" dialog on // during initialization or based on the current // driver selected. //================================================================ void QueryResetConnectDialog (HWND hWnd, const DBStructArray dbarray, const int iSelected) { hDBICur hList; DBDesc DbData; int i; // Reset default connection static control. SendDlgItemMessage(hWnd, IDS_SELECTED_CONNECTION, WM_SETTEXT, 0, (LPARAM) dbarray[iSelected].szDatabaseName); // Reset alias listbox. if (DBIErr(DbiOpenDatabaseList(&hList)) == DBIERR_NONE) { while (DbiGetNextRecord(hList, dbiNOLOCK, (pBYTE) &DbData, NULL) == DBIERR_NONE) { SendDlgItemMessage(hWnd, IDC_LB_ALIASES, LB_INSERTSTRING, 0, (LPARAM) DbData.szName); } DBIErr(DbiCloseCursor(&hList)); } // Reset connections listbox. SendDlgItemMessage(hWnd, IDC_LB_CONNECTIONS, LB_RESETCONTENT, 0, 0); for (i = 0; i < MAX_DATABASE_HANDLES; i++) { if (dbarray[i].hdb == 0) { break; } SendDlgItemMessage(hWnd, IDC_LB_CONNECTIONS, LB_INSERTSTRING, i, (LPARAM) dbarray[i].szDatabaseName); } } //=============================================================== // Name: QueryConnectToDatabase(hWnd); // // Input: hWnd - Handle to the connect dialog // // Return: Handle to the database, or zero if connection cannot // be established // // Description: // Try to connect to a database based on the data // selected in the connection dialog box; display // result in the static control. //================================================================ hDBIDb QueryConnectToDatabase (HWND hWnd) { hDBIDb hDb; WORD ListIndex; pCHAR Msg; pCHAR Driver; pCHAR Alias; pCHAR Password; DBIErrInfo ErrInfo; // Init the strings. Alias = (pCHAR)malloc(DBIMAXSCFLDLEN); Driver = (pCHAR)malloc(DBIMAXSCFLDLEN); Password = (pCHAR)malloc(DBIMAXSCFLDLEN); Msg = (pCHAR)malloc((DBIMAXMSGLEN + 1) * 4); if ((Alias == NULL) || (Driver == NULL) || (Password == NULL) || (Msg == NULL)) { hDb = 0; if (Msg) free(Msg); if (Alias) free(Alias); if (Driver) free(Driver); if (Password) free(Password); sprintf(Msg, "Unable to connect: Out of memory!"); SendDlgItemMessage(hWnd, IDC_STATIC_STATUS, WM_SETTEXT, 0, (LPARAM) Msg); MessageBeep(MB_ICONEXCLAMATION); return hDb; } Alias[0] = '\0'; Driver[0] = '\0'; Password[0] = '\0'; // SQL database needs the alias & password. ListIndex = (WORD)SendDlgItemMessage(hWnd, IDC_LB_ALIASES, LB_GETCURSEL, 0, 0); SendDlgItemMessage(hWnd, IDC_LB_ALIASES, LB_GETTEXT, (WPARAM) ListIndex, (LPARAM) Alias); SendDlgItemMessage(hWnd, IDC_EDIT_PASSWORD, WM_GETTEXT, 80, (LPARAM) Password); // Try to open the database. hDb = 0; SendDlgItemMessage(hWnd, IDL_RESULTS, LB_RESETCONTENT, 0, 0); // Establish connection to the database if ((DbiOpenDatabase(Alias, Driver, dbiREADWRITE, dbiOPENSHARED, Password, 0, NULL, NULL, &hDb)) == DBIERR_NONE) { SendDlgItemMessage(hWnd, IDC_STATIC_STATUS, WM_SETTEXT, 0, (LPARAM) "Connection is available!"); } else { // Failed to connect hDb = 0; DbiGetErrorInfo(TRUE, &ErrInfo); sprintf(Msg, "Unable to connect: Cat:Code = [%xh:%xh]" "\r\n %s" "\r\n %s" "\r\n %s" "\r\n %s" "\r\n %s", ErrCat(ErrInfo.iError), ErrCode(ErrInfo.iError), ErrInfo.szErrCode, ErrInfo.szContext1, ErrInfo.szContext2, ErrInfo.szContext3, ErrInfo.szContext4); SendDlgItemMessage(hWnd, IDC_STATIC_STATUS, WM_SETTEXT, 0, (LPARAM) Msg); MessageBeep(MB_ICONEXCLAMATION); } // Clean up. free(Msg); free(Alias); free(Driver); free(Password); return hDb; } //=============================================================== // Name: QuerySaveResultSet(hCur, hDb, szFileName); // // Input: hCur - Handle to source cursor // hDb - Handle to database // szFileName - Filename to use in saving the result set // // Return: TRUE if result set was saved // FALSE otherwise // // Description: // Saves the result set of the last successful query. // IMPORTANT NOTE: since this function is called from the // common dialog box, and is only called after the user // has confirmed that an existing file should be // over-written, if the file exists this function // deletes the file before saving it. //================================================================ BOOL QuerySaveResultSet (hDBICur hCur, hDBIDb hDb, char* szFileName) { OFSTRUCT ofstruct; BATTblDesc BatTblDesc = { NULL, "", szPARADOX, { NULL }, { NULL } }; // Delete the file if it exists. OpenFile(szFileName, &ofstruct, OF_DELETE); BatTblDesc.hDb = hDb; strcpy(BatTblDesc.szTblName, szFileName); DBIErr(DbiSetToBegin(hCur)); // Save the result set to the hard disk. if (DBIErr(DbiBatchMove(NULL, hCur, &BatTblDesc, NULL, batCOPY, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, TRUE, TRUE, NULL, TRUE)) != DBIERR_NONE) { return FALSE; } return TRUE; } //=============================================================== // Name: GetWorkingDirectory(hDb, szDirectory) // // Input: hDb - Handle to the database // szDirectory - Working directory // // Return: Handle to the database, or zero if connection cannot // be established. // // Description: // Try to connect to a database based on the data // selected in the connection dialog box; display // result in the static control. //================================================================ DBIResult GetWorkingDirectory (hDBIDb hDb, pCHAR szDirectory) { return DBIErr(DbiGetDirectory(hDb, FALSE, szDirectory)); } //=============================================================== // Name: SetWorkingDirectory(hDb, szDirectory) // // Input: hDb - Handle to the Database // szDirectory - path to the directory // // Return: DBIResult - Success of the opperation // // Description: // This function is used to set the working directory of the // database. //================================================================ DBIResult SetWorkingDirectory (hDBIDb hDb, pCHAR szDirectory) { return DBIErr(DbiSetDirectory(hDb, szDirectory)); } //=============================================================== // Name: RegisterCallBack(hCur, ecbType, iClientData, iCbBufLen, // pCbBuf, pfCb); // // Input: hCur - Handle to the cursor // ecbType - Type of the callback // iClientData - Client Data // iCbBufLen - Length of the buffer // pCbBuf - CallBack buffer // pfCb - Callback function // // Return: Success of registering the callback // // Description: // This function is used to initialize callback functions. //================================================================ DBIResult RegisterCallBack (hDBICur hCur, CBType ecbType, UINT32 iClientData, UINT16 iCbBufLen, pVOID pCbBuf, pfDBICallBack pfCb) { DBIResult rslt; // Return value of IDAPI functions. rslt = DbiRegisterCallBack(hCur, ecbType, iClientData, iCbBufLen, pCbBuf, pfCb); return rslt; } //=============================================================== // Name: GetErrorInformation(szOutputErrorString); // // Input: szOutputErrorString - Sting to contain the error string // // Return: None // // Description: // This function will return information about an IDAPI error. // Not that this needs to be called imediately after the error // occurs. //================================================================ void GetErrorInformation (char *szOutputErrorString) { DBIErrInfo ErrInfo; // Error information. DbiGetErrorInfo(TRUE, &ErrInfo); sprintf(szOutputErrorString, " ERROR - Cat:Code = [%xh:%xh]" "\r\n %s", ErrCat(ErrInfo.iError), ErrCode(ErrInfo.iError), ErrInfo.szErrCode); if (strcmp(ErrInfo.szContext1, "")) { strcat(szOutputErrorString, "\r\n "); strcat(szOutputErrorString, ErrInfo.szContext1); } if (strcmp(ErrInfo.szContext2, "")) { strcat(szOutputErrorString, "\r\n "); strcat(szOutputErrorString, ErrInfo.szContext2); } if (strcmp(ErrInfo.szContext3, "")) { strcat(szOutputErrorString, "\r\n "); strcat(szOutputErrorString, ErrInfo.szContext3); } if (strcmp(ErrInfo.szContext4, "")) { strcat(szOutputErrorString, "\r\n "); strcat(szOutputErrorString, ErrInfo.szContext4); } } //=============================================================== // Name: CleanUpAnswer(hCur) // // Input: hCur - Handle to the cursor // // Return: Success of closing the cursor // // Description: // Close the cursor to the answer table and set the cursor // to 0. //================================================================ DBIResult CleanUpAnswer (hDBICur *hCur) { DBIResult rslt; // Return value from IDAPI functions if (*hCur) { rslt = DbiCloseCursor(hCur); if (rslt == DBIERR_NONE) { *hCur = 0; } } return rslt; }