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 | |
70 | static 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 | |
77 | typedef struct attr_value |
78 | { |
79 | char *text; |
80 | int value; |
81 | char *version; |
82 | int data_type; |
83 | } attr_value; |
84 | |
85 | typedef 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 | |
96 | static 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 | |
291 | static 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 | |
383 | static 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 | |
488 | static 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 | |
654 | static 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 | |
699 | static int find_option( char *kw, struct attr_set *as, struct attr_options *opt ) |
700 | { |
701 | struct attr_value *val; |
702 | int 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 | |
756 | struct attr_set * __get_set( char ** cp, int *skip ) |
757 | { |
758 | char *ptr, *kw; |
759 | int len; |
760 | struct 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 | |
851 | int __append_set( struct attr_struct *attr_str, struct attr_set *ap ) |
852 | { |
853 | struct 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 | |
897 | int __parse_attribute_string( struct attr_struct *attr_str, |
898 | char *str, int str_len ) |
899 | { |
900 | struct attr_set *cp; |
901 | char *local_str, *ptr; |
902 | int 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 | |
937 | void __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 | |
964 | static 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 | |
994 | static 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 | |
1209 | void __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 | |
1231 | void __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 | |
1261 | void *__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 | |
1326 | void *__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 | |
1406 | int 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 | |
1559 | int 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 | |