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 (that's 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 : * SQLGetDiagRec()
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 : #include "ODBCUtil.h"
38 :
39 : SQLRETURN
40 77 : MNDBGetDiagRec(SQLSMALLINT HandleType,
41 : SQLHANDLE Handle,
42 : SQLSMALLINT RecNumber,
43 : SQLCHAR *SQLState,
44 : SQLINTEGER *NativeErrorPtr,
45 : SQLCHAR *MessageText,
46 : SQLSMALLINT BufferLength,
47 : SQLSMALLINT *TextLengthPtr)
48 : {
49 77 : ODBCError *err;
50 77 : ODBCDbc *dbc = NULL;
51 77 : char *msg;
52 77 : SQLSMALLINT msgLen;
53 :
54 77 : switch (HandleType) {
55 0 : case SQL_HANDLE_ENV:
56 : /* Check if this struct is still valid/alive */
57 0 : if (!isValidEnv((ODBCEnv *) Handle))
58 : return SQL_INVALID_HANDLE;
59 0 : err = getEnvError((ODBCEnv *) Handle);
60 0 : break;
61 22 : case SQL_HANDLE_DBC:
62 : /* Check if this struct is still valid/alive */
63 22 : dbc = (ODBCDbc *) Handle;
64 22 : if (!isValidDbc(dbc))
65 : return SQL_INVALID_HANDLE;
66 22 : err = getDbcError(dbc);
67 22 : break;
68 55 : case SQL_HANDLE_STMT:
69 : /* Check if this struct is still valid/alive */
70 55 : if (!isValidStmt((ODBCStmt *) Handle))
71 : return SQL_INVALID_HANDLE;
72 55 : err = getStmtError((ODBCStmt *) Handle);
73 55 : dbc = ((ODBCStmt *) Handle)->Dbc;
74 55 : break;
75 0 : case SQL_HANDLE_DESC:
76 : /* Check if this struct is still valid/alive */
77 0 : if (!isValidDesc((ODBCDesc *) Handle))
78 : return SQL_INVALID_HANDLE;
79 0 : err = getDescError((ODBCDesc *) Handle);
80 0 : dbc = ((ODBCDesc *) Handle)->Dbc;
81 0 : break;
82 : default:
83 : return SQL_INVALID_HANDLE;
84 : }
85 :
86 : /* Note: BufferLength may be 0 !! */
87 77 : if (BufferLength < 0)
88 : return SQL_ERROR;
89 :
90 77 : if (RecNumber <= 0)
91 : return SQL_ERROR;
92 :
93 77 : err = getErrorRec(err, RecNumber);
94 : /* Check the error object from the handle, it may be NULL when
95 : * no (more) errors are available
96 : */
97 77 : if (err == NULL)
98 : return SQL_NO_DATA;
99 :
100 : /* Now fill the output parameters where possible */
101 46 : if (SQLState) {
102 46 : char *state = getSqlState(err);
103 :
104 46 : assert(state);
105 : /* copy only the first SQL_SQLSTATE_SIZE (5) chars in
106 : * the buffer and make it null terminated
107 : */
108 46 : strcpy_len((char *) SQLState, state, SQL_SQLSTATE_SIZE + 1);
109 : }
110 :
111 46 : if (NativeErrorPtr)
112 46 : *NativeErrorPtr = getNativeErrorCode(err);
113 :
114 46 : msg = getMessage(err);
115 :
116 : /* first write the error message prefix text:
117 : * [MonetDB][ODBC driver VERSION][DSN]
118 : * this is required by the ODBC spec:
119 : * https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/diagnostic-messages
120 : * and used to determine where the error originated
121 : */
122 46 : if (dbc && dbc->dsn)
123 36 : msgLen = (SQLSMALLINT) strconcat_len((char *) MessageText, BufferLength, ODBCErrorMsgPrefix, "[", dbc->dsn, "]", msg, NULL);
124 : else
125 10 : msgLen = (SQLSMALLINT) strconcat_len((char *) MessageText, BufferLength, ODBCErrorMsgPrefix, msg, NULL);
126 :
127 46 : if (TextLengthPtr)
128 46 : *TextLengthPtr = msgLen;
129 :
130 46 : if (MessageText == NULL || msgLen >= BufferLength) {
131 : /* it didn't fit */
132 0 : return SQL_SUCCESS_WITH_INFO;
133 : }
134 : return SQL_SUCCESS;
135 : }
136 :
137 : SQLRETURN SQL_API
138 : SQLGetDiagRec(SQLSMALLINT HandleType,
139 : SQLHANDLE Handle,
140 : SQLSMALLINT RecNumber,
141 : SQLCHAR *SQLState,
142 : SQLINTEGER *NativeErrorPtr,
143 : SQLCHAR *MessageText,
144 : SQLSMALLINT BufferLength,
145 : SQLSMALLINT *TextLengthPtr)
146 : {
147 : #ifdef ODBCDEBUG
148 50 : ODBCLOG("SQLGetDiagRec %s %p %d %d\n",
149 : HandleType == SQL_HANDLE_ENV ? "Env" : HandleType == SQL_HANDLE_DBC ? "Dbc" : HandleType == SQL_HANDLE_STMT ? "Stmt" : "Desc",
150 : Handle, (int) RecNumber, (int) BufferLength);
151 : #endif
152 :
153 25 : return MNDBGetDiagRec(HandleType,
154 : Handle,
155 : RecNumber,
156 : SQLState,
157 : NativeErrorPtr,
158 : MessageText,
159 : BufferLength,
160 : TextLengthPtr);
161 : }
162 :
163 : SQLRETURN SQL_API
164 : SQLGetDiagRecA(SQLSMALLINT HandleType,
165 : SQLHANDLE Handle,
166 : SQLSMALLINT RecNumber,
167 : SQLCHAR *SQLState,
168 : SQLINTEGER *NativeErrorPtr,
169 : SQLCHAR *MessageText,
170 : SQLSMALLINT BufferLength,
171 : SQLSMALLINT *TextLengthPtr)
172 : {
173 0 : return SQLGetDiagRec(HandleType,
174 : Handle,
175 : RecNumber,
176 : SQLState,
177 : NativeErrorPtr,
178 : MessageText,
179 : BufferLength,
180 : TextLengthPtr);
181 : }
182 :
183 : SQLRETURN SQL_API
184 : SQLGetDiagRecW(SQLSMALLINT HandleType,
185 : SQLHANDLE Handle,
186 : SQLSMALLINT RecNumber,
187 : SQLWCHAR *SQLState,
188 : SQLINTEGER *NativeErrorPtr,
189 : SQLWCHAR *MessageText,
190 : SQLSMALLINT BufferLength,
191 : SQLSMALLINT *TextLengthPtr)
192 : {
193 36 : SQLRETURN rc;
194 36 : SQLCHAR state[6];
195 36 : SQLCHAR msg[512];
196 36 : SQLSMALLINT n;
197 :
198 : #ifdef ODBCDEBUG
199 72 : ODBCLOG("SQLGetDiagRecW %s %p %d %d\n",
200 : HandleType == SQL_HANDLE_ENV ? "Env" : HandleType == SQL_HANDLE_DBC ? "Dbc" : HandleType == SQL_HANDLE_STMT ? "Stmt" : "Desc",
201 : Handle, (int) RecNumber, (int) BufferLength);
202 : #endif
203 :
204 :
205 36 : rc = MNDBGetDiagRec(HandleType, Handle, RecNumber, state,
206 : NativeErrorPtr, msg, (SQLSMALLINT) sizeof(msg), &n);
207 : #ifdef ODBCDEBUG
208 36 : ODBCLOG("SQLGetDiagRecW: %s\n", SQL_SUCCEEDED(rc) ? (char *) msg : rc == SQL_NO_DATA ? "no error" : "failed");
209 : #endif
210 :
211 36 : if (SQL_SUCCEEDED(rc)) {
212 18 : const char *e = ODBCutf82wchar(state, 5, SQLState, 6, NULL,
213 : NULL);
214 :
215 18 : if (e)
216 : rc = SQL_ERROR;
217 : }
218 :
219 18 : if (SQL_SUCCEEDED(rc)) {
220 18 : const char *e = ODBCutf82wchar(msg, n, MessageText,
221 : BufferLength, &n, NULL);
222 :
223 18 : if (e)
224 0 : rc = SQL_ERROR;
225 18 : if (TextLengthPtr)
226 18 : *TextLengthPtr = n;
227 : }
228 :
229 36 : return rc;
230 : }
|