PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/2.3.0/DriverManager/SQLDescribeColW.c

#
C | 467 lines | 288 code | 50 blank | 129 comment | 52 complexity | de05cf875db67de727716e18fc1c57b9 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-1.0
  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@easysoft.com).
  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: SQLDescribeColW.c,v 1.14 2009/02/18 17:59:08 lurcher Exp $
  31. *
  32. * $Log: SQLDescribeColW.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:38 lurcher
  37. * Alter the way W functions are passed to the driver
  38. *
  39. * Revision 1.12 2008/05/20 13:43:47 lurcher
  40. * Vms fixes
  41. *
  42. * Revision 1.11 2007/04/02 10:50:18 lurcher
  43. * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 )
  44. *
  45. * Revision 1.10 2007/02/28 15:37:47 lurcher
  46. * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg
  47. *
  48. * Revision 1.9 2007/01/02 10:27:50 lurcher
  49. * Fix descriptor leak with unicode only driver
  50. *
  51. * Revision 1.8 2003/10/30 18:20:45 lurcher
  52. *
  53. * Fix broken thread protection
  54. * Remove SQLNumResultCols after execute, lease S4/S% to driver
  55. * Fix string overrun in SQLDriverConnect
  56. * Add initial support for Interix
  57. *
  58. * Revision 1.7 2002/12/05 17:44:30 lurcher
  59. *
  60. * Display unknown return values in return logging
  61. *
  62. * Revision 1.6 2002/08/23 09:42:37 lurcher
  63. *
  64. * Fix some build warnings with casts, and a AIX linker mod, to include
  65. * deplib's on the link line, but not the libtool generated ones
  66. *
  67. * Revision 1.5 2002/08/19 09:11:49 lurcher
  68. *
  69. * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state
  70. *
  71. * Revision 1.4 2002/07/24 08:49:51 lurcher
  72. *
  73. * Alter UNICODE support to use iconv for UNICODE-ANSI conversion
  74. *
  75. * Revision 1.3 2002/05/21 14:19:44 lurcher
  76. *
  77. * * Update libtool to escape from AIX build problem
  78. * * Add fix to avoid file handle limitations
  79. * * Add more UNICODE changes, it looks like it is native 16 representation
  80. * the old way can be reproduced by defining UCS16BE
  81. * * Add iusql, its just the same as isql but uses the wide functions
  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:05 lurcher
  91. *
  92. * First upload to SourceForge
  93. *
  94. * Revision 1.4 2001/07/03 09:30:41 nick
  95. *
  96. * Add ability to alter size of displayed message in the log
  97. *
  98. * Revision 1.3 2001/04/12 17:43:36 nick
  99. *
  100. * Change logging and added autotest to odbctest
  101. *
  102. * Revision 1.2 2001/03/21 12:26:27 nick
  103. *
  104. * Alter def for SQLDescribeColW
  105. *
  106. * Revision 1.1 2000/12/31 20:30:54 nick
  107. *
  108. * Add UNICODE support
  109. *
  110. *
  111. **********************************************************************/
  112. #include <config.h>
  113. #include "drivermanager.h"
  114. static char const rcsid[]= "$RCSfile: SQLDescribeColW.c,v $";
  115. SQLRETURN SQLDescribeColW( SQLHSTMT statement_handle,
  116. SQLUSMALLINT column_number,
  117. SQLWCHAR *column_name,
  118. SQLSMALLINT buffer_length,
  119. SQLSMALLINT *name_length,
  120. SQLSMALLINT *data_type,
  121. SQLULEN *column_size,
  122. SQLSMALLINT *decimal_digits,
  123. SQLSMALLINT *nullable )
  124. {
  125. DMHSTMT statement = (DMHSTMT) statement_handle;
  126. SQLRETURN ret;
  127. SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ], s2[ 100 + LOG_MESSAGE_LEN ], s3[ 100 + LOG_MESSAGE_LEN ], s4[ 100 + LOG_MESSAGE_LEN ];
  128. SQLCHAR s5[ 100 + LOG_MESSAGE_LEN ];
  129. SQLCHAR s6[ 100 + LOG_MESSAGE_LEN ];
  130. /*
  131. * check statement
  132. */
  133. if ( !__validate_stmt( statement ))
  134. {
  135. dm_log_write( __FILE__,
  136. __LINE__,
  137. LOG_INFO,
  138. LOG_INFO,
  139. "Error: SQL_INVALID_HANDLE" );
  140. #ifdef WITH_HANDLE_REDIRECT
  141. {
  142. DMHSTMT parent_statement;
  143. parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT );
  144. if ( parent_statement ) {
  145. dm_log_write( __FILE__,
  146. __LINE__,
  147. LOG_INFO,
  148. LOG_INFO,
  149. "Info: found parent handle" );
  150. if ( CHECK_SQLDESCRIBECOLW( parent_statement -> connection ))
  151. {
  152. dm_log_write( __FILE__,
  153. __LINE__,
  154. LOG_INFO,
  155. LOG_INFO,
  156. "Info: calling redirected driver function" );
  157. return SQLDESCRIBECOLW( parent_statement -> connection,
  158. statement_handle,
  159. column_number,
  160. column_name,
  161. buffer_length,
  162. name_length,
  163. data_type,
  164. column_size,
  165. decimal_digits,
  166. nullable );
  167. }
  168. }
  169. }
  170. #endif
  171. return SQL_INVALID_HANDLE;
  172. }
  173. function_entry( statement );
  174. if ( log_info.log_flag )
  175. {
  176. sprintf( statement -> msg, "\n\t\tEntry:\
  177. \n\t\t\tStatement = %p\
  178. \n\t\t\tColumn Number = %d\
  179. \n\t\t\tColumn Name = %p\
  180. \n\t\t\tBuffer Length = %d\
  181. \n\t\t\tName Length = %p\
  182. \n\t\t\tData Type = %p\
  183. \n\t\t\tColumn Size = %p\
  184. \n\t\t\tDecimal Digits = %p\
  185. \n\t\t\tNullable = %p",
  186. statement,
  187. column_number,
  188. column_name,
  189. buffer_length,
  190. name_length,
  191. data_type,
  192. column_size,
  193. decimal_digits,
  194. nullable );
  195. dm_log_write( __FILE__,
  196. __LINE__,
  197. LOG_INFO,
  198. LOG_INFO,
  199. statement -> msg );
  200. }
  201. thread_protect( SQL_HANDLE_STMT, statement );
  202. if ( column_number == 0 &&
  203. statement -> bookmarks_on == SQL_UB_OFF && statement -> connection -> bookmarks_on == SQL_UB_OFF )
  204. {
  205. dm_log_write( __FILE__,
  206. __LINE__,
  207. LOG_INFO,
  208. LOG_INFO,
  209. "Error: 07009" );
  210. __post_internal_error_api( &statement -> error,
  211. ERROR_07009, NULL,
  212. statement -> connection -> environment -> requested_version,
  213. SQL_API_SQLDESCRIBECOL );
  214. return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
  215. }
  216. /*
  217. * sadly we can't trust the numcols value
  218. *
  219. if ( statement -> numcols < column_number )
  220. {
  221. __post_internal_error( &statement -> error,
  222. ERROR_07009, NULL,
  223. statement -> connection -> environment -> requested_version );
  224. return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
  225. }
  226. */
  227. if ( buffer_length < 0 )
  228. {
  229. dm_log_write( __FILE__,
  230. __LINE__,
  231. LOG_INFO,
  232. LOG_INFO,
  233. "Error: HY090" );
  234. __post_internal_error( &statement -> error,
  235. ERROR_HY090, NULL,
  236. statement -> connection -> environment -> requested_version );
  237. return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
  238. }
  239. /*
  240. * check states
  241. */
  242. if ( statement -> state == STATE_S1 ||
  243. statement -> state == STATE_S8 ||
  244. statement -> state == STATE_S9 ||
  245. statement -> state == STATE_S10 )
  246. {
  247. dm_log_write( __FILE__,
  248. __LINE__,
  249. LOG_INFO,
  250. LOG_INFO,
  251. "Error: HY010" );
  252. __post_internal_error( &statement -> error,
  253. ERROR_HY010, NULL,
  254. statement -> connection -> environment -> requested_version );
  255. return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
  256. }
  257. else if ( statement -> state == STATE_S2 )
  258. {
  259. dm_log_write( __FILE__,
  260. __LINE__,
  261. LOG_INFO,
  262. LOG_INFO,
  263. "Error: 07005" );
  264. __post_internal_error( &statement -> error,
  265. ERROR_07005, NULL,
  266. statement -> connection -> environment -> requested_version );
  267. return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
  268. }
  269. else if ( statement -> state == STATE_S4 )
  270. {
  271. dm_log_write( __FILE__,
  272. __LINE__,
  273. LOG_INFO,
  274. LOG_INFO,
  275. "Error: HY010" );
  276. __post_internal_error( &statement -> error,
  277. ERROR_HY010, NULL,
  278. statement -> connection -> environment -> requested_version );
  279. return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
  280. }
  281. else if ( statement -> state == STATE_S8 ||
  282. statement -> state == STATE_S9 ||
  283. statement -> state == STATE_S10 )
  284. {
  285. dm_log_write( __FILE__,
  286. __LINE__,
  287. LOG_INFO,
  288. LOG_INFO,
  289. "Error: HY010" );
  290. __post_internal_error( &statement -> error,
  291. ERROR_HY010, NULL,
  292. statement -> connection -> environment -> requested_version );
  293. return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
  294. }
  295. if ( statement -> state == STATE_S11 ||
  296. statement -> state == STATE_S12 )
  297. {
  298. if ( statement -> interupted_func != SQL_API_SQLDESCRIBECOL )
  299. {
  300. dm_log_write( __FILE__,
  301. __LINE__,
  302. LOG_INFO,
  303. LOG_INFO,
  304. "Error: HY010" );
  305. __post_internal_error( &statement -> error,
  306. ERROR_HY010, NULL,
  307. statement -> connection -> environment -> requested_version );
  308. return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
  309. }
  310. }
  311. if ( statement -> connection -> unicode_driver ||
  312. CHECK_SQLDESCRIBECOLW( statement -> connection ))
  313. {
  314. if ( !CHECK_SQLDESCRIBECOLW( statement -> connection ))
  315. {
  316. dm_log_write( __FILE__,
  317. __LINE__,
  318. LOG_INFO,
  319. LOG_INFO,
  320. "Error: IM001" );
  321. __post_internal_error( &statement -> error,
  322. ERROR_IM001, NULL,
  323. statement -> connection -> environment -> requested_version );
  324. return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
  325. }
  326. ret = SQLDESCRIBECOLW( statement -> connection,
  327. statement -> driver_stmt,
  328. column_number,
  329. column_name,
  330. buffer_length,
  331. name_length,
  332. data_type,
  333. column_size,
  334. decimal_digits,
  335. nullable );
  336. }
  337. else
  338. {
  339. SQLCHAR *as1 = NULL;
  340. if ( !CHECK_SQLDESCRIBECOL( statement -> connection ))
  341. {
  342. dm_log_write( __FILE__,
  343. __LINE__,
  344. LOG_INFO,
  345. LOG_INFO,
  346. "Error: IM001" );
  347. __post_internal_error( &statement -> error,
  348. ERROR_IM001, NULL,
  349. statement -> connection -> environment -> requested_version );
  350. return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
  351. }
  352. if ( buffer_length > 0 && column_name )
  353. {
  354. as1 = malloc( buffer_length + 1 );
  355. }
  356. ret = SQLDESCRIBECOL( statement -> connection,
  357. statement -> driver_stmt,
  358. column_number,
  359. as1 ? as1 : (SQLCHAR*)column_name,
  360. buffer_length,
  361. name_length,
  362. data_type,
  363. column_size,
  364. decimal_digits,
  365. nullable );
  366. if ( column_name && as1 )
  367. {
  368. ansi_to_unicode_copy( column_name, (char*) as1, SQL_NTS, statement -> connection );
  369. }
  370. if ( as1 )
  371. {
  372. free( as1 );
  373. }
  374. }
  375. if ( (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) && data_type )
  376. {
  377. *data_type=__map_type(MAP_SQL_D2DM,statement->connection, *data_type);
  378. }
  379. if ( ret == SQL_STILL_EXECUTING )
  380. {
  381. statement -> interupted_func = SQL_API_SQLDESCRIBECOL;
  382. if ( statement -> state != STATE_S11 &&
  383. statement -> state != STATE_S12 )
  384. statement -> state = STATE_S11;
  385. }
  386. if ( log_info.log_flag )
  387. {
  388. if ( !SQL_SUCCEEDED( ret )) {
  389. sprintf( statement -> msg,
  390. "\n\t\tExit:[%s]",
  391. __get_return_status( ret, s6 ));
  392. }
  393. else {
  394. sprintf( statement -> msg,
  395. "\n\t\tExit:[%s]\
  396. \n\t\t\tColumn Name = %s\
  397. \n\t\t\tData Type = %s\
  398. \n\t\t\tColumn Size = %s\
  399. \n\t\t\tDecimal Digits = %s\
  400. \n\t\t\tNullable = %s",
  401. __get_return_status( ret, s6 ),
  402. __sdata_as_string( s1, SQL_CHAR,
  403. name_length, column_name ),
  404. __sptr_as_string( s2, data_type ),
  405. __ptr_as_string( s3, (SQLLEN*)column_size ),
  406. __sptr_as_string( s4, decimal_digits ),
  407. __sptr_as_string( s5, nullable ));
  408. }
  409. dm_log_write( __FILE__,
  410. __LINE__,
  411. LOG_INFO,
  412. LOG_INFO,
  413. statement -> msg );
  414. }
  415. return function_return( SQL_HANDLE_STMT, statement, ret );
  416. }