1 /*
2  *  result.c
3  *
4  *  $Id: result.c 2613 1999-06-01 15:32:12Z VZ $
5  *
6  *  Prepare for getting query result
7  *
8  *  The iODBC driver manager.
9  *
10  *  Copyright (C) 1995 by Ke Jin <kejin@empress.com>
11  *
12  *  This library is free software; you can redistribute it and/or
13  *  modify it under the terms of the GNU Library General Public
14  *  License as published by the Free Software Foundation; either
15  *  version 2 of the License, or (at your option) any later version.
16  *
17  *  This library is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  *  Library General Public License for more details.
21  *
22  *  You should have received a copy of the GNU Library General Public
23  *  License along with this library; if not, write to the Free
24  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  */
26 
27 #include	"config.h"
28 
29 #include	"isql.h"
30 #include	"isqlext.h"
31 
32 #include        "dlproc.h"
33 
34 #include	"herr.h"
35 #include	"henv.h"
36 #include	"hdbc.h"
37 #include	"hstmt.h"
38 
39 #include	"itrace.h"
40 
41 RETCODE SQL_API
SQLBindCol(HSTMT hstmt,UWORD icol,SWORD fCType,PTR rgbValue,SDWORD cbValueMax,SDWORD FAR * pcbValue)42 SQLBindCol (
43     HSTMT hstmt,
44     UWORD icol,
45     SWORD fCType,
46     PTR rgbValue,
47     SDWORD cbValueMax,
48     SDWORD FAR * pcbValue)
49 {
50   STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
51   HPROC hproc = SQL_NULL_HPROC;
52   RETCODE retcode;
53 
54   if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
55     {
56       return SQL_INVALID_HANDLE;
57     }
58 
59   /* check argument */
60   switch (fCType)
61      {
62      case SQL_C_DEFAULT:
63      case SQL_C_CHAR:
64      case SQL_C_BINARY:
65      case SQL_C_BIT:
66      case SQL_C_TINYINT:
67      case SQL_C_STINYINT:
68      case SQL_C_UTINYINT:
69      case SQL_C_SHORT:
70      case SQL_C_SSHORT:
71      case SQL_C_USHORT:
72      case SQL_C_LONG:
73      case SQL_C_SLONG:
74      case SQL_C_ULONG:
75      case SQL_C_FLOAT:
76      case SQL_C_DOUBLE:
77      case SQL_C_DATE:
78      case SQL_C_TIME:
79      case SQL_C_TIMESTAMP:
80        break;
81 
82      default:
83        PUSHSQLERR (pstmt->herr, en_S1003);
84        return SQL_ERROR;
85      }
86 
87   if (cbValueMax < 0)
88     {
89       PUSHSQLERR (pstmt->herr, en_S1090);
90 
91       return SQL_ERROR;
92     }
93 
94   /* check state */
95   if (pstmt->state > en_stmt_needdata || pstmt->asyn_on != en_NullProc)
96     {
97       PUSHSQLERR (pstmt->herr, en_S1010);
98       return SQL_ERROR;
99     }
100 
101   /* call driver's function */
102   hproc = _iodbcdm_getproc (pstmt->hdbc, en_BindCol);
103 
104   if (hproc == SQL_NULL_HPROC)
105     {
106       PUSHSQLERR (pstmt->herr, en_IM001);
107 
108       return SQL_ERROR;
109     }
110 
111   CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_BindCol,
112     (pstmt->dhstmt, icol, fCType, rgbValue, cbValueMax, pcbValue))
113 
114   return retcode;
115 }
116 
117 
118 RETCODE SQL_API
SQLGetCursorName(HSTMT hstmt,UCHAR FAR * szCursor,SWORD cbCursorMax,SWORD FAR * pcbCursor)119 SQLGetCursorName (
120     HSTMT hstmt,
121     UCHAR FAR * szCursor,
122     SWORD cbCursorMax,
123     SWORD FAR * pcbCursor)
124 {
125   STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
126   HPROC hproc;
127   RETCODE retcode;
128 
129   if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
130     {
131       return SQL_INVALID_HANDLE;
132     }
133 
134   /* check argument */
135   if (cbCursorMax < (SWORD) 0)
136     {
137       PUSHSQLERR (pstmt->herr, en_S1090);
138 
139       return SQL_ERROR;
140     }
141 
142   /* check state */
143   if (pstmt->state >= en_stmt_needdata || pstmt->asyn_on != en_NullProc)
144     {
145       PUSHSQLERR (pstmt->herr, en_S1010);
146 
147       return SQL_ERROR;
148     }
149 
150   if (pstmt->state < en_stmt_cursoropen
151       && pstmt->cursor_state == en_stmt_cursor_no)
152     {
153       PUSHSQLERR (pstmt->herr, en_S1015);
154 
155       return SQL_ERROR;
156     }
157 
158   /* call driver's function */
159   hproc = _iodbcdm_getproc (pstmt->hdbc, en_GetCursorName);
160 
161   if (hproc == SQL_NULL_HPROC)
162     {
163       PUSHSQLERR (pstmt->herr, en_IM001);
164 
165       return SQL_ERROR;
166     }
167 
168   CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_GetCursorName,
169     (pstmt->dhstmt, szCursor, cbCursorMax, pcbCursor))
170 
171   return retcode;
172 }
173 
174 
175 RETCODE SQL_API
SQLRowCount(HSTMT hstmt,SDWORD FAR * pcrow)176 SQLRowCount (
177     HSTMT hstmt,
178     SDWORD FAR * pcrow)
179 {
180   STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
181   HPROC hproc;
182   RETCODE retcode;
183 
184   if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
185     {
186       return SQL_INVALID_HANDLE;
187     }
188 
189   /* check state */
190   if (pstmt->state >= en_stmt_needdata
191       || pstmt->state <= en_stmt_prepared
192       || pstmt->asyn_on != en_NullProc)
193     {
194       PUSHSQLERR (pstmt->herr, en_S1010);
195 
196       return SQL_ERROR;
197     }
198 
199   /* call driver */
200   hproc = _iodbcdm_getproc (pstmt->hdbc, en_RowCount);
201 
202   if (hproc == SQL_NULL_HPROC)
203     {
204       PUSHSQLERR (pstmt->herr, en_IM001);
205 
206       return SQL_ERROR;
207     }
208 
209   CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_RowCount,
210     (pstmt->dhstmt, pcrow))
211 
212   return retcode;
213 }
214 
215 
216 RETCODE SQL_API
SQLNumResultCols(HSTMT hstmt,SWORD FAR * pccol)217 SQLNumResultCols (
218     HSTMT hstmt,
219     SWORD FAR * pccol)
220 {
221   STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
222   HPROC hproc;
223   RETCODE retcode;
224   SWORD ccol;
225 
226   if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
227     {
228       return SQL_INVALID_HANDLE;
229     }
230 
231   /* check state */
232   if (pstmt->asyn_on == en_NullProc)
233     {
234       if (pstmt->state == en_stmt_allocated
235 	  || pstmt->state >= en_stmt_needdata)
236 	{
237 	  PUSHSQLERR (pstmt->herr, en_S1010);
238 	  return SQL_ERROR;
239 	}
240     }
241   else if (pstmt->asyn_on != en_NumResultCols)
242     {
243       PUSHSQLERR (pstmt->herr, en_S1010);
244 
245       return SQL_ERROR;
246     }
247 
248   /* call driver */
249   hproc = _iodbcdm_getproc (pstmt->hdbc, en_NumResultCols);
250 
251   if (hproc == SQL_NULL_HPROC)
252     {
253       PUSHSQLERR (pstmt->herr, en_IM001);
254 
255       return SQL_ERROR;
256     }
257 
258   CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_NumResultCols,
259     (pstmt->dhstmt, &ccol))
260 
261   /* state transition */
262   if (pstmt->asyn_on == en_NumResultCols)
263     {
264       switch (retcode)
265 	 {
266 	 case SQL_SUCCESS:
267 	 case SQL_SUCCESS_WITH_INFO:
268 	 case SQL_ERROR:
269 	   pstmt->asyn_on = en_NullProc;
270 
271 	 case SQL_STILL_EXECUTING:
272 	 default:
273 	   break;
274 	 }
275     }
276 
277   switch (retcode)
278      {
279      case SQL_SUCCESS:
280      case SQL_SUCCESS_WITH_INFO:
281        break;
282 
283      case SQL_STILL_EXECUTING:
284        ccol = 0;
285        pstmt->asyn_on = en_NumResultCols;
286        break;
287 
288      default:
289        ccol = 0;
290        break;
291      }
292 
293   if (pccol)
294     {
295       *pccol = ccol;
296     }
297 
298   return retcode;
299 }
300 
301 
302 RETCODE SQL_API
SQLDescribeCol(HSTMT hstmt,UWORD icol,UCHAR FAR * szColName,SWORD cbColNameMax,SWORD FAR * pcbColName,SWORD FAR * pfSqlType,UDWORD FAR * pcbColDef,SWORD FAR * pibScale,SWORD FAR * pfNullable)303 SQLDescribeCol (
304     HSTMT hstmt,
305     UWORD icol,
306     UCHAR FAR * szColName,
307     SWORD cbColNameMax,
308     SWORD FAR * pcbColName,
309     SWORD FAR * pfSqlType,
310     UDWORD FAR * pcbColDef,
311     SWORD FAR * pibScale,
312     SWORD FAR * pfNullable)
313 {
314   STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
315   HPROC hproc;
316   RETCODE retcode;
317   int sqlstat = en_00000;
318 
319   if (hstmt == SQL_NULL_HSTMT
320       || pstmt->hdbc == SQL_NULL_HDBC)
321     {
322       return SQL_INVALID_HANDLE;
323     }
324 
325   /* check arguments */
326   if (icol == 0)
327     {
328       sqlstat = en_S1002;
329     }
330   else if (cbColNameMax < 0)
331     {
332       sqlstat = en_S1090;
333     }
334 
335   if (sqlstat != en_00000)
336     {
337       PUSHSQLERR (pstmt->herr, sqlstat);
338 
339       return SQL_ERROR;
340     }
341 
342   /* check state */
343   if (pstmt->asyn_on == en_NullProc)
344     {
345       if (pstmt->asyn_on == en_stmt_allocated
346 	  || pstmt->asyn_on >= en_stmt_needdata)
347 	{
348 	  sqlstat = en_S1010;
349 	}
350     }
351   else if (pstmt->asyn_on != en_DescribeCol)
352     {
353       sqlstat = en_S1010;
354     }
355 
356   if (sqlstat != en_00000)
357     {
358       PUSHSQLERR (pstmt->herr, sqlstat);
359 
360       return SQL_ERROR;
361     }
362 
363   /* call driver */
364   hproc = _iodbcdm_getproc (pstmt->hdbc, en_DescribeCol);
365 
366   if (hproc == SQL_NULL_HPROC)
367     {
368       PUSHSQLERR (pstmt->herr, en_IM001);
369 
370       return SQL_ERROR;
371     }
372 
373   CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_DescribeCol,
374     (pstmt->dhstmt, icol, szColName, cbColNameMax, pcbColName,
375       pfSqlType, pcbColDef, pibScale, pfNullable))
376 
377   /* state transition */
378   if (pstmt->asyn_on == en_DescribeCol)
379     {
380       switch (retcode)
381 	 {
382 	 case SQL_SUCCESS:
383 	 case SQL_SUCCESS_WITH_INFO:
384 	 case SQL_ERROR:
385 	   pstmt->asyn_on = en_NullProc;
386 	   break;
387 
388 	 default:
389 	   return retcode;
390 	 }
391     }
392 
393   switch (pstmt->state)
394      {
395      case en_stmt_prepared:
396      case en_stmt_cursoropen:
397      case en_stmt_fetched:
398      case en_stmt_xfetched:
399        if (retcode == SQL_STILL_EXECUTING)
400 	 {
401 	   pstmt->asyn_on = en_DescribeCol;
402 	 }
403        break;
404 
405      default:
406        break;
407      }
408 
409   return retcode;
410 }
411 
412 
413 RETCODE SQL_API
SQLColAttributes(HSTMT hstmt,UWORD icol,UWORD fDescType,PTR rgbDesc,SWORD cbDescMax,SWORD FAR * pcbDesc,SDWORD FAR * pfDesc)414 SQLColAttributes (
415     HSTMT hstmt,
416     UWORD icol,
417     UWORD fDescType,
418     PTR rgbDesc,
419     SWORD cbDescMax,
420     SWORD FAR * pcbDesc,
421     SDWORD FAR * pfDesc)
422 {
423   STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
424   HPROC hproc;
425   RETCODE retcode;
426   int sqlstat = en_00000;
427 
428   if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
429     {
430       return SQL_INVALID_HANDLE;
431     }
432 
433   /* check arguments */
434   if (icol == 0 && fDescType != SQL_COLUMN_COUNT)
435     {
436       sqlstat = en_S1002;
437     }
438   else if (cbDescMax < 0)
439     {
440       sqlstat = en_S1090;
441     }
442   else if (			/* fDescType < SQL_COLATT_OPT_MIN || *//* turnoff warning */
443 	(fDescType > SQL_COLATT_OPT_MAX
444 	  && fDescType < SQL_COLUMN_DRIVER_START))
445     {
446       sqlstat = en_S1091;
447     }
448 
449   if (sqlstat != en_00000)
450     {
451       PUSHSQLERR (pstmt->herr, sqlstat);
452 
453       return SQL_ERROR;
454     }
455 
456   /* check state */
457   if (pstmt->asyn_on == en_NullProc)
458     {
459       if (pstmt->asyn_on == en_stmt_allocated
460 	  || pstmt->asyn_on >= en_stmt_needdata)
461 	{
462 	  sqlstat = en_S1010;
463 	}
464     }
465   else if (pstmt->asyn_on != en_ColAttributes)
466     {
467       sqlstat = en_S1010;
468     }
469 
470   if (sqlstat != en_00000)
471     {
472       PUSHSQLERR (pstmt->herr, sqlstat);
473 
474       return SQL_ERROR;
475     }
476 
477   /* call driver */
478   hproc = _iodbcdm_getproc (pstmt->hdbc, en_ColAttributes);
479 
480   if (hproc == SQL_NULL_HPROC)
481     {
482       PUSHSQLERR (pstmt->herr, en_IM001);
483 
484       return SQL_ERROR;
485     }
486 
487   CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_ColAttributes,
488     (pstmt->dhstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc))
489 
490   /* state transition */
491   if (pstmt->asyn_on == en_ColAttributes)
492     {
493       switch (retcode)
494 	 {
495 	 case SQL_SUCCESS:
496 	 case SQL_SUCCESS_WITH_INFO:
497 	 case SQL_ERROR:
498 	   pstmt->asyn_on = en_NullProc;
499 	   break;
500 
501 	 default:
502 	   return retcode;
503 	 }
504     }
505 
506   switch (pstmt->state)
507      {
508      case en_stmt_prepared:
509      case en_stmt_cursoropen:
510      case en_stmt_fetched:
511      case en_stmt_xfetched:
512        if (retcode == SQL_STILL_EXECUTING)
513 	 {
514 	   pstmt->asyn_on = en_ColAttributes;
515 	 }
516        break;
517 
518      default:
519        break;
520      }
521 
522   return retcode;
523 }
524