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: SQLSetEnvAttr.c,v 1.9 2009/02/18 17:59:08 lurcher Exp $
31 *
32 * $Log: SQLSetEnvAttr.c,v $
33 * Revision 1.9 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.8 2009/02/17 09:47:44 lurcher
37 * Clear up a number of bugs
38 *
39 * Revision 1.7 2004/06/21 10:01:11 lurcher
40 *
41 * Fix a couple of 64 bit issues
42 *
43 * Revision 1.6 2003/10/30 18:20:46 lurcher
44 *
45 * Fix broken thread protection
46 * Remove SQLNumResultCols after execute, lease S4/S% to driver
47 * Fix string overrun in SQLDriverConnect
48 * Add initial support for Interix
49 *
50 * Revision 1.5 2003/03/05 09:48:45 lurcher
51 *
52 * Add some 64 bit fixes
53 *
54 * Revision 1.4 2003/01/23 15:33:25 lurcher
55 *
56 * Fix problems with using putenv()
57 *
58 * Revision 1.3 2002/12/05 17:44:31 lurcher
59 *
60 * Display unknown return values in return logging
61 *
62 * Revision 1.2 2002/02/21 18:44:09 lurcher
63 *
64 * Fix bug on 32 bit platforms without long long support
65 * Add option to set environment variables from the ini file
66 *
67 * Revision 1.1.1.1 2001/10/17 16:40:07 lurcher
68 *
69 * First upload to SourceForge
70 *
71 * Revision 1.5 2001/09/27 17:05:48 nick
72 *
73 * Assorted fixes and tweeks
74 *
75 * Revision 1.4 2001/07/03 09:30:41 nick
76 *
77 * Add ability to alter size of displayed message in the log
78 *
79 * Revision 1.3 2001/04/12 17:43:36 nick
80 *
81 * Change logging and added autotest to odbctest
82 *
83 * Revision 1.2 2000/12/14 18:10:19 nick
84 *
85 * Add connection pooling
86 *
87 * Revision 1.1.1.1 2000/09/04 16:42:52 nick
88 * Imported Sources
89 *
90 * Revision 1.7 1999/11/13 23:41:01 ngorham
91 *
92 * Alter the way DM logging works
93 * Upgrade the Postgres driver to 6.4.6
94 *
95 * Revision 1.6 1999/10/24 23:54:19 ngorham
96 *
97 * First part of the changes to the error reporting
98 *
99 * Revision 1.5 1999/09/21 22:34:25 ngorham
100 *
101 * Improve performance by removing unneeded logging calls when logging is
102 * disabled
103 *
104 * Revision 1.4 1999/07/10 21:10:17 ngorham
105 *
106 * Adjust error sqlstate from driver manager, depending on requested
107 * version (ODBC2/3)
108 *
109 * Revision 1.3 1999/07/04 21:05:08 ngorham
110 *
111 * Add LGPL Headers to code
112 *
113 * Revision 1.2 1999/06/30 23:56:55 ngorham
114 *
115 * Add initial thread safety code
116 *
117 * Revision 1.1.1.1 1999/05/29 13:41:08 sShandyb
118 * first go at it
119 *
120 * Revision 1.1.1.1 1999/05/27 18:23:18 pharvey
121 * Imported sources
122 *
123 * Revision 1.3 1999/05/09 23:27:11 nick
124 * All the API done now
125 *
126 * Revision 1.2 1999/04/30 16:22:47 nick
127 * Another checkpoint
128 *
129 * Revision 1.1 1999/04/25 23:06:11 nick
130 * Initial revision
131 *
132 *
133 **********************************************************************/
134
135#include <config.h>
136#include "drivermanager.h"
137
138static char const rcsid[]= "$RCSfile: SQLSetEnvAttr.c,v $ $Revision: 1.9 $";
139
140SQLRETURN SQLSetEnvAttr( SQLHENV environment_handle,
141 SQLINTEGER attribute,
142 SQLPOINTER value,
143 SQLINTEGER string_length )
144{
145 DMHENV environment = (DMHENV) environment_handle;
146 SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ];
147
148 /*
149 * we may do someting with these later
150 */
151
152 if ( !environment_handle &&
153 ( attribute == SQL_ATTR_CONNECTION_POOLING ||
154 attribute == SQL_ATTR_CP_MATCH ))
155 {
156 return SQL_SUCCESS;
157 }
158
159 /*
160 * check environment
161 */
162
163 if ( !__validate_env( environment ))
164 {
165 dm_log_write( __FILE__,
166 __LINE__,
167 LOG_INFO,
168 LOG_INFO,
169 "Error: SQL_INVALID_HANDLE" );
170
171 return SQL_INVALID_HANDLE;
172 }
173
174 function_entry( environment );
175
176 if ( log_info.log_flag )
177 {
178 sprintf( environment -> msg, "\n\t\tEntry:\
179\n\t\t\tEnvironment = %p\
180\n\t\t\tAttribute = %s\
181\n\t\t\tValue = %p\
182\n\t\t\tStrLen = %d",
183 environment,
184 __env_attr_as_string( s1, attribute ),
185 value,
186 (int)string_length );
187
188 dm_log_write( __FILE__,
189 __LINE__,
190 LOG_INFO,
191 LOG_INFO,
192 environment -> msg );
193 }
194
195 thread_protect( SQL_HANDLE_ENV, environment );
196
197 switch ( attribute )
198 {
199 case SQL_ATTR_CONNECTION_POOLING:
200 {
201#ifdef HAVE_PTRDIFF_T
202 SQLUINTEGER ptr = (ptrdiff_t) value;
203#else
204 SQLUINTEGER ptr = (SQLUINTEGER) value;
205#endif
206
207 if ( ptr != SQL_CP_OFF &&
208 ptr != SQL_CP_ONE_PER_DRIVER &&
209 ptr != SQL_CP_ONE_PER_HENV )
210 {
211 dm_log_write( __FILE__,
212 __LINE__,
213 LOG_INFO,
214 LOG_INFO,
215 "Error: HY024" );
216
217 __post_internal_error( &environment -> error,
218 ERROR_HY024, NULL,
219 environment -> requested_version );
220
221 return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR );
222 }
223
224 environment -> connection_pooling = ptr;
225 }
226 break;
227
228 case SQL_ATTR_CP_MATCH:
229 {
230#ifdef HAVE_PTRDIFF_T
231 SQLUINTEGER ptr = (ptrdiff_t) value;
232#else
233 SQLUINTEGER ptr = (SQLUINTEGER) value;
234#endif
235
236 if ( ptr != SQL_CP_STRICT_MATCH &&
237 ptr != SQL_CP_RELAXED_MATCH )
238 {
239 dm_log_write( __FILE__,
240 __LINE__,
241 LOG_INFO,
242 LOG_INFO,
243 "Error: HY024" );
244
245 __post_internal_error( &environment -> error,
246 ERROR_HY024, NULL,
247 environment -> requested_version );
248
249 return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR );
250 }
251
252 environment -> cp_match = ptr;
253 }
254 break;
255
256 case SQL_ATTR_ODBC_VERSION:
257 {
258#ifdef HAVE_PTRDIFF_T
259 SQLUINTEGER ptr = (ptrdiff_t) value;
260#else
261 SQLUINTEGER ptr = (SQLUINTEGER) value;
262#endif
263
264 if ( ptr != SQL_OV_ODBC2 &&
265 ptr != SQL_OV_ODBC3 &&
266 ptr != SQL_OV_ODBC3_80 )
267 {
268 dm_log_write( __FILE__,
269 __LINE__,
270 LOG_INFO,
271 LOG_INFO,
272 "Error: HY024" );
273
274 __post_internal_error( &environment -> error,
275 ERROR_HY024, NULL,
276 environment -> requested_version );
277
278 return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR );
279 }
280 else
281 {
282 if ( environment -> connection_count > 0 )
283 {
284 dm_log_write( __FILE__,
285 __LINE__,
286 LOG_INFO,
287 LOG_INFO,
288 "Error: S1010" );
289
290 __post_internal_error( &environment -> error,
291 ERROR_S1010, NULL,
292 environment -> requested_version );
293
294 return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR );
295 }
296
297 environment -> requested_version = ptr;
298 environment -> version_set = 1;
299 }
300 }
301 break;
302
303 case SQL_ATTR_OUTPUT_NTS:
304 {
305#ifdef HAVE_PTRDIFF_T
306 SQLUINTEGER ptr = (ptrdiff_t) value;
307#else
308 SQLUINTEGER ptr = (SQLUINTEGER) value;
309#endif
310
311 /*
312 * this must be one of the most brain dead atribute,
313 * it can be set, but only to TRUE, any other value
314 * (ie FALSE) returns a error. It's almost as if it's not
315 * settable :-)
316 */
317
318 if ( ptr == SQL_FALSE )
319 {
320 dm_log_write( __FILE__,
321 __LINE__,
322 LOG_INFO,
323 LOG_INFO,
324 "Error: HYC00" );
325
326 __post_internal_error( &environment -> error,
327 ERROR_HYC00, NULL,
328 environment -> requested_version );
329
330 return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR );
331 }
332 }
333 break;
334
335 /*
336 * unixODBC additions
337 */
338
339 case SQL_ATTR_UNIXODBC_ENVATTR:
340 if ( value )
341 {
342 char *str = (char*) value;
343
344 /*
345 * its a memory leak, but not much I can do, see "man putenv"
346 */
347 putenv( strdup( str ));
348
349 return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR );
350 }
351 break;
352
353 /*
354 * Third party extensions
355 */
356
357 case 1064: /* SQL_ATTR_APP_UNICODE_TYPE */
358 break;
359
360 default:
361 dm_log_write( __FILE__,
362 __LINE__,
363 LOG_INFO,
364 LOG_INFO,
365 "Error: HY092" );
366
367 __post_internal_error( &environment -> error,
368 ERROR_HY092, NULL,
369 environment -> requested_version );
370
371 return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_ERROR );
372 }
373
374 if ( log_info.log_flag )
375 {
376 sprintf( environment -> msg,
377 "\n\t\tExit:[%s]",
378 __get_return_status( SQL_SUCCESS, s1 ));
379
380 dm_log_write( __FILE__,
381 __LINE__,
382 LOG_INFO,
383 LOG_INFO,
384 environment -> msg );
385 }
386
387 return function_return_nodrv( SQL_HANDLE_ENV, environment, SQL_SUCCESS );
388}
389