Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : /*
14 : * This code was created by Peter Harvey (mostly during Christmas 98/99).
15 : * This code is LGPL. Please ensure that this message remains in future
16 : * distributions and uses of this code (thats about all I get out of it).
17 : * - Peter Harvey pharvey@codebydesign.com
18 : *
19 : * This file has been modified for the MonetDB project. See the file
20 : * Copyright in this directory for more information.
21 : */
22 :
23 : /**********************************************************************
24 : * SQLEndTran()
25 : * CLI Compliance: ISO 92
26 : *
27 : * Author: Martin van Dinther, Sjoerd Mullender
28 : * Date : 30 aug 2002
29 : *
30 : **********************************************************************/
31 :
32 : #include "ODBCGlobal.h"
33 : #include "ODBCEnv.h"
34 : #include "ODBCDbc.h"
35 : #include "ODBCStmt.h"
36 : #include "ODBCError.h"
37 :
38 :
39 : SQLRETURN
40 2 : MNDBEndTran(SQLSMALLINT HandleType,
41 : SQLHANDLE Handle,
42 : SQLSMALLINT CompletionType)
43 : {
44 2 : ODBCEnv *env = NULL;
45 2 : ODBCDbc *dbc = NULL;
46 2 : SQLHANDLE StatementHandle;
47 2 : RETCODE rc;
48 :
49 : /* check parameters HandleType and Handle for validity */
50 2 : switch (HandleType) {
51 2 : case SQL_HANDLE_DBC:
52 2 : dbc = (ODBCDbc *) Handle;
53 2 : if (!isValidDbc(dbc))
54 : return SQL_INVALID_HANDLE;
55 2 : clearDbcErrors(dbc);
56 2 : if (!dbc->Connected) {
57 : /* Connection does not exist */
58 0 : addDbcError(dbc, "08003", NULL, 0);
59 0 : return SQL_ERROR;
60 : }
61 : break;
62 0 : case SQL_HANDLE_ENV:
63 0 : env = (ODBCEnv *) Handle;
64 0 : if (!isValidEnv(env))
65 : return SQL_INVALID_HANDLE;
66 0 : clearEnvErrors(env);
67 0 : if (env->sql_attr_odbc_version == 0) {
68 : /* Function sequence error */
69 0 : addEnvError(env, "HY010", NULL, 0);
70 0 : return SQL_ERROR;
71 : }
72 : break;
73 0 : case SQL_HANDLE_STMT:
74 0 : if (isValidStmt((ODBCStmt *) Handle)) {
75 0 : clearStmtErrors((ODBCStmt *) Handle);
76 : /* Invalid attribute/option identifier */
77 0 : addStmtError((ODBCStmt *) Handle, "HY092", NULL, 0);
78 0 : return SQL_ERROR;
79 : }
80 : return SQL_INVALID_HANDLE;
81 0 : case SQL_HANDLE_DESC:
82 0 : if (isValidDesc((ODBCDesc *) Handle)) {
83 0 : clearDescErrors((ODBCDesc *) Handle);
84 : /* Invalid attribute/option identifier */
85 0 : addDescError((ODBCDesc *) Handle, "HY092", NULL, 0);
86 0 : return SQL_ERROR;
87 : }
88 : return SQL_INVALID_HANDLE;
89 : default:
90 : return SQL_INVALID_HANDLE;
91 : }
92 :
93 : /* check parameter CompletionType */
94 2 : if (CompletionType != SQL_COMMIT && CompletionType != SQL_ROLLBACK) {
95 : /* Invalid transaction operation code */
96 0 : if (HandleType == SQL_HANDLE_DBC)
97 0 : addDbcError(dbc, "HY012", NULL, 0);
98 : else
99 0 : addEnvError(env, "HY012", NULL, 0);
100 0 : return SQL_ERROR;
101 : }
102 :
103 2 : if (HandleType == SQL_HANDLE_ENV) {
104 0 : RETCODE rc1 = SQL_SUCCESS;
105 :
106 0 : for (dbc = env->FirstDbc; dbc; dbc = dbc->next) {
107 0 : assert(isValidDbc(dbc));
108 0 : if (!dbc->Connected)
109 0 : continue;
110 0 : rc = MNDBEndTran(SQL_HANDLE_DBC, dbc, CompletionType);
111 0 : if (rc == SQL_ERROR)
112 : rc1 = SQL_ERROR;
113 0 : else if (rc == SQL_SUCCESS_WITH_INFO &&
114 0 : rc1 != SQL_ERROR)
115 0 : rc1 = rc;
116 : }
117 0 : return rc1;
118 : }
119 :
120 2 : assert(HandleType == SQL_HANDLE_DBC);
121 :
122 2 : if (dbc->sql_attr_autocommit == SQL_AUTOCOMMIT_ON) {
123 : /* nothing to do if in autocommit mode */
124 : return SQL_SUCCESS;
125 : }
126 :
127 : /* construct a statement object and excute a SQL COMMIT or ROLLBACK */
128 2 : rc = MNDBAllocStmt(dbc, &StatementHandle);
129 2 : if (SQL_SUCCEEDED(rc)) {
130 2 : ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
131 3 : rc = MNDBExecDirect(stmt,
132 : CompletionType == SQL_COMMIT ? (SQLCHAR *) "commit" : (SQLCHAR *) "rollback",
133 : SQL_NTS);
134 :
135 2 : if (rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO) {
136 : /* get the error/warning and post in on the
137 : * dbc handle */
138 0 : SQLCHAR sqlState[SQL_SQLSTATE_SIZE + 1];
139 0 : SQLINTEGER nativeErrCode;
140 0 : SQLCHAR msgText[SQL_MAX_MESSAGE_LENGTH + 1];
141 :
142 0 : (void) MNDBGetDiagRec(SQL_HANDLE_STMT, stmt, 1,
143 : sqlState, &nativeErrCode,
144 : msgText, sizeof(msgText), NULL);
145 :
146 0 : addDbcError(dbc, (char *) sqlState,
147 : (char *) msgText + ODBCErrorMsgPrefixLength,
148 : nativeErrCode);
149 : }
150 : /* clean up the statement handle */
151 2 : ODBCResetStmt(stmt);
152 2 : ODBCFreeStmt_(stmt);
153 :
154 3 : for (stmt = dbc->FirstStmt; stmt; stmt = stmt->next)
155 1 : ODBCResetStmt(stmt);
156 : } else {
157 : /* could not allocate a statement object */
158 : /* Memory management error */
159 0 : addDbcError(dbc, "HY013", NULL, 0);
160 0 : return SQL_ERROR;
161 : }
162 :
163 : return rc;
164 : }
165 :
166 : SQLRETURN SQL_API
167 : SQLEndTran(SQLSMALLINT HandleType,
168 : SQLHANDLE Handle,
169 : SQLSMALLINT CompletionType)
170 : {
171 : #ifdef ODBCDEBUG
172 2 : ODBCLOG("SQLEndTran %s %p %s\n",
173 : HandleType == SQL_HANDLE_ENV ? "Env" : HandleType == SQL_HANDLE_DBC ? "Dbc" : HandleType == SQL_HANDLE_STMT ? "Stmt" : "Desc",
174 : Handle, translateCompletionType(CompletionType));
175 : #endif
176 :
177 2 : return MNDBEndTran(HandleType, Handle, CompletionType);
178 : }
|