1/*
2 *  GetData.c
3 *
4 *  $Id: GetData.c,v 1.7 2006/01/20 15:58:35 source Exp $
5 *
6 *  SQLGetData trace functions
7 *
8 *  The iODBC driver manager.
9 *
10 *  Copyright (C) 1996-2006 by OpenLink Software <iodbc@openlinksw.com>
11 *  All Rights Reserved.
12 *
13 *  This software is released under the terms of either of the following
14 *  licenses:
15 *
16 *      - GNU Library General Public License (see LICENSE.LGPL)
17 *      - The BSD License (see LICENSE.BSD).
18 *
19 *  Note that the only valid version of the LGPL license as far as this
20 *  project is concerned is the original GNU Library General Public License
21 *  Version 2, dated June 1991.
22 *
23 *  While not mandated by the BSD license, any patches you make to the
24 *  iODBC source code may be contributed back into the iODBC project
25 *  at your discretion. Contributions will benefit the Open Source and
26 *  Data Access community as a whole. Submissions may be made at:
27 *
28 *      http://www.iodbc.org
29 *
30 *
31 *  GNU Library Generic Public License Version 2
32 *  ============================================
33 *  This library is free software; you can redistribute it and/or
34 *  modify it under the terms of the GNU Library General Public
35 *  License as published by the Free Software Foundation; only
36 *  Version 2 of the License dated June 1991.
37 *
38 *  This library is distributed in the hope that it will be useful,
39 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
40 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41 *  Library General Public License for more details.
42 *
43 *  You should have received a copy of the GNU Library General Public
44 *  License along with this library; if not, write to the Free
45 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
46 *
47 *
48 *  The BSD License
49 *  ===============
50 *  Redistribution and use in source and binary forms, with or without
51 *  modification, are permitted provided that the following conditions
52 *  are met:
53 *
54 *  1. Redistributions of source code must retain the above copyright
55 *     notice, this list of conditions and the following disclaimer.
56 *  2. Redistributions in binary form must reproduce the above copyright
57 *     notice, this list of conditions and the following disclaimer in
58 *     the documentation and/or other materials provided with the
59 *     distribution.
60 *  3. Neither the name of OpenLink Software Inc. nor the names of its
61 *     contributors may be used to endorse or promote products derived
62 *     from this software without specific prior written permission.
63 *
64 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
65 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
66 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
67 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR
68 *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
69 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
70 *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
71 *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
72 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
73 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75 */
76
77#include "trace.h"
78
79
80void
81_trace_data (
82  SQLSMALLINT		  fCType,
83  SQLPOINTER		  rgbValue,
84  SQLLEN		  cbValueMax,
85  SQLLEN	    	* pcbValue,
86  int			  output)
87{
88  char buf[1024];		/* Temp buffer */
89
90  if (!rgbValue)
91    {
92      trace_emit ("\t\t%-15.15s   0x0\n", "SQLPOINTER");
93      return;
94    }
95
96  trace_emit ("\t\t%-15.15s   %p\n", "SQLPOINTER", rgbValue);
97
98  if (!output)
99    return;			/* Only print buffer content on leave */
100
101  switch (fCType)
102    {
103    case SQL_C_BINARY:
104		{
105			int len=cbValueMax;
106			if (pcbValue) {
107				len = *((SQLINTEGER *) pcbValue);
108				if (len>cbValueMax)
109					len = cbValueMax;
110			}
111			trace_emit_binary ((unsigned char *) rgbValue, len);
112		}
113      break;
114
115    case SQL_C_BIT:
116      {
117	int i = (int) *(char *) rgbValue;
118	sprintf (buf, "%d", i > 0 ? 1 : 0);
119	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
120      }
121      break;
122
123    case SQL_C_CHAR:
124      {
125		  int len=cbValueMax;
126		  if (pcbValue) {
127			  len = *((SQLINTEGER *) pcbValue);
128			  if (len>cbValueMax)
129				  len = cbValueMax;
130		  }
131		  trace_emit_string ((SQLCHAR *) rgbValue, len, 0);
132      }
133      break;
134
135    case SQL_C_DATE:
136#if ODBCVER >= 0x0300
137    case SQL_C_TYPE_DATE:
138#endif
139      {
140	DATE_STRUCT *d = (DATE_STRUCT *) rgbValue;
141	sprintf (buf, "%04d-%02d-%02d", d->year, d->month, d->day);
142	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
143      }
144      break;
145
146    case SQL_C_DEFAULT:
147      /*
148       *  Not enough information to dump the content of the buffer
149       */
150      return;
151
152    case SQL_C_DOUBLE:
153      {
154	double d = *(double *) rgbValue;
155	sprintf (buf, "%f", d);
156	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
157      }
158      break;
159
160    case SQL_C_FLOAT:
161      {
162	float f = *(float *) rgbValue;
163	sprintf (buf, "%f", f);
164	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
165      }
166      break;
167
168#if (ODBCVER >= 0x0350)
169    case SQL_C_GUID:
170      {
171	SQLGUID *g = (SQLGUID *) rgbValue;
172	sprintf (buf,
173	    "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
174	    (unsigned long) g->Data1,
175	    g->Data2, g->Data3,
176	    g->Data4[0], g->Data4[1], g->Data4[2], g->Data4[3],
177            g->Data4[4], g->Data4[5], g->Data4[6], g->Data4[7]);
178	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
179      }
180      break;
181#endif
182
183#if ODBCVER >= 0x0300
184    case SQL_C_INTERVAL_DAY:
185      {
186	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
187	sprintf (buf, "%lu days",
188	    (unsigned long) i->intval.day_second.day);
189	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
190      }
191      break;
192
193    case SQL_C_INTERVAL_DAY_TO_HOUR:
194      {
195	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
196	sprintf (buf, "%lu days %lu hours",
197	    (unsigned long) i->intval.day_second.day,
198	    (unsigned long) i->intval.day_second.hour);
199	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
200      }
201      break;
202
203    case SQL_C_INTERVAL_DAY_TO_MINUTE:
204      {
205	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
206	sprintf (buf, "%lu days %lu hours %lu minutes",
207	    (unsigned long) i->intval.day_second.day,
208	    (unsigned long) i->intval.day_second.hour,
209	    (unsigned long) i->intval.day_second.minute);
210	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
211      }
212      break;
213
214    case SQL_C_INTERVAL_DAY_TO_SECOND:
215      {
216	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
217	sprintf (buf, "%lu days %lu hours %lu minutes %lu seconds",
218	    (unsigned long) i->intval.day_second.day,
219	    (unsigned long) i->intval.day_second.hour,
220	    (unsigned long) i->intval.day_second.minute,
221	    (unsigned long) i->intval.day_second.second);
222	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
223      }
224      break;
225
226    case SQL_C_INTERVAL_HOUR:
227      {
228	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
229	sprintf (buf, "%lu hours",
230	    (unsigned long) i->intval.day_second.hour);
231	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
232      }
233      break;
234
235    case SQL_C_INTERVAL_HOUR_TO_MINUTE:
236      {
237	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
238	sprintf (buf, "%lu hours %lu minutes",
239	    (unsigned long) i->intval.day_second.hour,
240	    (unsigned long) i->intval.day_second.minute);
241	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
242      }
243      break;
244
245    case SQL_C_INTERVAL_HOUR_TO_SECOND:
246      {
247	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
248	sprintf (buf, "%lu hours %lu minutes %lu seconds",
249	    (unsigned long) i->intval.day_second.hour,
250	    (unsigned long) i->intval.day_second.minute,
251	    (unsigned long) i->intval.day_second.second);
252	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
253      }
254      break;
255
256    case SQL_C_INTERVAL_MINUTE:
257      {
258	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
259	sprintf (buf, "%lu minutes",
260	    (unsigned long) i->intval.day_second.minute);
261	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
262      }
263      break;
264
265    case SQL_C_INTERVAL_MINUTE_TO_SECOND:
266      {
267	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
268	sprintf (buf, "%lu minutes %lu seconds",
269	    (unsigned long) i->intval.day_second.minute,
270	    (unsigned long) i->intval.day_second.second);
271	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
272      }
273      break;
274
275    case SQL_C_INTERVAL_MONTH:
276      {
277	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
278	sprintf (buf, "%lu months",
279	    (unsigned long) i->intval.year_month.month);
280	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
281      }
282      break;
283
284    case SQL_C_INTERVAL_SECOND:
285      {
286	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
287	sprintf (buf, "%lu seconds",
288	    (unsigned long) i->intval.day_second.second);
289	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
290      }
291      break;
292
293    case SQL_C_INTERVAL_YEAR:
294      {
295	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
296	sprintf (buf, "%lu years",
297	    (unsigned long) i->intval.year_month.year);
298	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
299      }
300      break;
301
302    case SQL_C_INTERVAL_YEAR_TO_MONTH:
303      {
304	SQL_INTERVAL_STRUCT *i = (SQL_INTERVAL_STRUCT *) rgbValue;
305	sprintf (buf, "%lu years %lu months",
306	    (unsigned long) i->intval.year_month.year,
307	    (unsigned long) i->intval.year_month.month);
308	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
309      }
310      break;
311#endif
312
313    case SQL_C_LONG:
314    case SQL_C_SLONG:
315      {
316	long l = *(long *) rgbValue;
317	sprintf (buf, "%ld", l);
318	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
319      }
320      break;
321
322    case SQL_C_ULONG:
323      {
324	unsigned long l = *(unsigned long *) rgbValue;
325	sprintf (buf, "%lu", l);
326	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
327      }
328      break;
329
330
331#if ODBCVER >= 0x0300
332    case SQL_C_NUMERIC:
333      /* NOT YET */
334      break;
335#endif
336
337#if ODBCVER >= 0x0300
338    case SQL_C_SBIGINT:
339#if defined (ODBCINT64)
340      {
341	ODBCINT64 l = *(ODBCINT64 *) rgbValue;
342	sprintf (buf, "%lld", l);
343	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
344      }
345#endif
346      break;
347
348    case SQL_C_UBIGINT:
349#if defined (ODBCINT64)
350      {
351	unsigned ODBCINT64 l = *(unsigned ODBCINT64 *) rgbValue;
352	sprintf (buf, "%llu", l);
353	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
354      }
355#endif
356      break;
357#endif
358
359    case SQL_C_SHORT:
360    case SQL_C_SSHORT:
361      {
362	int i = (int) *(short *) rgbValue;
363	sprintf (buf, "%d", i);
364	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
365      }
366      break;
367
368    case SQL_C_USHORT:
369      {
370	unsigned int i = (unsigned int) *(unsigned short *) rgbValue;
371	sprintf (buf, "%u", i);
372	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
373      }
374      break;
375
376    case SQL_C_TIME:
377#if ODBCVER >= 0x0300
378    case SQL_C_TYPE_TIME:
379#endif
380      {
381	TIME_STRUCT *t = (TIME_STRUCT *) rgbValue;
382	sprintf (buf, "%02d:%02d:%02d", t->hour, t->minute, t->second);
383	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
384      }
385      break;
386
387    case SQL_C_TIMESTAMP:
388#if ODBCVER >= 0x0300
389    case SQL_C_TYPE_TIMESTAMP:
390#endif
391      {
392	TIMESTAMP_STRUCT *t = (TIMESTAMP_STRUCT *) rgbValue;
393	sprintf (buf, "%04d-%02d-%02d %02d:%02d:%02d.%06ld",
394	    t->year, t->month, t->day,
395	    t->hour, t->minute, t->second,
396	    (long) t->fraction);
397	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
398      }
399      break;
400
401    case SQL_C_TINYINT:
402    case SQL_C_STINYINT:
403      {
404	int i = (int) *(char *) rgbValue;
405	sprintf (buf, "%d", i);
406	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
407      }
408      break;
409
410    case SQL_C_UTINYINT:
411      {
412	unsigned int i = (unsigned int) *(unsigned char *) rgbValue;
413	sprintf (buf, "%u", i);
414	trace_emit_string ((SQLCHAR *) buf, SQL_NTS, 0);
415      }
416      break;
417
418    case SQL_C_WCHAR:
419      {
420	SQLCHAR *wstr;
421        int len;
422	if (pcbValue && cbValueMax > 0)
423	  len = *((SQLINTEGER *) pcbValue);
424	else
425	  len = cbValueMax;
426	wstr = dm_SQL_W2A ((wchar_t *) rgbValue, len);
427	trace_emit_string (wstr, SQL_NTS, 1);
428	free (wstr);
429      }
430      break;
431
432    default:
433      /*
434       *  Unhandled/Unknown datatype
435       */
436      break;
437    }
438
439  return;
440}
441
442
443void
444trace_SQLGetData (int trace_leave, int retcode,
445  SQLHSTMT		  hstmt,
446  SQLUSMALLINT		  icol,
447  SQLSMALLINT		  fCType,
448  SQLPOINTER		  rgbValue,
449  SQLLEN		  cbValueMax,
450  SQLLEN	    	* pcbValue)
451{
452  /* Trace function */
453  _trace_print_function (en_GetData, trace_leave, retcode);
454
455  /* Trace Arguments */
456  _trace_handle (SQL_HANDLE_STMT, hstmt);
457  _trace_usmallint (icol);
458  _trace_c_type (fCType);
459  _trace_data (fCType, rgbValue, cbValueMax, pcbValue, TRACE_OUTPUT_SUCCESS);
460  _trace_len (cbValueMax);
461  _trace_len_p (pcbValue, TRACE_OUTPUT_SUCCESS);
462}
463