Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

903 lines
28 KiB

  1. /***************************************************************************/
  2. /* PREPARE.C */
  3. /* Copyright (C) 1995-96 SYWARE Inc., All rights reserved */
  4. /***************************************************************************/
  5. // Commenting #define out - causing compiler error - not sure if needed, compiles
  6. // okay without it.
  7. //#define WINVER 0x0400
  8. #include "precomp.h"
  9. #include "wbemidl.h"
  10. #include <comdef.h>
  11. //smart pointer
  12. _COM_SMARTPTR_TYPEDEF(IWbemServices, IID_IWbemServices);
  13. _COM_SMARTPTR_TYPEDEF(IEnumWbemClassObject, IID_IEnumWbemClassObject);
  14. //_COM_SMARTPTR_TYPEDEF(IWbemContext, IID_IWbemContext );
  15. _COM_SMARTPTR_TYPEDEF(IWbemLocator, IID_IWbemLocator);
  16. #include "drdbdr.h"
  17. /***************************************************************************/
  18. RETCODE SQL_API SQLAllocStmt(
  19. HDBC hdbc,
  20. HSTMT FAR *phstmt)
  21. {
  22. LPDBC lpdbc;
  23. LPSTMT lpstmt;
  24. HGLOBAL hstmt;
  25. //To make guarentee Ole is initialized per thread
  26. COleInitializationManager myOleManager;
  27. /* Get connection handle */
  28. lpdbc = (LPDBC) hdbc;
  29. lpdbc->errcode = ERR_SUCCESS;
  30. /* Allocate memory for the statement */
  31. hstmt = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (STMT));
  32. if (hstmt == NULL || (lpstmt = (LPSTMT)GlobalLock (hstmt)) == NULL) {
  33. if (hstmt)
  34. GlobalFree(hstmt);
  35. lpdbc->errcode = ERR_MEMALLOCFAIL;
  36. *phstmt = SQL_NULL_HSTMT;
  37. return SQL_ERROR;
  38. }
  39. /* Put statement on the list of statements for the connection */
  40. lpstmt->lpNext = lpdbc->lpstmts;
  41. lpdbc->lpstmts = lpstmt;
  42. /* Initialize the statement handle */
  43. lpstmt->lpdbc = lpdbc;
  44. lpstmt->errcode = ERR_SUCCESS;
  45. ((char*)lpstmt->szError)[0] = 0;
  46. ((char*)lpstmt->szISAMError)[0] = 0;
  47. ((char*)lpstmt->szCursor)[0] = 0;
  48. lpstmt->fStmtType = STMT_TYPE_NONE;
  49. lpstmt->fStmtSubtype = STMT_SUBTYPE_NONE;
  50. lpstmt->irow = AFTER_LAST_ROW;
  51. lpstmt->fSqlType = 0;
  52. lpstmt->lpISAMTableList = NULL;
  53. ((char*)lpstmt->szTableName)[0] = 0;
  54. lpstmt->lpISAMQualifierList = NULL;
  55. ((char*)lpstmt->szQualifierName)[0] = 0;
  56. ((char*)lpstmt->szTableType)[0] = 0;
  57. lpstmt->fSyncMode = SQL_ASYNC_ENABLE_OFF; //default value
  58. lpstmt->lpISAMTableDef = NULL;
  59. lpstmt->lpKeyInfo = NULL;
  60. lpstmt->lpSqlStmt = NULL;
  61. lpstmt->fPreparedSql = FALSE;
  62. lpstmt->lpISAMStatement = NULL;
  63. lpstmt->fNeedData = FALSE;
  64. lpstmt->idxParameter = NO_SQLNODE;
  65. lpstmt->cbParameterOffset = -1;
  66. lpstmt->icol = NO_COLUMN;
  67. lpstmt->cRowCount = -1;
  68. lpstmt->cbOffset = 0;
  69. lpstmt->fISAMTxnStarted = FALSE;
  70. lpstmt->fDMLTxn = FALSE;
  71. /* So far no bound columns */
  72. lpstmt->lpBound = NULL;
  73. /* So far no parameters */
  74. lpstmt->lpParameter = NULL;
  75. /* Return the statement handle */
  76. *phstmt = (HSTMT FAR *) lpstmt;
  77. return SQL_SUCCESS;
  78. }
  79. /***************************************************************************/
  80. RETCODE SQL_API SQLFreeStmt(
  81. HSTMT hstmt,
  82. UWORD fOption)
  83. {
  84. LPSTMT lpstmt;
  85. LPSTMT lpstmtPrev;
  86. LPBOUND lpBound;
  87. LPPARAMETER lpParameter;
  88. RETCODE err;
  89. //To make guarentee Ole is initialized per thread
  90. COleInitializationManager myOleManager;
  91. /* Get statement handle */
  92. lpstmt = (LPSTMT) hstmt;
  93. lpstmt->errcode = ERR_SUCCESS;
  94. // ODBCTRACE(_T("\nWBEM ODBC Driver : SQLFreeStmt\n"));
  95. // MyImpersonator im (lpstmt);
  96. /* Do the operation */
  97. switch (fOption) {
  98. case SQL_CLOSE:
  99. /* End the transaction if need be */
  100. if ((lpstmt->fStmtType == STMT_TYPE_SELECT) &&
  101. (lpstmt->lpdbc->lpISAM->fTxnCapable != SQL_TC_NONE) &&
  102. lpstmt->lpdbc->fAutoCommitTxn) {
  103. err = SQLTransact(SQL_NULL_HENV, (HDBC)lpstmt->lpdbc, SQL_COMMIT);
  104. if ((err != SQL_SUCCESS) && (err != SQL_SUCCESS_WITH_INFO)) {
  105. lpstmt->errcode = lpstmt->lpdbc->errcode;
  106. s_lstrcpy(lpstmt->szISAMError, lpstmt->lpdbc->szISAMError);
  107. return err;
  108. }
  109. }
  110. /* Terminate the active statement */
  111. lpstmt->fStmtType = STMT_TYPE_NONE;
  112. lpstmt->fStmtSubtype = STMT_SUBTYPE_NONE;
  113. lpstmt->irow = AFTER_LAST_ROW;
  114. lpstmt->fSqlType = 0;
  115. if (lpstmt->lpISAMTableList != NULL) {
  116. ISAMFreeTableList(lpstmt->lpISAMTableList);
  117. lpstmt->lpISAMTableList = NULL;
  118. }
  119. if (lpstmt->lpISAMQualifierList != NULL) {
  120. ISAMFreeQualifierList(lpstmt->lpISAMQualifierList);
  121. lpstmt->lpISAMQualifierList = NULL;
  122. }
  123. (lpstmt->szTableName)[0] = 0;
  124. (lpstmt->szTableType)[0] = 0;
  125. (lpstmt->szQualifierName)[0] = 0;
  126. if (lpstmt->lpISAMTableDef != NULL) {
  127. ISAMCloseTable(lpstmt->lpISAMTableDef);
  128. lpstmt->lpISAMTableDef = NULL;
  129. }
  130. (lpstmt->szColumnName)[0] = 0;
  131. if (lpstmt->lpKeyInfo != NULL) {
  132. GlobalUnlock (GlobalPtrHandle(lpstmt->lpKeyInfo));
  133. GlobalFree (GlobalPtrHandle(lpstmt->lpKeyInfo));
  134. }
  135. if ((lpstmt->lpSqlStmt != NULL) && !(lpstmt->fPreparedSql)) {
  136. FreeTree(lpstmt->lpSqlStmt);
  137. lpstmt->lpSqlStmt = NULL;
  138. lpstmt->fPreparedSql = FALSE;
  139. if (lpstmt->lpISAMStatement != NULL) {
  140. ISAMFreeStatement(lpstmt->lpISAMStatement);
  141. lpstmt->lpISAMStatement = NULL;
  142. }
  143. }
  144. lpstmt->fNeedData = FALSE;
  145. lpstmt->idxParameter = NO_SQLNODE;
  146. lpstmt->cbParameterOffset = -1;
  147. lpstmt->icol = NO_COLUMN;
  148. lpstmt->cbOffset = 0;
  149. break;
  150. case SQL_DROP:
  151. /* Terminate the active statement */
  152. err = SQLFreeStmt(hstmt, SQL_CLOSE);
  153. if ((err != SQL_SUCCESS) && (err != SQL_SUCCESS_WITH_INFO)) {
  154. lpstmt->fStmtType = STMT_TYPE_NONE;
  155. err = SQLTransact(SQL_NULL_HENV, (HDBC)lpstmt->lpdbc, SQL_ROLLBACK);
  156. SQLFreeStmt(hstmt, SQL_CLOSE);
  157. }
  158. if (lpstmt->lpSqlStmt != NULL) {
  159. FreeTree(lpstmt->lpSqlStmt);
  160. lpstmt->lpSqlStmt = NULL;
  161. lpstmt->fPreparedSql = FALSE;
  162. if (lpstmt->lpISAMStatement != NULL) {
  163. ISAMFreeStatement(lpstmt->lpISAMStatement);
  164. lpstmt->lpISAMStatement = NULL;
  165. }
  166. }
  167. lpstmt->fNeedData = FALSE;
  168. lpstmt->idxParameter = NO_SQLNODE;
  169. lpstmt->cbParameterOffset = -1;
  170. lpstmt->cRowCount = -1;
  171. /*/ Unbind everything */
  172. SQLFreeStmt(hstmt, SQL_UNBIND);
  173. /* Reset the parameters */
  174. SQLFreeStmt(hstmt, SQL_RESET_PARAMS);
  175. /* Take statement off of list of statements for the connection */
  176. if (lpstmt->lpdbc->lpstmts == lpstmt) {
  177. lpstmt->lpdbc->lpstmts = lpstmt->lpNext;
  178. }
  179. else {
  180. lpstmtPrev = lpstmt->lpdbc->lpstmts;
  181. while (lpstmtPrev->lpNext != lpstmt)
  182. lpstmtPrev = lpstmtPrev->lpNext;
  183. lpstmtPrev->lpNext = lpstmt->lpNext;
  184. }
  185. /* Dealloate the memory */
  186. GlobalUnlock (GlobalPtrHandle(hstmt));
  187. GlobalFree (GlobalPtrHandle(hstmt));
  188. break;
  189. case SQL_UNBIND:
  190. /* Remove all the bindings */
  191. while (lpstmt->lpBound != NULL) {
  192. lpBound = lpstmt->lpBound->lpNext;
  193. GlobalUnlock (GlobalPtrHandle(lpstmt->lpBound));
  194. GlobalFree (GlobalPtrHandle(lpstmt->lpBound));
  195. lpstmt->lpBound = lpBound;
  196. }
  197. break;
  198. case SQL_RESET_PARAMS:
  199. /* It is not possible to reset the parameters while setting them */
  200. if (lpstmt->fNeedData) {
  201. lpstmt->errcode = ERR_CURSORSTATE;
  202. return SQL_ERROR;
  203. }
  204. /* Reset all the parameters */
  205. while (lpstmt->lpParameter != NULL) {
  206. lpParameter = lpstmt->lpParameter->lpNext;
  207. GlobalUnlock (GlobalPtrHandle(lpstmt->lpParameter));
  208. GlobalFree (GlobalPtrHandle(lpstmt->lpParameter));
  209. lpstmt->lpParameter = lpParameter;
  210. }
  211. break;
  212. }
  213. return SQL_SUCCESS;
  214. }
  215. /***************************************************************************/
  216. RETCODE SQL_API SQLPrepare(
  217. HSTMT hstmt,
  218. UCHAR FAR *szSqlStr,
  219. SDWORD cbSqlStr)
  220. {
  221. LPSTMT lpstmt;
  222. LPSQLNODE lpSqlNode;
  223. UCHAR szCursorname[MAX_CURSOR_NAME_LENGTH];
  224. int i;
  225. UCHAR szSimpleSql[21 + MAX_TABLE_NAME_LENGTH + 1];
  226. UWORD parameterCount;
  227. SQLNODEIDX idxParameter;
  228. SQLNODEIDX idxParameterPrev;
  229. UWORD id;
  230. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  231. /* Get statement handle */
  232. lpstmt = (LPSTMT) hstmt;
  233. lpstmt->errcode = ERR_SUCCESS;
  234. //To make guarentee Ole is initialized per thread
  235. COleInitializationManager myOleManager;
  236. CString myInputString;
  237. myInputString.Format("\nWBEM ODBC Driver :SQLPrepare :\nszSqlStr = %s\ncbSqlStr = %ld\n",
  238. szSqlStr, cbSqlStr);
  239. ODBCTRACE(myInputString);
  240. MyImpersonator im (lpstmt,"SQLPrepare");
  241. /* Error if in the middle of a statement already */
  242. if (lpstmt->fStmtType != STMT_TYPE_NONE) {
  243. lpstmt->errcode = ERR_CURSORSTATE;
  244. return SQL_ERROR;
  245. }
  246. if (lpstmt->fNeedData) {
  247. lpstmt->errcode = ERR_CURSORSTATE;
  248. return SQL_ERROR;
  249. }
  250. /* Free previously prepared statement if any */
  251. if (lpstmt->lpSqlStmt != NULL) {
  252. FreeTree(lpstmt->lpSqlStmt);
  253. lpstmt->lpSqlStmt = NULL;
  254. lpstmt->fPreparedSql = FALSE;
  255. if (lpstmt->lpISAMStatement != NULL) {
  256. ISAMFreeStatement(lpstmt->lpISAMStatement);
  257. lpstmt->lpISAMStatement = NULL;
  258. }
  259. lpstmt->fNeedData = FALSE;
  260. lpstmt->idxParameter = NO_SQLNODE;
  261. lpstmt->cbParameterOffset = -1;
  262. lpstmt->cRowCount = -1;
  263. }
  264. /* Count of rows is not available */
  265. lpstmt->cRowCount = -1;
  266. /* Try passing the statement down to the ISAM layer */
  267. if (cbSqlStr == SQL_NTS)
  268. {
  269. if (szSqlStr)
  270. cbSqlStr = s_lstrlen((char*)szSqlStr);
  271. else
  272. cbSqlStr = 0;
  273. }
  274. szSimpleSql[0] = 0;
  275. s_lstrcpy(szSimpleSql, "SELECT * FROM \"");
  276. lpstmt->errcode = ISAMPrepare(lpstmt->lpdbc->lpISAM, szSqlStr, cbSqlStr,
  277. &(lpstmt->lpISAMStatement), (LPUSTR) (szSimpleSql + 15),
  278. &parameterCount, lpstmt);
  279. if (lpstmt->errcode == ISAM_NOTSUPPORTED)
  280. {
  281. //Check if we are in passthrough only mode
  282. if (lpstmt->lpdbc->lpISAM->fPassthroughOnly)
  283. {
  284. ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM, (LPUSTR)lpstmt->szISAMError);
  285. return SQL_ERROR;
  286. }
  287. else
  288. {
  289. lpstmt->lpISAMStatement = NULL;
  290. parameterCount = 0;
  291. }
  292. }
  293. else if (lpstmt->errcode != NO_ISAM_ERR) {
  294. ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM, (LPUSTR)lpstmt->szISAMError);
  295. return SQL_ERROR;
  296. }
  297. else
  298. lpstmt->fISAMTxnStarted = TRUE;
  299. /* Was the SQL passthrough rejected or is it returning a result set? */
  300. if ((lpstmt->errcode == ISAM_NOTSUPPORTED) ||
  301. (s_lstrlen((szSimpleSql + 15)) != 0)) {
  302. /* Yes. Parse the statement */
  303. if (lpstmt->errcode == ISAM_NOTSUPPORTED) {
  304. lpstmt->errcode = Parse(lpstmt, lpstmt->lpdbc->lpISAM, (LPUSTR)szSqlStr,
  305. cbSqlStr, &(lpstmt->lpSqlStmt));
  306. }
  307. else {
  308. s_lstrcat(szSimpleSql, "\"");
  309. //NEW
  310. //Sai Wong - removed this Parse as it has already been
  311. //done in ISAMPrepare
  312. //Changed again
  313. //Parse SELECT * from WBEMDR32VirtualTable
  314. lpstmt->errcode = Parse(lpstmt, lpstmt->lpdbc->lpISAM,
  315. szSimpleSql, s_lstrlen(szSimpleSql), &(lpstmt->lpSqlStmt));
  316. }
  317. if (lpstmt->errcode != SQL_SUCCESS) {
  318. if (lpstmt->lpISAMStatement != NULL) {
  319. ISAMFreeStatement(lpstmt->lpISAMStatement);
  320. lpstmt->lpISAMStatement = NULL;
  321. }
  322. return SQL_ERROR;
  323. }
  324. /* Semanticize the parsed statement */
  325. lpstmt->errcode = SemanticCheck(lpstmt, &(lpstmt->lpSqlStmt),
  326. ROOT_SQLNODE, FALSE, ISAMCaseSensitive(lpstmt->lpdbc->lpISAM),
  327. NO_SQLNODE, NO_SQLNODE);
  328. if (lpstmt->errcode != SQL_SUCCESS) {
  329. FreeTree(lpstmt->lpSqlStmt);
  330. lpstmt->lpSqlStmt = NULL;
  331. if (lpstmt->lpISAMStatement != NULL) {
  332. ISAMFreeStatement(lpstmt->lpISAMStatement);
  333. lpstmt->lpISAMStatement = NULL;
  334. }
  335. return SQL_ERROR;
  336. }
  337. /* Optimize execution */
  338. lpstmt->errcode = Optimize(lpstmt->lpSqlStmt,
  339. ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE)->node.root.sql,
  340. ISAMCaseSensitive(lpstmt->lpdbc->lpISAM));
  341. if (lpstmt->errcode != SQL_SUCCESS) {
  342. FreeTree(lpstmt->lpSqlStmt);
  343. lpstmt->lpSqlStmt = NULL;
  344. if (lpstmt->lpISAMStatement != NULL) {
  345. ISAMFreeStatement(lpstmt->lpISAMStatement);
  346. lpstmt->lpISAMStatement = NULL;
  347. }
  348. return SQL_ERROR;
  349. }
  350. #if ISAM_TRACE
  351. ShowSemantic(lpstmt->lpSqlStmt, ROOT_SQLNODE, 0);
  352. #endif
  353. }
  354. else {
  355. #ifdef IMPLTMT_PASSTHROUGH
  356. //No nothing
  357. #else
  358. /* No. Create a PASSTHROUGH parse tree */
  359. lpstmt->errcode = Parse(lpstmt, lpstmt->lpdbc->lpISAM, (LPUSTR) "SQL",
  360. 3, &(lpstmt->lpSqlStmt));
  361. if (lpstmt->errcode != SQL_SUCCESS) {
  362. ISAMFreeStatement(lpstmt->lpISAMStatement);
  363. lpstmt->lpISAMStatement = NULL;
  364. return SQL_ERROR;
  365. }
  366. #endif
  367. }
  368. /* Are there pass through parameters? */
  369. if (parameterCount != 0) {
  370. /* Yes. Create them */
  371. idxParameterPrev = NO_SQLNODE;
  372. for (id = 1; id <= parameterCount; id++) {
  373. /* Create the next parameter */
  374. idxParameter = AllocateNode(&(lpstmt->lpSqlStmt),
  375. NODE_TYPE_PARAMETER);
  376. if (idxParameter == NO_SQLNODE) {
  377. FreeTree(lpstmt->lpSqlStmt);
  378. lpstmt->lpSqlStmt = NULL;
  379. ISAMFreeStatement(lpstmt->lpISAMStatement);
  380. lpstmt->lpISAMStatement = NULL;
  381. lpstmt->errcode = ERR_MEMALLOCFAIL;
  382. return SQL_ERROR;
  383. }
  384. lpSqlNode = ToNode(lpstmt->lpSqlStmt, idxParameter);
  385. lpSqlNode->node.parameter.Id = id;
  386. lpSqlNode->node.parameter.Next = NO_SQLNODE;
  387. lpSqlNode->node.parameter.Value = NO_STRING;
  388. lpSqlNode->node.parameter.AtExec = FALSE;
  389. /* Put it on the list */
  390. if (idxParameterPrev == NO_SQLNODE) {
  391. lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  392. lpSqlNode->node.root.parameters = idxParameter;
  393. lpSqlNode->node.root.passthroughParams = TRUE;
  394. }
  395. else {
  396. lpSqlNode = ToNode(lpstmt->lpSqlStmt, idxParameterPrev);
  397. lpSqlNode->node.parameter.Next = idxParameter;
  398. }
  399. idxParameterPrev = idxParameter;
  400. /* Semantic check the newly created parameter */
  401. lpstmt->errcode = SemanticCheck(lpstmt, &(lpstmt->lpSqlStmt),
  402. idxParameter, FALSE, ISAMCaseSensitive(lpstmt->lpdbc->lpISAM),
  403. NO_SQLNODE, NO_SQLNODE);
  404. if (lpstmt->errcode != SQL_SUCCESS) {
  405. FreeTree(lpstmt->lpSqlStmt);
  406. lpstmt->lpSqlStmt = NULL;
  407. ISAMFreeStatement(lpstmt->lpISAMStatement);
  408. lpstmt->lpISAMStatement = NULL;
  409. return SQL_ERROR;
  410. }
  411. /* All passthrough parameters are strings */
  412. lpSqlNode = ToNode(lpstmt->lpSqlStmt, idxParameter);
  413. lpSqlNode->sqlDataType = TYPE_CHAR;
  414. lpSqlNode->sqlSqlType = SQL_VARCHAR;
  415. lpSqlNode->sqlPrecision = MAX_CHAR_LITERAL_LENGTH;
  416. lpSqlNode->sqlScale = NO_SCALE;
  417. }
  418. }
  419. /* Allocate space for the parameters */
  420. lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  421. for (idxParameter = lpSqlNode->node.root.parameters;
  422. idxParameter != NO_SQLNODE;
  423. idxParameter = lpSqlNode->node.parameter.Next) {
  424. /* Get parameter node */
  425. lpSqlNode = ToNode(lpstmt->lpSqlStmt, idxParameter);
  426. /* Allocate space for the parameter value */
  427. switch (lpSqlNode->sqlDataType) {
  428. case TYPE_DOUBLE:
  429. lpSqlNode->node.parameter.Value = NO_STRING;
  430. break;
  431. case TYPE_NUMERIC:
  432. lpSqlNode->node.parameter.Value = AllocateSpace(&(lpstmt->lpSqlStmt),
  433. (SWORD)(lpSqlNode->sqlPrecision + 2 + 1));
  434. if (lpSqlNode->node.parameter.Value == NO_STRING) {
  435. FreeTree(lpstmt->lpSqlStmt);
  436. lpstmt->lpSqlStmt = NULL;
  437. if (lpstmt->lpISAMStatement != NULL) {
  438. ISAMFreeStatement(lpstmt->lpISAMStatement);
  439. lpstmt->lpISAMStatement = NULL;
  440. }
  441. lpstmt->errcode = ERR_MEMALLOCFAIL;
  442. return SQL_ERROR;
  443. }
  444. break;
  445. case TYPE_INTEGER:
  446. lpSqlNode->node.parameter.Value = NO_STRING;
  447. break;
  448. case TYPE_CHAR:
  449. lpSqlNode->node.parameter.Value = AllocateSpace(&(lpstmt->lpSqlStmt),
  450. MAX_CHAR_LITERAL_LENGTH+1);
  451. if (lpSqlNode->node.parameter.Value == NO_STRING) {
  452. FreeTree(lpstmt->lpSqlStmt);
  453. lpstmt->lpSqlStmt = NULL;
  454. if (lpstmt->lpISAMStatement != NULL) {
  455. ISAMFreeStatement(lpstmt->lpISAMStatement);
  456. lpstmt->lpISAMStatement = NULL;
  457. }
  458. lpstmt->errcode = ERR_MEMALLOCFAIL;
  459. return SQL_ERROR;
  460. }
  461. break;
  462. case TYPE_BINARY:
  463. lpSqlNode->node.parameter.Value = AllocateSpace(&(lpstmt->lpSqlStmt),
  464. MAX_BINARY_LITERAL_LENGTH + sizeof(SDWORD));
  465. if (lpSqlNode->node.parameter.Value == NO_STRING) {
  466. FreeTree(lpstmt->lpSqlStmt);
  467. lpstmt->lpSqlStmt = NULL;
  468. if (lpstmt->lpISAMStatement != NULL) {
  469. ISAMFreeStatement(lpstmt->lpISAMStatement);
  470. lpstmt->lpISAMStatement = NULL;
  471. }
  472. lpstmt->errcode = ERR_MEMALLOCFAIL;
  473. return SQL_ERROR;
  474. }
  475. break;
  476. case TYPE_DATE:
  477. lpSqlNode->node.parameter.Value = NO_STRING;
  478. break;
  479. case TYPE_TIME:
  480. lpSqlNode->node.parameter.Value = NO_STRING;
  481. break;
  482. case TYPE_TIMESTAMP:
  483. lpSqlNode->node.parameter.Value = NO_STRING;
  484. break;
  485. case TYPE_UNKNOWN:
  486. /* Error if '?' used in a select list */
  487. if (parameterCount == 0)
  488. lpstmt->errcode = ERR_PARAMINSELECT;
  489. else
  490. lpstmt->errcode = ERR_INTERNAL;
  491. return SQL_ERROR;
  492. default:
  493. lpstmt->errcode = ERR_NOTSUPPORTED;
  494. return SQL_ERROR;
  495. }
  496. }
  497. /* Was a SELECT statement preprared? */
  498. lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  499. lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.root.sql);
  500. if (lpSqlNode->sqlNodeType == NODE_TYPE_SELECT) {
  501. /* Yes. Is a cursor name needed? */
  502. if (s_lstrlen(lpstmt->szCursor) == 0) {
  503. /* Yes. Assign one */
  504. for (i=0; TRUE; i++) {
  505. wsprintf((LPSTR)szCursorname, "CUR%05d", (SWORD)i);
  506. if (SQLSetCursorName(hstmt, (LPUSTR) szCursorname, SQL_NTS) ==
  507. SQL_SUCCESS)
  508. break;
  509. }
  510. }
  511. }
  512. /* Mark the statement as from SQLPrepare() */
  513. lpstmt->fPreparedSql = TRUE;
  514. return SQL_SUCCESS;
  515. }
  516. /***************************************************************************/
  517. RETCODE SQL_API SQLBindParameter(
  518. HSTMT hstmt,
  519. UWORD ipar,
  520. SWORD fParamType,
  521. SWORD fCType,
  522. SWORD fSqlType,
  523. UDWORD cbColDef,
  524. SWORD ibScale,
  525. PTR rgbValue,
  526. SDWORD cbValueMax,
  527. SDWORD FAR *pcbValue)
  528. {
  529. LPSTMT lpstmt;
  530. LPPARAMETER lpParameter;
  531. HGLOBAL hParameter;
  532. LPSQLTYPE lpSqlType;
  533. UWORD i;
  534. /* Get statement handle */
  535. lpstmt = (LPSTMT) hstmt;
  536. lpstmt->errcode = ERR_SUCCESS;
  537. //To make guarentee Ole is initialized per thread
  538. COleInitializationManager myOleManager;
  539. MyImpersonator im (lpstmt, "SQLBindParameter");
  540. /* Error if in the middle of a statement already */
  541. if (lpstmt->fNeedData) {
  542. lpstmt->errcode = ERR_CURSORSTATE;
  543. return SQL_ERROR;
  544. }
  545. /* If SQL_C_DEFAULT was specified as the type, figure out the real type */
  546. if (fCType == SQL_C_DEFAULT) {
  547. switch (fSqlType) {
  548. case SQL_CHAR:
  549. case SQL_VARCHAR:
  550. case SQL_LONGVARCHAR:
  551. fCType = SQL_C_CHAR;
  552. break;
  553. case SQL_BIGINT:
  554. case SQL_DECIMAL:
  555. case SQL_NUMERIC:
  556. fCType = SQL_C_CHAR;
  557. break;
  558. case SQL_DOUBLE:
  559. case SQL_FLOAT:
  560. fCType = SQL_C_DOUBLE;
  561. break;
  562. case SQL_BIT:
  563. fCType = SQL_C_BIT;
  564. break;
  565. case SQL_REAL:
  566. fCType = SQL_C_FLOAT;
  567. break;
  568. case SQL_INTEGER:
  569. fCType = SQL_C_LONG;
  570. break;
  571. case SQL_SMALLINT:
  572. fCType = SQL_C_SHORT;
  573. break;
  574. case SQL_TINYINT:
  575. fCType = SQL_C_TINYINT;
  576. break;
  577. case SQL_DATE:
  578. fCType = SQL_C_DATE;
  579. break;
  580. case SQL_TIME:
  581. fCType = SQL_C_TIME;
  582. break;
  583. case SQL_TIMESTAMP:
  584. fCType = SQL_C_TIMESTAMP;
  585. break;
  586. case SQL_BINARY:
  587. case SQL_VARBINARY:
  588. case SQL_LONGVARBINARY:
  589. fCType = SQL_C_BINARY;
  590. break;
  591. default:
  592. lpstmt->errcode = ERR_NOTSUPPORTED;
  593. return SQL_ERROR;
  594. }
  595. }
  596. /* If C type is SQL_C_TINYINT, figure out if it is signed or unsigned */
  597. if (fCType == SQL_C_TINYINT) {
  598. lpSqlType = NULL;
  599. for (i = 0; i < lpstmt->lpdbc->lpISAM->cSQLTypes; i++) {
  600. if (lpstmt->lpdbc->lpISAM->SQLTypes[i].type == SQL_TINYINT) {
  601. lpSqlType = &(lpstmt->lpdbc->lpISAM->SQLTypes[i]);
  602. break;
  603. }
  604. }
  605. if (lpSqlType == NULL)
  606. fCType = SQL_C_STINYINT;
  607. else if (lpSqlType->unsignedAttribute == TRUE)
  608. fCType = SQL_C_UTINYINT;
  609. else
  610. fCType = SQL_C_STINYINT;
  611. }
  612. /* If C type is SQL_C_SHORT, figure out if it is signed or unsigned */
  613. if (fCType == SQL_C_SHORT) {
  614. lpSqlType = NULL;
  615. for (i = 0; i < lpstmt->lpdbc->lpISAM->cSQLTypes; i++) {
  616. if (lpstmt->lpdbc->lpISAM->SQLTypes[i].type == SQL_SMALLINT) {
  617. lpSqlType = &(lpstmt->lpdbc->lpISAM->SQLTypes[i]);
  618. break;
  619. }
  620. }
  621. if (lpSqlType == NULL)
  622. fCType = SQL_C_SSHORT;
  623. else if (lpSqlType->unsignedAttribute == TRUE)
  624. fCType = SQL_C_USHORT;
  625. else
  626. fCType = SQL_C_SSHORT;
  627. }
  628. /* If C type is SQL_C_LONG, figure out if it is signed or unsigned */
  629. if (fCType == SQL_C_LONG) {
  630. lpSqlType = NULL;
  631. for (i = 0; i < lpstmt->lpdbc->lpISAM->cSQLTypes; i++) {
  632. if (lpstmt->lpdbc->lpISAM->SQLTypes[i].type == SQL_INTEGER) {
  633. lpSqlType = &(lpstmt->lpdbc->lpISAM->SQLTypes[i]);
  634. break;
  635. }
  636. }
  637. if (lpSqlType == NULL)
  638. fCType = SQL_C_SLONG;
  639. else if (lpSqlType->unsignedAttribute == TRUE)
  640. fCType = SQL_C_ULONG;
  641. else
  642. fCType = SQL_C_SLONG;
  643. }
  644. /* Ignore output parameters */
  645. if (fParamType == SQL_PARAM_OUTPUT)
  646. return SQL_SUCCESS;
  647. /* Find the parameter is on the list */
  648. lpParameter = lpstmt->lpParameter;
  649. while (lpParameter != NULL) {
  650. if (lpParameter->ipar == ipar)
  651. break;
  652. lpParameter = lpParameter->lpNext;
  653. }
  654. /* No. Was it on the list? */
  655. if (lpParameter == NULL) {
  656. /* No. Make an entry for it */
  657. hParameter = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (PARAMETER));
  658. if (hParameter == NULL || (lpParameter = (LPPARAMETER)GlobalLock (hParameter)) == NULL) {
  659. if (hParameter)
  660. GlobalFree(hParameter);
  661. lpstmt->errcode = ERR_MEMALLOCFAIL;
  662. return SQL_ERROR;
  663. }
  664. lpParameter->lpNext = lpstmt->lpParameter;
  665. lpstmt->lpParameter = lpParameter;
  666. lpParameter->ipar = ipar;
  667. }
  668. /* Save the bound description */
  669. lpParameter->fCType = fCType;
  670. lpParameter->rgbValue = rgbValue;
  671. lpParameter->pcbValue = pcbValue;
  672. return SQL_SUCCESS;
  673. }
  674. /***************************************************************************/
  675. RETCODE SQL_API SQLDescribeParam(
  676. HSTMT hstmt,
  677. UWORD ipar,
  678. SWORD FAR *pfSqlType,
  679. UDWORD FAR *pcbColDef,
  680. SWORD FAR *pibScale,
  681. SWORD FAR *pfNullable)
  682. {
  683. LPSTMT lpstmt;
  684. lpstmt = (LPSTMT) hstmt;
  685. lpstmt->errcode = ERR_NOTSUPPORTED;
  686. return SQL_ERROR;
  687. }
  688. /***************************************************************************/
  689. RETCODE SQL_API SQLParamOptions(
  690. HSTMT hstmt,
  691. UDWORD crow,
  692. UDWORD FAR *pirow)
  693. {
  694. LPSTMT lpstmt;
  695. lpstmt = (LPSTMT) hstmt;
  696. lpstmt->errcode = ERR_NOTSUPPORTED;
  697. return SQL_ERROR;
  698. }
  699. /***************************************************************************/
  700. RETCODE SQL_API SQLNumParams(
  701. HSTMT hstmt,
  702. SWORD FAR *pcpar)
  703. {
  704. LPSTMT lpstmt;
  705. lpstmt = (LPSTMT) hstmt;
  706. lpstmt->errcode = ERR_NOTSUPPORTED;
  707. return SQL_ERROR;
  708. }
  709. /***************************************************************************/
  710. RETCODE SQL_API SQLSetScrollOptions(
  711. HSTMT hstmt,
  712. UWORD fConcurrency,
  713. SDWORD crowKeyset,
  714. UWORD crowRowset)
  715. {
  716. LPSTMT lpstmt;
  717. lpstmt = (LPSTMT) hstmt;
  718. lpstmt->errcode = ERR_NOTSUPPORTED;
  719. return SQL_ERROR;
  720. }
  721. /***************************************************************************/
  722. RETCODE SQL_API SQLSetCursorName(
  723. HSTMT hstmt,
  724. UCHAR FAR *szCursor,
  725. SWORD cbCursor)
  726. {
  727. SWORD cbIn;
  728. LPSTMT lpstmt;
  729. UCHAR szCursorname[MAX_CURSOR_NAME_LENGTH];
  730. LPSTMT lpstmtOther;
  731. /* Get statement handle */
  732. lpstmt = (LPSTMT) hstmt;
  733. lpstmt->errcode = ERR_SUCCESS;
  734. //To make guarentee Ole is initialized per thread
  735. COleInitializationManager myOleManager;
  736. MyImpersonator im (lpstmt, "SQLSetCursorName");
  737. /* Get length of cursor name */
  738. if (cbCursor == SQL_NTS)
  739. cbIn = (SWORD) s_lstrlen(szCursor);
  740. else
  741. cbIn = cbCursor;
  742. if ((cbIn <= 0) || (cbIn >= MAX_CURSOR_NAME_LENGTH)) {
  743. lpstmt->errcode = ERR_INVALIDCURSORNAME;
  744. return SQL_ERROR;
  745. }
  746. /* Make a null terminated copy of the cursor name */
  747. _fmemcpy(szCursorname, szCursor, cbIn);
  748. szCursorname[cbIn] = '\0';
  749. /* Make sure name is not already in use */
  750. for (lpstmtOther = lpstmt->lpdbc->lpstmts;
  751. lpstmtOther != NULL;
  752. lpstmtOther = lpstmtOther->lpNext) {
  753. if (lpstmtOther != lpstmt) {
  754. if (!s_lstrcmpi(lpstmtOther->szCursor, szCursorname)) {
  755. lpstmt->errcode = ERR_CURSORNAMEINUSE;
  756. return SQL_ERROR;
  757. }
  758. }
  759. }
  760. /* Save cursor name */
  761. s_lstrcpy(lpstmt->szCursor, szCursorname);
  762. return SQL_SUCCESS;
  763. }
  764. /***************************************************************************/
  765. RETCODE SQL_API SQLGetCursorName(
  766. HSTMT hstmt,
  767. UCHAR FAR *szCursor,
  768. SWORD cbCursorMax,
  769. SWORD FAR *pcbCursor)
  770. {
  771. LPSTMT lpstmt;
  772. /* Get statement handle */
  773. lpstmt = (LPSTMT) hstmt;
  774. lpstmt->errcode = ERR_SUCCESS;
  775. //To make guarentee Ole is initialized per thread
  776. COleInitializationManager myOleManager;
  777. MyImpersonator im (lpstmt, "SQLGetCursorName");
  778. /* Return cursor name */
  779. lpstmt->errcode = ReturnString(szCursor, cbCursorMax,
  780. pcbCursor, (LPUSTR)lpstmt->szCursor);
  781. if (lpstmt->errcode == ERR_DATATRUNCATED)
  782. return SQL_SUCCESS_WITH_INFO;
  783. return SQL_SUCCESS;
  784. }
  785. /***************************************************************************/