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.

3497 lines
109 KiB

  1. /***************************************************************************/
  2. /* RESULTS.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. BOOL INTFUNC GetUnsignedAttribute(LPSTMT lpstmt, SWORD fSqlType)
  19. {
  20. UWORD i;
  21. for (i = 0; i < lpstmt->lpdbc->lpISAM->cSQLTypes; i++) {
  22. if (lpstmt->lpdbc->lpISAM->SQLTypes[i].type == fSqlType) {
  23. if (lpstmt->lpdbc->lpISAM->SQLTypes[i].unsignedAttribute == -1)
  24. return FALSE;
  25. else
  26. return lpstmt->lpdbc->lpISAM->SQLTypes[i].unsignedAttribute;
  27. }
  28. }
  29. return FALSE;
  30. }
  31. /***************************************************************************/
  32. RETCODE SQL_API SQLNumResultCols(
  33. HSTMT hstmt,
  34. SWORD FAR *pccol)
  35. {
  36. RETCODE rc;
  37. SDWORD ccol;
  38. //To make guarentee Ole is initialized per thread
  39. COleInitializationManager myOleManager;
  40. MyImpersonator im ( (LPSTMT)hstmt, "SQLNumResultCols" );
  41. /* Find the number of columns */
  42. rc = SQL_SUCCESS;
  43. if (pccol != NULL) {
  44. rc = SQLColAttributes(hstmt, 0, SQL_COLUMN_COUNT, NULL,
  45. 0, NULL, &ccol);
  46. if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  47. return rc;
  48. *pccol = (SWORD) ccol;
  49. }
  50. return rc;
  51. }
  52. /***************************************************************************/
  53. RETCODE SQL_API SQLDescribeCol(
  54. HSTMT hstmt,
  55. UWORD icol,
  56. UCHAR FAR *szColName,
  57. SWORD cbColNameMax,
  58. SWORD FAR *pcbColName,
  59. SWORD FAR *pfSqlType,
  60. UDWORD FAR *pcbColDef,
  61. SWORD FAR *pibScale,
  62. SWORD FAR *pfNullable)
  63. {
  64. RETCODE rc;
  65. SDWORD fDesc;
  66. LPSTMT lpstmt;
  67. //To make guarentee Ole is initialized per thread
  68. COleInitializationManager myOleManager;
  69. /* Get statement handle */
  70. lpstmt = (LPSTMT) hstmt;
  71. lpstmt->errcode = ERR_SUCCESS;
  72. MyImpersonator im (lpstmt, "SQLDecribeCol");
  73. /* Get each piece of information (get the column name last so that */
  74. /* if there is a truncation warning it will not get lost). */
  75. rc = SQL_SUCCESS;
  76. if (pfSqlType != NULL) {
  77. rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_TYPE, NULL,
  78. 0, NULL, &fDesc);
  79. if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  80. return rc;
  81. *pfSqlType = (SWORD) fDesc;
  82. }
  83. if (pcbColDef != NULL) {
  84. rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_PRECISION, NULL,
  85. 0, NULL, &fDesc);
  86. if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  87. return rc;
  88. *pcbColDef = (UDWORD) fDesc;
  89. //Added by Sai Wong
  90. if ( (SDWORD)fDesc == SQL_NO_TOTAL)
  91. {
  92. *pcbColDef = 0;
  93. }
  94. }
  95. if (pibScale != NULL) {
  96. rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_SCALE, NULL,
  97. 0, NULL, &fDesc);
  98. if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  99. return rc;
  100. *pibScale = (SWORD) fDesc;
  101. }
  102. if (pfNullable != NULL) {
  103. rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_NULLABLE, NULL,
  104. 0, NULL, &fDesc);
  105. if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  106. return rc;
  107. *pfNullable = (SWORD) fDesc;
  108. }
  109. if ((szColName != NULL) || (pcbColName)) {
  110. rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_NAME, szColName,
  111. cbColNameMax, pcbColName, NULL);
  112. if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  113. return rc;
  114. }
  115. return rc;
  116. }
  117. /***************************************************************************/
  118. RETCODE SQL_API SQLColAttributes(
  119. HSTMT hstmt,
  120. UWORD icol,
  121. UWORD fDescType,
  122. PTR rgbDesc,
  123. SWORD cbDescMax,
  124. SWORD FAR *pcbDesc,
  125. SDWORD FAR *pfDesc)
  126. {
  127. LPSTMT lpstmt;
  128. UINT fStmtType;
  129. LPSQLNODE lpSqlNode;
  130. RETCODE rc;
  131. UWORD count;
  132. LPSQLTYPE lpSqlType;
  133. STRINGIDX idxAlias;
  134. UWORD i;
  135. LPSQLNODE lpSqlNodeTable;
  136. /* Get statement handle */
  137. lpstmt = (LPSTMT) hstmt;
  138. lpstmt->errcode = ERR_SUCCESS;
  139. //To make guarentee Ole is initialized per thread
  140. COleInitializationManager myOleManager;
  141. MyImpersonator im (lpstmt, "SQLColAttributes");
  142. /* Get the statement type */
  143. fStmtType = lpstmt->fStmtType;
  144. /* Is there a prepared statement? */
  145. if (fStmtType == STMT_TYPE_NONE) {
  146. if (lpstmt->lpSqlStmt != NULL) {
  147. /* Yes. Determine the statement type */
  148. lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  149. lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.root.sql);
  150. switch (lpSqlNode->sqlNodeType) {
  151. case NODE_TYPE_SELECT:
  152. fStmtType = STMT_TYPE_SELECT;
  153. break;
  154. case NODE_TYPE_INSERT:
  155. case NODE_TYPE_DELETE:
  156. case NODE_TYPE_UPDATE:
  157. case NODE_TYPE_CREATE:
  158. case NODE_TYPE_DROP:
  159. case NODE_TYPE_CREATEINDEX:
  160. case NODE_TYPE_DROPINDEX:
  161. case NODE_TYPE_PASSTHROUGH:
  162. /* Update statements have no results */
  163. if (fDescType != SQL_COLUMN_COUNT) {
  164. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  165. return SQL_ERROR;
  166. }
  167. if (pfDesc != NULL)
  168. *pfDesc = 0;
  169. return SQL_SUCCESS;
  170. default:
  171. lpstmt->errcode = ERR_INTERNAL;
  172. return SQL_ERROR;
  173. }
  174. }
  175. }
  176. /* Get the attribute */
  177. switch (fStmtType) {
  178. case STMT_TYPE_NONE:
  179. if (fDescType != SQL_COLUMN_COUNT) {
  180. lpstmt->errcode = ERR_CURSORSTATE;
  181. return SQL_ERROR;
  182. }
  183. if (pfDesc != NULL)
  184. *pfDesc = 0;
  185. break;
  186. /* Look these answer up in the colAttributes table */
  187. case STMT_TYPE_TABLES:
  188. case STMT_TYPE_COLUMNS:
  189. case STMT_TYPE_STATISTICS:
  190. case STMT_TYPE_SPECIALCOLUMNS:
  191. case STMT_TYPE_TYPEINFO:
  192. case STMT_TYPE_PRIMARYKEYS:
  193. case STMT_TYPE_FOREIGNKEYS:
  194. /* Just want the number of columns? */
  195. if (fDescType == SQL_COLUMN_COUNT) {
  196. if (pfDesc != NULL)
  197. *pfDesc = colAttributes[lpstmt->fStmtType][0].count;
  198. }
  199. else if (icol > colAttributes[lpstmt->fStmtType][0].count) {
  200. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  201. return SQL_ERROR;
  202. }
  203. else {
  204. switch (fDescType) {
  205. case SQL_COLUMN_COUNT:
  206. if (pfDesc != NULL)
  207. *pfDesc = colAttributes[lpstmt->fStmtType][icol].count;
  208. break;
  209. case SQL_COLUMN_AUTO_INCREMENT:
  210. if (pfDesc != NULL)
  211. *pfDesc = colAttributes[lpstmt->fStmtType][icol].autoIncrement;
  212. break;
  213. case SQL_COLUMN_CASE_SENSITIVE:
  214. if (pfDesc != NULL) {
  215. *pfDesc = colAttributes[lpstmt->fStmtType][icol].caseSensitive;
  216. if (*pfDesc == -2)
  217. *pfDesc = ISAMCaseSensitive(lpstmt->lpdbc->lpISAM);
  218. }
  219. break;
  220. case SQL_COLUMN_DISPLAY_SIZE:
  221. if (pfDesc != NULL)
  222. *pfDesc = colAttributes[lpstmt->fStmtType][icol].displaySize;
  223. break;
  224. case SQL_COLUMN_LABEL:
  225. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc,
  226. colAttributes[lpstmt->fStmtType][icol].label);
  227. if (lpstmt->errcode == ERR_DATATRUNCATED)
  228. return SQL_SUCCESS_WITH_INFO;
  229. break;
  230. case SQL_COLUMN_LENGTH:
  231. if (pfDesc != NULL)
  232. *pfDesc = colAttributes[lpstmt->fStmtType][icol].length;
  233. break;
  234. case SQL_COLUMN_MONEY:
  235. if (pfDesc != NULL)
  236. *pfDesc = colAttributes[lpstmt->fStmtType][icol].money;
  237. break;
  238. case SQL_COLUMN_NAME:
  239. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc,
  240. colAttributes[lpstmt->fStmtType][icol].name);
  241. if (lpstmt->errcode == ERR_DATATRUNCATED)
  242. return SQL_SUCCESS_WITH_INFO;
  243. break;
  244. case SQL_COLUMN_NULLABLE:
  245. if (pfDesc != NULL)
  246. *pfDesc = colAttributes[lpstmt->fStmtType][icol].nullable;
  247. break;
  248. case SQL_COLUMN_OWNER_NAME:
  249. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc,
  250. colAttributes[lpstmt->fStmtType][icol].ownerName);
  251. if (lpstmt->errcode == ERR_DATATRUNCATED)
  252. return SQL_SUCCESS_WITH_INFO;
  253. break;
  254. case SQL_COLUMN_PRECISION:
  255. if (pfDesc != NULL)
  256. *pfDesc = (SDWORD)
  257. colAttributes[lpstmt->fStmtType][icol].precision;
  258. break;
  259. case SQL_COLUMN_QUALIFIER_NAME:
  260. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc,
  261. colAttributes[lpstmt->fStmtType][icol].qualifierName);
  262. if (lpstmt->errcode == ERR_DATATRUNCATED)
  263. return SQL_SUCCESS_WITH_INFO;
  264. break;
  265. case SQL_COLUMN_SCALE:
  266. if (pfDesc != NULL)
  267. *pfDesc = colAttributes[lpstmt->fStmtType][icol].scale;
  268. break;
  269. case SQL_COLUMN_SEARCHABLE:
  270. if (pfDesc != NULL)
  271. *pfDesc = colAttributes[lpstmt->fStmtType][icol].columnSearchable;
  272. break;
  273. case SQL_COLUMN_TABLE_NAME:
  274. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc,
  275. colAttributes[lpstmt->fStmtType][icol].tableName);
  276. if (lpstmt->errcode == ERR_DATATRUNCATED)
  277. return SQL_SUCCESS_WITH_INFO;
  278. break;
  279. case SQL_COLUMN_TYPE:
  280. if (pfDesc != NULL)
  281. *pfDesc = colAttributes[lpstmt->fStmtType][icol].type;
  282. break;
  283. case SQL_COLUMN_TYPE_NAME:
  284. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc,
  285. (LPUSTR) colAttributes[lpstmt->fStmtType][icol].typeName);
  286. if (lpstmt->errcode == ERR_DATATRUNCATED)
  287. return SQL_SUCCESS_WITH_INFO;
  288. break;
  289. case SQL_COLUMN_UNSIGNED:
  290. if (pfDesc != NULL)
  291. *pfDesc = colAttributes[lpstmt->fStmtType][icol].unsignedAttribute;
  292. break;
  293. case SQL_COLUMN_UPDATABLE:
  294. if (pfDesc != NULL)
  295. *pfDesc = colAttributes[lpstmt->fStmtType][icol].updatable;
  296. break;
  297. default:
  298. lpstmt->errcode = ERR_NOTSUPPORTED;
  299. return SQL_ERROR;
  300. }
  301. }
  302. break;
  303. case STMT_TYPE_SELECT:
  304. /* Get the list of columns */
  305. lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  306. lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.root.sql);
  307. /* Handle the special case when there are no columns */
  308. if (lpSqlNode->node.select.Values == NO_SQLNODE) {
  309. if (fDescType != SQL_COLUMN_COUNT) {
  310. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  311. return SQL_ERROR;
  312. }
  313. else {
  314. if (pfDesc != NULL)
  315. *pfDesc = 0;
  316. return SQL_SUCCESS;
  317. }
  318. }
  319. /* Find the desired column */
  320. lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.select.Values);
  321. for (count = 1;
  322. (count != icol) || (fDescType == SQL_COLUMN_COUNT);
  323. count++) {
  324. if (lpSqlNode->node.values.Next == NO_SQLNODE) {
  325. if (fDescType != SQL_COLUMN_COUNT) {
  326. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  327. return SQL_ERROR;
  328. }
  329. break;
  330. }
  331. lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.values.Next);
  332. }
  333. /* Column count? */
  334. if (fDescType != SQL_COLUMN_COUNT) {
  335. /* No. Save alias (if any) for later */
  336. idxAlias = lpSqlNode->node.values.Alias;
  337. /* No. Get the column node */
  338. lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.values.Value);
  339. /* Column reference? */
  340. if (lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) {
  341. /* Yes. Get the column definition */
  342. lpSqlNodeTable = ToNode(lpstmt->lpSqlStmt,
  343. lpSqlNode->node.column.Table);
  344. ClassColumnInfoBase* cInfoBase = lpSqlNodeTable->node.table.Handle->pColumnInfo;
  345. if ( !cInfoBase->IsValid() )
  346. {
  347. lpstmt->errcode = ERR_ISAM;
  348. return SQL_ERROR;
  349. }
  350. if ( !cInfoBase->GetDataTypeInfo(lpSqlNode->node.column.Id, lpSqlType) || (!lpSqlType) )
  351. {
  352. lpstmt->errcode = ERR_ISAM;
  353. return SQL_ERROR;
  354. }
  355. }
  356. else {
  357. /* No. Get the descriptor of the datatype */
  358. lpSqlType = NULL;
  359. for (i = 0; i < lpstmt->lpdbc->lpISAM->cSQLTypes; i++) {
  360. if (lpstmt->lpdbc->lpISAM->SQLTypes[i].type ==
  361. lpSqlNode->sqlSqlType) {
  362. lpSqlType = &(lpstmt->lpdbc->lpISAM->SQLTypes[i]);
  363. break;
  364. }
  365. }
  366. if (lpSqlType == NULL) {
  367. lpstmt->errcode = ERR_ISAM;
  368. return SQL_ERROR;
  369. }
  370. }
  371. }
  372. /* Get the data */
  373. switch (fDescType) {
  374. case SQL_COLUMN_AUTO_INCREMENT:
  375. if (pfDesc != NULL) {
  376. if (lpSqlType->autoincrement == -1)
  377. *pfDesc = FALSE;
  378. else
  379. *pfDesc = lpSqlType->autoincrement;
  380. }
  381. break;
  382. case SQL_COLUMN_CASE_SENSITIVE:
  383. if (pfDesc != NULL)
  384. *pfDesc = lpSqlType->caseSensitive;
  385. break;
  386. case SQL_COLUMN_COUNT:
  387. if (pfDesc != NULL)
  388. *pfDesc = count;
  389. break;
  390. case SQL_COLUMN_DISPLAY_SIZE:
  391. if (pfDesc == NULL)
  392. break;
  393. switch (lpSqlType->type) {
  394. case SQL_CHAR:
  395. case SQL_VARCHAR:
  396. case SQL_LONGVARCHAR:
  397. *pfDesc = lpSqlNode->sqlPrecision;
  398. break;
  399. case SQL_DECIMAL:
  400. case SQL_NUMERIC:
  401. *pfDesc = lpSqlNode->sqlPrecision + 2;
  402. break;
  403. case SQL_BIT:
  404. *pfDesc = 1;
  405. break;
  406. case SQL_TINYINT:
  407. if (lpSqlType->unsignedAttribute == TRUE)
  408. *pfDesc = 3;
  409. else
  410. *pfDesc = 4;
  411. break;
  412. case SQL_SMALLINT:
  413. if (lpSqlType->unsignedAttribute == TRUE)
  414. *pfDesc = 5;
  415. else
  416. *pfDesc = 6;
  417. break;
  418. case SQL_INTEGER:
  419. if (lpSqlType->unsignedAttribute == TRUE)
  420. *pfDesc = 10;
  421. else
  422. *pfDesc = 11;
  423. break;
  424. case SQL_BIGINT:
  425. if (lpSqlType->unsignedAttribute == TRUE)
  426. *pfDesc = lpSqlNode->sqlPrecision;
  427. else
  428. *pfDesc = lpSqlNode->sqlPrecision + 1;
  429. break;
  430. case SQL_REAL:
  431. *pfDesc = 13;
  432. break;
  433. case SQL_FLOAT:
  434. case SQL_DOUBLE:
  435. *pfDesc = 22;
  436. break;
  437. case SQL_DATE:
  438. *pfDesc = 10;
  439. break;
  440. case SQL_TIME:
  441. *pfDesc = 8;
  442. break;
  443. case SQL_TIMESTAMP:
  444. if (TIMESTAMP_SCALE > 0)
  445. *pfDesc = 20 + TIMESTAMP_SCALE;
  446. else
  447. *pfDesc = 19;
  448. break;
  449. case SQL_BINARY:
  450. case SQL_VARBINARY:
  451. case SQL_LONGVARBINARY:
  452. *pfDesc = lpSqlNode->sqlPrecision * 2;
  453. break;
  454. default:
  455. lpstmt->errcode = ERR_NOTSUPPORTED;
  456. return SQL_ERROR;
  457. }
  458. break;
  459. case SQL_COLUMN_LABEL:
  460. rc = SQLColAttributes(hstmt, icol, SQL_COLUMN_NAME, rgbDesc,
  461. cbDescMax, pcbDesc, pfDesc);
  462. if (rc != SQL_SUCCESS)
  463. return rc;
  464. break;
  465. case SQL_COLUMN_LENGTH:
  466. if (pfDesc == NULL)
  467. break;
  468. switch (lpSqlType->type) {
  469. case SQL_CHAR:
  470. case SQL_VARCHAR:
  471. case SQL_LONGVARCHAR:
  472. *pfDesc = lpSqlNode->sqlPrecision;
  473. break;
  474. case SQL_DECIMAL:
  475. case SQL_NUMERIC:
  476. *pfDesc = lpSqlNode->sqlPrecision + 2;
  477. break;
  478. case SQL_BIT:
  479. *pfDesc = 1;
  480. break;
  481. case SQL_TINYINT:
  482. *pfDesc = 1;
  483. break;
  484. case SQL_SMALLINT:
  485. *pfDesc = 2;
  486. break;
  487. case SQL_INTEGER:
  488. *pfDesc = 4;
  489. break;
  490. case SQL_BIGINT:
  491. if (lpSqlType->unsignedAttribute == TRUE)
  492. *pfDesc = lpSqlNode->sqlPrecision;
  493. else
  494. *pfDesc = lpSqlNode->sqlPrecision + 1;
  495. break;
  496. case SQL_REAL:
  497. *pfDesc = 4;
  498. break;
  499. case SQL_FLOAT:
  500. case SQL_DOUBLE:
  501. *pfDesc = 8;
  502. break;
  503. case SQL_DATE:
  504. *pfDesc = 6;
  505. break;
  506. case SQL_TIME:
  507. *pfDesc = 6;
  508. break;
  509. case SQL_TIMESTAMP:
  510. *pfDesc = 16;
  511. break;
  512. case SQL_BINARY:
  513. case SQL_VARBINARY:
  514. case SQL_LONGVARBINARY:
  515. *pfDesc = lpSqlNode->sqlPrecision;
  516. break;
  517. default:
  518. lpstmt->errcode = ERR_NOTSUPPORTED;
  519. return SQL_ERROR;
  520. }
  521. break;
  522. case SQL_COLUMN_MONEY:
  523. if (pfDesc != NULL)
  524. *pfDesc = lpSqlType->money;
  525. break;
  526. case SQL_COLUMN_NAME:
  527. if (idxAlias != NO_STRING) {
  528. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc,
  529. ToString(lpstmt->lpSqlStmt, idxAlias));
  530. if (lpstmt->errcode == ERR_DATATRUNCATED)
  531. return SQL_SUCCESS_WITH_INFO;
  532. else if (lpstmt->errcode != ERR_SUCCESS)
  533. return SQL_ERROR;
  534. }
  535. else if (lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) {
  536. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc,
  537. ToString(lpstmt->lpSqlStmt,
  538. lpSqlNode->node.column.Column));
  539. if (lpstmt->errcode == ERR_DATATRUNCATED)
  540. return SQL_SUCCESS_WITH_INFO;
  541. else if (lpstmt->errcode != ERR_SUCCESS)
  542. return SQL_ERROR;
  543. }
  544. else {
  545. if ((rgbDesc != NULL) && (cbDescMax > 0))
  546. s_lstrcpy(rgbDesc, "");
  547. if (pcbDesc != NULL)
  548. *pcbDesc = 0;
  549. }
  550. break;
  551. case SQL_COLUMN_NULLABLE:
  552. if (pfDesc != NULL) {
  553. // if (lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN)
  554. // *pfDesc = FALSE;
  555. // else
  556. *pfDesc = lpSqlType->nullable;
  557. }
  558. break;
  559. case SQL_COLUMN_OWNER_NAME:
  560. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, (LPUSTR) "");
  561. if (lpstmt->errcode == ERR_DATATRUNCATED)
  562. return SQL_SUCCESS_WITH_INFO;
  563. else if (lpstmt->errcode != ERR_SUCCESS)
  564. return SQL_ERROR;
  565. break;
  566. case SQL_COLUMN_PRECISION:
  567. if (pfDesc == NULL)
  568. break;
  569. switch (lpSqlType->type) {
  570. case SQL_CHAR:
  571. case SQL_VARCHAR:
  572. case SQL_LONGVARCHAR:
  573. case SQL_DECIMAL:
  574. case SQL_NUMERIC:
  575. case SQL_BIGINT:
  576. case SQL_BINARY:
  577. case SQL_VARBINARY:
  578. case SQL_LONGVARBINARY:
  579. *pfDesc = lpSqlNode->sqlPrecision;
  580. break;
  581. case SQL_BIT:
  582. *pfDesc = 1;
  583. break;
  584. case SQL_TINYINT:
  585. *pfDesc = 3;
  586. break;
  587. case SQL_SMALLINT:
  588. *pfDesc = 5;
  589. break;
  590. case SQL_INTEGER:
  591. *pfDesc = 10;
  592. break;
  593. case SQL_REAL:
  594. *pfDesc = 7;
  595. break;
  596. case SQL_FLOAT:
  597. case SQL_DOUBLE:
  598. *pfDesc = 15;
  599. break;
  600. case SQL_DATE:
  601. *pfDesc = 10;
  602. break;
  603. case SQL_TIME:
  604. *pfDesc = 8;
  605. break;
  606. case SQL_TIMESTAMP:
  607. if (TIMESTAMP_SCALE > 0)
  608. *pfDesc = 20 + TIMESTAMP_SCALE;
  609. else
  610. *pfDesc = 19;
  611. break;
  612. default:
  613. lpstmt->errcode = ERR_NOTSUPPORTED;
  614. return SQL_ERROR;
  615. }
  616. break;
  617. case SQL_COLUMN_QUALIFIER_NAME:
  618. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc, (LPUSTR) "");
  619. if (lpstmt->errcode == ERR_DATATRUNCATED)
  620. return SQL_SUCCESS_WITH_INFO;
  621. else if (lpstmt->errcode != ERR_SUCCESS)
  622. return SQL_ERROR;
  623. break;
  624. case SQL_COLUMN_SCALE:
  625. if (pfDesc != NULL) {
  626. if (lpSqlNode->sqlScale != NO_SCALE)
  627. *pfDesc = lpSqlNode->sqlScale;
  628. else
  629. *pfDesc = 0;
  630. }
  631. break;
  632. case SQL_COLUMN_SEARCHABLE:
  633. if (pfDesc != NULL)
  634. *pfDesc = lpSqlType->searchable;
  635. break;
  636. case SQL_COLUMN_TABLE_NAME:
  637. if (lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) {
  638. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc,
  639. ToString(lpstmt->lpSqlStmt,
  640. lpSqlNode->node.column.Tablealias));
  641. if (lpstmt->errcode == ERR_DATATRUNCATED)
  642. return SQL_SUCCESS_WITH_INFO;
  643. else if (lpstmt->errcode != ERR_SUCCESS)
  644. return SQL_ERROR;
  645. }
  646. else {
  647. if ((rgbDesc != NULL) && (cbDescMax > 0))
  648. s_lstrcpy(rgbDesc, "");
  649. if (pcbDesc != NULL)
  650. *pcbDesc = 0;
  651. }
  652. break;
  653. case SQL_COLUMN_TYPE:
  654. if (pfDesc != NULL)
  655. *pfDesc = lpSqlType->type;
  656. break;
  657. case SQL_COLUMN_TYPE_NAME:
  658. lpstmt->errcode = ReturnString(rgbDesc, cbDescMax, pcbDesc,
  659. lpSqlType->name);
  660. if (lpstmt->errcode == ERR_DATATRUNCATED)
  661. return SQL_SUCCESS_WITH_INFO;
  662. else if (lpstmt->errcode != ERR_SUCCESS)
  663. return SQL_ERROR;
  664. break;
  665. case SQL_COLUMN_UNSIGNED:
  666. if (pfDesc != NULL) {
  667. if (lpSqlType->unsignedAttribute == -1)
  668. *pfDesc = TRUE;
  669. else
  670. *pfDesc = lpSqlType->unsignedAttribute;
  671. }
  672. break;
  673. case SQL_COLUMN_UPDATABLE:
  674. if (pfDesc != NULL)
  675. *pfDesc = SQL_ATTR_READWRITE_UNKNOWN;
  676. break;
  677. default:
  678. lpstmt->errcode = ERR_NOTSUPPORTED;
  679. return SQL_ERROR;
  680. }
  681. break;
  682. }
  683. return SQL_SUCCESS;
  684. }
  685. /***************************************************************************/
  686. RETCODE SQL_API SQLBindCol(
  687. HSTMT hstmt,
  688. UWORD icol,
  689. SWORD fCType,
  690. PTR rgbValue,
  691. SDWORD cbValueMax,
  692. SDWORD FAR *pcbValue)
  693. {
  694. LPSTMT lpstmt;
  695. LPBOUND lpBound;
  696. LPBOUND lpBoundPrev;
  697. HGLOBAL hBound;
  698. /* Get statement handle */
  699. lpstmt = (LPSTMT) hstmt;
  700. lpstmt->errcode = ERR_SUCCESS;
  701. //To make guarentee Ole is initialized per thread
  702. COleInitializationManager myOleManager;
  703. MyImpersonator im (lpstmt, "SQLBindCol");
  704. /* Find the binding is on the list */
  705. lpBoundPrev = NULL;
  706. lpBound = lpstmt->lpBound;
  707. while (lpBound != NULL) {
  708. if (lpBound->icol == icol)
  709. break;
  710. lpBoundPrev = lpBound;
  711. lpBound = lpBound->lpNext;
  712. }
  713. /* Removing the binding? */
  714. if (rgbValue == NULL) {
  715. /* Yes. Was it on the list? */
  716. if (lpBound != NULL) {
  717. /* Yes. Take it off the list */
  718. if (lpBoundPrev != NULL)
  719. lpBoundPrev->lpNext = lpBound->lpNext;
  720. else
  721. lpstmt->lpBound = lpBound->lpNext;
  722. GlobalUnlock (GlobalPtrHandle(lpBound));
  723. GlobalFree (GlobalPtrHandle(lpBound));
  724. }
  725. }
  726. else {
  727. /* No. Was it on the list? */
  728. if (lpBound == NULL) {
  729. /* No. Make an entry for it */
  730. hBound = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (BOUND));
  731. if (hBound == NULL || (lpBound = (LPBOUND)GlobalLock (hBound)) == NULL) {
  732. if (hBound)
  733. GlobalFree(hBound);
  734. lpstmt->errcode = ERR_MEMALLOCFAIL;
  735. return SQL_ERROR;
  736. }
  737. lpBound->lpNext = lpstmt->lpBound;
  738. lpstmt->lpBound = lpBound;
  739. lpBound->icol = icol;
  740. }
  741. /* Save the bound description */
  742. lpBound->fCType = fCType;
  743. lpBound->rgbValue = rgbValue;
  744. lpBound->cbValueMax = cbValueMax;
  745. lpBound->pcbValue = pcbValue;
  746. }
  747. return SQL_SUCCESS;
  748. }
  749. /***************************************************************************/
  750. RETCODE SQL_API SQLFetch(
  751. HSTMT hstmt)
  752. {
  753. LPSTMT lpstmt;
  754. LPBOUND lpBound;
  755. RETCODE rc;
  756. RETCODE errcode;
  757. LPSQLNODE lpSqlNode;
  758. SWORD err;
  759. UWORD index;
  760. SDWORD count;
  761. HGLOBAL hKeyInfo;
  762. /* Get statement handle */
  763. lpstmt = (LPSTMT) hstmt;
  764. lpstmt->errcode = ERR_SUCCESS;
  765. //To make guarentee Ole is initialized per thread
  766. COleInitializationManager myOleManager;
  767. MyImpersonator im (lpstmt, "SQLFetch");
  768. /* Which table? */
  769. switch (lpstmt->fStmtType) {
  770. case STMT_TYPE_NONE:
  771. lpstmt->errcode = ERR_CURSORSTATE;
  772. return SQL_ERROR;
  773. /* SQLTables() result... */
  774. case STMT_TYPE_TABLES:
  775. {
  776. /* Error if after the last row */
  777. if (lpstmt->irow == AFTER_LAST_ROW)
  778. return SQL_NO_DATA_FOUND;
  779. /* Point at next row */
  780. if (lpstmt->irow == BEFORE_FIRST_ROW)
  781. lpstmt->irow = 0;
  782. else
  783. lpstmt->irow++;
  784. /* Does caller want all the tables or all the table types. */
  785. switch (lpstmt->fStmtSubtype)
  786. {
  787. case STMT_SUBTYPE_TABLES_TABLES:
  788. {
  789. /* All the tables. If no qualifying tables, return EOT */
  790. if (lpstmt->lpISAMTableList == NULL)
  791. {
  792. lpstmt->irow = AFTER_LAST_ROW;
  793. return SQL_NO_DATA_FOUND;
  794. }
  795. //Find out if we should perform next command
  796. //synchronously or asynchronously
  797. UDWORD fSyncMode = SQL_ASYNC_ENABLE_OFF;
  798. SQLGetStmtOption(lpstmt, SQL_ASYNC_ENABLE, &fSyncMode);
  799. /* Get next table name */
  800. err = ISAMGetNextTableName(fSyncMode, lpstmt->lpISAMTableList,
  801. (LPUSTR)lpstmt->szTableName, (LPUSTR)lpstmt->szTableType);
  802. if (err == ISAM_EOF)
  803. {
  804. if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned)
  805. lpstmt->fISAMTxnStarted = TRUE;
  806. lpstmt->irow = AFTER_LAST_ROW;
  807. return SQL_NO_DATA_FOUND;
  808. }
  809. else if (err == ISAM_STILL_EXECUTING)
  810. {
  811. return SQL_STILL_EXECUTING;
  812. }
  813. else if (err != NO_ISAM_ERR)
  814. {
  815. lpstmt->errcode = err;
  816. ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM,
  817. (LPUSTR)lpstmt->szISAMError);
  818. lpstmt->irow = AFTER_LAST_ROW;
  819. return SQL_ERROR;
  820. }
  821. if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned)
  822. lpstmt->fISAMTxnStarted = TRUE;
  823. }
  824. break;
  825. case STMT_SUBTYPE_TABLES_TYPES:
  826. {
  827. (lpstmt->szTableType)[0] = 0;
  828. switch (lpstmt->irow)
  829. {
  830. case 0:
  831. strcpy( (char*)lpstmt->szTableType, "TABLE");
  832. break;
  833. case 1:
  834. strcpy( (char*)lpstmt->szTableType, "SYSTEM TABLE");
  835. break;
  836. default:
  837. {
  838. //EOF
  839. lpstmt->irow = AFTER_LAST_ROW;
  840. return SQL_NO_DATA_FOUND;
  841. }
  842. break;
  843. }
  844. }
  845. break;
  846. case STMT_SUBTYPE_TABLES_QUALIFIERS:
  847. {
  848. if (lpstmt->lpISAMQualifierList == NULL)
  849. {
  850. lpstmt->irow = AFTER_LAST_ROW;
  851. return SQL_NO_DATA_FOUND;
  852. }
  853. //Find out if we should perform next command
  854. //synchronously or asynchronously
  855. UDWORD fSyncMode = SQL_ASYNC_ENABLE_OFF;
  856. SQLGetStmtOption(lpstmt, SQL_ASYNC_ENABLE, &fSyncMode);
  857. /* Get next qualifier name */
  858. err = ISAMGetNextQualifierName(fSyncMode, lpstmt->lpISAMQualifierList,
  859. (LPUSTR)lpstmt->szQualifierName);
  860. if (err == ISAM_EOF)
  861. {
  862. lpstmt->irow = AFTER_LAST_ROW;
  863. return SQL_NO_DATA_FOUND;
  864. }
  865. else if (err == ISAM_STILL_EXECUTING)
  866. {
  867. return SQL_STILL_EXECUTING;
  868. }
  869. else if (err != NO_ISAM_ERR)
  870. {
  871. lpstmt->errcode = err;
  872. ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM,
  873. (LPUSTR)lpstmt->szISAMError);
  874. lpstmt->irow = AFTER_LAST_ROW;
  875. return SQL_ERROR;
  876. }
  877. }
  878. break;
  879. case STMT_SUBTYPE_TABLES_OWNERS:
  880. {
  881. /* The table ownders. Has it been returned yet? */
  882. if (lpstmt->irow != 0)
  883. {
  884. /* Yes. EOT */
  885. lpstmt->irow = AFTER_LAST_ROW;
  886. return SQL_NO_DATA_FOUND;
  887. }
  888. }
  889. break;
  890. }
  891. break;
  892. }
  893. /* SQLColumns() result... */
  894. case STMT_TYPE_COLUMNS:
  895. {
  896. /* Error if after the last row */
  897. if (lpstmt->irow == AFTER_LAST_ROW)
  898. return SQL_NO_DATA_FOUND;
  899. /* If no qualifying tables, EOT */
  900. if (lpstmt->lpISAMTableList == NULL) {
  901. lpstmt->irow = AFTER_LAST_ROW;
  902. return SQL_NO_DATA_FOUND;
  903. }
  904. /* Point at next row */
  905. if (lpstmt->irow == BEFORE_FIRST_ROW)
  906. lpstmt->irow = 0;
  907. else
  908. lpstmt->irow++;
  909. /* Loop until a column is found */
  910. while (TRUE) {
  911. /* If no more columns in the current table... */
  912. //We need to find out the number of columns in table
  913. //Find out if we should perform next command
  914. //synchronously or asynchronously
  915. UDWORD fSyncMode = SQL_ASYNC_ENABLE_OFF;
  916. SQLGetStmtOption(lpstmt, SQL_ASYNC_ENABLE, &fSyncMode);
  917. BOOL fTableDefChange = TRUE;
  918. UWORD cNumberOfColsInCurrentTable = 0;
  919. while ( (lpstmt->lpISAMTableDef == NULL) ||
  920. ( fTableDefChange && (cNumberOfColsInCurrentTable = GetNumberOfColumnsInTable(lpstmt->lpISAMTableDef) ) && (UWORD)lpstmt->irow >= cNumberOfColsInCurrentTable ) ||
  921. ( (UWORD)lpstmt->irow >= cNumberOfColsInCurrentTable)
  922. )
  923. {
  924. /* Go to next table (if any) */
  925. err = ISAMGetNextTableName(fSyncMode, lpstmt->lpISAMTableList,
  926. (LPUSTR)lpstmt->szTableName, (LPUSTR)lpstmt->szTableType);
  927. fTableDefChange = TRUE;
  928. if (err == ISAM_EOF) {
  929. if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned)
  930. lpstmt->fISAMTxnStarted = TRUE;
  931. lpstmt->irow = AFTER_LAST_ROW;
  932. return SQL_NO_DATA_FOUND;
  933. }
  934. else if (err == ISAM_STILL_EXECUTING)
  935. {
  936. return SQL_STILL_EXECUTING;
  937. }
  938. else if (err != NO_ISAM_ERR) {
  939. lpstmt->errcode = err;
  940. ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM,
  941. (LPUSTR)lpstmt->szISAMError);
  942. lpstmt->irow = AFTER_LAST_ROW;
  943. return SQL_ERROR;
  944. }
  945. if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned)
  946. lpstmt->fISAMTxnStarted = TRUE;
  947. /* Get the definition of the table */
  948. if (lpstmt->lpISAMTableDef != NULL) {
  949. ISAMCloseTable(lpstmt->lpISAMTableDef);
  950. lpstmt->lpISAMTableDef = NULL;
  951. }
  952. if (NO_ISAM_ERR != ISAMOpenTable(lpstmt->lpdbc->lpISAM,
  953. (LPUSTR)lpstmt->lpISAMTableList->lpQualifierName,
  954. lpstmt->lpISAMTableList->cbQualifierName,
  955. (LPUSTR)lpstmt->szTableName, TRUE, &(lpstmt->lpISAMTableDef)))
  956. lpstmt->lpISAMTableDef = NULL;
  957. else if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned)
  958. lpstmt->fISAMTxnStarted = TRUE;
  959. /* Get first column of that table */
  960. lpstmt->irow = 0;
  961. }
  962. //Out of While ..loop, so we must have check TABLEDEF at least once
  963. fTableDefChange = FALSE;
  964. /* Does this column name match the pattern supplied? */
  965. //Remember, we may have a DIFFERENT TABLEDEF !!!
  966. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  967. if ( !cInfoBase->IsValid() )
  968. {
  969. lpstmt->irow = AFTER_LAST_ROW;
  970. return SQL_NO_DATA_FOUND;
  971. }
  972. char pColumnName [MAX_COLUMN_NAME_LENGTH+1];
  973. if ( FAILED(cInfoBase->GetColumnName(lpstmt->irow, pColumnName)) )
  974. {
  975. lpstmt->irow = AFTER_LAST_ROW;
  976. return SQL_NO_DATA_FOUND;
  977. }
  978. //Check if this column type is support
  979. //if not we skip this column
  980. if (ISAMGetColumnType(lpstmt->lpISAMTableDef, (UWORD) lpstmt->irow) )
  981. {
  982. //Check that column name matches search pattern
  983. if ( (PatternMatch(TRUE, (LPUSTR)pColumnName, SQL_NTS,
  984. (LPUSTR)lpstmt->szColumnName, SQL_NTS,
  985. ISAMCaseSensitive(lpstmt->lpdbc->lpISAM)) ) )
  986. {
  987. //Ignore any 'lazy' columns
  988. BOOL fIsLazy = FALSE;
  989. cInfoBase->IsLazy(lpstmt->irow, fIsLazy);
  990. //Check if we want to show system properties
  991. if (lpstmt->lpISAMTableDef->lpISAM->fSysProps && !fIsLazy)
  992. {
  993. //We want to show system properties, so continue
  994. /* Yes. Return this column */
  995. break;
  996. }
  997. else
  998. {
  999. //We don't want to show system properties
  1000. if (_strnicmp("__", pColumnName, 2) && !fIsLazy)
  1001. {
  1002. //Not a system property
  1003. /* Yes. Return this column */
  1004. break;
  1005. }
  1006. }
  1007. }
  1008. }
  1009. /* Try the next row */
  1010. lpstmt->irow++;
  1011. }
  1012. }
  1013. break;
  1014. /* SQLStatistics() result... */
  1015. case STMT_TYPE_STATISTICS:
  1016. {
  1017. /* Error if after the last row */
  1018. if (lpstmt->irow == AFTER_LAST_ROW)
  1019. return SQL_NO_DATA_FOUND;
  1020. /* Was a table found? */
  1021. if (lpstmt->lpISAMTableDef == NULL) {
  1022. /* No. EOT */
  1023. lpstmt->irow = AFTER_LAST_ROW;
  1024. return SQL_NO_DATA_FOUND;
  1025. }
  1026. /* Point at next row */
  1027. if (lpstmt->irow == BEFORE_FIRST_ROW)
  1028. lpstmt->irow = 0;
  1029. else
  1030. lpstmt->irow++;
  1031. /* Get number of key columns */
  1032. count = 0;
  1033. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1034. if ( !cInfoBase->IsValid() )
  1035. {
  1036. lpstmt->irow = AFTER_LAST_ROW;
  1037. return SQL_NO_DATA_FOUND;
  1038. }
  1039. UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns();
  1040. BOOL fIsKey = FALSE;
  1041. for (index = 0; index < cNumberOfCols; index++)
  1042. {
  1043. if (SUCCEEDED(cInfoBase->GetKey(index, fIsKey)) && fIsKey)
  1044. count++;
  1045. }
  1046. /* Has the table or key component been returned yet? */
  1047. if (lpstmt->irow > count) {
  1048. /* Yes. EOT */
  1049. lpstmt->irow = AFTER_LAST_ROW;
  1050. return SQL_NO_DATA_FOUND;
  1051. }
  1052. }
  1053. break;
  1054. /* SQLSpecialColumns() result... */
  1055. case STMT_TYPE_SPECIALCOLUMNS:
  1056. {
  1057. /* Error if after the last row */
  1058. if (lpstmt->irow == AFTER_LAST_ROW)
  1059. return SQL_NO_DATA_FOUND;
  1060. /* Was a table found? */
  1061. if (lpstmt->lpISAMTableDef == NULL) {
  1062. /* No. EOT */
  1063. lpstmt->irow = AFTER_LAST_ROW;
  1064. return SQL_NO_DATA_FOUND;
  1065. }
  1066. /* Point at next row */
  1067. if (lpstmt->irow == BEFORE_FIRST_ROW)
  1068. lpstmt->irow = 0;
  1069. else
  1070. lpstmt->irow++;
  1071. /* Get number of key columns */
  1072. count = 0;
  1073. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1074. if ( !cInfoBase->IsValid() )
  1075. {
  1076. lpstmt->irow = AFTER_LAST_ROW;
  1077. return SQL_NO_DATA_FOUND;
  1078. }
  1079. UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns();
  1080. BOOL fIsKey = FALSE;
  1081. for (index = 0; index < cNumberOfCols; index++)
  1082. {
  1083. if (SUCCEEDED(cInfoBase->GetKey(index, fIsKey)) && fIsKey)
  1084. count++;
  1085. }
  1086. /* Has the key component been returned yet? */
  1087. if (lpstmt->irow >= count) {
  1088. /* Yes. EOT */
  1089. lpstmt->irow = AFTER_LAST_ROW;
  1090. return SQL_NO_DATA_FOUND;
  1091. }
  1092. }
  1093. break;
  1094. /* SQLGetTypeInfo() */
  1095. case STMT_TYPE_TYPEINFO:
  1096. {
  1097. /* Error if after the last row */
  1098. if (lpstmt->irow == AFTER_LAST_ROW)
  1099. return SQL_NO_DATA_FOUND;
  1100. /* Find next qualifying type */
  1101. while (TRUE) {
  1102. /* Point at next row */
  1103. if (lpstmt->irow == BEFORE_FIRST_ROW)
  1104. lpstmt->irow = 0;
  1105. else
  1106. lpstmt->irow++;
  1107. /* Error if no more */
  1108. if (lpstmt->irow >= (SDWORD) lpstmt->lpdbc->lpISAM->cSQLTypes) {
  1109. lpstmt->irow = AFTER_LAST_ROW;
  1110. return SQL_NO_DATA_FOUND;
  1111. }
  1112. /* If this one is supported and matches it, use it */
  1113. if (lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].supported &&
  1114. ((lpstmt->fSqlType == SQL_ALL_TYPES) ||
  1115. (lpstmt->fSqlType ==
  1116. lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].type)))
  1117. break;
  1118. }
  1119. }
  1120. break;
  1121. /* SQLPrimaryKeys() */
  1122. case STMT_TYPE_PRIMARYKEYS:
  1123. {
  1124. /* Error if after the last row */
  1125. if (lpstmt->irow == AFTER_LAST_ROW)
  1126. return SQL_NO_DATA_FOUND;
  1127. /* Was a table found? */
  1128. if (lpstmt->lpISAMTableDef == NULL) {
  1129. /* No. EOT */
  1130. lpstmt->irow = AFTER_LAST_ROW;
  1131. return SQL_NO_DATA_FOUND;
  1132. }
  1133. /* Point at next row */
  1134. if (lpstmt->irow == BEFORE_FIRST_ROW)
  1135. lpstmt->irow = 0;
  1136. else
  1137. lpstmt->irow++;
  1138. /* Get number of key columns */
  1139. count = 0;
  1140. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1141. if ( !cInfoBase->IsValid() )
  1142. {
  1143. lpstmt->irow = AFTER_LAST_ROW;
  1144. return SQL_NO_DATA_FOUND;
  1145. }
  1146. UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns();
  1147. BOOL fIsKey = FALSE;
  1148. for (index = 0; index < cNumberOfCols; index++)
  1149. {
  1150. if (SUCCEEDED(cInfoBase->GetKey(index, fIsKey)) && fIsKey)
  1151. count++;
  1152. }
  1153. /* Has the key component been returned yet? */
  1154. if (lpstmt->irow >= count) {
  1155. /* Yes. EOT */
  1156. lpstmt->irow = AFTER_LAST_ROW;
  1157. return SQL_NO_DATA_FOUND;
  1158. }
  1159. }
  1160. break;
  1161. /* SQLForeignKeys() */
  1162. case STMT_TYPE_FOREIGNKEYS:
  1163. {
  1164. /* Error if after the last row */
  1165. if (lpstmt->irow == AFTER_LAST_ROW)
  1166. return SQL_NO_DATA_FOUND;
  1167. /* If before first row, allocate space for key information */
  1168. if (lpstmt->irow == BEFORE_FIRST_ROW) {
  1169. hKeyInfo = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (KEYINFO));
  1170. if (hKeyInfo == NULL || (lpstmt->lpKeyInfo =
  1171. (LPKEYINFO)GlobalLock (hKeyInfo)) == NULL) {
  1172. if (hKeyInfo)
  1173. GlobalFree(hKeyInfo);
  1174. lpstmt->errcode = ERR_MEMALLOCFAIL;
  1175. return SQL_ERROR;
  1176. }
  1177. s_lstrcpy(lpstmt->lpKeyInfo->szPrimaryKeyName, "");
  1178. s_lstrcpy(lpstmt->lpKeyInfo->szForeignKeyName, "");
  1179. lpstmt->lpKeyInfo->iKeyColumns = 0;
  1180. lpstmt->lpKeyInfo->cKeyColumns = 0;
  1181. lpstmt->lpKeyInfo->fForeignKeyUpdateRule = -1;
  1182. lpstmt->lpKeyInfo->fForeignKeyDeleteRule = -1;
  1183. }
  1184. /* If need information for next foreign key, retrieve it */
  1185. while (lpstmt->lpKeyInfo->iKeyColumns ==
  1186. lpstmt->lpKeyInfo->cKeyColumns) {
  1187. switch (lpstmt->fStmtSubtype) {
  1188. case STMT_SUBTYPE_FOREIGNKEYS_SINGLE:
  1189. if (lpstmt->irow != BEFORE_FIRST_ROW) {
  1190. lpstmt->irow = AFTER_LAST_ROW;
  1191. return SQL_NO_DATA_FOUND;
  1192. }
  1193. break;
  1194. case STMT_SUBTYPE_FOREIGNKEYS_MULTIPLE_FK_TABLES:
  1195. {
  1196. if (lpstmt->lpISAMTableList == NULL) {
  1197. lpstmt->irow = AFTER_LAST_ROW;
  1198. return SQL_NO_DATA_FOUND;
  1199. }
  1200. //Find out if we should perform next command
  1201. //synchronously or asynchronously
  1202. UDWORD fSyncMode = SQL_ASYNC_ENABLE_OFF;
  1203. SQLGetStmtOption(lpstmt, SQL_ASYNC_ENABLE, &fSyncMode);
  1204. err = ISAMGetNextTableName(fSyncMode, lpstmt->lpISAMTableList,
  1205. (LPUSTR)lpstmt->szTableName, (LPUSTR)lpstmt->szTableType);
  1206. if (err == ISAM_EOF) {
  1207. if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned)
  1208. lpstmt->fISAMTxnStarted = TRUE;
  1209. lpstmt->irow = AFTER_LAST_ROW;
  1210. return SQL_NO_DATA_FOUND;
  1211. }
  1212. else if (err != NO_ISAM_ERR) {
  1213. lpstmt->errcode = err;
  1214. ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM,
  1215. lpstmt->szISAMError);
  1216. lpstmt->irow = AFTER_LAST_ROW;
  1217. return SQL_ERROR;
  1218. }
  1219. if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned)
  1220. lpstmt->fISAMTxnStarted = TRUE;
  1221. }
  1222. break;
  1223. case STMT_SUBTYPE_FOREIGNKEYS_MULTIPLE_PK_TABLES:
  1224. {
  1225. if (lpstmt->lpISAMTableList == NULL) {
  1226. lpstmt->irow = AFTER_LAST_ROW;
  1227. return SQL_NO_DATA_FOUND;
  1228. }
  1229. //Find out if we should perform next command
  1230. //synchronously or asynchronously
  1231. UDWORD fSyncMode = SQL_ASYNC_ENABLE_OFF;
  1232. SQLGetStmtOption(lpstmt, SQL_ASYNC_ENABLE, &fSyncMode);
  1233. err = ISAMGetNextTableName(fSyncMode, lpstmt->lpISAMTableList,
  1234. lpstmt->szPkTableName, (LPUSTR)lpstmt->szTableType);
  1235. if (err == ISAM_EOF) {
  1236. if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned)
  1237. lpstmt->fISAMTxnStarted = TRUE;
  1238. lpstmt->irow = AFTER_LAST_ROW;
  1239. return SQL_NO_DATA_FOUND;
  1240. }
  1241. else if (err != NO_ISAM_ERR) {
  1242. lpstmt->errcode = err;
  1243. ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM,
  1244. lpstmt->szISAMError);
  1245. lpstmt->irow = AFTER_LAST_ROW;
  1246. return SQL_ERROR;
  1247. }
  1248. if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned)
  1249. lpstmt->fISAMTxnStarted = TRUE;
  1250. /* Get the foriegn key information */
  1251. err = ISAMForeignKey(lpstmt->lpdbc->lpISAM,
  1252. lpstmt->szPkTableName, lpstmt->szTableName,
  1253. lpstmt->lpKeyInfo->szPrimaryKeyName,
  1254. lpstmt->lpKeyInfo->szForeignKeyName,
  1255. &(lpstmt->lpKeyInfo->fForeignKeyUpdateRule),
  1256. &(lpstmt->lpKeyInfo->fForeignKeyDeleteRule),
  1257. &(lpstmt->lpKeyInfo->cKeyColumns),
  1258. lpstmt->lpKeyInfo->PrimaryKeyColumns,
  1259. lpstmt->lpKeyInfo->ForeignKeyColumns);
  1260. if (err == ISAM_EOF) {
  1261. if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned)
  1262. lpstmt->fISAMTxnStarted = TRUE;
  1263. if (lpstmt->fStmtSubtype == STMT_SUBTYPE_FOREIGNKEYS_SINGLE) {
  1264. lpstmt->irow = AFTER_LAST_ROW;
  1265. return SQL_NO_DATA_FOUND;
  1266. }
  1267. lpstmt->lpKeyInfo->cKeyColumns = 0;
  1268. }
  1269. else if (err != NO_ISAM_ERR) {
  1270. lpstmt->errcode = err;
  1271. ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM,
  1272. lpstmt->szISAMError);
  1273. lpstmt->irow = AFTER_LAST_ROW;
  1274. return SQL_ERROR;
  1275. }
  1276. if (lpstmt->lpdbc->lpISAM->fSchemaInfoTransactioned)
  1277. lpstmt->fISAMTxnStarted = TRUE;
  1278. lpstmt->lpKeyInfo->iKeyColumns = 0;
  1279. /* Point at next row of data to return */
  1280. (lpstmt->lpKeyInfo->iKeyColumns)++;
  1281. if (lpstmt->irow == BEFORE_FIRST_ROW)
  1282. lpstmt->irow = 0;
  1283. else
  1284. lpstmt->irow++;
  1285. }
  1286. break;
  1287. }
  1288. }
  1289. }
  1290. break;
  1291. /* SELECT statement... */
  1292. case STMT_TYPE_SELECT:
  1293. /* Get the select statement */
  1294. lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  1295. lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.root.sql);
  1296. /* Error parameters are still needed */
  1297. if ((lpstmt->idxParameter != NO_SQLNODE) || lpstmt->fNeedData) {
  1298. lpstmt->errcode = ERR_CURSORSTATE;
  1299. return SQL_ERROR;
  1300. }
  1301. /* Fetch the next row */
  1302. lpstmt->errcode = FetchRow(lpstmt, lpSqlNode);
  1303. if (lpstmt->errcode == ERR_NODATAFOUND)
  1304. return SQL_NO_DATA_FOUND;
  1305. else if (lpstmt->errcode != ERR_SUCCESS)
  1306. return SQL_ERROR;
  1307. break;
  1308. }
  1309. /* Get the bound columns */
  1310. errcode = ERR_SUCCESS;
  1311. for (lpBound = lpstmt->lpBound; lpBound != NULL; lpBound = lpBound->lpNext) {
  1312. rc = SQLGetData(hstmt, lpBound->icol, lpBound->fCType,
  1313. lpBound->rgbValue, lpBound->cbValueMax, lpBound->pcbValue);
  1314. if (rc == SQL_SUCCESS_WITH_INFO)
  1315. errcode = lpstmt->errcode;
  1316. else if (rc != SQL_SUCCESS)
  1317. return rc;
  1318. }
  1319. /* So far no column read */
  1320. lpstmt->icol = NO_COLUMN;
  1321. lpstmt->cbOffset = 0;
  1322. if (errcode != ERR_SUCCESS) {
  1323. lpstmt->errcode = errcode;
  1324. return SQL_SUCCESS_WITH_INFO;
  1325. }
  1326. return SQL_SUCCESS;
  1327. }
  1328. /***************************************************************************/
  1329. RETCODE SQL_API SQLGetData(
  1330. HSTMT hstmt,
  1331. UWORD icol,
  1332. SWORD fCType,
  1333. PTR rgbValue,
  1334. SDWORD cbValueMax,
  1335. SDWORD FAR *pcbValue)
  1336. {
  1337. LPSTMT lpstmt;
  1338. SWORD sValue;
  1339. UDWORD udValue;
  1340. SWORD fSqlTypeIn;
  1341. PTR rgbValueIn;
  1342. SDWORD cbValueIn;
  1343. LPSQLTYPE lpSqlType;
  1344. LPSQLNODE lpSqlNode;
  1345. LPSQLNODE lpSqlNodeValues;
  1346. SQLNODEIDX idxSqlNodeValues;
  1347. UWORD column;
  1348. SWORD err;
  1349. SDWORD cbValue;
  1350. UWORD index;
  1351. long intval;
  1352. // UWORD i;
  1353. LPSQLNODE lpSqlNodeTable;
  1354. BOOL fReturningDistinct;
  1355. //To make guarentee Ole is initialized per thread
  1356. COleInitializationManager myOleManager;
  1357. // ODBCTRACE(_T("\nWBEM ODBC Driver : ENTERING SQLGetData\n"));
  1358. /* Get statement handle */
  1359. lpstmt = (LPSTMT) hstmt;
  1360. lpstmt->errcode = ERR_SUCCESS;
  1361. MyImpersonator im (lpstmt, "SQLGetData");
  1362. /*
  1363. //SAI REPLACE
  1364. // if ( (icol == 1) && (cbValueMax == 201) )
  1365. {
  1366. char* pTemp = (char*) rgbValue;
  1367. pTemp[0] = 0;
  1368. lstrcpy(pTemp, "This is a long test dummy string to check for memory leaks");
  1369. // lstrcpy(pTemp, "This is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaksThis is a long test dummy string to check for memory leaks");
  1370. *pcbValue = 58;
  1371. // *pcbValue = 580;
  1372. ODBCTRACE("\n***** REACHED HERE *****\n");
  1373. return SQL_SUCCESS;
  1374. }
  1375. */
  1376. /* Which table? */
  1377. switch (lpstmt->fStmtType) {
  1378. case STMT_TYPE_NONE:
  1379. lpstmt->errcode = ERR_CURSORSTATE;
  1380. return SQL_ERROR;
  1381. /* SQLTables() result... */
  1382. case STMT_TYPE_TABLES:
  1383. {
  1384. /* Error if not on a row */
  1385. if ((lpstmt->irow == BEFORE_FIRST_ROW) ||
  1386. (lpstmt->irow == AFTER_LAST_ROW)) {
  1387. lpstmt->errcode = ERR_CURSORSTATE;
  1388. return SQL_ERROR;
  1389. }
  1390. /* Return requested column */
  1391. switch (icol) {
  1392. case TABLE_QUALIFIER:
  1393. switch (lpstmt->fStmtSubtype)
  1394. {
  1395. case STMT_SUBTYPE_TABLES_QUALIFIERS:
  1396. case STMT_SUBTYPE_TABLES_TABLES:
  1397. fSqlTypeIn = SQL_CHAR;
  1398. rgbValueIn = (LPSTR) (lpstmt->szQualifierName);
  1399. cbValueIn = SQL_NTS;
  1400. break;
  1401. default:
  1402. fSqlTypeIn = SQL_CHAR;
  1403. rgbValueIn = NULL;
  1404. cbValueIn = SQL_NULL_DATA;
  1405. break;
  1406. }
  1407. break;
  1408. case TABLE_OWNER:
  1409. fSqlTypeIn = SQL_CHAR;
  1410. rgbValueIn = NULL;
  1411. cbValueIn = SQL_NULL_DATA;
  1412. break;
  1413. case TABLE_NAME:
  1414. /* Return either the table name or 'NULL' if just getting the */
  1415. /* table types */
  1416. switch (lpstmt->fStmtSubtype)
  1417. {
  1418. case STMT_SUBTYPE_TABLES_TABLES:
  1419. fSqlTypeIn = SQL_CHAR;
  1420. rgbValueIn = (LPSTR) (lpstmt->szTableName);
  1421. cbValueIn = SQL_NTS;
  1422. break;
  1423. default:
  1424. fSqlTypeIn = SQL_CHAR;
  1425. rgbValueIn = NULL;
  1426. cbValueIn = SQL_NULL_DATA;
  1427. break;
  1428. }
  1429. break;
  1430. case TABLE_TYPE:
  1431. fSqlTypeIn = SQL_CHAR;
  1432. rgbValueIn = (LPSTR) (lpstmt->szTableType);
  1433. cbValueIn = SQL_NTS;
  1434. break;
  1435. case TABLE_REMARKS:
  1436. fSqlTypeIn = SQL_CHAR;
  1437. rgbValueIn = NULL;
  1438. cbValueIn = SQL_NULL_DATA;
  1439. break;
  1440. case TABLE_ATTRIBUTES:
  1441. {
  1442. fSqlTypeIn = SQL_CHAR;
  1443. SDWORD cbBytesCopied = 0;
  1444. rgbValueIn = NULL;
  1445. cbValueIn = SQL_NULL_DATA;
  1446. /* No. Figure out how long szTableQualifier really is */
  1447. SWORD cbTableQualifier = (SWORD) TrueSize((LPUSTR)lpstmt->szQualifierName, SQL_NTS,
  1448. MAX_QUALIFIER_NAME_LENGTH);
  1449. LPSTR szConstqualifier = (LPSTR)lpstmt->szQualifierName;
  1450. //If no table qualifier is specified then use the 'current' database
  1451. if (!cbTableQualifier)
  1452. {
  1453. szConstqualifier = (char*) lpstmt->lpdbc->lpISAM->szDatabase;
  1454. cbTableQualifier = (SWORD) TrueSize((LPUSTR)szConstqualifier, SQL_NTS,
  1455. MAX_QUALIFIER_NAME_LENGTH);
  1456. }
  1457. if ( ISAMOpenTable(lpstmt->lpdbc->lpISAM, (LPUSTR)szConstqualifier, cbTableQualifier,
  1458. (LPUSTR) lpstmt->szTableName,
  1459. TRUE, &(lpstmt->lpISAMTableDef) ) == NO_ISAM_ERR)
  1460. {
  1461. ISAMGetTableAttr(lpstmt->lpISAMTableDef, (char*) rgbValue, cbValueMax, cbBytesCopied);
  1462. rgbValueIn = (char*) rgbValue;
  1463. cbValueIn = cbBytesCopied;
  1464. ISAMCloseTable(lpstmt->lpISAMTableDef);
  1465. lpstmt->lpISAMTableDef = NULL;
  1466. }
  1467. }
  1468. break;
  1469. default:
  1470. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  1471. return SQL_ERROR;
  1472. }
  1473. /* Reset offset if first read of this column */
  1474. if (lpstmt->icol != icol) {
  1475. lpstmt->icol = icol;
  1476. lpstmt->cbOffset = 0;
  1477. }
  1478. /* Convert the results to the requested type */
  1479. lpstmt->errcode = ConvertSqlToC(fSqlTypeIn,
  1480. GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn,
  1481. cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax,
  1482. pcbValue);
  1483. if (lpstmt->errcode == ERR_DATATRUNCATED)
  1484. return SQL_SUCCESS_WITH_INFO;
  1485. else if (lpstmt->errcode != ERR_SUCCESS)
  1486. return SQL_ERROR;
  1487. break;
  1488. }
  1489. /* SQLColumns()... */
  1490. case STMT_TYPE_COLUMNS:
  1491. {
  1492. /* Error if not on a row */
  1493. if ((lpstmt->irow == BEFORE_FIRST_ROW) ||
  1494. (lpstmt->irow == AFTER_LAST_ROW)) {
  1495. lpstmt->errcode = ERR_CURSORSTATE;
  1496. return SQL_ERROR;
  1497. }
  1498. /* Get pointer to definition of the type of the column */
  1499. lpSqlType = ISAMGetColumnType(lpstmt->lpISAMTableDef,
  1500. (UWORD) lpstmt->irow);
  1501. if (lpSqlType == NULL) {
  1502. lpstmt->errcode = ERR_ISAM;
  1503. return SQL_ERROR;
  1504. }
  1505. char szcolName [MAX_COLUMN_NAME_LENGTH + 1];
  1506. /* Return the requested column */
  1507. switch (icol) {
  1508. case COLUMN_QUALIFIER:
  1509. fSqlTypeIn = SQL_CHAR;
  1510. rgbValueIn = NULL;
  1511. cbValueIn = SQL_NULL_DATA;
  1512. break;
  1513. case COLUMN_OWNER:
  1514. fSqlTypeIn = SQL_CHAR;
  1515. rgbValueIn = NULL;
  1516. cbValueIn = SQL_NULL_DATA;
  1517. break;
  1518. case COLUMN_TABLE:
  1519. fSqlTypeIn = SQL_CHAR;
  1520. rgbValueIn = (LPSTR) (lpstmt->szTableName);
  1521. cbValueIn = SQL_NTS;
  1522. break;
  1523. case COLUMN_NAME:
  1524. {
  1525. fSqlTypeIn = SQL_CHAR;
  1526. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1527. if ( !cInfoBase->IsValid() )
  1528. {
  1529. return SQL_ERROR;
  1530. }
  1531. rgbValueIn = szcolName;
  1532. if ( FAILED(cInfoBase->GetColumnName(lpstmt->irow, (char*)rgbValueIn)) )
  1533. {
  1534. return SQL_ERROR;
  1535. }
  1536. cbValueIn = SQL_NTS;
  1537. }
  1538. break;
  1539. case COLUMN_TYPE:
  1540. fSqlTypeIn = SQL_SMALLINT;
  1541. rgbValueIn = &(lpSqlType->type);
  1542. cbValueIn = 2;
  1543. break;
  1544. case COLUMN_TYPENAME:
  1545. fSqlTypeIn = SQL_CHAR;
  1546. rgbValueIn = lpSqlType->name;
  1547. cbValueIn = SQL_NTS;
  1548. break;
  1549. case COLUMN_PRECISION:
  1550. fSqlTypeIn = SQL_INTEGER;
  1551. switch (lpSqlType->type) {
  1552. case SQL_DECIMAL:
  1553. case SQL_NUMERIC:
  1554. case SQL_BIGINT:
  1555. case SQL_CHAR:
  1556. case SQL_VARCHAR:
  1557. case SQL_LONGVARCHAR:
  1558. case SQL_BINARY:
  1559. case SQL_VARBINARY:
  1560. case SQL_LONGVARBINARY:
  1561. case SQL_DOUBLE:
  1562. {
  1563. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1564. if ( !cInfoBase->IsValid() )
  1565. {
  1566. return SQL_ERROR;
  1567. }
  1568. if ( !cInfoBase->GetPrecision(lpstmt->irow, udValue) )
  1569. {
  1570. return SQL_ERROR;
  1571. }
  1572. }
  1573. break;
  1574. case SQL_TINYINT:
  1575. udValue = 3;
  1576. break;
  1577. case SQL_SMALLINT:
  1578. udValue = 5;
  1579. break;
  1580. case SQL_INTEGER:
  1581. udValue = 10;
  1582. break;
  1583. case SQL_REAL:
  1584. udValue = 7;
  1585. break;
  1586. case SQL_FLOAT:
  1587. // case SQL_DOUBLE:
  1588. udValue = 15;
  1589. break;
  1590. case SQL_BIT:
  1591. udValue = 1;
  1592. break;
  1593. case SQL_DATE:
  1594. udValue = 10;
  1595. break;
  1596. case SQL_TIME:
  1597. udValue = 8;
  1598. break;
  1599. case SQL_TIMESTAMP:
  1600. if (TIMESTAMP_SCALE > 0)
  1601. udValue = 20 + TIMESTAMP_SCALE;
  1602. else
  1603. udValue = 19;
  1604. break;
  1605. default:
  1606. udValue = 0;
  1607. break;
  1608. }
  1609. rgbValueIn = &udValue;
  1610. cbValueIn = 4;
  1611. break;
  1612. case COLUMN_LENGTH:
  1613. fSqlTypeIn = SQL_INTEGER;
  1614. switch (lpSqlType->type) {
  1615. case SQL_DECIMAL:
  1616. case SQL_NUMERIC:
  1617. {
  1618. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1619. if ( !cInfoBase->IsValid() )
  1620. {
  1621. return SQL_ERROR;
  1622. }
  1623. if ( !cInfoBase->GetPrecision(lpstmt->irow, udValue) )
  1624. {
  1625. return SQL_ERROR;
  1626. }
  1627. udValue = udValue + 2;
  1628. }
  1629. break;
  1630. case SQL_CHAR:
  1631. case SQL_VARCHAR:
  1632. case SQL_LONGVARCHAR:
  1633. case SQL_BINARY:
  1634. case SQL_VARBINARY:
  1635. case SQL_LONGVARBINARY:
  1636. {
  1637. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1638. if ( !cInfoBase->IsValid() )
  1639. {
  1640. return SQL_ERROR;
  1641. }
  1642. if ( !cInfoBase->GetPrecision(lpstmt->irow, udValue) )
  1643. {
  1644. return SQL_ERROR;
  1645. }
  1646. }
  1647. break;
  1648. case SQL_TINYINT:
  1649. udValue = 1;
  1650. break;
  1651. case SQL_SMALLINT:
  1652. udValue = 2;
  1653. break;
  1654. case SQL_INTEGER:
  1655. udValue = 4;
  1656. break;
  1657. case SQL_BIGINT:
  1658. {
  1659. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1660. if ( !cInfoBase->IsValid() )
  1661. {
  1662. return SQL_ERROR;
  1663. }
  1664. if ( !cInfoBase->GetPrecision(lpstmt->irow, udValue) )
  1665. {
  1666. return SQL_ERROR;
  1667. }
  1668. if ( ! lpSqlType->unsignedAttribute)
  1669. udValue = udValue + 1;
  1670. }
  1671. break;
  1672. case SQL_REAL:
  1673. udValue = 4;
  1674. break;
  1675. case SQL_FLOAT:
  1676. case SQL_DOUBLE:
  1677. udValue = 8;
  1678. break;
  1679. case SQL_BIT:
  1680. udValue = 1;
  1681. break;
  1682. case SQL_DATE:
  1683. udValue = 6;
  1684. break;
  1685. case SQL_TIME:
  1686. udValue = 6;
  1687. break;
  1688. case SQL_TIMESTAMP:
  1689. udValue = 16;
  1690. break;
  1691. default:
  1692. udValue = 0;
  1693. break;
  1694. }
  1695. rgbValueIn = &udValue;
  1696. cbValueIn = 4;
  1697. break;
  1698. case COLUMN_SCALE:
  1699. {
  1700. fSqlTypeIn = SQL_SMALLINT;
  1701. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1702. if ( !cInfoBase->IsValid() )
  1703. {
  1704. return SQL_ERROR;
  1705. }
  1706. SWORD wScaleVal = 0;
  1707. if ( !cInfoBase->GetScale(lpstmt->irow, wScaleVal) )
  1708. {
  1709. return SQL_ERROR;
  1710. }
  1711. else
  1712. {
  1713. udValue = wScaleVal;
  1714. }
  1715. rgbValueIn = &udValue;
  1716. cbValueIn = 2;
  1717. }
  1718. break;
  1719. case COLUMN_RADIX:
  1720. fSqlTypeIn = SQL_SMALLINT;
  1721. switch (lpSqlType->type) {
  1722. case SQL_DECIMAL:
  1723. case SQL_NUMERIC:
  1724. case SQL_TINYINT:
  1725. case SQL_SMALLINT:
  1726. case SQL_INTEGER:
  1727. case SQL_BIGINT:
  1728. case SQL_REAL:
  1729. case SQL_FLOAT:
  1730. case SQL_DOUBLE:
  1731. sValue = 10;
  1732. rgbValueIn = &sValue;
  1733. cbValueIn = 2;
  1734. break;
  1735. case SQL_CHAR:
  1736. case SQL_VARCHAR:
  1737. case SQL_LONGVARCHAR:
  1738. case SQL_BIT:
  1739. case SQL_BINARY:
  1740. case SQL_VARBINARY:
  1741. case SQL_LONGVARBINARY:
  1742. case SQL_DATE:
  1743. case SQL_TIME:
  1744. case SQL_TIMESTAMP:
  1745. default:
  1746. rgbValueIn = NULL;
  1747. cbValueIn = SQL_NULL_DATA;
  1748. break;
  1749. }
  1750. break;
  1751. case COLUMN_NULLABLE:
  1752. {
  1753. fSqlTypeIn = SQL_SMALLINT;
  1754. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1755. if ( !cInfoBase->IsValid() )
  1756. {
  1757. return SQL_ERROR;
  1758. }
  1759. if ( !cInfoBase->IsNullable(lpstmt->irow, sValue) )
  1760. {
  1761. return SQL_ERROR;
  1762. }
  1763. rgbValueIn = &sValue;
  1764. cbValueIn = 2;
  1765. }
  1766. break;
  1767. case COLUMN_REMARKS:
  1768. fSqlTypeIn = SQL_CHAR;
  1769. rgbValueIn = NULL;
  1770. cbValueIn = SQL_NULL_DATA;
  1771. break;
  1772. case COLUMN_ATTRIBUTES:
  1773. {
  1774. rgbValueIn = NULL;
  1775. cbValueIn = SQL_NULL_DATA;
  1776. fSqlTypeIn = SQL_CHAR;
  1777. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1778. if ( !cInfoBase->IsValid() )
  1779. {
  1780. return SQL_ERROR;
  1781. }
  1782. if ( FAILED(cInfoBase->GetColumnAttr(lpstmt->irow, (char*)rgbValue, cbValueMax, cbValueIn)) )
  1783. {
  1784. return SQL_ERROR;
  1785. }
  1786. rgbValueIn = rgbValue;
  1787. }
  1788. break;
  1789. default:
  1790. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  1791. return SQL_ERROR;
  1792. }
  1793. /* Reset offset if first read of this column */
  1794. if (lpstmt->icol != icol) {
  1795. lpstmt->icol = icol;
  1796. lpstmt->cbOffset = 0;
  1797. }
  1798. /* Convert the results to the requested type */
  1799. lpstmt->errcode = ConvertSqlToC(fSqlTypeIn,
  1800. GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn,
  1801. cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax,
  1802. pcbValue);
  1803. if (lpstmt->errcode == ERR_DATATRUNCATED)
  1804. return SQL_SUCCESS_WITH_INFO;
  1805. else if (lpstmt->errcode != ERR_SUCCESS)
  1806. return SQL_ERROR;
  1807. break;
  1808. }
  1809. /* SQLStatistics()... */
  1810. case STMT_TYPE_STATISTICS:
  1811. {
  1812. /* Error if not on a row */
  1813. if ((lpstmt->irow == BEFORE_FIRST_ROW) ||
  1814. (lpstmt->irow == AFTER_LAST_ROW)) {
  1815. lpstmt->errcode = ERR_CURSORSTATE;
  1816. return SQL_ERROR;
  1817. }
  1818. /* Return the requested column */
  1819. switch (icol) {
  1820. case STATISTIC_QUALIFIER:
  1821. fSqlTypeIn = SQL_CHAR;
  1822. rgbValueIn = (LPSTR) (lpstmt->szQualifierName);
  1823. cbValueIn = SQL_NTS;
  1824. break;
  1825. case STATISTIC_OWNER:
  1826. fSqlTypeIn = SQL_CHAR;
  1827. rgbValueIn = (LPSTR) "";
  1828. cbValueIn = SQL_NTS;
  1829. break;
  1830. case STATISTIC_NAME:
  1831. fSqlTypeIn = SQL_CHAR;
  1832. rgbValueIn = (LPSTR) (lpstmt->lpISAMTableDef->szTableName);
  1833. cbValueIn = SQL_NTS;
  1834. break;
  1835. case STATISTIC_NONUNIQUE:
  1836. if (lpstmt->irow == 0) {
  1837. fSqlTypeIn = SQL_SMALLINT;
  1838. rgbValueIn = NULL;
  1839. cbValueIn = SQL_NULL_DATA;
  1840. }
  1841. else {
  1842. fSqlTypeIn = SQL_SMALLINT;
  1843. sValue = FALSE;
  1844. rgbValueIn = &sValue;
  1845. cbValueIn = 2;
  1846. }
  1847. break;
  1848. case STATISTIC_INDEXQUALIFIER:
  1849. fSqlTypeIn = SQL_CHAR;
  1850. rgbValueIn = NULL;
  1851. cbValueIn = SQL_NULL_DATA;
  1852. break;
  1853. case STATISTIC_INDEXNAME:
  1854. if (lpstmt->irow == 0) {
  1855. fSqlTypeIn = SQL_CHAR;
  1856. rgbValueIn = NULL;
  1857. cbValueIn = SQL_NULL_DATA;
  1858. }
  1859. else {
  1860. fSqlTypeIn = SQL_CHAR;
  1861. rgbValueIn = (LPSTR) "KEY";
  1862. cbValueIn = SQL_NTS;
  1863. }
  1864. break;
  1865. case STATISTIC_TYPE:
  1866. if (lpstmt->irow == 0) {
  1867. fSqlTypeIn = SQL_SMALLINT;
  1868. sValue = SQL_TABLE_STAT;
  1869. rgbValueIn = &sValue;
  1870. cbValueIn = 2;
  1871. }
  1872. else {
  1873. fSqlTypeIn = SQL_SMALLINT;
  1874. sValue = SQL_INDEX_OTHER;
  1875. rgbValueIn = &sValue;
  1876. cbValueIn = 2;
  1877. }
  1878. break;
  1879. case STATISTIC_SEQININDEX:
  1880. if (lpstmt->irow == 0) {
  1881. fSqlTypeIn = SQL_SMALLINT;
  1882. rgbValueIn = NULL;
  1883. cbValueIn = SQL_NULL_DATA;
  1884. }
  1885. else {
  1886. fSqlTypeIn = SQL_SMALLINT;
  1887. sValue = (SWORD) lpstmt->irow;
  1888. rgbValueIn = &sValue;
  1889. cbValueIn = 2;
  1890. }
  1891. break;
  1892. case STATISTIC_COLUMNNAME:
  1893. if (lpstmt->irow == 0) {
  1894. fSqlTypeIn = SQL_CHAR;
  1895. rgbValueIn = NULL;
  1896. cbValueIn = SQL_NULL_DATA;
  1897. }
  1898. else {
  1899. /* Find the description of the column. For each column... */
  1900. rgbValueIn = NULL;
  1901. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1902. if ( !cInfoBase->IsValid() )
  1903. {
  1904. return SQL_ERROR;
  1905. }
  1906. UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns();
  1907. char pColumnName [MAX_COLUMN_NAME_LENGTH+1];
  1908. BOOL fIsKey = FALSE;
  1909. for (index = 0;index < cNumberOfCols;index++)
  1910. {
  1911. if ( FAILED(cInfoBase->GetColumnName(index, pColumnName)) )
  1912. {
  1913. return SQL_ERROR;
  1914. }
  1915. /* Is this column a component of the key? */
  1916. cInfoBase->GetKey(index, fIsKey);
  1917. if (fIsKey)
  1918. {
  1919. /* Yes. Is this the component we want? */
  1920. /* Yes. Save pointer to column name */
  1921. fSqlTypeIn = SQL_CHAR;
  1922. ((char*)rgbValue)[0] = 0;
  1923. lstrcpy ((char*)rgbValue, pColumnName);
  1924. rgbValueIn = (char*)rgbValue;
  1925. cbValueIn = SQL_NTS;
  1926. break;
  1927. }
  1928. }
  1929. if (rgbValueIn == NULL) {
  1930. lpstmt->errcode = ERR_ISAM;
  1931. return SQL_ERROR;
  1932. }
  1933. }
  1934. break;
  1935. case STATISTIC_COLLATION:
  1936. fSqlTypeIn = SQL_CHAR;
  1937. rgbValueIn = NULL;
  1938. cbValueIn = SQL_NULL_DATA;
  1939. break;
  1940. case STATISTIC_CARDINALITY:
  1941. fSqlTypeIn = SQL_INTEGER;
  1942. rgbValueIn = NULL;
  1943. cbValueIn = SQL_NULL_DATA;
  1944. break;
  1945. case STATISTIC_PAGES:
  1946. fSqlTypeIn = SQL_INTEGER;
  1947. rgbValueIn = NULL;
  1948. cbValueIn = SQL_NULL_DATA;
  1949. break;
  1950. case STATISTIC_FILTERCONDITION:
  1951. fSqlTypeIn = SQL_CHAR;
  1952. rgbValueIn = NULL;
  1953. cbValueIn = SQL_NULL_DATA;
  1954. break;
  1955. default:
  1956. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  1957. return SQL_ERROR;
  1958. }
  1959. /* Reset offset if first read of this column */
  1960. if (lpstmt->icol != icol) {
  1961. lpstmt->icol = icol;
  1962. lpstmt->cbOffset = 0;
  1963. }
  1964. /* Convert the results to the requested type */
  1965. lpstmt->errcode = ConvertSqlToC(fSqlTypeIn,
  1966. GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn,
  1967. cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax,
  1968. pcbValue);
  1969. if (lpstmt->errcode == ERR_DATATRUNCATED)
  1970. return SQL_SUCCESS_WITH_INFO;
  1971. else if (lpstmt->errcode != ERR_SUCCESS)
  1972. return SQL_ERROR;
  1973. }
  1974. break;
  1975. /* SQLSpecialColumns()... */
  1976. case STMT_TYPE_SPECIALCOLUMNS:
  1977. {
  1978. /* Error if not on a row */
  1979. if ((lpstmt->irow == BEFORE_FIRST_ROW) ||
  1980. (lpstmt->irow == AFTER_LAST_ROW)) {
  1981. lpstmt->errcode = ERR_CURSORSTATE;
  1982. return SQL_ERROR;
  1983. }
  1984. /* Find the description of the column. For each column... */
  1985. lpstmt->errcode = ERR_ISAM;
  1986. ClassColumnInfoBase* cInfoBase = lpstmt->lpISAMTableDef->pColumnInfo;
  1987. if ( !cInfoBase->IsValid() )
  1988. {
  1989. return SQL_ERROR;
  1990. }
  1991. UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns();
  1992. char pColumnName [MAX_COLUMN_NAME_LENGTH+1];
  1993. BOOL fIsKey = FALSE;
  1994. for (index = 0; index < cNumberOfCols; index++)
  1995. {
  1996. if ( FAILED(cInfoBase->GetColumnName(index, pColumnName)) )
  1997. {
  1998. lpstmt->errcode = ERR_ISAM;
  1999. return SQL_ERROR;
  2000. }
  2001. /* Is this column a component of the key? */
  2002. cInfoBase->GetKey(index, fIsKey);
  2003. if (fIsKey)
  2004. {
  2005. /* Yes. Save index to column */
  2006. lpstmt->errcode = ERR_SUCCESS;
  2007. break;
  2008. }
  2009. }
  2010. if (lpstmt->errcode == ERR_ISAM)
  2011. return SQL_ERROR;
  2012. /* Get pointer to definition of the type of the column */
  2013. if ( (!cInfoBase->GetDataTypeInfo(index, lpSqlType)) || (lpSqlType == NULL) )
  2014. {
  2015. lpstmt->errcode = ERR_ISAM;
  2016. return SQL_ERROR;
  2017. }
  2018. /* Return the requested column */
  2019. switch (icol) {
  2020. case SPECIALCOLUMN_SCOPE:
  2021. fSqlTypeIn = SQL_SMALLINT;
  2022. sValue = SQL_SCOPE_SESSION;
  2023. rgbValueIn = &sValue;
  2024. cbValueIn = 2;
  2025. break;
  2026. case SPECIALCOLUMN_NAME:
  2027. fSqlTypeIn = SQL_CHAR;
  2028. ((char*)rgbValue)[0] = 0;
  2029. lstrcpy((char*)rgbValue, pColumnName);
  2030. rgbValueIn = (char*)rgbValue;
  2031. cbValueIn = SQL_NTS;
  2032. break;
  2033. case SPECIALCOLUMN_TYPE:
  2034. fSqlTypeIn = SQL_SMALLINT;
  2035. rgbValueIn = &(lpSqlType->type);
  2036. cbValueIn = 2;
  2037. break;
  2038. case SPECIALCOLUMN_TYPENAME:
  2039. fSqlTypeIn = SQL_CHAR;
  2040. rgbValueIn = lpSqlType->name;
  2041. cbValueIn = SQL_NTS;
  2042. break;
  2043. case SPECIALCOLUMN_PRECISION:
  2044. fSqlTypeIn = SQL_INTEGER;
  2045. switch (lpSqlType->type) {
  2046. case SQL_DECIMAL:
  2047. case SQL_NUMERIC:
  2048. case SQL_BIGINT:
  2049. case SQL_CHAR:
  2050. case SQL_VARCHAR:
  2051. case SQL_LONGVARCHAR:
  2052. case SQL_BINARY:
  2053. case SQL_VARBINARY:
  2054. case SQL_LONGVARBINARY:
  2055. cInfoBase->GetPrecision(index, udValue);
  2056. break;
  2057. case SQL_TINYINT:
  2058. udValue = 3;
  2059. break;
  2060. case SQL_SMALLINT:
  2061. udValue = 5;
  2062. break;
  2063. case SQL_INTEGER:
  2064. udValue = 10;
  2065. break;
  2066. case SQL_REAL:
  2067. udValue = 7;
  2068. break;
  2069. case SQL_FLOAT:
  2070. case SQL_DOUBLE:
  2071. udValue = 15;
  2072. break;
  2073. case SQL_BIT:
  2074. udValue = 1;
  2075. break;
  2076. case SQL_DATE:
  2077. udValue = 10;
  2078. break;
  2079. case SQL_TIME:
  2080. udValue = 8;
  2081. break;
  2082. case SQL_TIMESTAMP:
  2083. if (TIMESTAMP_SCALE > 0)
  2084. udValue = 20 + TIMESTAMP_SCALE;
  2085. else
  2086. udValue = 19;
  2087. break;
  2088. default:
  2089. udValue = 0;
  2090. break;
  2091. }
  2092. rgbValueIn = &udValue;
  2093. cbValueIn = 4;
  2094. break;
  2095. case SPECIALCOLUMN_LENGTH:
  2096. fSqlTypeIn = SQL_INTEGER;
  2097. switch (lpSqlType->type) {
  2098. case SQL_DECIMAL:
  2099. case SQL_NUMERIC:
  2100. {
  2101. cInfoBase->GetPrecision(index, udValue);
  2102. udValue = udValue + 2;
  2103. }
  2104. break;
  2105. case SQL_CHAR:
  2106. case SQL_VARCHAR:
  2107. case SQL_LONGVARCHAR:
  2108. case SQL_BINARY:
  2109. case SQL_VARBINARY:
  2110. case SQL_LONGVARBINARY:
  2111. cInfoBase->GetPrecision(index, udValue);
  2112. break;
  2113. case SQL_TINYINT:
  2114. udValue = 1;
  2115. break;
  2116. case SQL_SMALLINT:
  2117. udValue = 2;
  2118. break;
  2119. case SQL_INTEGER:
  2120. udValue = 4;
  2121. break;
  2122. case SQL_BIGINT:
  2123. {
  2124. cInfoBase->GetPrecision(index, udValue);
  2125. if ( !lpSqlType->unsignedAttribute )
  2126. udValue = udValue + 1;
  2127. }
  2128. break;
  2129. case SQL_REAL:
  2130. udValue = 4;
  2131. break;
  2132. case SQL_FLOAT:
  2133. case SQL_DOUBLE:
  2134. udValue = 8;
  2135. break;
  2136. case SQL_BIT:
  2137. udValue = 1;
  2138. break;
  2139. case SQL_DATE:
  2140. udValue = 6;
  2141. break;
  2142. case SQL_TIME:
  2143. udValue = 6;
  2144. break;
  2145. case SQL_TIMESTAMP:
  2146. udValue = 16;
  2147. break;
  2148. default:
  2149. udValue = 0;
  2150. break;
  2151. }
  2152. rgbValueIn = &udValue;
  2153. cbValueIn = 4;
  2154. break;
  2155. case SPECIALCOLUMN_SCALE:
  2156. {
  2157. fSqlTypeIn = SQL_SMALLINT;
  2158. cInfoBase->GetScale(index, sValue);
  2159. rgbValueIn = &sValue;
  2160. cbValueIn = 2;
  2161. }
  2162. break;
  2163. case SPECIALCOLUMN_PSEUDOCOLUMN:
  2164. fSqlTypeIn = SQL_SMALLINT;
  2165. sValue = SQL_PC_UNKNOWN;
  2166. rgbValueIn = &sValue;
  2167. cbValueIn = 2;
  2168. break;
  2169. default:
  2170. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  2171. return SQL_ERROR;
  2172. }
  2173. /* Reset offset if first read of this column */
  2174. if (lpstmt->icol != icol) {
  2175. lpstmt->icol = icol;
  2176. lpstmt->cbOffset = 0;
  2177. }
  2178. /* Convert the results to the requested type */
  2179. lpstmt->errcode = ConvertSqlToC(fSqlTypeIn,
  2180. GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn,
  2181. cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax,
  2182. pcbValue);
  2183. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2184. return SQL_SUCCESS_WITH_INFO;
  2185. else if (lpstmt->errcode != ERR_SUCCESS)
  2186. return SQL_ERROR;
  2187. break;
  2188. }
  2189. /* SQLGetTypeInfo()... */
  2190. case STMT_TYPE_TYPEINFO:
  2191. /* Error if not on a row */
  2192. if ((lpstmt->irow == BEFORE_FIRST_ROW) ||
  2193. (lpstmt->irow == AFTER_LAST_ROW)) {
  2194. lpstmt->errcode = ERR_CURSORSTATE;
  2195. return SQL_ERROR;
  2196. }
  2197. /* Return the requested column */
  2198. switch (icol) {
  2199. case TYPEINFO_NAME:
  2200. fSqlTypeIn = SQL_CHAR;
  2201. rgbValueIn = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].name;
  2202. cbValueIn = SQL_NTS;
  2203. break;
  2204. case TYPEINFO_TYPE:
  2205. fSqlTypeIn = SQL_SMALLINT;
  2206. sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].type;
  2207. rgbValueIn = &sValue;
  2208. cbValueIn = 2;
  2209. break;
  2210. case TYPEINFO_PRECISION:
  2211. fSqlTypeIn = SQL_INTEGER;
  2212. udValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].precision;
  2213. rgbValueIn = &udValue;
  2214. cbValueIn = 4;
  2215. break;
  2216. case TYPEINFO_PREFIX:
  2217. fSqlTypeIn = SQL_CHAR;
  2218. rgbValueIn = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].prefix;
  2219. if (rgbValueIn != NULL)
  2220. cbValueIn = SQL_NTS;
  2221. else
  2222. cbValueIn = SQL_NULL_DATA;
  2223. break;
  2224. case TYPEINFO_SUFFIX:
  2225. fSqlTypeIn = SQL_CHAR;
  2226. rgbValueIn = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].suffix;
  2227. if (rgbValueIn != NULL)
  2228. cbValueIn = SQL_NTS;
  2229. else
  2230. cbValueIn = SQL_NULL_DATA;
  2231. break;
  2232. case TYPEINFO_PARAMS:
  2233. fSqlTypeIn = SQL_CHAR;
  2234. rgbValueIn = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].params;
  2235. if (rgbValueIn != NULL)
  2236. cbValueIn = SQL_NTS;
  2237. else
  2238. cbValueIn = SQL_NULL_DATA;
  2239. break;
  2240. case TYPEINFO_NULLABLE:
  2241. fSqlTypeIn = SQL_SMALLINT;
  2242. sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].nullable;
  2243. rgbValueIn = &sValue;
  2244. cbValueIn = 2;
  2245. break;
  2246. case TYPEINFO_CASESENSITIVE:
  2247. fSqlTypeIn = SQL_SMALLINT;
  2248. sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].caseSensitive;
  2249. rgbValueIn = &sValue;
  2250. cbValueIn = 2;
  2251. break;
  2252. case TYPEINFO_SEARCHABLE:
  2253. fSqlTypeIn = SQL_SMALLINT;
  2254. sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].searchable;
  2255. rgbValueIn = &sValue;
  2256. cbValueIn = 2;
  2257. break;
  2258. case TYPEINFO_UNSIGNED:
  2259. fSqlTypeIn = SQL_SMALLINT;
  2260. sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].unsignedAttribute;
  2261. rgbValueIn = &sValue;
  2262. if (sValue != -1)
  2263. cbValueIn = 2;
  2264. else
  2265. cbValueIn = SQL_NULL_DATA;
  2266. break;
  2267. case TYPEINFO_MONEY:
  2268. fSqlTypeIn = SQL_SMALLINT;
  2269. sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].money;
  2270. rgbValueIn = &sValue;
  2271. cbValueIn = 2;
  2272. break;
  2273. case TYPEINFO_AUTOINCREMENT:
  2274. fSqlTypeIn = SQL_SMALLINT;
  2275. sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].autoincrement;
  2276. rgbValueIn = &sValue;
  2277. if (sValue != -1)
  2278. cbValueIn = 2;
  2279. else
  2280. cbValueIn = SQL_NULL_DATA;
  2281. break;
  2282. case TYPEINFO_LOCALNAME:
  2283. fSqlTypeIn = SQL_CHAR;
  2284. rgbValueIn = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].localName;
  2285. if (rgbValueIn != NULL)
  2286. cbValueIn = SQL_NTS;
  2287. else
  2288. cbValueIn = SQL_NULL_DATA;
  2289. break;
  2290. case TYPEINFO_MINSCALE:
  2291. fSqlTypeIn = SQL_SMALLINT;
  2292. sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].minscale;
  2293. rgbValueIn = &sValue;
  2294. if (sValue != -1)
  2295. cbValueIn = 2;
  2296. else
  2297. cbValueIn = SQL_NULL_DATA;
  2298. break;
  2299. case TYPEINFO_MAXSCALE:
  2300. fSqlTypeIn = SQL_SMALLINT;
  2301. sValue = lpstmt->lpdbc->lpISAM->SQLTypes[lpstmt->irow].maxscale;
  2302. rgbValueIn = &sValue;
  2303. if (sValue != -1)
  2304. cbValueIn = 2;
  2305. else
  2306. cbValueIn = SQL_NULL_DATA;
  2307. break;
  2308. default:
  2309. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  2310. return SQL_ERROR;
  2311. }
  2312. /* Reset offset if first read of this column */
  2313. if (lpstmt->icol != icol) {
  2314. lpstmt->icol = icol;
  2315. lpstmt->cbOffset = 0;
  2316. }
  2317. /* Convert the results to the requested type */
  2318. lpstmt->errcode = ConvertSqlToC(fSqlTypeIn,
  2319. GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn,
  2320. cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax,
  2321. pcbValue);
  2322. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2323. return SQL_SUCCESS_WITH_INFO;
  2324. else if (lpstmt->errcode != ERR_SUCCESS)
  2325. return SQL_ERROR;
  2326. break;
  2327. /* SQLPrimaryKeys()... */
  2328. case STMT_TYPE_PRIMARYKEYS:
  2329. /* Error if not on a row */
  2330. if ((lpstmt->irow == BEFORE_FIRST_ROW) ||
  2331. (lpstmt->irow == AFTER_LAST_ROW)) {
  2332. lpstmt->errcode = ERR_CURSORSTATE;
  2333. return SQL_ERROR;
  2334. }
  2335. /* Return the requested column */
  2336. switch (icol) {
  2337. case PRIMARYKEY_QUALIFIER:
  2338. fSqlTypeIn = SQL_CHAR;
  2339. rgbValueIn = NULL;
  2340. cbValueIn = SQL_NULL_DATA;
  2341. break;
  2342. case PRIMARYKEY_OWNER:
  2343. fSqlTypeIn = SQL_CHAR;
  2344. rgbValueIn = NULL;
  2345. cbValueIn = SQL_NULL_DATA;
  2346. break;
  2347. case PRIMARYKEY_TABLE:
  2348. fSqlTypeIn = SQL_CHAR;
  2349. rgbValueIn = (LPSTR) (lpstmt->lpISAMTableDef->szTableName);
  2350. cbValueIn = SQL_NTS;
  2351. break;
  2352. case PRIMARYKEY_COLUMN:
  2353. /* Find the description of the column. For each column... */
  2354. return SQL_ERROR;
  2355. break;
  2356. case PRIMARYKEY_KEYSEQ:
  2357. fSqlTypeIn = SQL_SMALLINT;
  2358. sValue = (SWORD) (lpstmt->irow + 1);
  2359. rgbValueIn = &sValue;
  2360. cbValueIn = 2;
  2361. break;
  2362. case PRIMARYKEY_NAME:
  2363. fSqlTypeIn = SQL_CHAR;
  2364. if (s_lstrlen(lpstmt->lpISAMTableDef->szPrimaryKeyName) != 0) {
  2365. rgbValueIn = lpstmt->lpISAMTableDef->szPrimaryKeyName;
  2366. cbValueIn = SQL_NTS;
  2367. }
  2368. else {
  2369. rgbValueIn = NULL;
  2370. cbValueIn = SQL_NULL_DATA;
  2371. }
  2372. break;
  2373. default:
  2374. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  2375. return SQL_ERROR;
  2376. }
  2377. /* Reset offset if first read of this column */
  2378. if (lpstmt->icol != icol) {
  2379. lpstmt->icol = icol;
  2380. lpstmt->cbOffset = 0;
  2381. }
  2382. /* Convert the results to the requested type */
  2383. lpstmt->errcode = ConvertSqlToC(fSqlTypeIn,
  2384. GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn,
  2385. cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax,
  2386. pcbValue);
  2387. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2388. return SQL_SUCCESS_WITH_INFO;
  2389. else if (lpstmt->errcode != ERR_SUCCESS)
  2390. return SQL_ERROR;
  2391. break;
  2392. /* SQLForeignKeys()... */
  2393. case STMT_TYPE_FOREIGNKEYS:
  2394. /* Error if not on a row */
  2395. if ((lpstmt->irow == BEFORE_FIRST_ROW) ||
  2396. (lpstmt->irow == AFTER_LAST_ROW)) {
  2397. lpstmt->errcode = ERR_CURSORSTATE;
  2398. return SQL_ERROR;
  2399. }
  2400. /* Return the requested column */
  2401. switch (icol) {
  2402. case FOREIGNKEY_PKQUALIFIER:
  2403. fSqlTypeIn = SQL_CHAR;
  2404. rgbValueIn = NULL;
  2405. cbValueIn = SQL_NULL_DATA;
  2406. break;
  2407. case FOREIGNKEY_PKOWNER:
  2408. fSqlTypeIn = SQL_CHAR;
  2409. rgbValueIn = NULL;
  2410. cbValueIn = SQL_NULL_DATA;
  2411. break;
  2412. case FOREIGNKEY_PKTABLE:
  2413. fSqlTypeIn = SQL_CHAR;
  2414. rgbValueIn = lpstmt->szPkTableName;
  2415. cbValueIn = SQL_NTS;
  2416. break;
  2417. case FOREIGNKEY_PKCOLUMN:
  2418. fSqlTypeIn = SQL_CHAR;
  2419. rgbValueIn = lpstmt->lpKeyInfo->PrimaryKeyColumns[
  2420. lpstmt->lpKeyInfo->iKeyColumns-1];
  2421. cbValueIn = SQL_NTS;
  2422. break;
  2423. case FOREIGNKEY_FKQUALIFIER:
  2424. fSqlTypeIn = SQL_CHAR;
  2425. rgbValueIn = NULL;
  2426. cbValueIn = SQL_NULL_DATA;
  2427. break;
  2428. case FOREIGNKEY_FKOWNER:
  2429. fSqlTypeIn = SQL_CHAR;
  2430. rgbValueIn = NULL;
  2431. cbValueIn = SQL_NULL_DATA;
  2432. break;
  2433. case FOREIGNKEY_FKTABLE:
  2434. fSqlTypeIn = SQL_CHAR;
  2435. rgbValueIn = lpstmt->szTableName;
  2436. cbValueIn = SQL_NTS;
  2437. break;
  2438. case FOREIGNKEY_FKCOLUMN:
  2439. fSqlTypeIn = SQL_CHAR;
  2440. rgbValueIn = lpstmt->lpKeyInfo->ForeignKeyColumns[
  2441. lpstmt->lpKeyInfo->iKeyColumns-1];
  2442. cbValueIn = SQL_NTS;
  2443. break;
  2444. case FOREIGNKEY_KEYSEQ:
  2445. fSqlTypeIn = SQL_SMALLINT;
  2446. sValue = (SWORD) lpstmt->lpKeyInfo->iKeyColumns;
  2447. rgbValueIn = &sValue;
  2448. cbValueIn = 2;
  2449. break;
  2450. case FOREIGNKEY_UPDATERULE:
  2451. fSqlTypeIn = SQL_SMALLINT;
  2452. sValue = lpstmt->lpKeyInfo->fForeignKeyUpdateRule;
  2453. rgbValueIn = &sValue;
  2454. if (lpstmt->lpKeyInfo->fForeignKeyUpdateRule != -1)
  2455. cbValueIn = 2;
  2456. else
  2457. cbValueIn = SQL_NULL_DATA;
  2458. break;
  2459. case FOREIGNKEY_DELETERULE:
  2460. fSqlTypeIn = SQL_SMALLINT;
  2461. sValue = lpstmt->lpKeyInfo->fForeignKeyDeleteRule;
  2462. rgbValueIn = &sValue;
  2463. if (lpstmt->lpKeyInfo->fForeignKeyDeleteRule != -1)
  2464. cbValueIn = 2;
  2465. else
  2466. cbValueIn = SQL_NULL_DATA;
  2467. break;
  2468. case FOREIGNKEY_FKNAME:
  2469. fSqlTypeIn = SQL_CHAR;
  2470. if (s_lstrlen(lpstmt->lpKeyInfo->szForeignKeyName) != 0) {
  2471. rgbValueIn = lpstmt->lpKeyInfo->szForeignKeyName;
  2472. cbValueIn = SQL_NTS;
  2473. }
  2474. else {
  2475. rgbValueIn = NULL;
  2476. cbValueIn = SQL_NULL_DATA;
  2477. }
  2478. break;
  2479. case FOREIGNKEY_PKNAME:
  2480. fSqlTypeIn = SQL_CHAR;
  2481. if (s_lstrlen(lpstmt->lpKeyInfo->szPrimaryKeyName) != 0) {
  2482. rgbValueIn = lpstmt->lpKeyInfo->szPrimaryKeyName;
  2483. cbValueIn = SQL_NTS;
  2484. }
  2485. else {
  2486. rgbValueIn = NULL;
  2487. cbValueIn = SQL_NULL_DATA;
  2488. }
  2489. break;
  2490. default:
  2491. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  2492. return SQL_ERROR;
  2493. }
  2494. /* Reset offset if first read of this column */
  2495. if (lpstmt->icol != icol) {
  2496. lpstmt->icol = icol;
  2497. lpstmt->cbOffset = 0;
  2498. }
  2499. /* Convert the results to the requested type */
  2500. lpstmt->errcode = ConvertSqlToC(fSqlTypeIn,
  2501. GetUnsignedAttribute(lpstmt, fSqlTypeIn), rgbValueIn,
  2502. cbValueIn, &(lpstmt->cbOffset), fCType, rgbValue, cbValueMax,
  2503. pcbValue);
  2504. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2505. return SQL_SUCCESS_WITH_INFO;
  2506. else if (lpstmt->errcode != ERR_SUCCESS)
  2507. return SQL_ERROR;
  2508. break;
  2509. /* SELECT statement */
  2510. case STMT_TYPE_SELECT:
  2511. {
  2512. /* Error if not on a row */
  2513. lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  2514. lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode->node.root.sql);
  2515. if ((lpSqlNode->node.select.CurrentRow == BEFORE_FIRST_ROW) ||
  2516. (lpSqlNode->node.select.CurrentRow == AFTER_LAST_ROW)) {
  2517. lpstmt->errcode = ERR_CURSORSTATE;
  2518. return SQL_ERROR;
  2519. }
  2520. fReturningDistinct = lpSqlNode->node.select.ReturningDistinct;
  2521. //This was added to fix an MS Access bug
  2522. if ( (fCType == SQL_C_DEFAULT) || (fCType == SQL_C_LONG) || (fCType == SQL_C_SHORT) || (fCType == SQL_C_TINYINT) )
  2523. {
  2524. SWORD pcbBytesRet = 0;
  2525. SDWORD pfDummy = 0;
  2526. UCHAR szColType [MAX_COLUMN_NAME_LENGTH+1];
  2527. szColType[0] = 0;
  2528. SQLColAttributes(hstmt, icol, SQL_COLUMN_TYPE_NAME, szColType, MAX_COLUMN_NAME_LENGTH,
  2529. &pcbBytesRet, &pfDummy);
  2530. //test data
  2531. // strcpy((char*)szColType, "SMALL_STRING");
  2532. // pcbBytesRet = 12;
  2533. LPSQLTYPE lpSqlType = GetType2(szColType);
  2534. if (lpSqlType == 0)
  2535. {
  2536. lpstmt->errcode = ERR_ISAM;
  2537. return SQL_ERROR;
  2538. };
  2539. if ( (lpSqlType->unsignedAttribute == -1) || (lpSqlType->unsignedAttribute == TRUE) )
  2540. {
  2541. switch (fCType)
  2542. {
  2543. case SQL_C_DEFAULT:
  2544. {
  2545. switch (lpSqlType->type)
  2546. {
  2547. case SQL_TINYINT:
  2548. fCType = SQL_C_UTINYINT;
  2549. break;
  2550. case SQL_SMALLINT:
  2551. fCType = SQL_C_USHORT;
  2552. break;
  2553. case SQL_INTEGER:
  2554. fCType = SQL_C_ULONG;
  2555. break;
  2556. default:
  2557. break;
  2558. }
  2559. }
  2560. break;
  2561. case SQL_C_LONG:
  2562. fCType = SQL_C_ULONG;
  2563. break;
  2564. case SQL_C_SHORT:
  2565. fCType = SQL_C_USHORT;
  2566. break;
  2567. case SQL_C_TINYINT:
  2568. fCType = SQL_C_UTINYINT;
  2569. break;
  2570. default:
  2571. break;
  2572. }
  2573. }
  2574. }
  2575. /* Get the VALUE node corresponding to the column number. */
  2576. idxSqlNodeValues = lpSqlNode->node.select.Values;
  2577. for (column = 1; column <= icol; column++) {
  2578. if (idxSqlNodeValues == NO_SQLNODE) {
  2579. lpstmt->errcode = ERR_INVALIDCOLUMNID;
  2580. return SQL_ERROR;
  2581. }
  2582. lpSqlNodeValues = ToNode(lpstmt->lpSqlStmt, idxSqlNodeValues);
  2583. idxSqlNodeValues = lpSqlNodeValues->node.values.Next;
  2584. }
  2585. lpSqlNode = ToNode(lpstmt->lpSqlStmt, lpSqlNodeValues->node.values.Value);
  2586. /* Reset offset if first read of this column */
  2587. if (lpstmt->icol != icol) {
  2588. lpstmt->icol = icol;
  2589. lpstmt->cbOffset = 0;
  2590. }
  2591. /* Is this a COLUMN node for a character (binary) column that is */
  2592. /* to be read into a character (binary) buffer? */
  2593. if ((lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) &&
  2594. (((lpSqlNode->sqlDataType == TYPE_CHAR) &&
  2595. (fCType == SQL_C_CHAR)) ||
  2596. ((lpSqlNode->sqlDataType == TYPE_BINARY) &&
  2597. (fCType == SQL_C_BINARY))) &&
  2598. (!(lpSqlNode->node.column.InSortRecord)) &&
  2599. (!(fReturningDistinct)) ) {
  2600. /* Yes. Get the character data */
  2601. lpSqlNodeTable = ToNode(lpstmt->lpSqlStmt,
  2602. lpSqlNode->node.column.Table);
  2603. if (!(lpSqlNodeTable->node.table.AllNull)) {
  2604. err = ISAMGetData(lpSqlNodeTable->node.table.Handle,
  2605. lpSqlNode->node.column.Id, lpstmt->cbOffset,
  2606. fCType, rgbValue, cbValueMax, &cbValue);
  2607. if ((err == NO_ISAM_ERR) || (err == ISAM_TRUNCATION))
  2608. lpstmt->fISAMTxnStarted = TRUE;
  2609. }
  2610. else {
  2611. if ((fCType == SQL_C_CHAR) && (rgbValue != NULL) &&
  2612. (cbValueMax > 0))
  2613. s_lstrcpy(rgbValue, "");
  2614. err = NO_ISAM_ERR;
  2615. cbValue = SQL_NULL_DATA;
  2616. }
  2617. if (err == ISAM_TRUNCATION)
  2618. lpstmt->errcode = ERR_DATATRUNCATED;
  2619. else if (err != NO_ISAM_ERR) {
  2620. lpstmt->errcode = err;
  2621. ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM,
  2622. (LPUSTR)lpstmt->szISAMError);
  2623. return SQL_ERROR;
  2624. }
  2625. /* Return the size */
  2626. if (pcbValue != NULL)
  2627. *pcbValue = cbValue;
  2628. // CString myOutput1;
  2629. // myOutput1.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=1 pcbValue = %ld\n"), *pcbValue);
  2630. // ODBCTRACE(myOutput1);
  2631. /* Fix the offset */
  2632. if (cbValue >= cbValueMax) {
  2633. if (fCType == SQL_C_CHAR)
  2634. {
  2635. if (cbValueMax > 0)
  2636. lpstmt->cbOffset += (cbValueMax-1);
  2637. }
  2638. else
  2639. lpstmt->cbOffset += (cbValueMax);
  2640. }
  2641. else if (cbValue > 0)
  2642. lpstmt->cbOffset += (cbValue);
  2643. /* Return warning if data was truncated */
  2644. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2645. return SQL_SUCCESS_WITH_INFO;
  2646. }
  2647. /* Is this a COLUMN node for a character column that is */
  2648. /* to be read into a binary buffer? */
  2649. else if ((lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) &&
  2650. (lpSqlNode->sqlDataType == TYPE_CHAR) &&
  2651. (fCType == SQL_C_BINARY) &&
  2652. (!(lpSqlNode->node.column.InSortRecord)) &&
  2653. (!(fReturningDistinct)) ) {
  2654. /* Yes. Get the character data */
  2655. lpSqlNodeTable = ToNode(lpstmt->lpSqlStmt,
  2656. lpSqlNode->node.column.Table);
  2657. if (!(lpSqlNodeTable->node.table.AllNull)) {
  2658. err = ISAMGetData(lpSqlNodeTable->node.table.Handle,
  2659. lpSqlNode->node.column.Id, lpstmt->cbOffset,
  2660. SQL_C_CHAR, rgbValue, cbValueMax, &cbValue);
  2661. if ((err == NO_ISAM_ERR) || (err == ISAM_TRUNCATION))
  2662. lpstmt->fISAMTxnStarted = TRUE;
  2663. }
  2664. else {
  2665. err = NO_ISAM_ERR;
  2666. cbValue = SQL_NULL_DATA;
  2667. }
  2668. if (err == ISAM_TRUNCATION)
  2669. lpstmt->errcode = ERR_DATATRUNCATED;
  2670. else if (err != NO_ISAM_ERR) {
  2671. lpstmt->errcode = err;
  2672. ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM,
  2673. (LPUSTR)lpstmt->szISAMError);
  2674. return SQL_ERROR;
  2675. }
  2676. /* Return the size */
  2677. if (pcbValue != NULL)
  2678. *pcbValue = cbValue;
  2679. // CString myOutput2;
  2680. // myOutput2.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=2 pcbValue = %ld\n"), *pcbValue);
  2681. // ODBCTRACE(myOutput2);
  2682. /* Fix the offset */
  2683. if (cbValue >= cbValueMax)
  2684. lpstmt->cbOffset += (cbValueMax);
  2685. else if (cbValue > 0)
  2686. lpstmt->cbOffset += (cbValue);
  2687. /* Return warning if data was truncated */
  2688. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2689. return SQL_SUCCESS_WITH_INFO;
  2690. }
  2691. /* Is this a COLUMN node for a binary column that is */
  2692. /* to be read into a character buffer? */
  2693. else if ((lpSqlNode->sqlNodeType == NODE_TYPE_COLUMN) &&
  2694. (lpSqlNode->sqlDataType == TYPE_BINARY) &&
  2695. (fCType == SQL_C_CHAR) &&
  2696. (!(lpSqlNode->node.column.InSortRecord)) &&
  2697. (!(fReturningDistinct)) ) {
  2698. /* Yes. Get the character data */
  2699. lpSqlNodeTable = ToNode(lpstmt->lpSqlStmt,
  2700. lpSqlNode->node.column.Table);
  2701. if (!(lpSqlNodeTable->node.table.AllNull)) {
  2702. err = ISAMGetData(lpSqlNodeTable->node.table.Handle,
  2703. lpSqlNode->node.column.Id, lpstmt->cbOffset,
  2704. fCType, rgbValue, cbValueMax, &cbValue);
  2705. if ((err == NO_ISAM_ERR) || (err == ISAM_TRUNCATION))
  2706. lpstmt->fISAMTxnStarted = TRUE;
  2707. }
  2708. else {
  2709. if ((rgbValue != NULL) && (cbValueMax > 0))
  2710. s_lstrcpy(rgbValue, "");
  2711. err = NO_ISAM_ERR;
  2712. cbValue = SQL_NULL_DATA;
  2713. }
  2714. if (err == ISAM_TRUNCATION)
  2715. lpstmt->errcode = ERR_DATATRUNCATED;
  2716. else if (err != NO_ISAM_ERR) {
  2717. lpstmt->errcode = err;
  2718. ISAMGetErrorMessage(lpstmt->lpdbc->lpISAM,
  2719. (LPUSTR)lpstmt->szISAMError);
  2720. return SQL_ERROR;
  2721. }
  2722. /* Return the size */
  2723. if (pcbValue != NULL)
  2724. *pcbValue = cbValue;
  2725. // CString myOutput3;
  2726. // myOutput3.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=3 pcbValue = %ld\n"), *pcbValue);
  2727. // ODBCTRACE(myOutput3);
  2728. /* Fix the offset */
  2729. if (cbValue >= cbValueMax)
  2730. {
  2731. if (cbValueMax > 0)
  2732. lpstmt->cbOffset += (cbValueMax-1);
  2733. }
  2734. else if (cbValue > 0)
  2735. lpstmt->cbOffset += (cbValue);
  2736. /* Return warning if data was truncated */
  2737. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2738. return SQL_SUCCESS_WITH_INFO;
  2739. }
  2740. else {
  2741. /* No. Evaluate the VALUE node. */
  2742. err = EvaluateExpression(lpstmt, lpSqlNode);
  2743. if (err != ERR_SUCCESS) {
  2744. lpstmt->errcode = err;
  2745. return SQL_ERROR;
  2746. }
  2747. /* Is the value NULL? */
  2748. if (lpSqlNode->sqlIsNull) {
  2749. /* Yes. Return NULL */
  2750. if (pcbValue != NULL)
  2751. *pcbValue = SQL_NULL_DATA;
  2752. }
  2753. else {
  2754. /* No. Copy the value from the node to the output buffer. */
  2755. switch (lpSqlNode->sqlDataType) {
  2756. case TYPE_DOUBLE:
  2757. case TYPE_NUMERIC:
  2758. case TYPE_INTEGER:
  2759. /* SQL_C_DEFAULT or SQL_C_BINARY specified? */
  2760. if ((fCType == SQL_C_DEFAULT)||(fCType == SQL_C_BINARY)) {
  2761. /* Yes. Get the descriptor of datatype of value */
  2762. //Get type information about the column
  2763. SWORD pcbBytesRet = 0;
  2764. SDWORD pfDummy = 0;
  2765. UCHAR szColType [MAX_COLUMN_NAME_LENGTH+1];
  2766. szColType[0] = 0;
  2767. SQLColAttributes(hstmt, icol, SQL_COLUMN_TYPE_NAME, szColType, MAX_COLUMN_NAME_LENGTH,
  2768. &pcbBytesRet, &pfDummy);
  2769. lpSqlType = GetType2(szColType);
  2770. // lpSqlType = GetType(lpSqlNode->sqlSqlType);
  2771. if (lpSqlType == NULL) {
  2772. lpstmt->errcode = ERR_ISAM;
  2773. return SQL_ERROR;
  2774. }
  2775. /* Determine the C Type the value */
  2776. switch (lpSqlType->type) {
  2777. case SQL_CHAR:
  2778. case SQL_VARCHAR:
  2779. case SQL_LONGVARCHAR:
  2780. fCType = SQL_C_CHAR;
  2781. break;
  2782. case SQL_BIGINT:
  2783. fCType = SQL_C_CHAR;
  2784. break;
  2785. case SQL_DECIMAL:
  2786. case SQL_NUMERIC:
  2787. fCType = SQL_C_CHAR;
  2788. break;
  2789. case SQL_DOUBLE:
  2790. case SQL_FLOAT:
  2791. fCType = SQL_C_DOUBLE;
  2792. break;
  2793. case SQL_BIT:
  2794. fCType = SQL_C_BIT;
  2795. break;
  2796. case SQL_REAL:
  2797. fCType = SQL_C_FLOAT;
  2798. break;
  2799. case SQL_INTEGER:
  2800. if (lpSqlType->unsignedAttribute == TRUE)
  2801. fCType = SQL_C_ULONG;
  2802. else
  2803. fCType = SQL_C_SLONG;
  2804. break;
  2805. case SQL_SMALLINT:
  2806. if (lpSqlType->unsignedAttribute == TRUE)
  2807. fCType = SQL_C_USHORT;
  2808. else
  2809. fCType = SQL_C_SSHORT;
  2810. break;
  2811. case SQL_TINYINT:
  2812. if (lpSqlType->unsignedAttribute == TRUE)
  2813. fCType = SQL_C_UTINYINT;
  2814. else
  2815. fCType = SQL_C_STINYINT;
  2816. break;
  2817. case SQL_DATE:
  2818. case SQL_TIME:
  2819. case SQL_TIMESTAMP:
  2820. lpstmt->errcode = ERR_NOTSUPPORTED;
  2821. return SQL_ERROR;
  2822. case SQL_BINARY:
  2823. case SQL_VARBINARY:
  2824. case SQL_LONGVARBINARY:
  2825. fCType = SQL_C_BINARY;
  2826. break;
  2827. default:
  2828. lpstmt->errcode = ERR_NOTSUPPORTED;
  2829. return SQL_ERROR;
  2830. }
  2831. }
  2832. /* Get the value */
  2833. switch (lpSqlNode->sqlDataType) {
  2834. case TYPE_DOUBLE:
  2835. {
  2836. lpstmt->errcode = ConvertSqlToC(SQL_DOUBLE,
  2837. GetUnsignedAttribute(lpstmt, SQL_DOUBLE),
  2838. &(lpSqlNode->value.Double), sizeof(double),
  2839. &(lpstmt->cbOffset), fCType, rgbValue,
  2840. cbValueMax, pcbValue);
  2841. // CString myOutput4;
  2842. // myOutput4.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=4 pcbValue = %ld\n"), *pcbValue);
  2843. // ODBCTRACE(myOutput4);
  2844. }
  2845. break;
  2846. case TYPE_INTEGER:
  2847. {
  2848. //We have already made sure value is stored in double
  2849. //as the appropriate signed or un-signed value
  2850. BOOL fIsUnsigned = (lpSqlNode->value.Double > 0) ? TRUE : FALSE;
  2851. intval = (long) lpSqlNode->value.Double;
  2852. lpstmt->errcode = ConvertSqlToC(SQL_INTEGER,
  2853. // GetUnsignedAttribute(lpstmt, SQL_INTEGER),
  2854. fIsUnsigned,
  2855. &intval, sizeof(long), &(lpstmt->cbOffset),
  2856. fCType, rgbValue, cbValueMax, pcbValue);
  2857. // CString myOutput5;
  2858. // myOutput5.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=5 pcbValue = %ld\n"), *pcbValue);
  2859. // ODBCTRACE(myOutput5);
  2860. }
  2861. break;
  2862. case TYPE_NUMERIC:
  2863. {
  2864. if (s_lstrlen(lpSqlNode->value.String) != 0) {
  2865. lpstmt->errcode = ConvertSqlToC(SQL_CHAR,
  2866. GetUnsignedAttribute(lpstmt, SQL_CHAR),
  2867. lpSqlNode->value.String,
  2868. s_lstrlen(lpSqlNode->value.String),
  2869. &(lpstmt->cbOffset), fCType, rgbValue,
  2870. cbValueMax, pcbValue);
  2871. // CString myOutput6;
  2872. // myOutput6.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=6 pcbValue = %ld\n"), *pcbValue);
  2873. // ODBCTRACE(myOutput6);
  2874. }
  2875. else {
  2876. lpstmt->errcode = ConvertSqlToC(SQL_CHAR,
  2877. GetUnsignedAttribute(lpstmt, SQL_CHAR),
  2878. "0", 1, &(lpstmt->cbOffset), fCType, rgbValue,
  2879. cbValueMax, pcbValue);
  2880. // CString myOutput7;
  2881. // myOutput7.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=7 pcbValue = %ld\n"), *pcbValue);
  2882. // ODBCTRACE(myOutput7);
  2883. }
  2884. }
  2885. break;
  2886. case TYPE_CHAR:
  2887. case TYPE_DATE:
  2888. case TYPE_TIME:
  2889. case TYPE_TIMESTAMP:
  2890. case TYPE_BINARY:
  2891. default:
  2892. lpstmt->errcode = ERR_INTERNAL;
  2893. break;
  2894. }
  2895. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2896. return SQL_SUCCESS_WITH_INFO;
  2897. else if (lpstmt->errcode != ERR_SUCCESS)
  2898. return SQL_ERROR;
  2899. break;
  2900. case TYPE_CHAR:
  2901. {
  2902. lpstmt->errcode = ConvertSqlToC(SQL_CHAR,
  2903. GetUnsignedAttribute(lpstmt, SQL_CHAR),
  2904. lpSqlNode->value.String,
  2905. s_lstrlen(lpSqlNode->value.String),
  2906. &(lpstmt->cbOffset), fCType, rgbValue,
  2907. cbValueMax, pcbValue);
  2908. // CString myOutput8;
  2909. // myOutput8.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=8 pcbValue = %ld\n"), *pcbValue);
  2910. // ODBCTRACE(myOutput8);
  2911. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2912. return SQL_SUCCESS_WITH_INFO;
  2913. else if (lpstmt->errcode != ERR_SUCCESS)
  2914. return SQL_ERROR;
  2915. }
  2916. break;
  2917. case TYPE_DATE:
  2918. lpstmt->errcode = ConvertSqlToC(SQL_DATE,
  2919. GetUnsignedAttribute(lpstmt, SQL_DATE),
  2920. &(lpSqlNode->value.Date), sizeof(DATE_STRUCT),
  2921. &(lpstmt->cbOffset), fCType, rgbValue,
  2922. cbValueMax, pcbValue);
  2923. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2924. return SQL_SUCCESS_WITH_INFO;
  2925. else if (lpstmt->errcode != ERR_SUCCESS)
  2926. return SQL_ERROR;
  2927. break;
  2928. case TYPE_TIME:
  2929. lpstmt->errcode = ConvertSqlToC(SQL_TIME,
  2930. GetUnsignedAttribute(lpstmt, SQL_TIME),
  2931. &(lpSqlNode->value.Time), sizeof(TIME_STRUCT),
  2932. &(lpstmt->cbOffset), fCType, rgbValue,
  2933. cbValueMax, pcbValue);
  2934. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2935. return SQL_SUCCESS_WITH_INFO;
  2936. else if (lpstmt->errcode != ERR_SUCCESS)
  2937. return SQL_ERROR;
  2938. break;
  2939. case TYPE_TIMESTAMP:
  2940. lpstmt->errcode = ConvertSqlToC(SQL_TIMESTAMP,
  2941. GetUnsignedAttribute(lpstmt, SQL_TIMESTAMP),
  2942. &(lpSqlNode->value.Timestamp),
  2943. sizeof(TIMESTAMP_STRUCT), &(lpstmt->cbOffset),
  2944. fCType, rgbValue, cbValueMax, pcbValue);
  2945. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2946. return SQL_SUCCESS_WITH_INFO;
  2947. else if (lpstmt->errcode != ERR_SUCCESS)
  2948. return SQL_ERROR;
  2949. break;
  2950. case TYPE_BINARY:
  2951. {
  2952. lpstmt->errcode = ConvertSqlToC(SQL_BINARY,
  2953. GetUnsignedAttribute(lpstmt, SQL_BINARY),
  2954. BINARY_DATA(lpSqlNode->value.Binary),
  2955. BINARY_LENGTH(lpSqlNode->value.Binary),
  2956. &(lpstmt->cbOffset), fCType, rgbValue,
  2957. cbValueMax, pcbValue);
  2958. // CString myOutput9;
  2959. // myOutput9.Format(_T("\nWBEM ODBC Driver : SQLGetData POS=9 pcbValue = %ld\n"), *pcbValue);
  2960. // ODBCTRACE(myOutput9);
  2961. if (lpstmt->errcode == ERR_DATATRUNCATED)
  2962. return SQL_SUCCESS_WITH_INFO;
  2963. else if (lpstmt->errcode != ERR_SUCCESS)
  2964. return SQL_ERROR;
  2965. }
  2966. break;
  2967. default:
  2968. lpstmt->errcode = ERR_NOTSUPPORTED;
  2969. return SQL_ERROR;
  2970. }
  2971. }
  2972. }
  2973. }
  2974. break;
  2975. }
  2976. // CString myOutput;
  2977. // myOutput.Format(_T("\nWBEM ODBC Driver : EXITING SQLGetData pcbValue = %ld\n"), *pcbValue);
  2978. // ODBCTRACE(myOutput);
  2979. return SQL_SUCCESS;
  2980. }
  2981. /***************************************************************************/
  2982. RETCODE SQL_API SQLMoreResults(
  2983. HSTMT hstmt)
  2984. {
  2985. LPSTMT lpstmt;
  2986. RETCODE err;
  2987. /* Get statement handle */
  2988. lpstmt = (LPSTMT) hstmt;
  2989. lpstmt->errcode = ERR_SUCCESS;
  2990. //To make guarentee Ole is initialized per thread
  2991. COleInitializationManager myOleManager;
  2992. MyImpersonator im (lpstmt, "SQLMoreResults");
  2993. /* There is never a second result set */
  2994. err = SQLFreeStmt(hstmt, SQL_CLOSE);
  2995. if ((err != SQL_SUCCESS) && (err != SQL_SUCCESS_WITH_INFO))
  2996. return err;
  2997. return SQL_NO_DATA_FOUND;
  2998. }
  2999. /***************************************************************************/
  3000. RETCODE SQL_API SQLRowCount(
  3001. HSTMT hstmt,
  3002. SDWORD FAR *pcrow)
  3003. {
  3004. LPSTMT lpstmt;
  3005. /* Get statement handle */
  3006. lpstmt = (LPSTMT) hstmt;
  3007. lpstmt->errcode = ERR_SUCCESS;
  3008. //To make guarentee Ole is initialized per thread
  3009. COleInitializationManager myOleManager;
  3010. /* Return row count */
  3011. if (pcrow != NULL)
  3012. *pcrow = lpstmt->cRowCount;
  3013. return SQL_SUCCESS;
  3014. }
  3015. /***************************************************************************/
  3016. RETCODE SQL_API SQLSetPos(
  3017. HSTMT hstmt,
  3018. UWORD irow,
  3019. UWORD fOption,
  3020. UWORD fLock)
  3021. {
  3022. LPSTMT lpstmt;
  3023. lpstmt = (LPSTMT) hstmt;
  3024. lpstmt->errcode = ERR_NOTSUPPORTED;
  3025. return SQL_ERROR;
  3026. }
  3027. /***************************************************************************/
  3028. RETCODE SQL_API SQLExtendedFetch(
  3029. HSTMT hstmt,
  3030. UWORD fFetchType,
  3031. SDWORD irow,
  3032. UDWORD FAR *pcrow,
  3033. UWORD FAR *rgfRowStatus)
  3034. {
  3035. LPSTMT lpstmt;
  3036. lpstmt = (LPSTMT) hstmt;
  3037. lpstmt->errcode = ERR_NOTSUPPORTED;
  3038. return SQL_ERROR;
  3039. }
  3040. /***************************************************************************/
  3041. RETCODE SQL_API SQLError(
  3042. HENV henv,
  3043. HDBC hdbc,
  3044. HSTMT hstmt,
  3045. UCHAR FAR *szSqlState,
  3046. SDWORD FAR *pfNativeError,
  3047. UCHAR FAR *szErrorMsg,
  3048. SWORD cbErrorMsgMax,
  3049. SWORD FAR *pcbErrorMsg)
  3050. {
  3051. LPENV lpenv;
  3052. LPDBC lpdbc;
  3053. LPSTMT lpstmt;
  3054. RETCODE errcode;
  3055. LPUSTR lpstr;
  3056. UCHAR szTemplate[MAX_ERROR_LENGTH+1];
  3057. UCHAR szError[MAX_ERROR_LENGTH+1];
  3058. LPUSTR lpszISAMError;
  3059. //To make guarentee Ole is initialized per thread
  3060. COleInitializationManager myOleManager;
  3061. //Initialize
  3062. szTemplate[0] = 0;
  3063. szError[0] = 0;
  3064. /* If a HSTMT is specified, get error from HSTMT */
  3065. if (hstmt != SQL_NULL_HSTMT) {
  3066. lpstmt = (LPSTMT) hstmt;
  3067. errcode = lpstmt->errcode;
  3068. lpszISAMError = (LPUSTR)lpstmt->szISAMError;
  3069. lpstmt->errcode = ERR_SUCCESS;
  3070. lpstr = (LPUSTR)lpstmt->szError;
  3071. }
  3072. /* Otherwise if a HDBC is specified, get error from HDBC */
  3073. else if (hdbc != SQL_NULL_HDBC) {
  3074. lpdbc = (LPDBC) hdbc;
  3075. errcode = lpdbc->errcode;
  3076. lpszISAMError = (LPUSTR)lpdbc->szISAMError;
  3077. lpdbc->errcode = ERR_SUCCESS;
  3078. lpstr = NULL;
  3079. }
  3080. /* Otherwise if a HENV is specified, get error from HENV */
  3081. else if (henv != SQL_NULL_HENV) {
  3082. lpenv = (LPENV) henv;
  3083. errcode = lpenv->errcode;
  3084. lpszISAMError = (LPUSTR)lpenv->szISAMError;
  3085. lpenv->errcode = ERR_SUCCESS;
  3086. lpstr = NULL;
  3087. }
  3088. /* Otherwise error */
  3089. else
  3090. return SQL_INVALID_HANDLE;
  3091. /* Return our internal error code */
  3092. if (pfNativeError != NULL)
  3093. *pfNativeError = errcode;
  3094. /* Success code? */
  3095. if (errcode == ERR_SUCCESS) {
  3096. /* Yes. No message to return */
  3097. LoadString(s_hModule, errcode, (LPSTR)szError, MAX_ERROR_LENGTH+1);
  3098. szError[SQL_SQLSTATE_SIZE] = '\0';
  3099. if (szSqlState != NULL)
  3100. s_lstrcpy(szSqlState, szError);
  3101. ReturnString(szErrorMsg, cbErrorMsgMax, pcbErrorMsg,
  3102. (LPUSTR) (szError + SQL_SQLSTATE_SIZE + 1));
  3103. return SQL_NO_DATA_FOUND;
  3104. }
  3105. /* Load in error string */
  3106. if (errcode <= LAST_ISAM_ERROR_CODE)
  3107. s_lstrcpy(szTemplate, lpszISAMError);
  3108. else
  3109. LoadString(s_hModule, errcode, (LPSTR)szTemplate, MAX_ERROR_LENGTH+1);
  3110. szTemplate[SQL_SQLSTATE_SIZE] = '\0';
  3111. /* Return state */
  3112. if (szSqlState != NULL)
  3113. {
  3114. szSqlState[0] = 0;
  3115. s_lstrcpy(szSqlState, szTemplate);
  3116. }
  3117. /* Return error message */
  3118. LPSTR lpTmp = (LPSTR)(szTemplate + SQL_SQLSTATE_SIZE + 1);
  3119. wsprintf((LPSTR)szError, lpTmp, lpstr);
  3120. errcode = ReturnString(szErrorMsg, cbErrorMsgMax, pcbErrorMsg, (LPUSTR)szError);
  3121. if (errcode == ERR_DATATRUNCATED)
  3122. return SQL_SUCCESS_WITH_INFO;
  3123. return SQL_SUCCESS;
  3124. }
  3125. /***************************************************************************/