]> granicus.if.org Git - postgresql/blob - src/interfaces/odbc/options.c
Version 06-30-0248
[postgresql] / src / interfaces / odbc / options.c
1
2 /* Module:          options.c
3  *
4  * Description:     This module contains routines for getting/setting
5  *                  connection and statement options.
6  *
7  * Classes:         n/a
8  *
9  * API functions:   SQLSetConnectOption, SQLSetStmtOption, SQLGetConnectOption,
10  *                  SQLGetStmtOption
11  *
12  * Comments:        See "notice.txt" for copyright and license information.
13  *
14  */
15
16 #ifdef HAVE_CONFIG_H
17 #include <config.h>
18 #endif
19
20 #include "psqlodbc.h"
21
22 #ifdef HAVE_IODBC
23 #include "iodbc.h"
24 #include "isql.h"
25 #include "isqlext.h"
26 #else
27 #include <windows.h>
28 #include <sql.h>
29 #include <sqlext.h>
30 #endif
31
32 #include "environ.h"
33 #include "connection.h"
34 #include "statement.h"
35
36
37 extern GLOBAL_VALUES globals;
38
39
40 /* Implements only SQL_AUTOCOMMIT */
41 RETCODE SQL_API SQLSetConnectOption(
42         HDBC    hdbc,
43         UWORD   fOption,
44         UDWORD  vParam)
45 {
46 char *func="SQLSetConnectOption";
47 ConnectionClass *conn = (ConnectionClass *) hdbc;
48
49         if ( ! conn)  {
50                 CC_log_error(func, "", NULL);
51                 return SQL_INVALID_HANDLE;
52         }
53
54
55         switch (fOption) {
56         case SQL_AUTOCOMMIT:
57
58                 /*  Since we are almost always in a transaction, this is now ok.
59                         Even if we were, the logic will handle it by sending a commit
60                         after the statement.
61                 
62                 if (CC_is_in_trans(conn)) {
63                         conn->errormsg = "Cannot switch commit mode while a transaction is in progres";
64                         conn->errornumber = CONN_TRANSACT_IN_PROGRES;
65                         CC_log_error(func, "", conn);
66                         return SQL_ERROR;
67                 }
68                 */
69
70                 mylog("SQLSetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam);
71
72                 switch(vParam) {
73                 case SQL_AUTOCOMMIT_OFF:
74                         CC_set_autocommit_off(conn);
75                         break;
76
77                 case SQL_AUTOCOMMIT_ON:
78                         CC_set_autocommit_on(conn);
79                         break;
80
81                 default:
82                         conn->errormsg = "Illegal parameter value for SQL_AUTOCOMMIT";
83                         conn->errornumber = CONN_INVALID_ARGUMENT_NO;
84                         CC_log_error(func, "", conn);
85                         return SQL_ERROR;
86                 }
87
88                 break;
89
90         case SQL_LOGIN_TIMEOUT:
91                 break;
92
93         case SQL_ACCESS_MODE:
94                 break;
95
96         case SQL_TXN_ISOLATION:
97                 break;
98
99         default:
100                 { 
101                 char option[64];
102                 conn->errormsg = "Driver does not support setting this connect option";
103                 conn->errornumber = CONN_UNSUPPORTED_OPTION;
104                 sprintf(option, "fOption=%d, vParam=%d", fOption, vParam);
105                 CC_log_error(func, option, conn);
106                 return SQL_ERROR;
107                 }
108
109         }    
110         return SQL_SUCCESS;
111 }
112
113 //      -       -       -       -       -       -       -       -       -
114
115 /* This function just can tell you whether you are in Autcommit mode or not */
116 RETCODE SQL_API SQLGetConnectOption(
117         HDBC    hdbc,
118         UWORD   fOption,
119         PTR     pvParam)
120 {
121 char *func="SQLGetConnectOption";
122 ConnectionClass *conn = (ConnectionClass *) hdbc;
123
124         if (! conn)  {
125                 CC_log_error(func, "", NULL);
126                 return SQL_INVALID_HANDLE;
127         }
128
129         switch (fOption) {
130         case SQL_AUTOCOMMIT:
131                 *((UDWORD *)pvParam) = (UDWORD)( CC_is_in_autocommit(conn) ?
132                                                 SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
133                 break;
134
135         /* don't use qualifiers */
136         case SQL_CURRENT_QUALIFIER:
137                 if(pvParam)
138                         strcpy(pvParam, "");
139
140                 break;
141
142         default:
143                 {
144                 char option[64];
145                 conn->errormsg = "Driver does not support getting this connect option";
146                 conn->errornumber = CONN_UNSUPPORTED_OPTION;
147                 sprintf(option, "fOption=%d", fOption);
148                 CC_log_error(func, option, conn);
149                 return SQL_ERROR;
150                 break;
151                 }
152
153         }    
154
155         return SQL_SUCCESS;
156 }
157
158 //      -       -       -       -       -       -       -       -       -
159
160 RETCODE SQL_API SQLSetStmtOption(
161         HSTMT   hstmt,
162         UWORD   fOption,
163         UDWORD  vParam)
164 {
165 char *func="SQLSetStmtOption";
166 StatementClass *stmt = (StatementClass *) hstmt;
167 char changed = FALSE;
168
169     // thought we could fake Access out by just returning SQL_SUCCESS
170     // all the time, but it tries to set a huge value for SQL_MAX_LENGTH
171     // and expects the driver to reduce it to the real value
172
173         if( ! stmt) {
174                 SC_log_error(func, "", NULL);
175                 return SQL_INVALID_HANDLE;
176         }
177
178         switch(fOption) {
179         case SQL_QUERY_TIMEOUT:
180                 mylog("SetStmtOption: vParam = %d\n", vParam);
181                 //      "0" returned in SQLGetStmtOption
182                 break;
183
184         case SQL_MAX_LENGTH:
185                 //      "4096" returned in SQLGetStmtOption
186                 break;
187
188         case SQL_MAX_ROWS:
189                 mylog("SetStmtOption(): SQL_MAX_ROWS = %d, returning success\n", vParam);
190                 stmt->maxRows = vParam;
191                 return SQL_SUCCESS;
192                 break;
193
194         case SQL_ROWSET_SIZE:
195                 mylog("SetStmtOption(): SQL_ROWSET_SIZE = %d\n", vParam);
196
197                 stmt->rowset_size = 1;          // only support 1 row at a time
198                 if (vParam != 1) 
199                         changed = TRUE;
200
201                 break;
202
203         case SQL_KEYSET_SIZE:
204                 mylog("SetStmtOption(): SQL_KEYSET_SIZE = %d\n", vParam);
205                 if (globals.lie)
206                         stmt->keyset_size = vParam;
207                 else {
208                         stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
209                         stmt->errormsg = "Driver does not support keyset size option";
210                         SC_log_error(func, "", stmt);
211                         return SQL_ERROR;
212                 }
213                 break;
214
215         case SQL_CONCURRENCY:
216                 //      positioned update isn't supported so cursor concurrency is read-only
217                 mylog("SetStmtOption(): SQL_CONCURRENCY = %d\n", vParam);
218
219                 if (globals.lie)
220                         stmt->scroll_concurrency = vParam;
221                 else {
222                         stmt->scroll_concurrency = SQL_CONCUR_READ_ONLY;
223                         if (vParam != SQL_CONCUR_READ_ONLY)
224                                 changed = TRUE;
225                 }
226                 break;
227                 
228         case SQL_CURSOR_TYPE:
229                 //      if declare/fetch, then type can only be forward.
230                 //      otherwise, it can only be forward or static.
231                 mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d\n", vParam);
232
233                 if (globals.lie)
234                         stmt->cursor_type = vParam;
235                 else {
236                         if (globals.use_declarefetch) {
237                                 stmt->cursor_type = SQL_CURSOR_FORWARD_ONLY;
238                                 if (vParam != SQL_CURSOR_FORWARD_ONLY) 
239                                         changed = TRUE;
240                         }
241                         else {
242                                 if (vParam == SQL_CURSOR_FORWARD_ONLY || vParam == SQL_CURSOR_STATIC)
243                                         stmt->cursor_type = vParam;             // valid type
244                                 else {
245                                         stmt->cursor_type = SQL_CURSOR_STATIC;
246                                         changed = TRUE;
247                                 }
248                         }
249                 }
250                 break;
251
252         case SQL_SIMULATE_CURSOR:
253                 stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
254                 stmt->errormsg = "Simulated positioned update/delete not supported.  Use the cursor library.";
255                 SC_log_error(func, "", stmt);
256                 return SQL_ERROR;
257
258     default:
259                 {
260                 char option[64];
261                 stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
262                 stmt->errormsg = "Driver does not support setting this statement option";
263                 sprintf(option, "fOption=%d, vParam=%d", fOption, vParam);
264                 SC_log_error(func, option, stmt);
265         return SQL_ERROR;
266                 }
267     }
268
269         if (changed) {
270                 stmt->errormsg = "Requested value changed.";
271                 stmt->errornumber = STMT_OPTION_VALUE_CHANGED;
272                 return SQL_SUCCESS_WITH_INFO;
273         }
274         else
275                 return SQL_SUCCESS;
276 }
277
278
279 //      -       -       -       -       -       -       -       -       -
280
281 RETCODE SQL_API SQLGetStmtOption(
282         HSTMT   hstmt,
283         UWORD   fOption,
284         PTR     pvParam)
285 {
286 char *func="SQLGetStmtOption";
287 StatementClass *stmt = (StatementClass *) hstmt;
288
289     // thought we could fake Access out by just returning SQL_SUCCESS
290     // all the time, but it tries to set a huge value for SQL_MAX_LENGTH
291     // and expects the driver to reduce it to the real value
292
293         if( ! stmt) {
294                 SC_log_error(func, "", NULL);
295                 return SQL_INVALID_HANDLE;
296         }
297
298         switch(fOption) {
299         case SQL_QUERY_TIMEOUT:
300                 // how long we wait on a query before returning to the
301                 // application (0 == forever)
302                 *((SDWORD *)pvParam) = 0;
303                 break;
304
305         case SQL_MAX_LENGTH:
306                 // what is the maximum length that will be returned in
307                 // a single column
308                 *((SDWORD *)pvParam) = 4096;
309                 break;
310
311         case SQL_MAX_ROWS:
312                 *((SDWORD *)pvParam) = stmt->maxRows;
313                 mylog("GetSmtOption: MAX_ROWS, returning %d\n", stmt->maxRows);
314                 break;
315
316         case SQL_ROWSET_SIZE:
317                 mylog("GetStmtOption(): SQL_ROWSET_SIZE\n");
318                 *((SDWORD *)pvParam) = stmt->rowset_size;
319                 break;
320
321         case SQL_KEYSET_SIZE:
322                 mylog("GetStmtOption(): SQL_KEYSET_SIZE\n");
323                 *((SDWORD *)pvParam) = stmt->keyset_size;
324                 break;
325
326         case SQL_CONCURRENCY:
327                 mylog("GetStmtOption(): SQL_CONCURRENCY\n");
328                 *((SDWORD *)pvParam) = stmt->scroll_concurrency;
329                 break;
330
331         case SQL_CURSOR_TYPE:
332                 mylog("GetStmtOption(): SQL_CURSOR_TYPE\n");
333                 *((SDWORD *)pvParam) = stmt->cursor_type;
334                 break;
335
336         case SQL_SIMULATE_CURSOR:
337                 stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
338                 stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
339                 SC_log_error(func, "", stmt);
340                 return SQL_ERROR;
341
342         default:
343                 {
344                 char option[64];
345                 stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
346                 stmt->errormsg = "Driver does not support getting this statement option";
347                 sprintf(option, "fOption=%d", fOption);
348                 SC_log_error(func, option, stmt);
349                 return SQL_ERROR;
350                 }
351         }
352
353         return SQL_SUCCESS;
354 }
355
356 //      -       -       -       -       -       -       -       -       -