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: SQLSetConnectAttrW.c,v 1.14 2009/02/18 17:59:08 lurcher Exp $
31 *
32 * $Log: SQLSetConnectAttrW.c,v $
33 * Revision 1.14 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.13 2008/08/29 08:01:39 lurcher
37 * Alter the way W functions are passed to the driver
38 *
39 * Revision 1.12 2007/02/28 15:37:48 lurcher
40 * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg
41 *
42 * Revision 1.11 2006/04/18 10:24:47 lurcher
43 * Add a couple of changes from Mark Vanderwiel
44 *
45 * Revision 1.10 2003/10/30 18:20:46 lurcher
46 *
47 * Fix broken thread protection
48 * Remove SQLNumResultCols after execute, lease S4/S% to driver
49 * Fix string overrun in SQLDriverConnect
50 * Add initial support for Interix
51 *
52 * Revision 1.9 2003/03/05 09:48:44 lurcher
53 *
54 * Add some 64 bit fixes
55 *
56 * Revision 1.8 2002/12/05 17:44:31 lurcher
57 *
58 * Display unknown return values in return logging
59 *
60 * Revision 1.7 2002/08/23 09:42:37 lurcher
61 *
62 * Fix some build warnings with casts, and a AIX linker mod, to include
63 * deplib's on the link line, but not the libtool generated ones
64 *
65 * Revision 1.6 2002/07/24 08:49:52 lurcher
66 *
67 * Alter UNICODE support to use iconv for UNICODE-ANSI conversion
68 *
69 * Revision 1.5 2002/07/16 13:08:18 lurcher
70 *
71 * Filter attribute values from SQLSetStmtAttr to SQLSetStmtOption to fit
72 * within ODBC 2
73 * Make DSN's double clickable in ODBCConfig
74 *
75 * Revision 1.4 2002/07/04 17:27:56 lurcher
76 *
77 * Small bug fixes
78 *
79 * Revision 1.3 2002/01/30 12:20:02 lurcher
80 *
81 * Add MyODBC 3 driver source
82 *
83 * Revision 1.2 2001/12/13 13:00:32 lurcher
84 *
85 * Remove most if not all warnings on 64 bit platforms
86 * Add support for new MS 3.52 64 bit changes
87 * Add override to disable the stopping of tracing
88 * Add MAX_ROWS support in postgres driver
89 *
90 * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher
91 *
92 * First upload to SourceForge
93 *
94 * Revision 1.7 2001/09/27 17:05:48 nick
95 *
96 * Assorted fixes and tweeks
97 *
98 * Revision 1.6 2001/08/08 17:05:17 nick
99 *
100 * Add support for attribute setting in the ini files
101 *
102 * Revision 1.5 2001/08/03 15:19:00 nick
103 *
104 * Add changes to set values before connect
105 *
106 * Revision 1.4 2001/07/03 09:30:41 nick
107 *
108 * Add ability to alter size of displayed message in the log
109 *
110 * Revision 1.3 2001/05/23 13:48:37 nick
111 *
112 * Remove unwanted include
113 *
114 * Revision 1.2 2001/04/12 17:43:36 nick
115 *
116 * Change logging and added autotest to odbctest
117 *
118 * Revision 1.1 2000/12/31 20:30:54 nick
119 *
120 * Add UNICODE support
121 *
122 *
123 **********************************************************************/
124
125 #include <config.h>
126 #include "drivermanager.h"
127
128 static char const rcsid[]= "$RCSfile: SQLSetConnectAttrW.c,v $";
129
SQLSetConnectAttrW(SQLHDBC connection_handle,SQLINTEGER attribute,SQLPOINTER value,SQLINTEGER string_length)130 SQLRETURN SQLSetConnectAttrW( SQLHDBC connection_handle,
131 SQLINTEGER attribute,
132 SQLPOINTER value,
133 SQLINTEGER string_length )
134 {
135 DMHDBC connection = (DMHDBC)connection_handle;
136 SQLRETURN ret;
137 SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ];
138 SQLWCHAR buffer[ 512 ];
139
140 /*
141 * doesn't require a handle
142 */
143
144 if ( attribute == SQL_ATTR_TRACE )
145 {
146 if ((SQLLEN) value != SQL_OPT_TRACE_OFF &&
147 (SQLLEN) value != SQL_OPT_TRACE_ON )
148 {
149 if ( __validate_dbc( connection ))
150 {
151 thread_protect( SQL_HANDLE_DBC, connection );
152 dm_log_write( __FILE__,
153 __LINE__,
154 LOG_INFO,
155 LOG_INFO,
156 "Error: HY024" );
157
158 function_entry( connection );
159 __post_internal_error( &connection -> error,
160 ERROR_HY024, NULL,
161 connection -> environment -> requested_version );
162
163 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
164 }
165 else
166 {
167 return SQL_INVALID_HANDLE;
168 }
169 }
170
171 if ((SQLLEN) value == SQL_OPT_TRACE_OFF )
172 {
173 char force_string[ 30 ];
174
175 SQLGetPrivateProfileString( "ODBC", "ForceTrace", "0",
176 force_string, sizeof( force_string ),
177 "ODBCINST.INI" );
178
179 if ( force_string[ 0 ] == '1' ||
180 toupper( force_string[ 0 ] ) == 'Y' ||
181 ( toupper( force_string[ 0 ] ) == 'O' &&
182 toupper( force_string[ 1 ] ) == 'N' ))
183 {
184 if ( log_info.log_flag )
185 {
186 dm_log_write( __FILE__,
187 __LINE__,
188 LOG_INFO,
189 LOG_INFO,
190 "Application tried to turn logging off" );
191 }
192 }
193 else
194 {
195 if ( log_info.log_flag )
196 {
197 dm_log_write( __FILE__,
198 __LINE__,
199 LOG_INFO,
200 LOG_INFO,
201 "Application turning logging off" );
202 }
203 log_info.log_flag = 0;
204 }
205 }
206 else
207 {
208 log_info.log_flag = 1;
209 }
210
211 return SQL_SUCCESS;
212 }
213 else if ( attribute == SQL_ATTR_TRACEFILE )
214 {
215 if ( value )
216 {
217 if (((SQLWCHAR*)value)[ 0 ] == 0 )
218 {
219 if ( __validate_dbc( connection ))
220 {
221 thread_protect( SQL_HANDLE_DBC, connection );
222 dm_log_write( __FILE__,
223 __LINE__,
224 LOG_INFO,
225 LOG_INFO,
226 "Error: HY024" );
227
228 function_entry( connection );
229 __post_internal_error( &connection -> error,
230 ERROR_HY024, NULL,
231 connection -> environment -> requested_version );
232
233 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
234 }
235 else
236 {
237 return SQL_INVALID_HANDLE;
238 }
239 }
240 else
241 {
242 if ( log_info.log_file_name )
243 {
244 free( log_info.log_file_name );
245 }
246 log_info.log_file_name = unicode_to_ansi_alloc((SQLWCHAR *) value, SQL_NTS, connection, NULL );
247 }
248 }
249 else
250 {
251 if ( __validate_dbc( connection ))
252 {
253 thread_protect( SQL_HANDLE_DBC, connection );
254 dm_log_write( __FILE__,
255 __LINE__,
256 LOG_INFO,
257 LOG_INFO,
258 "Error: HY024" );
259
260 function_entry( connection );
261 __post_internal_error( &connection -> error,
262 ERROR_HY024, NULL,
263 connection -> environment -> requested_version );
264
265 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
266 }
267 else
268 {
269 return SQL_INVALID_HANDLE;
270 }
271 }
272 return SQL_SUCCESS;
273 }
274
275 /*
276 * check connection
277 */
278
279 if ( !__validate_dbc( connection ))
280 {
281 dm_log_write( __FILE__,
282 __LINE__,
283 LOG_INFO,
284 LOG_INFO,
285 "Error: SQL_INVALID_HANDLE" );
286
287 #ifdef WITH_HANDLE_REDIRECT
288 {
289 DMHDBC parent_connection;
290
291 parent_connection = find_parent_handle( connection, SQL_HANDLE_DBC );
292
293 if ( parent_connection ) {
294 dm_log_write( __FILE__,
295 __LINE__,
296 LOG_INFO,
297 LOG_INFO,
298 "Info: found parent handle" );
299
300 if ( CHECK_SQLSETCONNECTATTRW( parent_connection ))
301 {
302 dm_log_write( __FILE__,
303 __LINE__,
304 LOG_INFO,
305 LOG_INFO,
306 "Info: calling redirected driver function" );
307
308 return SQLSETCONNECTATTRW( parent_connection,
309 connection_handle,
310 attribute,
311 value,
312 string_length );
313 }
314 }
315 }
316 #endif
317 return SQL_INVALID_HANDLE;
318 }
319
320 function_entry( connection );
321
322 if ( log_info.log_flag )
323 {
324 sprintf( connection -> msg, "\n\t\tEntry:\
325 \n\t\t\tConnection = %p\
326 \n\t\t\tAttribute = %s\
327 \n\t\t\tValue = %p\
328 \n\t\t\tStrLen = %d",
329 connection,
330 __con_attr_as_string( s1, attribute ),
331 value,
332 (int)string_length );
333
334 dm_log_write( __FILE__,
335 __LINE__,
336 LOG_INFO,
337 LOG_INFO,
338 connection -> msg );
339 }
340
341 thread_protect( SQL_HANDLE_DBC, connection );
342
343 if ( connection -> state == STATE_C2 )
344 {
345 if ( attribute == SQL_ATTR_TRANSLATE_OPTION ||
346 attribute == SQL_ATTR_TRANSLATE_LIB )
347 {
348 dm_log_write( __FILE__,
349 __LINE__,
350 LOG_INFO,
351 LOG_INFO,
352 "Error: 08003" );
353
354 __post_internal_error( &connection -> error,
355 ERROR_08003, NULL,
356 connection -> environment -> requested_version );
357
358 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
359 }
360 }
361 else if ( connection -> state == STATE_C3 )
362 {
363 dm_log_write( __FILE__,
364 __LINE__,
365 LOG_INFO,
366 LOG_INFO,
367 "Error: HY010" );
368
369 __post_internal_error( &connection -> error,
370 ERROR_HY010, NULL,
371 connection -> environment -> requested_version );
372
373 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
374 }
375 else if ( connection -> state == STATE_C4 ||
376 connection -> state == STATE_C5 ||
377 connection -> state == STATE_C6 )
378 {
379 if ( attribute == SQL_ATTR_ODBC_CURSORS )
380 {
381 dm_log_write( __FILE__,
382 __LINE__,
383 LOG_INFO,
384 LOG_INFO,
385 "Error: 08002" );
386
387 __post_internal_error( &connection -> error,
388 ERROR_08002, NULL,
389 connection -> environment -> requested_version );
390
391 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
392 }
393 else if ( attribute == SQL_ATTR_PACKET_SIZE )
394 {
395 dm_log_write( __FILE__,
396 __LINE__,
397 LOG_INFO,
398 LOG_INFO,
399 "Error: HY011" );
400
401 __post_internal_error( &connection -> error,
402 ERROR_HY011, NULL,
403 connection -> environment -> requested_version );
404
405 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
406 }
407 }
408
409 /*
410 * is it a legitimate value
411 */
412 ret = dm_check_connection_attrs( connection, attribute, value );
413
414 if ( ret != SQL_SUCCESS )
415 {
416 dm_log_write( __FILE__,
417 __LINE__,
418 LOG_INFO,
419 LOG_INFO,
420 "Error: HY024" );
421
422 __post_internal_error( &connection -> error,
423 ERROR_HY024, NULL,
424 connection -> environment -> requested_version );
425
426 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
427 }
428
429 /*
430 * is it a connection attribute or statement, check state of any active connections
431 */
432
433 switch( attribute )
434 {
435 /* ODBC 3.x statement attributes are not settable at the connection level */
436 case SQL_ATTR_APP_PARAM_DESC:
437 case SQL_ATTR_APP_ROW_DESC:
438 case SQL_ATTR_CURSOR_SCROLLABLE:
439 case SQL_ATTR_CURSOR_SENSITIVITY:
440 case SQL_ATTR_ENABLE_AUTO_IPD:
441 case SQL_ATTR_FETCH_BOOKMARK_PTR:
442 case SQL_ATTR_IMP_PARAM_DESC:
443 case SQL_ATTR_IMP_ROW_DESC:
444 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
445 case SQL_ATTR_PARAM_BIND_TYPE:
446 case SQL_ATTR_PARAM_OPERATION_PTR:
447 case SQL_ATTR_PARAM_STATUS_PTR:
448 case SQL_ATTR_PARAMS_PROCESSED_PTR:
449 case SQL_ATTR_PARAMSET_SIZE:
450 case SQL_ATTR_ROW_ARRAY_SIZE:
451 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
452 case SQL_ATTR_ROW_OPERATION_PTR:
453 case SQL_ATTR_ROW_STATUS_PTR:
454 case SQL_ATTR_ROWS_FETCHED_PTR:
455 __post_internal_error( &connection -> error,
456 ERROR_HY092, NULL,
457 connection -> environment -> requested_version );
458
459 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
460
461 case SQL_ATTR_CONCURRENCY:
462 case SQL_BIND_TYPE:
463 case SQL_ATTR_CURSOR_TYPE:
464 case SQL_ATTR_MAX_LENGTH:
465 case SQL_MAX_ROWS:
466 case SQL_ATTR_KEYSET_SIZE:
467 case SQL_ROWSET_SIZE:
468 case SQL_ATTR_NOSCAN:
469 case SQL_ATTR_QUERY_TIMEOUT:
470 case SQL_ATTR_RETRIEVE_DATA:
471 case SQL_ATTR_SIMULATE_CURSOR:
472 case SQL_ATTR_USE_BOOKMARKS:
473 if( __check_stmt_from_dbc_v( connection, 8, STATE_S8, STATE_S9, STATE_S10, STATE_S11, STATE_S12, STATE_S13, STATE_S14, STATE_S15 )) {
474
475 dm_log_write( __FILE__,
476 __LINE__,
477 LOG_INFO,
478 LOG_INFO,
479 "Error: 24000" );
480
481 __post_internal_error( &connection -> error,
482 ERROR_24000, NULL,
483 connection -> environment -> requested_version );
484
485 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
486 }
487 break;
488
489 default:
490
491 if( __check_stmt_from_dbc_v( connection, 8, STATE_S8, STATE_S9, STATE_S10, STATE_S11, STATE_S12, STATE_S13, STATE_S14, STATE_S15 )) {
492
493 dm_log_write( __FILE__,
494 __LINE__,
495 LOG_INFO,
496 LOG_INFO,
497 "Error: HY010" );
498
499 __post_internal_error( &connection -> error,
500 ERROR_HY010, NULL,
501 connection -> environment -> requested_version );
502
503 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
504 }
505 break;
506 }
507
508 /*
509 * is it something overridden
510 */
511
512 value = __attr_override_wide( connection, SQL_HANDLE_DBC, attribute, value, &string_length, buffer );
513
514 /*
515 * we need to save this even if connected so we can use it for the next connect
516 */
517 if ( attribute == SQL_ATTR_LOGIN_TIMEOUT )
518 {
519 connection -> login_timeout = ( SQLLEN ) value;
520 connection -> login_timeout_set = 1;
521 }
522
523 /*
524 * if connected, call the driver
525 * otherwise we need to save the states and set them when we
526 * do connect
527 */
528 if ( connection -> state == STATE_C2 )
529 {
530 /*
531 * is it for us
532 */
533
534 if ( attribute == SQL_ATTR_ODBC_CURSORS )
535 {
536 connection -> cursors = ( SQLLEN ) value;
537 }
538 else if ( attribute == SQL_ATTR_ACCESS_MODE )
539 {
540 connection -> access_mode = ( SQLLEN ) value;
541 connection -> access_mode_set = 1;
542 }
543 else if ( attribute == SQL_ATTR_ASYNC_ENABLE )
544 {
545 connection -> async_enable = ( SQLLEN ) value;
546 connection -> async_enable_set = 1;
547 }
548 else if ( attribute == SQL_ATTR_AUTO_IPD )
549 {
550 connection -> auto_ipd = ( SQLLEN ) value;
551 connection -> auto_ipd_set = 1;
552 }
553 else if ( attribute == SQL_ATTR_AUTOCOMMIT )
554 {
555 connection -> auto_commit = ( SQLLEN ) value;
556 connection -> auto_commit_set = 1;
557 }
558 else if ( attribute == SQL_ATTR_CONNECTION_TIMEOUT )
559 {
560 connection -> connection_timeout = ( SQLLEN ) value;
561 connection -> connection_timeout_set = 1;
562 }
563 else if ( attribute == SQL_ATTR_METADATA_ID )
564 {
565 connection -> metadata_id = ( SQLLEN ) value;
566 connection -> metadata_id_set = 1;
567 }
568 else if ( attribute == SQL_ATTR_PACKET_SIZE )
569 {
570 connection -> packet_size = ( SQLLEN ) value;
571 connection -> packet_size_set = 1;
572 }
573 else if ( attribute == SQL_ATTR_QUIET_MODE )
574 {
575 connection -> quite_mode = ( SQLLEN ) value;
576 connection -> quite_mode_set = 1;
577 }
578 else if ( attribute == SQL_ATTR_TXN_ISOLATION )
579 {
580 connection -> txn_isolation = ( SQLLEN ) value;
581 connection -> txn_isolation_set = 1;
582 }
583 else if ( attribute != SQL_ATTR_LOGIN_TIMEOUT )
584 {
585 /*
586 * save any unknown attributes untill connect
587 */
588
589 struct save_attr *sa = calloc( 1, sizeof( struct save_attr ));
590
591 sa -> attr_type = attribute;
592 if ( string_length > 0 )
593 {
594 sa -> str_attr = malloc( string_length );
595 memcpy( sa -> str_attr, value, string_length );
596 sa -> str_len = string_length;
597 }
598 else if ( string_length == SQL_NTS )
599 {
600 if (!value)
601 {
602 __post_internal_error( &connection -> error,
603 ERROR_HY024, "Invalid argument value",
604 connection -> environment -> requested_version );
605 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
606 }
607 else
608 {
609 sa -> str_attr = unicode_to_ansi_alloc( value, string_length, connection, NULL );
610 sa -> str_len = string_length;
611 }
612 }
613 else
614 {
615 sa -> intptr_attr = (intptr_t) value;
616 sa -> str_len = string_length;
617 }
618 sa -> next = connection -> save_attr;
619 connection -> save_attr = sa;
620 }
621
622 sprintf( connection -> msg,
623 "\n\t\tExit:[%s]",
624 __get_return_status( SQL_SUCCESS, s1 ));
625
626 dm_log_write( __FILE__,
627 __LINE__,
628 LOG_INFO,
629 LOG_INFO,
630 connection -> msg );
631
632 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_SUCCESS );
633 }
634 else
635 {
636 if ( connection -> unicode_driver ||
637 CHECK_SQLSETCONNECTATTRW( connection ))
638 {
639 if ( !CHECK_SQLSETCONNECTATTRW( connection ))
640 {
641 if ( CHECK_SQLSETCONNECTOPTIONW( connection ))
642 {
643 /*
644 * Is it in the legal range of values
645 */
646
647 if ( attribute < SQL_CONN_DRIVER_MIN &&
648 ( attribute > SQL_PACKET_SIZE || attribute < SQL_ACCESS_MODE ))
649 {
650 dm_log_write( __FILE__,
651 __LINE__,
652 LOG_INFO,
653 LOG_INFO,
654 "Error: HY092" );
655
656 __post_internal_error( &connection -> error,
657 ERROR_HY092, NULL,
658 connection -> environment -> requested_version );
659
660 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
661 }
662
663 ret = SQLSETCONNECTOPTIONW( connection,
664 connection -> driver_dbc,
665 attribute,
666 value );
667 }
668 else
669 {
670 dm_log_write( __FILE__,
671 __LINE__,
672 LOG_INFO,
673 LOG_INFO,
674 "Error: IM001" );
675
676 __post_internal_error( &connection -> error,
677 ERROR_IM001, NULL,
678 connection -> environment -> requested_version );
679
680 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
681 }
682 }
683 else
684 {
685 ret = SQLSETCONNECTATTRW( connection,
686 connection -> driver_dbc,
687 attribute,
688 value,
689 string_length );
690 }
691 }
692 else
693 {
694 if ( !CHECK_SQLSETCONNECTATTR( connection ))
695 {
696 if ( CHECK_SQLSETCONNECTOPTION( connection ))
697 {
698 SQLCHAR *as1 = NULL;
699
700 /*
701 * Is it in the legal range of values
702 */
703
704 if ( attribute < SQL_CONN_DRIVER_MIN &&
705 ( attribute > SQL_PACKET_SIZE || attribute < SQL_ACCESS_MODE ))
706 {
707 dm_log_write( __FILE__,
708 __LINE__,
709 LOG_INFO,
710 LOG_INFO,
711 "Error: HY092" );
712
713 __post_internal_error( &connection -> error,
714 ERROR_HY092, NULL,
715 connection -> environment -> requested_version );
716
717 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
718 }
719
720 switch( attribute )
721 {
722 case SQL_ATTR_CURRENT_CATALOG:
723 case SQL_ATTR_TRACEFILE:
724 case SQL_ATTR_TRANSLATE_LIB:
725 if ( value )
726 {
727 as1 = (SQLCHAR*) unicode_to_ansi_alloc( value, SQL_NTS, connection, NULL );
728 }
729 break;
730 }
731
732 ret = SQLSETCONNECTOPTION( connection,
733 connection -> driver_dbc,
734 attribute,
735 as1 ? as1 : value );
736
737 if ( as1 ) free( as1 );
738 }
739 else
740 {
741 dm_log_write( __FILE__,
742 __LINE__,
743 LOG_INFO,
744 LOG_INFO,
745 "Error: IM001" );
746
747 __post_internal_error( &connection -> error,
748 ERROR_IM001, NULL,
749 connection -> environment -> requested_version );
750
751 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
752 }
753 }
754 else
755 {
756 SQLCHAR *as1 = NULL;
757
758 switch( attribute )
759 {
760 case SQL_ATTR_CURRENT_CATALOG:
761 case SQL_ATTR_TRACEFILE:
762 case SQL_ATTR_TRANSLATE_LIB:
763 if ( value )
764 {
765 if ( string_length > 0 )
766 {
767 as1 = (SQLCHAR*) unicode_to_ansi_alloc( value, string_length, connection, NULL );
768 }
769 else if ( string_length == SQL_NTS )
770 {
771 as1 = (SQLCHAR*) unicode_to_ansi_alloc( value, SQL_NTS, connection, NULL );
772 }
773 }
774
775 ret = SQLSETCONNECTATTR( connection,
776 connection -> driver_dbc,
777 attribute,
778 as1 ? as1 : value,
779 string_length / sizeof( SQLWCHAR ));
780
781 if ( as1 )
782 {
783 free( as1 );
784 }
785 break;
786
787 default:
788 ret = SQLSETCONNECTATTR( connection,
789 connection -> driver_dbc,
790 attribute,
791 value,
792 string_length );
793 break;
794 }
795 }
796 }
797
798 if ( log_info.log_flag )
799 {
800 sprintf( connection -> msg,
801 "\n\t\tExit:[%s]",
802 __get_return_status( ret, s1 ));
803
804 dm_log_write( __FILE__,
805 __LINE__,
806 LOG_INFO,
807 LOG_INFO,
808 connection -> msg );
809 }
810 }
811
812 /*
813 * catch this
814 */
815
816 if ( attribute == SQL_ATTR_USE_BOOKMARKS && SQL_SUCCEEDED( ret ))
817 {
818 connection -> bookmarks_on = (SQLULEN) value;
819 }
820
821 return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 );
822 }
823