1 /**
2 Copyright (C) 1995, 1996 by Ke Jin <kejin@visigenic.com>
3 Enhanced for unixODBC (1999) by Peter Harvey <pharvey@codebydesign.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 **/
15 #include <config.h>
16 #include "driver.h"
17
18 /* It looks silly to use a MEM_ALLOC() in function char2str(), etc,
19 * for converting C data type into STRING SQL data type. Esspecially
20 * for char2str(), simply return the C data buffer address seems can
21 * do the same thing. However, all these 'to STRING' functions are
22 * assumed to be invoked in SQLExecute(), etc. According to ODBC, after
23 * that, user buffers are detached from the statement been executed.
24 * For example, for a statement:
25 *
26 * "SELECT FROM comp.databases WHERE subject LIKE ?"
27 *
28 * You may bind a SQL_C_CHAR data to it as the pattern for the
29 * LIKE condition. After SQLExecute(), the user buffer should be
30 * detached from the statement. You can change the data in that
31 * buffer without worry about the SQLFetch() results will be
32 * affected. If we don't use a separate buffer to keep the user
33 * data at SQLExecute() time but only keep a pointer of user buffer,
34 * then when user changes data in user buffer after SQLExecute()
35 * but before or during SQLFetch()s, the SQLFetch()'s result will
36 * be affected as a result of the change of LIKE condition.
37 *
38 * These allocated memory will be released by SQL layer.
39 */
40
41 typedef DATE_STRUCT odbc_date_t;
42
char2str(char * buf,int size)43 char* char2str( char* buf, int size )
44 {
45 char* ptr;
46 int len;
47
48 if( size < 0 )
49 size = STRLEN(buf);
50
51 ptr = (char*)MEM_ALLOC(size + 1);
52
53 if( ! ptr )
54 return (char*)(-1);
55
56 STRNCPY(ptr, buf, size+1);
57 ptr[size] = 0;
58
59 return ptr;
60 }
61
char2num(char * buf,int size)62 char* char2num( char* buf, int size)
63 {
64 char tbuf[16];
65
66 if( size < 0 )
67 size = strlen(buf);
68
69 if( size>15 )
70 size = 15;
71
72 STRNCPY(tbuf, buf, size);
73
74 tbuf[15] = 0;
75
76 return (char*)atol(tbuf);
77 }
78
char2date(char * buf,int size,date_t * dt)79 char* char2date( char* buf, int size, date_t* dt)
80 {
81 char tbuf[16];
82
83 if( size < 0 )
84 size = strlen(buf);
85
86 if( size > 15 )
87 size = 15;
88
89 STRNCPY( tbuf, buf, size);
90
91 tbuf[15] = 0;
92
93 if( nnsql_odbcdatestr2date(tbuf, dt) )
94 return (char*)(-1);
95
96 return (char*)dt;
97 }
98
date2str(odbc_date_t * dt)99 char* date2str( odbc_date_t* dt )
100 {
101 char* ptr;
102
103 if( dt->year < 0 || dt->year > 9999
104 || dt->month< 1 || dt->month> 12
105 || dt->day < 1 || dt->day > 31
106 || !( ptr = (char*)MEM_ALLOC(12)) )
107 return (char*)(-1);
108
109 sprintf(ptr, "%04d-%02d-%02d", dt->year, dt->month, dt->day);
110
111 return ptr;
112 }
113
odate2date(odbc_date_t * odt,int size,date_t * dt)114 char* odate2date( odbc_date_t* odt, int size, date_t* dt )
115 {
116 if( dt->year < 0 || dt->year > 9999
117 || dt->month< 1 || dt->month> 12
118 || dt->day < 1 || dt->day > 31 )
119 return (char*)(-1);
120
121 dt->year = odt->year;
122 dt->month= odt->month;
123 dt->day = odt->day;
124
125 return (char*)dt;
126 }
127
tint2num(char * d)128 char* tint2num( char* d )
129 {
130 long num = *d;
131
132 return (char*)num;
133 }
134
short2num(short * d)135 char* short2num( short* d )
136 {
137 long num = *d;
138
139 return (char*)num;
140 }
141
long2num(long * d)142 char* long2num( long* d )
143 {
144 return (char*)*d;
145 }
146
tint2str(char * d)147 char* tint2str( char* d )
148 {
149 int c = *d;
150 char* ptr;
151
152 if( ! (ptr = MEM_ALLOC(5)) )
153 return (char*)(-1);
154
155 sprintf(ptr, "%d", c);
156
157 return ptr;
158 }
159
short2str(short * d)160 char* short2str( short* d )
161 {
162 int c = *d;
163 char* ptr;
164
165 if( ! (ptr = MEM_ALLOC(32)) )
166 return (char*)(-1);
167
168 sprintf(ptr, "%d", c);
169
170 return ptr;
171 }
172
long2str(long * d)173 char* long2str( long* d )
174 {
175 long l = *d;
176 char* ptr;
177
178 if( ! (ptr = MEM_ALLOC(64)) )
179 return (char*)(-1);
180
181 sprintf(ptr, "%ld", l);
182
183 return ptr;
184 }
185
186 static fptr_t c2sql_cvt_tab[5][3] =
187 {
188 char2str, char2num, char2date,
189 tint2str, tint2num, 0,
190 short2str, short2num,0,
191 long2str, long2num, 0,
192 date2str, 0, odate2date
193 };
194
195 static struct {
196 int ctype;
197 int idx;
198 } ctype_idx_tab[] =
199 {
200 SQL_C_CHAR, 0,
201
202 SQL_C_TINYINT, 1,
203 SQL_C_STINYINT, 1,
204 SQL_C_UTINYINT, 1,
205
206 SQL_C_SHORT, 2,
207 SQL_C_SSHORT, 2,
208 SQL_C_USHORT, 2,
209
210 SQL_C_LONG, 3,
211 SQL_C_SLONG, 3,
212 SQL_C_ULONG, 3,
213
214 SQL_C_DATE, 4
215 };
216
217 static struct {
218 int sqltype;
219 int idx;
220 } sqltype_idx_tab[] =
221 {
222 SQL_CHAR, 0,
223 SQL_VARCHAR, 0,
224 SQL_LONGVARCHAR,0,
225
226 SQL_TINYINT, 1,
227 SQL_SMALLINT, 1,
228 SQL_INTEGER, 1,
229
230 SQL_DATE, 2
231 };
232
nnodbc_get_c2sql_cvt(int ctype,int sqltype)233 fptr_t nnodbc_get_c2sql_cvt(int ctype, int sqltype)
234 {
235 int i, cidx = -1, sqlidx = -1;
236
237 for(i=0; i< sizeof(ctype_idx_tab) / sizeof(ctype_idx_tab[ 0 ]); i++ )
238 {
239 if( ctype_idx_tab[i].ctype == ctype )
240 {
241 cidx = ctype_idx_tab[i].idx;
242 break;
243 }
244 }
245
246 if( cidx == -1 )
247 return 0;
248
249 for(i=0; i< sizeof(sqltype_idx_tab) / sizeof(sqltype_idx_tab[ 0 ]); i++ )
250 {
251 if( sqltype_idx_tab[i].sqltype == sqltype )
252 {
253 sqlidx = sqltype_idx_tab[i].idx;
254 break;
255 }
256 }
257
258 if( sqlidx == -1 )
259 return 0;
260
261 return c2sql_cvt_tab[cidx][sqlidx];
262 }
263
str2char(char * ptr,char * buf,long size,long * psize)264 static char* str2char( char* ptr, char* buf, long size, long* psize)
265 {
266 long len;
267
268 len = STRLEN(ptr) + 1;
269
270 if( len > size )
271 len = size;
272
273 if( len )
274 {
275 STRNCPY( buf, ptr, len );
276 buf[len - 1] = 0;
277 }
278
279 *psize = len;
280
281 return 0;
282 }
283
str2tint(char * ptr,char * buf,long size,long * psize)284 static char* str2tint( char* ptr, char* buf, long size, long* psize )
285 {
286 unsigned long a, b = (unsigned char)(-1);
287
288 a = (unsigned long)atol(ptr);
289
290 if( a > b )
291 {
292 *psize = a;
293 return (char*)(-1);
294 }
295
296 *buf = (char)a;
297
298 return 0;
299 }
300
str2short(char * ptr,short * buf,long size,long * psize)301 static char* str2short( char* ptr, short* buf, long size, long* psize)
302 {
303 unsigned long a, b = (unsigned short)(-1);
304
305 a = atoi(ptr);
306
307 if( a > b )
308 {
309 *psize = a;
310 return (char*)(-1);
311 }
312
313 *buf = (short)a;
314
315 return 0;
316 }
317
str2long(char * ptr,long * buf)318 static char* str2long( char* ptr, long* buf)
319 {
320 *buf = atol(ptr);
321 return 0;
322 }
323
str2date(char * ptr,odbc_date_t * buf)324 static char* str2date( char* ptr, odbc_date_t* buf )
325 {
326 date_t dt;
327
328 if( nnsql_nndatestr2date(ptr, &dt) )
329 return (char*)(-1);
330
331 buf->year = dt.year;
332 buf->month= dt.month;
333 buf->day = dt.day;
334
335 return 0;
336 }
337
num2char(long x,char * buf,long size,long * psize)338 static char* num2char( long x, char* buf, long size, long* psize)
339 {
340 char tbuf[48];
341
342 sprintf(tbuf, "%ld", x);
343
344 *psize = STRLEN(buf) + 1;
345
346 if(*psize > size )
347 return (char*)(-1);
348
349 STRCPY(buf, tbuf);
350
351 return 0;
352 }
353
num2tint(long x,char * buf,long size,long * psize)354 static char* num2tint(long x, char* buf, long size, long* psize)
355 {
356 unsigned long a = x, b = (unsigned char)(-1);
357
358 if( a > b )
359 {
360 *psize = x;
361 return (char*)(-1);
362 }
363
364 *buf = (char)x;
365
366 return 0;
367 }
368
num2short(long x,short * buf,long size,long * psize)369 static char* num2short(long x, short* buf, long size, long* psize)
370 {
371 unsigned long a = x, b = (unsigned short)(-1);
372
373 if( a > b)
374 {
375 *psize = x;
376 return (char*)(-1);
377 }
378
379 *buf = (short)x;
380
381 return 0;
382 }
383
num2long(long x,long * buf)384 static char* num2long(long x, long* buf )
385 {
386 *buf = x;
387
388 return 0;
389 }
390
date2char(date_t * dt,char * buf,long size,long * psize)391 static char* date2char(date_t* dt, char* buf, long size, long* psize)
392 {
393 *psize = 11;
394
395 if(size < 11)
396 return (char*)(-1);
397
398 sprintf(buf, "%04d-%02d-%02d", dt->year, dt->month, dt->day);
399
400 return 0;
401 }
402
date2odate(date_t * dt,odbc_date_t * buf)403 static char* date2odate(date_t* dt, odbc_date_t* buf)
404 {
405 buf->year = dt->year;
406 buf->month= dt->month;
407 buf->day = dt->day;
408
409 return 0;
410 }
411
412 static fptr_t sql2c_cvt_tab[3][5] =
413 {
414 str2char, str2tint, str2short, str2long, str2date,
415 num2char, num2tint, num2short, num2long, 0,
416 date2char, 0, 0, 0, date2odate
417 };
418
nnodbc_get_sql2c_cvt(int sqltype,int ctype)419 fptr_t nnodbc_get_sql2c_cvt(int sqltype, int ctype)
420 {
421 int i, cidx = -1, sqlidx = -1;
422
423 for(i=0; i< sizeof(ctype_idx_tab) / sizeof(ctype_idx_tab[ 0 ]); i++ )
424 {
425 if( ctype_idx_tab[i].ctype == ctype )
426 {
427 cidx = ctype_idx_tab[i].idx;
428 break;
429 }
430 }
431
432 if( cidx == -1 )
433 return 0;
434
435 for(i=0; i< sizeof(sqltype_idx_tab) / sizeof(sqltype_idx_tab[ 0 ]); i++ )
436 {
437 if( sqltype_idx_tab[i].sqltype == sqltype )
438 {
439 sqlidx = sqltype_idx_tab[i].idx;
440 break;
441 }
442 }
443
444 if( sqlidx == -1 )
445 return 0;
446
447 return sql2c_cvt_tab[sqlidx][cidx];
448 }
449