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 
SQLFetch(HSTMT hstmt)18 RETCODE SQL_API SQLFetch( HSTMT hstmt )
19 {
20 	stmt_t*  pstmt = hstmt;
21 	column_t*   pcol = pstmt->pcol;
22 	int      ncol, i;
23 	long     len, clen;
24 	char*    ptr;
25 	int      sqltype, sqlstat, dft_ctype, flag = 0, err;
26 	fptr_t      cvt;
27 	char*    ret;
28 
29 	UNSET_ERROR( pstmt->herr );
30 
31 	ncol = nnsql_getcolnum(pstmt->yystmt);
32 
33 	if ( !pstmt->refetch && (err = nnsql_fetch(pstmt->yystmt)) )
34 	{
35 		int   code;
36 
37 		if ( err == 100 )
38 			return SQL_NO_DATA_FOUND;
39 
40 		code = nnsql_errcode(pstmt->yystmt);
41 
42 		if ( code == -1 )
43 			code = errno;
44 
45 		PUSHSYSERR( pstmt->herr, code, nnsql_errmsg(pstmt->yystmt));
46 
47 		return SQL_ERROR;
48 	}
49 
50 	if ( !pcol )
51 	{
52 		int   max;
53 
54 		max = nnsql_max_column();
55 
56 		pcol = pstmt->pcol = (column_t*)MEM_ALLOC( sizeof(column_t)*(max+1) );
57 
58 		if ( ! pcol )
59 		{
60 			PUSHSQLERR( pstmt->herr, en_S1001 );
61 
62 			return SQL_ERROR;
63 		}
64 
65 		MEM_SET(pcol, 0, sizeof(column_t)*(max+1) );
66 
67 		return SQL_SUCCESS;
68 	}
69 
70 	for (i=0;i<ncol;i++, pcol++)
71 	{
72 		len = clen = 0L;
73 		pcol->offset = 0;
74 
75 		if ( ! pcol->userbuf )
76 			continue;
77 
78 		if ( nnsql_isnullcol(pstmt->yystmt, i) )
79 		{
80 			if ( pcol->pdatalen )
81 				*(pcol->pdatalen) = SQL_NULL_DATA;
82 			continue;
83 		}
84 
85 		if ( pcol->pdatalen )
86 			*(pcol->pdatalen ) = 0L;
87 
88 		if ( nnsql_isstrcol(pstmt->yystmt, i) )
89 		{
90 			ptr = nnsql_getstr(pstmt->yystmt, i);
91 			len = STRLEN(ptr) + 1;
92 			sqltype = SQL_CHAR;
93 			dft_ctype = SQL_C_CHAR;
94 		}
95 		else if ( nnsql_isnumcol(pstmt->yystmt, i) )
96 		{
97 			ptr = (char*)nnsql_getnum(pstmt->yystmt, i);
98 			sqltype = SQL_INTEGER;
99 			dft_ctype = SQL_C_LONG;
100 		}
101 		else if ( nnsql_isdatecol(pstmt->yystmt, i) )
102 		{
103 			ptr = (char*)nnsql_getdate(pstmt->yystmt, i);
104 			sqltype = SQL_DATE;
105 			dft_ctype = SQL_C_DATE;
106 		}
107 		else
108 			abort();
109 
110 		if ( pcol->ctype == SQL_C_DEFAULT )
111 			pcol->ctype = dft_ctype;
112 
113 		cvt = nnodbc_get_sql2c_cvt(sqltype, pcol->ctype);
114 
115 		if ( ! cvt )
116 		{
117 			pstmt->refetch = 1;
118 
119 			PUSHSQLERR(pstmt->herr, en_07006);
120 
121 			return SQL_ERROR;
122 		}
123 
124 		ret = cvt(  ptr, pcol->userbuf, pcol->userbufsize, &clen);
125 
126 		if ( ret )
127 		{
128 			pstmt->refetch = 1;
129 
130 			if ( clen )
131 				sqlstat = en_22003;
132 			else
133 				sqlstat = en_22005;
134 
135 			PUSHSQLERR( pstmt->herr, sqlstat );
136 
137 			return SQL_ERROR;
138 		}
139 
140 		if ( len && clen == len )
141 			flag = 1;
142 
143 		if ( len && pcol->pdatalen )
144 			*(pcol->pdatalen) = clen;	/* not 'len' but 'clen' */
145 	}
146 
147 	if ( flag )
148 	{
149 		PUSHSQLERR( pstmt->herr, en_01004 );
150 
151 		return SQL_SUCCESS_WITH_INFO;
152 	}
153 
154 	return SQL_SUCCESS;
155 }
156 
157 
158