home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bde / sdkqry.pak / ENGINE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-24  |  15.9 KB  |  502 lines

  1. // BDE - (C) Copyright 1994 by Borland International
  2.  
  3. #include "query.h"
  4.  
  5. //===============================================================
  6. //  Name:   QueryGetStandardConnection(void)
  7. //
  8. //  Input:  None
  9. //
  10. //  Return: returns handle to standard database if successful, 
  11. //          zero otherwise
  12. //
  13. //  Description:
  14. //          Opens a standard (Paradox & dBase) database.
  15. //================================================================
  16. hDBIDb
  17. QueryGetStandardConnection(void)
  18. {
  19.     hDBIDb   hDb;   // Handle to the database
  20.  
  21.     // Open the standard database
  22.     DBIErr(DbiOpenDatabase(NULL, NULL, dbiREADWRITE, dbiOPENSHARED,
  23.                            NULL, 0, NULL, NULL, &hDb));
  24.  
  25.     // Point to the sample tables
  26.     DBIErr(DbiSetDirectory(hDb, szTblDirectory));
  27.  
  28.     return hDb;
  29. }
  30.  
  31. //===============================================================
  32. //  Name:   QueryQExec(hDb, eQryLang, szQuery, szOutputErrorString,
  33. //                     phCur)
  34. //
  35. //  Input:  hDb         - Handle to the database
  36. //          eQryLang    - Query language (SQL or QBE)
  37. //          szQuery     - Query string
  38. //          phCur       - Pointer to a cursor handle to the result
  39. //                        set
  40. //
  41. //  Return: DBIERR_NONE if successful, otherwise error encountered
  42. //
  43. //  Description:
  44. //          Prepares and executes an SQL or QBE query.          
  45. //================================================================
  46. DBIResult
  47. QueryQExec (hDBIDb hDb, DBIQryLang eQryLang, char* szQuery,
  48.             char *szOutputErrorString, phDBICur phCur)
  49. {
  50.     DBIResult   rslt;   // Return Value from Engine functions
  51.     hDBIStmt    hStmt;  // Handle to the returned Statment (query)
  52.  
  53.     // Set up the query.
  54.     if ((rslt = DbiQPrepare(hDb, eQryLang, szQuery, &hStmt))
  55.         != DBIERR_NONE)
  56.     {
  57.         GetErrorInformation(szOutputErrorString);
  58.         return rslt;
  59.     }
  60.  
  61.     // Execute the query.
  62.     rslt = DbiQExec(hStmt, phCur);
  63.  
  64.     // Check if query failed.
  65.     if (rslt != DBIERR_NONE)
  66.     {
  67.         GetErrorInformation(szOutputErrorString);
  68.         DBIErr(DbiQFree(&hStmt));
  69.         return rslt;
  70.     }
  71.  
  72.     // Free memory associated with the query.
  73.     DBIErr(DbiQFree(&hStmt));
  74.  
  75.     return rslt;       
  76. }                      
  77.  
  78. //===============================================================
  79. //  Name:   QueryDBIInit(void)
  80. //
  81. //  Input:  None.
  82. //
  83. //  Return: Result of attempt to use DbiInit.
  84. //
  85. //  Description:
  86. //          Calls DbiInit, notifies user if problem.          
  87. //================================================================
  88. DBIResult
  89. QueryDbiInit (void)
  90. {
  91.     DBIResult   rslt;   // Return value from IDAPI functions.
  92.     pCHAR       pszMessage = NULL;
  93.  
  94.     // Initialize IDAPI.
  95.     if (DBIErr(DbiInit(NULL)) != DBIERR_NONE)
  96.     {
  97.          return GlobalDBIErr;
  98.     }
  99.  
  100.     // Enable trace info if the debugging layer is enabled.
  101.     DbiDebugLayerOptions(DEBUGON | OUTPUTTOFILE, "QUERY.INF");
  102.  
  103.     // Set the directory to use for temporary files.
  104.     rslt = DbiSetPrivateDir(szPrivDirectory);
  105.     if (rslt == DBIERR_DIRBUSY)
  106.     {
  107.         pszMessage = (pCHAR)malloc(((DBIMAXMSGLEN * 3) + 1) * sizeof(char));
  108.         if (pszMessage)
  109.         {
  110.             sprintf(pszMessage, "Directory is busy. Make certain no .LCK"
  111.                     " files exist in the %s directory and that the IDAPI"
  112.                     " DLLs are unloaded (Reboot Windows).",
  113.                     szPrivDirectory);
  114.             MessageBox(NULL, pszMessage, "SetPrivateDir Error",
  115.                        MB_OK | MB_ICONHAND);
  116.             free(pszMessage);
  117.         }
  118.         return rslt;
  119.     }
  120.  
  121.     return DBIERR_NONE;
  122. }
  123.  
  124. //===============================================================
  125. //  Name:   QueryDbiExit(void)
  126. //
  127. //  Input:  None
  128. //
  129. //  Return: Result of attempt to use DbiExit.
  130. //
  131. //  Descrption:
  132. //          Calls DbiExit, notifies user if problem.          
  133. //================================================================
  134. DBIResult
  135. QueryDbiExit (void)
  136. {
  137.     // Turn off debugging (if Debug layer DLL selected).
  138.     DbiDebugLayerOptions(0, NULL);
  139.  
  140.     // Close the engine.
  141.     return DBIErr(DbiExit());
  142. }
  143.  
  144. //===============================================================
  145. //  Name:   QueryDbiCloseDatabase(phDb);
  146. //
  147. //  Input:  phDb -- pointer to database handle to close
  148. //
  149. //  Return: None
  150. //
  151. //  Description:
  152. //          Calls DbiCloseDatabase, displays error message if
  153. //          DBI error is encountered and bDisplayError is TRUE.          
  154. //================================================================
  155. void
  156. QueryDbiCloseDatabase (phDBIDb phDb)
  157. {
  158.     // Close the standard database.
  159.     DBIErr(DbiCloseDatabase(phDb));
  160. }
  161.  
  162. //===============================================================
  163. //  Name:   QueryResetConnectDialog(hWnd, dbarray, iSelected);
  164. //
  165. //  Input:  hWnd        - Handle to the connect dialog
  166. //          dbarray     - The array of database handles, which is used
  167. //                        to fill the connection listbox
  168. //          iSelected   - Currently selected database
  169. //
  170. //  Return: None
  171. //
  172. //  Description:
  173. //          Resets the "connect to the database" dialog on 
  174. //          during initialization or based on the current 
  175. //          driver selected.
  176. //================================================================
  177. void
  178. QueryResetConnectDialog (HWND hWnd, const DBStructArray dbarray,
  179.                          const int iSelected)
  180. {
  181.     hDBICur     hList;
  182.     DBDesc      DbData;
  183.     int         i;
  184.  
  185.     // Reset default connection static control.
  186.     SendDlgItemMessage(hWnd, IDS_SELECTED_CONNECTION,
  187.                        WM_SETTEXT, 0,
  188.                        (LPARAM) dbarray[iSelected].szDatabaseName);
  189.  
  190.     // Reset alias listbox.
  191.     if (DBIErr(DbiOpenDatabaseList(&hList)) == DBIERR_NONE)
  192.     {
  193.         while (DbiGetNextRecord(hList, dbiNOLOCK, (pBYTE) &DbData,
  194.                                 NULL) == DBIERR_NONE)
  195.         {
  196.             SendDlgItemMessage(hWnd, IDC_LB_ALIASES, LB_INSERTSTRING,
  197.                                0, (LPARAM) DbData.szName);
  198.         }
  199.         DBIErr(DbiCloseCursor(&hList));
  200.     }
  201.  
  202.     // Reset connections listbox.
  203.     SendDlgItemMessage(hWnd, IDC_LB_CONNECTIONS, LB_RESETCONTENT, 0, 0);
  204.     for (i = 0; i < MAX_DATABASE_HANDLES; i++)
  205.     {
  206.         if (dbarray[i].hdb == 0)
  207.         {
  208.             break;
  209.         }
  210.         SendDlgItemMessage(hWnd, IDC_LB_CONNECTIONS, LB_INSERTSTRING, i, 
  211.                           (LPARAM) dbarray[i].szDatabaseName);
  212.     }                                          
  213. }
  214.  
  215. //===============================================================
  216. //  Name:   QueryConnectToDatabase(hWnd);
  217. //
  218. //  Input:  hWnd - Handle to the connect dialog
  219. //
  220. //  Return: Handle to the database, or zero if connection cannot
  221. //          be established
  222. //
  223. //  Description:
  224. //          Try to connect to a database based on the data
  225. //          selected in the connection dialog box; display 
  226. //          result in the static control.
  227. //================================================================
  228. hDBIDb
  229. QueryConnectToDatabase (HWND hWnd)
  230. {
  231.     hDBIDb      hDb;
  232.     WORD        ListIndex;
  233.     pCHAR       Msg;
  234.     pCHAR       Driver;
  235.     pCHAR       Alias;
  236.     pCHAR       Password;
  237.     DBIErrInfo  ErrInfo;
  238.  
  239.     // Init the strings. 
  240.     Alias = (pCHAR)malloc(DBIMAXSCFLDLEN);
  241.     Driver = (pCHAR)malloc(DBIMAXSCFLDLEN);
  242.     Password = (pCHAR)malloc(DBIMAXSCFLDLEN);
  243.     Msg = (pCHAR)malloc((DBIMAXMSGLEN + 1) * 4);
  244.     if ((Alias == NULL) || (Driver == NULL) || (Password == NULL) ||
  245.         (Msg == NULL))
  246.     {
  247.         hDb = 0;
  248.         if (Msg) free(Msg);
  249.         if (Alias) free(Alias);
  250.         if (Driver) free(Driver);
  251.         if (Password) free(Password);
  252.         sprintf(Msg, "Unable to connect: Out of memory!");
  253.         SendDlgItemMessage(hWnd, IDC_STATIC_STATUS, WM_SETTEXT, 0,
  254.                            (LPARAM) Msg);
  255.         MessageBeep(MB_ICONEXCLAMATION);
  256.         return hDb;
  257.     }
  258.  
  259.     Alias[0] = '\0';
  260.     Driver[0] = '\0';
  261.     Password[0] = '\0';
  262.  
  263.     // SQL database needs the alias & password. 
  264.     ListIndex = (WORD)SendDlgItemMessage(hWnd, IDC_LB_ALIASES, LB_GETCURSEL, 0,
  265.                                          0);
  266.     SendDlgItemMessage(hWnd, IDC_LB_ALIASES, LB_GETTEXT, (WPARAM)
  267.                        ListIndex, (LPARAM) Alias);
  268.     SendDlgItemMessage(hWnd, IDC_EDIT_PASSWORD, WM_GETTEXT, 80,
  269.                        (LPARAM) Password);
  270.  
  271.     // Try to open the database. 
  272.     hDb = 0;
  273.     SendDlgItemMessage(hWnd, IDL_RESULTS, LB_RESETCONTENT, 0, 0);
  274.  
  275.     // Establish connection to the database
  276.     if ((DbiOpenDatabase(Alias, Driver, dbiREADWRITE, dbiOPENSHARED,
  277.                          Password, 0, NULL, NULL, &hDb))
  278.         == DBIERR_NONE)
  279.     {
  280.         SendDlgItemMessage(hWnd, IDC_STATIC_STATUS, WM_SETTEXT, 0,
  281.                            (LPARAM) "Connection is available!");
  282.     }
  283.     else
  284.     {
  285.         // Failed to connect
  286.         hDb = 0;
  287.         DbiGetErrorInfo(TRUE, &ErrInfo);
  288.  
  289.         sprintf(Msg, "Unable to connect:  Cat:Code = [%xh:%xh]"
  290.                 "\r\n    %s"
  291.                 "\r\n    %s"
  292.                 "\r\n    %s"
  293.                 "\r\n    %s"
  294.                 "\r\n    %s",
  295.                 ErrCat(ErrInfo.iError), ErrCode(ErrInfo.iError),
  296.                 ErrInfo.szErrCode, ErrInfo.szContext1, ErrInfo.szContext2,
  297.                 ErrInfo.szContext3, ErrInfo.szContext4);
  298.         SendDlgItemMessage(hWnd, IDC_STATIC_STATUS, WM_SETTEXT, 0,
  299.                            (LPARAM) Msg);
  300.         MessageBeep(MB_ICONEXCLAMATION);
  301.     }
  302.  
  303.     // Clean up.
  304.     
  305.     free(Msg);
  306.     free(Alias);
  307.     free(Driver);
  308.     free(Password);
  309.  
  310.     return hDb;
  311. }
  312.  
  313. //===============================================================
  314. //  Name:   QuerySaveResultSet(hCur, hDb, szFileName);
  315. //
  316. //  Input:  hCur        - Handle to source cursor
  317. //          hDb         - Handle to database
  318. //          szFileName  - Filename to use in saving the result set
  319. //
  320. //  Return: TRUE if result set was saved
  321. //          FALSE otherwise
  322. //
  323. //  Description:
  324. //          Saves the result set of the last successful query.
  325. //          IMPORTANT NOTE:  since this function is called from the
  326. //          common dialog box, and is only called after the user
  327. //          has confirmed that an existing file should be
  328. //          over-written, if the file exists this function
  329. //          deletes the file before saving it.
  330. //================================================================
  331. BOOL
  332. QuerySaveResultSet (hDBICur hCur, hDBIDb hDb, char* szFileName)
  333. {           
  334.     OFSTRUCT    ofstruct;
  335.     BATTblDesc  BatTblDesc = {
  336.                                NULL,
  337.                                "",
  338.                                szPARADOX,
  339.                                { NULL },
  340.                                { NULL }
  341.                              };
  342.  
  343.     // Delete the file if it exists.
  344.     OpenFile(szFileName, &ofstruct, OF_DELETE);                           
  345.     
  346.     BatTblDesc.hDb = hDb;   
  347.     strcpy(BatTblDesc.szTblName, szFileName);
  348.  
  349.     DBIErr(DbiSetToBegin(hCur));
  350.  
  351.     // Save the result set to the hard disk.                                
  352.     if (DBIErr(DbiBatchMove(NULL, hCur, &BatTblDesc, NULL, batCOPY, NULL,
  353.                             NULL, NULL, NULL, NULL, NULL, NULL,
  354.                             NULL, NULL, NULL, NULL, TRUE, TRUE,
  355.                             NULL, TRUE)) != DBIERR_NONE)
  356.     {
  357.         return FALSE;
  358.     }
  359.  
  360.     return TRUE;
  361. }
  362.  
  363. //===============================================================
  364. //  Name:   GetWorkingDirectory(hDb, szDirectory)
  365. //
  366. //  Input:  hDb         - Handle to the database
  367. //          szDirectory - Working directory
  368. //
  369. //  Return: Handle to the database, or zero if connection cannot
  370. //          be established.
  371. //
  372. //  Description:
  373. //          Try to connect to a database based on the data
  374. //          selected in the connection dialog box; display
  375. //          result in the static control.
  376. //================================================================
  377. DBIResult
  378. GetWorkingDirectory (hDBIDb hDb, pCHAR szDirectory)
  379. {
  380.     return DBIErr(DbiGetDirectory(hDb, FALSE, szDirectory));
  381. }
  382.  
  383. //===============================================================
  384. //  Name:   SetWorkingDirectory(hDb, szDirectory)
  385. //
  386. //  Input:  hDb         - Handle to the Database
  387. //          szDirectory - path to the directory
  388. //
  389. //  Return: DBIResult   - Success of the opperation
  390. //
  391. //  Description:
  392. //          This function is used to set the working directory of the
  393. //          database.
  394. //================================================================
  395. DBIResult
  396. SetWorkingDirectory (hDBIDb hDb, pCHAR szDirectory)
  397. {
  398.     return DBIErr(DbiSetDirectory(hDb, szDirectory));
  399. }
  400.  
  401. //===============================================================
  402. //  Name:   RegisterCallBack(hCur, ecbType, iClientData, iCbBufLen,
  403. //                           pCbBuf, pfCb);
  404. //
  405. //  Input:  hCur            - Handle to the cursor
  406. //          ecbType         - Type of the callback
  407. //          iClientData     - Client Data
  408. //          iCbBufLen       - Length of the buffer
  409. //          pCbBuf          - CallBack buffer
  410. //          pfCb            - Callback function
  411. //
  412. //  Return: Success of registering the callback
  413. //
  414. //  Description:
  415. //          This function is used to initialize callback functions.
  416. //================================================================
  417. DBIResult
  418. RegisterCallBack (hDBICur hCur, CBType ecbType, UINT32 iClientData,
  419.                   UINT16 iCbBufLen, pVOID pCbBuf, pfDBICallBack pfCb)
  420. {
  421.     DBIResult rslt; // Return value of IDAPI functions.
  422.  
  423.     rslt = DbiRegisterCallBack(hCur, ecbType, iClientData, iCbBufLen,
  424.                                pCbBuf, pfCb);
  425.     return rslt;
  426. }
  427.  
  428. //===============================================================
  429. //  Name:   GetErrorInformation(szOutputErrorString);
  430. //
  431. //  Input:  szOutputErrorString - Sting to contain the error string
  432. //
  433. //  Return: None
  434. //
  435. //  Description:
  436. //          This function will return information about an IDAPI error.
  437. //          Not that this needs to be called imediately after the error
  438. //          occurs.
  439. //================================================================
  440. void
  441. GetErrorInformation (char *szOutputErrorString)
  442. {
  443.     DBIErrInfo  ErrInfo;    // Error information.
  444.  
  445.     DbiGetErrorInfo(TRUE, &ErrInfo);
  446.  
  447.     sprintf(szOutputErrorString, "        ERROR -  Cat:Code = [%xh:%xh]"
  448.             "\r\n                 %s",
  449.             ErrCat(ErrInfo.iError), ErrCode(ErrInfo.iError),
  450.             ErrInfo.szErrCode);
  451.  
  452.     if (strcmp(ErrInfo.szContext1, ""))
  453.     {
  454.         strcat(szOutputErrorString, "\r\n                 ");
  455.         strcat(szOutputErrorString, ErrInfo.szContext1);
  456.     }
  457.     if (strcmp(ErrInfo.szContext2, ""))
  458.     {
  459.         strcat(szOutputErrorString, "\r\n                 ");
  460.         strcat(szOutputErrorString, ErrInfo.szContext2);
  461.     }
  462.     if (strcmp(ErrInfo.szContext3, ""))
  463.     {
  464.         strcat(szOutputErrorString, "\r\n                 ");
  465.         strcat(szOutputErrorString, ErrInfo.szContext3);
  466.     }
  467.     if (strcmp(ErrInfo.szContext4, ""))
  468.     {
  469.         strcat(szOutputErrorString, "\r\n                 ");
  470.         strcat(szOutputErrorString, ErrInfo.szContext4);
  471.     }
  472. }
  473.  
  474. //===============================================================
  475. //  Name:   CleanUpAnswer(hCur)
  476. //
  477. //  Input:  hCur    - Handle to the cursor
  478. //
  479. //  Return: Success of closing the cursor
  480. //
  481. //  Description:
  482. //          Close the cursor to the answer table and set the cursor
  483. //          to 0.
  484. //================================================================
  485. DBIResult
  486. CleanUpAnswer (hDBICur *hCur)
  487. {
  488.     DBIResult rslt;     // Return value from IDAPI functions
  489.  
  490.     if (*hCur)
  491.     {
  492.         rslt = DbiCloseCursor(hCur);
  493.         if (rslt == DBIERR_NONE)
  494.         {
  495.             *hCur = 0;
  496.         }
  497.     }
  498.  
  499.     return rslt;
  500. }
  501.  
  502.