1/*********************************************************************
2 *
3 * This is based on code created by Peter Harvey,
4 * (pharvey@codebydesign.com).
5 *
6 * Modified and extended by Nick Gorham
7 * (nick@lurcher.org).
8 *
9 * Any bugs or problems should be considered the fault of Nick and not
10 * Peter.
11 *
12 * copyright (c) 1999 Nick Gorham
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 **********************************************************************
29 *
30 * $Id: __info.c,v 1.50 2009/02/18 17:59:08 lurcher Exp $
31 *
32 * $Log: __info.c,v $
33 * Revision 1.50 2009/02/18 17:59:08 lurcher
34 * Shift to using config.h, the compile lines were making it hard to spot warnings
35 *
36 * Revision 1.49 2009/02/17 09:47:44 lurcher
37 * Clear up a number of bugs
38 *
39 * Revision 1.48 2008/09/29 14:02:45 lurcher
40 * Fix missing dlfcn group option
41 *
42 * Revision 1.47 2008/01/02 15:10:33 lurcher
43 * Fix problems trying to use the cursor lib on a non select statement
44 *
45 * Revision 1.46 2007/11/26 11:37:23 lurcher
46 * Sync up before tag
47 *
48 * Revision 1.45 2007/09/28 13:20:22 lurcher
49 * Add timestamp to logging
50 *
51 * Revision 1.44 2007/04/02 10:50:19 lurcher
52 * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 )
53 *
54 * Revision 1.43 2007/03/05 09:49:24 lurcher
55 * Get it to build on VMS again
56 *
57 * Revision 1.42 2006/11/27 14:08:34 lurcher
58 * Sync up dirs
59 *
60 * Revision 1.41 2006/03/08 11:22:13 lurcher
61 * Add check for valid C_TYPE
62 *
63 * Revision 1.40 2005/12/19 18:43:26 lurcher
64 * Add new parts to contrib and alter how the errors are returned from the driver
65 *
66 * Revision 1.39 2005/11/08 09:37:10 lurcher
67 * Allow the driver and application to have different length handles
68 *
69 * Revision 1.38 2005/02/07 11:46:45 lurcher
70 * Add missing ODBC2 installer stubs
71 *
72 * Revision 1.37 2004/07/24 17:55:37 lurcher
73 * Sync up CVS
74 *
75 * Revision 1.36 2004/05/17 08:25:00 lurcher
76 * Update the way the libltso is used, and fix a problem with gODBCConfig
77 * not closeing correctly.
78 *
79 * Revision 1.35 2004/03/30 13:20:11 lurcher
80 *
81 *
82 * Fix problem with SQLCopyDesc
83 * Add additional target for iconv
84 *
85 * Revision 1.34 2003/12/01 16:37:17 lurcher
86 *
87 * Fix a bug in SQLWritePrivateProfileString
88 *
89 * Revision 1.33 2003/10/30 18:20:46 lurcher
90 *
91 * Fix broken thread protection
92 * Remove SQLNumResultCols after execute, lease S4/S% to driver
93 * Fix string overrun in SQLDriverConnect
94 * Add initial support for Interix
95 *
96 * Revision 1.32 2003/09/08 15:34:29 lurcher
97 *
98 * A couple of small but perfectly formed fixes
99 *
100 * Revision 1.31 2003/07/21 11:12:59 lurcher
101 *
102 * Fix corruption in Postgre7.1 driver
103 * Tidy up gODBCconfig
104 *
105 * Revision 1.30 2003/06/24 09:40:58 lurcher
106 *
107 * Extra UNICODE stuff
108 *
109 * Revision 1.29 2003/06/04 12:49:45 lurcher
110 *
111 * Further PID logging tweeks
112 *
113 * Revision 1.28 2003/06/03 13:52:13 lurcher
114 *
115 * Change the mode of PID logfiles to allow the process to change to another
116 * user
117 *
118 * Revision 1.27 2003/06/02 16:51:36 lurcher
119 *
120 * Add TracePid option
121 *
122 * Revision 1.26 2003/02/25 13:28:31 lurcher
123 *
124 * Allow errors on the drivers AllocHandle to be reported
125 * Fix a problem that caused errors to not be reported in the log
126 * Remove a redundant line from the spec file
127 *
128 * Revision 1.25 2003/02/06 12:58:25 lurcher
129 *
130 * Fix a speeling problem :-)
131 *
132 * Revision 1.24 2002/12/05 17:44:31 lurcher
133 *
134 * Display unknown return values in return logging
135 *
136 * Revision 1.23 2002/11/11 17:10:20 lurcher
137 *
138 * VMS changes
139 *
140 * Revision 1.22 2002/11/06 16:08:01 lurcher
141 *
142 * Update missing
143 *
144 * Revision 1.21 2002/08/23 09:42:37 lurcher
145 *
146 * Fix some build warnings with casts, and a AIX linker mod, to include
147 * deplib's on the link line, but not the libtool generated ones
148 *
149 * Revision 1.20 2002/08/20 12:41:07 lurcher
150 *
151 * Fix incorrect return state from SQLEndTran/SQLTransact
152 *
153 * Revision 1.19 2002/08/19 09:11:49 lurcher
154 *
155 * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state
156 *
157 * Revision 1.18 2002/08/15 08:10:33 lurcher
158 *
159 * Couple of small fixes from John L Miller
160 *
161 * Revision 1.17 2002/08/12 16:20:44 lurcher
162 *
163 * Make it try and find a working iconv set of encodings
164 *
165 * Revision 1.16 2002/08/12 13:17:52 lurcher
166 *
167 * Replicate the way the MS DM handles loading of driver libs, and allocating
168 * handles in the driver. usage counting in the driver means that dlopen is
169 * only called for the first use, and dlclose for the last. AllocHandle for
170 * the driver environment is only called for the first time per driver
171 * per application environment.
172 *
173 * Revision 1.15 2002/07/25 09:30:26 lurcher
174 *
175 * Additional unicode and iconv changes
176 *
177 * Revision 1.14 2002/07/24 08:49:52 lurcher
178 *
179 * Alter UNICODE support to use iconv for UNICODE-ANSI conversion
180 *
181 * Revision 1.13 2002/07/10 15:05:57 lurcher
182 *
183 * Alter the return code in the Postgres driver, for a warning, it should be
184 * 01000 it was 00000
185 * Fix a problem in DriverManagerII with the postgres driver as the driver
186 * doesn't return a propper list of schemas
187 * Allow the delimiter to be set in isql to a hex/octal char not just a
188 * printable one
189 *
190 * Revision 1.12 2002/07/08 16:37:35 lurcher
191 *
192 * Fix bug in unicode_to_ansi_copy
193 *
194 * Revision 1.11 2002/07/04 17:27:56 lurcher
195 *
196 * Small bug fixes
197 *
198 * Revision 1.9 2002/05/28 13:30:34 lurcher
199 *
200 * Tidy up for AIX
201 *
202 * Revision 1.8 2002/05/21 14:19:44 lurcher
203 *
204 * * Update libtool to escape from AIX build problem
205 * * Add fix to avoid file handle limitations
206 * * Add more UNICODE changes, it looks like it is native 16 representation
207 * the old way can be reproduced by defining UCS16BE
208 * * Add iusql, its just the same as isql but uses the wide functions
209 *
210 * Revision 1.7 2002/04/10 11:04:36 lurcher
211 *
212 * Fix endian issue with 4 byte unicode support
213 *
214 * Revision 1.6 2002/02/27 11:27:14 lurcher
215 *
216 * Fix bug in error reporting
217 *
218 * Revision 1.5 2002/01/21 18:00:51 lurcher
219 *
220 * Assorted fixed and changes, mainly UNICODE/bug fixes
221 *
222 * Revision 1.4 2001/12/13 13:56:31 lurcher
223 *
224 * init a global for Peter
225 *
226 * Revision 1.3 2001/12/13 13:00:32 lurcher
227 *
228 * Remove most if not all warnings on 64 bit platforms
229 * Add support for new MS 3.52 64 bit changes
230 * Add override to disable the stopping of tracing
231 * Add MAX_ROWS support in postgres driver
232 *
233 * Revision 1.2 2001/11/15 18:38:21 lurcher
234 *
235 * Make the errors returned from SQLError reset after each API call
236 * if the app is expecting ODBC 3 operation
237 *
238 * Revision 1.1.1.1 2001/10/17 16:40:09 lurcher
239 *
240 * First upload to SourceForge
241 *
242 * Revision 1.23 2001/09/27 17:05:48 nick
243 *
244 * Assorted fixes and tweeks
245 *
246 * Revision 1.22 2001/07/03 09:30:41 nick
247 *
248 * Add ability to alter size of displayed message in the log
249 *
250 * Revision 1.21 2001/07/02 17:09:37 nick
251 *
252 * Add some portability changes
253 *
254 * Revision 1.20 2001/06/20 17:25:32 pat
255 * Correct msg1 length in 4 extract diag functions
256 *
257 * Revision 1.19 2001/06/20 08:19:25 nick
258 *
259 * Fix buffer overflow in error handling
260 *
261 * Revision 1.18 2001/04/23 13:58:43 nick
262 *
263 * Assorted tweeks to text driver to get it to work with StarOffice
264 *
265 * Revision 1.17 2001/04/20 16:57:25 nick
266 *
267 * Add extra mapping of data types
268 *
269 * Revision 1.16 2001/04/18 15:03:37 nick
270 *
271 * Fix problem when going to DB2 unicode driver
272 *
273 * Revision 1.15 2001/04/16 22:35:10 nick
274 *
275 * More tweeks to the AutoTest code
276 *
277 * Revision 1.14 2001/04/14 10:42:03 nick
278 *
279 * Extra work on the autotest feature of odbctest
280 *
281 * Revision 1.13 2001/04/12 17:43:36 nick
282 *
283 * Change logging and added autotest to odbctest
284 *
285 * Revision 1.12 2001/04/03 16:34:12 nick
286 *
287 * Add support for strangly broken unicode drivers
288 *
289 * Revision 1.11 2001/01/09 23:15:18 nick
290 *
291 * More unicode error fixes
292 *
293 * Revision 1.10 2001/01/09 22:33:13 nick
294 *
295 * Stop passing NULL into SQLExtendedFetch
296 * Further fixes to unicode to ansi conversions
297 *
298 * Revision 1.9 2001/01/09 11:03:32 nick
299 *
300 * Fixed overrun bug
301 *
302 * Revision 1.8 2001/01/06 15:00:12 nick
303 *
304 * Fix bug in SQLError introduced with UNICODE
305 *
306 * Revision 1.7 2000/12/31 20:30:54 nick
307 *
308 * Add UNICODE support
309 *
310 * Revision 1.6 2000/10/25 12:45:51 nick
311 *
312 * Add mapping for both ODBC 2 - 3 and ODBC 3 - 2 error states
313 *
314 * Revision 1.5 2000/10/25 12:32:41 nick
315 *
316 * The mapping was the wrong way around for errors, ODBC3 error are mapped
317 * to ODBC 2 not the other way around
318 *
319 * Revision 1.4 2000/10/25 09:13:26 nick
320 *
321 * Remove some invalid ODBC2-ODBC3 error mappings
322 *
323 * Revision 1.3 2000/10/13 15:18:49 nick
324 *
325 * Change string length parameter from SQLINTEGER to SQLSMALLINT
326 *
327 * Revision 1.2 2000/09/19 13:13:13 nick
328 *
329 * Add display of returned error text in log file
330 *
331 * Revision 1.1.1.1 2000/09/04 16:42:52 nick
332 * Imported Sources
333 *
334 * Revision 1.28 2000/07/31 08:46:11 ngorham
335 *
336 * Avoid potential buffer overrun
337 *
338 * Revision 1.27 2000/06/23 16:11:38 ngorham
339 *
340 * Map ODBC 2 SQLSTATE values to ODBC 3
341 *
342 * Revision 1.25 2000/06/21 11:07:36 ngorham
343 *
344 * Stop Errors from SQLAllocHandle being lost
345 *
346 * Revision 1.24 2000/06/20 12:44:01 ngorham
347 *
348 * Fix bug that caused a success with info message from SQLExecute or
349 * SQLExecDirect to be lost if used with a ODBC 3 driver and the application
350 * called SQLGetDiagRec
351 *
352 * Revision 1.23 2000/06/01 11:00:51 ngorham
353 *
354 * return errors from descriptor functions
355 *
356 * Revision 1.22 2001/05/31 23:24:20 ngorham
357 *
358 * Update timestamps
359 *
360 * Revision 1.21 2000/05/21 21:49:19 ngorham
361 *
362 * Assorted fixes
363 *
364 * Revision 1.20 2001/04/11 09:00:05 ngorham
365 *
366 * remove stray printf
367 *
368 * Revision 1.19 2001/04/01 00:06:50 ngorham
369 *
370 * Dont use stderr, if the log file fails to open.
371 *
372 * Revision 1.18 2000/03/14 07:45:35 ngorham
373 *
374 * Fix bug that discarded connection errors
375 *
376 * Revision 1.17 2000/01/18 17:24:50 ngorham
377 *
378 * Add missing [unixODBC] prefix in front of error messages.
379 *
380 * Revision 1.16 1999/12/14 19:02:25 ngorham
381 *
382 * Mask out the password fields in the logging
383 *
384 * Revision 1.15 1999/12/04 17:01:23 ngorham
385 *
386 * Remove C++ comments from the Postgres code
387 *
388 * Revision 1.14 1999/12/01 09:20:07 ngorham
389 *
390 * Fix some threading problems
391 *
392 * Revision 1.13 1999/11/17 21:08:58 ngorham
393 *
394 * Fix Bug with the ODBC 3 error handling
395 *
396 * Revision 1.12 1999/11/13 23:41:01 ngorham
397 *
398 * Alter the way DM logging works
399 * Upgrade the Postgres driver to 6.4.6
400 *
401 * Revision 1.11 1999/11/10 22:15:48 ngorham
402 *
403 * Fix some bugs with the DM and error reporting.
404 *
405 * Revision 1.10 1999/11/10 03:51:34 ngorham
406 *
407 * Update the error reporting in the DM to enable ODBC 3 and 2 calls to
408 * work at the same time
409 *
410 * Revision 1.9 1999/10/24 23:54:19 ngorham
411 *
412 * First part of the changes to the error reporting
413 *
414 * Revision 1.8 1999/10/03 23:05:16 ngorham
415 *
416 * First public outing of the cursor lib
417 *
418 * Revision 1.7 1999/09/19 22:24:34 ngorham
419 *
420 * Added support for the cursor library
421 *
422 * Revision 1.6 1999/08/03 21:47:39 shandyb
423 * Moving to automake: changed files in DriverManager
424 *
425 * Revision 1.5 1999/07/10 21:10:17 ngorham
426 *
427 * Adjust error sqlstate from driver manager, depending on requested
428 * version (ODBC2/3)
429 *
430 * Revision 1.4 1999/07/05 19:54:05 ngorham
431 *
432 * Fix a problem where a long string could crash the DM
433 *
434 * Revision 1.3 1999/07/04 21:05:08 ngorham
435 *
436 * Add LGPL Headers to code
437 *
438 * Revision 1.2 1999/06/19 17:51:41 ngorham
439 *
440 * Applied assorted minor bug fixes
441 *
442 * Revision 1.1.1.1 1999/05/29 13:41:09 sShandyb
443 * first go at it
444 *
445 * Revision 1.2 1999/06/03 22:20:25 ngorham
446 *
447 * Finished off the ODBC3-2 mapping
448 *
449 * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey
450 * Imported sources
451 *
452 *
453 *
454 **********************************************************************/
455
456#include <config.h>
457#include <sys/types.h>
458#include <sys/stat.h>
459#include <unistd.h>
460
461#if defined( HAVE_GETTIMEOFDAY ) && defined( HAVE_SYS_TIME_H )
462#include <sys/time.h>
463#elif defined( HAVE_FTIME ) && defined( HAVE_SYS_TIMEB_H )
464#include <sys/timeb.h>
465#elif defined( DHAVE_TIME ) && defined( HAVE_TIME_H )
466#include <time.h>
467#endif
468
469#ifdef HAVE_LANGINFO_H
470#include <langinfo.h>
471#endif
472
473#include "drivermanager.h"
474
475static char const rcsid[]= "$RCSfile: __info.c,v $ $Revision: 1.50 $";
476
477struct log_structure log_info = { NULL, NULL, 0 };
478
479SQLINTEGER ODBCSharedTraceFlag = 0;
480
481/*
482 * unicode setup functions, do them on a connection basis.
483 */
484
485int unicode_setup( DMHDBC connection )
486{
487#ifdef HAVE_ICONV
488 char ascii[ 256 ], unicode[ 256 ];
489 char *be_ucode[] = { "UCS-2-INTERNAL", "UCS-2BE", "UCS-2", "ucs2", NULL };
490 char *le_ucode[] = { "UCS-2-INTERNAL", "UCS-2LE", NULL };
491 char *asc[] = { "char", "char", "ISO8859-1", "ISO-8859-1", "8859-1", "iso8859_1", "ASCII", NULL };
492 union { long l; char c[sizeof (long)]; } u;
493 int be;
494
495 if ( connection -> iconv_cd_uc_to_ascii != (iconv_t)(-1) &&
496 connection -> iconv_cd_ascii_to_uc != (iconv_t)(-1))
497 {
498 return 1;
499 }
500
501 /*
502 * is this a bigendian machine ?
503 */
504
505 u.l = 1;
506 be = (u.c[sizeof (long) - 1] == 1);
507
508 mutex_iconv_entry();
509
510#if defined( HAVE_NL_LANGINFO ) && defined(HAVE_LANGINFO_CODESET)
511 /*
512 * Try with current locale settings first
513 */
514 asc[ 0 ] = nl_langinfo(CODESET);
515#endif
516
517 /*
518 * if required find a match
519 */
520
521 if ( strcmp( ASCII_ENCODING, "auto-search" ) == 0 && strcmp( connection -> unicode_string, "auto-search" ) == 0 )
522 {
523 /*
524 * look for both
525 */
526 int i, j, found;
527 iconv_t icvt;
528
529 ascii[ 0 ] = '\0';
530 unicode[ 0 ] = '\0';
531
532 for ( i = found = 0; ( be ? be_ucode[ i ] : le_ucode[ i ] ) != NULL && !found; i ++ )
533 {
534 for ( j = 0; asc[ j ] && !found; j ++ )
535 {
536 if (( icvt = iconv_open( asc[ j ], be ? be_ucode[ i ] : le_ucode[ i ] )) != ((iconv_t) -1 ) )
537 {
538 strcpy( ascii, asc[ j ] );
539 strcpy( unicode, be ? be_ucode[ i ] : le_ucode[ i ] );
540 iconv_close( icvt );
541 found = 1;
542 }
543 }
544 }
545 }
546 else if ( strcmp( ASCII_ENCODING, "auto-search" ) == 0 )
547 {
548 /*
549 * look for ascii
550 */
551 int j;
552 iconv_t icvt;
553
554 strcpy( unicode, connection -> unicode_string );
555
556 for ( j = 0; asc[ j ]; j ++ )
557 {
558 if (( icvt = iconv_open( asc[ j ], unicode )) != ((iconv_t) -1 ) )
559 {
560 strcpy( ascii, asc[ j ] );
561 iconv_close( icvt );
562 break;
563 }
564 }
565 }
566 else if ( strcmp( connection -> unicode_string, "auto-search" ) == 0 )
567 {
568 /*
569 * look for unicode
570 */
571 int i;
572 iconv_t icvt;
573
574 strcpy( ascii, ASCII_ENCODING );
575
576 for ( i = 0; be ? be_ucode[ i ] : le_ucode[ i ]; i ++ )
577 {
578 if (( icvt = iconv_open( ascii, be ? be_ucode[ i ] : le_ucode[ i ] )) != ((iconv_t) -1 ) )
579 {
580 strcpy( unicode, be ? be_ucode[ i ] : le_ucode[ i ] );
581 iconv_close( icvt );
582 break;
583 }
584 }
585 }
586 else
587 {
588 strcpy( ascii, ASCII_ENCODING );
589 strcpy( unicode, connection -> unicode_string );
590 }
591
592 if ( log_info.log_flag )
593 {
594 sprintf( connection -> msg, "\t\tUNICODE Using encoding ASCII '%s' and UNICODE '%s'",
595 ascii, unicode );
596
597 dm_log_write_diag( connection -> msg );
598 }
599
600 connection -> iconv_cd_uc_to_ascii = iconv_open( ascii, unicode );
601 connection -> iconv_cd_ascii_to_uc = iconv_open( unicode, ascii );
602
603 mutex_iconv_exit();
604
605 if ( connection -> iconv_cd_uc_to_ascii == (iconv_t)(-1) ||
606 connection -> iconv_cd_ascii_to_uc == (iconv_t)(-1))
607 {
608 return 0;
609 }
610 else
611 {
612 return 1;
613 }
614
615#else
616 return 1;
617#endif
618}
619
620void unicode_shutdown( DMHDBC connection )
621{
622#ifdef HAVE_ICONV
623 mutex_iconv_entry();
624
625 if ( connection -> iconv_cd_ascii_to_uc != (iconv_t)(-1) )
626 {
627 iconv_close( connection -> iconv_cd_ascii_to_uc );
628 }
629
630 if ( connection -> iconv_cd_uc_to_ascii != (iconv_t)(-1))
631 {
632 iconv_close( connection -> iconv_cd_uc_to_ascii );
633 }
634
635 connection -> iconv_cd_uc_to_ascii = (iconv_t)(-1);
636 connection -> iconv_cd_ascii_to_uc = (iconv_t)(-1);
637
638 mutex_iconv_exit();
639#endif
640}
641
642/*
643 * returned a malloc'd buffer in unicode converted from the ansi buffer
644 */
645
646SQLWCHAR *ansi_to_unicode_alloc( SQLCHAR *str, SQLINTEGER len, DMHDBC connection, int *wlen )
647{
648 SQLWCHAR *ustr;
649
650 if ( wlen )
651 {
652 *wlen = len;
653 }
654
655 if( !str )
656 {
657 return NULL;
658 }
659
660 if ( len == SQL_NTS )
661 {
662 len = strlen((char*) str );
663 }
664
665 ustr = malloc( sizeof( SQLWCHAR ) * ( len + 1 ));
666 if ( !ustr )
667 {
668 return NULL;
669 }
670
671 return ansi_to_unicode_copy( ustr, (char*) str, len, connection, wlen );
672}
673
674/*
675 * return a ansi representation of a unicode buffer, according to
676 * the chosen conversion method
677 */
678
679char *unicode_to_ansi_alloc( SQLWCHAR *str, SQLINTEGER len, DMHDBC connection, int *clen )
680{
681 char *aptr;
682
683 if ( clen )
684 {
685 *clen = len;
686 }
687
688 if ( !str )
689 {
690 return NULL;
691 }
692
693 if ( len == SQL_NTS )
694 {
695 len = wide_strlen( str ) + 1;
696 }
697
698 aptr = malloc(( len * 4 ) + 1 ); /* There may be UTF8 */
699 if ( !aptr )
700 {
701 return NULL;
702 }
703
704 return unicode_to_ansi_copy( aptr, len * 4, str, len, connection, clen );
705}
706
707/*
708 * copy from a unicode buffer to a ansi buffer using the chosen conversion
709 */
710
711char *unicode_to_ansi_copy( char * dest, int dest_len, SQLWCHAR *src, SQLINTEGER buffer_len, DMHDBC connection, int *clen )
712{
713 int i;
714
715 if ( !src || !dest )
716 {
717 return NULL;
718 }
719
720 if ( buffer_len == SQL_NTS )
721 {
722 buffer_len = wide_strlen( src );
723 }
724#ifdef HAVE_ICONV
725
726 mutex_iconv_entry();
727
728 if ( connection && connection -> iconv_cd_uc_to_ascii != (iconv_t)(-1))
729 {
730 size_t ret;
731 size_t inbl = buffer_len * sizeof( SQLWCHAR );
732 size_t obl = dest_len;
733 char *ipt = (char*)src;
734 char *opt = (char*)dest;
735
736 if (( ret = iconv( connection -> iconv_cd_uc_to_ascii,
737 (ICONV_CONST char**)&ipt, &inbl,
738 &opt, &obl )) != (size_t)(-1))
739 {
740 mutex_iconv_exit();
741
742 if ( clen )
743 {
744 *clen = opt - dest;
745 }
746 /* Null terminate outside of iconv, so that the length returned does not include the null terminator. */
747 if ( obl )
748 {
749 *opt = '\0';
750 }
751 return dest;
752 }
753 }
754
755 mutex_iconv_exit();
756
757#endif
758
759 for ( i = 0; i < buffer_len && i < dest_len && src[ i ] != 0; i ++ )
760 {
761#ifdef SQL_WCHART_CONVERT
762 dest[ i ] = (char)(src[ i ] & 0x000000ff);
763#else
764 dest[ i ] = src[ i ] & 0x00FF;
765#endif
766 }
767
768 if ( clen )
769 {
770 *clen = i;
771 }
772
773 if (dest_len)
774 {
775 dest[ i < dest_len ? i : i-1 ] = '\0';
776 }
777
778 return dest;
779}
780
781/*
782 * copy from a ansi buffer to a unicode buffer using the chosen conversion
783 */
784
785SQLWCHAR *ansi_to_unicode_copy( SQLWCHAR * dest, char *src, SQLINTEGER buffer_len, DMHDBC connection, int *wlen )
786{
787 int i;
788
789 if ( !src || !dest )
790 {
791 return NULL;
792 }
793
794 if ( buffer_len == SQL_NTS )
795 {
796 buffer_len = strlen( src );
797 }
798
799#ifdef HAVE_ICONV
800
801 if ( connection && connection -> iconv_cd_ascii_to_uc != (iconv_t)(-1))
802 {
803 size_t inbl = buffer_len;
804 size_t obl = buffer_len * sizeof( SQLWCHAR );
805 char *ipt = (char*)src;
806 char *opt = (char*)dest;
807
808 mutex_iconv_entry();
809
810 if ( iconv( connection -> iconv_cd_ascii_to_uc,
811 (ICONV_CONST char**)&ipt, &inbl,
812 &opt, &obl ) != (size_t)(-1))
813 {
814 mutex_iconv_exit();
815
816 if ( wlen )
817 {
818 *wlen = ( opt - ((char*)dest)) / sizeof( SQLWCHAR );
819 }
820 /* Null terminate outside of iconv, so that the length returned does not include the null terminator. */
821 dest[( opt - ((char*)dest)) / sizeof( SQLWCHAR )] = 0;
822 return dest;
823 }
824
825 mutex_iconv_exit();
826 }
827
828#endif
829
830 for ( i = 0; i < buffer_len && src[ i ] != 0; i ++ )
831 {
832#ifdef SQL_WCHART_CONVERT
833 dest[ i ] = src[ i ] & 0x000000ff;
834#else
835 dest[ i ] = src[ i ] & 0x00FF;
836#endif
837 }
838
839 if ( wlen )
840 {
841 *wlen = i;
842 }
843
844 dest[ i ] = 0;
845
846
847 return dest;
848}
849
850
851/*
852 * display a SQLGetTypeInfo type as a astring
853 */
854
855char * __type_as_string( SQLCHAR *s, SQLSMALLINT type )
856{
857 switch( type )
858 {
859 case SQL_DOUBLE:
860 sprintf((char*) s, "SQL_DOUBLE" );
861 break;
862
863 case SQL_FLOAT:
864 sprintf((char*) s, "SQL_FLOAT" );
865 break;
866
867 case SQL_REAL:
868 sprintf((char*) s, "SQL_REAL" );
869 break;
870
871 case SQL_BIT:
872 sprintf((char*) s, "SQL_BIT" );
873 break;
874
875 case SQL_CHAR:
876 sprintf((char*) s, "SQL_CHAR" );
877 break;
878
879 case SQL_VARCHAR:
880 sprintf((char*) s, "SQL_VARCHAR" );
881 break;
882
883 case SQL_LONGVARCHAR:
884 sprintf((char*) s, "SQL_LONGVARCHAR" );
885 break;
886
887 case SQL_BINARY:
888 sprintf((char*) s, "SQL_BINARY" );
889 break;
890
891 case SQL_VARBINARY:
892 sprintf((char*) s, "SQL_VARBINARY" );
893 break;
894
895 case SQL_LONGVARBINARY:
896 sprintf((char*) s, "SQL_LONGVARBINARY" );
897 break;
898
899 case SQL_DECIMAL:
900 sprintf((char*) s, "SQL_DECIMAL" );
901 break;
902
903 case SQL_NUMERIC:
904 sprintf((char*) s, "SQL_NUMERIC" );
905 break;
906
907 case SQL_BIGINT:
908 sprintf((char*) s, "SQL_BIGINT" );
909 break;
910
911 case SQL_INTEGER:
912 sprintf((char*) s, "SQL_INTEGER" );
913 break;
914
915 case SQL_SMALLINT:
916 sprintf((char*) s, "SQL_SMALLINT" );
917 break;
918
919 case SQL_TINYINT:
920 sprintf((char*) s, "SQL_TINYINT" );
921 break;
922
923 case SQL_TYPE_DATE:
924 sprintf((char*) s, "SQL_TYPE_DATE" );
925 break;
926
927 case SQL_TYPE_TIME:
928 sprintf((char*) s, "SQL_TYPE_TIME" );
929 break;
930
931 case SQL_TYPE_TIMESTAMP:
932 sprintf((char*) s, "SQL_TYPE_TIMESTAMP" );
933 break;
934
935 case SQL_DATE:
936 sprintf((char*) s, "SQL_DATE" );
937 break;
938
939 case SQL_TIME:
940 sprintf((char*) s, "SQL_TIME" );
941 break;
942
943 case SQL_TIMESTAMP:
944 sprintf((char*) s, "SQL_TIMESTAMP" );
945 break;
946
947 case SQL_INTERVAL_YEAR:
948 sprintf((char*) s, "SQL_INTERVAL_YEAR" );
949 break;
950
951 case SQL_INTERVAL_YEAR_TO_MONTH:
952 sprintf((char*) s, "SQL_INTERVAL_YEAR_TO_MONTH" );
953 break;
954
955 case SQL_INTERVAL_MONTH:
956 sprintf((char*) s, "SQL_INTERVAL_MONTH" );
957 break;
958
959 case SQL_INTERVAL_DAY_TO_SECOND:
960 sprintf((char*) s, "SQL_INTERVAL_DAY_TO_SECOND" );
961 break;
962
963 case SQL_INTERVAL_DAY_TO_MINUTE:
964 sprintf((char*) s, "SQL_INTERVAL_DAY_TO_MINUTE" );
965 break;
966
967 case SQL_INTERVAL_DAY:
968 sprintf((char*) s, "SQL_INTERVAL_DAY" );
969 break;
970
971 case SQL_INTERVAL_HOUR_TO_SECOND:
972 sprintf((char*) s, "SQL_INTERVAL_HOUR_TO_SECOND" );
973 break;
974
975 case SQL_INTERVAL_HOUR_TO_MINUTE:
976 sprintf((char*) s, "SQL_INTERVAL_HOUR_TO_MINUTE" );
977 break;
978
979 case SQL_INTERVAL_HOUR:
980 sprintf((char*) s, "SQL_INTERVAL_HOUR" );
981 break;
982
983 case SQL_INTERVAL_MINUTE_TO_SECOND:
984 sprintf((char*) s, "SQL_INTERVAL_MINUTE_TO_SECOND" );
985 break;
986
987 case SQL_INTERVAL_MINUTE:
988 sprintf((char*) s, "SQL_INTERVAL_MINUTE" );
989 break;
990
991 case SQL_INTERVAL_SECOND:
992 sprintf((char*) s, "SQL_INTERVAL_SECOND" );
993 break;
994
995 case SQL_ALL_TYPES:
996 sprintf((char*) s, "SQL_ALL_TYPES" );
997 break;
998
999 default:
1000 sprintf((char*) s, "Unknown(%d)", (int)type );
1001 break;
1002 }
1003
1004 return (char*) s;
1005}
1006
1007/*
1008 * display a data field as a string
1009 */
1010
1011char * __sdata_as_string( SQLCHAR *s, SQLINTEGER type,
1012 SQLSMALLINT *ptr, SQLPOINTER buf )
1013{
1014 SQLLEN iptr;
1015
1016 if ( ptr )
1017 {
1018 iptr = *ptr;
1019 return __data_as_string( s, type, &iptr, buf );
1020 }
1021 else
1022 {
1023 return __data_as_string( s, type, NULL, buf );
1024 }
1025
1026 return (char*) s;
1027}
1028
1029char * __idata_as_string( SQLCHAR *s, SQLINTEGER type,
1030 SQLINTEGER *ptr, SQLPOINTER buf )
1031{
1032 SQLLEN iptr;
1033
1034 if ( ptr )
1035 {
1036 iptr = *ptr;
1037 return __data_as_string( s, type, &iptr, buf );
1038 }
1039 else
1040 {
1041 return __data_as_string( s, type, NULL, buf );
1042 }
1043
1044 return (char*) s;
1045}
1046
1047char * __data_as_string( SQLCHAR *s, SQLINTEGER type,
1048 SQLLEN *ptr, SQLPOINTER buf )
1049{
1050 if ( ptr && *ptr == SQL_NULL_DATA )
1051 {
1052 sprintf((char*) s, "SQL_NULL_DATA" );
1053 }
1054 else if ( ptr && *ptr < 0 )
1055 {
1056 sprintf((char*) s, "Indicator = %d", (int)*ptr );
1057 }
1058 else if ( !buf )
1059 {
1060 sprintf((char*) s, "[NULLPTR]" );
1061 }
1062 else
1063 {
1064 switch ( type )
1065 {
1066 case SQL_INTEGER:
1067 {
1068 SQLINTEGER val;
1069
1070 memcpy( &val, buf, sizeof( SQLINTEGER ));
1071 sprintf((char*) s, "[%d]", (int)val );
1072 }
1073 break;
1074
1075 case SQL_CHAR:
1076 case SQL_VARCHAR:
1077 sprintf((char*) s, "[%.*s]", LOG_MESSAGE_LEN, (char*)buf );
1078 break;
1079
1080 case SQL_WCHAR:
1081 case SQL_WVARCHAR:
1082 {
1083 int len = LOG_MESSAGE_LEN;
1084 signed short *ptr = (signed short*)buf;
1085 char *optr;
1086
1087 optr = (char*) s;
1088 sprintf((char*) s, "[" );
1089
1090 optr ++;
1091
1092 while( len > 0 )
1093 {
1094 if ( *ptr == 0x0000 )
1095 break;
1096 sprintf( optr, "%c", *ptr & 0x00FF );
1097 optr ++;
1098 len --;
1099 ptr ++;
1100 }
1101 sprintf( optr, "](unicode)" );
1102 }
1103 break;
1104
1105 case SQL_DOUBLE:
1106 {
1107 double val;
1108
1109 memcpy( &val, buf, sizeof( double ));
1110 sprintf((char*) s, "[%g]", val );
1111 }
1112 break;
1113
1114 case SQL_FLOAT:
1115 case SQL_REAL:
1116 {
1117 float val;
1118
1119 memcpy( &val, buf, sizeof( float ));
1120 sprintf((char*) s, "[%g]", val );
1121 }
1122 break;
1123
1124 case SQL_BIT:
1125 {
1126 SQLCHAR val;
1127
1128 memcpy( &val, buf, sizeof( SQLCHAR ));
1129 sprintf((char*) s, "[%d]", (int)val );
1130 }
1131 break;
1132
1133 case SQL_LONGVARCHAR:
1134 sprintf((char*) s, "[LONGVARCHARDATA...]" );
1135 break;
1136
1137 case SQL_BINARY:
1138 sprintf((char*) s, "[BINARYDATA...]" );
1139 break;
1140
1141 case SQL_VARBINARY:
1142 sprintf((char*) s, "[VARBINARYDATA...]" );
1143 break;
1144
1145 case SQL_LONGVARBINARY:
1146 sprintf((char*) s, "[LONGVARBINARYDATA...]" );
1147 break;
1148
1149 case SQL_DECIMAL:
1150 sprintf((char*) s, "[DECIMAL...]" );
1151 break;
1152
1153 case SQL_NUMERIC:
1154 sprintf((char*) s, "[NUMERIC...]" );
1155 break;
1156
1157 case SQL_BIGINT:
1158 sprintf((char*) s, "[BIGINT...]" );
1159 break;
1160
1161 case SQL_SMALLINT:
1162 {
1163 short val;
1164
1165 memcpy( &val, buf, sizeof( short ));
1166 sprintf((char*) s, "[%d]", (int)val );
1167 }
1168 break;
1169
1170 case SQL_TINYINT:
1171 {
1172 char val;
1173
1174 memcpy( &val, buf, sizeof( char ));
1175 sprintf((char*) s, "[%d]", (int)val );
1176 }
1177 break;
1178
1179 case SQL_TYPE_DATE:
1180 case SQL_DATE:
1181 sprintf((char*) s, "[DATE...]" );
1182 break;
1183
1184 case SQL_TYPE_TIME:
1185 case SQL_TIME:
1186 sprintf((char*) s, "[TIME...]" );
1187 break;
1188
1189 case SQL_TYPE_TIMESTAMP:
1190 case SQL_TIMESTAMP:
1191 sprintf((char*) s, "[TIMESTAMP...]" );
1192 break;
1193
1194 case SQL_INTERVAL_YEAR:
1195 case SQL_INTERVAL_YEAR_TO_MONTH:
1196 case SQL_INTERVAL_MONTH:
1197 case SQL_INTERVAL_DAY_TO_SECOND:
1198 case SQL_INTERVAL_DAY_TO_MINUTE:
1199 case SQL_INTERVAL_DAY:
1200 case SQL_INTERVAL_HOUR_TO_SECOND:
1201 case SQL_INTERVAL_HOUR_TO_MINUTE:
1202 case SQL_INTERVAL_HOUR:
1203 case SQL_INTERVAL_MINUTE_TO_SECOND:
1204 case SQL_INTERVAL_MINUTE:
1205 case SQL_INTERVAL_SECOND:
1206 sprintf((char*) s, "[INTERVAL...]" );
1207 break;
1208
1209 default:
1210 sprintf((char*) s, "[Data...]" );
1211 break;
1212 }
1213 }
1214
1215 return (char*) s;
1216}
1217
1218/*
1219 * display a pointer to a int
1220 */
1221
1222char * __iptr_as_string( SQLCHAR *s, SQLINTEGER *ptr )
1223{
1224 if ( ptr )
1225 {
1226 sprintf((char*) s, "%p -> %d", (void*)ptr, (int)*ptr );
1227 }
1228 else
1229 {
1230 sprintf((char*) s, "NULLPTR" );
1231 }
1232
1233 return (char*) s;
1234}
1235
1236char * __ptr_as_string( SQLCHAR *s, SQLLEN *ptr )
1237{
1238 if ( ptr )
1239 {
1240 sprintf((char*) s, "%p -> %d", (void*)ptr, (int)*ptr );
1241 }
1242 else
1243 {
1244 sprintf((char*) s, "NULLPTR" );
1245 }
1246
1247 return (char*) s;
1248}
1249
1250/*
1251 * display a pointer to a int
1252 */
1253
1254char * __sptr_as_string( SQLCHAR *s, SQLSMALLINT *ptr )
1255{
1256 if ( ptr )
1257 {
1258 sprintf((char*) s, "%p -> %d", (void*)ptr, (int)*ptr );
1259 }
1260 else
1261 {
1262 sprintf((char*) s, "NULLPTR" );
1263 }
1264
1265 return (char*) s;
1266}
1267
1268/*
1269 * convert a function id to a string
1270 */
1271
1272char * __fid_as_string( SQLCHAR *s, SQLINTEGER type )
1273{
1274 switch( type )
1275 {
1276 case SQL_API_SQLALLOCCONNECT:
1277 sprintf((char*) s, "SQLAllocConnect" );
1278 break;
1279
1280 case SQL_API_SQLALLOCENV:
1281 sprintf((char*) s, "SQLAllocEnv" );
1282 break;
1283
1284 case SQL_API_SQLALLOCHANDLE:
1285 sprintf((char*) s, "SQLAllocHandle" );
1286 break;
1287
1288 case SQL_API_SQLALLOCSTMT:
1289 sprintf((char*) s, "SQLAllocStmt" );
1290 break;
1291
1292 case SQL_API_SQLALLOCHANDLESTD:
1293 sprintf((char*) s, "SQLAllochandleStd" );
1294 break;
1295
1296 case SQL_API_SQLBINDCOL:
1297 sprintf((char*) s, "SQLBindCol" );
1298 break;
1299
1300 case SQL_API_SQLBINDPARAM:
1301 sprintf((char*) s, "SQLBindParam" );
1302 break;
1303
1304 case SQL_API_SQLBINDPARAMETER:
1305 sprintf((char*) s, "SQLBindParameter" );
1306 break;
1307
1308 case SQL_API_SQLBROWSECONNECT:
1309 sprintf((char*) s, "SQLBrowseConnect" );
1310 break;
1311
1312 case SQL_API_SQLBULKOPERATIONS:
1313 sprintf((char*) s, "SQLBulkOperations" );
1314 break;
1315
1316 case SQL_API_SQLCANCEL:
1317 sprintf((char*) s, "SQLCancel" );
1318 break;
1319
1320 case SQL_API_SQLCLOSECURSOR:
1321 sprintf((char*) s, "SQLCloseCursor" );
1322 break;
1323
1324 case SQL_API_SQLCOLATTRIBUTES:
1325 sprintf((char*) s, "SQLColAttribute(s)" );
1326 break;
1327
1328 case SQL_API_SQLCOLUMNPRIVILEGES:
1329 sprintf((char*) s, "SQLColumnPrivileges" );
1330 break;
1331
1332 case SQL_API_SQLCOLUMNS:
1333 sprintf((char*) s, "SQLColumns" );
1334 break;
1335
1336 case SQL_API_SQLCONNECT:
1337 sprintf((char*) s, "SQLConnect" );
1338 break;
1339
1340 case SQL_API_SQLCOPYDESC:
1341 sprintf((char*) s, "SQLCopyDesc" );
1342 break;
1343
1344 case SQL_API_SQLDATASOURCES:
1345 sprintf((char*) s, "SQLDataSources" );
1346 break;
1347
1348 case SQL_API_SQLDESCRIBECOL:
1349 sprintf((char*) s, "SQLDescribeCol" );
1350 break;
1351
1352 case SQL_API_SQLDESCRIBEPARAM:
1353 sprintf((char*) s, "SQLDescribeParam" );
1354 break;
1355
1356 case SQL_API_SQLDISCONNECT:
1357 sprintf((char*) s, "SQLDisconnect" );
1358 break;
1359
1360 case SQL_API_SQLDRIVERCONNECT:
1361 sprintf((char*) s, "SQLDriverConnect" );
1362 break;
1363
1364 case SQL_API_SQLDRIVERS:
1365 sprintf((char*) s, "SQLDrivers" );
1366 break;
1367
1368 case SQL_API_SQLENDTRAN:
1369 sprintf((char*) s, "SQLEndTran" );
1370 break;
1371
1372 case SQL_API_SQLERROR:
1373 sprintf((char*) s, "SQLError" );
1374 break;
1375
1376 case SQL_API_SQLEXECDIRECT:
1377 sprintf((char*) s, "SQLExecDirect" );
1378 break;
1379
1380 case SQL_API_SQLEXECUTE:
1381 sprintf((char*) s, "SQLExecute" );
1382 break;
1383
1384 case SQL_API_SQLEXTENDEDFETCH:
1385 sprintf((char*) s, "SQLExtendedFetch" );
1386 break;
1387
1388 case SQL_API_SQLFETCH:
1389 sprintf((char*) s, "SQLFetch" );
1390 break;
1391
1392 case SQL_API_SQLFETCHSCROLL:
1393 sprintf((char*) s, "SQLFetchScroll" );
1394 break;
1395
1396 case SQL_API_SQLFOREIGNKEYS:
1397 sprintf((char*) s, "SQLForeignKeys" );
1398 break;
1399
1400 case SQL_API_SQLFREEENV:
1401 sprintf((char*) s, "SQLFreeEnv" );
1402 break;
1403
1404 case SQL_API_SQLFREEHANDLE:
1405 sprintf((char*) s, "SQLFreeHandle" );
1406 break;
1407
1408 case SQL_API_SQLFREESTMT:
1409 sprintf((char*) s, "SQLFreeStmt" );
1410 break;
1411
1412 case SQL_API_SQLFREECONNECT:
1413 sprintf((char*) s, "SQLFreeConnect" );
1414 break;
1415
1416 case SQL_API_SQLGETCONNECTATTR:
1417 sprintf((char*) s, "SQLGetConnectAttr" );
1418 break;
1419
1420 case SQL_API_SQLGETCONNECTOPTION:
1421 sprintf((char*) s, "SQLGetConnectOption" );
1422 break;
1423
1424 case SQL_API_SQLGETCURSORNAME:
1425 sprintf((char*) s, "SQLGetCursorName" );
1426 break;
1427
1428 case SQL_API_SQLGETDATA:
1429 sprintf((char*) s, "SQLGetData" );
1430 break;
1431
1432 case SQL_API_SQLGETDESCFIELD:
1433 sprintf((char*) s, "SQLGetDescField" );
1434 break;
1435
1436 case SQL_API_SQLGETDESCREC:
1437 sprintf((char*) s, "SQLGetDescRec" );
1438 break;
1439
1440 case SQL_API_SQLGETDIAGFIELD:
1441 sprintf((char*) s, "SQLGetDiagField" );
1442 break;
1443
1444 case SQL_API_SQLGETENVATTR:
1445 sprintf((char*) s, "SQLGetEnvAttr" );
1446 break;
1447
1448 case SQL_API_SQLGETFUNCTIONS:
1449 sprintf((char*) s, "SQLGetFunctions" );
1450 break;
1451
1452 case SQL_API_SQLGETINFO:
1453 sprintf((char*) s, "SQLGetInfo" );
1454 break;
1455
1456 case SQL_API_SQLGETSTMTATTR:
1457 sprintf((char*) s, "SQLGetStmtAttr" );
1458 break;
1459
1460 case SQL_API_SQLGETSTMTOPTION:
1461 sprintf((char*) s, "SQLGetStmtOption" );
1462 break;
1463
1464 case SQL_API_SQLGETTYPEINFO:
1465 sprintf((char*) s, "SQLGetTypeInfo" );
1466 break;
1467
1468 case SQL_API_SQLMORERESULTS:
1469 sprintf((char*) s, "SQLMoreResults" );
1470 break;
1471
1472 case SQL_API_SQLNATIVESQL:
1473 sprintf((char*) s, "SQLNativeSql" );
1474 break;
1475
1476 case SQL_API_SQLNUMPARAMS:
1477 sprintf((char*) s, "SQLNumParams" );
1478 break;
1479
1480 case SQL_API_SQLNUMRESULTCOLS:
1481 sprintf((char*) s, "SQLNumResultCols" );
1482 break;
1483
1484 case SQL_API_SQLPARAMDATA:
1485 sprintf((char*) s, "SQLParamData" );
1486 break;
1487
1488 case SQL_API_SQLPARAMOPTIONS:
1489 sprintf((char*) s, "SQLParamOptions" );
1490 break;
1491
1492 case SQL_API_SQLPREPARE:
1493 sprintf((char*) s, "SQLPrepare" );
1494 break;
1495
1496 case SQL_API_SQLPRIMARYKEYS:
1497 sprintf((char*) s, "SQLPrimaryKeys" );
1498 break;
1499
1500 case SQL_API_SQLPROCEDURECOLUMNS:
1501 sprintf((char*) s, "SQLProcedureColumns" );
1502 break;
1503
1504 case SQL_API_SQLPROCEDURES:
1505 sprintf((char*) s, "SQLProcedures" );
1506 break;
1507
1508 case SQL_API_SQLPUTDATA:
1509 sprintf((char*) s, "SQLPutData" );
1510 break;
1511
1512 case SQL_API_SQLROWCOUNT:
1513 sprintf((char*) s, "SQLRowCount" );
1514 break;
1515
1516 case SQL_API_SQLSETCONNECTATTR:
1517 sprintf((char*) s, "SQLSetConnectAttr" );
1518 break;
1519
1520 case SQL_API_SQLSETCONNECTOPTION:
1521 sprintf((char*) s, "SQLSetConnectOption" );
1522 break;
1523
1524 case SQL_API_SQLSETCURSORNAME:
1525 sprintf((char*) s, "SQLSetCursorName" );
1526 break;
1527
1528 case SQL_API_SQLSETDESCFIELD:
1529 sprintf((char*) s, "SQLSetDescField" );
1530 break;
1531
1532 case SQL_API_SQLSETDESCREC:
1533 sprintf((char*) s, "SQLSetDescRec" );
1534 break;
1535
1536 case SQL_API_SQLSETENVATTR:
1537 sprintf((char*) s, "SQLSetEnvAttr" );
1538 break;
1539
1540 case SQL_API_SQLSETPARAM:
1541 sprintf((char*) s, "SQLSetParam" );
1542 break;
1543
1544 case SQL_API_SQLSETPOS:
1545 sprintf((char*) s, "SQLSetPos" );
1546 break;
1547
1548 case SQL_API_SQLSETSCROLLOPTIONS:
1549 sprintf((char*) s, "SQLSetScrollOptions" );
1550 break;
1551
1552 case SQL_API_SQLSETSTMTATTR:
1553 sprintf((char*) s, "SQLSetStmtAttr" );
1554 break;
1555
1556 case SQL_API_SQLSETSTMTOPTION:
1557 sprintf((char*) s, "SQLSetStmtOption" );
1558 break;
1559
1560 case SQL_API_SQLSPECIALCOLUMNS:
1561 sprintf((char*) s, "SQLSpecialColumns" );
1562 break;
1563
1564 case SQL_API_SQLSTATISTICS:
1565 sprintf((char*) s, "SQLStatistics" );
1566 break;
1567
1568 case SQL_API_SQLTABLEPRIVILEGES:
1569 sprintf((char*) s, "SQLTablePrivileges" );
1570 break;
1571
1572 case SQL_API_SQLTABLES:
1573 sprintf((char*) s, "SQLTables" );
1574 break;
1575
1576 case SQL_API_SQLTRANSACT:
1577 sprintf((char*) s, "SQLTransact" );
1578 break;
1579
1580 case SQL_API_SQLGETDIAGREC:
1581 sprintf((char*) s, "SQLGetDiagRec" );
1582 break;
1583
1584 default:
1585 sprintf((char*) s, "%d", (int)type );
1586 }
1587
1588 return (char*) s;
1589}
1590
1591/*
1592 * convert a column attribute to a string
1593 */
1594
1595char * __col_attr_as_string( SQLCHAR *s, SQLINTEGER type )
1596{
1597 switch( type )
1598 {
1599 case SQL_DESC_AUTO_UNIQUE_VALUE:
1600 sprintf((char*) s, "SQL_DESC_AUTO_UNIQUE_VALUE" );
1601 break;
1602
1603 case SQL_DESC_BASE_COLUMN_NAME:
1604 sprintf((char*) s, "SQL_DESC_BASE_COLUMN_NAME" );
1605 break;
1606
1607 case SQL_DESC_BASE_TABLE_NAME:
1608 sprintf((char*) s, "SQL_DESC_BASE_TABLE_NAME" );
1609 break;
1610
1611 case SQL_DESC_CASE_SENSITIVE:
1612 sprintf((char*) s, "SQL_DESC_CASE_SENSITIVE" );
1613 break;
1614
1615 case SQL_DESC_CATALOG_NAME:
1616 sprintf((char*) s, "SQL_DESC_CATALOG_NAME" );
1617 break;
1618
1619 case SQL_DESC_CONCISE_TYPE:
1620 sprintf((char*) s, "SQL_DESC_CONCISE_TYPE" );
1621 break;
1622
1623 case SQL_DESC_DISPLAY_SIZE:
1624 sprintf((char*) s, "SQL_DESC_DISPLAY_SIZE" );
1625 break;
1626
1627 case SQL_DESC_FIXED_PREC_SCALE:
1628 sprintf((char*) s, "SQL_DESC_FIXED_PREC_SCALE" );
1629 break;
1630
1631 case SQL_DESC_LABEL:
1632 sprintf((char*) s, "SQL_DESC_LABEL" );
1633 break;
1634
1635 case SQL_COLUMN_NAME:
1636 sprintf((char*) s, "SQL_COLUMN_NAME" );
1637 break;
1638
1639 case SQL_DESC_LENGTH:
1640 sprintf((char*) s, "SQL_DESC_LENGTH" );
1641 break;
1642
1643 case SQL_COLUMN_LENGTH:
1644 sprintf((char*) s, "SQL_COLUMN_LENGTH" );
1645 break;
1646
1647 case SQL_DESC_LITERAL_PREFIX:
1648 sprintf((char*) s, "SQL_DESC_LITERAL_PREFIX" );
1649 break;
1650
1651 case SQL_DESC_LITERAL_SUFFIX:
1652 sprintf((char*) s, "SQL_DESC_LITERAL_SUFFIX" );
1653 break;
1654
1655 case SQL_DESC_LOCAL_TYPE_NAME:
1656 sprintf((char*) s, "SQL_DESC_LOCAL_TYPE_NAME" );
1657 break;
1658
1659 case SQL_DESC_NAME:
1660 sprintf((char*) s, "SQL_DESC_NAME" );
1661 break;
1662
1663 case SQL_DESC_NULLABLE:
1664 sprintf((char*) s, "SQL_DESC_NULLABLE" );
1665 break;
1666
1667 case SQL_COLUMN_NULLABLE:
1668 sprintf((char*) s, "SQL_COLUMN_NULLABLE" );
1669 break;
1670
1671 case SQL_DESC_NUM_PREC_RADIX:
1672 sprintf((char*) s, "SQL_DESC_NUM_PREC_RADIX" );
1673 break;
1674
1675 case SQL_DESC_OCTET_LENGTH:
1676 sprintf((char*) s, "SQL_DESC_OCTET_LENGTH" );
1677 break;
1678
1679 case SQL_DESC_PRECISION:
1680 sprintf((char*) s, "SQL_DESC_PRECISION" );
1681 break;
1682
1683 case SQL_COLUMN_PRECISION:
1684 sprintf((char*) s, "SQL_COLUMN_PRECISION" );
1685 break;
1686
1687 case SQL_DESC_SCALE:
1688 sprintf((char*) s, "SQL_DESC_SCALE" );
1689 break;
1690
1691 case SQL_COLUMN_SCALE:
1692 sprintf((char*) s, "SQL_COLUMN_SCALE" );
1693 break;
1694
1695 case SQL_DESC_SCHEMA_NAME:
1696 sprintf((char*) s, "SQL_DESC_SCHEMA_NAME" );
1697 break;
1698
1699 case SQL_DESC_SEARCHABLE:
1700 sprintf((char*) s, "SQL_DESC_SEARCHABLE" );
1701 break;
1702
1703 case SQL_DESC_TABLE_NAME:
1704 sprintf((char*) s, "SQL_DESC_TABLE_NAME" );
1705 break;
1706
1707 case SQL_DESC_TYPE:
1708 sprintf((char*) s, "SQL_DESC_TYPE" );
1709 break;
1710
1711 case SQL_DESC_TYPE_NAME:
1712 sprintf((char*) s, "SQL_DESC_TYPE_NAME" );
1713 break;
1714
1715 case SQL_DESC_UNNAMED:
1716 sprintf((char*) s, "SQL_DESC_UNNAMED" );
1717 break;
1718
1719 case SQL_DESC_UNSIGNED:
1720 sprintf((char*) s, "SQL_DESC_UNSIGNED" );
1721 break;
1722
1723 case SQL_DESC_UPDATABLE:
1724 sprintf((char*) s, "SQL_DESC_UPDATABLE" );
1725 break;
1726
1727 default:
1728 sprintf((char*) s, "%d", (int)type );
1729 }
1730
1731 return (char*) s;
1732}
1733
1734/*
1735 * convert a connect attribute to a string
1736 */
1737
1738char * __env_attr_as_string( SQLCHAR *s, SQLINTEGER type )
1739{
1740 switch( type )
1741 {
1742 case SQL_ATTR_CONNECTION_POOLING:
1743 sprintf((char*) s, "SQL_ATTR_CONNECTION_POOLING" );
1744 break;
1745
1746 case SQL_ATTR_CP_MATCH:
1747 sprintf((char*) s, "SQL_ATTR_CP_MATCH" );
1748 break;
1749
1750 case SQL_ATTR_ODBC_VERSION:
1751 sprintf((char*) s, "SQL_ATTR_ODBC_VERSION" );
1752 break;
1753
1754 case SQL_ATTR_OUTPUT_NTS:
1755 sprintf((char*) s, "SQL_ATTR_OUTPUT_NTS" );
1756 break;
1757
1758 default:
1759 sprintf((char*) s, "%d", (int)type );
1760 }
1761
1762 return (char*) s;
1763}
1764
1765/*
1766 * convert a connect attribute to a string
1767 */
1768
1769char * __con_attr_as_string( SQLCHAR *s, SQLINTEGER type )
1770{
1771 switch( type )
1772 {
1773 case SQL_ATTR_ACCESS_MODE:
1774 sprintf((char*) s, "SQL_ATTR_ACCESS_MODE" );
1775 break;
1776
1777 case SQL_ATTR_ASYNC_ENABLE:
1778 sprintf((char*) s, "SQL_ATTR_ASYNC_ENABLE" );
1779 break;
1780
1781 case SQL_ATTR_AUTO_IPD:
1782 sprintf((char*) s, "SQL_ATTR_AUTO_IPD" );
1783 break;
1784
1785 case SQL_ATTR_AUTOCOMMIT:
1786 sprintf((char*) s, "SQL_ATTR_AUTOCOMMIT" );
1787 break;
1788
1789 case SQL_ATTR_CONNECTION_TIMEOUT:
1790 sprintf((char*) s, "SQL_ATTR_CONNECTION_TIMEOUT" );
1791 break;
1792
1793 case SQL_ATTR_CURRENT_CATALOG:
1794 sprintf((char*) s, "SQL_ATTR_CURRENT_CATALOG" );
1795 break;
1796
1797 case SQL_ATTR_LOGIN_TIMEOUT:
1798 sprintf((char*) s, "SQL_ATTR_LOGIN_TIMEOUT" );
1799 break;
1800
1801 case SQL_ATTR_METADATA_ID:
1802 sprintf((char*) s, "SQL_ATTR_METADATA_ID" );
1803 break;
1804
1805 case SQL_ATTR_ODBC_CURSORS:
1806 sprintf((char*) s, "SQL_ATTR_ODBC_CURSORS" );
1807 break;
1808
1809 case SQL_ATTR_PACKET_SIZE:
1810 sprintf((char*) s, "SQL_ATTR_PACKET_SIZE" );
1811 break;
1812
1813 case SQL_ATTR_QUIET_MODE:
1814 sprintf((char*) s, "SQL_ATTR_QUIET_MODE" );
1815 break;
1816
1817 case SQL_ATTR_TRACE:
1818 sprintf((char*) s, "SQL_ATTR_TRACE" );
1819 break;
1820
1821 case SQL_ATTR_TRACEFILE:
1822 sprintf((char*) s, "SQL_ATTR_TRACEFILE" );
1823 break;
1824
1825 case SQL_ATTR_TRANSLATE_LIB:
1826 sprintf((char*) s, "SQL_ATTR_TRANSLATE_LIB" );
1827 break;
1828
1829 case SQL_ATTR_TRANSLATE_OPTION:
1830 sprintf((char*) s, "SQL_ATTR_TRANSLATE_OPTION" );
1831 break;
1832
1833 case SQL_ATTR_TXN_ISOLATION:
1834 sprintf((char*) s, "SQL_ATTR_TXN_ISOLATION" );
1835 break;
1836
1837 default:
1838 sprintf((char*) s, "%d", (int)type );
1839 }
1840
1841 return (char*) s;
1842}
1843
1844/*
1845 * convert a diagnostic attribute to a string
1846 */
1847
1848char * __diag_attr_as_string( SQLCHAR *s, SQLINTEGER type )
1849{
1850 switch( type )
1851 {
1852 case SQL_DIAG_CURSOR_ROW_COUNT:
1853 sprintf((char*) s, "SQL_DIAG_CURSOR_ROW_COUNT" );
1854 break;
1855
1856 case SQL_DIAG_DYNAMIC_FUNCTION:
1857 sprintf((char*) s, "SQL_DIAG_DYNAMIC_FUNCTION" );
1858 break;
1859
1860 case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
1861 sprintf((char*) s, "SQL_DIAG_DYNAMIC_FUNCTION_CODE" );
1862 break;
1863
1864 case SQL_DIAG_NUMBER:
1865 sprintf((char*) s, "SQL_DIAG_NUMBER" );
1866 break;
1867
1868 case SQL_DIAG_RETURNCODE:
1869 sprintf((char*) s, "SQL_DIAG_RETURNCODE" );
1870 break;
1871
1872 case SQL_DIAG_ROW_COUNT:
1873 sprintf((char*) s, "SQL_DIAG_ROW_COUNT" );
1874 break;
1875
1876 case SQL_DIAG_CLASS_ORIGIN:
1877 sprintf((char*) s, "SQL_DIAG_CLASS_ORIGIN" );
1878 break;
1879
1880 case SQL_DIAG_COLUMN_NUMBER:
1881 sprintf((char*) s, "SQL_DIAG_COLUMN_NUMBER" );
1882 break;
1883
1884 case SQL_DIAG_CONNECTION_NAME:
1885 sprintf((char*) s, "SQL_DIAG_CONNECTION_NAME" );
1886 break;
1887
1888 case SQL_DIAG_MESSAGE_TEXT:
1889 sprintf((char*) s, "SQL_DIAG_MESSAGE_TEXT" );
1890 break;
1891
1892 case SQL_DIAG_NATIVE:
1893 sprintf((char*) s, "SQL_DIAG_NATIVE" );
1894 break;
1895
1896 case SQL_DIAG_ROW_NUMBER:
1897 sprintf((char*) s, "SQL_DIAG_ROW_NUMBER" );
1898 break;
1899
1900 case SQL_DIAG_SERVER_NAME:
1901 sprintf((char*) s, "SQL_DIAG_SERVER_NAME" );
1902 break;
1903
1904 case SQL_DIAG_SQLSTATE:
1905 sprintf((char*) s, "SQL_DIAG_SQLSTATE" );
1906 break;
1907
1908 case SQL_DIAG_SUBCLASS_ORIGIN:
1909 sprintf((char*) s, "SQL_DIAG_SUBCLASS_ORIGIN" );
1910 break;
1911
1912 default:
1913 sprintf((char*) s, "%d", (int)type );
1914 }
1915
1916 return (char*) s;
1917}
1918
1919/*
1920 * convert a descriptor attribute to a string
1921 */
1922
1923char * __desc_attr_as_string( SQLCHAR *s, SQLINTEGER type )
1924{
1925 switch( type )
1926 {
1927 case SQL_DESC_ALLOC_TYPE:
1928 sprintf((char*) s, "SQL_DESC_ALLOC_TYPE" );
1929 break;
1930
1931 case SQL_DESC_ARRAY_SIZE:
1932 sprintf((char*) s, "SQL_DESC_ARRAY_SIZE" );
1933 break;
1934
1935 case SQL_DESC_ARRAY_STATUS_PTR:
1936 sprintf((char*) s, "SQL_DESC_ARRAY_STATUS_PTR" );
1937 break;
1938
1939 case SQL_DESC_BIND_OFFSET_PTR:
1940 sprintf((char*) s, "SQL_DESC_BIND_OFFSET_PTR" );
1941 break;
1942
1943 case SQL_DESC_BIND_TYPE:
1944 sprintf((char*) s, "SQL_DESC_BIND_TYPE" );
1945 break;
1946
1947 case SQL_DESC_COUNT:
1948 sprintf((char*) s, "SQL_DESC_COUNT" );
1949 break;
1950
1951 case SQL_DESC_ROWS_PROCESSED_PTR:
1952 sprintf((char*) s, "SQL_DESC_ROWS_PROCESSED_PTR" );
1953 break;
1954
1955 case SQL_DESC_AUTO_UNIQUE_VALUE:
1956 sprintf((char*) s, "SQL_DESC_AUTO_UNIQUE_VALUE" );
1957 break;
1958
1959 case SQL_DESC_BASE_COLUMN_NAME:
1960 sprintf((char*) s, "SQL_DESC_BASE_COLUMN_NAME" );
1961 break;
1962
1963 case SQL_DESC_BASE_TABLE_NAME:
1964 sprintf((char*) s, "SQL_DESC_BASE_TABLE_NAME" );
1965 break;
1966
1967 case SQL_DESC_CASE_SENSITIVE:
1968 sprintf((char*) s, "SQL_DESC_CASE_SENSITIVE" );
1969 break;
1970
1971 case SQL_DESC_CATALOG_NAME:
1972 sprintf((char*) s, "SQL_DESC_CATALOG_NAME" );
1973 break;
1974
1975 case SQL_DESC_CONCISE_TYPE:
1976 sprintf((char*) s, "SQL_DESC_CONCISE_TYPE" );
1977 break;
1978
1979 case SQL_DESC_DATA_PTR:
1980 sprintf((char*) s, "SQL_DESC_DATA_PTR" );
1981 break;
1982
1983 case SQL_DESC_DATETIME_INTERVAL_CODE:
1984 sprintf((char*) s, "SQL_DESC_DATETIME_INTERVAL_CODE" );
1985 break;
1986
1987 case SQL_DESC_DATETIME_INTERVAL_PRECISION:
1988 sprintf((char*) s, "SQL_DESC_DATETIME_INTERVAL_PRECISION" );
1989 break;
1990
1991 case SQL_DESC_DISPLAY_SIZE:
1992 sprintf((char*) s, "SQL_DESC_DISPLAY_SIZE" );
1993 break;
1994
1995 case SQL_DESC_FIXED_PREC_SCALE:
1996 sprintf((char*) s, "SQL_DESC_FIXED_PREC_SCALE" );
1997 break;
1998
1999 case SQL_DESC_INDICATOR_PTR:
2000 sprintf((char*) s, "SQL_DESC_INDICATOR_PTR" );
2001 break;
2002
2003 case SQL_DESC_LABEL:
2004 sprintf((char*) s, "SQL_DESC_LABEL" );
2005 break;
2006
2007 case SQL_DESC_LENGTH:
2008 sprintf((char*) s, "SQL_DESC_LENGTH" );
2009 break;
2010
2011 case SQL_DESC_LITERAL_PREFIX:
2012 sprintf((char*) s, "SQL_DESC_LITERAL_PREFIX" );
2013 break;
2014
2015 case SQL_DESC_LITERAL_SUFFIX:
2016 sprintf((char*) s, "SQL_DESC_LITERAL_SUFFIX" );
2017 break;
2018
2019 case SQL_DESC_LOCAL_TYPE_NAME:
2020 sprintf((char*) s, "SQL_DESC_LOCAL_TYPE_NAME" );
2021 break;
2022
2023 case SQL_DESC_NAME:
2024 sprintf((char*) s, "SQL_DESC_NAME" );
2025 break;
2026
2027 case SQL_DESC_NULLABLE:
2028 sprintf((char*) s, "SQL_DESC_NULLABLE" );
2029 break;
2030
2031 case SQL_DESC_NUM_PREC_RADIX:
2032 sprintf((char*) s, "SQL_DESC_NUM_PREC_RADIX" );
2033 break;
2034
2035 case SQL_DESC_OCTET_LENGTH:
2036 sprintf((char*) s, "SQL_DESC_OCTET_LENGTH" );
2037 break;
2038
2039 case SQL_DESC_OCTET_LENGTH_PTR:
2040 sprintf((char*) s, "SQL_DESC_OCTET_LENGTH_PTR" );
2041 break;
2042
2043 case SQL_DESC_PARAMETER_TYPE:
2044 sprintf((char*) s, "SQL_DESC_PARAMETER_TYPE" );
2045 break;
2046
2047 case SQL_DESC_PRECISION:
2048 sprintf((char*) s, "SQL_DESC_PRECISION" );
2049 break;
2050
2051 case SQL_DESC_SCALE:
2052 sprintf((char*) s, "SQL_DESC_SCALE" );
2053 break;
2054
2055 case SQL_DESC_SCHEMA_NAME:
2056 sprintf((char*) s, "SQL_DESC_SCHEMA_NAME" );
2057 break;
2058
2059 case SQL_DESC_SEARCHABLE:
2060 sprintf((char*) s, "SQL_DESC_SEARCHABLE" );
2061 break;
2062
2063 case SQL_DESC_TABLE_NAME:
2064 sprintf((char*) s, "SQL_DESC_TABLE_NAME" );
2065 break;
2066
2067 case SQL_DESC_TYPE:
2068 sprintf((char*) s, "SQL_DESC_TYPE" );
2069 break;
2070
2071 case SQL_DESC_TYPE_NAME:
2072 sprintf((char*) s, "SQL_DESC_TYPE_NAME" );
2073 break;
2074
2075 case SQL_DESC_UNNAMED:
2076 sprintf((char*) s, "SQL_DESC_UNNAMED" );
2077 break;
2078
2079 case SQL_DESC_UNSIGNED:
2080 sprintf((char*) s, "SQL_DESC_UNSIGNED" );
2081 break;
2082
2083 case SQL_DESC_UPDATABLE:
2084 sprintf((char*) s, "SQL_DESC_UPDATABLE" );
2085 break;
2086
2087 default:
2088 sprintf((char*) s, "%d", (int)type );
2089 }
2090
2091 return (char*) s;
2092}
2093
2094/*
2095 * convert a statement attribute to a string
2096 */
2097
2098char * __stmt_attr_as_string( SQLCHAR *s, SQLINTEGER type )
2099{
2100 switch( type )
2101 {
2102 case SQL_ATTR_APP_PARAM_DESC:
2103 sprintf((char*) s, "SQL_ATTR_APP_PARAM_DESC" );
2104 break;
2105
2106 case SQL_ATTR_APP_ROW_DESC:
2107 sprintf((char*) s, "SQL_ATTR_APP_ROW_DESC" );
2108 break;
2109
2110 case SQL_ATTR_ASYNC_ENABLE:
2111 sprintf((char*) s, "SQL_ATTR_ASYNC_ENABLE" );
2112 break;
2113
2114 case SQL_ATTR_CONCURRENCY:
2115 sprintf((char*) s, "SQL_ATTR_CONCURRENCY" );
2116 break;
2117
2118 case SQL_ATTR_CURSOR_SCROLLABLE:
2119 sprintf((char*) s, "SQL_ATTR_CURSOR_SCROLLABLE" );
2120 break;
2121
2122 case SQL_ATTR_CURSOR_SENSITIVITY:
2123 sprintf((char*) s, "SQL_ATTR_CURSOR_SENSITIVITY" );
2124 break;
2125
2126 case SQL_ATTR_CURSOR_TYPE:
2127 sprintf((char*) s, "SQL_ATTR_CURSOR_TYPE" );
2128 break;
2129
2130 case SQL_ATTR_ENABLE_AUTO_IPD:
2131 sprintf((char*) s, "SQL_ATTR_ENABLE_AUTO_IPD" );
2132 break;
2133
2134 case SQL_ATTR_FETCH_BOOKMARK_PTR:
2135 sprintf((char*) s, "SQL_ATTR_FETCH_BOOKMARK_PTR" );
2136 break;
2137
2138 case SQL_ATTR_IMP_PARAM_DESC:
2139 sprintf((char*) s, "SQL_ATTR_IMP_PARAM_DESC" );
2140 break;
2141
2142 case SQL_ATTR_IMP_ROW_DESC:
2143 sprintf((char*) s, "SQL_ATTR_IMP_ROW_DESC" );
2144 break;
2145
2146 case SQL_ATTR_KEYSET_SIZE:
2147 sprintf((char*) s, "SQL_ATTR_KEYSET_SIZE" );
2148 break;
2149
2150 case SQL_ATTR_MAX_LENGTH:
2151 sprintf((char*) s, "SQL_ATTR_MAX_LENGTH" );
2152 break;
2153
2154 case SQL_ATTR_MAX_ROWS:
2155 sprintf((char*) s, "SQL_ATTR_MAX_ROWS" );
2156 break;
2157
2158 case SQL_ATTR_METADATA_ID:
2159 sprintf((char*) s, "SQL_ATTR_METADATA_ID" );
2160 break;
2161
2162 case SQL_ATTR_NOSCAN:
2163 sprintf((char*) s, "SQL_ATTR_NOSCAN" );
2164 break;
2165
2166 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
2167 sprintf((char*) s, "SQL_ATTR_PARAM_BIND_OFFSET_PTR" );
2168 break;
2169
2170 case SQL_ATTR_PARAM_BIND_TYPE:
2171 sprintf((char*) s, "SQL_ATTR_PARAM_BIND_TYPE" );
2172 break;
2173
2174 case SQL_ATTR_PARAM_OPERATION_PTR:
2175 sprintf((char*) s, "SQL_ATTR_PARAM_OPERATION_PTR" );
2176 break;
2177
2178 case SQL_ATTR_PARAM_STATUS_PTR:
2179 sprintf((char*) s, "SQL_ATTR_PARAM_STATUS_PTR" );
2180 break;
2181
2182 case SQL_ATTR_PARAMS_PROCESSED_PTR:
2183 sprintf((char*) s, "SQL_ATTR_PARAMS_PROCESSED_PTR" );
2184 break;
2185
2186 case SQL_ATTR_PARAMSET_SIZE:
2187 sprintf((char*) s, "SQL_ATTR_PARAMSET_SIZE" );
2188 break;
2189
2190 case SQL_ATTR_QUERY_TIMEOUT:
2191 sprintf((char*) s, "SQL_ATTR_QUERY_TIMEOUT" );
2192 break;
2193
2194 case SQL_ATTR_RETRIEVE_DATA:
2195 sprintf((char*) s, "SQL_ATTR_RETRIEVE_DATA" );
2196 break;
2197
2198 case SQL_ROWSET_SIZE:
2199 sprintf((char*) s, "SQL_ROWSET_SIZE" );
2200 break;
2201
2202 case SQL_ATTR_ROW_ARRAY_SIZE:
2203 sprintf((char*) s, "SQL_ATTR_ROW_ARRAY_SIZE" );
2204 break;
2205
2206 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
2207 sprintf((char*) s, "SQL_ATTR_ROW_BIND_OFFSET_PTR" );
2208 break;
2209
2210 case SQL_ATTR_ROW_BIND_TYPE:
2211 sprintf((char*) s, "SQL_ATTR_ROW_BIND_TYPE" );
2212 break;
2213
2214 case SQL_ATTR_ROW_NUMBER:
2215 sprintf((char*) s, "SQL_ATTR_ROW_NUMBER" );
2216 break;
2217
2218 case SQL_ATTR_ROW_OPERATION_PTR:
2219 sprintf((char*) s, "SQL_ATTR_ROW_OPERATION_PTR" );
2220 break;
2221
2222 case SQL_ATTR_ROW_STATUS_PTR:
2223 sprintf((char*) s, "SQL_ATTR_ROW_STATUS_PTR" );
2224 break;
2225
2226 case SQL_ATTR_ROWS_FETCHED_PTR:
2227 sprintf((char*) s, "SQL_ATTR_ROWS_FETCHED_PTR" );
2228 break;
2229
2230 case SQL_ATTR_SIMULATE_CURSOR:
2231 sprintf((char*) s, "SQL_ATTR_SIMULATE_CURSOR" );
2232 break;
2233
2234 case SQL_ATTR_USE_BOOKMARKS:
2235 sprintf((char*) s, "SQL_ATTR_USE_BOOKMARKS" );
2236 break;
2237
2238 default:
2239 sprintf((char*) s, "%d", (int)type );
2240 }
2241
2242 return (char*) s;
2243}
2244
2245/*
2246 * return a SQLGetInfo type as a string
2247 */
2248
2249char * __info_as_string( SQLCHAR *s, SQLINTEGER type )
2250{
2251 switch( type )
2252 {
2253 case SQL_ACCESSIBLE_PROCEDURES:
2254 sprintf((char*) s, "SQL_ACCESSIBLE_PROCEDURES" );
2255 break;
2256
2257 case SQL_ACCESSIBLE_TABLES:
2258 sprintf((char*) s, "SQL_ACCESSIBLE_TABLES" );
2259 break;
2260
2261 case SQL_ACTIVE_ENVIRONMENTS:
2262 sprintf((char*) s, "SQL_ACTIVE_ENVIRONMENTS" );
2263 break;
2264
2265 case SQL_AGGREGATE_FUNCTIONS:
2266 sprintf((char*) s, "SQL_AGGREGATE_FUNCTIONS" );
2267 break;
2268
2269 case SQL_ALTER_DOMAIN:
2270 sprintf((char*) s, "SQL_ALTER_DOMAIN" );
2271 break;
2272
2273 case SQL_ALTER_TABLE:
2274 sprintf((char*) s, "SQL_ALTER_TABLE" );
2275 break;
2276
2277 case SQL_ASYNC_MODE:
2278 sprintf((char*) s, "SQL_ASYNC_MODE" );
2279 break;
2280
2281 case SQL_BATCH_ROW_COUNT:
2282 sprintf((char*) s, "SQL_BATCH_ROW_COUNT" );
2283 break;
2284
2285 case SQL_BATCH_SUPPORT:
2286 sprintf((char*) s, "SQL_BATCH_SUPPORT" );
2287 break;
2288
2289 case SQL_BOOKMARK_PERSISTENCE:
2290 sprintf((char*) s, "SQL_BOOKMARK_PERSISTENCE" );
2291 break;
2292
2293 case SQL_CATALOG_LOCATION:
2294 sprintf((char*) s, "SQL_CATALOG_LOCATION" );
2295 break;
2296
2297 case SQL_CATALOG_NAME:
2298 sprintf((char*) s, "SQL_CATALOG_NAME" );
2299 break;
2300
2301 case SQL_CATALOG_NAME_SEPARATOR:
2302 sprintf((char*) s, "SQL_CATALOG_NAME_SEPARATOR" );
2303 break;
2304
2305 case SQL_CATALOG_TERM:
2306 sprintf((char*) s, "SQL_CATALOG_TERM" );
2307 break;
2308
2309 case SQL_CATALOG_USAGE:
2310 sprintf((char*) s, "SQL_CATALOG_USAGE" );
2311 break;
2312
2313 case SQL_COLLATION_SEQ:
2314 sprintf((char*) s, "SQL_COLLATION_SEQ" );
2315 break;
2316
2317 case SQL_COLUMN_ALIAS:
2318 sprintf((char*) s, "SQL_COLUMN_ALIAS" );
2319 break;
2320
2321 case SQL_CONCAT_NULL_BEHAVIOR:
2322 sprintf((char*) s, "SQL_CONCAT_NULL_BEHAVIOR" );
2323 break;
2324
2325 case SQL_CONVERT_BIGINT:
2326 sprintf((char*) s, "SQL_CONVERT_BIGINT" );
2327 break;
2328
2329 case SQL_CONVERT_BINARY:
2330 sprintf((char*) s, "SQL_CONVERT_BINARY" );
2331 break;
2332
2333 case SQL_CONVERT_BIT:
2334 sprintf((char*) s, "SQL_CONVERT_BIT" );
2335 break;
2336
2337 case SQL_CONVERT_CHAR:
2338 sprintf((char*) s, "SQL_CONVERT_CHAR" );
2339 break;
2340
2341 case SQL_CONVERT_DATE:
2342 sprintf((char*) s, "SQL_CONVERT_DATE" );
2343 break;
2344
2345 case SQL_CONVERT_DECIMAL:
2346 sprintf((char*) s, "SQL_CONVERT_DECIMAL" );
2347 break;
2348
2349 case SQL_CONVERT_DOUBLE:
2350 sprintf((char*) s, "SQL_CONVERT_DOUBLE" );
2351 break;
2352
2353 case SQL_CONVERT_FLOAT:
2354 sprintf((char*) s, "SQL_CONVERT_FLOAT" );
2355 break;
2356
2357 case SQL_CONVERT_INTEGER:
2358 sprintf((char*) s, "SQL_CONVERT_INTEGER" );
2359 break;
2360
2361 case SQL_CONVERT_INTERVAL_YEAR_MONTH:
2362 sprintf((char*) s, "SQL_CONVERT_INTERVAL_YEAR_MONTH" );
2363 break;
2364
2365 case SQL_CONVERT_INTERVAL_DAY_TIME:
2366 sprintf((char*) s, "SQL_CONVERT_INTERVAL_DAY_TIME" );
2367 break;
2368
2369 case SQL_CONVERT_LONGVARBINARY:
2370 sprintf((char*) s, "SQL_CONVERT_LONGVARBINARY" );
2371 break;
2372
2373 case SQL_CONVERT_LONGVARCHAR:
2374 sprintf((char*) s, "SQL_CONVERT_LONGVARCHAR" );
2375 break;
2376
2377 case SQL_CONVERT_NUMERIC:
2378 sprintf((char*) s, "SQL_CONVERT_NUMERIC" );
2379 break;
2380
2381 case SQL_CONVERT_REAL:
2382 sprintf((char*) s, "SQL_CONVERT_REAL" );
2383 break;
2384
2385 case SQL_CONVERT_SMALLINT:
2386 sprintf((char*) s, "SQL_CONVERT_SMALLINT" );
2387 break;
2388
2389 case SQL_CONVERT_TIME:
2390 sprintf((char*) s, "SQL_CONVERT_TIME" );
2391 break;
2392
2393 case SQL_CONVERT_TIMESTAMP:
2394 sprintf((char*) s, "SQL_CONVERT_TIMESTAMP" );
2395 break;
2396
2397 case SQL_CONVERT_TINYINT:
2398 sprintf((char*) s, "SQL_CONVERT_TINYINT" );
2399 break;
2400
2401 case SQL_CONVERT_VARBINARY:
2402 sprintf((char*) s, "SQL_CONVERT_VARBINARY" );
2403 break;
2404
2405 case SQL_CONVERT_VARCHAR:
2406 sprintf((char*) s, "SQL_CONVERT_VARCHAR" );
2407 break;
2408
2409 case SQL_CONVERT_FUNCTIONS:
2410 sprintf((char*) s, "SQL_CONVERT_FUNCTIONS" );
2411 break;
2412
2413 case SQL_CORRELATION_NAME:
2414 sprintf((char*) s, "SQL_CORRELATION_NAME" );
2415 break;
2416
2417 case SQL_CREATE_ASSERTION:
2418 sprintf((char*) s, "SQL_CREATE_ASSERTION" );
2419 break;
2420
2421 case SQL_CREATE_CHARACTER_SET:
2422 sprintf((char*) s, "SQL_CREATE_CHARACTER_SET" );
2423 break;
2424
2425 case SQL_CREATE_COLLATION:
2426 sprintf((char*) s, "SQL_CREATE_COLLATION" );
2427 break;
2428
2429 case SQL_CREATE_DOMAIN:
2430 sprintf((char*) s, "SQL_CREATE_DOMAIN" );
2431 break;
2432
2433 case SQL_CREATE_SCHEMA:
2434 sprintf((char*) s, "SQL_CREATE_SCHEMA" );
2435 break;
2436
2437 case SQL_CREATE_TABLE:
2438 sprintf((char*) s, "SQL_CREATE_TABLE" );
2439 break;
2440
2441 case SQL_CREATE_TRANSLATION:
2442 sprintf((char*) s, "SQL_CREATE_TRANSLATION" );
2443 break;
2444
2445 case SQL_CREATE_VIEW:
2446 sprintf((char*) s, "SQL_CREATE_VIEW" );
2447 break;
2448
2449 case SQL_CURSOR_COMMIT_BEHAVIOR:
2450 sprintf((char*) s, "SQL_CURSOR_COMMIT_BEHAVIOR" );
2451 break;
2452
2453 case SQL_CURSOR_ROLLBACK_BEHAVIOR:
2454 sprintf((char*) s, "SQL_CURSOR_ROLLBACK_BEHAVIOR" );
2455 break;
2456
2457 case SQL_CURSOR_SENSITIVITY:
2458 sprintf((char*) s, "SQL_CURSOR_SENSITIVITY" );
2459 break;
2460
2461 case SQL_DATA_SOURCE_NAME:
2462 sprintf((char*) s, "SQL_DATA_SOURCE_NAME" );
2463 break;
2464
2465 case SQL_DATA_SOURCE_READ_ONLY:
2466 sprintf((char*) s, "SQL_DATA_SOURCE_READ_ONLY" );
2467 break;
2468
2469 case SQL_DATABASE_NAME:
2470 sprintf((char*) s, "SQL_DATABASE_NAME" );
2471 break;
2472
2473 case SQL_DATETIME_LITERALS:
2474 sprintf((char*) s, "SQL_DATETIME_LITERALS" );
2475 break;
2476
2477 case SQL_DBMS_NAME:
2478 sprintf((char*) s, "SQL_DBMS_NAME" );
2479 break;
2480
2481 case SQL_DBMS_VER:
2482 sprintf((char*) s, "SQL_DBMS_VER" );
2483 break;
2484
2485 case SQL_DDL_INDEX:
2486 sprintf((char*) s, "SQL_DDL_INDEX" );
2487 break;
2488
2489 case SQL_DEFAULT_TXN_ISOLATION:
2490 sprintf((char*) s, "SQL_DEFAULT_TXN_ISOLATION" );
2491 break;
2492
2493 case SQL_DESCRIBE_PARAMETER:
2494 sprintf((char*) s, "SQL_DESCRIBE_PARAMETER" );
2495 break;
2496
2497 case SQL_DRIVER_NAME:
2498 sprintf((char*) s, "SQL_DRIVER_NAME" );
2499 break;
2500
2501 case SQL_DRIVER_HLIB:
2502 sprintf((char*) s, "SQL_DRIVER_HLIB" );
2503 break;
2504
2505 case SQL_DRIVER_HSTMT:
2506 sprintf((char*) s, "SQL_DRIVER_HSTMT" );
2507 break;
2508
2509 case SQL_DRIVER_ODBC_VER:
2510 sprintf((char*) s, "SQL_DRIVER_ODBC_VER" );
2511 break;
2512
2513 case SQL_DRIVER_VER:
2514 sprintf((char*) s, "SQL_DRIVER_VER" );
2515 break;
2516
2517 case SQL_ODBC_VER:
2518 sprintf((char*) s, "SQL_ODBC_VER" );
2519 break;
2520
2521 case SQL_DROP_ASSERTION:
2522 sprintf((char*) s, "SQL_DROP_ASSERTION" );
2523 break;
2524
2525 case SQL_DROP_CHARACTER_SET:
2526 sprintf((char*) s, "SQL_DROP_CHARACTER_SET" );
2527 break;
2528
2529 case SQL_DROP_COLLATION:
2530 sprintf((char*) s, "SQL_DROP_COLLATION" );
2531 break;
2532
2533 case SQL_DROP_DOMAIN:
2534 sprintf((char*) s, "SQL_DROP_DOMAIN" );
2535 break;
2536
2537 case SQL_DROP_SCHEMA:
2538 sprintf((char*) s, "SQL_DROP_SCHEMA" );
2539 break;
2540
2541 case SQL_DROP_TABLE:
2542 sprintf((char*) s, "SQL_DROP_TABLE" );
2543 break;
2544
2545 case SQL_DROP_TRANSLATION:
2546 sprintf((char*) s, "SQL_DROP_TRANSLATION" );
2547 break;
2548
2549 case SQL_DROP_VIEW:
2550 sprintf((char*) s, "SQL_DROP_VIEW" );
2551 break;
2552
2553 case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
2554 sprintf((char*) s, "SQL_DYNAMIC_CURSOR_ATTRIBUTES1" );
2555 break;
2556
2557 case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
2558 sprintf((char*) s, "SQL_EXPRESSIONS_IN_ORDERBY" );
2559 break;
2560
2561 case SQL_EXPRESSIONS_IN_ORDERBY:
2562 sprintf((char*) s, "SQL_EXPRESSIONS_IN_ORDERBY" );
2563 break;
2564
2565 case SQL_FILE_USAGE:
2566 sprintf((char*) s, "SQL_FILE_USAGE" );
2567 break;
2568
2569 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
2570 sprintf((char*) s, "SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1" );
2571 break;
2572
2573 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
2574 sprintf((char*) s, "SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2" );
2575 break;
2576
2577 case SQL_GETDATA_EXTENSIONS:
2578 sprintf((char*) s, "SQL_GETDATA_EXTENSIONS" );
2579 break;
2580
2581 case SQL_GROUP_BY:
2582 sprintf((char*) s, "SQL_GROUP_BY" );
2583 break;
2584
2585 case SQL_IDENTIFIER_CASE:
2586 sprintf((char*) s, "SQL_IDENTIFIER_CASE" );
2587 break;
2588
2589 case SQL_IDENTIFIER_QUOTE_CHAR:
2590 sprintf((char*) s, "SQL_IDENTIFIER_QUOTE_CHAR" );
2591 break;
2592
2593 case SQL_INDEX_KEYWORDS:
2594 sprintf((char*) s, "SQL_INDEX_KEYWORDS" );
2595 break;
2596
2597 case SQL_INFO_SCHEMA_VIEWS:
2598 sprintf((char*) s, "SQL_INFO_SCHEMA_VIEWS" );
2599 break;
2600
2601 case SQL_INSERT_STATEMENT:
2602 sprintf((char*) s, "SQL_INSERT_STATEMENT" );
2603 break;
2604
2605 case SQL_INTEGRITY:
2606 sprintf((char*) s, "SQL_INTEGRITY" );
2607 break;
2608
2609 case SQL_KEYSET_CURSOR_ATTRIBUTES1:
2610 sprintf((char*) s, "SQL_KEYSET_CURSOR_ATTRIBUTES1" );
2611 break;
2612
2613 case SQL_KEYSET_CURSOR_ATTRIBUTES2:
2614 sprintf((char*) s, "SQL_KEYSET_CURSOR_ATTRIBUTES2" );
2615 break;
2616
2617 case SQL_KEYWORDS:
2618 sprintf((char*) s, "SQL_KEYWORDS" );
2619 break;
2620
2621 case SQL_LIKE_ESCAPE_CLAUSE:
2622 sprintf((char*) s, "SQL_LIKE_ESCAPE_CLAUSE" );
2623 break;
2624
2625 case SQL_MAX_ASYNC_CONCURRENT_STATEMENTS:
2626 sprintf((char*) s, "SQL_MAX_ASYNC_CONCURRENT_STATEMENTS" );
2627 break;
2628
2629 case SQL_MAX_BINARY_LITERAL_LEN:
2630 sprintf((char*) s, "SQL_MAX_BINARY_LITERAL_LEN" );
2631 break;
2632
2633 case SQL_MAX_CATALOG_NAME_LEN:
2634 sprintf((char*) s, "SQL_MAX_CATALOG_NAME_LEN" );
2635 break;
2636
2637 case SQL_MAX_CHAR_LITERAL_LEN:
2638 sprintf((char*) s, "SQL_MAX_CHAR_LITERAL_LEN" );
2639 break;
2640
2641 case SQL_MAX_COLUMN_NAME_LEN:
2642 sprintf((char*) s, "SQL_MAX_COLUMN_NAME_LEN" );
2643 break;
2644
2645 case SQL_MAX_COLUMNS_IN_GROUP_BY:
2646 sprintf((char*) s, "SQL_MAX_COLUMNS_IN_GROUP_BY" );
2647 break;
2648
2649 case SQL_MAX_COLUMNS_IN_INDEX:
2650 sprintf((char*) s, "SQL_MAX_COLUMNS_IN_INDEX" );
2651 break;
2652
2653 case SQL_MAX_COLUMNS_IN_SELECT:
2654 sprintf((char*) s, "SQL_MAX_COLUMNS_IN_SELECT" );
2655 break;
2656
2657 case SQL_MAX_COLUMNS_IN_ORDER_BY:
2658 sprintf((char*) s, "SQL_MAX_COLUMNS_IN_ORDER_BY" );
2659 break;
2660
2661 case SQL_MAX_COLUMNS_IN_TABLE:
2662 sprintf((char*) s, "SQL_MAX_COLUMNS_IN_TABLE" );
2663 break;
2664
2665 case SQL_MAX_CONCURRENT_ACTIVITIES:
2666 sprintf((char*) s, "SQL_MAX_CONCURRENT_ACTIVITIES" );
2667 break;
2668
2669 case SQL_MAX_CURSOR_NAME_LEN:
2670 sprintf((char*) s, "SQL_MAX_CURSOR_NAME_LEN" );
2671 break;
2672
2673 case SQL_MAX_DRIVER_CONNECTIONS:
2674 sprintf((char*) s, "SQL_MAX_DRIVER_CONNECTIONS" );
2675 break;
2676
2677 case SQL_MAX_IDENTIFIER_LEN:
2678 sprintf((char*) s, "SQL_MAX_IDENTIFIER_LEN" );
2679 break;
2680
2681 case SQL_MAX_INDEX_SIZE:
2682 sprintf((char*) s, "SQL_MAX_INDEX_SIZE" );
2683 break;
2684
2685 case SQL_MAX_PROCEDURE_NAME_LEN:
2686 sprintf((char*) s, "SQL_MAX_PROCEDURE_NAME_LEN" );
2687 break;
2688
2689 case SQL_MAX_ROW_SIZE:
2690 sprintf((char*) s, "SQL_MAX_ROW_SIZE" );
2691 break;
2692
2693 case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
2694 sprintf((char*) s, "SQL_MAX_ROW_SIZE_INCLUDES_LONG" );
2695 break;
2696
2697 case SQL_MAX_SCHEMA_NAME_LEN:
2698 sprintf((char*) s, "SQL_MAX_SCHEMA_NAME_LEN" );
2699 break;
2700
2701 case SQL_MAX_STATEMENT_LEN:
2702 sprintf((char*) s, "SQL_MAX_STATEMENT_LEN" );
2703 break;
2704
2705 case SQL_MAX_TABLE_NAME_LEN:
2706 sprintf((char*) s, "SQL_MAX_TABLE_NAME_LEN" );
2707 break;
2708
2709 case SQL_MAX_TABLES_IN_SELECT:
2710 sprintf((char*) s, "SQL_MAX_TABLES_IN_SELECT" );
2711 break;
2712
2713 case SQL_MAX_USER_NAME_LEN:
2714 sprintf((char*) s, "SQL_MAX_USER_NAME_LEN" );
2715 break;
2716
2717 case SQL_MULT_RESULT_SETS:
2718 sprintf((char*) s, "SQL_MULT_RESULT_SETS" );
2719 break;
2720
2721 case SQL_MULTIPLE_ACTIVE_TXN:
2722 sprintf((char*) s, "SQL_MULTIPLE_ACTIVE_TXN" );
2723 break;
2724
2725 case SQL_NEED_LONG_DATA_LEN:
2726 sprintf((char*) s, "SQL_NEED_LONG_DATA_LEN" );
2727 break;
2728
2729 case SQL_NON_NULLABLE_COLUMNS:
2730 sprintf((char*) s, "SQL_NON_NULLABLE_COLUMNS" );
2731 break;
2732
2733 case SQL_NULL_COLLATION:
2734 sprintf((char*) s, "SQL_NULL_COLLATION" );
2735 break;
2736
2737 case SQL_NUMERIC_FUNCTIONS:
2738 sprintf((char*) s, "SQL_NUMERIC_FUNCTIONS" );
2739 break;
2740
2741 case SQL_ODBC_INTERFACE_CONFORMANCE:
2742 sprintf((char*) s, "SQL_ODBC_INTERFACE_CONFORMANCE" );
2743 break;
2744
2745 case SQL_OJ_CAPABILITIES:
2746 sprintf((char*) s, "SQL_OJ_CAPABILITIES" );
2747 break;
2748
2749 case SQL_ORDER_BY_COLUMNS_IN_SELECT:
2750 sprintf((char*) s, "SQL_ORDER_BY_COLUMNS_IN_SELECT" );
2751 break;
2752
2753 case SQL_PARAM_ARRAY_ROW_COUNTS:
2754 sprintf((char*) s, "SQL_PARAM_ARRAY_ROW_COUNTS" );
2755 break;
2756
2757 case SQL_PARAM_ARRAY_SELECTS:
2758 sprintf((char*) s, "SQL_PARAM_ARRAY_SELECTS" );
2759 break;
2760
2761 case SQL_PROCEDURE_TERM:
2762 sprintf((char*) s, "SQL_PROCEDURE_TERM" );
2763 break;
2764
2765 case SQL_PROCEDURES:
2766 sprintf((char*) s, "SQL_PROCEDURES" );
2767 break;
2768
2769 case SQL_QUOTED_IDENTIFIER_CASE:
2770 sprintf((char*) s, "SQL_QUOTED_IDENTIFIER_CASE" );
2771 break;
2772
2773 case SQL_ROW_UPDATES:
2774 sprintf((char*) s, "SQL_ROW_UPDATES" );
2775 break;
2776
2777 case SQL_SCHEMA_TERM:
2778 sprintf((char*) s, "SQL_SCHEMA_TERM" );
2779 break;
2780
2781 case SQL_SCHEMA_USAGE:
2782 sprintf((char*) s, "SQL_SCHEMA_USAGE" );
2783 break;
2784
2785 case SQL_SCROLL_OPTIONS:
2786 sprintf((char*) s, "SQL_SCROLL_OPTIONS" );
2787 break;
2788
2789 case SQL_SEARCH_PATTERN_ESCAPE:
2790 sprintf((char*) s, "SQL_SEARCH_PATTERN_ESCAPE" );
2791 break;
2792
2793 case SQL_SERVER_NAME:
2794 sprintf((char*) s, "SQL_SERVER_NAME" );
2795 break;
2796
2797 case SQL_SPECIAL_CHARACTERS:
2798 sprintf((char*) s, "SQL_SPECIAL_CHARACTERS" );
2799 break;
2800
2801 case SQL_SQL_CONFORMANCE:
2802 sprintf((char*) s, "SQL_SQL_CONFORMANCE" );
2803 break;
2804
2805 case SQL_SQL92_DATETIME_FUNCTIONS:
2806 sprintf((char*) s, "SQL_SQL92_DATETIME_FUNCTIONS" );
2807 break;
2808
2809 case SQL_SQL92_FOREIGN_KEY_DELETE_RULE:
2810 sprintf((char*) s, "SQL_SQL92_FOREIGN_KEY_DELETE_RULE" );
2811 break;
2812
2813 case SQL_SQL92_FOREIGN_KEY_UPDATE_RULE:
2814 sprintf((char*) s, "SQL_SQL92_FOREIGN_KEY_UPDATE_RULE" );
2815 break;
2816
2817 case SQL_SQL92_GRANT:
2818 sprintf((char*) s, "SQL_SQL92_GRANT" );
2819 break;
2820
2821 case SQL_SQL92_NUMERIC_VALUE_FUNCTIONS:
2822 sprintf((char*) s, "SQL_SQL92_NUMERIC_VALUE_FUNCTIONS" );
2823 break;
2824
2825 case SQL_SQL92_PREDICATES:
2826 sprintf((char*) s, "SQL_SQL92_PREDICATES" );
2827 break;
2828
2829 case SQL_SQL92_RELATIONAL_JOIN_OPERATORS:
2830 sprintf((char*) s, "SQL_SQL92_RELATIONAL_JOIN_OPERATORS" );
2831 break;
2832
2833 case SQL_SQL92_REVOKE:
2834 sprintf((char*) s, "SQL_SQL92_REVOKE" );
2835 break;
2836
2837 case SQL_SQL92_ROW_VALUE_CONSTRUCTOR:
2838 sprintf((char*) s, "SQL_SQL92_ROW_VALUE_CONSTRUCTOR" );
2839 break;
2840
2841 case SQL_SQL92_STRING_FUNCTIONS:
2842 sprintf((char*) s, "SQL_SQL92_STRING_EXPRESSIONS" );
2843 break;
2844
2845 case SQL_SQL92_VALUE_EXPRESSIONS:
2846 sprintf((char*) s, "SQL_SQL92_VALUE_EXPRESSIONS" );
2847 break;
2848
2849 case SQL_STANDARD_CLI_CONFORMANCE:
2850 sprintf((char*) s, "SQL_STANDARD_CLI_CONFORMANCE" );
2851 break;
2852
2853 case SQL_STATIC_CURSOR_ATTRIBUTES1:
2854 sprintf((char*) s, "SQL_STATIC_CURSOR_ATTRIBUTES1" );
2855 break;
2856
2857 case SQL_STATIC_CURSOR_ATTRIBUTES2:
2858 sprintf((char*) s, "SQL_STATIC_CURSOR_ATTRIBUTES2" );
2859 break;
2860
2861 case SQL_STRING_FUNCTIONS:
2862 sprintf((char*) s, "SQL_STRING_FUNCTIONS" );
2863 break;
2864
2865 case SQL_SUBQUERIES:
2866 sprintf((char*) s, "SQL_SUBQUERIES" );
2867 break;
2868
2869 case SQL_SYSTEM_FUNCTIONS:
2870 sprintf((char*) s, "SQL_SYSTEM_FUNCTIONS" );
2871 break;
2872
2873 case SQL_TABLE_TERM:
2874 sprintf((char*) s, "SQL_TABLE_TERM" );
2875 break;
2876
2877 case SQL_TIMEDATE_ADD_INTERVALS:
2878 sprintf((char*) s, "SQL_TIMEDATE_ADD_INTERVALS" );
2879 break;
2880
2881 case SQL_TIMEDATE_DIFF_INTERVALS:
2882 sprintf((char*) s, "SQL_TIMEDATE_DIFF_INTERVALS" );
2883 break;
2884
2885 case SQL_TIMEDATE_FUNCTIONS:
2886 sprintf((char*) s, "SQL_TIMEDATE_FUNCTIONS" );
2887 break;
2888
2889 case SQL_TXN_CAPABLE:
2890 sprintf((char*) s, "SQL_TXN_CAPABLE" );
2891 break;
2892
2893 case SQL_TXN_ISOLATION_OPTION:
2894 sprintf((char*) s, "SQL_TXN_ISOLATION_OPTION" );
2895 break;
2896
2897 case SQL_UNION:
2898 sprintf((char*) s, "SQL_UNION" );
2899 break;
2900
2901 case SQL_USER_NAME:
2902 sprintf((char*) s, "SQL_USER_NAME" );
2903 break;
2904
2905 case SQL_XOPEN_CLI_YEAR:
2906 sprintf((char*) s, "SQL_XOPEN_CLI_YEAR" );
2907 break;
2908
2909 case SQL_FETCH_DIRECTION:
2910 sprintf((char*) s, "SQL_FETCH_DIRECTION" );
2911 break;
2912
2913 case SQL_LOCK_TYPES:
2914 sprintf((char*) s, "SQL_LOCK_TYPES" );
2915 break;
2916
2917 case SQL_ODBC_API_CONFORMANCE:
2918 sprintf((char*) s, "SQL_ODBC_API_CONFORMANCE" );
2919 break;
2920
2921 case SQL_ODBC_SQL_CONFORMANCE:
2922 sprintf((char*) s, "SQL_ODBC_SQL_CONFORMANCE" );
2923 break;
2924
2925 case SQL_POS_OPERATIONS:
2926 sprintf((char*) s, "SQL_POS_OPERATIONS" );
2927 break;
2928
2929 case SQL_POSITIONED_STATEMENTS:
2930 sprintf((char*) s, "SQL_POSITIONED_STATEMENTS" );
2931 break;
2932
2933 case SQL_SCROLL_CONCURRENCY:
2934 sprintf((char*) s, "SQL_SCROLL_CONCURRENCY" );
2935 break;
2936
2937 case SQL_STATIC_SENSITIVITY:
2938 sprintf((char*) s, "SQL_STATIC_SENSITIVITY" );
2939 break;
2940
2941 case SQL_OUTER_JOINS:
2942 sprintf((char*) s, "SQL_OUTER_JOINS" );
2943 break;
2944
2945 case SQL_DRIVER_AWARE_POOLING_SUPPORTED:
2946 sprintf((char*) s, "SQL_DRIVER_AWARE_POOLING_SUPPORTED" );
2947 break;
2948
2949 default:
2950 sprintf((char*) s, "%d", (int)type );
2951 }
2952
2953 return (char*) s;
2954}
2955
2956/*
2957 * convert from type 3 error states to type 2
2958 */
2959
2960struct state_map
2961{
2962 char ver2[6];
2963 char ver3[6];
2964};
2965
2966static const struct state_map state_mapping_3_2[] = {
2967 { "01S03", "01001" },
2968 { "01S04", "01001" },
2969 { "22003", "HY019" },
2970 { "22005", "22018" },
2971 { "22008", "22007" },
2972 { "24000", "07005" },
2973 { "37000", "42000" },
2974 { "70100", "HY018" },
2975 { "S0001", "42S01" },
2976 { "S0002", "42S02" },
2977 { "S0011", "42S11" },
2978 { "S0012", "42S12" },
2979 { "S0021", "42S21" },
2980 { "S0022", "42S22" },
2981 { "S0023", "42S23" },
2982 { "S1000", "HY000" },
2983 { "S1001", "HY001" },
2984 { "S1002", "07009" },
2985 { "S1003", "HY003" },
2986 { "S1004", "HY004" },
2987 { "S1007", "HY007" },
2988 { "S1008", "HY008" },
2989 { "S1009", "HY009" },
2990 { "S1010", "HY010" },
2991 { "S1011", "HY011" },
2992 { "S1012", "HY012" },
2993 { "S1090", "HY090" },
2994 { "S1091", "HY091" },
2995 { "S1092", "HY092" },
2996 { "S1093", "07009" },
2997 { "S1096", "HY096" },
2998 { "S1097", "HY097" },
2999 { "S1098", "HY098" },
3000 { "S1099", "HY099" },
3001 { "S1100", "HY100" },
3002 { "S1101", "HY101" },
3003 { "S1103", "HY103" },
3004 { "S1104", "HY104" },
3005 { "S1105", "HY105" },
3006 { "S1106", "HY106" },
3007 { "S1107", "HY107" },
3008 { "S1108", "HY108" },
3009 { "S1109", "HY109" },
3010 { "S1110", "HY110" },
3011 { "S1111", "HY111" },
3012 { "S1C00", "HYC00" },
3013 { "S1T00", "HYT00" },
3014 { "", "" }
3015};
3016
3017/*
3018 * the book doesn't say that it should map ODBC 2 states to ODBC 3
3019 * but the MS Windows DM can be seen to do just that
3020 */
3021
3022static const struct state_map state_mapping_2_3[] = {
3023 { "01S03", "01001" },
3024 { "01S04", "01001" },
3025 { "22005", "22018" },
3026 { "37000", "42000" },
3027 { "70100", "HY018" },
3028 { "S0001", "42S01" },
3029 { "S0002", "42S02" },
3030 { "S0011", "42S11" },
3031 { "S0012", "42S12" },
3032 { "S0021", "42S21" },
3033 { "S0022", "42S22" },
3034 { "S0023", "42S23" },
3035 { "S1000", "HY000" },
3036 { "S1001", "HY001" },
3037 { "S1002", "07009" },
3038 { "S1003", "HY003" },
3039 { "S1004", "HY004" },
3040 { "S1007", "HY007" },
3041 { "S1008", "HY008" },
3042 { "S1009", "HY009" },
3043 { "S1010", "HY010" },
3044 { "S1011", "HY011" },
3045 { "S1012", "HY012" },
3046 { "S1090", "HY090" },
3047 { "S1091", "HY091" },
3048 { "S1092", "HY092" },
3049 { "S1093", "07009" },
3050 { "S1096", "HY096" },
3051 { "S1097", "HY097" },
3052 { "S1098", "HY098" },
3053 { "S1099", "HY099" },
3054 { "S1100", "HY100" },
3055 { "S1101", "HY101" },
3056 { "S1103", "HY103" },
3057 { "S1104", "HY104" },
3058 { "S1105", "HY105" },
3059 { "S1106", "HY106" },
3060 { "S1107", "HY107" },
3061 { "S1108", "HY108" },
3062 { "S1109", "HY109" },
3063 { "S1110", "HY110" },
3064 { "S1111", "HY111" },
3065 { "S1C00", "HYC00" },
3066 { "S1T00", "HYT00" },
3067 { "", "" }
3068};
3069
3070/*
3071 * map ODBC3 states to/from ODBC 2
3072 */
3073
3074void __map_error_state( char * state, int requested_version )
3075{
3076 const struct state_map *ptr;
3077
3078 if ( !state )
3079 return;
3080
3081
3082 if ( requested_version == SQL_OV_ODBC2 )
3083 {
3084 ptr = state_mapping_3_2;
3085
3086 while( ptr -> ver3[0] )
3087 {
3088 if ( strcmp( ptr -> ver3, state ) == 0 )
3089 {
3090 strcpy( state, ptr -> ver2 );
3091 return;
3092 }
3093 ptr ++;
3094 }
3095 }
3096 else if ( requested_version >= SQL_OV_ODBC3 )
3097 {
3098 ptr = state_mapping_2_3;
3099
3100 while( ptr -> ver2[0] )
3101 {
3102 if ( strcmp( ptr -> ver2, state ) == 0 )
3103 {
3104 strcpy( state, ptr -> ver3 );
3105 return;
3106 }
3107 ptr ++;
3108 }
3109 }
3110}
3111
3112void __map_error_state_w( SQLWCHAR * wstate, int requested_version )
3113{
3114 char state[ 6 ];
3115
3116 unicode_to_ansi_copy( state, 6, wstate, SQL_NTS, NULL, NULL );
3117
3118 __map_error_state( state, requested_version );
3119
3120 ansi_to_unicode_copy( wstate, state, SQL_NTS, NULL, NULL );
3121}
3122
3123/*
3124 * return the process id as a string
3125 */
3126
3127char * __get_pid( SQLCHAR * str )
3128{
3129 sprintf((char *) str, "%d", getpid());
3130
3131 return (char*)str;
3132}
3133
3134/*
3135 * take a SQL string and its length indicator and format it for
3136 * display
3137 */
3138
3139char * __string_with_length( SQLCHAR *ostr, SQLCHAR *instr, SQLINTEGER len )
3140{
3141 if ( instr == NULL )
3142 {
3143 sprintf((char*) ostr, "[NULL]" );
3144 }
3145 else if ( len == SQL_NTS )
3146 {
3147 if ( strlen((char*) instr ) > LOG_MESSAGE_LEN )
3148 {
3149 sprintf((char*) ostr, "[%.*s...][length = %ld (SQL_NTS)]",
3150 LOG_MESSAGE_LEN, instr, (long int)strlen((char*) instr ));
3151 }
3152 else
3153 {
3154 sprintf((char*) ostr, "[%s][length = %ld (SQL_NTS)]",
3155 instr, (long int)strlen((char*) instr ));
3156 }
3157
3158 }
3159 else
3160 {
3161 if ( len < LOG_MESSAGE_LEN )
3162 sprintf((char*) ostr, "[%.*s][length = %d]", (int)len, instr, (int)len );
3163 else
3164 sprintf((char*) ostr, "[%.*s...][length = %d]", LOG_MESSAGE_LEN, instr, (int)len );
3165 }
3166
3167 return (char*)ostr;
3168}
3169
3170char * __wstring_with_length( SQLCHAR *ostr, SQLWCHAR *instr, SQLINTEGER len )
3171{
3172 int i = 0;
3173 char tmp[ LOG_MESSAGE_LEN ];
3174
3175 if ( instr == NULL )
3176 {
3177 sprintf((char*) ostr, "[NULL]" );
3178 }
3179 else if ( len == SQL_NTS )
3180 {
3181 if ( ( i = wide_strlen( instr ) ) < LOG_MESSAGE_LEN )
3182 {
3183 strcpy((char*) ostr, "[" );
3184 unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, i, NULL, NULL );
3185 strcat((char*) ostr, "]" );
3186 }
3187 else
3188 {
3189 strcpy((char*) ostr, "[" );
3190 unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, LOG_MESSAGE_LEN, NULL, NULL );
3191 strcat((char*) ostr, "...]" );
3192 }
3193 sprintf( tmp, "[length = %d (SQL_NTS)]", i );
3194 strcat((char*) ostr, tmp );
3195 }
3196 else
3197 {
3198 if ( len < LOG_MESSAGE_LEN )
3199 {
3200 strcpy((char*) ostr, "[" );
3201 unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, len, NULL, NULL );
3202 strcat((char*) ostr, "]" );
3203 }
3204 else
3205 {
3206 strcpy((char*) ostr, "[" );
3207 unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, LOG_MESSAGE_LEN, NULL, NULL );
3208 strcat((char*) ostr, "...]" );
3209 }
3210 sprintf( tmp, "[length = %d]", (int)len );
3211 strcat((char*) ostr, tmp );
3212 }
3213
3214 return (char*)ostr;
3215}
3216
3217/*
3218 * replace password with ****
3219 */
3220
3221char * __string_with_length_pass( SQLCHAR *out, SQLCHAR *str, SQLINTEGER len )
3222{
3223 char *p = __string_with_length( out, str, len );
3224
3225 /*
3226 * the string will be of the form [text]
3227 */
3228
3229 if ( str )
3230 {
3231 char * ptr = p + 1;
3232
3233 while ( *ptr && *ptr != ']' )
3234 {
3235 *ptr = '*';
3236 ptr ++;
3237 }
3238 }
3239
3240 return p;
3241}
3242
3243char * __wstring_with_length_pass( SQLCHAR *out, SQLWCHAR *str, SQLINTEGER len )
3244{
3245 char *p = __wstring_with_length( out, str, len );
3246
3247 /*
3248 * the string will be of the form [text]
3249 */
3250
3251 if ( str )
3252 {
3253 char * ptr = p + 1;
3254
3255 while ( *ptr && *ptr != ']' )
3256 {
3257 *ptr = '*';
3258 ptr ++;
3259 }
3260 }
3261
3262 return p;
3263}
3264
3265/*
3266 * mask out PWD=str;
3267 * wont work on lower case pwd but there you go
3268 */
3269
3270char * __string_with_length_hide_pwd( SQLCHAR *out, SQLCHAR *str, SQLINTEGER len )
3271{
3272 char *p = __string_with_length( out, str, len );
3273
3274 if ( str )
3275 {
3276 char *ptr;
3277
3278 ptr = strstr( p, "PWD=" );
3279 while ( ptr )
3280 {
3281 ptr += 4;
3282 while ( *ptr && *ptr != ';' && *ptr != ']' )
3283 {
3284 *ptr = '*';
3285 ptr ++;
3286 }
3287 ptr = strstr( ptr, "PWD=" );
3288 }
3289 }
3290
3291 return p;
3292}
3293
3294char * __wstring_with_length_hide_pwd( SQLCHAR *out, SQLWCHAR *str, SQLINTEGER len )
3295{
3296 char *p = __wstring_with_length( out, str, len );
3297
3298 return p;
3299}
3300
3301/*
3302 * display a C type as a string
3303 */
3304
3305char * __c_as_text( SQLINTEGER type )
3306{
3307 switch( type )
3308 {
3309 case SQL_C_CHAR:
3310 return "SQL_C_CHAR";
3311
3312 case SQL_C_LONG:
3313 return "SQL_C_LONG";
3314
3315 case SQL_C_SHORT:
3316 return "SQL_C_SHORT";
3317
3318 case SQL_C_FLOAT:
3319 return "SQL_C_FLOAT";
3320
3321 case SQL_C_DOUBLE:
3322 return "SQL_C_DOUBLE";
3323
3324 case SQL_C_NUMERIC:
3325 return "SQL_C_NUMERIC";
3326
3327 case SQL_C_DEFAULT:
3328 return "SQL_C_DEFAULT";
3329
3330 case SQL_C_DATE:
3331 return "SQL_C_DATE";
3332
3333 case SQL_C_TIME:
3334 return "SQL_C_TIME";
3335
3336 case SQL_C_TIMESTAMP:
3337 return "SQL_C_TIMESTAMP";
3338
3339 case SQL_C_TYPE_DATE:
3340 return "SQL_C_TYPE_DATE";
3341
3342 case SQL_C_TYPE_TIME:
3343 return "SQL_C_TYPE_TIME";
3344
3345 case SQL_C_TYPE_TIMESTAMP:
3346 return "SQL_C_TYPE_TIMESTAMP ";
3347
3348 case SQL_C_INTERVAL_YEAR:
3349 return "SQL_C_INTERVAL_YEAR ";
3350
3351 case SQL_C_INTERVAL_MONTH:
3352 return "SQL_C_INTERVAL_MONTH";
3353
3354 case SQL_C_INTERVAL_DAY:
3355 return "SQL_C_INTERVAL_DAY ";
3356
3357 case SQL_C_INTERVAL_HOUR:
3358 return "SQL_C_INTERVAL_HOUR";
3359
3360 case SQL_C_INTERVAL_MINUTE:
3361 return "SQL_C_INTERVAL_MINUTE";
3362
3363 case SQL_C_INTERVAL_SECOND:
3364 return "SQL_C_INTERVAL_SECOND";
3365
3366 case SQL_C_INTERVAL_YEAR_TO_MONTH:
3367 return "SQL_C_INTERVAL_YEAR_TO_MONTH";
3368
3369 case SQL_C_INTERVAL_DAY_TO_HOUR:
3370 return "SQL_C_INTERVAL_DAY_TO_HOUR ";
3371
3372 case SQL_C_INTERVAL_DAY_TO_MINUTE:
3373 return "SQL_C_INTERVAL_DAY_TO_MINUTE";
3374
3375 case SQL_C_INTERVAL_DAY_TO_SECOND:
3376 return "SQL_C_INTERVAL_DAY_TO_SECOND";
3377
3378 case SQL_C_INTERVAL_HOUR_TO_MINUTE:
3379 return "SQL_C_INTERVAL_HOUR_TO_MINUTE";
3380
3381 case SQL_C_INTERVAL_HOUR_TO_SECOND:
3382 return "SQL_C_INTERVAL_HOUR_TO_SECOND";
3383
3384 case SQL_C_INTERVAL_MINUTE_TO_SECOND:
3385 return "SQL_C_INTERVAL_MINUTE_TO_SECOND";
3386
3387 case SQL_C_BINARY:
3388 return "SQL_C_BINARY";
3389
3390 case SQL_C_BIT:
3391 return "SQL_C_BIT";
3392
3393 case SQL_C_SBIGINT:
3394 return "SQL_C_SBIGINT";
3395
3396 case SQL_C_UBIGINT:
3397 return "SQL_C_UBIGINT";
3398
3399 case SQL_C_TINYINT:
3400 return "SQL_C_TINYINT";
3401
3402 case SQL_C_SLONG:
3403 return "SQL_C_SLONG";
3404
3405 case SQL_C_SSHORT:
3406 return "SQL_C_SSHORT";
3407
3408 case SQL_C_STINYINT:
3409 return "SQL_C_STINYINT";
3410
3411 case SQL_C_ULONG:
3412 return "SQL_C_ULONG";
3413
3414 case SQL_C_USHORT:
3415 return "SQL_C_USHORT";
3416
3417 case SQL_C_UTINYINT:
3418 return "SQL_C_UTINYINT";
3419
3420 case SQL_C_GUID:
3421 return "SQL_C_GUID";
3422
3423 case SQL_C_WCHAR:
3424 return "SQL_C_WCHAR";
3425
3426 default:
3427 return "";
3428 }
3429}
3430
3431/*
3432 * display a SQL type as a string
3433 */
3434
3435char * __sql_as_text( SQLINTEGER type )
3436{
3437 switch( type )
3438 {
3439 case SQL_DECIMAL:
3440 return "SQL_DECIMAL";
3441
3442 case SQL_VARCHAR:
3443 return "SQL_VARCHAR";
3444
3445 case SQL_LONGVARCHAR:
3446 return "SQL_LONGVARCHAR";
3447
3448 case SQL_LONGVARBINARY:
3449 return "SQL_LONGVARBINARY";
3450
3451 case SQL_C_BINARY:
3452 return "SQL_C_BINARY";
3453
3454 case SQL_VARBINARY:
3455 return "SQL_VARBINARY";
3456
3457 case SQL_CHAR:
3458 return "SQL_CHAR";
3459
3460 case SQL_WCHAR:
3461 return "SQL_WCHAR";
3462
3463 case SQL_WVARCHAR:
3464 return "SQL_WVARCHAR";
3465
3466 case SQL_INTEGER:
3467 return "SQL_INTEGER";
3468
3469 case SQL_C_ULONG:
3470 return "SQL_C_ULONG";
3471
3472 case SQL_C_SLONG:
3473 return "SQL_C_SLONG";
3474
3475 case SQL_BIGINT:
3476 return "SQL_BIGINT";
3477
3478 case SQL_C_UBIGINT:
3479 return "SQL_C_SBIGINT";
3480
3481 case SQL_C_SBIGINT:
3482 return "SQL_C_SBIGINT";
3483
3484 case SQL_SMALLINT:
3485 return "SQL_SMALLINT";
3486
3487 case SQL_C_USHORT:
3488 return "SQL_C_USHORT";
3489
3490 case SQL_C_SSHORT:
3491 return "SQL_C_SSHORT";
3492
3493 case SQL_TINYINT:
3494 return "SQL_TINYINT";
3495
3496 case SQL_C_UTINYINT:
3497 return "SQL_C_UTINYINT";
3498
3499 case SQL_C_STINYINT:
3500 return "SQL_C_STINYINT";
3501
3502 case SQL_BIT:
3503 return "SQL_BIT";
3504
3505 case SQL_NUMERIC:
3506 return "SQL_NUMERIC";
3507
3508 case SQL_REAL:
3509 return "SQL_REAL";
3510
3511 case SQL_DOUBLE:
3512 return "SQL_DOUBLE";
3513
3514 case SQL_FLOAT:
3515 return "SQL_FLOAT";
3516
3517 case SQL_TYPE_DATE:
3518 return "SQL_TYPE_DATE";
3519
3520 case SQL_DATE:
3521 return "SQL_DATE";
3522
3523 case SQL_TYPE_TIME:
3524 return "SQL_TYPE_TIME";
3525
3526 case SQL_TIME:
3527 return "SQL_TIME";
3528
3529 case SQL_TYPE_TIMESTAMP:
3530 return "SQL_TYPE_TIMESTAMP";
3531
3532 case SQL_TIMESTAMP:
3533 return "SQL_TIMESTAMP";
3534
3535 case SQL_INTERVAL_YEAR:
3536 return "SQL_INTERVAL_YEAR ";
3537
3538 case SQL_INTERVAL_MONTH:
3539 return "SQL_INTERVAL_MONTH";
3540
3541 case SQL_INTERVAL_DAY:
3542 return "SQL_INTERVAL_DAY ";
3543
3544 case SQL_INTERVAL_HOUR:
3545 return "SQL_INTERVAL_HOUR";
3546
3547 case SQL_INTERVAL_MINUTE:
3548 return "SQL_INTERVAL_MINUTE";
3549
3550 case SQL_INTERVAL_SECOND:
3551 return "SQL_INTERVAL_SECOND";
3552
3553 case SQL_INTERVAL_YEAR_TO_MONTH:
3554 return "SQL_INTERVAL_YEAR_TO_MONTH";
3555
3556 case SQL_INTERVAL_DAY_TO_HOUR:
3557 return "SQL_INTERVAL_DAY_TO_HOUR ";
3558
3559 case SQL_INTERVAL_DAY_TO_MINUTE:
3560 return "SQL_INTERVAL_DAY_TO_MINUTE";
3561
3562 case SQL_INTERVAL_DAY_TO_SECOND:
3563 return "SQL_INTERVAL_DAY_TO_SECOND";
3564
3565 case SQL_INTERVAL_HOUR_TO_MINUTE:
3566 return "SQL_INTERVAL_HOUR_TO_MINUTE";
3567
3568 case SQL_INTERVAL_HOUR_TO_SECOND:
3569 return "SQL_INTERVAL_HOUR_TO_SECOND";
3570
3571 case SQL_INTERVAL_MINUTE_TO_SECOND:
3572 return "SQL_INTERVAL_MINUTE_TO_SECOND";
3573
3574 default:
3575 return "";
3576 }
3577}
3578
3579/*
3580 * convert a return type as a string
3581 */
3582
3583char * __get_return_status( SQLRETURN ret, SQLCHAR *buffer )
3584{
3585 switch ( ret )
3586 {
3587 case SQL_SUCCESS:
3588 return "SQL_SUCCESS";
3589
3590 case SQL_ERROR:
3591 return "SQL_ERROR";
3592
3593 case SQL_SUCCESS_WITH_INFO:
3594 return "SQL_SUCCESS_WITH_INFO";
3595
3596 case SQL_NO_DATA:
3597 return "SQL_NO_DATA";
3598
3599 case SQL_STILL_EXECUTING:
3600 return "SQL_STILL_EXECUTING";
3601
3602 case SQL_INVALID_HANDLE:
3603 return "SQL_INVALID_HANDLE";
3604
3605 case SQL_NEED_DATA:
3606 return "SQL_NEED_DATA";
3607
3608 case SQL_PARAM_DATA_AVAILABLE:
3609 return "SQL_PARAM_DATA_AVAILABLE";
3610
3611 default:
3612 sprintf((char*) buffer, "UNKNOWN(%d)", ret );
3613 return (char*)buffer;
3614 }
3615}
3616
3617int wide_ansi_strncmp( SQLWCHAR *str1, char *str2, int len )
3618{
3619 char c;
3620
3621 while( len > 0 )
3622 {
3623 if ( *str1 == 0 || *str2 == 0 )
3624 break;
3625
3626 c = (char) *str1;
3627 if ( c != *str2 )
3628 return *str2 - c;
3629
3630 str1 ++;
3631 str2 ++;
3632 len --;
3633 }
3634
3635 c = (char) *str1;
3636
3637 return *str2 - c;
3638}
3639
3640SQLWCHAR *wide_strcpy( SQLWCHAR *str1, SQLWCHAR *str2 )
3641{
3642 SQLWCHAR *retp = str1;
3643
3644 if ( !str1 )
3645 return NULL;
3646
3647 while( *str2 )
3648 {
3649 *str1 = *str2;
3650 str1 ++;
3651 str2 ++;
3652 }
3653 *str1 = 0;
3654
3655 return retp;
3656}
3657
3658SQLWCHAR *wide_strncpy( SQLWCHAR *str1, SQLWCHAR *str2, int buffer_length )
3659{
3660 SQLWCHAR *retp = str1;
3661
3662 if ( !str1 )
3663 return NULL;
3664
3665 while( *str2 && buffer_length > 0 )
3666 {
3667 *str1 = *str2;
3668 str1 ++;
3669 str2 ++;
3670 buffer_length --;
3671 }
3672 *str1 = 0;
3673
3674 return retp;
3675}
3676
3677SQLWCHAR *wide_strcat( SQLWCHAR *str1, SQLWCHAR *str2 )
3678{
3679 SQLWCHAR *retp = str1;
3680
3681 while( *str1 )
3682 {
3683 str1 ++;
3684 }
3685
3686 while( *str2 )
3687 {
3688 *str1 = *str2;
3689 str1 ++;
3690 str2 ++;
3691 }
3692 *str1 = 0;
3693
3694 return retp;
3695}
3696
3697SQLWCHAR *wide_strdup( SQLWCHAR *str1 )
3698{
3699 SQLWCHAR *ptr;
3700 int len = 0;
3701
3702 while( str1[ len ] )
3703 len ++;
3704
3705 ptr = malloc( sizeof( SQLWCHAR ) * ( len + 1 ));
3706 if ( !ptr )
3707 return NULL;
3708
3709 return wide_strcpy( ptr, str1 );
3710}
3711
3712int wide_strlen( SQLWCHAR *str1 )
3713{
3714 int len = 0;
3715
3716 while( str1[ len ] ) {
3717 len ++;
3718 }
3719
3720 return len;
3721}
3722
3723static int check_error_order( ERROR *e1, ERROR *e2, EHEAD *head )
3724{
3725 char *s1, *s2;
3726 int ret;
3727
3728 /*
3729 * as far as I can see, a simple strcmp gives the order we need
3730 */
3731
3732 s1 = unicode_to_ansi_alloc( e1 -> sqlstate, SQL_NTS, __get_connection( head ), NULL);
3733 s2 = unicode_to_ansi_alloc( e2 -> sqlstate, SQL_NTS, __get_connection( head ), NULL );
3734
3735 ret = strcmp( s1, s2 );
3736
3737 free( s1 );
3738 free( s2 );
3739
3740 return ret;
3741}
3742
3743/*
3744 * insert the error into the list, making sure its in the correct
3745 * order
3746 */
3747
3748static void insert_into_error_list( EHEAD *error_header, ERROR *e1 )
3749{
3750 error_header -> sql_error_head.error_count ++;
3751
3752 if ( error_header -> sql_error_head.error_list_head )
3753 {
3754 /*
3755 * find where in the list it needs to go
3756 */
3757
3758 ERROR *curr, *prev;
3759
3760 prev = NULL;
3761 curr = error_header -> sql_error_head.error_list_head;
3762 while ( curr && check_error_order( curr, e1, error_header ) >= 0 )
3763 {
3764 prev = curr;
3765 curr = curr -> next;
3766 }
3767
3768 if ( curr )
3769 {
3770 if ( prev )
3771 {
3772 /*
3773 * in the middle
3774 */
3775 e1 -> next = curr;
3776 e1 -> prev = curr -> prev;
3777 curr -> prev -> next = e1;
3778 curr -> prev = e1;
3779 }
3780 else
3781 {
3782 /*
3783 * at the beginning
3784 */
3785 e1 -> next = error_header -> sql_error_head.error_list_head;
3786 e1 -> prev = NULL;
3787 e1 -> next -> prev = e1;
3788 error_header -> sql_error_head.error_list_head = e1;
3789 }
3790 }
3791 else
3792 {
3793 /*
3794 * at the end
3795 */
3796
3797 e1 -> next = NULL;
3798 e1 -> prev = error_header -> sql_error_head.error_list_tail;
3799 e1 -> prev -> next = e1;
3800 error_header -> sql_error_head.error_list_tail = e1;
3801 }
3802 }
3803 else
3804 {
3805 e1 -> next = e1 -> prev = NULL;
3806 error_header -> sql_error_head.error_list_tail = e1;
3807 error_header -> sql_error_head.error_list_head = e1;
3808 }
3809}
3810
3811static void insert_into_diag_list( EHEAD *error_header, ERROR *e2 )
3812{
3813 error_header -> sql_diag_head.internal_count ++;
3814
3815 if ( error_header -> sql_diag_head.internal_list_head )
3816 {
3817 /*
3818 * find where in the list it needs to go
3819 */
3820
3821 ERROR *curr, *prev;
3822
3823 prev = NULL;
3824 curr = error_header -> sql_diag_head.internal_list_head;
3825 while ( curr && check_error_order( curr, e2, error_header ) >= 0 )
3826 {
3827 prev = curr;
3828 curr = curr -> next;
3829 }
3830
3831 if ( curr )
3832 {
3833 if ( prev )
3834 {
3835 /*
3836 * in the middle
3837 */
3838 e2 -> next = curr;
3839 e2 -> prev = curr -> prev;
3840 curr -> prev -> next = e2;
3841 curr -> prev = e2;
3842 }
3843 else
3844 {
3845 /*
3846 * at the beginning
3847 */
3848 e2 -> next = error_header -> sql_diag_head.internal_list_head;
3849 e2 -> prev = NULL;
3850 e2 -> next -> prev = e2;
3851 error_header -> sql_diag_head.internal_list_head = e2;
3852 }
3853 }
3854 else
3855 {
3856 /*
3857 * at the end
3858 */
3859
3860 e2 -> next = NULL;
3861 e2 -> prev = error_header -> sql_diag_head.internal_list_tail;
3862 e2 -> prev -> next = e2;
3863 error_header -> sql_diag_head.internal_list_tail = e2;
3864 }
3865 }
3866 else
3867 {
3868 e2 -> next = e2 -> prev = NULL;
3869 error_header -> sql_diag_head.internal_list_tail = e2;
3870 error_header -> sql_diag_head.internal_list_head = e2;
3871 }
3872}
3873
3874void __post_internal_error_ex( EHEAD *error_header,
3875 SQLCHAR *sqlstate,
3876 SQLINTEGER native_error,
3877 SQLCHAR *message_text,
3878 int class_origin,
3879 int subclass_origin )
3880{
3881 SQLCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
3882
3883 /*
3884 * add our prefix
3885 */
3886
3887 strcpy((char*) msg, ERROR_PREFIX );
3888 strcat((char*) msg, (char*) message_text );
3889
3890 __post_internal_error_ex_noprefix(
3891 error_header,
3892 sqlstate,
3893 native_error,
3894 msg,
3895 class_origin,
3896 subclass_origin );
3897}
3898
3899void __post_internal_error_ex_noprefix( EHEAD *error_header,
3900 SQLCHAR *sqlstate,
3901 SQLINTEGER native_error,
3902 SQLCHAR *msg,
3903 int class_origin,
3904 int subclass_origin )
3905{
3906 /*
3907 * create a error block and add to the lists,
3908 * leave space for the error prefix
3909 */
3910
3911 ERROR *e1, *e2;
3912 DMHDBC conn = __get_connection( error_header );
3913
3914 e1 = malloc( sizeof( ERROR ));
3915 if (e1 == NULL)
3916 return;
3917 e2 = malloc( sizeof( ERROR ));
3918 if (e2 == NULL)
3919 {
3920 free(e1);
3921 return;
3922 }
3923
3924 memset( e1, 0, sizeof( *e1 ));
3925 memset( e2, 0, sizeof( *e2 ));
3926
3927 e1 -> native_error = native_error;
3928 e2 -> native_error = native_error;
3929 ansi_to_unicode_copy(e1 -> sqlstate,
3930 (char*)sqlstate, SQL_NTS, conn, NULL );
3931 wide_strcpy( e2 -> sqlstate, e1 -> sqlstate );
3932
3933 e1 -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, conn, NULL );
3934 if ( !e1 -> msg )
3935 {
3936 free( e1 );
3937 free( e2 );
3938 return;
3939 }
3940 e2 -> msg = wide_strdup( e1 -> msg );
3941 if ( !e2 -> msg )
3942 {
3943 free( e1 -> msg);
3944 free( e1 );
3945 free( e2 );
3946 return;
3947 }
3948
3949 e1 -> return_val = SQL_ERROR;
3950 e2 -> return_val = SQL_ERROR;
3951
3952 e1 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER;
3953 e1 -> diag_row_number_ret = SQL_NO_ROW_NUMBER;
3954 e1 -> diag_class_origin_ret = SQL_SUCCESS;
3955 e1 -> diag_subclass_origin_ret = SQL_SUCCESS;
3956 e1 -> diag_connection_name_ret = SQL_SUCCESS;
3957 e1 -> diag_server_name_ret = SQL_SUCCESS;
3958 e1 -> diag_column_number = 0;
3959 e1 -> diag_row_number = 0;
3960
3961 e2 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER;
3962 e2 -> diag_row_number_ret = SQL_NO_ROW_NUMBER;
3963 e2 -> diag_class_origin_ret = SQL_SUCCESS;
3964 e2 -> diag_subclass_origin_ret = SQL_SUCCESS;
3965 e2 -> diag_connection_name_ret = SQL_SUCCESS;
3966 e2 -> diag_server_name_ret = SQL_SUCCESS;
3967 e2 -> diag_column_number = 0;
3968 e2 -> diag_row_number = 0;
3969
3970 if ( class_origin == SUBCLASS_ODBC )
3971 ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ODBC 3.0",
3972 SQL_NTS, conn, NULL );
3973 else
3974 ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ISO 9075",
3975 SQL_NTS, conn, NULL );
3976 wide_strcpy( e2 -> diag_class_origin, e1 -> diag_class_origin );
3977
3978 if ( subclass_origin == SUBCLASS_ODBC )
3979 ansi_to_unicode_copy( e1 -> diag_subclass_origin, (char*) "ODBC 3.0",
3980 SQL_NTS, conn, NULL );
3981 else
3982 ansi_to_unicode_copy( e1 -> diag_subclass_origin, (char*) "ISO 9075",
3983 SQL_NTS, conn, NULL );
3984 wide_strcpy( e2 -> diag_subclass_origin, e1 -> diag_subclass_origin );
3985
3986 ansi_to_unicode_copy( e1 -> diag_connection_name, (char*) "", SQL_NTS,
3987 conn, NULL );
3988 wide_strcpy( e2 -> diag_connection_name, e1 -> diag_connection_name );
3989
3990 ansi_to_unicode_copy( e1 -> diag_server_name, conn ? conn->dsn : (char*) "", SQL_NTS,
3991 conn, NULL );
3992 wide_strcpy( e2 -> diag_server_name, e1 -> diag_server_name );
3993
3994 /*
3995 * the list for SQLError puts both local and driver
3996 * errors in the same list
3997 */
3998
3999 insert_into_error_list( error_header, e1 );
4000 insert_into_diag_list( error_header, e2 );
4001}
4002
4003void __post_internal_error_ex_w( EHEAD *error_header,
4004 SQLWCHAR *sqlstate,
4005 SQLINTEGER native_error,
4006 SQLWCHAR *message_text,
4007 int class_origin,
4008 int subclass_origin )
4009{
4010 SQLWCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
4011
4012 /*
4013 * add our prefix
4014 */
4015
4016 ansi_to_unicode_copy(msg, (char*) ERROR_PREFIX, SQL_NTS,
4017 __get_connection( error_header ), NULL);
4018 wide_strcat( msg, message_text );
4019
4020 __post_internal_error_ex_w_noprefix(
4021 error_header,
4022 sqlstate,
4023 native_error,
4024 msg,
4025 class_origin,
4026 subclass_origin );
4027}
4028
4029void __post_internal_error_ex_w_noprefix( EHEAD *error_header,
4030 SQLWCHAR *sqlstate,
4031 SQLINTEGER native_error,
4032 SQLWCHAR *msg,
4033 int class_origin,
4034 int subclass_origin )
4035{
4036 /*
4037 * create a error block and add to the lists,
4038 * leave space for the error prefix
4039 */
4040
4041 ERROR *e1, *e2;
4042
4043 e1 = malloc( sizeof( ERROR ));
4044 if ( !e1 )
4045 return;
4046 e2 = malloc( sizeof( ERROR ));
4047 if ( !e2 )
4048 {
4049 free(e1);
4050 return;
4051 }
4052
4053 memset( e1, 0, sizeof( *e1 ));
4054 memset( e2, 0, sizeof( *e2 ));
4055
4056 e1 -> native_error = native_error;
4057 e2 -> native_error = native_error;
4058 wide_strcpy( e1 -> sqlstate, sqlstate );
4059 wide_strcpy( e2 -> sqlstate, sqlstate );
4060 e1 -> msg = wide_strdup( msg );
4061 e2 -> msg = wide_strdup( msg );
4062 e1 -> return_val = SQL_ERROR;
4063 e2 -> return_val = SQL_ERROR;
4064
4065 e1 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER;
4066 e1 -> diag_row_number_ret = SQL_NO_ROW_NUMBER;
4067 e1 -> diag_class_origin_ret = SQL_SUCCESS;
4068 e1 -> diag_subclass_origin_ret = SQL_SUCCESS;
4069 e1 -> diag_connection_name_ret = SQL_SUCCESS;
4070 e1 -> diag_server_name_ret = SQL_SUCCESS;
4071 e1 -> diag_column_number = 0;
4072 e1 -> diag_row_number = 0;
4073
4074 e2 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER;
4075 e2 -> diag_row_number_ret = SQL_NO_ROW_NUMBER;
4076 e2 -> diag_class_origin_ret = SQL_SUCCESS;
4077 e2 -> diag_subclass_origin_ret = SQL_SUCCESS;
4078 e2 -> diag_connection_name_ret = SQL_SUCCESS;
4079 e2 -> diag_server_name_ret = SQL_SUCCESS;
4080 e2 -> diag_column_number = 0;
4081 e2 -> diag_row_number = 0;
4082
4083 if ( class_origin == SUBCLASS_ODBC )
4084 ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ODBC 3.0",
4085 SQL_NTS, __get_connection( error_header ), NULL );
4086 else
4087 ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ISO 9075",
4088 SQL_NTS, __get_connection( error_header ), NULL );
4089 wide_strcpy( e2 -> diag_class_origin, e1 -> diag_class_origin );
4090
4091 if ( subclass_origin == SUBCLASS_ODBC )
4092 ansi_to_unicode_copy( e1 -> diag_subclass_origin, (char*) "ODBC 3.0",
4093 SQL_NTS, __get_connection( error_header ), NULL );
4094 else
4095 ansi_to_unicode_copy( e1 ->diag_subclass_origin, (char*) "ISO 9075",
4096 SQL_NTS, __get_connection( error_header ), NULL );
4097 wide_strcpy( e2 -> diag_subclass_origin, e1 -> diag_subclass_origin );
4098
4099 e1 -> diag_connection_name[ 0 ] = 0;
4100 e2 -> diag_connection_name[ 0 ] = 0;
4101
4102 e1 -> diag_server_name[ 0 ] = 0;
4103 e2 -> diag_server_name[ 0 ] = 0;
4104
4105 error_header -> return_code = SQL_ERROR;
4106
4107 /*
4108 * the list for SQLError puts both local and driver
4109 * errors in the same list
4110 */
4111
4112 insert_into_error_list( error_header, e1 );
4113 insert_into_diag_list( error_header, e2 );
4114}
4115
4116/*
4117 * initialise a error header and take note what it belongs to
4118 */
4119
4120void setup_error_head( EHEAD *error_header, void *handle, int type )
4121{
4122 memset( error_header, 0, sizeof( *error_header ));
4123
4124 error_header -> owning_handle = handle;
4125 error_header -> handle_type = type;
4126}
4127
4128/*
4129 * free any resources used but the error headers
4130 */
4131
4132void clear_error_head( EHEAD *error_header )
4133{
4134 ERROR *cur, *prev;
4135
4136 prev = NULL;
4137 cur = error_header -> sql_error_head.error_list_head;
4138
4139 while( cur )
4140 {
4141 prev = cur;
4142
4143 free( prev -> msg );
4144 cur = prev -> next;
4145 free( prev );
4146 }
4147
4148 error_header -> sql_error_head.error_list_head = NULL;
4149 error_header -> sql_error_head.error_list_tail = NULL;
4150
4151 prev = NULL;
4152 cur = error_header -> sql_diag_head.error_list_head;
4153
4154 while( cur )
4155 {
4156 prev = cur;
4157
4158 free( prev -> msg );
4159 cur = prev -> next;
4160 free( prev );
4161 }
4162
4163 error_header -> sql_diag_head.error_list_head = NULL;
4164 error_header -> sql_diag_head.error_list_tail = NULL;
4165
4166 prev = NULL;
4167 cur = error_header -> sql_diag_head.internal_list_head;
4168
4169 while( cur )
4170 {
4171 prev = cur;
4172
4173 free( prev -> msg );
4174 cur = prev -> next;
4175 free( prev );
4176 }
4177
4178 error_header -> sql_diag_head.internal_list_head = NULL;
4179 error_header -> sql_diag_head.internal_list_tail = NULL;
4180}
4181
4182/*
4183 * get the error values from the handle
4184 */
4185
4186static void extract_diag_error( int htype,
4187 DRV_SQLHANDLE handle,
4188 DMHDBC connection,
4189 EHEAD *head,
4190 int return_code,
4191 int save_to_diag )
4192{
4193 SQLRETURN ret;
4194 SQLCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
4195 SQLCHAR msg1[ SQL_MAX_MESSAGE_LENGTH + 1 ];
4196 SQLCHAR sqlstate[ 6 ];
4197 SQLINTEGER native, len;
4198 SQLINTEGER rec_number;
4199
4200 head -> return_code = return_code;
4201 head -> header_set = 0;
4202 head -> diag_cursor_row_count_ret = SQL_ERROR;
4203 head -> diag_dynamic_function_ret = SQL_ERROR;
4204 head -> diag_dynamic_function_code_ret = SQL_ERROR;
4205 head -> diag_number_ret = SQL_ERROR;
4206 head -> diag_row_count_ret = SQL_ERROR;
4207
4208 rec_number = 1;
4209 do
4210 {
4211 len = 0;
4212
4213 ret = SQLGETDIAGREC( connection,
4214 head -> handle_type,
4215 handle,
4216 rec_number,
4217 sqlstate,
4218 &native,
4219 msg1,
4220 sizeof( msg1 ),
4221 &len );
4222
4223
4224 if ( SQL_SUCCEEDED( ret ))
4225 {
4226 ERROR *e = malloc( sizeof( ERROR ));
4227 SQLWCHAR *tmp;
4228
4229 /*
4230 * make sure we are truncated in the right place
4231 */
4232
4233 if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) {
4234 msg1[ SQL_MAX_MESSAGE_LENGTH - 1 ] = '\0';
4235 }
4236
4237#ifdef STRICT_ODBC_ERROR
4238 strcpy((char*) msg, (char*)msg1 );
4239#else
4240 strcpy((char*) msg, ERROR_PREFIX );
4241 strcat((char*) msg, (char*)msg1 );
4242#endif
4243
4244 /*
4245 * add to the SQLError list
4246 */
4247
4248 e -> native_error = native;
4249 tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL );
4250 wide_strcpy( e -> sqlstate, tmp );
4251 free( tmp );
4252 e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4253 e -> return_val = return_code;
4254
4255 insert_into_error_list( head, e );
4256
4257 /*
4258 * we do this if called from a DM function that goes on to call
4259 * a further driver function before returning
4260 */
4261
4262 if ( save_to_diag )
4263 {
4264 SQLWCHAR *tmp;
4265
4266 e = malloc( sizeof( ERROR ));
4267 e -> native_error = native;
4268 tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL );
4269 wide_strcpy( e -> sqlstate, tmp );
4270 free( tmp );
4271 e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4272 e -> return_val = return_code;
4273
4274 insert_into_diag_list( head, e );
4275
4276 /*
4277 * now we need to do some extra calls to get
4278 * extended info
4279 */
4280
4281 e -> diag_column_number_ret = SQL_ERROR;
4282 e -> diag_row_number_ret = SQL_ERROR;
4283 e -> diag_class_origin_ret = SQL_ERROR;
4284 e -> diag_subclass_origin_ret = SQL_ERROR;
4285 e -> diag_connection_name_ret = SQL_ERROR;
4286 e -> diag_server_name_ret= SQL_ERROR;
4287
4288
4289 if ( head -> handle_type == SQL_HANDLE_STMT )
4290 {
4291 if ( rec_number == 1 )
4292 {
4293 head -> header_set = 1;
4294 head -> diag_cursor_row_count_ret = SQLGETDIAGFIELD( connection,
4295 head -> handle_type,
4296 handle,
4297 0,
4298 SQL_DIAG_CURSOR_ROW_COUNT,
4299 &head->diag_cursor_row_count,
4300 0,
4301 NULL );
4302
4303 if ( SQL_SUCCEEDED( head -> diag_dynamic_function_ret = SQLGETDIAGFIELD( connection,
4304 head -> handle_type,
4305 handle,
4306 0,
4307 SQL_DIAG_DYNAMIC_FUNCTION,
4308 msg,
4309 sizeof( msg ),
4310 &len )))
4311 {
4312 tmp = ansi_to_unicode_alloc(msg, SQL_NTS, connection, NULL );
4313 wide_strcpy( head->diag_dynamic_function, tmp );
4314 free( tmp );
4315 }
4316
4317 head -> diag_dynamic_function_code_ret = SQLGETDIAGFIELD( connection,
4318 head -> handle_type,
4319 handle,
4320 0,
4321 SQL_DIAG_DYNAMIC_FUNCTION_CODE,
4322 &head->diag_dynamic_function_code,
4323 0,
4324 NULL );
4325
4326 head -> diag_number_ret = SQLGETDIAGFIELD( connection,
4327 head -> handle_type,
4328 handle,
4329 0,
4330 SQL_DIAG_NUMBER,
4331 &head->diag_number,
4332 0,
4333 NULL );
4334
4335 head -> diag_row_count_ret = SQLGETDIAGFIELD( connection,
4336 head -> handle_type,
4337 handle,
4338 0,
4339 SQL_DIAG_ROW_COUNT,
4340 &head->diag_row_count,
4341 0,
4342 NULL );
4343 }
4344
4345 e -> diag_column_number_ret = SQLGETDIAGFIELD( connection,
4346 head -> handle_type,
4347 handle,
4348 rec_number,
4349 SQL_DIAG_COLUMN_NUMBER,
4350 &e->diag_column_number,
4351 0,
4352 NULL );
4353
4354 e -> diag_row_number_ret = SQLGETDIAGFIELD( connection,
4355 head -> handle_type,
4356 handle,
4357 rec_number,
4358 SQL_DIAG_ROW_NUMBER,
4359 &e->diag_row_number,
4360 0,
4361 NULL );
4362 }
4363 else
4364 {
4365 e -> diag_column_number_ret = SQL_ERROR;
4366 e -> diag_row_number_ret = SQL_ERROR;
4367 e -> diag_class_origin_ret = SQL_ERROR;
4368 e -> diag_subclass_origin_ret = SQL_ERROR;
4369 e -> diag_connection_name_ret = SQL_ERROR;
4370 e -> diag_server_name_ret= SQL_ERROR;
4371
4372 if ( SQL_SUCCEEDED( e -> diag_class_origin_ret = SQLGETDIAGFIELD( connection,
4373 head -> handle_type,
4374 handle,
4375 rec_number,
4376 SQL_DIAG_CLASS_ORIGIN,
4377 msg,
4378 sizeof( msg ),
4379 &len )))
4380 {
4381 tmp = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4382 wide_strcpy( e->diag_class_origin, tmp );
4383 free( tmp );
4384 }
4385
4386 if ( SQL_SUCCEEDED( e -> diag_subclass_origin_ret = SQLGETDIAGFIELD( connection,
4387 head -> handle_type,
4388 handle,
4389 rec_number,
4390 SQL_DIAG_SUBCLASS_ORIGIN,
4391 msg,
4392 sizeof( msg ),
4393 &len )))
4394 {
4395 tmp = ansi_to_unicode_alloc(msg, SQL_NTS, connection, NULL );
4396 wide_strcpy( e->diag_subclass_origin, tmp );
4397 free( tmp );
4398 }
4399
4400 if ( SQL_SUCCEEDED( e -> diag_connection_name_ret = SQLGETDIAGFIELD( connection,
4401 head -> handle_type,
4402 handle,
4403 rec_number,
4404 SQL_DIAG_CONNECTION_NAME,
4405 msg,
4406 sizeof( msg ),
4407 &len )))
4408 {
4409 tmp = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4410 wide_strcpy( e->diag_connection_name, tmp );
4411 free( tmp );
4412 }
4413
4414 if ( SQL_SUCCEEDED( e -> diag_server_name_ret = SQLGETDIAGFIELD( connection,
4415 head -> handle_type,
4416 handle,
4417 rec_number,
4418 SQL_DIAG_SERVER_NAME,
4419 msg,
4420 sizeof( msg ),
4421 &len )))
4422 {
4423 tmp = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4424 wide_strcpy( e -> diag_server_name, tmp );
4425 free( tmp );
4426 }
4427 }
4428 }
4429 else
4430 {
4431 head -> sql_diag_head.error_count ++;
4432 }
4433
4434 rec_number ++;
4435
4436 /*
4437 * add to logfile
4438 */
4439
4440 if ( log_info.log_flag )
4441 {
4442 sprintf( connection -> msg, "\t\tDIAG [%s] %s",
4443 sqlstate, msg1 );
4444
4445 dm_log_write_diag( connection -> msg );
4446 }
4447 }
4448 }
4449 while( SQL_SUCCEEDED( ret ));
4450}
4451
4452static void extract_sql_error( DRV_SQLHANDLE henv,
4453 DRV_SQLHANDLE hdbc,
4454 DRV_SQLHANDLE hstmt,
4455 DMHDBC connection,
4456 EHEAD *head,
4457 int return_code )
4458{
4459 SQLRETURN ret;
4460 SQLCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
4461 SQLCHAR msg1[ SQL_MAX_MESSAGE_LENGTH + 1 ];
4462 SQLCHAR sqlstate[ 6 ];
4463 SQLINTEGER native;
4464 SQLSMALLINT len;
4465
4466 head -> return_code = return_code;
4467 head -> header_set = 0;
4468 head -> diag_cursor_row_count_ret = SQL_ERROR;
4469 head -> diag_dynamic_function_ret = SQL_ERROR;
4470 head -> diag_dynamic_function_code_ret = SQL_ERROR;
4471 head -> diag_number_ret = SQL_ERROR;
4472 head -> diag_row_count_ret = SQL_ERROR;
4473
4474 do
4475 {
4476 len = 0;
4477
4478 ret = SQLERROR( connection,
4479 henv,
4480 hdbc,
4481 hstmt,
4482 sqlstate,
4483 &native,
4484 msg1,
4485 sizeof( msg1 ),
4486 &len );
4487
4488 if ( SQL_SUCCEEDED( ret ))
4489 {
4490 SQLWCHAR *tmp;
4491 ERROR *e = malloc( sizeof( ERROR ));
4492
4493 /*
4494 * add to the lists, SQLError list first
4495 */
4496
4497 /*
4498 * add our prefix
4499 */
4500
4501 /*
4502 * make sure we are truncated in the right place
4503 */
4504
4505 if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) {
4506 msg1[ SQL_MAX_MESSAGE_LENGTH ] = '\0';
4507 }
4508
4509#ifdef STRICT_ODBC_ERROR
4510 strcpy((char*) msg, (char*)msg1 );
4511#else
4512 strcpy((char*) msg, ERROR_PREFIX );
4513 strcat((char*) msg, (char*)msg1 );
4514#endif
4515
4516 e -> native_error = native;
4517 tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL );
4518 wide_strcpy( e -> sqlstate, tmp );
4519 free( tmp );
4520 e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4521 e -> return_val = return_code;
4522
4523 insert_into_error_list( head, e );
4524
4525 /*
4526 * SQLGetDiagRec list next
4527 */
4528
4529 e = malloc( sizeof( ERROR ));
4530
4531 e -> diag_column_number_ret = SQL_ERROR;
4532 e -> diag_row_number_ret = SQL_ERROR;
4533 e -> diag_class_origin_ret = SQL_ERROR;
4534 e -> diag_subclass_origin_ret = SQL_ERROR;
4535 e -> diag_connection_name_ret = SQL_ERROR;
4536 e -> diag_server_name_ret= SQL_ERROR;
4537
4538 e -> native_error = native;
4539 tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL );
4540 wide_strcpy( e -> sqlstate, tmp );
4541 free( tmp );
4542 e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4543 e -> return_val = return_code;
4544
4545 insert_into_diag_list( head, e );
4546
4547 /*
4548 * add to logfile
4549 */
4550
4551 if ( log_info.log_flag )
4552 {
4553 sprintf( connection -> msg, "\t\tDIAG [%s] %s",
4554 sqlstate, msg1 );
4555
4556 dm_log_write_diag( connection -> msg );
4557 }
4558 }
4559 }
4560 while( SQL_SUCCEEDED( ret ));
4561}
4562
4563static void extract_diag_error_w( int htype,
4564 DRV_SQLHANDLE handle,
4565 DMHDBC connection,
4566 EHEAD *head,
4567 int return_code,
4568 int save_to_diag )
4569{
4570 SQLRETURN ret;
4571 SQLWCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
4572 SQLWCHAR msg1[ SQL_MAX_MESSAGE_LENGTH + 1 ];
4573 SQLWCHAR sqlstate[ 6 ];
4574 SQLINTEGER native, len;
4575 SQLINTEGER rec_number;
4576
4577 head -> return_code = return_code;
4578 head -> header_set = 0;
4579 head -> diag_cursor_row_count_ret = SQL_ERROR;
4580 head -> diag_dynamic_function_ret = SQL_ERROR;
4581 head -> diag_dynamic_function_code_ret = SQL_ERROR;
4582 head -> diag_number_ret = SQL_ERROR;
4583 head -> diag_row_count_ret = SQL_ERROR;
4584
4585 rec_number = 1;
4586 do
4587 {
4588 len = 0;
4589
4590 ret = SQLGETDIAGRECW( connection,
4591 head -> handle_type,
4592 handle,
4593 rec_number,
4594 sqlstate,
4595 &native,
4596 msg1,
4597 SQL_MAX_MESSAGE_LENGTH,
4598 &len );
4599
4600 if ( SQL_SUCCEEDED( ret ))
4601 {
4602 ERROR *e = malloc( sizeof( ERROR ));
4603 SQLWCHAR *tmp;
4604
4605 /*
4606 * make sure we are truncated in the right place
4607 */
4608
4609 if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) {
4610 msg1[ SQL_MAX_MESSAGE_LENGTH ] = 0;
4611 }
4612
4613#ifdef STRICT_ODBC_ERROR
4614 wide_strcpy( msg, msg1 );
4615#else
4616 tmp = ansi_to_unicode_alloc((SQLCHAR*) ERROR_PREFIX, SQL_NTS, connection );
4617 wide_strcpy( msg, tmp );
4618 free( tmp );
4619 wide_strcat( msg, msg1 );
4620#endif
4621
4622 /*
4623 * add to the SQLError list
4624 */
4625
4626 e -> native_error = native;
4627 wide_strcpy( e -> sqlstate, sqlstate );
4628 e -> msg = wide_strdup( msg );
4629 e -> return_val = return_code;
4630
4631 insert_into_error_list( head, e );
4632
4633 /*
4634 * we do this if called from a DM function that goes on to call
4635 * a further driver function before returning
4636 */
4637
4638 if ( save_to_diag )
4639 {
4640 e = malloc( sizeof( ERROR ));
4641 e -> native_error = native;
4642 wide_strcpy( e -> sqlstate, sqlstate );
4643 e -> msg = wide_strdup( msg );
4644 e -> return_val = return_code;
4645
4646 insert_into_diag_list( head, e );
4647
4648 /*
4649 * now we need to do some extra calls to get
4650 * extended info
4651 */
4652
4653 e -> diag_column_number_ret = SQL_ERROR;
4654 e -> diag_row_number_ret = SQL_ERROR;
4655 e -> diag_class_origin_ret = SQL_ERROR;
4656 e -> diag_subclass_origin_ret = SQL_ERROR;
4657 e -> diag_connection_name_ret = SQL_ERROR;
4658 e -> diag_server_name_ret= SQL_ERROR;
4659
4660 if ( head -> handle_type == SQL_HANDLE_STMT )
4661 {
4662 if ( rec_number == 1 )
4663 {
4664 head -> header_set = 1;
4665
4666 head -> diag_cursor_row_count_ret = SQLGETDIAGFIELDW( connection,
4667 head -> handle_type,
4668 handle,
4669 0,
4670 SQL_DIAG_CURSOR_ROW_COUNT,
4671 &head->diag_cursor_row_count,
4672 0,
4673 NULL );
4674
4675 head -> diag_dynamic_function_ret = SQLGETDIAGFIELDW( connection,
4676 head -> handle_type,
4677 handle,
4678 0,
4679 SQL_DIAG_DYNAMIC_FUNCTION,
4680 head->diag_dynamic_function,
4681 sizeof( head->diag_dynamic_function ),
4682 &len );
4683
4684 head -> diag_dynamic_function_code_ret = SQLGETDIAGFIELDW( connection,
4685 head -> handle_type,
4686 handle,
4687 0,
4688 SQL_DIAG_DYNAMIC_FUNCTION_CODE,
4689 &head->diag_dynamic_function_code,
4690 0,
4691 NULL );
4692
4693 head -> diag_number_ret = SQLGETDIAGFIELDW( connection,
4694 head -> handle_type,
4695 handle,
4696 0,
4697 SQL_DIAG_NUMBER,
4698 &head->diag_number,
4699 0,
4700 NULL );
4701
4702 head -> diag_row_count_ret = SQLGETDIAGFIELDW( connection,
4703 head -> handle_type,
4704 handle,
4705 0,
4706 SQL_DIAG_ROW_COUNT,
4707 &head->diag_row_count,
4708 0,
4709 NULL );
4710 }
4711
4712 e -> diag_column_number_ret = SQLGETDIAGFIELDW( connection,
4713 head -> handle_type,
4714 handle,
4715 rec_number,
4716 SQL_DIAG_COLUMN_NUMBER,
4717 &e->diag_column_number,
4718 0,
4719 NULL );
4720
4721 e -> diag_row_number_ret = SQLGETDIAGFIELDW( connection,
4722 head -> handle_type,
4723 handle,
4724 rec_number,
4725 SQL_DIAG_ROW_NUMBER,
4726 &e->diag_row_number,
4727 0,
4728 NULL );
4729 }
4730 else
4731 {
4732 e -> diag_column_number_ret = SQL_ERROR;
4733 e -> diag_row_number_ret = SQL_ERROR;
4734 e -> diag_class_origin_ret = SQL_ERROR;
4735 e -> diag_subclass_origin_ret = SQL_ERROR;
4736 e -> diag_connection_name_ret = SQL_ERROR;
4737 e -> diag_server_name_ret= SQL_ERROR;
4738
4739 e -> diag_class_origin_ret = SQLGETDIAGFIELDW( connection,
4740 head -> handle_type,
4741 handle,
4742 rec_number,
4743 SQL_DIAG_CLASS_ORIGIN,
4744 e->diag_class_origin,
4745 sizeof( e->diag_class_origin ),
4746 &len );
4747
4748 e -> diag_subclass_origin_ret = SQLGETDIAGFIELDW( connection,
4749 head -> handle_type,
4750 handle,
4751 rec_number,
4752 SQL_DIAG_SUBCLASS_ORIGIN,
4753 e->diag_subclass_origin,
4754 sizeof( e->diag_subclass_origin ),
4755 &len );
4756
4757 e -> diag_connection_name_ret = SQLGETDIAGFIELDW( connection,
4758 head -> handle_type,
4759 handle,
4760 rec_number,
4761 SQL_DIAG_CONNECTION_NAME,
4762 e->diag_connection_name,
4763 sizeof( e->diag_connection_name ),
4764 &len );
4765
4766 e -> diag_server_name_ret = SQLGETDIAGFIELDW( connection,
4767 head -> handle_type,
4768 handle,
4769 rec_number,
4770 SQL_DIAG_SERVER_NAME,
4771 e->diag_server_name,
4772 sizeof( e->diag_server_name ),
4773 &len );
4774 }
4775 }
4776 else
4777 {
4778 head -> sql_diag_head.error_count ++;
4779 }
4780
4781 rec_number ++;
4782
4783 /*
4784 * add to logfile
4785 */
4786
4787 if ( log_info.log_flag )
4788 {
4789 SQLCHAR *as1, *as2;
4790
4791 as1 = (SQLCHAR*) unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL );
4792 as2 = (SQLCHAR*) unicode_to_ansi_alloc( msg1, SQL_NTS, connection, NULL );
4793
4794 sprintf( connection -> msg, "\t\tDIAG [%s] %s",
4795 as1, as2 );
4796
4797 if( as1 ) free( as1 );
4798 if( as2 ) free( as2 );
4799
4800 dm_log_write_diag( connection -> msg );
4801 }
4802 }
4803 }
4804 while( SQL_SUCCEEDED( ret ));
4805}
4806
4807static void extract_sql_error_w( DRV_SQLHANDLE henv,
4808 DRV_SQLHANDLE hdbc,
4809 DRV_SQLHANDLE hstmt,
4810 DMHDBC connection,
4811 EHEAD *head,
4812 int return_code )
4813{
4814 SQLRETURN ret;
4815 SQLWCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
4816 SQLWCHAR msg1[ SQL_MAX_MESSAGE_LENGTH + 1 ];
4817 SQLWCHAR sqlstate[ 6 ];
4818 SQLINTEGER native;
4819 SQLSMALLINT len;
4820
4821 head -> return_code = return_code;
4822
4823 do
4824 {
4825 len = 0;
4826
4827 ret = SQLERRORW( connection,
4828 henv,
4829 hdbc,
4830 hstmt,
4831 sqlstate,
4832 &native,
4833 msg1,
4834 SQL_MAX_MESSAGE_LENGTH,
4835 &len );
4836
4837 if ( SQL_SUCCEEDED( ret ))
4838 {
4839 SQLWCHAR *tmp;
4840
4841 /*
4842 * add to the lists, SQLError list first
4843 */
4844
4845 ERROR *e = malloc( sizeof( ERROR ));
4846
4847 /*
4848 * add our prefix
4849 */
4850
4851 /*
4852 * make sure we are truncated in the right place
4853 */
4854
4855 if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) {
4856 msg1[ SQL_MAX_MESSAGE_LENGTH ] = 0;
4857 }
4858
4859#ifdef STRICT_ODBC_ERROR
4860 wide_strcpy( msg, msg1 );
4861#else
4862 tmp = ansi_to_unicode_alloc((SQLCHAR*) ERROR_PREFIX, SQL_NTS, connection, NULL );
4863 wide_strcpy( msg, tmp );
4864 free( tmp );
4865 wide_strcat( msg, msg1 );
4866#endif
4867
4868 e -> native_error = native;
4869 wide_strcpy( e -> sqlstate, sqlstate );
4870 e -> msg = wide_strdup( msg );
4871 e -> return_val = return_code;
4872
4873 insert_into_error_list( head, e );
4874
4875 /*
4876 * SQLGetDiagRec list next
4877 */
4878
4879 e = malloc( sizeof( ERROR ));
4880 e -> native_error = native;
4881 wide_strcpy( e -> sqlstate, sqlstate );
4882 e -> msg = wide_strdup( msg );
4883 e -> return_val = return_code;
4884
4885 insert_into_diag_list( head, e );
4886
4887 /*
4888 * add to logfile
4889 */
4890
4891 if ( log_info.log_flag )
4892 {
4893 SQLCHAR *as1, *as2;
4894
4895 as1 = (SQLCHAR*) unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL );
4896 as2 = (SQLCHAR*) unicode_to_ansi_alloc( msg1, SQL_NTS, connection, NULL );
4897
4898 sprintf( connection -> msg, "\t\tDIAG [%s] %s",
4899 as1, as2 );
4900
4901 if( as1 ) free( as1 );
4902 if( as2 ) free( as2 );
4903
4904 dm_log_write_diag( connection -> msg );
4905 }
4906 }
4907 }
4908 while( SQL_SUCCEEDED( ret ));
4909}
4910
4911/* Return without collecting diag recs from the handle - to be called if the
4912 DM function is returning before calling the driver function. */
4913int function_return_nodrv( int level, void *handle, int ret_code)
4914{
4915 if ( level != IGNORE_THREAD )
4916 {
4917 thread_release( level, handle );
4918 }
4919 return ret_code;
4920}
4921
4922/*
4923 * capture function returns and check error's if necessary
4924 */
4925
4926int function_return_ex( int level, void * handle, int ret_code, int save_to_diag )
4927{
4928 DMHENV henv;
4929 DMHDBC hdbc;
4930 DMHSTMT hstmt;
4931 DMHDESC hdesc;
4932
4933 if ( ret_code == SQL_SUCCESS_WITH_INFO || ret_code == SQL_ERROR )
4934 {
4935 /*
4936 * find what type of handle it is
4937 */
4938
4939 henv = handle;
4940
4941 switch ( henv -> type )
4942 {
4943 case HENV_MAGIC:
4944 {
4945 /*
4946 * do nothing, it must be local
4947 */
4948 }
4949 break;
4950
4951 case HDBC_MAGIC:
4952 {
4953 hdbc = handle;
4954
4955 /*
4956 * are we connected ?
4957 */
4958
4959 if ( hdbc -> state >= STATE_C4 )
4960 {
4961 if ( hdbc -> unicode_driver )
4962 {
4963 if ( CHECK_SQLGETDIAGFIELDW( hdbc ) &&
4964 CHECK_SQLGETDIAGRECW( hdbc ))
4965 {
4966 extract_diag_error_w( SQL_HANDLE_DBC,
4967 hdbc -> driver_dbc,
4968 hdbc,
4969 &hdbc -> error,
4970 ret_code,
4971 save_to_diag );
4972 }
4973 else if ( CHECK_SQLERRORW( hdbc ))
4974 {
4975 extract_sql_error_w( SQL_NULL_HENV,
4976 hdbc -> driver_dbc,
4977 SQL_NULL_HSTMT,
4978 hdbc,
4979 &hdbc -> error,
4980 ret_code );
4981 }
4982 else if ( CHECK_SQLGETDIAGFIELD( hdbc ) &&
4983 CHECK_SQLGETDIAGREC( hdbc ))
4984 {
4985 extract_diag_error( SQL_HANDLE_DBC,
4986 hdbc -> driver_dbc,
4987 hdbc,
4988 &hdbc -> error,
4989 ret_code,
4990 save_to_diag );
4991 }
4992 else if ( CHECK_SQLERROR( hdbc ))
4993 {
4994 extract_sql_error( SQL_NULL_HENV,
4995 hdbc -> driver_dbc,
4996 SQL_NULL_HSTMT,
4997 hdbc,
4998 &hdbc -> error,
4999 ret_code );
5000 }
5001 else
5002 {
5003 __post_internal_error( &hdbc -> error,
5004 ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found",
5005 hdbc -> environment -> requested_version );
5006 }
5007 }
5008 else
5009 {
5010 if ( CHECK_SQLGETDIAGFIELD( hdbc ) &&
5011 CHECK_SQLGETDIAGREC( hdbc ))
5012 {
5013 extract_diag_error( SQL_HANDLE_DBC,
5014 hdbc -> driver_dbc,
5015 hdbc,
5016 &hdbc -> error,
5017 ret_code,
5018 save_to_diag );
5019 }
5020 else if ( CHECK_SQLERROR( hdbc ))
5021 {
5022 extract_sql_error( SQL_NULL_HENV,
5023 hdbc -> driver_dbc,
5024 SQL_NULL_HSTMT,
5025 hdbc,
5026 &hdbc -> error,
5027 ret_code );
5028 }
5029 else if ( CHECK_SQLGETDIAGFIELDW( hdbc ) &&
5030 CHECK_SQLGETDIAGRECW( hdbc ))
5031 {
5032 extract_diag_error_w( SQL_HANDLE_DBC,
5033 hdbc -> driver_dbc,
5034 hdbc,
5035 &hdbc -> error,
5036 ret_code,
5037 save_to_diag );
5038 }
5039 else if ( CHECK_SQLERRORW( hdbc ))
5040 {
5041 extract_sql_error_w( SQL_NULL_HENV,
5042 hdbc -> driver_dbc,
5043 SQL_NULL_HSTMT,
5044 hdbc,
5045 &hdbc -> error,
5046 ret_code );
5047 }
5048 else
5049 {
5050 __post_internal_error( &hdbc -> error,
5051 ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found",
5052 hdbc -> environment -> requested_version );
5053 }
5054 }
5055 }
5056 }
5057 break;
5058
5059 case HSTMT_MAGIC:
5060 {
5061 hstmt = handle;
5062
5063 /*
5064 * how are we to get the error
5065 */
5066
5067 if ( hstmt -> connection -> unicode_driver )
5068 {
5069 if ( CHECK_SQLGETDIAGFIELDW( hstmt -> connection ) &&
5070 CHECK_SQLGETDIAGRECW( hstmt -> connection ))
5071 {
5072 extract_diag_error_w( SQL_HANDLE_STMT,
5073 hstmt -> driver_stmt,
5074 hstmt -> connection,
5075 &hstmt -> error,
5076 ret_code,
5077 save_to_diag );
5078 }
5079 else if ( CHECK_SQLERRORW( hstmt -> connection ))
5080 {
5081 extract_sql_error_w( SQL_NULL_HENV,
5082 SQL_NULL_HDBC,
5083 hstmt -> driver_stmt,
5084 hstmt -> connection,
5085 &hstmt -> error,
5086 ret_code );
5087 }
5088 else if ( CHECK_SQLGETDIAGFIELD( hstmt -> connection ) &&
5089 CHECK_SQLGETDIAGREC( hstmt -> connection ))
5090 {
5091 extract_diag_error( SQL_HANDLE_STMT,
5092 hstmt -> driver_stmt,
5093 hstmt -> connection,
5094 &hstmt -> error,
5095 ret_code,
5096 save_to_diag );
5097 }
5098 else if ( CHECK_SQLERROR( hstmt -> connection ))
5099 {
5100 extract_sql_error( SQL_NULL_HENV,
5101 SQL_NULL_HDBC,
5102 hstmt -> driver_stmt,
5103 hstmt -> connection,
5104 &hstmt -> error,
5105 ret_code );
5106 }
5107 else
5108 {
5109 __post_internal_error( &hstmt -> error,
5110 ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found",
5111 hstmt -> connection -> environment -> requested_version );
5112 }
5113 }
5114 else
5115 {
5116 if ( CHECK_SQLGETDIAGFIELD( hstmt -> connection ) &&
5117 CHECK_SQLGETDIAGREC( hstmt -> connection ))
5118 {
5119 extract_diag_error( SQL_HANDLE_STMT,
5120 hstmt -> driver_stmt,
5121 hstmt -> connection,
5122 &hstmt -> error,
5123 ret_code,
5124 save_to_diag );
5125 }
5126 else if ( CHECK_SQLERROR( hstmt -> connection ))
5127 {
5128 extract_sql_error( SQL_NULL_HENV,
5129 SQL_NULL_HDBC,
5130 hstmt -> driver_stmt,
5131 hstmt -> connection,
5132 &hstmt -> error,
5133 ret_code );
5134 }
5135 else if ( CHECK_SQLGETDIAGFIELDW( hstmt -> connection ) &&
5136 CHECK_SQLGETDIAGRECW( hstmt -> connection ))
5137 {
5138 extract_diag_error_w( SQL_HANDLE_STMT,
5139 hstmt -> driver_stmt,
5140 hstmt -> connection,
5141 &hstmt -> error,
5142 ret_code,
5143 save_to_diag );
5144 }
5145 else if ( CHECK_SQLERRORW( hstmt -> connection ))
5146 {
5147 extract_sql_error_w( SQL_NULL_HENV,
5148 SQL_NULL_HDBC,
5149 hstmt -> driver_stmt,
5150 hstmt -> connection,
5151 &hstmt -> error,
5152 ret_code );
5153 }
5154 else
5155 {
5156 __post_internal_error( &hstmt -> error,
5157 ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found",
5158 hstmt -> connection -> environment -> requested_version );
5159 }
5160 }
5161 }
5162 break;
5163
5164 case HDESC_MAGIC:
5165 {
5166 hdesc = handle;
5167
5168 if ( hdesc -> connection -> unicode_driver )
5169 {
5170 if ( CHECK_SQLGETDIAGFIELDW( hdesc -> connection ) &&
5171 CHECK_SQLGETDIAGRECW( hdesc -> connection ))
5172 {
5173 extract_diag_error_w( SQL_HANDLE_DESC,
5174 hdesc -> driver_desc,
5175 hdesc -> connection,
5176 &hdesc -> error,
5177 ret_code,
5178 save_to_diag );
5179 }
5180 else if ( CHECK_SQLGETDIAGFIELD( hdesc -> connection ) &&
5181 CHECK_SQLGETDIAGREC( hdesc -> connection ))
5182 {
5183 extract_diag_error( SQL_HANDLE_DESC,
5184 hdesc -> driver_desc,
5185 hdesc -> connection,
5186 &hdesc -> error,
5187 ret_code,
5188 save_to_diag );
5189 }
5190 else
5191 {
5192 __post_internal_error( &hdesc -> error,
5193 ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found",
5194 hdesc -> connection -> environment -> requested_version );
5195 }
5196 }
5197 else
5198 {
5199 if ( CHECK_SQLGETDIAGFIELD( hdesc -> connection ) &&
5200 CHECK_SQLGETDIAGREC( hdesc -> connection ))
5201 {
5202 extract_diag_error( SQL_HANDLE_DESC,
5203 hdesc -> driver_desc,
5204 hdesc -> connection,
5205 &hdesc -> error,
5206 ret_code,
5207 save_to_diag );
5208 }
5209 else if ( CHECK_SQLGETDIAGFIELDW( hdesc -> connection ) &&
5210 CHECK_SQLGETDIAGRECW( hdesc -> connection ))
5211 {
5212 extract_diag_error_w( SQL_HANDLE_DESC,
5213 hdesc -> driver_desc,
5214 hdesc -> connection,
5215 &hdesc -> error,
5216 ret_code,
5217 save_to_diag );
5218 }
5219 else
5220 {
5221 __post_internal_error( &hdesc -> error,
5222 ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found",
5223 hdesc -> connection -> environment -> requested_version );
5224 }
5225 }
5226 }
5227 break;
5228 }
5229 }
5230
5231 /*
5232 * release any threads
5233 */
5234
5235 if ( level != IGNORE_THREAD )
5236 {
5237 thread_release( level, handle );
5238 }
5239
5240 return ret_code;
5241}
5242
5243/*
5244 * clear errors down at the start of a new statement
5245 * only clear for the ODBC lists, the rest stay
5246 */
5247
5248void function_entry( void *handle )
5249{
5250 ERROR *cur, *prev;
5251 EHEAD *error_header;
5252 DMHENV henv;
5253 DMHDBC hdbc;
5254 DMHSTMT hstmt;
5255 DMHDESC hdesc;
5256 int version;
5257
5258 /*
5259 * find what the handle is
5260 */
5261
5262 henv = handle;
5263 switch( henv -> type )
5264 {
5265 case HENV_MAGIC:
5266 error_header = &henv -> error;
5267 version = henv -> requested_version;
5268 break;
5269
5270 case HDBC_MAGIC:
5271 hdbc = handle;
5272 error_header = &hdbc -> error;
5273 version = hdbc -> environment -> requested_version;
5274 break;
5275
5276 case HSTMT_MAGIC:
5277 hstmt = handle;
5278 error_header = &hstmt -> error;
5279 version = hstmt -> connection -> environment -> requested_version;
5280 break;
5281
5282 case HDESC_MAGIC:
5283 hdesc = handle;
5284 error_header = &hdesc -> error;
5285 version = hdesc -> connection -> environment -> requested_version;
5286 break;
5287 }
5288
5289 prev = NULL;
5290 cur = error_header -> sql_diag_head.error_list_head;
5291
5292 while( cur )
5293 {
5294 prev = cur;
5295
5296 free( prev -> msg );
5297 cur = prev -> next;
5298 free( prev );
5299 }
5300
5301 error_header -> sql_diag_head.error_list_head = NULL;
5302 error_header -> sql_diag_head.error_list_tail = NULL;
5303 error_header -> sql_diag_head.error_count = 0;
5304 error_header -> header_set = 0;
5305
5306 prev = NULL;
5307 cur = error_header -> sql_diag_head.internal_list_head;
5308
5309 while( cur )
5310 {
5311 prev = cur;
5312
5313 free( prev -> msg );
5314 cur = prev -> next;
5315 free( prev );
5316 }
5317
5318 error_header -> sql_diag_head.internal_list_head = NULL;
5319 error_header -> sql_diag_head.internal_list_tail = NULL;
5320 error_header -> sql_diag_head.internal_count = 0;
5321
5322 /*
5323 * if version is SQL_OV_ODBC3 then clear the SQLError list
5324 * as well
5325 */
5326
5327#ifdef USE_OLD_ODBC2_ERROR_CLEARING
5328 if ( version >= SQL_OV_ODBC3 )
5329#endif
5330 {
5331 prev = NULL;
5332 cur = error_header -> sql_error_head.error_list_head;
5333
5334 while( cur )
5335 {
5336 prev = cur;
5337
5338 free( prev -> msg );
5339 cur = prev -> next;
5340 free( prev );
5341 }
5342
5343 error_header -> sql_error_head.error_list_head = NULL;
5344 error_header -> sql_error_head.error_list_tail = NULL;
5345 error_header -> sql_error_head.error_count = 0;
5346 }
5347}
5348
5349void __post_internal_error( EHEAD *error_handle,
5350 error_id id, char *txt, int connection_mode )
5351{
5352 __post_internal_error_api( error_handle, id, txt, connection_mode, 0 );
5353
5354}
5355
5356void __post_internal_error_api( EHEAD *error_handle,
5357 error_id id, char *txt, int connection_mode, int calling_api )
5358{
5359 char sqlstate[ 6 ];
5360 char *message;
5361 SQLCHAR msg[ SQL_MAX_MESSAGE_LENGTH ];
5362 SQLRETURN ret = SQL_ERROR;
5363 int class, subclass;
5364
5365 class = SUBCLASS_ISO;
5366 subclass = SUBCLASS_ISO;
5367
5368 switch( id )
5369 {
5370 case ERROR_01000:
5371 strcpy( sqlstate, "01000" );
5372 message = "General warning";
5373 break;
5374
5375 case ERROR_01004:
5376 strcpy( sqlstate, "01004" );
5377 message = "String data, right truncated";
5378 break;
5379
5380 case ERROR_01S02:
5381 strcpy( sqlstate, "01S02" );
5382 message = "Option value changed";
5383 subclass = SUBCLASS_ODBC;
5384 break;
5385
5386 case ERROR_01S06:
5387 strcpy( sqlstate, "01S06" );
5388 message = "Attempt to fetch before the result set returned the first rowset";
5389 subclass = SUBCLASS_ODBC;
5390 break;
5391
5392 case ERROR_07005:
5393 strcpy( sqlstate, "07005" );
5394 message = "Prepared statement not a cursor-specification";
5395 break;
5396
5397 case ERROR_07009:
5398 switch( calling_api )
5399 {
5400 case SQL_API_SQLDESCRIBEPARAM:
5401 case SQL_API_SQLBINDPARAMETER:
5402 case SQL_API_SQLSETPARAM:
5403 if ( connection_mode >= SQL_OV_ODBC3 )
5404 strcpy( sqlstate, "07009" );
5405 else
5406 strcpy( sqlstate, "S1093" );
5407 message = "Invalid parameter index";
5408 break;
5409
5410 default:
5411 if ( connection_mode >= SQL_OV_ODBC3 )
5412 strcpy( sqlstate, "07009" );
5413 else
5414 strcpy( sqlstate, "S1002" );
5415 message = "Invalid descriptor index";
5416 break;
5417 }
5418 break;
5419
5420 case ERROR_08002:
5421 strcpy( sqlstate, "08002" );
5422 message = "Connection name in use";
5423 break;
5424
5425 case ERROR_08003:
5426 strcpy( sqlstate, "08003" );
5427 message = "Connection not open";
5428 break;
5429
5430 case ERROR_24000:
5431 strcpy( sqlstate, "24000" );
5432 message = "Invalid cursor state";
5433 break;
5434
5435 case ERROR_25000:
5436 message = "Invalid transaction state";
5437 strcpy( sqlstate, "25000" );
5438 break;
5439
5440 case ERROR_25S01:
5441 message = "Transaction state unknown";
5442 strcpy( sqlstate, "25S01" );
5443 subclass = SUBCLASS_ODBC;
5444 break;
5445
5446 case ERROR_S1000:
5447 message = "General error";
5448 strcpy( sqlstate, "S1000" );
5449 break;
5450
5451 case ERROR_S1003:
5452 message = "Program type out of range";
5453 strcpy( sqlstate, "S1003" );
5454 break;
5455
5456 case ERROR_S1010:
5457 message = "Function sequence error";
5458 strcpy( sqlstate, "S1010" );
5459 break;
5460
5461 case ERROR_S1011:
5462 message = "Operation invalid at this time";
5463 strcpy( sqlstate, "S1011" );
5464 break;
5465
5466 case ERROR_S1107:
5467 message = "Row value out of range";
5468 strcpy( sqlstate, "S1107" );
5469 break;
5470
5471 case ERROR_S1108:
5472 message = "Concurrency option out of range";
5473 strcpy( sqlstate, "S1108" );
5474 break;
5475
5476 case ERROR_S1C00:
5477 message = "Driver not capable";
5478 strcpy( sqlstate, "S1C00" );
5479 break;
5480
5481 case ERROR_HY001:
5482 if ( connection_mode >= SQL_OV_ODBC3 )
5483 strcpy( sqlstate, "HY001" );
5484 else
5485 strcpy( sqlstate, "S1011" );
5486 message = "Memory allocation error";
5487 break;
5488
5489 case ERROR_HY003:
5490 if ( connection_mode >= SQL_OV_ODBC3 )
5491 {
5492 strcpy( sqlstate, "HY003" );
5493 /* Windows DM returns " Program type out of range" instead of
5494 "Invalid application buffer type" */
5495 message = "Program type out of range";
5496 }
5497 else
5498 {
5499 strcpy( sqlstate, "S1003" );
5500 message = "Invalid application buffer type";
5501 }
5502 break;
5503
5504 case ERROR_HY004:
5505 if ( connection_mode >= SQL_OV_ODBC3 )
5506 strcpy( sqlstate, "HY004" );
5507 else
5508 strcpy( sqlstate, "S1004" );
5509 message = "Invalid SQL data type";
5510 break;
5511
5512 case ERROR_HY007:
5513 if ( connection_mode >= SQL_OV_ODBC3 )
5514 strcpy( sqlstate, "HY007" );
5515 else
5516 strcpy( sqlstate, "S1007" );
5517 message = "Associated statement is not prepared";
5518 break;
5519
5520 case ERROR_HY009:
5521 if ( connection_mode >= SQL_OV_ODBC3 )
5522 strcpy( sqlstate, "HY009" );
5523 else
5524 strcpy( sqlstate, "S1009" );
5525 message = "Invalid use of null pointer";
5526 break;
5527
5528 case ERROR_HY010:
5529 if ( connection_mode >= SQL_OV_ODBC3 )
5530 strcpy( sqlstate, "HY010" );
5531 else
5532 strcpy( sqlstate, "S1010" );
5533 message = "Function sequence error";
5534 break;
5535
5536 case ERROR_HY011:
5537 if ( connection_mode >= SQL_OV_ODBC3 )
5538 strcpy( sqlstate, "HY011" );
5539 else
5540 strcpy( sqlstate, "S1011" );
5541 message = "Attribute cannot be set now";
5542 break;
5543
5544 case ERROR_HY012:
5545 if ( connection_mode >= SQL_OV_ODBC3 )
5546 strcpy( sqlstate, "HY012" );
5547 else
5548 strcpy( sqlstate, "S1012" );
5549 message = "Invalid transaction operation code";
5550 break;
5551
5552 case ERROR_HY013:
5553 if ( connection_mode >= SQL_OV_ODBC3 )
5554 strcpy( sqlstate, "HY013" );
5555 else
5556 strcpy( sqlstate, "S1013" );
5557 message = "Memory management error";
5558 break;
5559
5560 case ERROR_HY017:
5561 strcpy( sqlstate, "HY017" );
5562 message = "Invalid use of an automatically allocated descriptor handle";
5563 break;
5564
5565 case ERROR_HY024:
5566 if ( connection_mode >= SQL_OV_ODBC3 )
5567 strcpy( sqlstate, "HY024" );
5568 else
5569 strcpy( sqlstate, "S1009" );
5570 message = "Invalid attribute value";
5571 break;
5572
5573 case ERROR_HY090:
5574 if ( connection_mode >= SQL_OV_ODBC3 )
5575 strcpy( sqlstate, "HY090" );
5576 else
5577 strcpy( sqlstate, "S1090" );
5578 message = "Invalid string or buffer length";
5579 break;
5580
5581 case ERROR_HY092:
5582 if ( connection_mode >= SQL_OV_ODBC3 )
5583 strcpy( sqlstate, "HY092" );
5584 else
5585 strcpy( sqlstate, "S1092" );
5586 message = "Invalid attribute/option identifier";
5587 break;
5588
5589 case ERROR_HY095:
5590 if ( connection_mode >= SQL_OV_ODBC3 )
5591 strcpy( sqlstate, "HY095" );
5592 else
5593 strcpy( sqlstate, "S1095" );
5594 message = "Function type out of range";
5595 break;
5596
5597 case ERROR_HY097:
5598 if ( connection_mode >= SQL_OV_ODBC3 )
5599 strcpy( sqlstate, "HY097" );
5600 else
5601 strcpy( sqlstate, "S1097" );
5602 message = "Column type out of range";
5603 break;
5604
5605 case ERROR_HY098:
5606 if ( connection_mode >= SQL_OV_ODBC3 )
5607 strcpy( sqlstate, "HY098" );
5608 else
5609 strcpy( sqlstate, "S1098" );
5610 message = "Scope type out of range";
5611 break;
5612
5613 case ERROR_HY099:
5614 if ( connection_mode >= SQL_OV_ODBC3 )
5615 strcpy( sqlstate, "HY099" );
5616 else
5617 strcpy( sqlstate, "S1099" );
5618 message = "Nullable type out of range";
5619 break;
5620
5621 case ERROR_HY100:
5622 if ( connection_mode >= SQL_OV_ODBC3 )
5623 strcpy( sqlstate, "HY100" );
5624 else
5625 strcpy( sqlstate, "S1100" );
5626 message = "Uniqueness option type out of range";
5627 break;
5628
5629 case ERROR_HY101:
5630 if ( connection_mode >= SQL_OV_ODBC3 )
5631 strcpy( sqlstate, "HY101" );
5632 else
5633 strcpy( sqlstate, "S1101" );
5634 message = "Accuracy option type out of range";
5635 break;
5636
5637 case ERROR_HY103:
5638 if ( connection_mode >= SQL_OV_ODBC3 )
5639 strcpy( sqlstate, "HY103" );
5640 else
5641 strcpy( sqlstate, "S1103" );
5642 message = "Invalid retrieval code";
5643 break;
5644
5645 case ERROR_HY105:
5646 if ( connection_mode >= SQL_OV_ODBC3 )
5647 strcpy( sqlstate, "HY105" );
5648 else
5649 strcpy( sqlstate, "S1105" );
5650 message = "Invalid parameter type";
5651 break;
5652
5653 case ERROR_HY106:
5654 if ( connection_mode >= SQL_OV_ODBC3 )
5655 strcpy( sqlstate, "HY106" );
5656 else
5657 strcpy( sqlstate, "S1106" );
5658 message = "Fetch type out of range";
5659 break;
5660
5661 case ERROR_HY110:
5662 if ( connection_mode >= SQL_OV_ODBC3 )
5663 strcpy( sqlstate, "HY110" );
5664 else
5665 strcpy( sqlstate, "S1110" );
5666 message = "Invalid driver completion";
5667 break;
5668
5669 case ERROR_HY111:
5670 if ( connection_mode >= SQL_OV_ODBC3 )
5671 strcpy( sqlstate, "HY111" );
5672 else
5673 strcpy( sqlstate, "S1111" );
5674 message = "Invalid bookmark value";
5675 break;
5676
5677 case ERROR_HYC00:
5678 if ( connection_mode >= SQL_OV_ODBC3 )
5679 strcpy( sqlstate, "HYC00" );
5680 else
5681 strcpy( sqlstate, "S1C00" );
5682 message = "Optional feature not implemented";
5683 break;
5684
5685 case ERROR_IM001:
5686 strcpy( sqlstate, "IM001" );
5687 message = "Driver does not support this function";
5688 subclass = SUBCLASS_ODBC;
5689 class = SUBCLASS_ODBC;
5690 break;
5691
5692 case ERROR_IM002:
5693 strcpy( sqlstate, "IM002" );
5694 message = "Data source name not found, and no default driver specified";
5695 subclass = SUBCLASS_ODBC;
5696 class = SUBCLASS_ODBC;
5697 break;
5698
5699 case ERROR_IM003:
5700 strcpy( sqlstate, "IM003" );
5701 message = "Specified driver could not be loaded";
5702 subclass = SUBCLASS_ODBC;
5703 class = SUBCLASS_ODBC;
5704 break;
5705
5706 case ERROR_IM004:
5707 strcpy( sqlstate, "IM004" );
5708 message = "Driver's SQLAllocHandle on SQL_HANDLE_HENV failed";
5709 subclass = SUBCLASS_ODBC;
5710 class = SUBCLASS_ODBC;
5711 break;
5712
5713 case ERROR_IM005:
5714 strcpy( sqlstate, "IM005" );
5715 message = "Driver's SQLAllocHandle on SQL_HANDLE_DBC failed";
5716 subclass = SUBCLASS_ODBC;
5717 class = SUBCLASS_ODBC;
5718 break;
5719
5720 case ERROR_IM010:
5721 strcpy( sqlstate, "IM010" );
5722 message = "Data source name too long";
5723 subclass = SUBCLASS_ODBC;
5724 class = SUBCLASS_ODBC;
5725 break;
5726
5727 case ERROR_IM011:
5728 strcpy( sqlstate, "IM011" );
5729 message = "Driver name too long";
5730 subclass = SUBCLASS_ODBC;
5731 class = SUBCLASS_ODBC;
5732 break;
5733
5734 case ERROR_IM012:
5735 strcpy( sqlstate, "IM012" );
5736 message = "DRIVER keyword syntax error";
5737 subclass = SUBCLASS_ODBC;
5738 class = SUBCLASS_ODBC;
5739 break;
5740
5741 case ERROR_SL004:
5742 strcpy( sqlstate, "SL004" );
5743 message = "Result set not generated by a SELECT statement";
5744 subclass = SUBCLASS_ODBC;
5745 class = SUBCLASS_ODBC;
5746 break;
5747
5748 case ERROR_SL009:
5749 strcpy( sqlstate, "SL009" );
5750 message = "No columns were bound prior to calling SQLFetch or SQLFetchScroll";
5751 subclass = SUBCLASS_ODBC;
5752 class = SUBCLASS_ODBC;
5753 break;
5754
5755 case ERROR_SL010:
5756 strcpy( sqlstate, "SL010" );
5757 message = "SQLBindCol returned SQL_ERROR on a attempt to bind a internal buffer";
5758 subclass = SUBCLASS_ODBC;
5759 class = SUBCLASS_ODBC;
5760 break;
5761
5762 case ERROR_SL008:
5763 strcpy( sqlstate, "SL008" );
5764 message = "SQLGetData is not allowed on a forward only (non-buffered) cursor";
5765 subclass = SUBCLASS_ODBC;
5766 class = SUBCLASS_ODBC;
5767 break;
5768
5769 case ERROR_HY000:
5770 if ( connection_mode >= SQL_OV_ODBC3 )
5771 strcpy( sqlstate, "HY000" );
5772 else
5773 strcpy( sqlstate, "S1000" );
5774 message = "General error";
5775 break;
5776
5777 default:
5778 strcpy( sqlstate, "?????" );
5779 message = "Unknown";
5780 }
5781
5782 if ( txt )
5783 message = txt;
5784
5785 strcpy((char*) msg, DM_ERROR_PREFIX );
5786 strncat((char*) msg, message, sizeof(msg) - sizeof(DM_ERROR_PREFIX) );
5787
5788 error_handle -> return_code = ret;
5789
5790 __post_internal_error_ex( error_handle,
5791 (SQLCHAR*)sqlstate, 0, msg, class, subclass );
5792}
5793
5794/*
5795 * open a log file
5796 */
5797
5798void dm_log_open( char *program_name,
5799 char *log_file_name, int pid_logging )
5800{
5801 if ( log_info.program_name )
5802 {
5803 free( log_info.program_name );
5804 }
5805 if ( log_info.log_file_name )
5806 {
5807 free( log_info.log_file_name );
5808 }
5809 log_info.program_name = strdup( program_name );
5810 log_info.log_file_name = strdup( log_file_name );
5811 log_info.log_flag = 1;
5812
5813 /*
5814 * are we doing perprocess logging
5815 */
5816
5817 log_info.pid_logging = pid_logging;
5818}
5819
5820void dm_log_write( char *function_name, int line, int type, int severity,
5821 char *message )
5822{
5823 FILE *fp;
5824 char tmp[ 24 ];
5825
5826 if ( !log_info.log_flag && !ODBCSharedTraceFlag )
5827 return;
5828
5829 if ( log_info.pid_logging )
5830 {
5831 char file_name[ 256 ], str[ 20 ];
5832
5833 if ( !log_info.log_file_name )
5834 {
5835 strcpy( file_name, "/tmp/sql.log" );
5836 }
5837 else
5838 {
5839 sprintf( file_name, "%s/%s", log_info.log_file_name, __get_pid((SQLCHAR*) str ));
5840 }
5841 fp = uo_fopen( file_name, "a" );
5842
5843 /*
5844 * Change the mode to be rw for all
5845 */
5846 chmod( file_name, 0666 );
5847 }
5848 else
5849 {
5850 if ( !log_info.log_file_name )
5851 {
5852 fp = uo_fopen( "/tmp/sql.log", "a" );
5853 }
5854 else
5855 {
5856 fp = uo_fopen( log_info.log_file_name, "a" );
5857 }
5858 }
5859
5860 if ( fp )
5861 {
5862 char tstamp_str[ 128 ];
5863
5864#if defined( HAVE_GETTIMEOFDAY ) && defined( HAVE_SYS_TIME_H )
5865 {
5866 struct timeval tv;
5867 void* tz = NULL;
5868
5869 gettimeofday( &tv, tz );
5870
5871 sprintf( tstamp_str, "[%ld.%06ld]", tv.tv_sec, tv.tv_usec );
5872 }
5873#elif defined( HAVE_FTIME ) && defined( HAVE_SYS_TIMEB_H )
5874 {
5875 struct timeb tp;
5876
5877 ftime( &tp );
5878
5879 sprintf( tstamp_str, "[%ld.%03d]", tp.time, tp.millitm );
5880 }
5881#elif defined( DHAVE_TIME ) && defined( HAVE_TIME_H )
5882 {
5883 time_t tv;
5884
5885 time( &tv );
5886 sprintf( tstamp_str, "[%ld]", tv );
5887 }
5888#else
5889 tstamp_str[ 0 ] = '\0';
5890#endif
5891 if ( !log_info.program_name )
5892 {
5893 uo_fprintf( fp, "[ODBC][%s]%s[%s][%d]%s\n", __get_pid((SQLCHAR*) tmp ),
5894 tstamp_str,
5895 function_name, line, message );
5896 }
5897 else
5898 {
5899 uo_fprintf( fp, "[%s][%s]%s[%s][%d]%s\n", log_info.program_name,
5900 __get_pid((SQLCHAR*) tmp ),
5901 tstamp_str,
5902 function_name, line, message );
5903 }
5904
5905 uo_fclose( fp );
5906 }
5907}
5908
5909void dm_log_write_diag( char *message )
5910{
5911 FILE *fp;
5912
5913 if ( !log_info.log_flag && !ODBCSharedTraceFlag )
5914 return;
5915
5916 if ( log_info.pid_logging )
5917 {
5918 char file_name[ 256 ], str[ 20 ];
5919
5920 if ( !log_info.log_file_name )
5921 {
5922 strcpy( file_name, "/tmp/sql.log" );
5923 }
5924 else
5925 {
5926 sprintf( file_name, "%s/%s", log_info.log_file_name, __get_pid((SQLCHAR*) str ));
5927 }
5928 fp = uo_fopen( file_name, "a" );
5929
5930 /*
5931 * Change the mode to be rw for all
5932 */
5933 chmod( file_name, 0666 );
5934 }
5935 else
5936 {
5937 if ( !log_info.log_file_name )
5938 {
5939 fp = uo_fopen( "/tmp/sql.log", "a" );
5940 }
5941 else
5942 {
5943 fp = uo_fopen( log_info.log_file_name, "a" );
5944 }
5945 }
5946
5947 if ( fp )
5948 {
5949 uo_fprintf( fp, "%s\n\n", message );
5950
5951 uo_fclose( fp );
5952 }
5953}
5954
5955void dm_log_close( void )
5956{
5957 free( log_info.program_name );
5958 free( log_info.log_file_name );
5959 log_info.program_name = NULL;
5960 log_info.log_file_name = NULL;
5961 log_info.log_flag = 0;
5962}
5963