]> granicus.if.org Git - postgresql/blob - src/interfaces/odbc/odbcapi30.c
e657595c031038806de17eebbdaf8c4946beb369
[postgresql] / src / interfaces / odbc / odbcapi30.c
1 /*-------
2  * Module:                      odbcapi30.c
3  *
4  * Description:         This module contains routines related to ODBC 3.0
5  *                      most of their implementations are temporary
6  *                      and must be rewritten properly.
7  *                      2001/07/23      inoue
8  *
9  * Classes:                     n/a
10  *
11  * API functions:       SQLAllocHandle, SQLBindParam, SQLCloseCursor,
12                         SQLColAttribute, SQLCopyDesc, SQLEndTran,
13                         SQLFetchScroll, SQLFreeHandle, SQLGetDescField,
14                         SQLGetDescRec, SQLGetDiagField, SQLGetDiagRec,
15                         SQLGetEnvAttr, SQLGetConnectAttr, SQLGetStmtAttr,
16                         SQLSetConnectAttr, SQLSetDescField, SQLSetDescRec,
17                         SQLSetEnvAttr, SQLSetStmtAttr, SQLBulkOperations
18  *-------
19  */
20
21 #include "psqlodbc.h"
22 #undef ODBCVER
23 #define ODBCVER 0x0300
24 #include <stdio.h>
25 #include <string.h>
26
27 #ifndef WIN32
28 #include "iodbc.h"
29 #include "isqlext.h"
30 #else
31 #include <windows.h>
32 #include <sqlext.h>
33 #endif
34 #include "environ.h"
35 #include "connection.h"
36 #include "statement.h"
37 #include "pgapifunc.h"
38
39 /*      SQLAllocConnect/SQLAllocEnv/SQLAllocStmt -> SQLAllocHandle */
40 RETCODE  SQL_API SQLAllocHandle(SQLSMALLINT HandleType,
41            SQLHANDLE InputHandle, SQLHANDLE *OutputHandle)
42 {
43         mylog("[[SQLAllocHandle]]");
44         switch (HandleType)
45         {
46                 case SQL_HANDLE_ENV:
47                         return PGAPI_AllocEnv(OutputHandle);
48                 case SQL_HANDLE_DBC:
49                         return PGAPI_AllocConnect(InputHandle, OutputHandle);
50                 case SQL_HANDLE_STMT:
51                         return PGAPI_AllocStmt(InputHandle, OutputHandle);
52                 default: break;
53         }
54         return SQL_ERROR;
55 }
56 /*      SQLBindParameter/SQLSetParam -> SQLBindParam */
57 RETCODE  SQL_API SQLBindParam(HSTMT StatementHandle,
58            SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
59            SQLSMALLINT ParameterType, SQLUINTEGER LengthPrecision,
60            SQLSMALLINT ParameterScale, PTR ParameterValue,
61            SQLINTEGER *StrLen_or_Ind)
62 {
63         int     BufferLength = 512; /* Is it OK ? */
64         mylog("[[SQLBindParam]]");
65         return PGAPI_BindParameter(StatementHandle, ParameterNumber, SQL_PARAM_INPUT, ValueType, ParameterType, LengthPrecision, ParameterScale, ParameterValue, BufferLength, StrLen_or_Ind);
66 }
67 /*      New function */
68 RETCODE  SQL_API SQLCloseCursor(HSTMT StatementHandle)
69 {
70         mylog("[[SQLCloseCursor]]");
71         return PGAPI_FreeStmt(StatementHandle, SQL_CLOSE);
72 }
73
74 /*      SQLColAttributes -> SQLColAttribute */
75 RETCODE  SQL_API SQLColAttribute (HSTMT StatementHandle,
76            SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier,
77            PTR CharacterAttribute, SQLSMALLINT BufferLength,
78            SQLSMALLINT *StringLength, PTR NumericAttribute)
79 {
80         mylog("[[SQLColAttribute]]");
81         return PGAPI_ColAttributes(StatementHandle, ColumnNumber,
82                 FieldIdentifier, CharacterAttribute, BufferLength,
83                 StringLength, NumericAttribute);
84 }
85 /*      new function */
86 RETCODE  SQL_API SQLCopyDesc(SQLHDESC SourceDescHandle,
87            SQLHDESC TargetDescHandle)
88 {
89         mylog("[[SQLCopyDesc]]\n");
90         return SQL_ERROR;
91 }
92 /*      SQLTransact -> SQLEndTran */    
93 RETCODE  SQL_API SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle,
94            SQLSMALLINT CompletionType)
95 {
96         mylog("[[SQLEndTran]]");
97         switch (HandleType)
98         {
99                 case SQL_HANDLE_ENV:
100                         return PGAPI_Transact(Handle, SQL_NULL_HDBC, CompletionType);
101                  case SQL_HANDLE_DBC:
102                         return PGAPI_Transact(SQL_NULL_HENV, Handle, CompletionType);
103                 default:break;
104         }
105         return SQL_ERROR; /* SQLSTATE HY092 ("Invalid attribute/option identifier")*/
106
107 }
108 /*      SQLExtendedFetch -> SQLFetchScroll */
109 RETCODE  SQL_API SQLFetchScroll(HSTMT StatementHandle,
110            SQLSMALLINT FetchOrientation, SQLINTEGER FetchOffset)
111 {
112         static char *func = "SQLFetchScroll";
113         StatementClass  *stmt = (StatementClass *) StatementHandle;
114         RETCODE ret;
115         SQLUSMALLINT    *rowStatusArray = stmt->options.rowStatusArray;
116         SQLINTEGER      *pcRow = stmt->options.rowsFetched;
117         mylog("[[%s]] %d,%d\n", func, FetchOrientation, FetchOffset);
118         if (FetchOrientation == SQL_FETCH_BOOKMARK)
119         {
120                 if (stmt->options.bookmark_ptr)
121                         FetchOffset += *((Int4 *) stmt->options.bookmark_ptr);
122                 else
123                 {
124                         stmt->errornumber = STMT_SEQUENCE_ERROR;
125                         stmt->errormsg = "Bookmark isn't specifed yet";
126                         SC_log_error(func, "", stmt);
127                         return SQL_ERROR;
128                 }
129         }
130         ret = PGAPI_ExtendedFetch(StatementHandle, FetchOrientation, FetchOffset,
131                         pcRow, rowStatusArray);
132         if (ret != SQL_SUCCESS)
133                 mylog("%s return = %d\n", func, ret);
134         return ret;
135 }
136 /*      SQLFree(Connect/Env/Stmt) -> SQLFreeHandle */
137 RETCODE  SQL_API SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
138 {
139         mylog("[[SQLFreeHandle]]");
140         switch (HandleType)
141         {
142                 case SQL_HANDLE_ENV:
143                         return PGAPI_FreeEnv(Handle);
144                 case SQL_HANDLE_DBC:
145                         return PGAPI_FreeConnect(Handle);
146                 case SQL_HANDLE_STMT:
147                         return PGAPI_FreeStmt(Handle, SQL_DROP);
148                 default: break;
149         }
150         return SQL_ERROR;
151 }
152 /*      new function */
153 RETCODE  SQL_API SQLGetDescField(SQLHDESC DescriptorHandle,
154            SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
155            PTR Value, SQLINTEGER BufferLength,
156            SQLINTEGER *StringLength)
157 {
158         mylog("[[SQLGetDescField]]\n");
159         return SQL_ERROR;
160 }
161 /*      new function */
162 RETCODE  SQL_API SQLGetDescRec(SQLHDESC DescriptorHandle,
163            SQLSMALLINT RecNumber, SQLCHAR *Name,
164            SQLSMALLINT BufferLength, SQLSMALLINT *StringLength,
165            SQLSMALLINT *Type, SQLSMALLINT *SubType, 
166            SQLINTEGER *Length, SQLSMALLINT *Precision, 
167            SQLSMALLINT *Scale, SQLSMALLINT *Nullable)
168 {
169         mylog("[[SQLGetDescRec]]\n");
170         return SQL_ERROR;
171 }
172 /*      new function */
173 RETCODE  SQL_API SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
174            SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
175            PTR DiagInfo, SQLSMALLINT BufferLength,
176            SQLSMALLINT *StringLength)
177 {
178         mylog("[[SQLGetDiagField]]\n");
179         return SQL_ERROR;
180 }
181 /*      SQLError -> SQLDiagRec */
182 RETCODE  SQL_API SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
183            SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
184            SQLINTEGER *NativeError, SQLCHAR *MessageText,
185            SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
186 {
187         RETCODE ret;
188         mylog("[[SQLGetDiagRec]]\n");
189         switch (HandleType)
190         {
191                 case SQL_HANDLE_ENV:
192                         ret = PGAPI_Error(Handle, NULL, NULL, Sqlstate, NativeError,
193                                 MessageText, BufferLength, TextLength);
194                         break;
195                 case SQL_HANDLE_DBC:
196                         ret = PGAPI_Error(NULL, Handle,  NULL, Sqlstate, NativeError,
197                                 MessageText, BufferLength, TextLength);
198                         break;
199                 case SQL_HANDLE_STMT:
200                         ret = PGAPI_Error(NULL, NULL, Handle, Sqlstate, NativeError,
201                                 MessageText, BufferLength, TextLength);
202                         break;
203                 default:
204                         ret = SQL_ERROR;
205         }
206         if (ret == SQL_SUCCESS_WITH_INFO &&
207             BufferLength == 0 &&
208             *TextLength)
209         {
210                 SQLSMALLINT     BufferLength = *TextLength + 4;
211                 SQLCHAR *MessageText = malloc(BufferLength);
212                 ret = SQLGetDiagRec(HandleType, Handle, RecNumber, Sqlstate,
213                                 NativeError, MessageText, BufferLength,
214                                 TextLength);
215                 free(MessageText);
216         }
217         return ret;
218 }
219 /*      new function */
220 RETCODE  SQL_API SQLGetEnvAttr(HENV EnvironmentHandle,
221            SQLINTEGER Attribute, PTR Value,
222            SQLINTEGER BufferLength, SQLINTEGER *StringLength)
223 {
224         EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle;
225         mylog("[[SQLGetEnvAttr]] %d\n", Attribute);
226         switch (Attribute)
227         {
228                 case SQL_ATTR_CONNECTION_POOLING:
229                         *((unsigned int *) Value) = SQL_CP_OFF;
230                         break;
231                 case SQL_ATTR_CP_MATCH:
232                         *((unsigned int *) Value) = SQL_CP_RELAXED_MATCH;
233                         break;
234                 case SQL_ATTR_ODBC_VERSION:
235                         *((unsigned int *) Value) = SQL_OV_ODBC3;
236                         break;
237                 case SQL_ATTR_OUTPUT_NTS:
238                         *((unsigned int *) Value) = SQL_TRUE;
239                         break;
240                 default:
241                         env->errornumber = CONN_INVALID_ARGUMENT_NO;
242                         return SQL_ERROR;
243         }
244         return SQL_SUCCESS;
245 }
246 /*      SQLGetConnectOption -> SQLGetconnectAttr */
247 RETCODE  SQL_API SQLGetConnectAttr(HDBC ConnectionHandle,
248            SQLINTEGER Attribute, PTR Value,
249            SQLINTEGER BufferLength, SQLINTEGER *StringLength)
250 {
251         ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
252         mylog("[[SQLGetConnectAttr]] %d\n", Attribute);
253         switch (Attribute)
254         {
255                 case SQL_ATTR_ASYNC_ENABLE:
256                 case SQL_ATTR_AUTO_IPD:
257                 case SQL_ATTR_CONNECTION_DEAD:
258                 case SQL_ATTR_CONNECTION_TIMEOUT:
259                 case SQL_ATTR_METADATA_ID:
260                         conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
261                         conn->errormsg = "Unsupported connection option (Set)";
262                         return SQL_ERROR;
263         }
264         return PGAPI_GetConnectOption (ConnectionHandle, (UWORD) Attribute, Value);
265 }
266 /*      SQLGetStmtOption -> SQLGetStmtAttr */
267 RETCODE  SQL_API SQLGetStmtAttr(HSTMT StatementHandle,
268            SQLINTEGER Attribute, PTR Value,
269            SQLINTEGER BufferLength, SQLINTEGER *StringLength)
270 {
271         static char *func = "SQLGetStmtAttr";
272         StatementClass  *stmt = (StatementClass *) StatementHandle;
273         RETCODE ret = SQL_SUCCESS;
274         int     len = 0;
275         mylog("[[%s]] %d\n", func, Attribute);
276         switch (Attribute)
277         {
278                 case SQL_ATTR_FETCH_BOOKMARK_PTR:       /* 16 */
279                         Value = stmt->options.bookmark_ptr;
280                         len = 4;
281                         break;  
282                 case SQL_ATTR_ROW_STATUS_PTR:   /* 25 */
283                         Value = stmt->options.rowStatusArray;
284                         len = 4;
285                         break;
286                 case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
287                         Value = stmt->options.rowsFetched;
288                         len = 4;
289                         break;
290                 case SQL_ATTR_ROW_ARRAY_SIZE:   /* 27 */
291                         *((SQLUINTEGER *) Value) = stmt->options.rowset_size;
292                         len = 4;
293                         break; 
294                 case SQL_ATTR_APP_ROW_DESC:     /* 10010 */
295                         *((HSTMT *) Value) = StatementHandle; /* this is useless */
296                         len = 4;
297                         break;  
298                 case SQL_ATTR_APP_PARAM_DESC:   /* 10011 */
299                         *((HSTMT *) Value) = StatementHandle; /* this is useless */
300                         len = 4;
301                         break;  
302                 case SQL_ATTR_IMP_ROW_DESC:     /* 10012 */
303                         *((HSTMT *) Value) = StatementHandle; /* this is useless */
304                         len = 4;
305                         break;  
306                 case SQL_ATTR_IMP_PARAM_DESC:   /* 10013 */
307                         *((HSTMT *) Value) = StatementHandle; /* this is useless */
308                         len = 4;
309                         break;  
310                 case SQL_ATTR_AUTO_IPD:         /* 10001 */
311                 case SQL_ATTR_ROW_BIND_TYPE:    /* == SQL_BIND_TYPE */
312                 case SQL_ATTR_PARAMSET_SIZE:    /* 22 */
313                 case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
314                 case SQL_ATTR_PARAMS_PROCESSED_PTR:     /* 21 */
315
316                 case SQL_ATTR_CURSOR_SCROLLABLE:        /* -1 */
317                 case SQL_ATTR_CURSOR_SENSITIVITY:       /* -2 */
318
319                 case SQL_ATTR_ENABLE_AUTO_IPD:  /* 15 */
320                 case SQL_ATTR_METADATA_ID:      /* 10014 */
321                 /* case SQL_ATTR_PREDICATE_PTR:
322                 case SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR: */
323                 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:    /* 17 */
324                 case SQL_ATTR_PARAM_BIND_TYPE:          /* 18 */
325                 case SQL_ATTR_PARAM_OPERATION_PTR:      /* 19 */
326                 case SQL_ATTR_ROW_BIND_OFFSET_PTR:      /* 23 */
327                 case SQL_ATTR_ROW_OPERATION_PTR:        /* 24 */
328                         stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
329                         stmt->errormsg = "Unsupported statement option (Get)";
330                         SC_log_error(func, "", stmt);
331                         return SQL_ERROR;
332                 default:
333                         len = 4;
334                         ret = PGAPI_GetStmtOption(StatementHandle, (UWORD) Attribute, Value);
335         }
336         if (ret == SQL_SUCCESS && StringLength)
337                 *StringLength = len;
338         return ret;
339 }
340
341 /*      SQLSetConnectOption -> SQLSetConnectAttr */
342 RETCODE  SQL_API SQLSetConnectAttr(HDBC ConnectionHandle,
343            SQLINTEGER Attribute, PTR Value,
344            SQLINTEGER StringLength)
345 {
346         ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
347
348         mylog("[[SQLSetConnectAttr]] %d\n", Attribute);
349         switch (Attribute)
350         {
351                 case SQL_ATTR_ASYNC_ENABLE:
352                 case SQL_ATTR_AUTO_IPD:
353                 case SQL_ATTR_CONNECTION_DEAD:
354                 case SQL_ATTR_CONNECTION_TIMEOUT:
355                 case SQL_ATTR_METADATA_ID:
356                         conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
357                         conn->errormsg = "Unsupported connection option (Set)";
358                         return SQL_ERROR;
359         }
360         return PGAPI_SetConnectOption(ConnectionHandle, (UWORD) Attribute, (UDWORD) Value);
361 }
362 /*      new function */
363 RETCODE  SQL_API SQLSetDescField(SQLHDESC DescriptorHandle,
364            SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
365            PTR Value, SQLINTEGER BufferLength)
366 {
367         mylog("[[SQLSetDescField]]\n");
368         return SQL_ERROR;
369 }
370 /*      new fucntion */
371 RETCODE  SQL_API SQLSetDescRec(SQLHDESC DescriptorHandle,
372            SQLSMALLINT RecNumber, SQLSMALLINT Type,
373            SQLSMALLINT SubType, SQLINTEGER Length,
374            SQLSMALLINT Precision, SQLSMALLINT Scale,
375            PTR Data, SQLINTEGER *StringLength,
376            SQLINTEGER *Indicator)
377 {
378         mylog("[[SQLsetDescRec]]\n");
379         return SQL_ERROR;
380 }
381 /*      new function */
382 RETCODE  SQL_API SQLSetEnvAttr(HENV EnvironmentHandle,
383            SQLINTEGER Attribute, PTR Value,
384            SQLINTEGER StringLength)
385 {
386         EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle;
387         mylog("[[SQLSetEnvAttr]] att=%d,%u\n", Attribute, Value);
388         switch (Attribute)
389         {
390                 case SQL_ATTR_CONNECTION_POOLING:
391                         if ((SQLUINTEGER) Value == SQL_CP_OFF)
392                                 return SQL_SUCCESS;
393                         break;
394                 case SQL_ATTR_CP_MATCH:
395                         /* *((unsigned int *) Value) = SQL_CP_RELAXED_MATCH; */
396                         return SQL_SUCCESS;
397                 case SQL_ATTR_ODBC_VERSION:
398                         if ((SQLUINTEGER) Value == SQL_OV_ODBC2)
399                                 return SQL_SUCCESS;
400                         break;
401                 case SQL_ATTR_OUTPUT_NTS:
402                         if ((SQLUINTEGER) Value == SQL_TRUE)
403                                 return SQL_SUCCESS;
404                         break;
405                 default:
406                         env->errornumber = CONN_INVALID_ARGUMENT_NO;
407                         return SQL_ERROR;
408         }
409         env->errornumber = CONN_OPTION_VALUE_CHANGED;
410         env->errormsg = "SetEnv changed to ";
411         return SQL_SUCCESS_WITH_INFO;
412 }
413 /*      SQLSet(Param/Scroll/Stmt)Option -> SQLSetStmtAttr */
414 RETCODE  SQL_API SQLSetStmtAttr(HSTMT StatementHandle,
415            SQLINTEGER Attribute, PTR Value,
416            SQLINTEGER StringLength)
417 {
418         static char *func = "SQLSetStmtAttr";
419         StatementClass  *stmt = (StatementClass *) StatementHandle;
420         UDWORD  rowcount;
421         mylog("[[%s]] %d,%u\n", func, Attribute, Value);
422         switch (Attribute)
423         {
424                 case SQL_ATTR_PARAMSET_SIZE:    /* 22 */
425                         return PGAPI_ParamOptions(StatementHandle, (UWORD) Value, &rowcount);
426                 case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
427                 case SQL_ATTR_PARAMS_PROCESSED_PTR:     /* 21 */
428
429                 case SQL_ATTR_CURSOR_SCROLLABLE:        /* -1 */
430                 case SQL_ATTR_CURSOR_SENSITIVITY:       /* -2 */
431
432                 case SQL_ATTR_ENABLE_AUTO_IPD:  /* 15 */
433
434                 case SQL_ATTR_APP_ROW_DESC:     /* 10010 */
435                 case SQL_ATTR_APP_PARAM_DESC:   /* 10011 */
436                 case SQL_ATTR_AUTO_IPD:         /* 10001 */
437                 /*case SQL_ATTR_ROW_BIND_TYPE:*/        /* == SQL_BIND_TYPE */
438                 case SQL_ATTR_IMP_ROW_DESC:     /* 10012 */
439                 case SQL_ATTR_IMP_PARAM_DESC:   /* 10013 */
440                 case SQL_ATTR_METADATA_ID:      /* 10014 */
441                 /* case SQL_ATTR_PREDICATE_PTR:
442                 case SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR: */
443                 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:    /* 17 */
444                 case SQL_ATTR_PARAM_BIND_TYPE:          /* 18 */
445                 case SQL_ATTR_PARAM_OPERATION_PTR:      /* 19 */
446                 case SQL_ATTR_ROW_BIND_OFFSET_PTR:      /* 23 */
447                 case SQL_ATTR_ROW_OPERATION_PTR:        /* 24 */
448                         stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
449                         stmt->errormsg = "Unsupported statement option (Set)";
450                         SC_log_error(func, "", stmt);
451                         return SQL_ERROR;
452  
453                 case SQL_ATTR_FETCH_BOOKMARK_PTR:       /* 16 */
454                         stmt->options.bookmark_ptr = Value;
455                         break;
456                 case SQL_ATTR_ROW_STATUS_PTR:   /* 25 */
457                         stmt->options.rowStatusArray = (SQLUSMALLINT *) Value;
458                         break;
459                 case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
460                         stmt->options.rowsFetched = (SQLUINTEGER *) Value;
461                         break;
462                 case SQL_ATTR_ROW_ARRAY_SIZE:   /* 27 */ 
463                         stmt->options.rowset_size = (SQLUINTEGER) Value;
464                         break;
465                 default: 
466                         return PGAPI_SetStmtOption(StatementHandle, (UWORD) Attribute, (UDWORD) Value);
467         }
468         return SQL_SUCCESS;
469 }
470
471 #define SQL_FUNC_ESET(pfExists, uwAPI) \
472                 (*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) \
473                         |= (1 << ((uwAPI) & 0x000F)) \
474                                 )
475 RETCODE SQL_API
476 PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR *pfExists)
477 {
478         if (fFunction != SQL_API_ODBC3_ALL_FUNCTIONS)
479                 return SQL_ERROR;
480         memset(pfExists, 0, sizeof(UWORD) * 250);
481
482         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCCONNECT); 1 deprecated */
483         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCENV); 2 deprecated */
484         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCSTMT); 3 deprecated */
485         /* for (i = SQL_API_SQLBINDCOL; i <= 23; i++)
486                 SQL_FUNC_ESET(pfExists, i); */
487         SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDCOL); /* 4 */
488         SQL_FUNC_ESET(pfExists, SQL_API_SQLCANCEL); /* 5 */
489         SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLATTRIBUTE); /* 6 */
490         SQL_FUNC_ESET(pfExists, SQL_API_SQLCONNECT); /* 7 */
491         SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBECOL); /* 8 */
492         SQL_FUNC_ESET(pfExists, SQL_API_SQLDISCONNECT); /* 9 */
493         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLERROR);  10 deprecated */
494         SQL_FUNC_ESET(pfExists, SQL_API_SQLEXECDIRECT); /* 11 */
495         SQL_FUNC_ESET(pfExists, SQL_API_SQLEXECUTE); /* 12 */
496         SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCH); /* 13 */
497         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLFREECONNECT); 14 deprecated */
498         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLFREEENV); 15 deprecated */
499         SQL_FUNC_ESET(pfExists, SQL_API_SQLFREESTMT); /* 16 */
500         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCURSORNAME); /* 17 */
501         SQL_FUNC_ESET(pfExists, SQL_API_SQLNUMRESULTCOLS); /* 18 */
502         SQL_FUNC_ESET(pfExists, SQL_API_SQLPREPARE); /* 19 */
503         SQL_FUNC_ESET(pfExists, SQL_API_SQLROWCOUNT); /* 20 */
504         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCURSORNAME); /* 21 */
505         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPARAM); 22 deprecated */
506         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLTRANSACT); 23 deprecated */
507         /*for (i = 40; i < SQL_API_SQLEXTENDEDFETCH; i++)
508                 SQL_FUNC_ESET(pfExists, i);*/
509         SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNS); /* 40 */
510         SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERCONNECT); /* 41 */
511         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTOPTION); 42 deprecated */
512         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDATA); /* 43 */
513         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETFUNCTIONS); /* 44 */
514         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETINFO); /* 45 */
515         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLGETSTMTOPTION); 46 deprecated */
516         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETTYPEINFO); /* 47 */
517         SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMDATA); /* 48 */
518         SQL_FUNC_ESET(pfExists, SQL_API_SQLPUTDATA); /* 49 */
519         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTIONOPTION); 50 deprecated */
520         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTOPTION); 51 deprecated */
521         SQL_FUNC_ESET(pfExists, SQL_API_SQLSPECIALCOLUMNS); /* 52 */
522         SQL_FUNC_ESET(pfExists, SQL_API_SQLSTATISTICS); /* 53 */
523         SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLES); /* 54 */
524         SQL_FUNC_ESET(pfExists, SQL_API_SQLBROWSECONNECT); /* 55 */
525         SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNPRIVILEGES); /* 56 */
526         SQL_FUNC_ESET(pfExists, SQL_API_SQLDATASOURCES); /* 57 */
527         SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBEPARAM); /* 58 */
528         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLEXTENDEDFETCH); 59 deprecated */
529         /*for (++i; i < SQL_API_SQLBINDPARAMETER; i++)
530                 SQL_FUNC_ESET(pfExists, i);*/
531         SQL_FUNC_ESET(pfExists, SQL_API_SQLFOREIGNKEYS); /* 60 */
532         SQL_FUNC_ESET(pfExists, SQL_API_SQLMORERESULTS); /* 61 */
533         SQL_FUNC_ESET(pfExists, SQL_API_SQLNATIVESQL); /* 62 */
534         SQL_FUNC_ESET(pfExists, SQL_API_SQLNUMPARAMS); /* 63 */
535         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMOPTIONS); 64 deprecated */
536         SQL_FUNC_ESET(pfExists, SQL_API_SQLPRIMARYKEYS); /* 65 */
537         SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURECOLUMNS); /* 66 */
538         SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURES); /* 67 */
539         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPOS); /* 68 */
540         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSCROLLOPTIONS); /* 69 deprecated */
541         SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLEPRIVILEGES); /* 70 */
542         /*SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERS);*/ /* 71 */
543         SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAMETER); /* 72 */
544
545         SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCHANDLE); /* 1001 */
546         SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAM); /* 1002 */
547         SQL_FUNC_ESET(pfExists, SQL_API_SQLCLOSECURSOR); /* 1003 */
548         SQL_FUNC_ESET(pfExists, SQL_API_SQLCOPYDESC);/* 1004 not implemented yet */
549         SQL_FUNC_ESET(pfExists, SQL_API_SQLENDTRAN); /* 1005 */
550         SQL_FUNC_ESET(pfExists, SQL_API_SQLFREEHANDLE); /* 1006 */
551         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTATTR); /* 1007 */
552         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCFIELD);/* 1008 not implemented yet */
553         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCREC);/* 1009 not implemented yet */
554         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGFIELD);/* 1010 not implemented yet */
555         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGREC); /* 1011 */
556         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETENVATTR); /* 1012 */
557         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETSTMTATTR); /* 1014 */
558         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTATTR); /* 1016 */
559         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCFIELD); /* 1017 not implemeted yet */
560         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCREC); /* 1018 not implemented yet */
561         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETENVATTR); /* 1019 */
562         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTATTR); /* 1020 */
563         SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCHSCROLL); /* 1021 */
564         SQL_FUNC_ESET(pfExists, SQL_API_SQLBULKOPERATIONS);/* 24 not implemented yet */
565
566         return SQL_SUCCESS;
567 }
568 RETCODE SQL_API
569 PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
570                 SWORD cbInfoValueMax, SWORD FAR *pcbInfoValue)
571 {
572         static char *func = "PGAPI_GetInfo30";
573         ConnectionClass *conn = (ConnectionClass *) hdbc;
574         char    *p = NULL;
575         int     len = 0, value = 0;
576         RETCODE result;
577
578         switch (fInfoType)
579         {
580                 case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
581                         len = 4;
582                         value = 0;
583                         break;
584                 case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
585                         len = 4;
586                         value = 0;
587                         break;
588
589                 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
590                         len = 4;
591                         value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
592                                 SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK;
593                         break;
594                 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
595                         len = 4;
596                         value = 0;
597                         break;
598                 case SQL_KEYSET_CURSOR_ATTRIBUTES1:
599                         len = 4;
600                         value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE
601                                 | SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK
602                                 | SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION
603                                 | SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE
604                                 | SQL_CA1_POS_REFRESH
605                                 | SQL_CA1_BULK_ADD
606                                 | SQL_CA1_BULK_UPDATE_BY_BOOKMARK
607                                 | SQL_CA1_BULK_DELETE_BY_BOOKMARK
608                                 | SQL_CA1_BULK_FETCH_BY_BOOKMARK
609                                 ;
610                         break;
611                 case SQL_KEYSET_CURSOR_ATTRIBUTES2:
612                         len = 4;
613                         value = SQL_CA2_OPT_ROWVER_CONCURRENCY |
614                                 SQL_CA2_SENSITIVITY_ADDITIONS |
615                                 SQL_CA2_SENSITIVITY_DELETIONS |
616                                 SQL_CA2_SENSITIVITY_UPDATES;
617                         break;
618
619                 case SQL_STATIC_CURSOR_ATTRIBUTES1:
620                         len = 4;
621                         value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
622                                 SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK |
623                                 SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION |
624                                 SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE |
625                                 SQL_CA1_POS_REFRESH;
626                         break;
627                 case SQL_STATIC_CURSOR_ATTRIBUTES2:
628                         len = 4;
629                         value = SQL_CA2_OPT_ROWVER_CONCURRENCY |
630                                 SQL_CA2_SENSITIVITY_ADDITIONS |
631                                 SQL_CA2_SENSITIVITY_DELETIONS |
632                                 SQL_CA2_SENSITIVITY_UPDATES;
633                         break;
634                 default:
635                         /* unrecognized key */
636                         conn->errormsg = "Unrecognized key passed to SQLGetInfo.";
637                         conn->errornumber = CONN_NOT_IMPLEMENTED_ERROR;
638                         CC_log_error(func, "", conn);
639                         return SQL_ERROR;
640         }
641         result = SQL_SUCCESS;
642         if (p)
643         {
644                 /* char/binary data */
645                 len = strlen(p);
646
647                 if (rgbInfoValue)
648                 {
649                         strncpy_null((char *) rgbInfoValue, p, (size_t) cbInfoValueMax);
650
651                         if (len >= cbInfoValueMax)
652                         {
653                                 result = SQL_SUCCESS_WITH_INFO;
654                                 conn->errornumber = STMT_TRUNCATED;
655                                 conn->errormsg = "The buffer was too small for tthe InfoValue.";
656                         }
657                 }
658         }
659         else
660         {
661                 /* numeric data */
662                 if (rgbInfoValue)
663                 {
664                         if (len == 2)
665                                 *((WORD *) rgbInfoValue) = (WORD) value;
666                         else if (len == 4)
667                                 *((DWORD *) rgbInfoValue) = (DWORD) value;
668                 }
669         }
670
671         if (pcbInfoValue)
672                 *pcbInfoValue = len;
673         return result;
674 }