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.

417 lines
13 KiB

  1. /***************************************************************************/
  2. /* EXECUTE.C */
  3. /* Copyright (C) 1995-96 SYWARE Inc., All rights reserved */
  4. /***************************************************************************/
  5. // Commenting #define out - causing compiler error - not sure if needed, compiles
  6. // okay without it.
  7. //#define WINVER 0x0400
  8. #include "precomp.h"
  9. #include "wbemidl.h"
  10. #include <comdef.h>
  11. //smart pointer
  12. _COM_SMARTPTR_TYPEDEF(IWbemServices, IID_IWbemServices);
  13. _COM_SMARTPTR_TYPEDEF(IEnumWbemClassObject, IID_IEnumWbemClassObject);
  14. //_COM_SMARTPTR_TYPEDEF(IWbemContext, IID_IWbemContext );
  15. _COM_SMARTPTR_TYPEDEF(IWbemLocator, IID_IWbemLocator);
  16. #include "drdbdr.h"
  17. /***************************************************************************/
  18. RETCODE SQL_API SQLExecute(
  19. HSTMT hstmt) /* statement to execute. */
  20. {
  21. LPSTMT lpstmt;
  22. LPSQLNODE lpSqlNode;
  23. SQLNODEIDX idxParameter;
  24. LPSQLNODE lpSqlNodeParameter;
  25. LPPARAMETER lpParameter;
  26. SDWORD cbValue;
  27. BOOL fDataTruncated;
  28. /* Get handle */
  29. lpstmt = (LPSTMT) hstmt;
  30. lpstmt->errcode = ERR_SUCCESS;
  31. //To make guarentee Ole is initialized per thread
  32. COleInitializationManager myOleManager;
  33. MyImpersonator im (lpstmt, "SQLExecute");
  34. /* Error if in the middle of a statement already */
  35. if (lpstmt->fStmtType != STMT_TYPE_NONE) {
  36. lpstmt->errcode = ERR_CURSORSTATE;
  37. return SQL_ERROR;
  38. }
  39. if (lpstmt->fNeedData) {
  40. lpstmt->errcode = ERR_CURSORSTATE;
  41. return SQL_ERROR;
  42. }
  43. /* Error if no SQL statement available */
  44. if (lpstmt->lpSqlStmt == NULL) {
  45. lpstmt->errcode = ERR_CURSORSTATE;
  46. return SQL_ERROR;
  47. }
  48. /* Get the root of the SQL tree */
  49. lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  50. if (lpSqlNode->sqlNodeType != NODE_TYPE_ROOT) {
  51. lpstmt->errcode = ERR_INTERNAL;
  52. return SQL_ERROR;
  53. }
  54. /* Count of rows is not available */
  55. lpstmt->cRowCount = -1;
  56. /* Do parameter substitution */
  57. lpstmt->fNeedData = FALSE;
  58. lpstmt->idxParameter = NO_SQLNODE;
  59. lpstmt->cbParameterOffset = -1;
  60. fDataTruncated = FALSE;
  61. idxParameter = lpSqlNode->node.root.parameters;
  62. while (idxParameter != NO_SQLNODE) {
  63. /* Get the parameter node in the SQL tree */
  64. lpSqlNodeParameter = ToNode(lpstmt->lpSqlStmt, idxParameter);
  65. /* Find the parameter specification in the list of bound parameters */
  66. for (lpParameter = lpstmt->lpParameter;
  67. lpParameter != NULL;
  68. lpParameter = lpParameter->lpNext) {
  69. if (lpParameter->ipar == lpSqlNodeParameter->node.parameter.Id)
  70. break;
  71. }
  72. if (lpParameter == NULL) {
  73. lpstmt->fNeedData = FALSE;
  74. lpstmt->errcode = ERR_PARAMETERMISSING;
  75. return SQL_ERROR;
  76. }
  77. /* Get length of parameter */
  78. if (lpParameter->pcbValue != NULL)
  79. cbValue = *(lpParameter->pcbValue);
  80. else
  81. cbValue = SQL_NTS;
  82. /* Is this a data-at-exec parameter? */
  83. if ((cbValue != SQL_DATA_AT_EXEC) &&
  84. (cbValue > SQL_LEN_DATA_AT_EXEC(0))) {
  85. /* No. Mark it */
  86. lpSqlNodeParameter->node.parameter.AtExec = FALSE;
  87. /* Copy the value into the parameter node */
  88. lpstmt->errcode = SetParameterValue(lpstmt, lpSqlNodeParameter,
  89. NULL, lpParameter->fCType, lpParameter->rgbValue, cbValue);
  90. if (lpstmt->errcode == ERR_DATATRUNCATED) {
  91. fDataTruncated = TRUE;
  92. lpstmt->errcode = ERR_SUCCESS;
  93. }
  94. if (lpstmt->errcode != ERR_SUCCESS) {
  95. lpstmt->fNeedData = FALSE;
  96. return SQL_ERROR;
  97. }
  98. }
  99. else {
  100. /* Yes. Mark it */
  101. lpSqlNodeParameter->node.parameter.AtExec = TRUE;
  102. /* Set flag saying data is still needed */
  103. lpstmt->fNeedData = TRUE;
  104. lpstmt->cbParameterOffset = 0;
  105. }
  106. /* Point to the next parameter */
  107. idxParameter = lpSqlNodeParameter->node.parameter.Next;
  108. }
  109. /* Are any parameters still needed? */
  110. if (lpstmt->fNeedData)
  111. /* Yes. let caller know that */
  112. return SQL_NEED_DATA;
  113. else {
  114. /* No. Perform the operation now */
  115. lpstmt->errcode = ExecuteQuery(lpstmt, NULL);
  116. if ((lpstmt->errcode == ERR_DATATRUNCATED) ||
  117. (lpstmt->errcode == ERR_DDLIGNORED) ||
  118. (lpstmt->errcode == ERR_DDLCAUSEDACOMMIT))
  119. return SQL_SUCCESS_WITH_INFO;
  120. if (lpstmt->errcode != ERR_SUCCESS)
  121. return SQL_ERROR;
  122. }
  123. if (fDataTruncated) {
  124. lpstmt->errcode = ERR_DATATRUNCATED;
  125. return SQL_SUCCESS_WITH_INFO;
  126. }
  127. return SQL_SUCCESS;
  128. }
  129. /***************************************************************************/
  130. RETCODE SQL_API SQLExecDirect(
  131. HSTMT hstmt,
  132. UCHAR FAR *szSqlStr,
  133. SDWORD cbSqlStr)
  134. {
  135. LPSTMT lpstmt;
  136. RETCODE rc;
  137. //To make guarentee Ole is initialized per thread
  138. COleInitializationManager myOleManager;
  139. //Check if size is given as SQL_NTS, if so calculate real size
  140. if ( (cbSqlStr == SQL_NTS) && szSqlStr)
  141. cbSqlStr = lstrlen((char*)szSqlStr);
  142. /* Get handle */
  143. lpstmt = (LPSTMT) hstmt;
  144. lpstmt->errcode = ERR_SUCCESS;
  145. MyImpersonator im (lpstmt, "SQLExecDirect");
  146. /* Prepare the statement */
  147. rc = SQLPrepare(hstmt, szSqlStr, cbSqlStr);
  148. if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  149. return rc;
  150. /* Execute it */
  151. rc = SQLExecute(hstmt);
  152. /* If execution caused a commit and the commit wiped out the prepared */
  153. /* statement, try again. It will work this time since the transaction */
  154. /* has been committed */
  155. if ((rc == SQL_ERROR) && (lpstmt->errcode == ERR_DDLSTATEMENTLOST)) {
  156. rc = SQLExecDirect(hstmt, szSqlStr, cbSqlStr);
  157. if ((rc == SQL_SUCCESS) || (rc == SQL_SUCCESS_WITH_INFO)) {
  158. lpstmt->errcode = ERR_DDLCAUSEDACOMMIT;
  159. rc = SQL_SUCCESS_WITH_INFO;
  160. }
  161. return rc;
  162. }
  163. /* If execution failed, get rid of prepared statement */
  164. if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO) &&
  165. (rc != SQL_NEED_DATA)) {
  166. FreeTree(lpstmt->lpSqlStmt);
  167. lpstmt->lpSqlStmt = NULL;
  168. lpstmt->fPreparedSql = FALSE;
  169. if (lpstmt->lpISAMStatement != NULL) {
  170. ISAMFreeStatement(lpstmt->lpISAMStatement);
  171. lpstmt->lpISAMStatement = NULL;
  172. }
  173. lpstmt->fNeedData = FALSE;
  174. lpstmt->idxParameter = NO_SQLNODE;
  175. lpstmt->cbParameterOffset = -1;
  176. lpstmt->cRowCount = -1;
  177. }
  178. /* If not a SELECT statement, get rid of prepared statement */
  179. else if ((lpstmt->fStmtType != STMT_TYPE_SELECT) &&
  180. (rc != SQL_NEED_DATA)) {
  181. FreeTree(lpstmt->lpSqlStmt);
  182. lpstmt->lpSqlStmt = NULL;
  183. lpstmt->fPreparedSql = FALSE;
  184. if (lpstmt->lpISAMStatement != NULL) {
  185. ISAMFreeStatement(lpstmt->lpISAMStatement);
  186. lpstmt->lpISAMStatement = NULL;
  187. }
  188. lpstmt->fNeedData = FALSE;
  189. lpstmt->idxParameter = NO_SQLNODE;
  190. lpstmt->cbParameterOffset = -1;
  191. }
  192. /* Otherwise, set flag so statement will be discarded in SQLFreeStmt() */
  193. else {
  194. lpstmt->fPreparedSql = FALSE;
  195. }
  196. return rc;
  197. }
  198. /***************************************************************************/
  199. RETCODE SQL_API SQLNativeSql(
  200. HDBC hdbc,
  201. UCHAR FAR *szSqlStrIn,
  202. SDWORD cbSqlStrIn,
  203. UCHAR FAR *szSqlStr,
  204. SDWORD cbSqlStrMax,
  205. SDWORD FAR *pcbSqlStr)
  206. {
  207. LPDBC lpdbc;
  208. lpdbc = (LPDBC) hdbc;
  209. lpdbc->errcode = ERR_NOTSUPPORTED;
  210. return SQL_ERROR;
  211. }
  212. /***************************************************************************/
  213. RETCODE SQL_API SQLParamData(
  214. HSTMT hstmt,
  215. PTR FAR *prgbValue)
  216. {
  217. LPSTMT lpstmt;
  218. LPSQLNODE lpSqlNode;
  219. LPSQLNODE lpSqlNodeParameter;
  220. LPPARAMETER lpParameter;
  221. /* Get handle */
  222. lpstmt = (LPSTMT) hstmt;
  223. lpstmt->errcode = ERR_SUCCESS;
  224. //To make guarentee Ole is initialized per thread
  225. COleInitializationManager myOleManager;
  226. MyImpersonator im (lpstmt, "SQLParamData");
  227. /* Error if no more parameters to return */
  228. if (!(lpstmt->fNeedData)) {
  229. lpstmt->errcode = ERR_CURSORSTATE;
  230. return SQL_ERROR;
  231. }
  232. /* Error if data was not provided for the previous parameter */
  233. if (lpstmt->cbParameterOffset == -1) {
  234. lpstmt->errcode = ERR_CURSORSTATE;
  235. return SQL_ERROR;
  236. }
  237. /* Point at next parameter */
  238. if (lpstmt->idxParameter == NO_SQLNODE) {
  239. lpSqlNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
  240. lpstmt->idxParameter = lpSqlNode->node.root.parameters;
  241. }
  242. else {
  243. lpSqlNodeParameter = ToNode(lpstmt->lpSqlStmt, lpstmt->idxParameter);
  244. lpstmt->idxParameter = lpSqlNodeParameter->node.parameter.Next;
  245. }
  246. /* Skip over all parameters that are not SQL_DATA_AT_EXEC */
  247. while (TRUE) {
  248. if (lpstmt->idxParameter == NO_SQLNODE) {
  249. /* If no more paramaeters, execute the query now */
  250. lpstmt->fNeedData = FALSE;
  251. lpstmt->cbParameterOffset = -1;
  252. lpstmt->errcode = ExecuteQuery(lpstmt, NULL);
  253. /* If an SQLExecDirect() on something other than a SELECT, get */
  254. /* rid of prepared statement */
  255. if ((lpstmt->fStmtType != STMT_TYPE_SELECT) &&
  256. !lpstmt->fPreparedSql) {
  257. FreeTree(lpstmt->lpSqlStmt);
  258. lpstmt->lpSqlStmt = NULL;
  259. }
  260. /* Leave */
  261. if ((lpstmt->errcode == ERR_DATATRUNCATED) ||
  262. (lpstmt->errcode == ERR_DDLIGNORED) ||
  263. (lpstmt->errcode == ERR_DDLCAUSEDACOMMIT))
  264. return SQL_SUCCESS_WITH_INFO;
  265. if (lpstmt->errcode != ERR_SUCCESS)
  266. return SQL_ERROR;
  267. return SQL_SUCCESS;
  268. }
  269. lpSqlNodeParameter = ToNode(lpstmt->lpSqlStmt, lpstmt->idxParameter);
  270. if (lpSqlNodeParameter->node.parameter.AtExec)
  271. break;
  272. lpstmt->idxParameter = lpSqlNodeParameter->node.parameter.Next;
  273. }
  274. /* Find the parameter definition (create by SQLBindParameter) */
  275. for (lpParameter = lpstmt->lpParameter;
  276. lpParameter != NULL;
  277. lpParameter = lpParameter->lpNext) {
  278. if (lpParameter->ipar == lpSqlNodeParameter->node.parameter.Id)
  279. break;
  280. }
  281. if (lpParameter == NULL) {
  282. lpstmt->errcode = ERR_INTERNAL;
  283. return SQL_ERROR;
  284. }
  285. /* Return rgbValue */
  286. if (prgbValue != NULL)
  287. *prgbValue = lpParameter->rgbValue;
  288. lpstmt->cbParameterOffset = -1;
  289. return SQL_NEED_DATA;
  290. }
  291. /***************************************************************************/
  292. RETCODE SQL_API SQLPutData(
  293. HSTMT hstmt,
  294. PTR rgbValue,
  295. SDWORD cbValue)
  296. {
  297. LPSTMT lpstmt;
  298. LPSQLNODE lpSqlNodeParameter;
  299. LPPARAMETER lpParameter;
  300. /* Get handle */
  301. lpstmt = (LPSTMT) hstmt;
  302. lpstmt->errcode = ERR_SUCCESS;
  303. //To make guarentee Ole is initialized per thread
  304. COleInitializationManager myOleManager;
  305. MyImpersonator im (lpstmt, "SQLPutData");
  306. /* Error if no parameter value needed */
  307. if (!(lpstmt->fNeedData) || (lpstmt->idxParameter == NO_SQLNODE)) {
  308. lpstmt->errcode = ERR_CURSORSTATE;
  309. return SQL_ERROR;
  310. }
  311. /* Find the parameter definition (create by SQLBindParameter) */
  312. lpSqlNodeParameter = ToNode(lpstmt->lpSqlStmt, lpstmt->idxParameter);
  313. for (lpParameter = lpstmt->lpParameter;
  314. lpParameter != NULL;
  315. lpParameter = lpParameter->lpNext) {
  316. if (lpParameter->ipar == lpSqlNodeParameter->node.parameter.Id)
  317. break;
  318. }
  319. if (lpParameter == NULL) {
  320. lpstmt->errcode = ERR_INTERNAL;
  321. return SQL_ERROR;
  322. }
  323. /* Save the value */
  324. if (lpstmt->cbParameterOffset == -1)
  325. lpstmt->cbParameterOffset = 0;
  326. lpstmt->errcode = SetParameterValue(lpstmt, lpSqlNodeParameter,
  327. &(lpstmt->cbParameterOffset),
  328. lpParameter->fCType, rgbValue,
  329. cbValue);
  330. if (lpstmt->errcode == ERR_DATATRUNCATED)
  331. return SQL_SUCCESS_WITH_INFO;
  332. else if (lpstmt->errcode != ERR_SUCCESS) {
  333. lpstmt->fNeedData = FALSE;
  334. lpstmt->idxParameter = NO_SQLNODE;
  335. return SQL_ERROR;
  336. }
  337. return SQL_SUCCESS;
  338. }
  339. /***************************************************************************/
  340. RETCODE SQL_API SQLCancel(
  341. HSTMT hstmt)
  342. {
  343. return SQLFreeStmt(hstmt, SQL_CLOSE);
  344. }
  345. /***************************************************************************/