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: SQLGetTypeInfoW.c,v 1.7 2009/02/18 17:59:08 lurcher Exp $
31 *
32 * $Log: SQLGetTypeInfoW.c,v $
33 * Revision 1.7 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.6 2008/08/29 08:01:39 lurcher
37 * Alter the way W functions are passed to the driver
38 *
39 * Revision 1.5 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.4 2004/01/12 09:54:39 lurcher
43 *
44 * Fix problem where STATE_S5 stops metadata calls
45 *
46 * Revision 1.3 2003/10/30 18:20:46 lurcher
47 *
48 * Fix broken thread protection
49 * Remove SQLNumResultCols after execute, lease S4/S% to driver
50 * Fix string overrun in SQLDriverConnect
51 * Add initial support for Interix
52 *
53 * Revision 1.2 2002/12/05 17:44:31 lurcher
54 *
55 * Display unknown return values in return logging
56 *
57 * Revision 1.1.1.1 2001/10/17 16:40:06 lurcher
58 *
59 * First upload to SourceForge
60 *
61 * Revision 1.3 2001/07/03 09:30:41 nick
62 *
63 * Add ability to alter size of displayed message in the log
64 *
65 * Revision 1.2 2001/04/12 17:43:36 nick
66 *
67 * Change logging and added autotest to odbctest
68 *
69 * Revision 1.1 2000/12/31 20:30:54 nick
70 *
71 * Add UNICODE support
72 *
73 *
74 **********************************************************************/
75
76#include <config.h>
77#include "drivermanager.h"
78
79static char const rcsid[]= "$RCSfile: SQLGetTypeInfoW.c,v $";
80
81SQLRETURN SQLGetTypeInfoW( SQLHSTMT statement_handle,
82 SQLSMALLINT data_type )
83{
84 DMHSTMT statement = (DMHSTMT) statement_handle;
85 SQLRETURN ret;
86 SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ];
87
88 /*
89 * check statement
90 */
91
92 if ( !__validate_stmt( statement ))
93 {
94 dm_log_write( __FILE__,
95 __LINE__,
96 LOG_INFO,
97 LOG_INFO,
98 "Error: SQL_INVALID_HANDLE" );
99
100#ifdef WITH_HANDLE_REDIRECT
101 {
102 DMHSTMT parent_statement;
103
104 parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT );
105
106 if ( parent_statement ) {
107 dm_log_write( __FILE__,
108 __LINE__,
109 LOG_INFO,
110 LOG_INFO,
111 "Info: found parent handle" );
112
113 if ( CHECK_SQLGETTYPEINFOW( parent_statement -> connection ))
114 {
115 dm_log_write( __FILE__,
116 __LINE__,
117 LOG_INFO,
118 LOG_INFO,
119 "Info: calling redirected driver function" );
120
121 return SQLGETTYPEINFOW( parent_statement -> connection,
122 statement_handle,
123 data_type );
124 }
125 }
126 }
127#endif
128 return SQL_INVALID_HANDLE;
129 }
130
131 function_entry( statement );
132
133 if ( log_info.log_flag )
134 {
135 sprintf( statement -> msg, "\n\t\tEntry:\
136\n\t\t\tStatement = %p\
137\n\t\t\tData Type = %s",
138 statement,
139 __type_as_string( s1, data_type ));
140
141 dm_log_write( __FILE__,
142 __LINE__,
143 LOG_INFO,
144 LOG_INFO,
145 statement -> msg );
146 }
147
148 thread_protect( SQL_HANDLE_STMT, statement );
149
150 /*
151 * check states
152 */
153
154#ifdef NR_PROBE
155 if ( statement -> state == STATE_S5 ||
156 statement -> state == STATE_S6 ||
157 statement -> state == STATE_S7 )
158#else
159 if (( statement -> state == STATE_S6 && statement -> eod == 0 ) ||
160 statement -> state == STATE_S7 )
161#endif
162 {
163 dm_log_write( __FILE__,
164 __LINE__,
165 LOG_INFO,
166 LOG_INFO,
167 "Error: 24000" );
168
169 __post_internal_error( &statement -> error,
170 ERROR_24000, NULL,
171 statement -> connection -> environment -> requested_version );
172
173 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
174 }
175 else if ( statement -> state == STATE_S8 ||
176 statement -> state == STATE_S9 ||
177 statement -> state == STATE_S10 ||
178 statement -> state == STATE_S13 ||
179 statement -> state == STATE_S14 ||
180 statement -> state == STATE_S15 )
181 {
182 dm_log_write( __FILE__,
183 __LINE__,
184 LOG_INFO,
185 LOG_INFO,
186 "Error: HY010" );
187
188 __post_internal_error( &statement -> error,
189 ERROR_HY010, NULL,
190 statement -> connection -> environment -> requested_version );
191
192 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
193 }
194
195 if ( statement -> state == STATE_S11 ||
196 statement -> state == STATE_S12 )
197 {
198 if ( statement -> interupted_func != SQL_API_SQLGETTYPEINFO )
199 {
200 dm_log_write( __FILE__,
201 __LINE__,
202 LOG_INFO,
203 LOG_INFO,
204 "Error: HY010" );
205
206 __post_internal_error( &statement -> error,
207 ERROR_HY010, NULL,
208 statement -> connection -> environment -> requested_version );
209
210 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
211 }
212 }
213
214 /*
215 * TO_DO Check the SQL_ATTR_METADATA_ID settings
216 */
217
218 if ( statement -> connection -> unicode_driver ||
219 CHECK_SQLGETTYPEINFOW( statement -> connection ))
220 {
221 if ( !CHECK_SQLGETTYPEINFOW( statement -> connection ))
222 {
223 dm_log_write( __FILE__,
224 __LINE__,
225 LOG_INFO,
226 LOG_INFO,
227 "Error: IM001" );
228
229 __post_internal_error( &statement -> error,
230 ERROR_IM001, NULL,
231 statement -> connection -> environment -> requested_version );
232
233 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
234 }
235
236 ret = SQLGETTYPEINFOW( statement -> connection ,
237 statement -> driver_stmt,
238 data_type );
239 }
240 else
241 {
242 if ( !CHECK_SQLGETTYPEINFO( statement -> connection ))
243 {
244 dm_log_write( __FILE__,
245 __LINE__,
246 LOG_INFO,
247 LOG_INFO,
248 "Error: IM001" );
249
250 __post_internal_error( &statement -> error,
251 ERROR_IM001, NULL,
252 statement -> connection -> environment -> requested_version );
253
254 return function_return_nodrv( SQL_HANDLE_STMT, statement, SQL_ERROR );
255 }
256
257 ret = SQLGETTYPEINFO( statement -> connection ,
258 statement -> driver_stmt,
259 data_type );
260 }
261
262 if ( SQL_SUCCEEDED( ret ))
263 {
264 statement -> state = STATE_S5;
265 statement -> prepared = 0;
266 }
267 else if ( ret == SQL_STILL_EXECUTING )
268 {
269 statement -> interupted_func = SQL_API_SQLGETTYPEINFO;
270 if ( statement -> state != STATE_S11 &&
271 statement -> state != STATE_S12 )
272 statement -> state = STATE_S11;
273 }
274 else
275 {
276 statement -> state = STATE_S1;
277 }
278
279 if ( log_info.log_flag )
280 {
281 sprintf( statement -> msg,
282 "\n\t\tExit:[%s]",
283 __get_return_status( ret, s1 ));
284
285 dm_log_write( __FILE__,
286 __LINE__,
287 LOG_INFO,
288 LOG_INFO,
289 statement -> msg );
290 }
291
292 return function_return( SQL_HANDLE_STMT, statement, ret );
293}
294