~ubuntu-branches/ubuntu/gutsy/psqlodbc/gutsy

« back to all changes in this revision

Viewing changes to options.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-05-13 10:47:36 UTC
  • Revision ID: james.westby@ubuntu.com-20040513104736-a530gmn0p3knep89
Tags: upstream-07.03.0200
ImportĀ upstreamĀ versionĀ 07.03.0200

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#include "psqlodbc.h"
 
17
#include <string.h>
 
18
 
 
19
#include "environ.h"
 
20
#include "connection.h"
 
21
#include "statement.h"
 
22
#include "qresult.h"
 
23
#include "pgapifunc.h"
 
24
 
 
25
 
 
26
 
 
27
RETCODE set_statement_option(ConnectionClass *conn,
 
28
                                         StatementClass *stmt,
 
29
                                         UWORD fOption,
 
30
                                         UDWORD vParam);
 
31
 
 
32
 
 
33
RETCODE
 
34
set_statement_option(ConnectionClass *conn,
 
35
                                         StatementClass *stmt,
 
36
                                         UWORD fOption,
 
37
                                         UDWORD vParam)
 
38
{
 
39
        CSTR func = "set_statement_option";
 
40
        char            changed = FALSE;
 
41
        ConnInfo   *ci = NULL;
 
42
        UDWORD          setval;
 
43
 
 
44
        if (conn)
 
45
                ci = &(conn->connInfo);
 
46
        else if (stmt)
 
47
                ci = &(SC_get_conn(stmt)->connInfo);
 
48
        switch (fOption)
 
49
        {
 
50
                case SQL_ASYNC_ENABLE:  /* ignored */
 
51
                        break;
 
52
 
 
53
                case SQL_BIND_TYPE:
 
54
                        /* now support multi-column and multi-row binding */
 
55
                        if (conn)
 
56
                                conn->ardOptions.bind_size = vParam;
 
57
                        if (stmt)
 
58
                                SC_get_ARD(stmt)->bind_size = vParam;
 
59
                        break;
 
60
 
 
61
                case SQL_CONCURRENCY:
 
62
 
 
63
                        /*
 
64
                         * positioned update isn't supported so cursor concurrency is
 
65
                         * read-only
 
66
                         */
 
67
                        mylog("SetStmtOption(): SQL_CONCURRENCY = %d ", vParam);
 
68
                        setval = SQL_CONCUR_READ_ONLY;
 
69
                        if (SQL_CONCUR_READ_ONLY == vParam)
 
70
                                ;
 
71
                        else if (ci->drivers.lie)
 
72
                                setval = vParam;
 
73
                        else if (ci->updatable_cursors)
 
74
                                setval = SQL_CONCUR_ROWVER;
 
75
                        if (conn)
 
76
                                conn->stmtOptions.scroll_concurrency = setval;
 
77
                        else if (stmt)
 
78
                        {
 
79
                                if (SC_get_Result(stmt))
 
80
                                {
 
81
                                        SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.");
 
82
                                        SC_log_error(func, "", stmt);
 
83
                                        return SQL_ERROR;
 
84
                                }
 
85
                                stmt->options.scroll_concurrency =
 
86
                                stmt->options_orig.scroll_concurrency = setval;
 
87
                        }
 
88
                        if (setval != vParam)
 
89
                                changed = TRUE;
 
90
                        mylog("-> %d\n", setval);
 
91
                        break;
 
92
 
 
93
                case SQL_CURSOR_TYPE:
 
94
 
 
95
                        /*
 
96
                         * if declare/fetch, then type can only be forward. otherwise,
 
97
                         * it can only be forward or static.
 
98
                         */
 
99
                        mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d ", vParam);
 
100
                        setval = SQL_CURSOR_FORWARD_ONLY;
 
101
                        if (ci->drivers.lie)
 
102
                                setval = vParam;
 
103
#ifdef  DECLAREFETCH_FORWARDONLY
 
104
                        else if (ci->drivers.use_declarefetch)
 
105
                                ;
 
106
#endif /* DECLAREFETCH_FORWARDONLY */
 
107
                        else if (SQL_CURSOR_STATIC == vParam)
 
108
                                setval = vParam;
 
109
                        else if (SQL_CURSOR_KEYSET_DRIVEN == vParam)
 
110
                        {
 
111
                                if (ci->updatable_cursors)
 
112
                                        setval = vParam;
 
113
                                else
 
114
                                        setval = SQL_CURSOR_STATIC; /* at least scrollable */
 
115
                        }
 
116
                        if (conn)
 
117
                                conn->stmtOptions.cursor_type = setval;
 
118
                        else if (stmt)
 
119
                        {
 
120
                                if (SC_get_Result(stmt))
 
121
                                {
 
122
                                        SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.");
 
123
                                        SC_log_error(func, "", stmt);
 
124
                                        return SQL_ERROR;
 
125
                                }
 
126
                                stmt->options_orig.cursor_type =
 
127
                                stmt->options.cursor_type = setval;
 
128
                        }
 
129
                        if (setval != vParam)
 
130
                                changed = TRUE;
 
131
                        mylog("-> %d\n", setval);
 
132
                        break;
 
133
 
 
134
                case SQL_KEYSET_SIZE:   /* ignored, but saved and returned      */
 
135
                        mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n", vParam);
 
136
 
 
137
                        if (conn)
 
138
                                conn->stmtOptions.keyset_size = vParam;
 
139
                        if (stmt)
 
140
                        {
 
141
                                stmt->options_orig.keyset_size = vParam;
 
142
                                if (!SC_get_Result(stmt)) 
 
143
                                        stmt->options.keyset_size = vParam;
 
144
                                if (stmt->options.keyset_size != (int)vParam)
 
145
                                        changed = TRUE;
 
146
                        }
 
147
 
 
148
                        break;
 
149
 
 
150
                        /*-------
 
151
                         *      if (ci->drivers.lie)
 
152
                         *              stmt->keyset_size = vParam;
 
153
                         *      else
 
154
                         *      {
 
155
                         *              stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
 
156
                         *              stmt->errormsg = "Driver does not support keyset size option";
 
157
                         *              SC_log_error(func, "", stmt);
 
158
                         *              return SQL_ERROR;
 
159
                         *      }
 
160
                         *-------
 
161
                         */
 
162
 
 
163
                case SQL_MAX_LENGTH:    /* ignored, but saved */
 
164
                        mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam);
 
165
                        if (conn)
 
166
                                conn->stmtOptions.maxLength = vParam;
 
167
                        if (stmt)
 
168
                        {
 
169
                                stmt->options_orig.maxLength = vParam;
 
170
                                if (!SC_get_Result(stmt)) 
 
171
                                        stmt->options.maxLength = vParam;
 
172
                                if (stmt->options.maxLength != (int)vParam)
 
173
                                        changed = TRUE;
 
174
                        }
 
175
                        break;
 
176
 
 
177
                case SQL_MAX_ROWS:              /* ignored, but saved */
 
178
                        mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam);
 
179
                        if (conn)
 
180
                                conn->stmtOptions.maxRows = vParam;
 
181
                        if (stmt)
 
182
                        {
 
183
                                stmt->options_orig.maxRows = vParam;
 
184
                                if (!SC_get_Result(stmt)) 
 
185
                                        stmt->options.maxRows = vParam;
 
186
                                if (stmt->options.maxRows != (int)vParam)
 
187
                                        changed = TRUE;
 
188
                        }
 
189
                        break;
 
190
 
 
191
                case SQL_NOSCAN:                /* ignored */
 
192
                        mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam);
 
193
                        break;
 
194
 
 
195
                case SQL_QUERY_TIMEOUT: /* ignored */
 
196
                        mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n", vParam);
 
197
                        /* "0" returned in SQLGetStmtOption */
 
198
                        break;
 
199
 
 
200
                case SQL_RETRIEVE_DATA:
 
201
                        mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n", vParam);
 
202
                        if (conn)
 
203
                                conn->stmtOptions.retrieve_data = vParam;
 
204
                        if (stmt)
 
205
                                stmt->options.retrieve_data = vParam;
 
206
                        break;
 
207
 
 
208
                case SQL_ROWSET_SIZE:
 
209
                        mylog("SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d\n", vParam);
 
210
 
 
211
                        /*
 
212
                         * Save old rowset size for SQLExtendedFetch purposes If the
 
213
                         * rowset_size is being changed since the last call to fetch
 
214
                         * rows.
 
215
                         */
 
216
 
 
217
                        if (stmt && stmt->save_rowset_size <= 0 && stmt->last_fetch_count > 0)
 
218
                                stmt->save_rowset_size = SC_get_ARD(stmt)->size_of_rowset_odbc2;
 
219
 
 
220
                        if (vParam < 1)
 
221
                        {
 
222
                                vParam = 1;
 
223
                                changed = TRUE;
 
224
                        }
 
225
 
 
226
                        if (conn)
 
227
                                conn->ardOptions.size_of_rowset_odbc2 = vParam;
 
228
                        if (stmt)
 
229
                                SC_get_ARD(stmt)->size_of_rowset_odbc2 = vParam;
 
230
                        break;
 
231
 
 
232
                case SQL_SIMULATE_CURSOR:               /* NOT SUPPORTED */
 
233
                        if (stmt)
 
234
                        {
 
235
                                SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Simulated positioned update/delete not supported.  Use the cursor library.");
 
236
                                SC_log_error(func, "", stmt);
 
237
                        }
 
238
                        if (conn)
 
239
                        {
 
240
                                CC_set_error(conn, STMT_NOT_IMPLEMENTED_ERROR, "Simulated positioned update/delete not supported.  Use the cursor library.");
 
241
                                CC_log_error(func, "", conn);
 
242
                        }
 
243
                        return SQL_ERROR;
 
244
 
 
245
                case SQL_USE_BOOKMARKS:
 
246
                        if (stmt)
 
247
                                stmt->options.use_bookmarks = vParam;
 
248
                        if (conn)
 
249
                                conn->stmtOptions.use_bookmarks = vParam;
 
250
                        break;
 
251
 
 
252
                case 1227:
 
253
                case 1228:
 
254
                        if (stmt)
 
255
                        {
 
256
                                SC_set_error(stmt, STMT_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)");
 
257
                        }
 
258
                        else if (conn)
 
259
                        {
 
260
                                CC_set_error(conn, STMT_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)");
 
261
                        }
 
262
                        return SQL_ERROR;
 
263
                default:
 
264
                        {
 
265
                                char            option[64];
 
266
 
 
267
                                if (stmt)
 
268
                                {
 
269
                                        SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Set)");
 
270
                                        sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
 
271
                                        SC_log_error(func, option, stmt);
 
272
                                }
 
273
                                if (conn)
 
274
                                {
 
275
                                        CC_set_error(conn, STMT_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Set)");
 
276
                                        sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
 
277
                                        CC_log_error(func, option, conn);
 
278
                                }
 
279
 
 
280
                                return SQL_ERROR;
 
281
                        }
 
282
        }
 
283
 
 
284
        if (changed)
 
285
        {
 
286
                if (stmt)
 
287
                {
 
288
                        SC_set_error(stmt, STMT_OPTION_VALUE_CHANGED, "Requested value changed.");
 
289
                }
 
290
                if (conn)
 
291
                {
 
292
                        CC_set_error(conn, STMT_OPTION_VALUE_CHANGED, "Requested value changed.");
 
293
                }
 
294
                return SQL_SUCCESS_WITH_INFO;
 
295
        }
 
296
        else
 
297
                return SQL_SUCCESS;
 
298
}
 
299
 
 
300
 
 
301
/* Implements only SQL_AUTOCOMMIT */
 
302
RETCODE         SQL_API
 
303
PGAPI_SetConnectOption(
 
304
                                           HDBC hdbc,
 
305
                                           UWORD fOption,
 
306
                                           UDWORD vParam)
 
307
{
 
308
        CSTR func = "PGAPI_SetConnectOption";
 
309
        ConnectionClass *conn = (ConnectionClass *) hdbc;
 
310
        char            changed = FALSE;
 
311
        RETCODE         retval;
 
312
        int                     i;
 
313
 
 
314
        mylog("%s: entering fOption = %d vParam = %d\n", func, fOption, vParam);
 
315
        if (!conn)
 
316
        {
 
317
                CC_log_error(func, "", NULL);
 
318
                return SQL_INVALID_HANDLE;
 
319
        }
 
320
 
 
321
        switch (fOption)
 
322
        {
 
323
                        /*
 
324
                         * Statement Options (apply to all stmts on the connection and
 
325
                         * become defaults for new stmts)
 
326
                         */
 
327
                case SQL_ASYNC_ENABLE:
 
328
                case SQL_BIND_TYPE:
 
329
                case SQL_CONCURRENCY:
 
330
                case SQL_CURSOR_TYPE:
 
331
                case SQL_KEYSET_SIZE:
 
332
                case SQL_MAX_LENGTH:
 
333
                case SQL_MAX_ROWS:
 
334
                case SQL_NOSCAN:
 
335
                case SQL_QUERY_TIMEOUT:
 
336
                case SQL_RETRIEVE_DATA:
 
337
                case SQL_ROWSET_SIZE:
 
338
                case SQL_SIMULATE_CURSOR:
 
339
                case SQL_USE_BOOKMARKS:
 
340
 
 
341
                        /* Affect all current Statements */
 
342
                        for (i = 0; i < conn->num_stmts; i++)
 
343
                        {
 
344
                                if (conn->stmts[i])
 
345
                                        set_statement_option(NULL, conn->stmts[i], fOption, vParam);
 
346
                        }
 
347
 
 
348
                        /*
 
349
                         * Become the default for all future statements on this
 
350
                         * connection
 
351
                         */
 
352
                        retval = set_statement_option(conn, NULL, fOption, vParam);
 
353
 
 
354
                        if (retval == SQL_SUCCESS_WITH_INFO)
 
355
                                changed = TRUE;
 
356
                        else if (retval == SQL_ERROR)
 
357
                                return SQL_ERROR;
 
358
 
 
359
                        break;
 
360
 
 
361
                        /*
 
362
                         * Connection Options
 
363
                         */
 
364
 
 
365
                case SQL_ACCESS_MODE:   /* ignored */
 
366
                        break;
 
367
 
 
368
                case SQL_AUTOCOMMIT:
 
369
                        if (vParam == SQL_AUTOCOMMIT_ON && CC_is_in_autocommit(conn))
 
370
                                break;
 
371
                        else if (vParam == SQL_AUTOCOMMIT_OFF && !CC_is_in_autocommit(conn))
 
372
                                break;
 
373
                        if (CC_is_in_trans(conn))
 
374
                                CC_commit(conn);
 
375
 
 
376
                        mylog("PGAPI_SetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam);
 
377
 
 
378
                        switch (vParam)
 
379
                        {
 
380
                                case SQL_AUTOCOMMIT_OFF:
 
381
                                        CC_set_autocommit_off(conn);
 
382
                                        break;
 
383
 
 
384
                                case SQL_AUTOCOMMIT_ON:
 
385
                                        CC_set_autocommit_on(conn);
 
386
                                        break;
 
387
 
 
388
                                default:
 
389
                                        CC_set_error(conn, CONN_INVALID_ARGUMENT_NO, "Illegal parameter value for SQL_AUTOCOMMIT");
 
390
                                        CC_log_error(func, "", conn);
 
391
                                        return SQL_ERROR;
 
392
                        }
 
393
                        break;
 
394
 
 
395
                case SQL_CURRENT_QUALIFIER:             /* ignored */
 
396
                        break;
 
397
 
 
398
                case SQL_LOGIN_TIMEOUT: /* ignored */
 
399
                        break;
 
400
 
 
401
                case SQL_PACKET_SIZE:   /* ignored */
 
402
                        break;
 
403
 
 
404
                case SQL_QUIET_MODE:    /* ignored */
 
405
                        break;
 
406
 
 
407
                case SQL_TXN_ISOLATION: /* ignored */
 
408
                        retval = SQL_SUCCESS;
 
409
                        if (CC_is_in_trans(conn))
 
410
                        {
 
411
                                CC_set_error(conn, CONN_TRANSACT_IN_PROGRES, "Cannot switch isolation level while a transaction is in progress");
 
412
                                CC_log_error(func, "", conn);
 
413
                                return SQL_ERROR;
 
414
                        }
 
415
                        if (conn->isolation == vParam)
 
416
                                break; 
 
417
                        switch (vParam)
 
418
                        {
 
419
                                case SQL_TXN_SERIALIZABLE:
 
420
                                        if (PG_VERSION_GE(conn, 6.5) &&
 
421
                                            PG_VERSION_LE(conn, 7.0))
 
422
                                                retval = SQL_ERROR;
 
423
                                        break;
 
424
                                case SQL_TXN_READ_COMMITTED:
 
425
                                        if (PG_VERSION_LT(conn, 6.5))
 
426
                                                retval = SQL_ERROR;
 
427
                                        break;
 
428
                                default:
 
429
                                        retval = SQL_ERROR;
 
430
                        }
 
431
                        if (SQL_ERROR == retval)
 
432
                        {
 
433
                                CC_set_error(conn, CONN_INVALID_ARGUMENT_NO, "Illegal parameter value for SQL_TXN_ISOLATION");
 
434
                                CC_log_error(func, "", conn);
 
435
                                return SQL_ERROR;
 
436
                        }
 
437
                        else
 
438
                        {
 
439
                                char *query;
 
440
                                QResultClass *res;
 
441
 
 
442
                                if (vParam == SQL_TXN_SERIALIZABLE)
 
443
                                        query = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE";
 
444
                                else
 
445
                                        query = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED";
 
446
                                res = CC_send_query(conn, query, NULL, 0);
 
447
                                if (!res || !QR_command_maybe_successful(res))
 
448
                                        retval = SQL_ERROR;
 
449
                                else
 
450
                                        conn->isolation = vParam;
 
451
                                if (res)
 
452
                                        QR_Destructor(res);
 
453
                                if (SQL_ERROR == retval)
 
454
                                {
 
455
                                        CC_set_error(conn, STMT_EXEC_ERROR, "ISOLATION change request to the server error");
 
456
                                        return SQL_ERROR;
 
457
                                }
 
458
                        }
 
459
                        break;
 
460
 
 
461
                        /* These options should be handled by driver manager */
 
462
                case SQL_ODBC_CURSORS:
 
463
                case SQL_OPT_TRACE:
 
464
                case SQL_OPT_TRACEFILE:
 
465
                case SQL_TRANSLATE_DLL:
 
466
                case SQL_TRANSLATE_OPTION:
 
467
                        CC_log_error(func, "This connect option (Set) is only used by the Driver Manager", conn);
 
468
                        break;
 
469
 
 
470
                default:
 
471
                        {
 
472
                                char            option[64];
 
473
 
 
474
                                CC_set_error(conn, CONN_UNSUPPORTED_OPTION, "Unknown connect option (Set)");
 
475
                                sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
 
476
                                if (fOption == 30002 && vParam)
 
477
                                {
 
478
                                        int     cmp;
 
479
#ifdef  UNICODE_SUPPORT
 
480
                                        char *asPara;
 
481
                                        if (conn->unicode)
 
482
                                        {
 
483
                                                asPara = ucs2_to_utf8((SQLWCHAR *) vParam, -1, NULL, FALSE);
 
484
                                                cmp = strcmp(asPara, "Microsoft Jet");
 
485
                                                free(asPara);
 
486
                                        }
 
487
                                        else
 
488
#endif /* UNICODE_SUPPORT */
 
489
                                        cmp = strncmp((char *) vParam, "Microsoft Jet", 13);
 
490
                                        if (0 == cmp)
 
491
                                        {
 
492
                                                mylog("Microsoft Jet !!!!\n");
 
493
                                                CC_set_errornumber(conn, 0);
 
494
                                                conn->ms_jet = 1;
 
495
                                                return SQL_SUCCESS;
 
496
                                        }
 
497
                                }
 
498
                                CC_log_error(func, option, conn);
 
499
                                return SQL_ERROR;
 
500
                        }
 
501
        }
 
502
 
 
503
        if (changed)
 
504
        {
 
505
                CC_set_error(conn, CONN_OPTION_VALUE_CHANGED, "Requested value changed.");
 
506
                return SQL_SUCCESS_WITH_INFO;
 
507
        }
 
508
        else
 
509
                return SQL_SUCCESS;
 
510
}
 
511
 
 
512
 
 
513
/* This function just can tell you whether you are in Autcommit mode or not */
 
514
RETCODE         SQL_API
 
515
PGAPI_GetConnectOption(
 
516
                                           HDBC hdbc,
 
517
                                           UWORD fOption,
 
518
                                           PTR pvParam)
 
519
{
 
520
        CSTR func = "PGAPI_GetConnectOption";
 
521
        ConnectionClass *conn = (ConnectionClass *) hdbc;
 
522
        ConnInfo   *ci = &(conn->connInfo);
 
523
 
 
524
        mylog("%s: entering...\n", func);
 
525
 
 
526
        if (!conn)
 
527
        {
 
528
                CC_log_error(func, "", NULL);
 
529
                return SQL_INVALID_HANDLE;
 
530
        }
 
531
 
 
532
        switch (fOption)
 
533
        {
 
534
                case SQL_ACCESS_MODE:   /* NOT SUPPORTED */
 
535
                        *((UDWORD *) pvParam) = SQL_MODE_READ_WRITE;
 
536
                        break;
 
537
 
 
538
                case SQL_AUTOCOMMIT:
 
539
                        *((UDWORD *) pvParam) = (UDWORD) (CC_is_in_autocommit(conn) ?
 
540
                                                                 SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
 
541
                        break;
 
542
 
 
543
                case SQL_CURRENT_QUALIFIER:             /* don't use qualifiers */
 
544
                        if (pvParam)
 
545
                                ((char *) pvParam)[0] = ((char *) pvParam)[1] = '\0';
 
546
 
 
547
                        break;
 
548
 
 
549
                case SQL_LOGIN_TIMEOUT: /* NOT SUPPORTED */
 
550
                        *((UDWORD *) pvParam) = 0;
 
551
                        break;
 
552
 
 
553
                case SQL_PACKET_SIZE:   /* NOT SUPPORTED */
 
554
                        *((UDWORD *) pvParam) = ci->drivers.socket_buffersize;
 
555
                        break;
 
556
 
 
557
                case SQL_QUIET_MODE:    /* NOT SUPPORTED */
 
558
                        *((UDWORD *) pvParam) = (UDWORD) NULL;
 
559
                        break;
 
560
 
 
561
                case SQL_TXN_ISOLATION:
 
562
                        *((UDWORD *) pvParam) = conn->isolation;
 
563
                        break;
 
564
 
 
565
#ifdef  SQL_ATTR_CONNECTION_DEAD
 
566
                case SQL_ATTR_CONNECTION_DEAD:
 
567
#else
 
568
                case 1209:
 
569
#endif /* SQL_ATTR_CONNECTION_DEAD */
 
570
                        mylog("CONNECTION_DEAD status=%d", conn->status);
 
571
                        *((SQLUINTEGER *) pvParam) = (conn->status == CONN_NOT_CONNECTED || conn->status == CONN_DOWN);
 
572
                        mylog(" val=%d\n", *((SQLUINTEGER *) pvParam));
 
573
                        break;
 
574
 
 
575
                        /* These options should be handled by driver manager */
 
576
                case SQL_ODBC_CURSORS:
 
577
                case SQL_OPT_TRACE:
 
578
                case SQL_OPT_TRACEFILE:
 
579
                case SQL_TRANSLATE_DLL:
 
580
                case SQL_TRANSLATE_OPTION:
 
581
                        CC_log_error(func, "This connect option (Get) is only used by the Driver Manager", conn);
 
582
                        break;
 
583
 
 
584
                default:
 
585
                        {
 
586
                                char            option[64];
 
587
 
 
588
                                CC_set_error(conn, CONN_UNSUPPORTED_OPTION, "Unknown connect option (Get)");
 
589
                                sprintf(option, "fOption=%d", fOption);
 
590
                                CC_log_error(func, option, conn);
 
591
                                return SQL_ERROR;
 
592
                                break;
 
593
                        }
 
594
        }
 
595
 
 
596
        return SQL_SUCCESS;
 
597
}
 
598
 
 
599
 
 
600
RETCODE         SQL_API
 
601
PGAPI_SetStmtOption(
 
602
                                        HSTMT hstmt,
 
603
                                        UWORD fOption,
 
604
                                        UDWORD vParam)
 
605
{
 
606
        CSTR func = "PGAPI_SetStmtOption";
 
607
        StatementClass *stmt = (StatementClass *) hstmt;
 
608
 
 
609
        mylog("%s: entering...\n", func);
 
610
 
 
611
        /*
 
612
         * Though we could fake Access out by just returning SQL_SUCCESS all
 
613
         * the time, but it tries to set a huge value for SQL_MAX_LENGTH and
 
614
         * expects the driver to reduce it to the real value.
 
615
         */
 
616
        if (!stmt)
 
617
        {
 
618
                SC_log_error(func, "", NULL);
 
619
                return SQL_INVALID_HANDLE;
 
620
        }
 
621
 
 
622
        return set_statement_option(NULL, stmt, fOption, vParam);
 
623
}
 
624
 
 
625
 
 
626
RETCODE         SQL_API
 
627
PGAPI_GetStmtOption(
 
628
                                        HSTMT hstmt,
 
629
                                        UWORD fOption,
 
630
                                        PTR pvParam)
 
631
{
 
632
        CSTR func = "PGAPI_GetStmtOption";
 
633
        StatementClass *stmt = (StatementClass *) hstmt;
 
634
        QResultClass *res;
 
635
        ConnInfo   *ci = &(SC_get_conn(stmt)->connInfo);
 
636
        int     ridx;
 
637
 
 
638
        mylog("%s: entering...\n", func);
 
639
 
 
640
        /*
 
641
         * thought we could fake Access out by just returning SQL_SUCCESS all
 
642
         * the time, but it tries to set a huge value for SQL_MAX_LENGTH and
 
643
         * expects the driver to reduce it to the real value
 
644
         */
 
645
        if (!stmt)
 
646
        {
 
647
                SC_log_error(func, "", NULL);
 
648
                return SQL_INVALID_HANDLE;
 
649
        }
 
650
 
 
651
        switch (fOption)
 
652
        {
 
653
                case SQL_GET_BOOKMARK:
 
654
                case SQL_ROW_NUMBER:
 
655
 
 
656
                        res = SC_get_Curres(stmt);
 
657
                        if (!res)
 
658
                        {
 
659
                                SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The cursor has no result.");
 
660
                                SC_log_error(func, "", stmt);
 
661
                                return SQL_ERROR;
 
662
                        }
 
663
 
 
664
                        ridx = GIdx2ResultIdx(stmt->currTuple, stmt, res);
 
665
                        if (stmt->manual_result || !SC_is_fetchcursor(stmt))
 
666
                        {
 
667
                                /* make sure we're positioned on a valid row */
 
668
                                if ((ridx < 0) ||
 
669
                                        (ridx >= QR_get_num_backend_tuples(res)))
 
670
                                {
 
671
                                        SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row.");
 
672
                                        SC_log_error(func, "", stmt);
 
673
                                        return SQL_ERROR;
 
674
                                }
 
675
                        }
 
676
                        else
 
677
                        {
 
678
                                if (stmt->currTuple < 0 || !res->tupleField)
 
679
                                {
 
680
                                        SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row.");
 
681
                                        SC_log_error(func, "", stmt);
 
682
                                        return SQL_ERROR;
 
683
                                }
 
684
                        }
 
685
 
 
686
                        if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF)
 
687
                        {
 
688
                                SC_set_error(stmt, STMT_OPERATION_INVALID, "Operation invalid because use bookmarks not enabled.");
 
689
                                SC_log_error(func, "", stmt);
 
690
                                return SQL_ERROR;
 
691
                        }
 
692
 
 
693
                        *((UDWORD *) pvParam) = SC_get_bookmark(stmt);
 
694
 
 
695
                        break;
 
696
 
 
697
                case SQL_ASYNC_ENABLE:  /* NOT SUPPORTED */
 
698
                        *((SDWORD *) pvParam) = SQL_ASYNC_ENABLE_OFF;
 
699
                        break;
 
700
 
 
701
                case SQL_BIND_TYPE:
 
702
                        *((SDWORD *) pvParam) = SC_get_ARD(stmt)->bind_size;
 
703
                        break;
 
704
 
 
705
                case SQL_CONCURRENCY:   /* NOT REALLY SUPPORTED */
 
706
                        mylog("GetStmtOption(): SQL_CONCURRENCY %d\n", stmt->options.scroll_concurrency);
 
707
                        *((SDWORD *) pvParam) = stmt->options.scroll_concurrency;
 
708
                        break;
 
709
 
 
710
                case SQL_CURSOR_TYPE:   /* PARTIAL SUPPORT */
 
711
                        mylog("GetStmtOption(): SQL_CURSOR_TYPE %d\n", stmt->options.cursor_type);
 
712
                        *((SDWORD *) pvParam) = stmt->options.cursor_type;
 
713
                        break;
 
714
 
 
715
                case SQL_KEYSET_SIZE:   /* NOT SUPPORTED, but saved */
 
716
                        mylog("GetStmtOption(): SQL_KEYSET_SIZE\n");
 
717
                        *((SDWORD *) pvParam) = stmt->options.keyset_size;
 
718
                        break;
 
719
 
 
720
                case SQL_MAX_LENGTH:    /* NOT SUPPORTED, but saved */
 
721
                        *((SDWORD *) pvParam) = stmt->options.maxLength;
 
722
                        break;
 
723
 
 
724
                case SQL_MAX_ROWS:              /* NOT SUPPORTED, but saved */
 
725
                        *((SDWORD *) pvParam) = stmt->options.maxRows;
 
726
                        mylog("GetSmtOption: MAX_ROWS, returning %d\n", stmt->options.maxRows);
 
727
                        break;
 
728
 
 
729
                case SQL_NOSCAN:                /* NOT SUPPORTED */
 
730
                        *((SDWORD *) pvParam) = SQL_NOSCAN_ON;
 
731
                        break;
 
732
 
 
733
                case SQL_QUERY_TIMEOUT: /* NOT SUPPORTED */
 
734
                        *((SDWORD *) pvParam) = 0;
 
735
                        break;
 
736
 
 
737
                case SQL_RETRIEVE_DATA:
 
738
                        *((SDWORD *) pvParam) = stmt->options.retrieve_data;
 
739
                        break;
 
740
 
 
741
                case SQL_ROWSET_SIZE:
 
742
                        *((SDWORD *) pvParam) = SC_get_ARD(stmt)->size_of_rowset_odbc2;
 
743
                        break;
 
744
 
 
745
                case SQL_SIMULATE_CURSOR:               /* NOT SUPPORTED */
 
746
                        *((SDWORD *) pvParam) = SQL_SC_NON_UNIQUE;
 
747
                        break;
 
748
 
 
749
                case SQL_USE_BOOKMARKS:
 
750
                        *((SDWORD *) pvParam) = stmt->options.use_bookmarks;
 
751
                        break;
 
752
 
 
753
                default:
 
754
                        {
 
755
                                char            option[64];
 
756
 
 
757
                                SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Get)");
 
758
                                sprintf(option, "fOption=%d", fOption);
 
759
                                SC_log_error(func, option, stmt);
 
760
                                return SQL_ERROR;
 
761
                        }
 
762
        }
 
763
 
 
764
        return SQL_SUCCESS;
 
765
}