1/*********************************************************************
2 *
3 * Written by Nick Gorham
4 * (nick@lurcher.org).
5 *
6 * copyright (c) 1999 Nick Gorham
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 **********************************************************************
23 *
24 * $Id: __attribute.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $
25 *
26 * $Log: __attribute.c,v $
27 * Revision 1.9 2009/02/18 17:59:08 lurcher
28 * Shift to using config.h, the compile lines were making it hard to spot warnings
29 *
30 * Revision 1.8 2009/02/17 09:47:44 lurcher
31 * Clear up a number of bugs
32 *
33 * Revision 1.7 2007/07/13 09:01:08 lurcher
34 * Add isql option to quote field data
35 *
36 * Revision 1.6 2006/04/18 10:24:47 lurcher
37 * Add a couple of changes from Mark Vanderwiel
38 *
39 * Revision 1.5 2004/10/27 08:57:57 lurcher
40 * Remove -module from cur Makefile.am, it seems to stop the lib building on HPUX...
41 *
42 * Revision 1.4 2004/06/21 10:01:12 lurcher
43 *
44 * Fix a couple of 64 bit issues
45 *
46 * Revision 1.3 2003/01/23 15:33:25 lurcher
47 *
48 * Fix problems with using putenv()
49 *
50 * Revision 1.2 2002/02/21 18:44:09 lurcher
51 *
52 * Fix bug on 32 bit platforms without long long support
53 * Add option to set environment variables from the ini file
54 *
55 * Revision 1.1.1.1 2001/10/17 16:40:09 lurcher
56 *
57 * First upload to SourceForge
58 *
59 * Revision 1.1 2001/08/08 17:05:17 nick
60 *
61 * Add support for attribute setting in the ini files
62 *
63 *
64 **********************************************************************/
65
66#include <config.h>
67#include <string.h>
68#include "drivermanager.h"
69
70static char const rcsid[]= "$RCSfile: __attribute.c,v $";
71
72/*
73 * these are taken directly from odbctest/attr.cpp
74 * so any bugs or additions, should be added there also
75 */
76
77typedef struct attr_value
78{
79 char *text;
80 int value;
81 char *version;
82 int data_type;
83} attr_value;
84
85typedef struct attr_options
86{
87 char *text;
88 int attr;
89 attr_value values[ 6 ];
90 char *version;
91 int data_type;
92 int is_bitmap;
93 int is_pointer;
94} attr_options;
95
96static attr_options stmt_options[] =
97{
98 { "SQL_ATTR_APP_PARAM_DESC", SQL_ATTR_APP_PARAM_DESC,
99 {
100 { NULL }
101 }, "3.0", SQL_INTEGER
102 },
103 { "SQL_ATTR_APP_ROW_DESC", SQL_ATTR_APP_ROW_DESC,
104 {
105 { NULL }
106 }, "3.0", SQL_INTEGER
107 },
108 { "SQL_ATTR_ASYNC_ENABLE", SQL_ATTR_ASYNC_ENABLE,
109 {
110 { "SQL_ASYNC_ENABLE_OFF", SQL_ASYNC_ENABLE_OFF },
111 { "SQL_ASYNC_ENABLE_ON", SQL_ASYNC_ENABLE_ON },
112 { NULL }
113 }, "1.0", SQL_INTEGER
114 },
115 { "SQL_ATTR_CONCURRENCY", SQL_ATTR_CONCURRENCY,
116 {
117 { "SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY },
118 { "SQL_CONCUR_LOCK", SQL_CONCUR_LOCK },
119 { "SQL_CONCUR_ROWVER", SQL_CONCUR_ROWVER },
120 { "SQL_CONCUR_VALUES", SQL_CONCUR_VALUES },
121 { NULL }
122 }, "2.0", SQL_INTEGER
123 },
124 { "SQL_ATTR_CURSOR_SCROLLABLE", SQL_ATTR_CURSOR_SCROLLABLE,
125 {
126 { "SQL_NONSCROLLABLE", SQL_NONSCROLLABLE },
127 { "SQL_SCROLLABLE", SQL_SCROLLABLE },
128 { NULL }
129 }, "3.0", SQL_INTEGER
130 },
131 { "SQL_ATTR_CURSOR_SENSITIVITY", SQL_ATTR_CURSOR_SENSITIVITY,
132 {
133 { "SQL_UNSPECIFIED", SQL_UNSPECIFIED },
134 { "SQL_INSENSITIVE", SQL_INSENSITIVE },
135 { "SQL_SENSITIVE", SQL_SENSITIVE },
136 { NULL }
137 }, "3.0", SQL_INTEGER
138 },
139 { "SQL_ATTR_CURSOR_TYPE", SQL_ATTR_CURSOR_TYPE,
140 {
141 { "SQL_CURSOR_FORWARD_ONLY", SQL_CURSOR_FORWARD_ONLY },
142 { "SQL_CURSOR_STATIC", SQL_CURSOR_STATIC },
143 { "SQL_CURSOR_KEYSET_DRIVEN", SQL_CURSOR_KEYSET_DRIVEN },
144 { "SQL_CURSOR_DYNAMIC", SQL_CURSOR_DYNAMIC },
145 { NULL }
146 }, "2.0", SQL_INTEGER
147 },
148 { "SQL_ATTR_ENABLE_AUTO_IPD", SQL_ATTR_ENABLE_AUTO_IPD,
149 {
150 { "SQL_FALSE", SQL_FALSE },
151 { "SQL_TRUE", SQL_TRUE },
152 { NULL }
153 }, "3.0", SQL_INTEGER
154 },
155 { "SQL_ATTR_FETCH_BOOKMARK_PTR", SQL_ATTR_FETCH_BOOKMARK_PTR,
156 {
157 { NULL }
158 }, "3.0", SQL_INTEGER, FALSE, TRUE
159 },
160 { "SQL_ATTR_FETCH_IMP_PARAM_DESC", SQL_ATTR_IMP_PARAM_DESC,
161 {
162 { NULL }
163 }, "3.0", SQL_INTEGER
164 },
165 { "SQL_ATTR_FETCH_IMP_ROW_DESC", SQL_ATTR_IMP_ROW_DESC,
166 {
167 { NULL }
168 }, "3.0", SQL_INTEGER
169 },
170 { "SQL_ATTR_KEYSET_SIZE", SQL_ATTR_KEYSET_SIZE,
171 {
172 { NULL }
173 }, "2.0", SQL_INTEGER
174 },
175 { "SQL_ATTR_MAX_LENGTH", SQL_ATTR_MAX_LENGTH,
176 {
177 { NULL }
178 }, "1.0", SQL_INTEGER
179 },
180 { "SQL_ATTR_MAX_ROWS", SQL_ATTR_MAX_ROWS,
181 {
182 { NULL }
183 }, "1.0", SQL_INTEGER
184 },
185 { "SQL_ATTR_METADATA_ID", SQL_ATTR_METADATA_ID,
186 {
187 { "SQL_FALSE", SQL_FALSE },
188 { "SQL_TRUE", SQL_TRUE },
189 { NULL }
190 }, "3.0", SQL_INTEGER
191 },
192 { "SQL_ATTR_NOSCAN", SQL_ATTR_NOSCAN,
193 {
194 { "SQL_NOSCAN_OFF", SQL_NOSCAN_OFF },
195 { "SQL_NOSCAN_ON", SQL_NOSCAN_ON },
196 { NULL }
197 }, "1.0", SQL_INTEGER
198 },
199 { "SQL_ATTR_PARAM_BIND_OFFSET_PTR", SQL_ATTR_PARAM_BIND_OFFSET_PTR,
200 {
201 { NULL }
202 }, "3.0", SQL_INTEGER, FALSE, TRUE
203 },
204 { "SQL_ATTR_PARAM_BIND_TYPE", SQL_ATTR_PARAM_BIND_TYPE,
205 {
206 { NULL }
207 }, "3.0", SQL_INTEGER
208 },
209 { "SQL_ATTR_PARAM_OPERATION_PTR", SQL_ATTR_PARAM_OPERATION_PTR,
210 {
211 { NULL }
212 }, "3.0", SQL_SMALLINT, FALSE, TRUE
213 },
214 { "SQL_ATTR_PARAM_STATUS_PTR", SQL_ATTR_PARAM_STATUS_PTR,
215 {
216 { NULL }
217 }, "3.0", SQL_SMALLINT, FALSE, TRUE
218 },
219 { "SQL_ATTR_PARAMS_PROCESSED_PTR", SQL_ATTR_PARAMS_PROCESSED_PTR,
220 {
221 { NULL }
222 }, "3.0", SQL_SMALLINT, FALSE, TRUE
223 },
224 { "SQL_ATTR_PARAMSET_SIZE", SQL_ATTR_PARAMSET_SIZE,
225 {
226 { NULL }
227 }, "3.0", SQL_INTEGER
228 },
229 { "SQL_ATTR_QUERY_TIMEOUT", SQL_ATTR_QUERY_TIMEOUT,
230 {
231 { NULL }
232 }, "3.0", SQL_INTEGER
233 },
234 { "SQL_ATTR_RETRIEVE_DATA", SQL_ATTR_RETRIEVE_DATA,
235 {
236 { "SQL_RD_ON", SQL_RD_ON },
237 { "SQL_RD_OFF", SQL_RD_OFF },
238 { NULL }
239 }, "2.0", SQL_INTEGER
240 },
241 { "SQL_ATTR_ROW_ARRAY_SIZE", SQL_ATTR_ROW_ARRAY_SIZE,
242 {
243 { NULL }
244 }, "3.0", SQL_INTEGER
245 },
246 { "SQL_ATTR_ROW_BIND_OFFSET_PTR", SQL_ATTR_ROW_BIND_OFFSET_PTR,
247 {
248 { NULL }
249 }, "3.0", SQL_INTEGER, FALSE, TRUE
250 },
251 { "SQL_ATTR_ROW_BIND_TYPE", SQL_ATTR_ROW_BIND_TYPE,
252 {
253 { "SQL_BIND_BY_COLUMN", SQL_BIND_BY_COLUMN },
254 { NULL }
255 }, "1.0", SQL_INTEGER
256 },
257 { "SQL_ATTR_ROW_NUMBER", SQL_ATTR_ROW_NUMBER,
258 {
259 { NULL }
260 }, "2.0", SQL_INTEGER
261 },
262 { "SQL_ATTR_ROW_OPERATION_PTR", SQL_ATTR_ROW_OPERATION_PTR,
263 {
264 { NULL }
265 }, "3.0", SQL_SMALLINT, FALSE, TRUE
266 },
267 { "SQL_ATTR_ROW_STATUS_PTR", SQL_ATTR_ROW_STATUS_PTR,
268 {
269 { NULL }
270 }, "3.0", SQL_SMALLINT, FALSE, TRUE
271 },
272 { "SQL_ATTR_ROWS_FETCHED_PTR", SQL_ATTR_ROWS_FETCHED_PTR,
273 {
274 { NULL }
275 }, "3.0", SQL_INTEGER
276 },
277 { "SQL_ATTR_SIMULATE_CURSOR", SQL_ATTR_SIMULATE_CURSOR,
278 {
279 { NULL }
280 }, "2.0", SQL_INTEGER
281 },
282 { "SQL_ATTR_USE_BOOKMARKS", SQL_ATTR_USE_BOOKMARKS,
283 {
284 { NULL }
285 }, "2.0", SQL_INTEGER
286 },
287 { NULL
288 }
289};
290
291static attr_options stmt_opt_options[] =
292{
293 { "SQL_ASYNC_ENABLE", SQL_ASYNC_ENABLE,
294 {
295 { "SQL_ASYNC_ENABLE_OFF", SQL_ASYNC_ENABLE_OFF },
296 { "SQL_ASYNC_ENABLE_ON", SQL_ASYNC_ENABLE_ON },
297 { NULL }
298 }, "1.0", SQL_INTEGER
299 },
300 { "SQL_BIND_TYPE", SQL_BIND_TYPE,
301 {
302 { "SQL_BIND_BY_COLUMN", SQL_BIND_BY_COLUMN },
303 { NULL }
304 }, "1.0", SQL_INTEGER
305 },
306 { "SQL_CONCURRENCY", SQL_CONCURRENCY,
307 {
308 { "SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY },
309 { "SQL_CONCUR_LOCK", SQL_CONCUR_LOCK },
310 { "SQL_CONCUR_ROWVER", SQL_CONCUR_ROWVER },
311 { "SQL_CONCUR_VALUES", SQL_CONCUR_VALUES },
312 { "SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY },
313 { NULL }
314 }, "2.0", SQL_INTEGER
315 },
316 { "SQL_CURSOR_TYPE", SQL_CURSOR_TYPE,
317 {
318 { "SQL_CURSOR_FORWARD_ONLY", SQL_CURSOR_FORWARD_ONLY },
319 { "SQL_CURSOR_STATIC", SQL_CURSOR_STATIC },
320 { "SQL_CURSOR_KEYSET_DRIVEN", SQL_CURSOR_KEYSET_DRIVEN },
321 { "SQL_CURSOR_DYNAMIC", SQL_CURSOR_DYNAMIC },
322 { NULL }
323 }, "2.0", SQL_INTEGER
324 },
325 { "SQL_KEYSET_SIZE", SQL_KEYSET_SIZE,
326 {
327 { NULL }
328 }, "2.0", SQL_INTEGER
329 },
330 { "SQL_MAX_LENGTH", SQL_MAX_LENGTH,
331 {
332 { NULL }
333 }, "1.0", SQL_INTEGER
334 },
335 { "SQL_MAX_ROWS", SQL_MAX_ROWS,
336 {
337 { NULL }
338 }, "1.0", SQL_INTEGER
339 },
340 { "SQL_NOSCAN", SQL_NOSCAN,
341 {
342 { "SQL_NOSCAN_OFF", SQL_NOSCAN_OFF },
343 { "SQL_NOSCAN_ON", SQL_NOSCAN_ON },
344 { NULL }
345 }, "1.0", SQL_INTEGER
346 },
347 { "SQL_QUERY_TIMEOUT", SQL_QUERY_TIMEOUT,
348 {
349 { NULL }
350 }, "1.0", SQL_INTEGER
351 },
352 { "SQL_RETRIEVE_DATA", SQL_RETRIEVE_DATA,
353 {
354 { "SQL_RD_ON", SQL_RD_ON },
355 { "SQL_RD_OFF", SQL_RD_OFF },
356 { NULL }
357 }, "2.0", SQL_INTEGER
358 },
359 { "SQL_ROWSET_SIZE", SQL_ROWSET_SIZE,
360 {
361 { NULL }
362 }, "2.0", SQL_INTEGER
363 },
364 { "SQL_SIMULATE_CURSOR", SQL_SIMULATE_CURSOR,
365 {
366 { "SQL_SC_NON_UNIQUE", SQL_SC_NON_UNIQUE },
367 { "SQL_SC_TRY_UNIQUE", SQL_SC_TRY_UNIQUE },
368 { "SQL_SC_UNIQUE", SQL_SC_UNIQUE },
369 { NULL }
370 }, "2.0", SQL_INTEGER
371 },
372 { "SQL_USE_BOOKMARKS", SQL_USE_BOOKMARKS,
373 {
374 { "SQL_UB_ON", SQL_UB_ON },
375 { "SQL_UB_OFF", SQL_UB_OFF },
376 { NULL }
377 }, "2.0", SQL_INTEGER
378 },
379 { NULL
380 }
381};
382
383static attr_options conn_options[] =
384{
385 { "SQL_ATTR_ACCESS_MODE", SQL_ATTR_ACCESS_MODE,
386 {
387 { "SQL_MODE_READ_WRITE", SQL_MODE_READ_WRITE },
388 { "SQL_MODE_READ_ONLY", SQL_MODE_READ_ONLY },
389 { NULL }
390 }, "1.0", SQL_INTEGER
391 },
392 { "SQL_ATTR_ASYNC_ENABLE", SQL_ATTR_ASYNC_ENABLE,
393 {
394 { "SQL_ASYNC_ENABLE_OFF", SQL_ASYNC_ENABLE_OFF },
395 { "SQL_ASYNC_ENABLE_ON", SQL_ASYNC_ENABLE_ON },
396 { NULL }
397 }, "3.0", SQL_INTEGER
398 },
399 { "SQL_ATTR_AUTO_IPD", SQL_ATTR_AUTO_IPD,
400 {
401 { "SQL_TRUE", SQL_TRUE },
402 { "SQL_FALSE", SQL_FALSE },
403 { NULL }
404 }, "3.0", SQL_INTEGER
405 },
406 { "SQL_ATTR_AUTOCOMMIT", SQL_ATTR_AUTOCOMMIT,
407 {
408 { "SQL_AUTOCOMMIT_ON", SQL_AUTOCOMMIT_ON },
409 { "SQL_AUTOCOMMIT_OFF", SQL_AUTOCOMMIT_OFF },
410 { NULL }
411 }, "1.0", SQL_INTEGER
412 },
413 { "SQL_ATTR_CONNECTION_TIMEOUT", SQL_ATTR_CONNECTION_TIMEOUT,
414 {
415 { NULL }
416 }, "3.0", SQL_INTEGER
417 },
418 { "SQL_ATTR_CURRENT_CATALOG", SQL_ATTR_CURRENT_CATALOG,
419 {
420 { NULL }
421 }, "2.0", SQL_CHAR
422 },
423 { "SQL_ATTR_LOGIN_TIMEOUT", SQL_ATTR_LOGIN_TIMEOUT,
424 {
425 { NULL }
426 }, "1.0", SQL_INTEGER
427 },
428 { "SQL_ATTR_METADATA_ID", SQL_ATTR_METADATA_ID,
429 {
430 { "SQL_TRUE", SQL_TRUE },
431 { "SQL_FALSE", SQL_FALSE },
432 { NULL }
433 }, "3.0", SQL_INTEGER
434 },
435 { "SQL_ATTR_ODBC_CURSORS", SQL_ATTR_ODBC_CURSORS,
436 {
437 { "SQL_CUR_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED },
438 { "SQL_CUR_USE_ODBC", SQL_CUR_USE_ODBC },
439 { "SQL_CUR_USE_DRIVER", SQL_CUR_USE_DRIVER },
440 { NULL }
441 }, "2.0", SQL_INTEGER
442 },
443 { "SQL_ATTR_PACKET_SIZE", SQL_ATTR_PACKET_SIZE,
444 {
445 { NULL }
446 }, "2.0", SQL_INTEGER
447 },
448 { "SQL_ATTR_QUIET_MODE", SQL_ATTR_QUIET_MODE,
449 {
450 { NULL }
451 }, "2.0", SQL_INTEGER
452 },
453 { "SQL_ATTR_TRACE", SQL_ATTR_TRACE,
454 {
455 { "SQL_OPT_TRACE_OFF", SQL_OPT_TRACE_OFF },
456 { "SQL_OPT_TRACE_ON", SQL_OPT_TRACE_ON },
457 { NULL }
458 }, "1.0", SQL_INTEGER
459 },
460 { "SQL_ATTR_TRACEFILE", SQL_ATTR_TRACEFILE,
461 {
462 { NULL }
463 }, "1.0", SQL_CHAR
464 },
465 { "SQL_ATTR_TRANSLATE_LIB", SQL_ATTR_TRANSLATE_LIB,
466 {
467 { NULL }
468 }, "1.0", SQL_CHAR
469 },
470 { "SQL_ATTR_TRANSLATE_OPTION", SQL_ATTR_TRANSLATE_OPTION,
471 {
472 { NULL }
473 }, "1.0", SQL_INTEGER
474 },
475 { "SQL_ATTR_TXN_ISOLATION", SQL_ATTR_TXN_ISOLATION,
476 {
477 { "SQL_TXN_READ_UNCOMMITTED", SQL_TXN_READ_UNCOMMITTED },
478 { "SQL_TXN_READ_COMMITTED", SQL_TXN_READ_COMMITTED },
479 { "SQL_TXN_REPEATABLE_READ", SQL_TXN_REPEATABLE_READ },
480 { "SQL_TXN_SERIALIZABLE", SQL_TXN_SERIALIZABLE },
481 { NULL }
482 }, "1.0", SQL_INTEGER
483 },
484 { NULL
485 }
486};
487
488static attr_options conn_opt_options[] =
489{
490 { "conn: SQL_ACCESS_MODE", SQL_ACCESS_MODE,
491 {
492 { "SQL_MODE_READ_ONLY", SQL_MODE_READ_ONLY },
493 { "SQL_MODE_READ_WRITE", SQL_MODE_READ_WRITE },
494 { NULL }
495 }, "1.0", SQL_INTEGER
496 },
497 { "conn: SQL_AUTOCOMMIT", SQL_AUTOCOMMIT,
498 {
499 { "SQL_AUTOCOMMIT_ON", SQL_AUTOCOMMIT_ON },
500 { "SQL_AUTOCOMMIT_OFF", SQL_AUTOCOMMIT_OFF },
501 { NULL }
502 }, "1.0", SQL_INTEGER
503 },
504 { "conn: SQL_CURRENT_QUALIFIER", SQL_CURRENT_QUALIFIER,
505 {
506 { NULL }
507 }, "2.0", SQL_CHAR
508 },
509 { "conn: SQL_LOGIN_TIMEOUT", SQL_LOGIN_TIMEOUT,
510 {
511 { NULL }
512 }, "1.0", SQL_INTEGER
513 },
514 { "conn: SQL_ODBC_CURSORS", SQL_ODBC_CURSORS,
515 {
516 { "SQL_CUR_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED },
517 { "SQL_CUR_USE_ODBC", SQL_CUR_USE_ODBC },
518 { "SQL_CUR_USE_DRIVER", SQL_CUR_USE_DRIVER },
519 { NULL }
520 }, "2.0", SQL_INTEGER
521 },
522 { "conn: SQL_OPT_TRACE", SQL_OPT_TRACE,
523 {
524 { "SQL_OPT_TRACE_ON", SQL_OPT_TRACE_ON },
525 { "SQL_OPT_TRACE_OFF", SQL_OPT_TRACE_OFF },
526 { NULL }
527 }, "1.0", SQL_INTEGER
528 },
529 { "conn: SQL_OPT_TRACEFILE", SQL_OPT_TRACEFILE,
530 {
531 { NULL }
532 }, "1.0", SQL_CHAR
533 },
534 { "conn: SQL_PACKET_SIZE", SQL_PACKET_SIZE,
535 {
536 { NULL }
537 }, "2.0", SQL_INTEGER
538 },
539 { "conn: SQL_QUIET_MODE", SQL_QUIET_MODE,
540 {
541 { NULL }
542 }, "2.0", SQL_INTEGER
543 },
544 { "conn: SQL_TRANSLATE_DLL", SQL_TRANSLATE_DLL,
545 {
546 { NULL }
547 }, "1.0", SQL_CHAR
548 },
549 { "conn: SQL_TRANSLATE_OPTION", SQL_TRANSLATE_OPTION,
550 {
551 { NULL }
552 }, "1.0", SQL_INTEGER
553 },
554 { "conn: SQL_TXN_ISOLATION", SQL_TXN_ISOLATION,
555 {
556 { "SQL_TXN_READ_UNCOMMITED", SQL_TXN_READ_UNCOMMITTED },
557 { "SQL_TXN_READ_COMMITED", SQL_TXN_READ_COMMITTED },
558 { "SQL_TXN_REPEATABLE_READ", SQL_TXN_REPEATABLE_READ },
559 { "SQL_TXN_SERIALIZABLE", SQL_TXN_SERIALIZABLE },
560 { "SQL_TXN_VERSIONING", 0x00000010L },
561 { NULL }
562 }, "1.0", SQL_INTEGER
563 },
564 { "stmt: SQL_ASYNC_ENABLE", SQL_ASYNC_ENABLE,
565 {
566 { "SQL_ASYNC_ENABLE_OFF", SQL_ASYNC_ENABLE_OFF },
567 { "SQL_ASYNC_ENABLE_ON", SQL_ASYNC_ENABLE_ON },
568 { NULL }
569 }, "1.0", SQL_INTEGER
570 },
571 { "stmt: SQL_BIND_TYPE", SQL_BIND_TYPE,
572 {
573 { "SQL_BIND_BY_COLUMN", SQL_BIND_BY_COLUMN },
574 { NULL }
575 }, "1.0", SQL_INTEGER
576 },
577 { "stmt: SQL_CONCURRENCY", SQL_CONCURRENCY,
578 {
579 { "SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY },
580 { "SQL_CONCUR_LOCK", SQL_CONCUR_LOCK },
581 { "SQL_CONCUR_ROWVER", SQL_CONCUR_ROWVER },
582 { "SQL_CONCUR_VALUES", SQL_CONCUR_VALUES },
583 { "SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY },
584 { NULL }
585 }, "2.0", SQL_INTEGER
586 },
587 { "stmt: SQL_CURSOR_TYPE", SQL_CURSOR_TYPE,
588 {
589 { "SQL_CURSOR_FORWARD_ONLY", SQL_CURSOR_FORWARD_ONLY },
590 { "SQL_CURSOR_STATIC", SQL_CURSOR_STATIC },
591 { "SQL_CURSOR_KEYSET_DRIVEN", SQL_CURSOR_KEYSET_DRIVEN },
592 { "SQL_CURSOR_DYNAMIC", SQL_CURSOR_DYNAMIC },
593 { NULL }
594 }, "2.0", SQL_INTEGER
595 },
596 { "stmt: SQL_KEYSET_SIZE", SQL_KEYSET_SIZE,
597 {
598 { NULL }
599 }, "2.0", SQL_INTEGER
600 },
601 { "stmt: SQL_MAX_LENGTH", SQL_MAX_LENGTH,
602 {
603 { NULL }
604 }, "1.0", SQL_INTEGER
605 },
606 { "stmt: SQL_MAX_ROWS", SQL_MAX_ROWS,
607 {
608 { NULL }
609 }, "1.0", SQL_INTEGER
610 },
611 { "stmt: SQL_NOSCAN", SQL_NOSCAN,
612 {
613 { "SQL_NOSCAN_OFF", SQL_NOSCAN_OFF },
614 { "SQL_NOSCAN_ON", SQL_NOSCAN_ON },
615 { NULL }
616 }, "1.0", SQL_INTEGER
617 },
618 { "stmt: SQL_QUERY_TIMEOUT", SQL_QUERY_TIMEOUT,
619 {
620 { NULL }
621 }, "1.0", SQL_INTEGER
622 },
623 { "stmt: SQL_RETRIEVE_DATA", SQL_RETRIEVE_DATA,
624 {
625 { "SQL_RD_ON", SQL_RD_ON },
626 { "SQL_RD_OFF", SQL_RD_OFF },
627 { NULL }
628 }, "2.0", SQL_INTEGER
629 },
630 { "stmt: SQL_ROWSET_SIZE", SQL_ROWSET_SIZE,
631 {
632 { NULL }
633 }, "2.0", SQL_INTEGER
634 },
635 { "stmt: SQL_SIMULATE_CURSOR", SQL_SIMULATE_CURSOR,
636 {
637 { "SQL_SC_NON_UNIQUE", SQL_SC_NON_UNIQUE },
638 { "SQL_SC_TRY_UNIQUE", SQL_SC_TRY_UNIQUE },
639 { "SQL_SC_UNIQUE", SQL_SC_UNIQUE },
640 { NULL }
641 }, "2.0", SQL_INTEGER
642 },
643 { "stmt: SQL_USE_BOOKMARKS", SQL_USE_BOOKMARKS,
644 {
645 { "SQL_UB_ON", SQL_UB_ON },
646 { "SQL_UB_OFF", SQL_UB_OFF },
647 { NULL }
648 }, "2.0", SQL_INTEGER
649 },
650 { NULL
651 }
652};
653
654static attr_options env_options[] =
655{
656 { "SQL_ATTR_ODBC_VERSION", SQL_ATTR_ODBC_VERSION,
657 {
658 { "SQL_OV_ODBC2", SQL_OV_ODBC2 },
659 { "SQL_OV_ODBC3", SQL_OV_ODBC3 },
660 { "SQL_OV_ODBC3_80", SQL_OV_ODBC3_80 },
661 { NULL }
662 }, "3.0", SQL_INTEGER
663 },
664 { "SQL_ATTR_CP_MATCH", SQL_ATTR_CP_MATCH,
665 {
666 { "SQL_CP_STRICT_MATCH", SQL_CP_STRICT_MATCH },
667 { "SQL_CP_RELAXED_MATCH", SQL_CP_RELAXED_MATCH },
668 { "SQL_CP_MATCH_DEFAULT", SQL_CP_MATCH_DEFAULT },
669 { NULL }
670 }, "3.0", SQL_INTEGER
671 },
672 { "SQL_ATTR_CONNECTION_POOLING", SQL_ATTR_CONNECTION_POOLING,
673 {
674 { "SQL_CP_OFF", SQL_OV_ODBC2 },
675 { "SQL_CP_ONE_PER_DRIVER", SQL_CP_ONE_PER_DRIVER },
676 { "SQL_CP_ONE_PER_HENV", SQL_CP_ONE_PER_HENV },
677 { "SQL_CP_DEFAULT", SQL_CP_DEFAULT },
678 { NULL }
679 }, "3.0", SQL_INTEGER
680 },
681 { "SQL_ATTR_OUTPUT_NTS", SQL_ATTR_OUTPUT_NTS,
682 {
683 { "SQL_TRUE", SQL_TRUE },
684 { "SQL_FALSE", SQL_FALSE },
685 { NULL }
686 }, "3.0", SQL_INTEGER
687 },
688 { "SQL_ATTR_UNIXODBC_ENVATTR", SQL_ATTR_UNIXODBC_ENVATTR,
689 {
690 { NULL }
691 }, "3.0", SQL_CHAR
692
693 },
694 {
695 NULL
696 }
697};
698
699static int find_option( char *kw, struct attr_set *as, struct attr_options *opt )
700{
701struct attr_value *val;
702int found = 0;
703
704 while( opt -> text && !found )
705 {
706 if ( strcasecmp( kw, opt -> text ) == 0 )
707 {
708 found = 1;
709 val = opt -> values;
710 as -> attribute = opt -> attr;
711
712 while ( val -> text )
713 {
714 if ( strcasecmp( as -> value, val -> text ) == 0 )
715 {
716 break;
717 }
718 val ++;
719 }
720
721 if ( val -> text )
722 {
723 as -> is_int_type = 1;
724 as -> int_value = val -> value;
725 }
726 else
727 {
728 if ( opt -> data_type != SQL_CHAR )
729 {
730 as -> is_int_type = 1;
731 as -> int_value = atoi( as -> value );
732 }
733 }
734 }
735 opt ++;
736 }
737
738 /*
739 * Handle non standard attributes by [numeric_value]={char value} or [numeric_value]=\int_value
740 */
741 if ( !found )
742 {
743 if ( kw[ 0 ] == '[' ) {
744 as -> attribute = atoi( kw + 1 );
745 if ( as -> value[ 0 ] == '\\' ) {
746 as -> is_int_type = 1;
747 as -> int_value = atoi( as -> value + 1 );
748 }
749 found = 1;
750 }
751 }
752
753 return found;
754}
755
756struct attr_set * __get_set( char ** cp, int *skip )
757{
758char *ptr, *kw;
759int len;
760struct attr_set *as;
761
762 /*
763 * flag to indicate a non valid option
764 */
765
766 *skip = 0;
767
768 ptr = *cp;
769
770 if ( !**cp )
771 return NULL;
772
773 while ( **cp && **cp != '=' )
774 {
775 (*cp)++;
776 }
777
778 if ( !**cp )
779 return NULL;
780
781 as = malloc( sizeof( struct attr_set ));
782 if ( !as )
783 {
784 return NULL;
785 }
786
787 memset( as, 0, sizeof( struct attr_set ));
788
789 len = *cp - ptr;
790 as -> keyword = malloc( len + 1 );
791 memcpy( as -> keyword, ptr, len );
792 as -> keyword[ len ] = '\0';
793
794 (*cp)++;
795 ptr = *cp;
796
797 if ( **cp && **cp == '{' )
798 {
799 (*cp)++;
800 ptr ++;
801 while ( **cp && **cp != '}' )
802 (*cp)++;
803
804 len = *cp - ptr;
805 as -> value = malloc( len + 1 );
806 memcpy( as -> value, ptr , len );
807 as -> value[ len ] = '\0';
808 (*cp)++;
809 }
810 else
811 {
812 while ( **cp && **cp != ';' )
813 (*cp)++;
814
815 len = *cp - ptr;
816 as -> value = malloc( len + 1 );
817 memcpy( as -> value, ptr, len );
818 as -> value[ len ] = '\0';
819 }
820
821 /*
822 * now we translate the keyword and attribute values
823 */
824
825 if ( as -> keyword[ 0 ] == '*' )
826 {
827 kw = as -> keyword + 1;
828 as -> override = 1;
829 }
830 else
831 {
832 kw = as -> keyword;
833 }
834
835
836 if ( !find_option( kw, as, env_options ) &&
837 !find_option( kw, as, conn_options ) &&
838 !find_option( kw, as, conn_opt_options ) &&
839 !find_option( kw, as, stmt_options ) &&
840 !find_option( kw, as, stmt_opt_options ))
841 {
842 *skip = 1;
843 }
844
845 if ( **cp )
846 (*cp)++;
847
848 return as;
849}
850
851int __append_set( struct attr_struct *attr_str, struct attr_set *ap )
852{
853struct attr_set *ptr, *end, *nap;
854
855 /* check that the attribute is not already in the list */
856
857 end = NULL;
858 if ( attr_str -> count > 0 )
859 {
860 ptr = attr_str -> list;
861 while( ptr )
862 {
863 if( ap -> attribute == ptr -> attribute )
864 {
865 return 0;
866 }
867 end = ptr;
868 ptr = ptr -> next;
869 }
870 }
871
872 nap = malloc( sizeof( *ptr ));
873 *nap = *ap;
874
875 nap -> keyword = malloc( strlen( ap -> keyword ) + 1 );
876 strcpy( nap -> keyword, ap -> keyword );
877
878 nap -> value = malloc( strlen( ap -> value ) + 1 );
879 strcpy( nap -> value, ap -> value );
880
881 attr_str -> count ++;
882
883 if ( attr_str -> list )
884 {
885 end -> next = nap;
886 nap -> next = NULL;
887 }
888 else
889 {
890 nap -> next = NULL;
891 attr_str -> list = nap;
892 }
893
894 return 0;
895}
896
897int __parse_attribute_string( struct attr_struct *attr_str,
898 char *str, int str_len )
899{
900struct attr_set *cp;
901char *local_str, *ptr;
902int skip;
903
904 attr_str -> count = 0;
905 attr_str -> list = NULL;
906
907 if ( str_len != SQL_NTS )
908 {
909 local_str = malloc( str_len + 1 );
910 memcpy( local_str, str, str_len );
911 local_str[ str_len ] = '\0';
912 }
913 else
914 {
915 local_str = str;
916 }
917
918 ptr = local_str;
919
920 while(( cp = __get_set( &ptr, &skip )) != NULL )
921 {
922 if ( !skip )
923 {
924 __append_set( attr_str, cp );
925 }
926 free( cp -> keyword );
927 free( cp -> value );
928 free( cp );
929 }
930
931 if ( str_len != SQL_NTS )
932 free( local_str );
933
934 return 0;
935}
936
937void __release_attr_str( struct attr_struct *attr_str )
938{
939 struct attr_set *set, *ptr;
940
941 if ( !attr_str )
942 {
943 return;
944 }
945
946 set = attr_str -> list;
947
948 while ( set )
949 {
950 ptr = set -> next;
951
952 free( set -> keyword );
953 free( set -> value );
954 free( set );
955
956 set = ptr;
957 }
958
959 attr_str -> list = NULL;
960 attr_str -> count = 0;
961}
962
963
964static void __set_local_attribute( void *handle, int type, struct attr_set *as )
965{
966 SQLRETURN ret = SQL_SUCCESS;
967
968 if ( type == SQL_HANDLE_ENV )
969 {
970 DMHDBC connection = (DMHDBC) handle;
971
972 if ( as -> attribute == SQL_ATTR_UNIXODBC_ENVATTR )
973 {
974 /*
975 * its a memory leak, but not much I can do, see "man putenv"
976 */
977 putenv( strdup( as -> value ));
978 }
979 else
980 {
981 return;
982 }
983
984 if ( log_info.log_flag )
985 {
986 sprintf( connection -> msg, "\t\tENV ATTR [%s=%s] ret = %d",
987 as -> keyword, as -> value, ret );
988
989 dm_log_write_diag( connection -> msg );
990 }
991 }
992}
993
994static void __set_attribute( void *handle, int type, struct attr_set *as )
995{
996 SQLRETURN ret = SQL_ERROR;
997
998 if ( type == SQL_HANDLE_ENV )
999 {
1000 DMHDBC connection = (DMHDBC) handle;
1001
1002 if ( as -> attribute == SQL_ATTR_UNIXODBC_ENVATTR )
1003 {
1004 return;
1005 }
1006
1007 if ( connection -> driver_version >= SQL_OV_ODBC3 )
1008 {
1009 if ( CHECK_SQLSETENVATTR( connection ))
1010 {
1011 if ( as -> is_int_type )
1012 {
1013 ret = SQLSETENVATTR( connection,
1014 connection -> driver_dbc,
1015 as -> attribute,
1016 as -> int_value,
1017 0 );
1018 }
1019 else
1020 {
1021 ret = SQLSETENVATTR( connection,
1022 connection -> driver_dbc,
1023 as -> attribute,
1024 as -> value,
1025 strlen( as -> value ));
1026 }
1027 }
1028 }
1029 if ( log_info.log_flag )
1030 {
1031 sprintf( connection -> msg, "\t\tENV ATTR [%s=%s] ret = %d",
1032 as -> keyword, as -> value, ret );
1033
1034 dm_log_write_diag( connection -> msg );
1035 }
1036 }
1037 else if ( type == SQL_HANDLE_DBC )
1038 {
1039 DMHDBC connection = (DMHDBC) handle;
1040
1041 if ( connection -> driver_version >= SQL_OV_ODBC3 )
1042 {
1043 if ( CHECK_SQLSETCONNECTATTR( connection ))
1044 {
1045 if ( as -> is_int_type )
1046 {
1047 ret = SQLSETCONNECTATTR( connection,
1048 connection -> driver_dbc,
1049 as -> attribute,
1050 as -> int_value,
1051 0 );
1052 }
1053 else
1054 {
1055 ret = SQLSETCONNECTATTR( connection,
1056 connection -> driver_dbc,
1057 as -> attribute,
1058 as -> value,
1059 strlen( as -> value ));
1060 }
1061 }
1062 else if ( CHECK_SQLSETCONNECTOPTION( connection ))
1063 {
1064 if ( as -> is_int_type )
1065 {
1066 ret = SQLSETCONNECTOPTION( connection,
1067 connection -> driver_dbc,
1068 as -> attribute,
1069 as -> int_value );
1070 }
1071 else
1072 {
1073 ret = SQLSETCONNECTOPTION( connection,
1074 connection -> driver_dbc,
1075 as -> attribute,
1076 as -> value );
1077 }
1078 }
1079 }
1080 else
1081 {
1082 if ( CHECK_SQLSETCONNECTOPTION( connection ))
1083 {
1084 if ( as -> is_int_type )
1085 {
1086 ret = SQLSETCONNECTOPTION( connection,
1087 connection -> driver_dbc,
1088 as -> attribute,
1089 as -> int_value );
1090 }
1091 else
1092 {
1093 ret = SQLSETCONNECTOPTION( connection,
1094 connection -> driver_dbc,
1095 as -> attribute,
1096 as -> value );
1097 }
1098 }
1099 }
1100 if ( log_info.log_flag )
1101 {
1102 sprintf( connection -> msg, "\t\tCONN ATTR [%s=%s] ret = %d",
1103 as -> keyword, as -> value, ret );
1104
1105 dm_log_write_diag( connection -> msg );
1106 }
1107 }
1108 else if ( type == SQL_HANDLE_STMT )
1109 {
1110 DMHSTMT statement = (DMHSTMT) handle;
1111 DMHDBC connection = statement -> connection;
1112
1113 if ( connection -> driver_version >= SQL_OV_ODBC3 )
1114 {
1115 if ( CHECK_SQLSETSTMTATTR( connection ))
1116 {
1117 if ( as -> is_int_type )
1118 {
1119 ret = SQLSETSTMTATTR( connection,
1120 statement -> driver_stmt,
1121 as -> attribute,
1122 as -> int_value,
1123 0 );
1124 }
1125 else
1126 {
1127 ret = SQLSETSTMTATTR( connection,
1128 statement -> driver_stmt,
1129 as -> attribute,
1130 as -> value,
1131 strlen( as -> value ));
1132 }
1133 }
1134 else if ( CHECK_SQLSETSTMTOPTION( connection ))
1135 {
1136 if ( as -> is_int_type )
1137 {
1138 ret = SQLSETSTMTOPTION( connection,
1139 statement -> driver_stmt,
1140 as -> attribute,
1141 as -> int_value );
1142 }
1143 else
1144 {
1145 ret = SQLSETSTMTOPTION( connection,
1146 statement -> driver_stmt,
1147 as -> attribute,
1148 as -> value );
1149 }
1150 }
1151 }
1152 else
1153 {
1154 if ( CHECK_SQLSETSTMTOPTION( connection ))
1155 {
1156 if ( as -> is_int_type )
1157 {
1158 ret = SQLSETSTMTOPTION( connection,
1159 statement -> driver_stmt,
1160 as -> attribute,
1161 as -> int_value );
1162 }
1163 else
1164 {
1165 ret = SQLSETSTMTOPTION( connection,
1166 statement -> driver_stmt,
1167 as -> attribute,
1168 as -> value );
1169 }
1170 }
1171
1172 /*
1173 * Fall back, the attribute may be ODBC 3 only
1174 */
1175
1176 if ( ret == SQL_ERROR ) {
1177
1178 if ( CHECK_SQLSETSTMTATTR( connection ))
1179 {
1180 if ( as -> is_int_type )
1181 {
1182 ret = SQLSETSTMTATTR( connection,
1183 statement -> driver_stmt,
1184 as -> attribute,
1185 as -> int_value,
1186 0 );
1187 }
1188 else
1189 {
1190 ret = SQLSETSTMTATTR( connection,
1191 statement -> driver_stmt,
1192 as -> attribute,
1193 as -> value,
1194 strlen( as -> value ));
1195 }
1196 }
1197 }
1198 }
1199 if ( log_info.log_flag )
1200 {
1201 sprintf( connection -> msg, "\t\tSTMT ATTR [%s=%s] ret = %d",
1202 as -> keyword, as -> value, ret );
1203
1204 dm_log_write_diag( connection -> msg );
1205 }
1206 }
1207}
1208
1209void __set_local_attributes( void * handle, int type )
1210{
1211 struct attr_set *as;
1212
1213 switch( type )
1214 {
1215 case SQL_HANDLE_ENV:
1216 as = ((DMHDBC) handle ) -> env_attribute.list;
1217 break;
1218
1219 default:
1220 as = NULL;
1221 break;
1222 }
1223
1224 while( as )
1225 {
1226 __set_local_attribute( handle, type, as );
1227 as = as -> next;
1228 }
1229}
1230
1231void __set_attributes( void * handle, int type )
1232{
1233 struct attr_set *as;
1234
1235 switch( type )
1236 {
1237 case SQL_HANDLE_ENV:
1238 as = ((DMHDBC) handle ) -> env_attribute.list;
1239 break;
1240
1241 case SQL_HANDLE_DBC:
1242 as = ((DMHDBC) handle ) -> dbc_attribute.list;
1243 break;
1244
1245 case SQL_HANDLE_STMT:
1246 as = ((DMHSTMT) handle ) -> connection -> stmt_attribute.list;
1247 break;
1248
1249 default:
1250 as = NULL;
1251 break;
1252 }
1253
1254 while( as )
1255 {
1256 __set_attribute( handle, type, as );
1257 as = as -> next;
1258 }
1259}
1260
1261void *__attr_override( void *handle, int type, int attribute, void *value, SQLINTEGER *string_length )
1262{
1263 struct attr_set *as;
1264 char *msg;
1265
1266 switch( type )
1267 {
1268 case SQL_HANDLE_DBC:
1269 as = ((DMHDBC) handle ) -> dbc_attribute.list;
1270 msg = ((DMHDBC) handle ) -> msg;
1271 break;
1272
1273 case SQL_HANDLE_STMT:
1274 as = ((DMHSTMT) handle ) -> connection -> stmt_attribute.list;
1275 msg = ((DMHSTMT) handle ) -> msg;
1276 break;
1277
1278 default:
1279 as = NULL;
1280 msg = NULL;
1281 break;
1282 }
1283
1284 while( as )
1285 {
1286 if ( as -> override && as -> attribute == attribute )
1287 {
1288 break;
1289 }
1290 as = as -> next;
1291 }
1292
1293 if ( as )
1294 {
1295 if ( log_info.log_flag )
1296 {
1297 sprintf( msg, "\t\tATTR OVERRIDE [%s=%s]",
1298 as -> keyword + 1, as -> value );
1299
1300 dm_log_write_diag( msg );
1301 }
1302
1303 if ( as -> is_int_type )
1304 {
1305#ifdef HAVE_PTRDIFF_T
1306 return (void*)(ptrdiff_t) as -> int_value;
1307#else
1308 return (void*)(long) as -> int_value;
1309#endif
1310 }
1311 else
1312 {
1313 if ( string_length )
1314 {
1315 *string_length = strlen( as -> value );
1316 }
1317 return as -> value;
1318 }
1319 }
1320 else
1321 {
1322 return value;
1323 }
1324}
1325
1326void *__attr_override_wide( void *handle, int type, int attribute, void *value, SQLINTEGER *string_length,
1327 SQLWCHAR *buffer )
1328{
1329 struct attr_set *as;
1330 char *msg;
1331
1332 switch( type )
1333 {
1334 case SQL_HANDLE_DBC:
1335 as = ((DMHDBC) handle ) -> dbc_attribute.list;
1336 msg = ((DMHDBC) handle ) -> msg;
1337 break;
1338
1339 case SQL_HANDLE_STMT:
1340 as = ((DMHSTMT) handle ) -> connection -> stmt_attribute.list;
1341 msg = ((DMHSTMT) handle ) -> msg;
1342 break;
1343
1344 default:
1345 as = NULL;
1346 msg = NULL;
1347 break;
1348 }
1349
1350 while( as )
1351 {
1352 if ( as -> override && as -> attribute == attribute )
1353 {
1354 break;
1355 }
1356 as = as -> next;
1357 }
1358
1359 if ( as )
1360 {
1361 if ( log_info.log_flag )
1362 {
1363 sprintf( msg, "\t\tATTR OVERRIDE [%s=%s]",
1364 as -> keyword + 1, as -> value );
1365
1366 dm_log_write_diag( msg );
1367 }
1368
1369 if ( as -> is_int_type )
1370 {
1371#ifdef HAVE_PTRDIFF_T
1372 return (void*)(ptrdiff_t) as -> int_value;
1373#else
1374 return (void*)(long) as -> int_value;
1375#endif
1376 }
1377 else
1378 {
1379 if ( string_length )
1380 {
1381 *string_length = strlen( as -> value ) * sizeof( SQLWCHAR );
1382 }
1383 switch( type )
1384 {
1385 case SQL_HANDLE_DBC:
1386 ansi_to_unicode_copy( buffer, as->value, SQL_NTS, (DMHDBC) handle, NULL );
1387 break;
1388
1389 case SQL_HANDLE_STMT:
1390 ansi_to_unicode_copy( buffer, as->value, SQL_NTS, ((DMHSTMT) handle ) -> connection, NULL );
1391 break;
1392 }
1393 return buffer;
1394 }
1395 }
1396 else
1397 {
1398 return value;
1399 }
1400}
1401
1402/*
1403 * check for valid attributes in the setting functions
1404 */
1405
1406int dm_check_connection_attrs( DMHDBC connection, SQLINTEGER attribute, SQLPOINTER value )
1407{
1408#ifdef HAVE_PTRDIFF_T
1409 ptrdiff_t ival;
1410#else
1411 SQLINTEGER ival;
1412#endif
1413
1414#ifdef HAVE_PTRDIFF_T
1415 ival = (ptrdiff_t) value;
1416#else
1417 ival = (SQLINTEGER) value;
1418#endif
1419
1420 switch( attribute )
1421 {
1422 case SQL_ACCESS_MODE:
1423 if ( ival != SQL_MODE_READ_ONLY && ival != SQL_MODE_READ_WRITE )
1424 {
1425 return SQL_ERROR;
1426 }
1427 break;
1428
1429 case SQL_ATTR_ASYNC_ENABLE:
1430 if ( ival != SQL_ASYNC_ENABLE_OFF && ival != SQL_ASYNC_ENABLE_ON )
1431 {
1432 return SQL_ERROR;
1433 }
1434 break;
1435
1436 case SQL_ATTR_AUTO_IPD:
1437 if ( ival != SQL_TRUE && ival != SQL_FALSE )
1438 {
1439 return SQL_ERROR;
1440 }
1441 break;
1442
1443 case SQL_ATTR_AUTOCOMMIT:
1444 if ( ival != SQL_AUTOCOMMIT_ON && ival != SQL_AUTOCOMMIT_OFF )
1445 {
1446 return SQL_ERROR;
1447 }
1448 break;
1449
1450 case SQL_ATTR_METADATA_ID:
1451 if ( ival != SQL_TRUE && ival != SQL_FALSE )
1452 {
1453 return SQL_ERROR;
1454 }
1455 break;
1456
1457 case SQL_ATTR_ODBC_CURSORS:
1458 if ( ival != SQL_CUR_USE_IF_NEEDED && ival != SQL_CUR_USE_ODBC &&
1459 ival != SQL_CUR_USE_DRIVER )
1460 {
1461 return SQL_ERROR;
1462 }
1463 break;
1464
1465 case SQL_ATTR_TRACE:
1466 if ( ival != SQL_OPT_TRACE_ON && ival != SQL_OPT_TRACE_OFF )
1467 {
1468 return SQL_ERROR;
1469 }
1470 break;
1471
1472 case SQL_ATTR_TXN_ISOLATION:
1473 if ( ival != SQL_TXN_READ_UNCOMMITTED && ival != SQL_TXN_READ_COMMITTED
1474 && ival != SQL_TXN_REPEATABLE_READ && ival != SQL_TXN_SERIALIZABLE )
1475 {
1476 return SQL_ERROR;
1477 }
1478 break;
1479
1480 /*
1481 * include statement attributes as well
1482 */
1483
1484 case SQL_ATTR_CONCURRENCY:
1485 if ( ival != SQL_CONCUR_READ_ONLY && ival != SQL_CONCUR_LOCK &&
1486 ival != SQL_CONCUR_ROWVER && ival != SQL_CONCUR_VALUES )
1487 {
1488 return SQL_ERROR;
1489 }
1490 break;
1491
1492 case SQL_ATTR_CURSOR_SCROLLABLE:
1493 if ( ival != SQL_NONSCROLLABLE && ival != SQL_SCROLLABLE )
1494 {
1495 return SQL_ERROR;
1496 }
1497 break;
1498
1499 case SQL_ATTR_CURSOR_SENSITIVITY:
1500 if ( ival != SQL_UNSPECIFIED && ival != SQL_INSENSITIVE
1501 && ival != SQL_SENSITIVE )
1502 {
1503 return SQL_ERROR;
1504 }
1505 break;
1506
1507 case SQL_ATTR_CURSOR_TYPE:
1508 if ( ival != SQL_CURSOR_FORWARD_ONLY && ival != SQL_CURSOR_STATIC &&
1509 ival != SQL_CURSOR_KEYSET_DRIVEN && ival != SQL_CURSOR_DYNAMIC )
1510 {
1511 return SQL_ERROR;
1512 }
1513 break;
1514
1515 case SQL_ATTR_ENABLE_AUTO_IPD:
1516 if ( ival != SQL_TRUE && ival != SQL_FALSE )
1517 {
1518 return SQL_ERROR;
1519 }
1520 break;
1521
1522 case SQL_ATTR_NOSCAN:
1523 if ( ival != SQL_NOSCAN_ON && ival != SQL_NOSCAN_OFF )
1524 {
1525 return SQL_ERROR;
1526 }
1527 break;
1528
1529 case SQL_ATTR_RETRIEVE_DATA:
1530 if ( ival != SQL_RD_ON && ival != SQL_RD_OFF )
1531 {
1532 return SQL_ERROR;
1533 }
1534 break;
1535
1536 case SQL_ATTR_SIMULATE_CURSOR:
1537 if ( ival != SQL_SC_NON_UNIQUE && ival != SQL_SC_TRY_UNIQUE &&
1538 ival != SQL_SC_UNIQUE )
1539 {
1540 return SQL_ERROR;
1541 }
1542 break;
1543
1544 case SQL_ATTR_USE_BOOKMARKS:
1545 if ( ival != SQL_UB_OFF && ival != SQL_UB_VARIABLE &&
1546 ival != SQL_UB_FIXED )
1547 {
1548 return SQL_ERROR;
1549 }
1550 break;
1551
1552 default:
1553 return SQL_SUCCESS;
1554 }
1555
1556 return SQL_SUCCESS;
1557}
1558
1559int dm_check_statement_attrs( DMHSTMT statement, SQLINTEGER attribute, SQLPOINTER value )
1560{
1561#ifdef HAVE_PTRDIFF_T
1562 ptrdiff_t ival;
1563#else
1564 SQLUINTEGER ival;
1565#endif
1566
1567#ifdef HAVE_PTRDIFF_T
1568 ival = (ptrdiff_t) value;
1569#else
1570 ival = (SQLUINTEGER) value;
1571#endif
1572
1573 switch( attribute )
1574 {
1575 case SQL_ATTR_ASYNC_ENABLE:
1576 if ( ival != SQL_ASYNC_ENABLE_OFF && ival != SQL_ASYNC_ENABLE_ON )
1577 {
1578 return SQL_ERROR;
1579 }
1580 break;
1581
1582 case SQL_ATTR_CONCURRENCY:
1583 if ( ival != SQL_CONCUR_READ_ONLY && ival != SQL_CONCUR_LOCK &&
1584 ival != SQL_CONCUR_ROWVER && ival != SQL_CONCUR_VALUES )
1585 {
1586 return SQL_ERROR;
1587 }
1588 break;
1589
1590 case SQL_ATTR_CURSOR_SCROLLABLE:
1591 if ( ival != SQL_NONSCROLLABLE && ival != SQL_SCROLLABLE )
1592 {
1593 return SQL_ERROR;
1594 }
1595 break;
1596
1597 case SQL_ATTR_CURSOR_SENSITIVITY:
1598 if ( ival != SQL_UNSPECIFIED && ival != SQL_INSENSITIVE
1599 && ival != SQL_SENSITIVE )
1600 {
1601 return SQL_ERROR;
1602 }
1603 break;
1604
1605 case SQL_ATTR_CURSOR_TYPE:
1606 if ( ival != SQL_CURSOR_FORWARD_ONLY && ival != SQL_CURSOR_STATIC &&
1607 ival != SQL_CURSOR_KEYSET_DRIVEN && ival != SQL_CURSOR_DYNAMIC )
1608 {
1609 return SQL_ERROR;
1610 }
1611 break;
1612
1613 case SQL_ATTR_ENABLE_AUTO_IPD:
1614 if ( ival != SQL_TRUE && ival != SQL_FALSE )
1615 {
1616 return SQL_ERROR;
1617 }
1618 break;
1619
1620 case SQL_ATTR_NOSCAN:
1621 if ( ival != SQL_NOSCAN_ON && ival != SQL_NOSCAN_OFF )
1622 {
1623 return SQL_ERROR;
1624 }
1625 break;
1626
1627 case SQL_ATTR_RETRIEVE_DATA:
1628 if ( ival != SQL_RD_ON && ival != SQL_RD_OFF )
1629 {
1630 return SQL_ERROR;
1631 }
1632 break;
1633
1634 case SQL_ATTR_SIMULATE_CURSOR:
1635 if ( ival != SQL_SC_NON_UNIQUE && ival != SQL_SC_TRY_UNIQUE &&
1636 ival != SQL_SC_UNIQUE )
1637 {
1638 return SQL_ERROR;
1639 }
1640 break;
1641
1642 case SQL_ATTR_USE_BOOKMARKS:
1643 if ( ival != SQL_UB_OFF && ival != SQL_UB_VARIABLE &&
1644 ival != SQL_UB_FIXED )
1645 {
1646 return SQL_ERROR;
1647 }
1648 break;
1649
1650 case SQL_ROWSET_SIZE:
1651 return ival > 0 ? SQL_SUCCESS : SQL_ERROR;
1652
1653 default:
1654 return SQL_SUCCESS;
1655 }
1656
1657 return SQL_SUCCESS;
1658}
1659
1660