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