]> git.saurik.com Git - wxWidgets.git/blame - src/iodbc/herr.c
reduce black background flicker a bit - there is still some left sometimes initially...
[wxWidgets.git] / src / iodbc / herr.c
CommitLineData
cd5bf2a6
RR
1/*
2 * herr.c
3 *
4 * $Id$
5 *
6 * Error stack management functions
7 *
8 * The iODBC driver manager.
9 *
10 * Copyright (C) 1995 by Ke Jin <kejin@empress.com>
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with this library; if not, write to the Free
24 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
88ac883a 27#include "config.h"
cd5bf2a6 28
88ac883a
VZ
29#include "isql.h"
30#include "isqlext.h"
cd5bf2a6 31
88ac883a 32#include "dlproc.h"
cd5bf2a6 33
88ac883a
VZ
34#include "herr.h"
35#include "henv.h"
36#include "hdbc.h"
37#include "hstmt.h"
cd5bf2a6 38
88ac883a 39#include "itrace.h"
cd5bf2a6
RR
40
41#include "herr.ci"
42
43static HERR
44_iodbcdm_popsqlerr (HERR herr)
1a6944fd 45{
cd5bf2a6
RR
46 sqlerr_t *list = (sqlerr_t *) herr;
47 sqlerr_t *next;
7e616b10 48
cd5bf2a6
RR
49 if (herr == SQL_NULL_HERR)
50 {
51 return herr;
52 }
1a6944fd 53
cd5bf2a6 54 next = list->next;
1a6944fd 55
cd5bf2a6 56 MEM_FREE (list);
1a6944fd 57
cd5bf2a6 58 return next;
1a6944fd
RR
59}
60
cd5bf2a6
RR
61
62void
63_iodbcdm_freesqlerrlist (HERR herrlist)
1a6944fd 64{
cd5bf2a6 65 HERR list;
1a6944fd 66
cd5bf2a6
RR
67 for (list = herrlist; list != 0;)
68 {
69 list = _iodbcdm_popsqlerr (list);
70 }
1a6944fd
RR
71}
72
cd5bf2a6
RR
73
74HERR
75_iodbcdm_pushsqlerr (
76 HERR herr,
77 sqlstcode_t code,
78 char *msg)
1a6944fd 79{
cd5bf2a6
RR
80 sqlerr_t *ebuf;
81 sqlerr_t *perr = (sqlerr_t *) herr;
82 int idx = 0;
7e616b10 83
cd5bf2a6
RR
84 if (herr != SQL_NULL_HERR)
85 {
86 idx = perr->idx + 1;
87 }
7e616b10 88
cd5bf2a6
RR
89 if (idx == 64)
90 /* over wirte the top entry to prevent error stack blow out */
91 {
92 perr->code = code;
93 perr->msg = msg;
7e616b10 94
cd5bf2a6
RR
95 return herr;
96 }
7e616b10 97
cd5bf2a6 98 ebuf = (sqlerr_t *) MEM_ALLOC (sizeof (sqlerr_t));
7e616b10 99
cd5bf2a6
RR
100 if (ebuf == NULL)
101 {
102 return NULL;
103 }
7e616b10 104
cd5bf2a6
RR
105 ebuf->msg = msg;
106 ebuf->code = code;
107 ebuf->idx = idx;
108 ebuf->next = (sqlerr_t *) herr;
7e616b10 109
cd5bf2a6 110 return (HERR) ebuf;
1a6944fd
RR
111}
112
cd5bf2a6
RR
113
114static char FAR *
115_iodbcdm_getsqlstate (
116 HERR herr,
117 void FAR * tab)
1a6944fd 118{
cd5bf2a6
RR
119 sqlerr_t *perr = (sqlerr_t *) herr;
120 sqlerrmsg_t *ptr;
121
122 if (herr == SQL_NULL_HERR || tab == NULL)
123 {
124 return (char FAR *) NULL;
125 }
126
127 for (ptr = tab;
128 ptr->code != en_sqlstat_total;
129 ptr++)
130 {
131 if (ptr->code == perr->code)
132 {
133 return (char FAR *) (ptr->stat);
134 }
135 }
136
137 return (char FAR *) NULL;
1a6944fd
RR
138}
139
cd5bf2a6
RR
140
141static char FAR *
142_iodbcdm_getsqlerrmsg (
143 HERR herr,
144 void FAR * errtab)
1a6944fd 145{
cd5bf2a6
RR
146 sqlerr_t *perr = (sqlerr_t *) herr;
147 sqlerrmsg_t *ptr;
148
149 if (herr == SQL_NULL_HERR)
150 {
151 return NULL;
152 }
153
154 if (perr->msg == NULL && errtab == NULL)
155 {
156 return NULL;
157 }
158
159 if (perr->msg != NULL)
160 {
161 return perr->msg;
162 }
163
164 for (ptr = (sqlerrmsg_t *) errtab;
165 ptr->code != en_sqlstat_total;
166 ptr++)
167 {
168 if (ptr->code == perr->code)
169 {
170 return (char FAR *) ptr->msg;
171 }
172 }
173
174 return (char FAR *) NULL;
1a6944fd
RR
175}
176
cd5bf2a6
RR
177
178RETCODE SQL_API
179SQLError (
180 HENV henv,
181 HDBC hdbc,
182 HSTMT hstmt,
183 UCHAR FAR * szSqlstate,
184 SDWORD FAR * pfNativeError,
185 UCHAR FAR * szErrorMsg,
186 SWORD cbErrorMsgMax,
187 SWORD FAR * pcbErrorMsg)
1a6944fd 188{
cd5bf2a6
RR
189 GENV_t FAR *genv = (GENV_t FAR *) henv;
190 DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
191 STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
192 HDBC thdbc;
193
194 HENV dhenv = SQL_NULL_HENV;
195 HDBC dhdbc = SQL_NULL_HDBC;
196 HSTMT dhstmt = SQL_NULL_HSTMT;
197
198 HERR herr = SQL_NULL_HERR;
199 HPROC hproc = SQL_NULL_HPROC;
200
201 char FAR *errmsg = NULL;
202 char FAR *ststr = NULL;
203
204 int handle = 0;
205 RETCODE retcode = SQL_SUCCESS;
206
207 if (hstmt != SQL_NULL_HSTMT) /* retrive stmt err */
208 {
209 herr = pstmt->herr;
210 thdbc = pstmt->hdbc;
211
212 if (thdbc == SQL_NULL_HDBC)
213 {
214 return SQL_INVALID_HANDLE;
215 }
216 hproc = _iodbcdm_getproc (thdbc, en_Error);
217 dhstmt = pstmt->dhstmt;
218 handle = 3;
219 }
220 else if (hdbc != SQL_NULL_HDBC) /* retrive dbc err */
221 {
222 herr = pdbc->herr;
223 thdbc = hdbc;
224 if (thdbc == SQL_NULL_HDBC)
225 {
226 return SQL_INVALID_HANDLE;
227 }
228 hproc = _iodbcdm_getproc (thdbc, en_Error);
229 dhdbc = pdbc->dhdbc;
230 handle = 2;
231
232 if (herr == SQL_NULL_HERR
233 && pdbc->henv == SQL_NULL_HENV)
234 {
235 return SQL_NO_DATA_FOUND;
236 }
237 }
238 else if (henv != SQL_NULL_HENV) /* retrive env err */
239 {
240 herr = genv->herr;
241
242 /* Drivers shouldn't push error message
243 * on envoriment handle */
244
245 if (herr == SQL_NULL_HERR)
246 {
247 return SQL_NO_DATA_FOUND;
248 }
249
250 handle = 1;
251 }
252 else
253 {
254 return SQL_INVALID_HANDLE;
255 }
256
257 if (szErrorMsg != NULL)
258 {
259 if (cbErrorMsgMax < 0
260 || cbErrorMsgMax > SQL_MAX_MESSAGE_LENGTH - 1)
261 {
262 return SQL_ERROR;
263 /* SQLError() doesn't post error for itself */
264 }
265 }
266
267 if (herr == SQL_NULL_HERR) /* no err on drv mng */
268 {
269 /* call driver */
270 if (hproc == SQL_NULL_HPROC)
271 {
272 PUSHSQLERR (herr, en_IM001);
273
274 return SQL_ERROR;
275 }
276
277 CALL_DRIVER (thdbc, retcode, hproc, en_Error,
278 (dhenv, dhdbc, dhstmt, szSqlstate, pfNativeError, szErrorMsg,
279 cbErrorMsgMax, pcbErrorMsg))
280
281 return retcode;
282 }
283
284 if (szSqlstate != NULL)
285 {
286 int len;
287
288 /* get sql state string */
289 ststr = (char FAR *) _iodbcdm_getsqlstate (herr,
290 (void FAR *) sqlerrmsg_tab);
291
292 if (ststr == NULL)
293 {
294 len = 0;
295 }
296 else
297 {
298 len = (int) STRLEN (ststr);
299 }
300
301 STRNCPY (szSqlstate, ststr, len);
302 szSqlstate[len] = 0;
303 /* buffer size of szSqlstate is not checked. Applications
304 * suppose provide enough ( not less than 6 bytes ) buffer
305 * or NULL for it.
306 */
307 }
308
309 if (pfNativeError != NULL)
310 {
311 /* native error code is specific to data source */
312 *pfNativeError = (SDWORD) 0L;
313 }
314
315 if (szErrorMsg == NULL || cbErrorMsgMax == 0)
316 {
317 if (pcbErrorMsg != NULL)
318 {
319 *pcbErrorMsg = (SWORD) 0;
320 }
321 }
322 else
323 {
324 int len;
325 char msgbuf[256] = {'\0'};
326
327 /* get sql state message */
328 errmsg = _iodbcdm_getsqlerrmsg (herr, (void FAR *) sqlerrmsg_tab);
329
330 if (errmsg == NULL)
331 {
332 errmsg = (char FAR *) "";
333 }
334
335 sprintf (msgbuf, "%s%s", sqlerrhd, errmsg);
336
337 len = STRLEN (msgbuf);
338
339 if (len < cbErrorMsgMax - 1)
340 {
341 retcode = SQL_SUCCESS;
342 }
343 else
344 {
345 len = cbErrorMsgMax - 1;
346 retcode = SQL_SUCCESS_WITH_INFO;
347 /* and not posts error for itself */
348 }
349
350 STRNCPY ((char *) szErrorMsg, msgbuf, len);
351 szErrorMsg[len] = 0;
352
353 if (pcbErrorMsg != NULL)
354 {
355 *pcbErrorMsg = (SWORD) len;
356 }
357 }
358
359 switch (handle) /* free this err */
360 {
361 case 1:
362 genv->herr = _iodbcdm_popsqlerr (genv->herr);
363 break;
364
365 case 2:
366 pdbc->herr = _iodbcdm_popsqlerr (pdbc->herr);
367 break;
368
369 case 3:
370 pstmt->herr = _iodbcdm_popsqlerr (pstmt->herr);
371 break;
372
373 default:
374 break;
375 }
376
377 return retcode;
1a6944fd 378}