drvconn.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:9k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /* Module:          drvconn.c
  2.  *
  3.  * Description:     This module contains only routines related to 
  4.  *                  implementing SQLDriverConnect.
  5.  *
  6.  * Classes:         n/a
  7.  *
  8.  * API functions:   SQLDriverConnect
  9.  *
  10.  * Comments:        See "notice.txt" for copyright and license information.
  11.  *
  12.  */
  13. #ifdef HAVE_CONFIG_H
  14. #include "config.h"
  15. #endif
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include "psqlodbc.h"
  19. #include "connection.h"
  20. #ifndef WIN32
  21. #include <sys/types.h>
  22. #include <sys/socket.h>
  23. #define NEAR
  24. #else
  25. #include <winsock.h>
  26. #include <sqlext.h>
  27. #endif
  28. #include <string.h>
  29. #ifndef WIN32
  30. #define stricmp(s1,s2) strcasecmp(s1,s2)
  31. #define strnicmp(s1,s2,n) strncasecmp(s1,s2,n)
  32. #else
  33. #include <windows.h>
  34. #include <windowsx.h>
  35. #include <odbcinst.h>
  36. #include "resource.h"
  37. #endif
  38. #ifndef TRUE
  39. #define TRUE (BOOL)1
  40. #endif
  41. #ifndef FALSE
  42. #define FALSE (BOOL)0
  43. #endif
  44. #include "dlg_specific.h"
  45. /* prototypes */
  46. void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci);
  47. #ifdef WIN32
  48. BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
  49. RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
  50. extern HINSTANCE NEAR s_hModule;               /* Saved module handle. */
  51. #endif
  52. extern GLOBAL_VALUES globals;
  53. RETCODE SQL_API SQLDriverConnect(
  54.                                  HDBC      hdbc,
  55.                                  HWND      hwnd,
  56.                                  UCHAR FAR *szConnStrIn,
  57.                                  SWORD     cbConnStrIn,
  58.                                  UCHAR FAR *szConnStrOut,
  59.                                  SWORD     cbConnStrOutMax,
  60.                                  SWORD FAR *pcbConnStrOut,
  61.                                  UWORD     fDriverCompletion)
  62. {
  63. static char *func = "SQLDriverConnect";
  64. ConnectionClass *conn = (ConnectionClass *) hdbc;
  65. ConnInfo *ci;
  66. #ifdef WIN32
  67. RETCODE dialog_result;
  68. #endif
  69. RETCODE result;
  70. char connStrIn[MAX_CONNECT_STRING];
  71. char connStrOut[MAX_CONNECT_STRING];
  72. int retval;
  73. char password_required = FALSE;
  74. int len = 0;
  75. mylog("%s: entering...n", func);
  76. if ( ! conn) {
  77. CC_log_error(func, "", NULL);
  78. return SQL_INVALID_HANDLE;
  79. }
  80. make_string(szConnStrIn, cbConnStrIn, connStrIn);
  81. mylog("**** SQLDriverConnect: fDriverCompletion=%d, connStrIn='%s'n", fDriverCompletion, connStrIn);
  82. qlog("conn=%u, SQLDriverConnect( in)='%s', fDriverCompletion=%dn", conn, connStrIn, fDriverCompletion);
  83. ci = &(conn->connInfo);
  84. // Parse the connect string and fill in conninfo for this hdbc.
  85. dconn_get_connect_attributes(connStrIn, ci);
  86. // If the ConnInfo in the hdbc is missing anything,
  87. // this function will fill them in from the registry (assuming
  88. // of course there is a DSN given -- if not, it does nothing!)
  89. getDSNinfo(ci, CONN_DONT_OVERWRITE);
  90. // Fill in any default parameters if they are not there.
  91. getDSNdefaults(ci);
  92. #ifdef WIN32
  93. dialog:
  94. #endif
  95. ci->focus_password = password_required;
  96. switch(fDriverCompletion) {
  97. #ifdef WIN32
  98. case SQL_DRIVER_PROMPT:
  99. dialog_result = dconn_DoDialog(hwnd, ci);
  100. if(dialog_result != SQL_SUCCESS) {
  101. return dialog_result;
  102. }
  103. break;
  104. case SQL_DRIVER_COMPLETE_REQUIRED:
  105. /* Fall through */
  106. case SQL_DRIVER_COMPLETE:
  107. /* Password is not a required parameter. */
  108. if( ci->username[0] == '' ||
  109. ci->server[0] == '' ||
  110. ci->database[0] == '' ||
  111. ci->port[0] == '' ||
  112. password_required) { 
  113. dialog_result = dconn_DoDialog(hwnd, ci);
  114. if(dialog_result != SQL_SUCCESS) {
  115. return dialog_result;
  116. }
  117. }
  118. break;
  119. #else
  120. case SQL_DRIVER_PROMPT:
  121. case SQL_DRIVER_COMPLETE:
  122. case SQL_DRIVER_COMPLETE_REQUIRED:
  123. #endif
  124. case SQL_DRIVER_NOPROMPT:
  125. break;
  126. }
  127. /* Password is not a required parameter unless authentication asks for it.
  128. For now, I think its better to just let the application ask over and over until
  129. a password is entered (the user can always hit Cancel to get out)
  130. */
  131. if( ci->username[0] == '' ||
  132. ci->server[0] == '' ||
  133. ci->database[0] == '' || 
  134. ci->port[0] == '') {
  135. // (password_required && ci->password[0] == ''))
  136. return SQL_NO_DATA_FOUND;
  137. }
  138. // do the actual connect
  139. retval = CC_connect(conn, password_required);
  140. if (retval < 0) { /* need a password */
  141. if (fDriverCompletion == SQL_DRIVER_NOPROMPT) {
  142. CC_log_error(func, "Need password but Driver_NoPrompt", conn);
  143. return SQL_ERROR; /* need a password but not allowed to prompt so error */
  144. }
  145. else {
  146. #ifdef WIN32
  147. password_required = TRUE;
  148. goto dialog;
  149. #else
  150. return SQL_ERROR; /* until a better solution is found. */
  151. #endif
  152. }
  153. }
  154. else if (retval == 0) {
  155. // error msg filled in above
  156. CC_log_error(func, "Error from CC_Connect", conn);
  157. return SQL_ERROR;
  158. }
  159. /*********************************************/
  160. /*     Create the Output Connection String   */
  161. /*********************************************/
  162. result = SQL_SUCCESS;
  163. makeConnectString(connStrOut, ci);
  164. len = strlen(connStrOut);
  165. if(szConnStrOut) {
  166. /* Return the completed string to the caller. The correct method is to 
  167. only construct the connect string if a dialog was put up, otherwise, 
  168. it should just copy the connection input string to the output.  
  169. However, it seems ok to just always construct an output string.  There
  170. are possible bad side effects on working applications (Access) by 
  171. implementing the correct behavior, anyway. 
  172. */
  173. strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);
  174. if (len >= cbConnStrOutMax) {
  175. result = SQL_SUCCESS_WITH_INFO;
  176. conn->errornumber = CONN_TRUNCATED;
  177. conn->errormsg = "The buffer was too small for the result.";
  178. }
  179. }
  180. if(pcbConnStrOut)
  181. *pcbConnStrOut = len;
  182. mylog("szConnStrOut = '%s'n", szConnStrOut);
  183. qlog("conn=%u, SQLDriverConnect(out)='%s'n", conn, szConnStrOut);
  184. mylog("SQLDRiverConnect: returning %dn", result);
  185. return result;
  186. }
  187. #ifdef WIN32
  188. RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci)
  189. {
  190. int dialog_result;
  191. mylog("dconn_DoDialog: ci = %un", ci);
  192. if(hwnd) {
  193. dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG),
  194. hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
  195. if(!dialog_result || (dialog_result == -1)) {
  196. return SQL_NO_DATA_FOUND;
  197. } else {
  198. return SQL_SUCCESS;
  199. }
  200. }
  201. return SQL_ERROR;
  202. }
  203. BOOL FAR PASCAL dconn_FDriverConnectProc(
  204.                                          HWND    hdlg,
  205.                                          UINT    wMsg,
  206.                                          WPARAM  wParam,
  207.                                          LPARAM  lParam)
  208. {
  209. ConnInfo *ci;
  210. switch (wMsg) {
  211. case WM_INITDIALOG:
  212. ci = (ConnInfo *) lParam;
  213. /* Change the caption for the setup dialog */
  214. SetWindowText(hdlg, "PostgreSQL Connection");
  215. SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), "Connection");
  216. /* Hide the DSN and description fields */
  217. ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE);
  218. ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE);
  219. ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
  220. ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE);
  221. SetWindowLong(hdlg, DWL_USER, lParam);// Save the ConnInfo for the "OK"
  222. SetDlgStuff(hdlg, ci);
  223. if (ci->database[0] == '')
  224. ; /* default focus */
  225. else if (ci->server[0] == '')
  226. SetFocus(GetDlgItem(hdlg, IDC_SERVER));
  227. else if (ci->port[0] == '')
  228. SetFocus(GetDlgItem(hdlg, IDC_PORT));
  229. else if (ci->username[0] == '')
  230. SetFocus(GetDlgItem(hdlg, IDC_USER));
  231. else if (ci->focus_password)
  232. SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
  233. break; 
  234. case WM_COMMAND:
  235. switch (GET_WM_COMMAND_ID(wParam, lParam)) {
  236. case IDOK:
  237. ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
  238. GetDlgStuff(hdlg, ci);
  239. case IDCANCEL:
  240. EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
  241. return TRUE;
  242. case IDC_DRIVER:
  243. DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
  244. hdlg, driver_optionsProc, (LPARAM) NULL);
  245. break;
  246. case IDC_DATASOURCE:
  247. ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
  248. DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
  249. hdlg, ds_optionsProc, (LPARAM) ci);
  250. break;
  251. }
  252. }
  253. return FALSE;
  254. }
  255. #endif /* WIN32 */
  256. void dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
  257. {
  258. char *our_connect_string;
  259. char *pair, *attribute, *value, *equals;
  260. char *strtok_arg;
  261. memset(ci, 0, sizeof(ConnInfo));
  262. our_connect_string = strdup(connect_string);
  263. strtok_arg = our_connect_string;
  264. mylog("our_connect_string = '%s'n", our_connect_string);
  265. while(1) {
  266. pair = strtok(strtok_arg, ";");
  267. if(strtok_arg) {
  268. strtok_arg = 0;
  269. }
  270. if(!pair) {
  271. break;
  272. }
  273. equals = strchr(pair, '=');
  274. if ( ! equals)
  275. continue;
  276. *equals = '';
  277. attribute = pair; // ex. DSN
  278. value = equals + 1; // ex. 'CEO co1'
  279. mylog("attribute = '%s', value = '%s'n", attribute, value);
  280. if( !attribute || !value)
  281. continue;          
  282. // Copy the appropriate value to the conninfo 
  283. copyAttributes(ci, attribute, value);
  284. }
  285. free(our_connect_string);
  286. }