~ubuntu-branches/ubuntu/trusty/libodbc-ruby/trusty

« back to all changes in this revision

Viewing changes to odbc.c

  • Committer: Bazaar Package Importer
  • Author(s): Daigo Moriwaki, Lucas Nussbaum
  • Date: 2010-05-07 16:50:04 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20100507165004-so71tlp4aaqvwa69
Tags: 0.99991-1
* New upstream release
* Switch to dpkg-source 3.0 (quilt) format
  + Added debian/source
* Bumped Standard Version to 3.8.4
* Updated debian/patches
  + Added quilt patch, removed dpatch
    because upstream has new directory structure
* Updated .example. no test.rb is available with new release
* Updated debian/control
  + Added Build-Depends for ruby1.9.1
  + Removed dpatch from Build-Depends
  + Added myself to Uploaders
* Updated debian/rules
  + Port to ruby1.9.1 (Closes: #507695)
  + Changed the directory structure for make
  + Removed dpatch.mk

[ Lucas Nussbaum ]
* Fixed Vcs-* fields after pkg-ruby-extras SVN layout change.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * ODBC-Ruby binding
3
 
 * Copyright (c) 2001-2009 Christian Werner <chw@ch-werner.de>
4
 
 * Portions copyright (c) 2004 Ryszard Niewisiewicz <micz@fibernet.pl>
5
 
 * Portions copyright (c) 2006 Carl Blakeley <cblakeley@openlinksw.co.uk>
6
 
 *
7
 
 * See the file "COPYING" for information on usage
8
 
 * and redistribution of this file and for a
9
 
 * DISCLAIMER OF ALL WARRANTIES.
10
 
 *
11
 
 * $Id: odbc.c,v 1.61 2009/05/20 05:30:03 chw Exp chw $
12
 
 */
13
 
 
14
 
#undef ODBCVER
15
 
 
16
 
#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__)
17
 
#include <windows.h>
18
 
#endif
19
 
#include <stdarg.h>
20
 
#include <ctype.h>
21
 
#include "ruby.h"
22
 
#ifdef HAVE_VERSION_H
23
 
#include "version.h"
24
 
#endif
25
 
#ifdef HAVE_SQL_H
26
 
#include <sql.h>
27
 
#else
28
 
#error Missing include: sql.h
29
 
#endif
30
 
#ifdef HAVE_SQLEXT_H
31
 
#include <sqlext.h>
32
 
#else
33
 
#error Missing include: sqlext.h
34
 
#endif
35
 
#ifdef HAVE_ODBCINST_H
36
 
#include <odbcinst.h>
37
 
#endif
38
 
 
39
 
#ifdef UNICODE
40
 
#include <sqlucode.h>
41
 
#endif
42
 
 
43
 
#ifndef HAVE_TYPE_SQLTCHAR
44
 
#ifdef UNICODE
45
 
typedef SQLWCHAR SQLTCHAR;
46
 
#else
47
 
typedef SQLCHAR SQLTCHAR;
48
 
#endif
49
 
#endif
50
 
 
51
 
#ifndef HAVE_TYPE_SQLLEN
52
 
#define SQLLEN  SQLINTEGER
53
 
#endif
54
 
#ifndef HAVE_TYPE_SQLULEN
55
 
#define SQLULEN SQLUINTEGER
56
 
#endif
57
 
 
58
 
/*
59
 
 * Conditionally undefine aliases of ODBC installer UNICODE functions.
60
 
 */
61
 
 
62
 
#if defined(UNICODE) && defined(HAVE_SQLINSTALLERERRORW)
63
 
#undef SQLInstallerError
64
 
#endif
65
 
#if defined(UNICODE) && defined(HAVE_SQLCONFIGDATASOURCEW)
66
 
#undef SQLConfigDataSource
67
 
#endif
68
 
#if defined(UNICODE) && defined(HAVE_SQLREADFILEDSNW)
69
 
#undef SQLReadFileDSN
70
 
#endif
71
 
#if defined(UNICODE) && defined(HAVE_SQLWRITEFILEDSNW)
72
 
#undef SQLWriteFileDSN
73
 
#endif
74
 
 
75
 
#if defined(UNICODE) && defined(USE_DLOPEN_FOR_ODBC_LIBS)
76
 
extern int ruby_odbc_have_func(char *name, void *addr);
77
 
#endif
78
 
 
79
 
#ifdef UNICODE
80
 
/*
81
 
 * Declarations of required installer APIs in case
82
 
 * header files don't provide them (unixODBC?).
83
 
 */
84
 
 
85
 
#ifndef HAVE_SQLINSTALLERERRORW
86
 
SQLRETURN INSTAPI SQLInstallerErrorW(WORD, DWORD *, LPWSTR, WORD, WORD *);
87
 
#endif
88
 
#ifndef HAVE_SQLCONFIGDATASOURCEW
89
 
BOOL INSTAPI SQLConfigDataSourceW(HWND, WORD, LPWSTR, LPWSTR);
90
 
#endif
91
 
#ifndef HAVE_SQLREADFILEDSNW
92
 
BOOL INSTAPI SQLReadFileDSNW(LPWSTR, LPWSTR, LPWSTR, LPWSTR, WORD, WORD *);
93
 
#endif
94
 
#ifndef HAVE_SQLWRITEFILEDSNW
95
 
BOOL INSTAPI SQLWriteFileDSNW(LPWSTR, LPWSTR, LPWSTR, LPWSTR);
96
 
#endif
97
 
#endif /* UNICODE */
98
 
 
99
 
#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
100
 
#define rb_define_alloc_func(cls, func) \
101
 
    rb_define_singleton_method(cls, "new", func, -1)
102
 
#define rb_undefine_alloc_func(cls) \
103
 
    rb_undef_method(CLASS_OF(cls), "new")
104
 
#endif
105
 
 
106
 
#ifdef RB_CVAR_SET_4ARGS
107
 
#define CVAR_SET(x, y, z) rb_cvar_set(x, y, z, 0)
108
 
#else
109
 
#define CVAR_SET(x, y, z) rb_cvar_set(x, y, z)
110
 
#endif
111
 
 
112
 
#ifdef TRACING
113
 
static int tracing = 0;
114
 
#define tracemsg(t, x) {if (tracing & t) { x }}
115
 
static SQLRETURN tracesql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt,
116
 
                          SQLRETURN ret, char *m);
117
 
#else
118
 
#define tracemsg(t, x)
119
 
#define tracesql(a, b, c, d, e) d
120
 
#endif
121
 
 
122
 
#ifndef SQL_SUCCEEDED
123
 
#define SQL_SUCCEEDED(x) \
124
 
    (((x) == SQL_SUCCESS) || ((x) == SQL_SUCCESS_WITH_INFO))
125
 
#endif
126
 
 
127
 
#ifndef SQL_NO_DATA
128
 
#define SQL_NO_DATA SQL_NO_DATA_FOUND
129
 
#endif
130
 
 
131
 
typedef struct link {
132
 
    struct link *succ;
133
 
    struct link *pred;
134
 
    struct link *head;
135
 
    int offs;
136
 
} LINK;
137
 
 
138
 
typedef struct env {
139
 
    VALUE self;
140
 
    LINK dbcs;
141
 
    SQLHENV henv;
142
 
} ENV;
143
 
 
144
 
typedef struct dbc {
145
 
    LINK link;
146
 
    VALUE self;
147
 
    VALUE env;
148
 
    struct env *envp;
149
 
    LINK stmts; 
150
 
    SQLHDBC hdbc;
151
 
    int upc;
152
 
} DBC;
153
 
 
154
 
typedef struct {
155
 
    SQLSMALLINT type;
156
 
    SQLULEN coldef;
157
 
    SQLULEN coldef_max;
158
 
    SQLSMALLINT scale;
159
 
    SQLLEN rlen;
160
 
    SQLSMALLINT nullable;
161
 
    SQLSMALLINT iotype;
162
 
    int override;
163
 
#ifdef UNICODE
164
 
    SQLWCHAR *tofree;
165
 
#endif
166
 
    char buffer[sizeof (double) * 4];
167
 
    SQLSMALLINT ctype;
168
 
    SQLSMALLINT outtype;
169
 
    int outsize;
170
 
    char *outbuf;
171
 
} PINFO;
172
 
 
173
 
typedef struct {
174
 
    int type;
175
 
    int size;
176
 
} COLTYPE;
177
 
 
178
 
typedef struct stmt {
179
 
    LINK link;
180
 
    VALUE self;
181
 
    VALUE dbc;
182
 
    struct dbc *dbcp;
183
 
    SQLHSTMT hstmt;
184
 
    int nump;
185
 
    PINFO *pinfo;
186
 
    int ncols;
187
 
    COLTYPE *coltypes;
188
 
    char **colnames;
189
 
    char **dbufs;
190
 
    int fetchc;
191
 
    int upc;
192
 
    int usef;
193
 
} STMT;
194
 
 
195
 
static VALUE Modbc;
196
 
static VALUE Cobj;
197
 
static VALUE Cenv;
198
 
static VALUE Cdbc;
199
 
static VALUE Cstmt;
200
 
static VALUE Ccolumn;
201
 
static VALUE Cparam;
202
 
static VALUE Cerror;
203
 
static VALUE Cdsn;
204
 
static VALUE Cdrv;
205
 
static VALUE Cdate;
206
 
static VALUE Ctime;
207
 
static VALUE Ctimestamp;
208
 
static VALUE Cproc;
209
 
static VALUE rb_cDate;
210
 
 
211
 
static ID IDstart;
212
 
static ID IDatatinfo;
213
 
static ID IDataterror;
214
 
static ID IDkeys;
215
 
static ID IDatattrs;
216
 
static ID IDday;
217
 
static ID IDmonth;
218
 
static ID IDyear;
219
 
static ID IDmday;
220
 
static ID IDsec;
221
 
static ID IDmin;
222
 
static ID IDhour;
223
 
static ID IDusec;
224
 
static ID IDkeyp;
225
 
static ID IDkey;
226
 
static ID IDSymbol;
227
 
static ID IDString;
228
 
static ID IDFixnum;
229
 
static ID IDtable_names;
230
 
static ID IDnew;
231
 
static ID IDnow;
232
 
static ID IDlocal;
233
 
static ID IDname;
234
 
static ID IDtable;
235
 
static ID IDtype;
236
 
static ID IDlength;
237
 
static ID IDnullable;
238
 
static ID IDscale;
239
 
static ID IDprecision;
240
 
static ID IDsearchable;
241
 
static ID IDunsigned;
242
 
static ID IDiotype;
243
 
static ID IDoutput_size;
244
 
static ID IDoutput_type;
245
 
static ID IDdescr;
246
 
static ID IDstatement;
247
 
static ID IDreturn_output_param;
248
 
static ID IDattrs;
249
 
static ID IDNULL;
250
 
static ID IDdefault;
251
 
 
252
 
/*
253
 
 * Modes for dbc_info
254
 
 */
255
 
 
256
 
#define INFO_TABLES   0
257
 
#define INFO_COLUMNS  1
258
 
#define INFO_PRIMKEYS 2
259
 
#define INFO_INDEXES  3
260
 
#define INFO_TYPES    4
261
 
#define INFO_FORKEYS  5
262
 
#define INFO_TPRIV    6
263
 
#define INFO_PROCS    7
264
 
#define INFO_PROCCOLS 8
265
 
#define INFO_SPECCOLS 9
266
 
 
267
 
/*
268
 
 * Modes for make_result/stmt_exec_int
269
 
 */
270
 
 
271
 
#define MAKERES_BLOCK   1
272
 
#define MAKERES_NOCLOSE 2
273
 
#define MAKERES_PREPARE 4
274
 
#define MAKERES_EXECD   8
275
 
#define EXEC_PARMXNULL(x) (16 | ((x) << 5))
276
 
#define EXEC_PARMXOUT(x)  (((x) & 16) ? ((x) >> 5) : -1)
277
 
 
278
 
/*
279
 
 * Modes for do_fetch
280
 
 */
281
 
 
282
 
#define DOFETCH_ARY    0
283
 
#define DOFETCH_HASH   1
284
 
#define DOFETCH_HASH2  2
285
 
#define DOFETCH_HASHK  3
286
 
#define DOFETCH_HASHK2 4
287
 
#define DOFETCH_HASHN  5
288
 
#define DOFETCH_MODES  7
289
 
#define DOFETCH_BANG   8
290
 
 
291
 
/*
292
 
 * Size of segment when SQL_NO_TOTAL
293
 
 */
294
 
 
295
 
#define SEGSIZE 65536
296
 
 
297
 
/*
298
 
 * Forward declarations.
299
 
 */
300
 
 
301
 
static SQLRETURN callsql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt,
302
 
                         SQLRETURN ret, char *m);
303
 
 
304
 
static VALUE stmt_exec(int argc, VALUE *argv, VALUE self);
305
 
static VALUE stmt_each(VALUE self);
306
 
static VALUE stmt_each_hash(int argc, VALUE *argv, VALUE self);
307
 
static VALUE stmt_close(VALUE self);
308
 
static VALUE stmt_drop(VALUE self);
309
 
 
310
 
/*
311
 
 * Macro to align buffers.
312
 
 */
313
 
 
314
 
#define LEN_ALIGN(x) \
315
 
    ((x) + sizeof (double) - (((x) + sizeof (double)) % sizeof (double)))
316
 
 
317
 
 
318
 
/*
319
 
 *----------------------------------------------------------------------
320
 
 *
321
 
 *      UNICODE converters et.al.
322
 
 *
323
 
 *----------------------------------------------------------------------
324
 
 */
325
 
 
326
 
#ifdef UNICODE
327
 
 
328
 
static int
329
 
uc_strlen(SQLWCHAR *str)
330
 
{
331
 
    int len = 0;
332
 
 
333
 
    if (str != NULL) {
334
 
        while (*str != '\0') {
335
 
            ++len;
336
 
            ++str;
337
 
        }
338
 
    }
339
 
    return len;
340
 
}
341
 
 
342
 
static SQLWCHAR *
343
 
uc_strchr(SQLWCHAR *str, SQLWCHAR c)
344
 
{
345
 
    if (str != NULL) {
346
 
        while ((*str != '\0') && (*str != c)) {
347
 
            ++str;
348
 
        }
349
 
        str = (*str == c) ? str : NULL;
350
 
    }
351
 
    return str;
352
 
}
353
 
 
354
 
static int
355
 
mkutf(char *dest, SQLWCHAR *src, int len)
356
 
{      
357
 
    int i;
358
 
    char *cp = dest;
359
 
 
360
 
    for (i = 0; i < len; i++) {
361
 
        unsigned long c = src[i];
362
 
 
363
 
        if (sizeof (SQLWCHAR) == (2 * sizeof (char))) {
364
 
            c &= 0xffff;
365
 
        }
366
 
        if (c < 0xc0) {
367
 
            *cp++ = c;
368
 
        } else if (c < 0x800) {
369
 
            *cp++ = 0xc0 | ((c >> 6) & 0x1f);
370
 
            *cp++ = 0x80 | (c & 0x3f);
371
 
        } else if (c < 0x10000) {
372
 
            if ((sizeof (SQLWCHAR) == (2 * sizeof (char))) &&
373
 
                (c >= 0xd800) && (c <= 0xdbff) && ((i + 1) < len)) {
374
 
                unsigned long c2 = src[i + 1] & 0xffff;
375
 
 
376
 
                if ((c2 >= 0xdc00) && (c <= 0xdfff)) {
377
 
                    c = ((c & 0x3ff) | ((c2 & 0x3ff) << 10)) + 0x10000;
378
 
                    *cp++ = 0xf0 | ((c >> 18) & 0x07);
379
 
                    *cp++ = 0x80 | ((c >> 12) & 0x3f);
380
 
                    *cp++ = 0x80 | ((c >> 6) & 0x3f);
381
 
                    *cp++ = 0x80 | (c & 0x3f);
382
 
                    ++i;
383
 
                    continue;
384
 
                }
385
 
            }
386
 
            *cp++ = 0xe0 | ((c >> 12) & 0x0f);
387
 
            *cp++ = 0x80 | ((c >> 6) & 0x3f);
388
 
            *cp++ = 0x80 | (c & 0x3f);
389
 
        } else if (c < 0x200000) {
390
 
            *cp++ = 0xf0 | ((c >> 18) & 0x07);
391
 
            *cp++ = 0x80 | ((c >> 12) & 0x3f);
392
 
            *cp++ = 0x80 | ((c >> 6) & 0x3f);
393
 
            *cp++ = 0x80 | (c & 0x3f);
394
 
        } else if (c < 0x4000000) {
395
 
            *cp++ = 0xf8 | ((c >> 24) & 0x03);
396
 
            *cp++ = 0x80 | ((c >> 18) & 0x3f);
397
 
            *cp++ = 0x80 | ((c >> 12) & 0x3f);
398
 
            *cp++ = 0x80 | ((c >> 6) & 0x3f);
399
 
            *cp++ = 0x80 | (c & 0x3f);
400
 
        } else if (c < 0x80000000) {
401
 
            *cp++ = 0xfc | ((c >> 31) & 0x01);
402
 
            *cp++ = 0x80 | ((c >> 24) & 0x3f);
403
 
            *cp++ = 0x80 | ((c >> 18) & 0x3f);
404
 
            *cp++ = 0x80 | ((c >> 12) & 0x3f);
405
 
            *cp++ = 0x80 | ((c >> 6) & 0x3f);
406
 
            *cp++ = 0x80 | (c & 0x3f);
407
 
        }
408
 
    }
409
 
    *cp = '\0';
410
 
    return cp - dest;
411
 
}
412
 
 
413
 
static VALUE
414
 
uc_tainted_str_new(SQLWCHAR *str, int len)
415
 
{
416
 
    VALUE v;
417
 
    char *cp = xmalloc(len * 6 + 1);
418
 
    int ulen = 0;
419
 
 
420
 
    if ((cp != NULL) && (str != NULL)) {
421
 
        ulen = mkutf(cp, str, len);
422
 
    }
423
 
    v = rb_tainted_str_new((cp != NULL) ? cp : "", ulen);
424
 
    if (cp != NULL) {
425
 
        xfree(cp);
426
 
    }
427
 
    return v;
428
 
}
429
 
 
430
 
static VALUE
431
 
uc_tainted_str_new2(SQLWCHAR *str)
432
 
{
433
 
    return uc_tainted_str_new(str, uc_strlen(str));
434
 
}
435
 
 
436
 
static VALUE
437
 
uc_str_new(SQLWCHAR *str, int len)
438
 
{
439
 
    VALUE v;
440
 
    char *cp = xmalloc(len * 6 + 1);
441
 
    int ulen = 0;
442
 
 
443
 
    if ((cp != NULL) && (str != NULL)) {
444
 
        ulen = mkutf(cp, str, len);
445
 
    }
446
 
    v = rb_str_new((cp != NULL) ? cp : "", ulen);
447
 
    if (cp != NULL) {
448
 
        xfree(cp);
449
 
    }
450
 
    return v;
451
 
}
452
 
 
453
 
static VALUE
454
 
uc_str_new2(SQLWCHAR *str)
455
 
{
456
 
    return uc_str_new(str, uc_strlen(str));
457
 
}
458
 
 
459
 
static VALUE
460
 
uc_str_cat(VALUE v, SQLWCHAR *str, int len)
461
 
{
462
 
    VALUE vv = v;
463
 
    char *cp = xmalloc(len * 6 + 1);
464
 
    int ulen = 0;
465
 
 
466
 
    if ((cp != NULL) && (str != NULL)) {
467
 
        ulen = mkutf(cp, str, len);
468
 
    }
469
 
    if (cp != NULL) {
470
 
        vv = rb_str_cat(v, cp, ulen);
471
 
        xfree(cp);
472
 
    }
473
 
    return vv;
474
 
}
475
 
 
476
 
static SQLWCHAR *
477
 
uc_from_utf(unsigned char *str, int len)
478
 
{
479
 
    SQLWCHAR *uc = NULL;
480
 
 
481
 
    if (str != NULL) {
482
 
        int i = 0;
483
 
        unsigned char *strend;
484
 
 
485
 
        if (len < 0) {
486
 
            len = strlen((char *) str);
487
 
        }
488
 
        strend = str + len;
489
 
        uc = ALLOC_N(SQLWCHAR, len + 1);
490
 
        if (uc != NULL) {
491
 
            while (str < strend) {
492
 
                unsigned char c = str[0];
493
 
 
494
 
                if (c < 0xc0) {
495
 
                    uc[i++] = c;
496
 
                    ++str;
497
 
                } else if (c < 0xe0) {
498
 
                    if ((str[1] & 0xc0) == 0x80) {
499
 
                        unsigned long t = ((c & 0x1f) << 6) | (str[1] & 0x3f);
500
 
 
501
 
                        uc[i++] = t;
502
 
                        str += 2;
503
 
                    } else {
504
 
                        uc[i++] = c;
505
 
                        ++str;
506
 
                    }
507
 
                } else if (c < 0xf0) {
508
 
                    if (((str[1] & 0xc0) == 0x80) &&
509
 
                        ((str[2] & 0xc0) == 0x80)) {
510
 
                        unsigned long t = ((c & 0x0f) << 12) |
511
 
                            ((str[1] & 0x3f) << 6) | (str[2] & 0x3f);
512
 
 
513
 
                        uc[i++] = t;
514
 
                        str += 3;
515
 
                    } else {
516
 
                        uc[i++] = c;
517
 
                        ++str;
518
 
                    }
519
 
                } else if (c < 0xf8) {
520
 
                    if (((str[1] & 0xc0) == 0x80) &&
521
 
                        ((str[2] & 0xc0) == 0x80) &&
522
 
                        ((str[3] & 0xc0) == 0x80)) {
523
 
                        unsigned long t = ((c & 0x03) << 18) |
524
 
                            ((str[1] & 0x3f) << 12) | ((str[2] & 0x3f) << 6) |
525
 
                            (str[4] & 0x3f);
526
 
 
527
 
                        if ((sizeof (SQLWCHAR) == (2 * sizeof (char))) &&
528
 
                            (t >= 0x10000)) {
529
 
                            t -= 0x10000;
530
 
                            uc[i++] = 0xd800 | (t & 0x3ff);
531
 
                            t = 0xdc00 | ((t >> 10) & 0x3ff);
532
 
                        }
533
 
                        uc[i++] = t;
534
 
                        str += 4;
535
 
                    } else {
536
 
                        uc[i++] = c;
537
 
                        ++str;
538
 
                    }
539
 
                } else if (c < 0xfc) {
540
 
                    if (((str[1] & 0xc0) == 0x80) &&
541
 
                        ((str[2] & 0xc0) == 0x80) &&
542
 
                        ((str[3] & 0xc0) == 0x80) &&
543
 
                        ((str[4] & 0xc0) == 0x80)) {
544
 
                        unsigned long t = ((c & 0x01) << 24) |
545
 
                            ((str[1] & 0x3f) << 18) | ((str[2] & 0x3f) << 12) |
546
 
                            ((str[4] & 0x3f) << 6) | (str[5] & 0x3f);
547
 
 
548
 
                        if ((sizeof (SQLWCHAR) == (2 * sizeof (char))) &&
549
 
                            (t >= 0x10000)) {
550
 
                            t -= 0x10000;
551
 
                            uc[i++] = 0xd800 | (t & 0x3ff);
552
 
                            t = 0xdc00 | ((t >> 10) & 0x3ff);
553
 
                        }
554
 
                        uc[i++] = t;
555
 
                        str += 5;
556
 
                    } else {
557
 
                        uc[i++] = c;
558
 
                        ++str;
559
 
                    }
560
 
                } else {
561
 
                    /* ignore */
562
 
                    ++str;
563
 
                }
564
 
            }
565
 
            uc[i] = 0;
566
 
        }
567
 
    }
568
 
    return uc;
569
 
}
570
 
 
571
 
static void
572
 
uc_free(SQLWCHAR *str)
573
 
{
574
 
    if (str != NULL) {
575
 
        xfree(str);
576
 
    }
577
 
}
578
 
 
579
 
#endif
580
 
 
581
 
 
582
 
/*
583
 
 *----------------------------------------------------------------------
584
 
 *
585
 
 *      Things for ODBC::DSN
586
 
 *
587
 
 *----------------------------------------------------------------------
588
 
 */
589
 
 
590
 
#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
591
 
static VALUE
592
 
dsn_new(VALUE self)
593
 
{
594
 
    VALUE obj = rb_obj_alloc(Cdsn);
595
 
 
596
 
    rb_obj_call_init(obj, 0, NULL);
597
 
    return obj;
598
 
}
599
 
#endif
600
 
 
601
 
static VALUE
602
 
dsn_init(VALUE self)
603
 
{
604
 
    rb_iv_set(self, "@name", Qnil);
605
 
    rb_iv_set(self, "@descr", Qnil);
606
 
    return self;
607
 
}
608
 
 
609
 
/*
610
 
 *----------------------------------------------------------------------
611
 
 *
612
 
 *      Things for ODBC::Driver
613
 
 *
614
 
 *----------------------------------------------------------------------
615
 
 */
616
 
 
617
 
#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
618
 
static VALUE
619
 
drv_new(VALUE self)
620
 
{
621
 
    VALUE obj = rb_obj_alloc(Cdrv);
622
 
 
623
 
    rb_obj_call_init(obj, 0, NULL);
624
 
    return obj;
625
 
}
626
 
#endif
627
 
 
628
 
static VALUE
629
 
drv_init(VALUE self)
630
 
{
631
 
    rb_iv_set(self, "@name", Qnil);
632
 
    rb_iv_set(self, "@attrs", rb_hash_new());
633
 
    return self;
634
 
}
635
 
 
636
 
/*
637
 
 *----------------------------------------------------------------------
638
 
 *
639
 
 *      Cleanup routines and GC mark/free callbacks.
640
 
 *
641
 
 *----------------------------------------------------------------------
642
 
 */
643
 
 
644
 
static void
645
 
list_init(LINK *link, int offs)
646
 
{
647
 
    link->succ = link->pred = link->head = NULL;
648
 
    link->offs = offs;
649
 
}
650
 
 
651
 
static void
652
 
list_add(LINK *link, LINK *head)
653
 
{
654
 
    if (link->head != NULL) {
655
 
        rb_fatal("RubyODBC: already in list");
656
 
    }
657
 
    if (head == NULL) {
658
 
        rb_fatal("RubyODBC: invalid list head");
659
 
    }
660
 
    link->head = head;
661
 
    link->pred = NULL;
662
 
    link->succ = head->succ;
663
 
    head->succ = link;
664
 
    if (link->succ != NULL) {
665
 
        link->succ->pred = link;
666
 
    }
667
 
}
668
 
 
669
 
static void
670
 
list_del(LINK *link)
671
 
{
672
 
    if (link == NULL) {
673
 
        rb_fatal("RubyODBC: invalid list item");
674
 
    }
675
 
    if (link->head == NULL) {
676
 
        rb_fatal("RubyODBC: item not in list");
677
 
    }
678
 
    if (link->succ != NULL) {
679
 
        link->succ->pred = link->pred;
680
 
    }
681
 
    if (link->pred != NULL) {
682
 
        link->pred->succ = link->succ;
683
 
    } else {
684
 
        link->head->succ = link->succ;
685
 
    }
686
 
    link->succ = link->pred = link->head = NULL;
687
 
}
688
 
 
689
 
static void *
690
 
list_first(LINK *head)
691
 
{
692
 
    if (head->succ == NULL) {
693
 
        return NULL;
694
 
    }
695
 
    return (void *) ((char *) head->succ - head->offs);
696
 
}
697
 
 
698
 
static int
699
 
list_empty(LINK *head)
700
 
{
701
 
    return head->succ == NULL; 
702
 
}
703
 
 
704
 
static void
705
 
free_env(ENV *e)
706
 
{
707
 
    e->self = Qnil;
708
 
    if (!list_empty(&e->dbcs)) {
709
 
        return;
710
 
    }
711
 
    tracemsg(2, fprintf(stderr, "ObjFree: ENV %p\n", e););
712
 
    if (e->henv != SQL_NULL_HENV) {
713
 
        callsql(SQL_NULL_HENV, e->henv, SQL_NULL_HSTMT,
714
 
                SQLFreeEnv(e->henv), "SQLFreeEnv");
715
 
        e->henv = SQL_NULL_HENV;
716
 
    }
717
 
    xfree(e);
718
 
}
719
 
 
720
 
static void
721
 
link_dbc(DBC *p, ENV *e)
722
 
{
723
 
    p->envp = e;
724
 
    list_add(&p->link, &e->dbcs);
725
 
}
726
 
 
727
 
static void
728
 
unlink_dbc(DBC *p)
729
 
{
730
 
    if (p == NULL) {
731
 
        return;
732
 
    }
733
 
    p->env = Qnil;
734
 
    if (p->envp != NULL) {
735
 
        ENV *e = p->envp;
736
 
 
737
 
        list_del(&p->link);
738
 
        if (e->self == Qnil) {
739
 
            free_env(e);
740
 
        }
741
 
        p->envp = NULL;
742
 
    }
743
 
}
744
 
 
745
 
static void
746
 
free_dbc(DBC *p)
747
 
{
748
 
    p->self = p->env = Qnil;
749
 
    if (!list_empty(&p->stmts)) {
750
 
        return;
751
 
    }
752
 
    tracemsg(2, fprintf(stderr, "ObjFree: DBC %p\n", p););
753
 
    if (p->hdbc != SQL_NULL_HDBC) {
754
 
        callsql(SQL_NULL_HENV, p->hdbc, SQL_NULL_HSTMT,
755
 
                SQLDisconnect(p->hdbc), "SQLDisconnect");
756
 
        callsql(SQL_NULL_HENV, p->hdbc, SQL_NULL_HSTMT,
757
 
                SQLFreeConnect(p->hdbc), "SQLFreeConnect");
758
 
        p->hdbc = SQL_NULL_HDBC;
759
 
    }
760
 
    unlink_dbc(p);
761
 
    xfree(p);
762
 
}
763
 
 
764
 
static void
765
 
free_stmt_sub(STMT *q)
766
 
{
767
 
    if (q->pinfo != NULL) {
768
 
        int i;
769
 
 
770
 
        for (i = 0; i < q->nump; i++) {
771
 
            if (q->pinfo[i].outbuf != NULL) {
772
 
                xfree(q->pinfo[i].outbuf);
773
 
            }
774
 
        }
775
 
        xfree(q->pinfo);
776
 
        q->pinfo = NULL;
777
 
    }
778
 
    q->nump = 0;
779
 
    q->ncols = 0;
780
 
    if (q->coltypes != NULL) {
781
 
        xfree(q->coltypes);
782
 
        q->coltypes = NULL;
783
 
    }
784
 
    if (q->colnames != NULL) {
785
 
        xfree(q->colnames);
786
 
        q->colnames = NULL;
787
 
    }
788
 
    if (q->dbufs != NULL) {
789
 
        xfree(q->dbufs);
790
 
        q->dbufs = NULL;
791
 
    }
792
 
    if (q->self != Qnil) {
793
 
        VALUE v;
794
 
 
795
 
        v = rb_iv_get(q->self, "@_a");
796
 
        if (v != Qnil) {
797
 
            rb_ary_clear(v);
798
 
        }
799
 
        v = rb_iv_get(q->self, "@_h");
800
 
        if (v != Qnil) {
801
 
            rb_iv_set(q->self, "@_h", rb_hash_new());
802
 
        }
803
 
    }
804
 
}
805
 
 
806
 
static void
807
 
link_stmt(STMT *q, DBC *p)
808
 
{
809
 
    q->dbcp = p;
810
 
    list_add(&q->link, &p->stmts);
811
 
}
812
 
 
813
 
static void
814
 
unlink_stmt(STMT *q)
815
 
{
816
 
    if (q == NULL) {
817
 
        return;
818
 
    }
819
 
    q->dbc = Qnil;
820
 
    if (q->dbcp != NULL) {
821
 
        DBC *p = q->dbcp;
822
 
 
823
 
        list_del(&q->link);
824
 
        if (p->self == Qnil) {
825
 
            free_dbc(p);
826
 
        }
827
 
        q->dbcp = NULL;
828
 
    }
829
 
}
830
 
 
831
 
static void
832
 
free_stmt(STMT *q)
833
 
{
834
 
    VALUE qself = q->self;
835
 
 
836
 
    q->self = q->dbc = Qnil;
837
 
    free_stmt_sub(q);
838
 
    tracemsg(2, fprintf(stderr, "ObjFree: STMT %p\n", q););
839
 
    if (q->hstmt != SQL_NULL_HSTMT) {
840
 
        /* Issue warning message. */
841
 
        fprintf(stderr, "WARNING: #<ODBC::Statement:0x%lx> was not dropped"
842
 
                " before garbage collection.\n", (long) qself);
843
 
        callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
844
 
                SQLFreeStmt(q->hstmt, SQL_DROP), "SQLFreeStmt(SQL_DROP)");
845
 
        q->hstmt = SQL_NULL_HSTMT;
846
 
    }
847
 
    unlink_stmt(q);
848
 
    xfree(q);
849
 
}
850
 
 
851
 
static void
852
 
start_gc()
853
 
{
854
 
    rb_funcall(rb_mGC, IDstart, 0, NULL);
855
 
}
856
 
 
857
 
static void
858
 
mark_dbc(DBC *p)
859
 
{
860
 
    if (p->env != Qnil) {
861
 
        rb_gc_mark(p->env);
862
 
    }
863
 
}
864
 
 
865
 
static void
866
 
mark_stmt(STMT *q)
867
 
{
868
 
    if (q->dbc != Qnil) {
869
 
        rb_gc_mark(q->dbc);
870
 
    }
871
 
}
872
 
 
873
 
/*
874
 
 *----------------------------------------------------------------------
875
 
 *
876
 
 *      Set internal error (or warning) message.
877
 
 *
878
 
 *----------------------------------------------------------------------
879
 
 */
880
 
 
881
 
static char *
882
 
set_err(char *msg, int warn)
883
 
{
884
 
    VALUE a, v = rb_str_new2("INTERN (0) [RubyODBC]");
885
 
 
886
 
    v = rb_str_cat2(v, msg);
887
 
    a = rb_ary_new2(1);
888
 
    rb_ary_push(a, rb_obj_taint(v));
889
 
    CVAR_SET(Cobj, warn ? IDatatinfo : IDataterror, a);
890
 
    return STR2CSTR(v);
891
 
}
892
 
 
893
 
/*
894
 
 *----------------------------------------------------------------------
895
 
 *
896
 
 *      Functions to retrieve last SQL error or warning.
897
 
 *
898
 
 *----------------------------------------------------------------------
899
 
 */
900
 
 
901
 
static char *
902
 
get_err_or_info(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, int isinfo)
903
 
{
904
 
#ifdef UNICODE
905
 
    SQLWCHAR msg[SQL_MAX_MESSAGE_LENGTH], state[6 + 1];
906
 
#else
907
 
    SQLCHAR msg[SQL_MAX_MESSAGE_LENGTH], state[6 + 1];
908
 
#endif
909
 
    char buf[32], tmp[SQL_MAX_MESSAGE_LENGTH];
910
 
    SQLRETURN err;
911
 
    SQLINTEGER nativeerr;
912
 
    SQLSMALLINT len;
913
 
    VALUE v0 = Qnil, a = Qnil, v;
914
 
    int done = 0;
915
 
 
916
 
    while (!done) {
917
 
        v = Qnil;
918
 
        err = tracesql(henv, hdbc, hstmt,
919
 
                       SQLError(henv, hdbc, hstmt, state, &nativeerr, msg,
920
 
                       SQL_MAX_MESSAGE_LENGTH - 1, &len),
921
 
                       "SQLError");
922
 
        state[6] = '\0';
923
 
        msg[SQL_MAX_MESSAGE_LENGTH - 1] = '\0';
924
 
        switch (err) {
925
 
        case SQL_SUCCESS:
926
 
#ifdef UNICODE
927
 
            v = uc_str_new2(state);
928
 
#else
929
 
            v = rb_str_new2((char *) state);
930
 
#endif
931
 
            sprintf(buf, " (%d) ", (int) nativeerr);
932
 
            v = rb_str_cat2(v, buf);
933
 
#ifdef UNICODE
934
 
            v = uc_str_cat(v, msg, len);
935
 
#else
936
 
            v = rb_str_cat(v, (char *) msg, len);
937
 
#endif
938
 
            break;
939
 
        case SQL_NO_DATA:
940
 
            if ((v0 == Qnil) && (!isinfo)) {
941
 
                v = rb_str_new2("INTERN (0) [RubyODBC]No data found");
942
 
            } else {
943
 
                v = Qnil;
944
 
            }
945
 
            done = 1;
946
 
            break;
947
 
        case SQL_INVALID_HANDLE:
948
 
            v = rb_str_new2("INTERN (0) [RubyODBC]Invalid handle");
949
 
            done = 1;
950
 
            break;
951
 
        case SQL_ERROR:
952
 
            v = rb_str_new2("INTERN (0) [RubyODBC]Error reading error message");
953
 
            done = 1;
954
 
            break;
955
 
        default:
956
 
            sprintf(tmp, "INTERN (0) [RubyODBC]Unknown error %d", (int) err);
957
 
            v = rb_str_new2(tmp);
958
 
            done = 1;
959
 
            break;
960
 
        }
961
 
        if (v != Qnil) {
962
 
            if (v0 == Qnil) {
963
 
                v0 = v;
964
 
                a = rb_ary_new();
965
 
            }
966
 
            rb_ary_push(a, rb_obj_taint(v));
967
 
            tracemsg(1, fprintf(stderr, "  | %s\n", STR2CSTR(v)););
968
 
        }
969
 
    }
970
 
    CVAR_SET(Cobj, isinfo ? IDatatinfo : IDataterror, a);
971
 
    if (isinfo) {
972
 
        return NULL;
973
 
    }
974
 
    return (v0 == Qnil) ? NULL : STR2CSTR(v0);
975
 
}
976
 
 
977
 
#if defined(HAVE_SQLINSTALLERERROR) || (defined(UNICODE) && defined(HAVE_SQLINSTALLERERRORW))
978
 
static char *
979
 
get_installer_err()
980
 
{
981
 
#ifdef UNICODE
982
 
#ifdef HAVE_SQLINSTALLERERRORW
983
 
    int have_w = 1;
984
 
#else
985
 
    int have_w = 0;
986
 
#endif
987
 
    SQLWCHAR msg[SQL_MAX_MESSAGE_LENGTH];
988
 
#else
989
 
    char msg[SQL_MAX_MESSAGE_LENGTH];
990
 
#endif
991
 
    char buf[128];
992
 
    SQLRETURN err;
993
 
    VALUE v0 = Qnil, a = Qnil, v;
994
 
    int done = 0;
995
 
    WORD i, len;
996
 
    DWORD insterrcode;
997
 
 
998
 
    for (i = 1; (!done) && (i <= 8); i++) {
999
 
        v = Qnil;
1000
 
#ifdef UNICODE
1001
 
#ifdef USE_DLOPEN_FOR_ODBC_LIBS
1002
 
        have_w = ruby_odbc_have_func("SQLInstallerErrorW", SQLInstallerErrorW);
1003
 
#endif
1004
 
        if (have_w) {
1005
 
            err = tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, SQL_NULL_HSTMT,
1006
 
                           SQLInstallerErrorW(i, &insterrcode, msg,
1007
 
                           SQL_MAX_MESSAGE_LENGTH, &len),
1008
 
                           "SQLInstallerErrorW");
1009
 
            msg[SQL_MAX_MESSAGE_LENGTH - 1] = 0;
1010
 
        } else {
1011
 
            err = tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, SQL_NULL_HSTMT,
1012
 
                           SQLInstallerError(i, &insterrcode, (char *) msg,
1013
 
                           SQL_MAX_MESSAGE_LENGTH, &len),
1014
 
                           "SQLInstallerErrorW");
1015
 
            ((char *) msg)[SQL_MAX_MESSAGE_LENGTH - 1] = '\0';
1016
 
        }
1017
 
#else
1018
 
        err = tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, SQL_NULL_HSTMT,
1019
 
                       SQLInstallerError(i, &insterrcode, msg,
1020
 
                                         SQL_MAX_MESSAGE_LENGTH, &len),
1021
 
                       "SQLInstallerError");
1022
 
        msg[SQL_MAX_MESSAGE_LENGTH - 1] = '\0';
1023
 
#endif
1024
 
        switch (err) {
1025
 
        case SQL_SUCCESS:
1026
 
        case SQL_SUCCESS_WITH_INFO:
1027
 
            sprintf(buf, "INSTALLER (%d) ", (int) insterrcode);
1028
 
            v = rb_str_new2(buf);
1029
 
#ifdef UNICODE
1030
 
            if (have_w) {
1031
 
                v = uc_str_cat(v, msg, len);
1032
 
            } else {
1033
 
                v = rb_str_cat(v, (char *) msg, len);
1034
 
            }
1035
 
#else
1036
 
            v = rb_str_cat(v, msg, len);
1037
 
#endif
1038
 
            break;
1039
 
        case SQL_NO_DATA:
1040
 
            done = 1;
1041
 
            break;
1042
 
        case SQL_ERROR:
1043
 
            v = rb_str_new2("INTERN (0) [RubyODBC]");
1044
 
            v = rb_str_cat2(v, "Error reading installer error message");
1045
 
            done = 1;
1046
 
            break;
1047
 
        default:
1048
 
            v = rb_str_new2("INTERN (0) [RubyODBC]");
1049
 
            sprintf(buf, "Unknown installer error %d", (int) err);
1050
 
            v = rb_str_cat2(v, buf);
1051
 
            done = 1;
1052
 
            break;
1053
 
        }
1054
 
        if (v != Qnil) {
1055
 
            if (v0 == Qnil) {
1056
 
                v0 = v;
1057
 
                a = rb_ary_new();
1058
 
            }
1059
 
            rb_ary_push(a, rb_obj_taint(v));
1060
 
            tracemsg(1, fprintf(stderr, "  | %s\n", STR2CSTR(v)););
1061
 
        }
1062
 
    }
1063
 
    CVAR_SET(Cobj, IDataterror, a);
1064
 
    return (v0 == Qnil) ? NULL : STR2CSTR(v0);
1065
 
}
1066
 
#endif
1067
 
 
1068
 
static char *
1069
 
get_err(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt)
1070
 
{
1071
 
    return get_err_or_info(henv, hdbc, hstmt, 0);
1072
 
}
1073
 
 
1074
 
#ifdef TRACING
1075
 
static void
1076
 
trace_sql_ret(SQLRETURN ret)
1077
 
{
1078
 
    char msg[32], *p;
1079
 
 
1080
 
    switch (ret) {
1081
 
    case SQL_SUCCESS:
1082
 
        p = "SQL_SUCCESS";
1083
 
        break;
1084
 
    case SQL_SUCCESS_WITH_INFO:
1085
 
        p = "SQL_SUCCESS_WITH_INFO";
1086
 
        break;
1087
 
    case SQL_NO_DATA:
1088
 
        p = "SQL_NO_DATA";
1089
 
        break;
1090
 
    case SQL_ERROR:
1091
 
        p = "SQL_ERROR";
1092
 
        break;
1093
 
    case SQL_INVALID_HANDLE:
1094
 
        p = "SQL_INVALID_HANDLE";
1095
 
        break;
1096
 
    default:
1097
 
        sprintf(msg, "SQL_RETURN=%d", (int) ret);
1098
 
        p = msg;
1099
 
        break;
1100
 
    }
1101
 
    fprintf(stderr, "  < %s\n", p);
1102
 
}
1103
 
 
1104
 
static SQLRETURN
1105
 
tracesql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret, char *m)
1106
 
{
1107
 
    if (tracing & 1) {
1108
 
        fprintf(stderr, "SQLCall: %s", m);
1109
 
        fprintf(stderr, "\n  > HENV=0x%lx, HDBC=0x%lx, HSTMT=0x%lx\n",
1110
 
                (long) henv, (long) hdbc, (long) hstmt);
1111
 
        trace_sql_ret(ret);
1112
 
    }
1113
 
    return ret;
1114
 
}
1115
 
#endif
1116
 
 
1117
 
static SQLRETURN
1118
 
callsql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret, char *m)
1119
 
{
1120
 
    SQLRETURN err;
1121
 
 
1122
 
    err = tracesql(henv, hdbc, hstmt, ret, m);
1123
 
    if (err != SQL_SUCCESS) {
1124
 
#ifdef UNICODE
1125
 
        SQLWCHAR msg[SQL_MAX_MESSAGE_LENGTH], state[6 + 1];
1126
 
#else
1127
 
        SQLCHAR msg[SQL_MAX_MESSAGE_LENGTH], state[6 + 1];
1128
 
#endif
1129
 
        SQLINTEGER nativeerr;
1130
 
        SQLSMALLINT len;
1131
 
        int done = 0;
1132
 
 
1133
 
        while (!done) {
1134
 
            err = tracesql(henv, hdbc, hstmt,
1135
 
                           SQLError(henv, hdbc, hstmt, state, &nativeerr, msg,
1136
 
                                    SQL_MAX_MESSAGE_LENGTH - 1, &len),
1137
 
                           "SQLError");
1138
 
            switch (err) {
1139
 
            case SQL_SUCCESS:
1140
 
                break;
1141
 
            case SQL_NO_DATA:
1142
 
            case SQL_INVALID_HANDLE:
1143
 
            case SQL_ERROR:
1144
 
            default:
1145
 
                done = 1;
1146
 
                break;
1147
 
            }
1148
 
        }
1149
 
    }
1150
 
    return ret;
1151
 
}
1152
 
 
1153
 
static int
1154
 
succeeded_common(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret,
1155
 
                 char **msgp)
1156
 
{
1157
 
    if (!SQL_SUCCEEDED(ret)) {
1158
 
        char *dummy;
1159
 
 
1160
 
        if (msgp == NULL) {
1161
 
            msgp = &dummy;
1162
 
        }
1163
 
        *msgp = get_err_or_info(henv, hdbc, hstmt, 0);
1164
 
        return 0;
1165
 
    }
1166
 
    if (ret == SQL_SUCCESS_WITH_INFO) {
1167
 
        get_err_or_info(henv, hdbc, hstmt, 1);
1168
 
    } else {
1169
 
        CVAR_SET(Cobj, IDatatinfo, Qnil);
1170
 
    }
1171
 
    return 1;
1172
 
}
1173
 
 
1174
 
static int
1175
 
succeeded(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret,
1176
 
          char **msgp, char *m, ...)
1177
 
{
1178
 
#ifdef TRACING
1179
 
    va_list args;
1180
 
 
1181
 
    if (tracing & 1) {
1182
 
        va_start(args, m);
1183
 
        fprintf(stderr, "SQLCall: ");
1184
 
        vfprintf(stderr, m, args);
1185
 
        va_end(args);
1186
 
        fprintf(stderr, "\n  > HENV=0x%lx, HDBC=0x%lx, HSTMT=0x%lx\n",
1187
 
                (long) henv, (long) hdbc, (long) hstmt);
1188
 
        trace_sql_ret(ret);
1189
 
    }
1190
 
#endif
1191
 
    return succeeded_common(henv, hdbc, hstmt, ret, msgp);
1192
 
}
1193
 
 
1194
 
static int
1195
 
succeeded_nodata(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret,
1196
 
                 char **msgp, char *m, ...)
1197
 
{
1198
 
#ifdef TRACING
1199
 
    va_list args;
1200
 
 
1201
 
    if (tracing & 1) {
1202
 
        va_start(args, m);
1203
 
        fprintf(stderr, "SQLCall: ");
1204
 
        vfprintf(stderr, m, args);
1205
 
        va_end(args);
1206
 
        fprintf(stderr, "\n  > HENV=0x%lx, HDBC=0x%lx, HSTMT=0x%lx\n",
1207
 
                (long) henv, (long) hdbc, (long) hstmt);
1208
 
        trace_sql_ret(ret);
1209
 
    }
1210
 
#endif
1211
 
    if (ret == SQL_NO_DATA) {
1212
 
        CVAR_SET(Cobj, IDatatinfo, Qnil);
1213
 
        return 1;
1214
 
    }
1215
 
    return succeeded_common(henv, hdbc, hstmt, ret, msgp);
1216
 
}
1217
 
 
1218
 
/*
1219
 
 *----------------------------------------------------------------------
1220
 
 *
1221
 
 *      Return ENV from VALUE.
1222
 
 *
1223
 
 *----------------------------------------------------------------------
1224
 
 */
1225
 
 
1226
 
static VALUE
1227
 
env_of(VALUE self)
1228
 
{
1229
 
    if (rb_obj_is_kind_of(self, Cstmt) == Qtrue) {
1230
 
        STMT *q;
1231
 
 
1232
 
        Data_Get_Struct(self, STMT, q);
1233
 
        self = q->dbc;
1234
 
        if (self == Qnil) {
1235
 
            rb_raise(Cerror, set_err("Stale ODBC::Statement", 0));
1236
 
        }
1237
 
    }
1238
 
    if (rb_obj_is_kind_of(self, Cdbc) == Qtrue) {
1239
 
        DBC *p;
1240
 
 
1241
 
        Data_Get_Struct(self, DBC, p);
1242
 
        self = p->env;
1243
 
        if (self == Qnil) {
1244
 
            rb_raise(Cerror, set_err("Stale ODBC::Database", 0));
1245
 
        }
1246
 
    }
1247
 
    return self;
1248
 
}
1249
 
 
1250
 
static ENV *
1251
 
get_env(VALUE self)
1252
 
{
1253
 
    ENV *e;
1254
 
 
1255
 
    Data_Get_Struct(env_of(self), ENV, e);
1256
 
    return e;
1257
 
}
1258
 
 
1259
 
/*
1260
 
 *----------------------------------------------------------------------
1261
 
 *
1262
 
 *      Return DBC from VALUE.
1263
 
 *
1264
 
 *----------------------------------------------------------------------
1265
 
 */
1266
 
 
1267
 
static DBC *
1268
 
get_dbc(VALUE self)
1269
 
{
1270
 
    DBC *p;
1271
 
 
1272
 
    if (rb_obj_is_kind_of(self, Cstmt) == Qtrue) {
1273
 
        STMT *q;
1274
 
 
1275
 
        Data_Get_Struct(self, STMT, q);
1276
 
        self = q->dbc;
1277
 
        if (self == Qnil) {
1278
 
            rb_raise(Cerror, set_err("Stale ODBC::Statement", 0));
1279
 
        }
1280
 
    }
1281
 
    Data_Get_Struct(self, DBC, p);
1282
 
    return p;
1283
 
}
1284
 
 
1285
 
/*
1286
 
 *----------------------------------------------------------------------
1287
 
 *
1288
 
 *      Raise ODBC error from Ruby.
1289
 
 *
1290
 
 *----------------------------------------------------------------------
1291
 
 */
1292
 
 
1293
 
static VALUE
1294
 
dbc_raise(VALUE self, VALUE msg)
1295
 
{
1296
 
    VALUE a, v;
1297
 
    char buf[SQL_MAX_MESSAGE_LENGTH + 1], *p;
1298
 
 
1299
 
    if (TYPE(msg) == T_STRING) {
1300
 
        v = msg;
1301
 
    } else {
1302
 
        v = rb_any_to_s(msg);
1303
 
    }
1304
 
    strcpy(buf, "INTERN (1) [RubyODBC]");
1305
 
    p = STR2CSTR(v);
1306
 
    strncat(buf, p, SQL_MAX_MESSAGE_LENGTH - strlen(buf));
1307
 
    buf[SQL_MAX_MESSAGE_LENGTH] = '\0';
1308
 
    v = rb_str_new2(buf);
1309
 
    a = rb_ary_new2(1);
1310
 
    rb_ary_push(a, rb_obj_taint(v));
1311
 
    CVAR_SET(Cobj, IDataterror, a);
1312
 
    rb_raise(Cerror, "%s", buf);
1313
 
    return Qnil;
1314
 
}
1315
 
 
1316
 
/*
1317
 
 *----------------------------------------------------------------------
1318
 
 *
1319
 
 *      Obtain an ENV.
1320
 
 *
1321
 
 *----------------------------------------------------------------------
1322
 
 */
1323
 
 
1324
 
static VALUE
1325
 
env_new(VALUE self)
1326
 
{
1327
 
    ENV *e;
1328
 
    SQLHENV henv = SQL_NULL_HENV;
1329
 
    VALUE obj;
1330
 
 
1331
 
    if (TYPE(self) == T_MODULE) {
1332
 
        self = Cobj;
1333
 
    }
1334
 
    if (self == Cobj) {
1335
 
        self = Cenv;
1336
 
    }
1337
 
    if ((!SQL_SUCCEEDED(SQLAllocEnv(&henv))) || (henv == SQL_NULL_HENV)) {
1338
 
        rb_raise(Cerror, set_err("Cannot allocate SQLHENV", 0));
1339
 
    }
1340
 
    obj = Data_Make_Struct(self, ENV, NULL, free_env, e);
1341
 
    tracemsg(2, fprintf(stderr, "ObjAlloc: ENV %p\n", e););
1342
 
    e->self = obj;
1343
 
    e->henv = henv;
1344
 
    list_init(&e->dbcs, offsetof(DBC, link));
1345
 
#if defined(UNICODE) && defined(SQL_OV_ODBC3)
1346
 
    callsql(henv, SQL_NULL_HDBC, SQL_NULL_HSTMT,
1347
 
            SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
1348
 
                          (SQLPOINTER) SQL_OV_ODBC3, 0),
1349
 
            "SQLSetEnvAttr(SQL_OV_ODBC3)");
1350
 
#endif
1351
 
    return obj;
1352
 
}
1353
 
 
1354
 
/*
1355
 
 *----------------------------------------------------------------------
1356
 
 *
1357
 
 *      Obtain array of known DSNs.
1358
 
 *
1359
 
 *----------------------------------------------------------------------
1360
 
 */
1361
 
 
1362
 
static VALUE
1363
 
dbc_dsns(VALUE self)
1364
 
{
1365
 
#ifdef UNICODE
1366
 
    SQLWCHAR dsn[SQL_MAX_DSN_LENGTH], descr[SQL_MAX_MESSAGE_LENGTH * 2];
1367
 
#else
1368
 
    char dsn[SQL_MAX_DSN_LENGTH], descr[SQL_MAX_MESSAGE_LENGTH * 2];
1369
 
#endif
1370
 
    SQLSMALLINT dsnLen = 0, descrLen = 0;
1371
 
    int first = 1;
1372
 
    VALUE env, aret;
1373
 
    ENV *e;
1374
 
 
1375
 
    env = env_new(Cenv);
1376
 
    Data_Get_Struct(env, ENV, e);
1377
 
    aret = rb_ary_new();
1378
 
    while (succeeded(e->henv, SQL_NULL_HDBC, SQL_NULL_HSTMT,
1379
 
                     SQLDataSources(e->henv, (SQLUSMALLINT) (first ?
1380
 
                                    SQL_FETCH_FIRST : SQL_FETCH_NEXT),
1381
 
                                    (SQLTCHAR *) dsn,
1382
 
                                    (SQLSMALLINT) sizeof (dsn), &dsnLen,
1383
 
                                    (SQLTCHAR *) descr,
1384
 
                                    (SQLSMALLINT) sizeof (descr),
1385
 
                                    &descrLen),
1386
 
                     NULL, "SQLDataSources")) {
1387
 
        VALUE odsn = rb_obj_alloc(Cdsn);
1388
 
 
1389
 
#ifdef UNICODE
1390
 
        dsnLen = (dsnLen == 0) ? uc_strlen(dsn) : (dsnLen / sizeof (SQLWCHAR));
1391
 
        descrLen = (descrLen == 0) ?
1392
 
            uc_strlen(descr) : (descrLen / sizeof (SQLWCHAR));
1393
 
        rb_iv_set(odsn, "@name", uc_tainted_str_new(dsn, dsnLen));
1394
 
        rb_iv_set(odsn, "@descr", uc_tainted_str_new(descr, descrLen));
1395
 
#else
1396
 
        dsnLen = (dsnLen == 0) ? strlen(dsn) : dsnLen;
1397
 
        descrLen = (descrLen == 0) ? strlen(descr) : descrLen;
1398
 
        rb_iv_set(odsn, "@name", rb_tainted_str_new(dsn, dsnLen));
1399
 
        rb_iv_set(odsn, "@descr", rb_tainted_str_new(descr, descrLen));
1400
 
#endif
1401
 
        rb_ary_push(aret, odsn);
1402
 
        first = dsnLen = descrLen = 0;
1403
 
    }
1404
 
    return aret;
1405
 
}
1406
 
 
1407
 
/*
1408
 
 *----------------------------------------------------------------------
1409
 
 *
1410
 
 *      Obtain array of known drivers.
1411
 
 *
1412
 
 *----------------------------------------------------------------------
1413
 
 */
1414
 
 
1415
 
static VALUE
1416
 
dbc_drivers(VALUE self)
1417
 
{
1418
 
#ifdef UNICODE
1419
 
    SQLWCHAR driver[SQL_MAX_MESSAGE_LENGTH], attrs[SQL_MAX_MESSAGE_LENGTH * 2];
1420
 
    SQLWCHAR *attr;
1421
 
#else
1422
 
    char driver[SQL_MAX_MESSAGE_LENGTH], attrs[SQL_MAX_MESSAGE_LENGTH * 2];
1423
 
    char *attr;
1424
 
#endif
1425
 
    SQLSMALLINT driverLen = 0, attrsLen = 0;
1426
 
    int first = 1;
1427
 
    VALUE env, aret;
1428
 
    ENV *e;
1429
 
 
1430
 
    env = env_new(Cenv);
1431
 
    Data_Get_Struct(env, ENV, e);
1432
 
    aret = rb_ary_new();
1433
 
    while (succeeded(e->henv, SQL_NULL_HDBC, SQL_NULL_HSTMT,
1434
 
                     SQLDrivers(e->henv, (SQLUSMALLINT) (first ?
1435
 
                                SQL_FETCH_FIRST : SQL_FETCH_NEXT),
1436
 
                                (SQLTCHAR *) driver,
1437
 
                                (SQLSMALLINT) sizeof (driver), &driverLen,
1438
 
                                (SQLTCHAR *) attrs,
1439
 
                                (SQLSMALLINT) sizeof (attrs), &attrsLen),
1440
 
                     NULL, "SQLDrivers")) {
1441
 
        VALUE odrv = rb_obj_alloc(Cdrv);
1442
 
        VALUE h = rb_hash_new();
1443
 
        int count = 0;
1444
 
 
1445
 
#ifdef UNICODE
1446
 
        driverLen = (driverLen == 0) ?
1447
 
            uc_strlen(driver) : (driverLen / sizeof (SQLWCHAR));
1448
 
        rb_iv_set(odrv, "@name", uc_tainted_str_new(driver, driverLen));
1449
 
        for (attr = attrs; *attr; attr += uc_strlen(attr) + 1) {
1450
 
            SQLWCHAR *p = uc_strchr(attr, (SQLWCHAR) '=');
1451
 
 
1452
 
            if ((p != NULL) && (p != attr)) {
1453
 
                rb_hash_aset(h,
1454
 
                             uc_tainted_str_new(attr, (p - attr) /
1455
 
                                                 sizeof (SQLWCHAR)),
1456
 
                             uc_tainted_str_new2(p + 1));
1457
 
                count++;
1458
 
            }
1459
 
        }
1460
 
#else
1461
 
        driverLen = (driverLen == 0) ? strlen(driver) : driverLen;
1462
 
        rb_iv_set(odrv, "@name", rb_tainted_str_new(driver, driverLen));
1463
 
        for (attr = attrs; *attr; attr += strlen(attr) + 1) {
1464
 
            char *p = strchr(attr, '=');
1465
 
 
1466
 
            if ((p != NULL) && (p != attr)) {
1467
 
                rb_hash_aset(h, rb_tainted_str_new(attr, p - attr),
1468
 
                             rb_tainted_str_new2(p + 1));
1469
 
                count++;
1470
 
            }
1471
 
        }
1472
 
#endif
1473
 
        if (count > 0) {
1474
 
            rb_iv_set(odrv, "@attrs", h);
1475
 
        }
1476
 
        rb_ary_push(aret, odrv);
1477
 
        first = driverLen = attrsLen = 0;
1478
 
    }
1479
 
    return aret;
1480
 
}
1481
 
 
1482
 
/*
1483
 
 *----------------------------------------------------------------------
1484
 
 *
1485
 
 *      Management methods.
1486
 
 *
1487
 
 *----------------------------------------------------------------------
1488
 
 */
1489
 
 
1490
 
#ifdef HAVE_ODBCINST_H
1491
 
static VALUE
1492
 
conf_dsn(int argc, VALUE *argv, VALUE self, int op)
1493
 
{
1494
 
    VALUE drv, attr, issys, astr;
1495
 
#ifdef UNICODE
1496
 
#ifdef HAVE_SQLCONFIGDATASOURCEW
1497
 
    int have_w = 1;
1498
 
#else
1499
 
    int have_w = 0;
1500
 
#endif
1501
 
    SQLWCHAR *sdrv, *sastr;
1502
 
#else
1503
 
    char *sdrv, *sastr;
1504
 
#endif
1505
 
 
1506
 
    rb_scan_args(argc, argv, "12", &drv, &attr, &issys);
1507
 
    if (rb_obj_is_kind_of(drv, Cdrv) == Qtrue) {
1508
 
        VALUE a, x;
1509
 
 
1510
 
        if (argc > 2) {
1511
 
            rb_raise(rb_eArgError, "wrong # of arguments");
1512
 
        }
1513
 
        x = rb_iv_get(drv, "@name");
1514
 
        a = rb_iv_get(drv, "@attrs");
1515
 
        issys = attr;
1516
 
        drv = x;
1517
 
        attr = a;
1518
 
    }
1519
 
    Check_Type(drv, T_STRING);
1520
 
    if (RTEST(issys)) {
1521
 
        switch (op) {
1522
 
        case ODBC_ADD_DSN:      op = ODBC_ADD_SYS_DSN; break;
1523
 
        case ODBC_CONFIG_DSN:   op = ODBC_CONFIG_SYS_DSN; break;
1524
 
        case ODBC_REMOVE_DSN:   op = ODBC_REMOVE_SYS_DSN; break;
1525
 
        }
1526
 
    }
1527
 
    astr = rb_str_new2("");
1528
 
    if (rb_obj_is_kind_of(attr, rb_cHash) == Qtrue) {
1529
 
        VALUE a, x;
1530
 
 
1531
 
        a = rb_funcall(attr, IDkeys, 0, NULL);
1532
 
        while ((x = rb_ary_shift(a)) != Qnil) {
1533
 
            VALUE v = rb_hash_aref(attr, x);
1534
 
 
1535
 
            astr = rb_str_concat(astr, x);
1536
 
            astr = rb_str_cat2(astr, "=");
1537
 
            astr = rb_str_concat(astr, v);
1538
 
            astr = rb_str_cat(astr, "", 1);
1539
 
        }
1540
 
    }
1541
 
    astr = rb_str_cat(astr, "", 1);
1542
 
#ifdef UNICODE
1543
 
#ifdef USE_DLOPEN_FOR_ODBC_LIBS
1544
 
    have_w = ruby_odbc_have_func("SQLConfigDataSourceW", SQLConfigDataSourceW);
1545
 
#endif
1546
 
    if (have_w) {
1547
 
        sdrv = uc_from_utf((unsigned char *) STR2CSTR(drv), -1);
1548
 
        sastr = uc_from_utf((unsigned char *) STR2CSTR(astr), -1);
1549
 
        if ((sdrv == NULL) || (sastr == NULL)) {
1550
 
            uc_free(sdrv);
1551
 
            uc_free(sastr);
1552
 
            rb_raise(Cerror, set_err("Out of memory", 0));
1553
 
        }
1554
 
        if (SQLConfigDataSourceW(NULL, (WORD) op,
1555
 
                                 (LPWSTR) sdrv, (LPWSTR) sastr)) {
1556
 
            uc_free(sdrv);
1557
 
            uc_free(sastr);
1558
 
            return Qnil;
1559
 
        }
1560
 
        uc_free(sdrv);
1561
 
        uc_free(sastr);
1562
 
    } else {
1563
 
        sdrv = (SQLWCHAR *) STR2CSTR(drv);
1564
 
        sastr = (SQLWCHAR *) STR2CSTR(astr);
1565
 
        if (SQLConfigDataSource(NULL, (WORD) op,
1566
 
                                (LPCSTR) sdrv, (LPCSTR) sastr)) {
1567
 
            return Qnil;
1568
 
        }
1569
 
    }
1570
 
#else
1571
 
    sdrv = STR2CSTR(drv);
1572
 
    sastr = STR2CSTR(astr);
1573
 
    if (SQLConfigDataSource(NULL, (WORD) op, sdrv, sastr)) {
1574
 
        return Qnil;
1575
 
    }
1576
 
#endif
1577
 
#if defined(HAVE_SQLINSTALLERERROR) || (defined(UNICODE) && defined(HAVE_SQLINSTALLERERRORW))
1578
 
    rb_raise(Cerror, set_err(get_installer_err(), 0));
1579
 
#else
1580
 
    rb_raise(Cerror, set_err("DSN configuration error", 0));
1581
 
#endif
1582
 
    return Qnil;
1583
 
}
1584
 
#endif
1585
 
 
1586
 
static VALUE
1587
 
dbc_adddsn(int argc, VALUE *argv, VALUE self)
1588
 
{
1589
 
#ifdef HAVE_ODBCINST_H
1590
 
    return conf_dsn(argc, argv, self, ODBC_ADD_DSN);
1591
 
#else
1592
 
    rb_raise(Cerror, set_err("ODBC::add_dsn not supported", 0));
1593
 
    return Qnil;
1594
 
#endif
1595
 
}
1596
 
 
1597
 
static VALUE
1598
 
dbc_confdsn(int argc, VALUE *argv, VALUE self)
1599
 
{
1600
 
#ifdef HAVE_ODBCINST_H
1601
 
    return conf_dsn(argc, argv, self, ODBC_CONFIG_DSN);
1602
 
#else
1603
 
    rb_raise(Cerror, set_err("ODBC::config_dsn not supported", 0));
1604
 
    return Qnil;
1605
 
#endif
1606
 
}
1607
 
 
1608
 
static VALUE
1609
 
dbc_deldsn(int argc, VALUE *argv, VALUE self)
1610
 
{
1611
 
#ifdef HAVE_ODBCINST_H
1612
 
    return conf_dsn(argc, argv, self, ODBC_REMOVE_DSN);
1613
 
#else
1614
 
    rb_raise(Cerror, set_err("ODBC::del_dsn not supported", 0));
1615
 
    return Qnil;
1616
 
#endif
1617
 
}
1618
 
 
1619
 
static VALUE
1620
 
dbc_wfdsn(int argc, VALUE *argv, VALUE self)
1621
 
{
1622
 
#ifdef HAVE_ODBCINST_H
1623
 
    VALUE fname, aname, kname, val;
1624
 
#ifdef UNICODE
1625
 
#ifdef HAVE_SQLWRITEFILEDSNW
1626
 
    int have_w = 1;
1627
 
#else
1628
 
    int have_w = 0;
1629
 
#endif
1630
 
    SQLWCHAR *sfname, *saname, *skname, *sval = NULL;
1631
 
#else
1632
 
    char *sfname, *saname, *skname, *sval = NULL;
1633
 
#endif
1634
 
 
1635
 
    rb_scan_args(argc, argv, "31", &fname, &aname, &kname, &val);
1636
 
    Check_Type(fname, T_STRING);
1637
 
    Check_Type(aname, T_STRING);
1638
 
    Check_Type(kname, T_STRING);
1639
 
    if (val != Qnil) {
1640
 
        Check_Type(val, T_STRING);
1641
 
    }
1642
 
#ifdef UNICODE
1643
 
#ifdef USE_DLOPEN_FOR_ODBC_LIBS
1644
 
    have_w = ruby_odbc_have_func("SQLWriteFileDSNW", SQLWriteFileDSNW);
1645
 
#endif
1646
 
    if (have_w) {
1647
 
        BOOL rc;
1648
 
 
1649
 
        sfname = uc_from_utf((unsigned char *) STR2CSTR(fname), -1);
1650
 
        saname = uc_from_utf((unsigned char *) STR2CSTR(aname), -1);
1651
 
        skname = uc_from_utf((unsigned char *) STR2CSTR(kname), -1);
1652
 
        if ((sfname == NULL) || (saname == NULL) || (skname == NULL)) {
1653
 
nomem:
1654
 
            uc_free(sfname);
1655
 
            uc_free(saname);
1656
 
            uc_free(skname);
1657
 
            rb_raise(Cerror, set_err("Out of memory", 0));
1658
 
        }
1659
 
        if (val != Qnil) {
1660
 
            sval = uc_from_utf((unsigned char *) STR2CSTR(val), -1);
1661
 
            if (sval == NULL) {
1662
 
                goto nomem;
1663
 
            }
1664
 
        }
1665
 
        rc = SQLWriteFileDSNW(sfname, saname, skname, sval);
1666
 
        uc_free(sfname);
1667
 
        uc_free(saname);
1668
 
        uc_free(skname);
1669
 
        uc_free(sval);
1670
 
        if (rc) {
1671
 
            return Qnil;
1672
 
        }
1673
 
    } else {
1674
 
        sfname = (SQLWCHAR *) STR2CSTR(fname);
1675
 
        saname = (SQLWCHAR *) STR2CSTR(aname);
1676
 
        skname = (SQLWCHAR *) STR2CSTR(kname);
1677
 
        if (val != Qnil) {
1678
 
            sval = (SQLWCHAR *) STR2CSTR(val);
1679
 
        }
1680
 
        if (SQLWriteFileDSN((LPCSTR) sfname, (LPCSTR) saname,
1681
 
                            (LPCSTR) skname, (LPCSTR) sval)) {
1682
 
            return Qnil;
1683
 
        }
1684
 
    }
1685
 
#else
1686
 
    sfname = STR2CSTR(fname);
1687
 
    saname = STR2CSTR(aname);
1688
 
    skname = STR2CSTR(kname);
1689
 
    if (val != Qnil) {
1690
 
        sval = STR2CSTR(val);
1691
 
    }
1692
 
    if (SQLWriteFileDSN(sfname, saname, skname, sval)) {
1693
 
        return Qnil;
1694
 
    }
1695
 
#endif
1696
 
#if defined(HAVE_SQLINSTALLERERROR) || (defined(UNICODE) && defined(HAVE_SQLINSTALLERERRORW))
1697
 
    rb_raise(Cerror, set_err(get_installer_err(), 0));
1698
 
#else
1699
 
    rb_raise(Cerror, set_err("File DSN configuration error", 0));
1700
 
#endif
1701
 
#else
1702
 
    rb_raise(Cerror, set_err("ODBC::write_file_dsn not supported", 0));
1703
 
#endif
1704
 
    return Qnil;
1705
 
}
1706
 
 
1707
 
static VALUE
1708
 
dbc_rfdsn(int argc, VALUE *argv, VALUE self)
1709
 
{
1710
 
#ifdef HAVE_ODBCINST_H
1711
 
    VALUE fname, aname, kname;
1712
 
#ifdef UNICODE
1713
 
#ifdef HAVE_SQLREADFILEDSNW
1714
 
    int have_w = 1;
1715
 
#else
1716
 
    int have_w = 0;
1717
 
#endif
1718
 
    SQLWCHAR *sfname, *saname, *skname, valbuf[SQL_MAX_MESSAGE_LENGTH];
1719
 
#else
1720
 
    char *sfname, *saname, *skname, valbuf[SQL_MAX_MESSAGE_LENGTH];
1721
 
#endif
1722
 
 
1723
 
    rb_scan_args(argc, argv, "30", &fname, &aname, &kname);
1724
 
    Check_Type(fname, T_STRING);
1725
 
    Check_Type(aname, T_STRING);
1726
 
    Check_Type(kname, T_STRING);
1727
 
#ifdef UNICODE
1728
 
#ifdef USE_DLOPEN_FOR_ODBC_LIBS
1729
 
    have_w = ruby_odbc_have_func("SQLReadFileDSNW", SQLReadFileDSNW);
1730
 
#endif
1731
 
    if (have_w) {
1732
 
        BOOL rc;
1733
 
 
1734
 
        sfname = uc_from_utf((unsigned char *) STR2CSTR(fname), -1);
1735
 
        saname = uc_from_utf((unsigned char *) STR2CSTR(aname), -1);
1736
 
        skname = uc_from_utf((unsigned char *) STR2CSTR(kname), -1);
1737
 
        valbuf[0] = 0;
1738
 
        if ((sfname == NULL) || (saname == NULL) || (skname == NULL)) {
1739
 
            uc_free(sfname);
1740
 
            uc_free(saname);
1741
 
            uc_free(skname);
1742
 
            rb_raise(Cerror, set_err("Out of memory", 0));
1743
 
        }
1744
 
        rc = SQLReadFileDSNW(sfname, saname, skname, valbuf,
1745
 
                             sizeof (valbuf), NULL);
1746
 
        uc_free(sfname);
1747
 
        uc_free(saname);
1748
 
        uc_free(skname);
1749
 
        if (rc) {
1750
 
            return uc_tainted_str_new2(valbuf);
1751
 
        }
1752
 
    } else {
1753
 
        sfname = (SQLWCHAR *) STR2CSTR(fname);
1754
 
        saname = (SQLWCHAR *) STR2CSTR(aname);
1755
 
        skname = (SQLWCHAR *) STR2CSTR(kname);
1756
 
        valbuf[0] = '\0';
1757
 
        if (SQLReadFileDSN((LPCSTR) sfname, (LPCSTR) saname,
1758
 
                           (LPCSTR) skname, (LPSTR) valbuf,
1759
 
                           sizeof (valbuf), NULL)) {
1760
 
            return rb_tainted_str_new2((char *) valbuf);
1761
 
        }
1762
 
    }
1763
 
#else
1764
 
    sfname = STR2CSTR(fname);
1765
 
    saname = STR2CSTR(aname);
1766
 
    skname = STR2CSTR(kname);
1767
 
    valbuf[0] = '\0';
1768
 
    if (SQLReadFileDSN(sfname, saname, skname, valbuf,
1769
 
                       sizeof (valbuf), NULL)) {
1770
 
        return rb_tainted_str_new2(valbuf);
1771
 
    }
1772
 
#endif
1773
 
#if defined(HAVE_SQLINSTALLERERROR) || (defined(UNICODE) && defined(HAVE_SQLINSTALLERERRORW))
1774
 
    rb_raise(Cerror, set_err(get_installer_err(), 0));
1775
 
#else
1776
 
    rb_raise(Cerror, set_err("File DSN configuration error", 0));
1777
 
#endif
1778
 
#else
1779
 
    rb_raise(Cerror, set_err("ODBC::read_file_dsn not supported", 0));
1780
 
    return Qnil;
1781
 
#endif
1782
 
}
1783
 
 
1784
 
/*
1785
 
 *----------------------------------------------------------------------
1786
 
 *
1787
 
 *      Return last ODBC error or warning.
1788
 
 *
1789
 
 *----------------------------------------------------------------------
1790
 
 */
1791
 
 
1792
 
static VALUE
1793
 
dbc_error(VALUE self)
1794
 
{
1795
 
    return rb_cvar_get(Cobj, IDataterror);
1796
 
}
1797
 
 
1798
 
static VALUE
1799
 
dbc_warn(VALUE self)
1800
 
{
1801
 
    return rb_cvar_get(Cobj, IDatatinfo);
1802
 
}
1803
 
 
1804
 
static VALUE
1805
 
dbc_clrerror(VALUE self)
1806
 
{
1807
 
    CVAR_SET(Cobj, IDataterror, Qnil);
1808
 
    CVAR_SET(Cobj, IDatatinfo, Qnil);
1809
 
    return Qnil;
1810
 
}
1811
 
 
1812
 
/*
1813
 
 *----------------------------------------------------------------------
1814
 
 *
1815
 
 *      Connection instance initializer.
1816
 
 *
1817
 
 *----------------------------------------------------------------------
1818
 
 */
1819
 
 
1820
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
1821
 
static VALUE
1822
 
dbc_alloc(VALUE self)
1823
 
{
1824
 
    DBC *p;
1825
 
    VALUE obj = Data_Make_Struct(self, DBC, mark_dbc, free_dbc, p);
1826
 
 
1827
 
    tracemsg(2, fprintf(stderr, "ObjAlloc: DBC %p\n", p););
1828
 
    list_init(&p->link, offsetof(DBC, link));
1829
 
    p->self = obj;
1830
 
    p->env = Qnil;
1831
 
    p->envp = NULL;
1832
 
    list_init(&p->stmts, offsetof(STMT, link));
1833
 
    p->hdbc = SQL_NULL_HDBC;
1834
 
    return obj;
1835
 
}
1836
 
#endif
1837
 
 
1838
 
static VALUE
1839
 
dbc_new(int argc, VALUE *argv, VALUE self)
1840
 
{
1841
 
    DBC *p;
1842
 
    VALUE obj, env = Qnil;
1843
 
 
1844
 
    if (TYPE(self) == T_MODULE) {
1845
 
        self = Cobj;
1846
 
    }
1847
 
    if (self == Cobj) {
1848
 
        self = Cdbc;
1849
 
    }
1850
 
    if (rb_obj_is_kind_of(self, Cenv) == Qtrue) {
1851
 
        env = env_of(self);
1852
 
        self = Cdbc;
1853
 
    }
1854
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
1855
 
    obj = rb_obj_alloc(Cdbc);
1856
 
    Data_Get_Struct(obj, DBC, p);
1857
 
    p->env = env;
1858
 
#else
1859
 
    obj = Data_Make_Struct(self, DBC, mark_dbc, free_dbc, p);
1860
 
    tracemsg(2, fprintf(stderr, "ObjAlloc: DBC %p\n", p););
1861
 
    list_init(&p->link, offsetof(DBC, link));
1862
 
    p->self = obj;
1863
 
    p->env = env;
1864
 
    p->envp = NULL;
1865
 
    list_init(&p->stmts, offsetof(STMT, link));
1866
 
    p->hdbc = SQL_NULL_HDBC;
1867
 
    p->upc = 0;
1868
 
#endif
1869
 
    if (env != Qnil) {
1870
 
        ENV *e;
1871
 
 
1872
 
        Data_Get_Struct(env, ENV, e);
1873
 
        link_dbc(p, e);
1874
 
    }
1875
 
    if (argc > 0) {
1876
 
        rb_obj_call_init(obj, argc, argv);
1877
 
    }
1878
 
    return obj;
1879
 
}
1880
 
 
1881
 
/*
1882
 
 *----------------------------------------------------------------------
1883
 
 *
1884
 
 *      Connect to data source.
1885
 
 *
1886
 
 *----------------------------------------------------------------------
1887
 
 */
1888
 
 
1889
 
static VALUE
1890
 
dbc_connect(int argc, VALUE *argv, VALUE self)
1891
 
{
1892
 
    ENV *e;
1893
 
    DBC *p;
1894
 
    VALUE dsn, user, passwd;
1895
 
#ifdef UNICODE
1896
 
    SQLWCHAR *sdsn = NULL, *suser = NULL, *spasswd = NULL;
1897
 
#else
1898
 
    char *sdsn, *suser = NULL, *spasswd = NULL;
1899
 
#endif
1900
 
    char *msg;
1901
 
    SQLHDBC dbc;
1902
 
 
1903
 
    rb_scan_args(argc, argv, "03", &dsn, &user, &passwd);
1904
 
    if (dsn != Qnil) {
1905
 
        if (rb_obj_is_kind_of(dsn, Cdsn) == Qtrue) {
1906
 
            dsn = rb_iv_get(dsn, "@name");
1907
 
        }
1908
 
        Check_Type(dsn, T_STRING);
1909
 
    }
1910
 
    if (user != Qnil) {
1911
 
        Check_Type(user, T_STRING);
1912
 
    }
1913
 
    if (passwd != Qnil) {
1914
 
        Check_Type(passwd, T_STRING);
1915
 
    }
1916
 
    p = get_dbc(self);
1917
 
    if (p->hdbc != SQL_NULL_HDBC) {
1918
 
        rb_raise(Cerror, set_err("Already connected", 0));
1919
 
    }
1920
 
    if (p->env == Qnil) {
1921
 
        p->env = env_new(Cenv);
1922
 
        e = get_env(p->env);
1923
 
        link_dbc(p, e);
1924
 
    } else {
1925
 
        e = get_env(p->env);
1926
 
    }
1927
 
    if (dsn == Qnil) {
1928
 
        return self;
1929
 
    }
1930
 
#ifdef UNICODE
1931
 
    if (user != Qnil) {
1932
 
        suser = uc_from_utf((unsigned char *) STR2CSTR(user), -1);
1933
 
    }
1934
 
    if (passwd != Qnil) {
1935
 
        spasswd = uc_from_utf((unsigned char *) STR2CSTR(passwd), -1);
1936
 
    }
1937
 
    sdsn = uc_from_utf((unsigned char *) STR2CSTR(dsn), -1);
1938
 
    if (((suser == NULL) && (user != Qnil)) ||
1939
 
        ((spasswd == NULL) && (passwd != Qnil)) ||
1940
 
        (sdsn == NULL)) {
1941
 
        uc_free(sdsn);
1942
 
        uc_free(suser);
1943
 
        uc_free(spasswd);
1944
 
        rb_raise(Cerror, set_err("Out of memory", 0));
1945
 
    }
1946
 
#else
1947
 
    if (user != Qnil) {
1948
 
        suser = STR2CSTR(user);
1949
 
    }
1950
 
    if (passwd != Qnil) {
1951
 
        spasswd = STR2CSTR(passwd);
1952
 
    }
1953
 
    sdsn = STR2CSTR(dsn);
1954
 
#endif
1955
 
    if (!succeeded(e->henv, SQL_NULL_HDBC, SQL_NULL_HSTMT,
1956
 
                   SQLAllocConnect(e->henv, &dbc), &msg, "SQLAllocConnect")) {
1957
 
#ifdef UNICODE
1958
 
        uc_free(sdsn);
1959
 
        uc_free(suser);
1960
 
        uc_free(spasswd);
1961
 
#endif
1962
 
        rb_raise(Cerror, "%s", msg);
1963
 
    }
1964
 
    if (!succeeded(SQL_NULL_HENV, dbc, SQL_NULL_HSTMT,
1965
 
                   SQLConnect(dbc, (SQLTCHAR *) sdsn, SQL_NTS,
1966
 
                              (SQLTCHAR *) suser,
1967
 
                              (SQLSMALLINT) (suser ? SQL_NTS : 0),
1968
 
                              (SQLTCHAR *) spasswd,
1969
 
                              (SQLSMALLINT) (spasswd ? SQL_NTS : 0)),
1970
 
                   &msg,
1971
 
                   "SQLConnect('%s')", sdsn)) {
1972
 
#ifdef UNICODE
1973
 
        uc_free(sdsn);
1974
 
        uc_free(suser);
1975
 
        uc_free(spasswd);
1976
 
#endif
1977
 
        callsql(SQL_NULL_HENV, dbc, SQL_NULL_HSTMT,
1978
 
                SQLFreeConnect(dbc), "SQLFreeConnect");
1979
 
        rb_raise(Cerror, "%s", msg);
1980
 
    }
1981
 
#ifdef UNICODE
1982
 
    uc_free(sdsn);
1983
 
    uc_free(suser);
1984
 
    uc_free(spasswd);
1985
 
#endif
1986
 
    p->hdbc = dbc;
1987
 
    return self;
1988
 
}
1989
 
 
1990
 
static VALUE
1991
 
dbc_drvconnect(VALUE self, VALUE drv)
1992
 
{
1993
 
    ENV *e;
1994
 
    DBC *p;
1995
 
#ifdef UNICODE
1996
 
    SQLWCHAR *sdrv;
1997
 
#else
1998
 
    char *sdrv;
1999
 
#endif
2000
 
    char *msg;
2001
 
    SQLHDBC dbc;
2002
 
 
2003
 
    if (rb_obj_is_kind_of(drv, Cdrv) == Qtrue) {
2004
 
        VALUE d, a, x;
2005
 
 
2006
 
        d = rb_str_new2("");
2007
 
        a = rb_funcall(rb_iv_get(drv, "@attrs"), IDkeys, 0, NULL);
2008
 
        while ((x = rb_ary_shift(a)) != Qnil) {
2009
 
            VALUE v = rb_hash_aref(rb_iv_get(drv, "@attrs"), x);
2010
 
 
2011
 
            d = rb_str_concat(d, x);
2012
 
            d = rb_str_cat2(d, "=");
2013
 
            d = rb_str_concat(d, v);
2014
 
            d = rb_str_cat2(d, ";");
2015
 
        }
2016
 
        drv = d;
2017
 
    }
2018
 
    Check_Type(drv, T_STRING);
2019
 
    p = get_dbc(self);
2020
 
    if (p->hdbc != SQL_NULL_HDBC) {
2021
 
        rb_raise(Cerror, set_err("Already connected", 0));
2022
 
    }
2023
 
    if (p->env == Qnil) {
2024
 
        p->env = env_new(Cenv);
2025
 
        e = get_env(p->env);
2026
 
        link_dbc(p, e);
2027
 
    } else {
2028
 
        e = get_env(p->env);
2029
 
    }
2030
 
#ifdef UNICODE
2031
 
    sdrv = uc_from_utf((unsigned char *) STR2CSTR(drv), -1);
2032
 
    if (sdrv == NULL) {
2033
 
        rb_raise(Cerror, set_err("Out of memory", 0));
2034
 
    }
2035
 
#else
2036
 
    sdrv = STR2CSTR(drv);
2037
 
#endif
2038
 
    if (!succeeded(e->henv, SQL_NULL_HDBC, SQL_NULL_HSTMT,
2039
 
                   SQLAllocConnect(e->henv, &dbc), &msg, "SQLAllocConnect")) {
2040
 
#ifdef UNICODE
2041
 
        uc_free(sdrv);
2042
 
#endif
2043
 
        rb_raise(Cerror, "%s", msg);
2044
 
    }
2045
 
    if (!succeeded(e->henv, dbc, SQL_NULL_HSTMT,
2046
 
                   SQLDriverConnect(dbc, NULL, (SQLTCHAR *) sdrv, SQL_NTS,
2047
 
                                    NULL, 0, NULL, SQL_DRIVER_NOPROMPT),
2048
 
                   &msg, "SQLDriverConnect")) {
2049
 
#ifdef UNICODE
2050
 
        uc_free(sdrv);
2051
 
#endif
2052
 
        callsql(SQL_NULL_HENV, dbc, SQL_NULL_HSTMT,
2053
 
                SQLFreeConnect(dbc), "SQLFreeConnect");
2054
 
        rb_raise(Cerror, "%s", msg);
2055
 
    }
2056
 
#ifdef UNICODE
2057
 
    uc_free(sdrv);
2058
 
#endif
2059
 
    p->hdbc = dbc;
2060
 
    return self;
2061
 
}
2062
 
 
2063
 
static VALUE
2064
 
dbc_connected(VALUE self)
2065
 
{
2066
 
    DBC *p = get_dbc(self);
2067
 
 
2068
 
    return (p->hdbc == SQL_NULL_HDBC) ? Qfalse : Qtrue;
2069
 
}
2070
 
 
2071
 
/*
2072
 
 *----------------------------------------------------------------------
2073
 
 *
2074
 
 *      Drop all active statements from data source.
2075
 
 *
2076
 
 *----------------------------------------------------------------------
2077
 
 */
2078
 
 
2079
 
static VALUE
2080
 
dbc_dropall(VALUE self)
2081
 
{
2082
 
    DBC *p = get_dbc(self);
2083
 
 
2084
 
    while (!list_empty(&p->stmts)) {
2085
 
        STMT *q = list_first(&p->stmts);
2086
 
 
2087
 
        if (q->self == Qnil) {
2088
 
            rb_fatal("RubyODBC: invalid stmt in dropall");
2089
 
        }
2090
 
        stmt_drop(q->self);
2091
 
    }
2092
 
    return self;
2093
 
}
2094
 
 
2095
 
/*
2096
 
 *----------------------------------------------------------------------
2097
 
 *
2098
 
 *      Disconnect from data source.
2099
 
 *
2100
 
 *----------------------------------------------------------------------
2101
 
 */
2102
 
 
2103
 
static VALUE
2104
 
dbc_disconnect(int argc, VALUE *argv, VALUE self)
2105
 
{
2106
 
    DBC *p = get_dbc(self);
2107
 
    VALUE nodrop = Qfalse;
2108
 
    char *msg;
2109
 
 
2110
 
    rb_scan_args(argc, argv, "01", &nodrop);
2111
 
    if (!RTEST(nodrop)) {
2112
 
        dbc_dropall(self);
2113
 
    }
2114
 
    if (p->hdbc == SQL_NULL_HDBC) {
2115
 
        return Qtrue;
2116
 
    }
2117
 
    if (list_empty(&p->stmts)) {
2118
 
        callsql(SQL_NULL_HENV, p->hdbc, SQL_NULL_HSTMT,
2119
 
                SQLDisconnect(p->hdbc), "SQLDisconnect");
2120
 
        if (!succeeded(SQL_NULL_HENV, p->hdbc, SQL_NULL_HSTMT,
2121
 
                       SQLFreeConnect(p->hdbc), &msg, "SQLFreeConnect")) {
2122
 
            rb_raise(Cerror, "%s", msg);
2123
 
        }
2124
 
        p->hdbc = SQL_NULL_HDBC;
2125
 
        unlink_dbc(p);
2126
 
        start_gc();
2127
 
        return Qtrue;
2128
 
    }
2129
 
    return Qfalse;
2130
 
}
2131
 
 
2132
 
/*
2133
 
 *----------------------------------------------------------------------
2134
 
 *
2135
 
 *      Database meta data via SQLGetInfo()
2136
 
 *
2137
 
 *----------------------------------------------------------------------
2138
 
 */
2139
 
 
2140
 
#define GI_CONST_SINT(x) { #x, x, SQL_C_SHORT }
2141
 
#define GI_CONST_INT(x)  { #x, x, SQL_C_LONG }
2142
 
#define GI_CONST_BITS(x) { #x, x, SQL_C_LONG }
2143
 
#define GI_CONST_STR(x)  { #x, x, SQL_C_CHAR }
2144
 
#define GI_CONST_END     { NULL, -1, -1 }
2145
 
static struct {
2146
 
    const char *name;
2147
 
    int info;
2148
 
    int maptype;
2149
 
} get_info_map[] = {
2150
 
 
2151
 
    /* yielding ints */
2152
 
    GI_CONST_SINT(SQL_ACTIVE_ENVIRONMENTS),
2153
 
    GI_CONST_SINT(SQL_ACTIVE_CONNECTIONS),
2154
 
    GI_CONST_SINT(SQL_ACTIVE_STATEMENTS),
2155
 
    GI_CONST_INT(SQL_ASYNC_MODE),
2156
 
    GI_CONST_SINT(SQL_CATALOG_LOCATION),
2157
 
    GI_CONST_SINT(SQL_CONCAT_NULL_BEHAVIOR),
2158
 
    GI_CONST_SINT(SQL_CORRELATION_NAME),
2159
 
    GI_CONST_SINT(SQL_CURSOR_COMMIT_BEHAVIOR),
2160
 
    GI_CONST_SINT(SQL_CURSOR_ROLLBACK_BEHAVIOR),
2161
 
    GI_CONST_INT(SQL_CURSOR_SENSITIVITY),
2162
 
    GI_CONST_INT(SQL_DDL_INDEX),
2163
 
    GI_CONST_INT(SQL_DEFAULT_TXN_ISOLATION),
2164
 
    GI_CONST_INT(SQL_DRIVER_HDBC),
2165
 
    GI_CONST_INT(SQL_DRIVER_HENV),
2166
 
    GI_CONST_INT(SQL_DRIVER_HDESC),
2167
 
    GI_CONST_INT(SQL_DRIVER_HLIB),
2168
 
    GI_CONST_INT(SQL_DRIVER_HSTMT),
2169
 
    GI_CONST_SINT(SQL_FILE_USAGE),
2170
 
    GI_CONST_SINT(SQL_GROUP_BY),
2171
 
    GI_CONST_SINT(SQL_IDENTIFIER_CASE),
2172
 
    GI_CONST_INT(SQL_MAX_ASYNC_CONCURRENT_STATEMENTS),
2173
 
    GI_CONST_INT(SQL_MAX_BINARY_LITERAL_LEN),
2174
 
    GI_CONST_SINT(SQL_MAX_CATALOG_NAME_LEN),
2175
 
    GI_CONST_INT(SQL_MAX_CHAR_LITERAL_LEN),
2176
 
    GI_CONST_SINT(SQL_MAX_COLUMN_NAME_LEN),
2177
 
    GI_CONST_SINT(SQL_MAX_COLUMNS_IN_GROUP_BY),
2178
 
    GI_CONST_SINT(SQL_MAX_COLUMNS_IN_INDEX),
2179
 
    GI_CONST_SINT(SQL_MAX_COLUMNS_IN_ORDER_BY),
2180
 
    GI_CONST_SINT(SQL_MAX_COLUMNS_IN_SELECT),
2181
 
    GI_CONST_SINT(SQL_MAX_COLUMNS_IN_TABLE),
2182
 
    GI_CONST_SINT(SQL_MAX_CONCURRENT_ACTIVITIES),
2183
 
    GI_CONST_SINT(SQL_MAX_CURSOR_NAME_LEN),
2184
 
    GI_CONST_SINT(SQL_MAX_DRIVER_CONNECTIONS),
2185
 
    GI_CONST_SINT(SQL_MAX_IDENTIFIER_LEN),
2186
 
    GI_CONST_INT(SQL_MAX_INDEX_SIZE),
2187
 
    GI_CONST_SINT(SQL_MAX_OWNER_NAME_LEN),
2188
 
    GI_CONST_SINT(SQL_MAX_PROCEDURE_NAME_LEN),
2189
 
    GI_CONST_SINT(SQL_MAX_QUALIFIER_NAME_LEN),
2190
 
    GI_CONST_INT(SQL_MAX_ROW_SIZE),
2191
 
    GI_CONST_SINT(SQL_MAX_SCHEMA_NAME_LEN),
2192
 
    GI_CONST_INT(SQL_MAX_STATEMENT_LEN),
2193
 
    GI_CONST_SINT(SQL_MAX_TABLE_NAME_LEN),
2194
 
    GI_CONST_SINT(SQL_MAX_TABLES_IN_SELECT),
2195
 
    GI_CONST_SINT(SQL_MAX_USER_NAME_LEN),
2196
 
    GI_CONST_SINT(SQL_NON_NULLABLE_COLUMNS),
2197
 
    GI_CONST_SINT(SQL_NULL_COLLATION),
2198
 
    GI_CONST_SINT(SQL_ODBC_API_CONFORMANCE),
2199
 
    GI_CONST_INT(SQL_ODBC_INTERFACE_CONFORMANCE),
2200
 
    GI_CONST_SINT(SQL_ODBC_SAG_CLI_CONFORMANCE),
2201
 
    GI_CONST_SINT(SQL_ODBC_SQL_CONFORMANCE),
2202
 
    GI_CONST_INT(SQL_PARAM_ARRAY_ROW_COUNTS),
2203
 
    GI_CONST_INT(SQL_PARAM_ARRAY_SELECTS),
2204
 
    GI_CONST_SINT(SQL_QUALIFIER_LOCATION),
2205
 
    GI_CONST_SINT(SQL_QUOTED_IDENTIFIER_CASE),
2206
 
    GI_CONST_INT(SQL_SQL_CONFORMANCE),
2207
 
    GI_CONST_SINT(SQL_TXN_CAPABLE),
2208
 
 
2209
 
    /* yielding ints (but bitmasks) */
2210
 
    GI_CONST_BITS(SQL_AGGREGATE_FUNCTIONS),
2211
 
    GI_CONST_BITS(SQL_ALTER_DOMAIN),
2212
 
    GI_CONST_BITS(SQL_ALTER_TABLE),
2213
 
    GI_CONST_BITS(SQL_BATCH_ROW_COUNT),
2214
 
    GI_CONST_BITS(SQL_BATCH_SUPPORT),
2215
 
    GI_CONST_BITS(SQL_BOOKMARK_PERSISTENCE),
2216
 
    GI_CONST_BITS(SQL_CATALOG_USAGE),
2217
 
    GI_CONST_BITS(SQL_CONVERT_BINARY),
2218
 
    GI_CONST_BITS(SQL_CONVERT_BIT),
2219
 
    GI_CONST_BITS(SQL_CONVERT_CHAR),
2220
 
#ifdef SQL_CONVERT_GUID
2221
 
    GI_CONST_BITS(SQL_CONVERT_GUID),
2222
 
#endif
2223
 
    GI_CONST_BITS(SQL_CONVERT_DATE),
2224
 
    GI_CONST_BITS(SQL_CONVERT_DECIMAL),
2225
 
    GI_CONST_BITS(SQL_CONVERT_DOUBLE),
2226
 
    GI_CONST_BITS(SQL_CONVERT_FLOAT),
2227
 
    GI_CONST_BITS(SQL_CONVERT_FUNCTIONS),
2228
 
    GI_CONST_BITS(SQL_CONVERT_INTEGER),
2229
 
    GI_CONST_BITS(SQL_CONVERT_INTERVAL_YEAR_MONTH),
2230
 
    GI_CONST_BITS(SQL_CONVERT_INTERVAL_DAY_TIME),
2231
 
    GI_CONST_BITS(SQL_CONVERT_LONGVARBINARY),
2232
 
    GI_CONST_BITS(SQL_CONVERT_LONGVARCHAR),
2233
 
    GI_CONST_BITS(SQL_CONVERT_NUMERIC),
2234
 
    GI_CONST_BITS(SQL_CONVERT_REAL),
2235
 
    GI_CONST_BITS(SQL_CONVERT_SMALLINT),
2236
 
    GI_CONST_BITS(SQL_CONVERT_TIME),
2237
 
    GI_CONST_BITS(SQL_CONVERT_TIMESTAMP),
2238
 
    GI_CONST_BITS(SQL_CONVERT_TINYINT),
2239
 
    GI_CONST_BITS(SQL_CONVERT_VARBINARY),
2240
 
    GI_CONST_BITS(SQL_CONVERT_VARCHAR),
2241
 
    GI_CONST_BITS(SQL_CONVERT_WCHAR),
2242
 
    GI_CONST_BITS(SQL_CONVERT_WLONGVARCHAR),
2243
 
    GI_CONST_BITS(SQL_CONVERT_WVARCHAR),
2244
 
    GI_CONST_BITS(SQL_CREATE_ASSERTION),
2245
 
    GI_CONST_BITS(SQL_CREATE_CHARACTER_SET),
2246
 
    GI_CONST_BITS(SQL_CREATE_COLLATION),
2247
 
    GI_CONST_BITS(SQL_CREATE_DOMAIN),
2248
 
    GI_CONST_BITS(SQL_CREATE_SCHEMA),
2249
 
    GI_CONST_BITS(SQL_CREATE_TABLE),
2250
 
    GI_CONST_BITS(SQL_CREATE_TRANSLATION),
2251
 
    GI_CONST_BITS(SQL_CREATE_VIEW),
2252
 
    GI_CONST_BITS(SQL_DATETIME_LITERALS),
2253
 
    GI_CONST_BITS(SQL_DROP_ASSERTION),
2254
 
    GI_CONST_BITS(SQL_DROP_CHARACTER_SET),
2255
 
    GI_CONST_BITS(SQL_DROP_COLLATION),
2256
 
    GI_CONST_BITS(SQL_DROP_DOMAIN),
2257
 
    GI_CONST_BITS(SQL_DROP_SCHEMA),
2258
 
    GI_CONST_BITS(SQL_DROP_TABLE),
2259
 
    GI_CONST_BITS(SQL_DROP_TRANSLATION),
2260
 
    GI_CONST_BITS(SQL_DROP_VIEW),
2261
 
    GI_CONST_BITS(SQL_DTC_TRANSITION_COST),
2262
 
    GI_CONST_BITS(SQL_DYNAMIC_CURSOR_ATTRIBUTES1),
2263
 
    GI_CONST_BITS(SQL_DYNAMIC_CURSOR_ATTRIBUTES2),
2264
 
    GI_CONST_BITS(SQL_FETCH_DIRECTION),
2265
 
    GI_CONST_BITS(SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1),
2266
 
    GI_CONST_BITS(SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2),
2267
 
    GI_CONST_BITS(SQL_GETDATA_EXTENSIONS),
2268
 
    GI_CONST_BITS(SQL_KEYSET_CURSOR_ATTRIBUTES1),
2269
 
    GI_CONST_BITS(SQL_KEYSET_CURSOR_ATTRIBUTES2),
2270
 
    GI_CONST_BITS(SQL_INDEX_KEYWORDS),
2271
 
    GI_CONST_BITS(SQL_INFO_SCHEMA_VIEWS),
2272
 
    GI_CONST_BITS(SQL_INSERT_STATEMENT),
2273
 
    GI_CONST_BITS(SQL_LOCK_TYPES),
2274
 
    GI_CONST_BITS(SQL_NUMERIC_FUNCTIONS),
2275
 
    GI_CONST_BITS(SQL_OJ_CAPABILITIES),
2276
 
    GI_CONST_BITS(SQL_OWNER_USAGE),
2277
 
    GI_CONST_BITS(SQL_POS_OPERATIONS),
2278
 
    GI_CONST_BITS(SQL_POSITIONED_STATEMENTS),
2279
 
    GI_CONST_BITS(SQL_QUALIFIER_USAGE),
2280
 
    GI_CONST_BITS(SQL_SCHEMA_USAGE),
2281
 
    GI_CONST_BITS(SQL_SCROLL_CONCURRENCY),
2282
 
    GI_CONST_BITS(SQL_SCROLL_OPTIONS),
2283
 
    GI_CONST_BITS(SQL_SQL92_DATETIME_FUNCTIONS),
2284
 
    GI_CONST_BITS(SQL_SQL92_FOREIGN_KEY_DELETE_RULE),
2285
 
    GI_CONST_BITS(SQL_SQL92_FOREIGN_KEY_UPDATE_RULE),
2286
 
    GI_CONST_BITS(SQL_SQL92_GRANT),
2287
 
    GI_CONST_BITS(SQL_SQL92_NUMERIC_VALUE_FUNCTIONS),
2288
 
    GI_CONST_BITS(SQL_SQL92_PREDICATES),
2289
 
    GI_CONST_BITS(SQL_SQL92_RELATIONAL_JOIN_OPERATORS),
2290
 
    GI_CONST_BITS(SQL_SQL92_REVOKE),
2291
 
    GI_CONST_BITS(SQL_SQL92_ROW_VALUE_CONSTRUCTOR),
2292
 
    GI_CONST_BITS(SQL_SQL92_STRING_FUNCTIONS),
2293
 
    GI_CONST_BITS(SQL_SQL92_VALUE_EXPRESSIONS),
2294
 
    GI_CONST_BITS(SQL_STANDARD_CLI_CONFORMANCE),
2295
 
    GI_CONST_BITS(SQL_STATIC_CURSOR_ATTRIBUTES1),
2296
 
    GI_CONST_BITS(SQL_STATIC_CURSOR_ATTRIBUTES2),
2297
 
    GI_CONST_BITS(SQL_STATIC_SENSITIVITY),
2298
 
    GI_CONST_BITS(SQL_STRING_FUNCTIONS),
2299
 
    GI_CONST_BITS(SQL_SUBQUERIES),
2300
 
    GI_CONST_BITS(SQL_SYSTEM_FUNCTIONS),
2301
 
    GI_CONST_BITS(SQL_TIMEDATE_ADD_INTERVALS),
2302
 
    GI_CONST_BITS(SQL_TIMEDATE_DIFF_INTERVALS),
2303
 
    GI_CONST_BITS(SQL_TIMEDATE_FUNCTIONS),
2304
 
    GI_CONST_BITS(SQL_TXN_ISOLATION_OPTION),
2305
 
    GI_CONST_BITS(SQL_UNION),
2306
 
 
2307
 
    /* yielding strings */
2308
 
    GI_CONST_STR(SQL_ACCESSIBLE_PROCEDURES),
2309
 
    GI_CONST_STR(SQL_ACCESSIBLE_TABLES),
2310
 
    GI_CONST_STR(SQL_CATALOG_NAME),
2311
 
    GI_CONST_STR(SQL_CATALOG_NAME_SEPARATOR),
2312
 
    GI_CONST_STR(SQL_CATALOG_TERM),
2313
 
    GI_CONST_STR(SQL_COLLATION_SEQ),
2314
 
    GI_CONST_STR(SQL_COLUMN_ALIAS),
2315
 
    GI_CONST_STR(SQL_DATA_SOURCE_NAME),
2316
 
    GI_CONST_STR(SQL_DATA_SOURCE_READ_ONLY),
2317
 
    GI_CONST_STR(SQL_DATABASE_NAME),
2318
 
    GI_CONST_STR(SQL_DBMS_NAME),
2319
 
    GI_CONST_STR(SQL_DBMS_VER),
2320
 
    GI_CONST_STR(SQL_DESCRIBE_PARAMETER),
2321
 
    GI_CONST_STR(SQL_DM_VER),
2322
 
    GI_CONST_STR(SQL_DRIVER_NAME),
2323
 
    GI_CONST_STR(SQL_DRIVER_ODBC_VER),
2324
 
    GI_CONST_STR(SQL_DRIVER_VER),
2325
 
    GI_CONST_STR(SQL_EXPRESSIONS_IN_ORDERBY),
2326
 
    GI_CONST_STR(SQL_IDENTIFIER_QUOTE_CHAR),
2327
 
    GI_CONST_STR(SQL_INTEGRITY),
2328
 
    GI_CONST_STR(SQL_KEYWORDS),
2329
 
    GI_CONST_STR(SQL_LIKE_ESCAPE_CLAUSE),
2330
 
    GI_CONST_STR(SQL_MAX_ROW_SIZE_INCLUDES_LONG),
2331
 
    GI_CONST_STR(SQL_MULT_RESULT_SETS),
2332
 
    GI_CONST_STR(SQL_MULTIPLE_ACTIVE_TXN),
2333
 
    GI_CONST_STR(SQL_NEED_LONG_DATA_LEN),
2334
 
    GI_CONST_STR(SQL_ODBC_SQL_OPT_IEF),
2335
 
    GI_CONST_STR(SQL_ODBC_VER),
2336
 
    GI_CONST_STR(SQL_ORDER_BY_COLUMNS_IN_SELECT),
2337
 
    GI_CONST_STR(SQL_OUTER_JOINS),
2338
 
    GI_CONST_STR(SQL_OWNER_TERM),
2339
 
    GI_CONST_STR(SQL_PROCEDURE_TERM),
2340
 
    GI_CONST_STR(SQL_PROCEDURES),
2341
 
    GI_CONST_STR(SQL_QUALIFIER_NAME_SEPARATOR),
2342
 
    GI_CONST_STR(SQL_QUALIFIER_TERM),
2343
 
    GI_CONST_STR(SQL_ROW_UPDATES),
2344
 
    GI_CONST_STR(SQL_SCHEMA_TERM),
2345
 
    GI_CONST_STR(SQL_SEARCH_PATTERN_ESCAPE),
2346
 
    GI_CONST_STR(SQL_SERVER_NAME),
2347
 
    GI_CONST_STR(SQL_SPECIAL_CHARACTERS),
2348
 
    GI_CONST_STR(SQL_TABLE_TERM),
2349
 
    GI_CONST_STR(SQL_USER_NAME),
2350
 
    GI_CONST_STR(SQL_XOPEN_CLI_YEAR),
2351
 
 
2352
 
    /* end of table */
2353
 
    GI_CONST_END
2354
 
};
2355
 
 
2356
 
#define GI_CONST_BITMAP(x)  { #x, x }
2357
 
#define GI_CONST_BITMAP_END { NULL, 0 }
2358
 
static struct {
2359
 
    const char *name;
2360
 
    int bits;
2361
 
} get_info_bitmap[] = {
2362
 
    GI_CONST_BITMAP(SQL_AD_ADD_CONSTRAINT_DEFERRABLE),
2363
 
    GI_CONST_BITMAP(SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED),
2364
 
    GI_CONST_BITMAP(SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE),
2365
 
    GI_CONST_BITMAP(SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE),
2366
 
    GI_CONST_BITMAP(SQL_AD_ADD_DOMAIN_CONSTRAINT),
2367
 
    GI_CONST_BITMAP(SQL_AD_ADD_DOMAIN_DEFAULT),
2368
 
    GI_CONST_BITMAP(SQL_AD_CONSTRAINT_NAME_DEFINITION),
2369
 
    GI_CONST_BITMAP(SQL_AD_DROP_DOMAIN_CONSTRAINT),
2370
 
    GI_CONST_BITMAP(SQL_AD_DROP_DOMAIN_DEFAULT),
2371
 
    GI_CONST_BITMAP(SQL_AF_ALL),
2372
 
    GI_CONST_BITMAP(SQL_AF_AVG),
2373
 
    GI_CONST_BITMAP(SQL_AF_COUNT),
2374
 
    GI_CONST_BITMAP(SQL_AF_DISTINCT),
2375
 
    GI_CONST_BITMAP(SQL_AF_MAX),
2376
 
    GI_CONST_BITMAP(SQL_AF_MIN),
2377
 
    GI_CONST_BITMAP(SQL_AF_SUM),
2378
 
    GI_CONST_BITMAP(SQL_AM_CONNECTION),
2379
 
    GI_CONST_BITMAP(SQL_AM_NONE),
2380
 
    GI_CONST_BITMAP(SQL_AM_STATEMENT),
2381
 
    GI_CONST_BITMAP(SQL_AT_ADD_COLUMN),
2382
 
    GI_CONST_BITMAP(SQL_AT_ADD_COLUMN_COLLATION),
2383
 
    GI_CONST_BITMAP(SQL_AT_ADD_COLUMN_DEFAULT),
2384
 
    GI_CONST_BITMAP(SQL_AT_ADD_COLUMN_SINGLE),
2385
 
    GI_CONST_BITMAP(SQL_AT_ADD_CONSTRAINT),
2386
 
    GI_CONST_BITMAP(SQL_AT_ADD_TABLE_CONSTRAINT),
2387
 
#ifdef SQL_AT_COLUMN_SINGLE
2388
 
    GI_CONST_BITMAP(SQL_AT_COLUMN_SINGLE),
2389
 
#endif
2390
 
    GI_CONST_BITMAP(SQL_AT_CONSTRAINT_DEFERRABLE),
2391
 
    GI_CONST_BITMAP(SQL_AT_CONSTRAINT_INITIALLY_DEFERRED),
2392
 
    GI_CONST_BITMAP(SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE),
2393
 
    GI_CONST_BITMAP(SQL_AT_CONSTRAINT_NAME_DEFINITION),
2394
 
    GI_CONST_BITMAP(SQL_AT_CONSTRAINT_NON_DEFERRABLE),
2395
 
    GI_CONST_BITMAP(SQL_AT_DROP_COLUMN),
2396
 
    GI_CONST_BITMAP(SQL_AT_DROP_COLUMN_CASCADE),
2397
 
    GI_CONST_BITMAP(SQL_AT_DROP_COLUMN_DEFAULT),
2398
 
    GI_CONST_BITMAP(SQL_AT_DROP_COLUMN_RESTRICT),
2399
 
    GI_CONST_BITMAP(SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE),
2400
 
    GI_CONST_BITMAP(SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT),
2401
 
    GI_CONST_BITMAP(SQL_AT_SET_COLUMN_DEFAULT),
2402
 
    GI_CONST_BITMAP(SQL_BP_CLOSE),
2403
 
    GI_CONST_BITMAP(SQL_BP_DELETE),
2404
 
    GI_CONST_BITMAP(SQL_BP_DROP),
2405
 
    GI_CONST_BITMAP(SQL_BP_OTHER_HSTMT),
2406
 
    GI_CONST_BITMAP(SQL_BP_SCROLL),
2407
 
    GI_CONST_BITMAP(SQL_BP_TRANSACTION),
2408
 
    GI_CONST_BITMAP(SQL_BP_UPDATE),
2409
 
    GI_CONST_BITMAP(SQL_BRC_EXPLICIT),
2410
 
    GI_CONST_BITMAP(SQL_BRC_PROCEDURES),
2411
 
    GI_CONST_BITMAP(SQL_BRC_ROLLED_UP),
2412
 
    GI_CONST_BITMAP(SQL_BS_ROW_COUNT_EXPLICIT),
2413
 
    GI_CONST_BITMAP(SQL_BS_ROW_COUNT_PROC),
2414
 
    GI_CONST_BITMAP(SQL_BS_SELECT_EXPLICIT),
2415
 
    GI_CONST_BITMAP(SQL_BS_SELECT_PROC),
2416
 
    GI_CONST_BITMAP(SQL_CA1_ABSOLUTE),
2417
 
    GI_CONST_BITMAP(SQL_CA1_BOOKMARK),
2418
 
    GI_CONST_BITMAP(SQL_CA1_BULK_ADD),
2419
 
    GI_CONST_BITMAP(SQL_CA1_BULK_DELETE_BY_BOOKMARK),
2420
 
    GI_CONST_BITMAP(SQL_CA1_BULK_FETCH_BY_BOOKMARK),
2421
 
    GI_CONST_BITMAP(SQL_CA1_BULK_UPDATE_BY_BOOKMARK),
2422
 
    GI_CONST_BITMAP(SQL_CA1_LOCK_EXCLUSIVE),
2423
 
    GI_CONST_BITMAP(SQL_CA1_LOCK_NO_CHANGE),
2424
 
    GI_CONST_BITMAP(SQL_CA1_LOCK_UNLOCK),
2425
 
    GI_CONST_BITMAP(SQL_CA1_NEXT),
2426
 
    GI_CONST_BITMAP(SQL_CA1_POS_DELETE),
2427
 
    GI_CONST_BITMAP(SQL_CA1_POSITIONED_DELETE),
2428
 
    GI_CONST_BITMAP(SQL_CA1_POSITIONED_UPDATE),
2429
 
    GI_CONST_BITMAP(SQL_CA1_POS_POSITION),
2430
 
    GI_CONST_BITMAP(SQL_CA1_POS_REFRESH),
2431
 
    GI_CONST_BITMAP(SQL_CA1_POS_UPDATE),
2432
 
    GI_CONST_BITMAP(SQL_CA1_RELATIVE),
2433
 
    GI_CONST_BITMAP(SQL_CA1_SELECT_FOR_UPDATE),
2434
 
    GI_CONST_BITMAP(SQL_CA2_CRC_APPROXIMATE),
2435
 
    GI_CONST_BITMAP(SQL_CA2_CRC_EXACT),
2436
 
    GI_CONST_BITMAP(SQL_CA2_LOCK_CONCURRENCY),
2437
 
    GI_CONST_BITMAP(SQL_CA2_MAX_ROWS_AFFECTS_ALL),
2438
 
    GI_CONST_BITMAP(SQL_CA2_MAX_ROWS_CATALOG),
2439
 
    GI_CONST_BITMAP(SQL_CA2_MAX_ROWS_DELETE),
2440
 
    GI_CONST_BITMAP(SQL_CA2_MAX_ROWS_INSERT),
2441
 
    GI_CONST_BITMAP(SQL_CA2_MAX_ROWS_SELECT),
2442
 
    GI_CONST_BITMAP(SQL_CA2_MAX_ROWS_UPDATE),
2443
 
    GI_CONST_BITMAP(SQL_CA2_OPT_ROWVER_CONCURRENCY),
2444
 
    GI_CONST_BITMAP(SQL_CA2_OPT_VALUES_CONCURRENCY),
2445
 
    GI_CONST_BITMAP(SQL_CA2_READ_ONLY_CONCURRENCY),
2446
 
    GI_CONST_BITMAP(SQL_CA2_SENSITIVITY_ADDITIONS),
2447
 
    GI_CONST_BITMAP(SQL_CA2_SENSITIVITY_DELETIONS),
2448
 
    GI_CONST_BITMAP(SQL_CA2_SENSITIVITY_UPDATES),
2449
 
    GI_CONST_BITMAP(SQL_CA2_SIMULATE_NON_UNIQUE),
2450
 
    GI_CONST_BITMAP(SQL_CA2_SIMULATE_TRY_UNIQUE),
2451
 
    GI_CONST_BITMAP(SQL_CA2_SIMULATE_UNIQUE),
2452
 
    GI_CONST_BITMAP(SQL_CA_CONSTRAINT_DEFERRABLE),
2453
 
    GI_CONST_BITMAP(SQL_CA_CONSTRAINT_INITIALLY_DEFERRED),
2454
 
    GI_CONST_BITMAP(SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE),
2455
 
    GI_CONST_BITMAP(SQL_CA_CONSTRAINT_NON_DEFERRABLE),
2456
 
    GI_CONST_BITMAP(SQL_CA_CREATE_ASSERTION),
2457
 
    GI_CONST_BITMAP(SQL_CB_CLOSE),
2458
 
    GI_CONST_BITMAP(SQL_CB_DELETE),
2459
 
    GI_CONST_BITMAP(SQL_CB_NON_NULL),
2460
 
    GI_CONST_BITMAP(SQL_CB_NULL),
2461
 
    GI_CONST_BITMAP(SQL_CB_PRESERVE),
2462
 
    GI_CONST_BITMAP(SQL_CC_CLOSE),
2463
 
    GI_CONST_BITMAP(SQL_CC_DELETE),
2464
 
    GI_CONST_BITMAP(SQL_CCOL_CREATE_COLLATION),
2465
 
    GI_CONST_BITMAP(SQL_CC_PRESERVE),
2466
 
    GI_CONST_BITMAP(SQL_CCS_COLLATE_CLAUSE),
2467
 
    GI_CONST_BITMAP(SQL_CCS_CREATE_CHARACTER_SET),
2468
 
    GI_CONST_BITMAP(SQL_CCS_LIMITED_COLLATION),
2469
 
    GI_CONST_BITMAP(SQL_CDO_COLLATION),
2470
 
    GI_CONST_BITMAP(SQL_CDO_CONSTRAINT),
2471
 
    GI_CONST_BITMAP(SQL_CDO_CONSTRAINT_DEFERRABLE),
2472
 
    GI_CONST_BITMAP(SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED),
2473
 
    GI_CONST_BITMAP(SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE),
2474
 
    GI_CONST_BITMAP(SQL_CDO_CONSTRAINT_NAME_DEFINITION),
2475
 
    GI_CONST_BITMAP(SQL_CDO_CONSTRAINT_NON_DEFERRABLE),
2476
 
    GI_CONST_BITMAP(SQL_CDO_CREATE_DOMAIN),
2477
 
    GI_CONST_BITMAP(SQL_CDO_DEFAULT),
2478
 
    GI_CONST_BITMAP(SQL_CL_END),
2479
 
    GI_CONST_BITMAP(SQL_CL_START),
2480
 
    GI_CONST_BITMAP(SQL_CN_ANY),
2481
 
    GI_CONST_BITMAP(SQL_CN_DIFFERENT),
2482
 
    GI_CONST_BITMAP(SQL_CN_NONE),
2483
 
    GI_CONST_BITMAP(SQL_CONCUR_TIMESTAMP),
2484
 
    GI_CONST_BITMAP(SQL_CR_CLOSE),
2485
 
    GI_CONST_BITMAP(SQL_CR_DELETE),
2486
 
    GI_CONST_BITMAP(SQL_CR_PRESERVE),
2487
 
    GI_CONST_BITMAP(SQL_CS_AUTHORIZATION),
2488
 
    GI_CONST_BITMAP(SQL_CS_CREATE_SCHEMA),
2489
 
    GI_CONST_BITMAP(SQL_CS_DEFAULT_CHARACTER_SET),
2490
 
    GI_CONST_BITMAP(SQL_CT_COLUMN_COLLATION),
2491
 
    GI_CONST_BITMAP(SQL_CT_COLUMN_CONSTRAINT),
2492
 
    GI_CONST_BITMAP(SQL_CT_COLUMN_DEFAULT),
2493
 
    GI_CONST_BITMAP(SQL_CT_COMMIT_DELETE),
2494
 
    GI_CONST_BITMAP(SQL_CT_COMMIT_PRESERVE),
2495
 
    GI_CONST_BITMAP(SQL_CT_CONSTRAINT_DEFERRABLE),
2496
 
    GI_CONST_BITMAP(SQL_CT_CONSTRAINT_INITIALLY_DEFERRED),
2497
 
    GI_CONST_BITMAP(SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE),
2498
 
    GI_CONST_BITMAP(SQL_CT_CONSTRAINT_NAME_DEFINITION),
2499
 
    GI_CONST_BITMAP(SQL_CT_CONSTRAINT_NON_DEFERRABLE),
2500
 
    GI_CONST_BITMAP(SQL_CT_CREATE_TABLE),
2501
 
    GI_CONST_BITMAP(SQL_CT_GLOBAL_TEMPORARY),
2502
 
    GI_CONST_BITMAP(SQL_CT_LOCAL_TEMPORARY),
2503
 
    GI_CONST_BITMAP(SQL_CTR_CREATE_TRANSLATION),
2504
 
    GI_CONST_BITMAP(SQL_CT_TABLE_CONSTRAINT),
2505
 
    GI_CONST_BITMAP(SQL_CU_DML_STATEMENTS),
2506
 
    GI_CONST_BITMAP(SQL_CU_INDEX_DEFINITION),
2507
 
    GI_CONST_BITMAP(SQL_CU_PRIVILEGE_DEFINITION),
2508
 
    GI_CONST_BITMAP(SQL_CU_PROCEDURE_INVOCATION),
2509
 
    GI_CONST_BITMAP(SQL_CU_TABLE_DEFINITION),
2510
 
    GI_CONST_BITMAP(SQL_CV_CASCADED),
2511
 
    GI_CONST_BITMAP(SQL_CV_CHECK_OPTION),
2512
 
    GI_CONST_BITMAP(SQL_CV_CREATE_VIEW),
2513
 
    GI_CONST_BITMAP(SQL_CV_LOCAL),
2514
 
    GI_CONST_BITMAP(SQL_CVT_BIGINT),
2515
 
    GI_CONST_BITMAP(SQL_CVT_BINARY),
2516
 
    GI_CONST_BITMAP(SQL_CVT_BIT),
2517
 
    GI_CONST_BITMAP(SQL_CVT_CHAR),
2518
 
    GI_CONST_BITMAP(SQL_CVT_DATE),
2519
 
    GI_CONST_BITMAP(SQL_CVT_DECIMAL),
2520
 
    GI_CONST_BITMAP(SQL_CVT_DOUBLE),
2521
 
    GI_CONST_BITMAP(SQL_CVT_FLOAT),
2522
 
    GI_CONST_BITMAP(SQL_CVT_INTEGER),
2523
 
    GI_CONST_BITMAP(SQL_CVT_INTERVAL_DAY_TIME),
2524
 
    GI_CONST_BITMAP(SQL_CVT_INTERVAL_YEAR_MONTH),
2525
 
    GI_CONST_BITMAP(SQL_CVT_LONGVARBINARY),
2526
 
    GI_CONST_BITMAP(SQL_CVT_LONGVARCHAR),
2527
 
    GI_CONST_BITMAP(SQL_CVT_NUMERIC),
2528
 
    GI_CONST_BITMAP(SQL_CVT_REAL),
2529
 
    GI_CONST_BITMAP(SQL_CVT_SMALLINT),
2530
 
    GI_CONST_BITMAP(SQL_CVT_TIME),
2531
 
    GI_CONST_BITMAP(SQL_CVT_TIMESTAMP),
2532
 
    GI_CONST_BITMAP(SQL_CVT_TINYINT),
2533
 
    GI_CONST_BITMAP(SQL_CVT_VARBINARY),
2534
 
    GI_CONST_BITMAP(SQL_CVT_VARCHAR),
2535
 
    GI_CONST_BITMAP(SQL_CVT_WCHAR),
2536
 
    GI_CONST_BITMAP(SQL_CVT_WLONGVARCHAR),
2537
 
    GI_CONST_BITMAP(SQL_CVT_WVARCHAR),
2538
 
    GI_CONST_BITMAP(SQL_DA_DROP_ASSERTION),
2539
 
    GI_CONST_BITMAP(SQL_DC_DROP_COLLATION),
2540
 
    GI_CONST_BITMAP(SQL_DCS_DROP_CHARACTER_SET),
2541
 
    GI_CONST_BITMAP(SQL_DD_CASCADE),
2542
 
    GI_CONST_BITMAP(SQL_DD_DROP_DOMAIN),
2543
 
    GI_CONST_BITMAP(SQL_DD_RESTRICT),
2544
 
    GI_CONST_BITMAP(SQL_DI_CREATE_INDEX),
2545
 
    GI_CONST_BITMAP(SQL_DI_DROP_INDEX),
2546
 
    GI_CONST_BITMAP(SQL_DL_SQL92_DATE),
2547
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_DAY),
2548
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR),
2549
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE),
2550
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND),
2551
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_HOUR),
2552
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE),
2553
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND),
2554
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_MINUTE),
2555
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND),
2556
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_MONTH),
2557
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_SECOND),
2558
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_YEAR),
2559
 
    GI_CONST_BITMAP(SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH),
2560
 
    GI_CONST_BITMAP(SQL_DL_SQL92_TIME),
2561
 
    GI_CONST_BITMAP(SQL_DL_SQL92_TIMESTAMP),
2562
 
    GI_CONST_BITMAP(SQL_DS_CASCADE),
2563
 
    GI_CONST_BITMAP(SQL_DS_DROP_SCHEMA),
2564
 
    GI_CONST_BITMAP(SQL_DS_RESTRICT),
2565
 
    GI_CONST_BITMAP(SQL_DT_CASCADE),
2566
 
    GI_CONST_BITMAP(SQL_DTC_ENLIST_EXPENSIVE),
2567
 
    GI_CONST_BITMAP(SQL_DTC_UNENLIST_EXPENSIVE),
2568
 
    GI_CONST_BITMAP(SQL_DT_DROP_TABLE),
2569
 
    GI_CONST_BITMAP(SQL_DTR_DROP_TRANSLATION),
2570
 
    GI_CONST_BITMAP(SQL_DT_RESTRICT),
2571
 
    GI_CONST_BITMAP(SQL_DV_CASCADE),
2572
 
    GI_CONST_BITMAP(SQL_DV_DROP_VIEW),
2573
 
    GI_CONST_BITMAP(SQL_DV_RESTRICT),
2574
 
    GI_CONST_BITMAP(SQL_FD_FETCH_ABSOLUTE),
2575
 
    GI_CONST_BITMAP(SQL_FD_FETCH_BOOKMARK),
2576
 
    GI_CONST_BITMAP(SQL_FD_FETCH_FIRST),
2577
 
    GI_CONST_BITMAP(SQL_FD_FETCH_LAST),
2578
 
    GI_CONST_BITMAP(SQL_FD_FETCH_NEXT),
2579
 
    GI_CONST_BITMAP(SQL_FD_FETCH_PRIOR),
2580
 
    GI_CONST_BITMAP(SQL_FD_FETCH_RELATIVE),
2581
 
#ifdef SQL_FD_FETCH_RESUME
2582
 
    GI_CONST_BITMAP(SQL_FD_FETCH_RESUME),
2583
 
#endif
2584
 
    GI_CONST_BITMAP(SQL_FILE_CATALOG),
2585
 
    GI_CONST_BITMAP(SQL_FILE_NOT_SUPPORTED),
2586
 
    GI_CONST_BITMAP(SQL_FILE_QUALIFIER),
2587
 
    GI_CONST_BITMAP(SQL_FILE_TABLE),
2588
 
    GI_CONST_BITMAP(SQL_FN_CVT_CAST),
2589
 
    GI_CONST_BITMAP(SQL_FN_CVT_CONVERT),
2590
 
    GI_CONST_BITMAP(SQL_FN_NUM_ABS),
2591
 
    GI_CONST_BITMAP(SQL_FN_NUM_ACOS),
2592
 
    GI_CONST_BITMAP(SQL_FN_NUM_ASIN),
2593
 
    GI_CONST_BITMAP(SQL_FN_NUM_ATAN),
2594
 
    GI_CONST_BITMAP(SQL_FN_NUM_ATAN2),
2595
 
    GI_CONST_BITMAP(SQL_FN_NUM_CEILING),
2596
 
    GI_CONST_BITMAP(SQL_FN_NUM_COS),
2597
 
    GI_CONST_BITMAP(SQL_FN_NUM_COT),
2598
 
    GI_CONST_BITMAP(SQL_FN_NUM_DEGREES),
2599
 
    GI_CONST_BITMAP(SQL_FN_NUM_EXP),
2600
 
    GI_CONST_BITMAP(SQL_FN_NUM_FLOOR),
2601
 
    GI_CONST_BITMAP(SQL_FN_NUM_LOG),
2602
 
    GI_CONST_BITMAP(SQL_FN_NUM_LOG10),
2603
 
    GI_CONST_BITMAP(SQL_FN_NUM_MOD),
2604
 
    GI_CONST_BITMAP(SQL_FN_NUM_PI),
2605
 
    GI_CONST_BITMAP(SQL_FN_NUM_POWER),
2606
 
    GI_CONST_BITMAP(SQL_FN_NUM_RADIANS),
2607
 
    GI_CONST_BITMAP(SQL_FN_NUM_RAND),
2608
 
    GI_CONST_BITMAP(SQL_FN_NUM_ROUND),
2609
 
    GI_CONST_BITMAP(SQL_FN_NUM_SIGN),
2610
 
    GI_CONST_BITMAP(SQL_FN_NUM_SIN),
2611
 
    GI_CONST_BITMAP(SQL_FN_NUM_SQRT),
2612
 
    GI_CONST_BITMAP(SQL_FN_NUM_TAN),
2613
 
    GI_CONST_BITMAP(SQL_FN_NUM_TRUNCATE),
2614
 
    GI_CONST_BITMAP(SQL_FN_STR_ASCII),
2615
 
    GI_CONST_BITMAP(SQL_FN_STR_BIT_LENGTH),
2616
 
    GI_CONST_BITMAP(SQL_FN_STR_CHAR),
2617
 
    GI_CONST_BITMAP(SQL_FN_STR_CHARACTER_LENGTH),
2618
 
    GI_CONST_BITMAP(SQL_FN_STR_CHAR_LENGTH),
2619
 
    GI_CONST_BITMAP(SQL_FN_STR_CONCAT),
2620
 
    GI_CONST_BITMAP(SQL_FN_STR_DIFFERENCE),
2621
 
    GI_CONST_BITMAP(SQL_FN_STR_INSERT),
2622
 
    GI_CONST_BITMAP(SQL_FN_STR_LCASE),
2623
 
    GI_CONST_BITMAP(SQL_FN_STR_LEFT),
2624
 
    GI_CONST_BITMAP(SQL_FN_STR_LENGTH),
2625
 
    GI_CONST_BITMAP(SQL_FN_STR_LOCATE),
2626
 
    GI_CONST_BITMAP(SQL_FN_STR_LOCATE_2),
2627
 
    GI_CONST_BITMAP(SQL_FN_STR_LTRIM),
2628
 
    GI_CONST_BITMAP(SQL_FN_STR_OCTET_LENGTH),
2629
 
    GI_CONST_BITMAP(SQL_FN_STR_POSITION),
2630
 
    GI_CONST_BITMAP(SQL_FN_STR_REPEAT),
2631
 
    GI_CONST_BITMAP(SQL_FN_STR_REPLACE),
2632
 
    GI_CONST_BITMAP(SQL_FN_STR_RIGHT),
2633
 
    GI_CONST_BITMAP(SQL_FN_STR_RTRIM),
2634
 
    GI_CONST_BITMAP(SQL_FN_STR_SOUNDEX),
2635
 
    GI_CONST_BITMAP(SQL_FN_STR_SPACE),
2636
 
    GI_CONST_BITMAP(SQL_FN_STR_SUBSTRING),
2637
 
    GI_CONST_BITMAP(SQL_FN_STR_UCASE),
2638
 
    GI_CONST_BITMAP(SQL_FN_SYS_DBNAME),
2639
 
    GI_CONST_BITMAP(SQL_FN_SYS_IFNULL),
2640
 
    GI_CONST_BITMAP(SQL_FN_SYS_USERNAME),
2641
 
    GI_CONST_BITMAP(SQL_FN_TD_CURDATE),
2642
 
    GI_CONST_BITMAP(SQL_FN_TD_CURRENT_DATE),
2643
 
    GI_CONST_BITMAP(SQL_FN_TD_CURRENT_TIME),
2644
 
    GI_CONST_BITMAP(SQL_FN_TD_CURRENT_TIMESTAMP),
2645
 
    GI_CONST_BITMAP(SQL_FN_TD_CURTIME),
2646
 
    GI_CONST_BITMAP(SQL_FN_TD_DAYNAME),
2647
 
    GI_CONST_BITMAP(SQL_FN_TD_DAYOFMONTH),
2648
 
    GI_CONST_BITMAP(SQL_FN_TD_DAYOFWEEK),
2649
 
    GI_CONST_BITMAP(SQL_FN_TD_DAYOFYEAR),
2650
 
    GI_CONST_BITMAP(SQL_FN_TD_EXTRACT),
2651
 
    GI_CONST_BITMAP(SQL_FN_TD_HOUR),
2652
 
    GI_CONST_BITMAP(SQL_FN_TD_MINUTE),
2653
 
    GI_CONST_BITMAP(SQL_FN_TD_MONTH),
2654
 
    GI_CONST_BITMAP(SQL_FN_TD_MONTHNAME),
2655
 
    GI_CONST_BITMAP(SQL_FN_TD_NOW),
2656
 
    GI_CONST_BITMAP(SQL_FN_TD_QUARTER),
2657
 
    GI_CONST_BITMAP(SQL_FN_TD_SECOND),
2658
 
    GI_CONST_BITMAP(SQL_FN_TD_TIMESTAMPADD),
2659
 
    GI_CONST_BITMAP(SQL_FN_TD_TIMESTAMPDIFF),
2660
 
    GI_CONST_BITMAP(SQL_FN_TD_WEEK),
2661
 
    GI_CONST_BITMAP(SQL_FN_TD_YEAR),
2662
 
    GI_CONST_BITMAP(SQL_FN_TSI_DAY),
2663
 
    GI_CONST_BITMAP(SQL_FN_TSI_FRAC_SECOND),
2664
 
    GI_CONST_BITMAP(SQL_FN_TSI_HOUR),
2665
 
    GI_CONST_BITMAP(SQL_FN_TSI_MINUTE),
2666
 
    GI_CONST_BITMAP(SQL_FN_TSI_MONTH),
2667
 
    GI_CONST_BITMAP(SQL_FN_TSI_QUARTER),
2668
 
    GI_CONST_BITMAP(SQL_FN_TSI_SECOND),
2669
 
    GI_CONST_BITMAP(SQL_FN_TSI_WEEK),
2670
 
    GI_CONST_BITMAP(SQL_FN_TSI_YEAR),
2671
 
    GI_CONST_BITMAP(SQL_GB_COLLATE),
2672
 
    GI_CONST_BITMAP(SQL_GB_GROUP_BY_CONTAINS_SELECT),
2673
 
    GI_CONST_BITMAP(SQL_GB_GROUP_BY_EQUALS_SELECT),
2674
 
    GI_CONST_BITMAP(SQL_GB_NO_RELATION),
2675
 
    GI_CONST_BITMAP(SQL_GB_NOT_SUPPORTED),
2676
 
    GI_CONST_BITMAP(SQL_GD_ANY_COLUMN),
2677
 
    GI_CONST_BITMAP(SQL_GD_ANY_ORDER),
2678
 
    GI_CONST_BITMAP(SQL_GD_BLOCK),
2679
 
    GI_CONST_BITMAP(SQL_GD_BOUND),
2680
 
    GI_CONST_BITMAP(SQL_IC_LOWER),
2681
 
    GI_CONST_BITMAP(SQL_IC_MIXED),
2682
 
    GI_CONST_BITMAP(SQL_IC_SENSITIVE),
2683
 
    GI_CONST_BITMAP(SQL_IC_UPPER),
2684
 
    GI_CONST_BITMAP(SQL_IK_ALL),
2685
 
    GI_CONST_BITMAP(SQL_IK_ASC),
2686
 
    GI_CONST_BITMAP(SQL_IK_DESC),
2687
 
    GI_CONST_BITMAP(SQL_IK_NONE),
2688
 
    GI_CONST_BITMAP(SQL_IS_INSERT_LITERALS),
2689
 
    GI_CONST_BITMAP(SQL_IS_INSERT_SEARCHED),
2690
 
    GI_CONST_BITMAP(SQL_IS_SELECT_INTO),
2691
 
    GI_CONST_BITMAP(SQL_ISV_ASSERTIONS),
2692
 
    GI_CONST_BITMAP(SQL_ISV_CHARACTER_SETS),
2693
 
    GI_CONST_BITMAP(SQL_ISV_CHECK_CONSTRAINTS),
2694
 
    GI_CONST_BITMAP(SQL_ISV_COLLATIONS),
2695
 
    GI_CONST_BITMAP(SQL_ISV_COLUMN_DOMAIN_USAGE),
2696
 
    GI_CONST_BITMAP(SQL_ISV_COLUMN_PRIVILEGES),
2697
 
    GI_CONST_BITMAP(SQL_ISV_COLUMNS),
2698
 
    GI_CONST_BITMAP(SQL_ISV_CONSTRAINT_COLUMN_USAGE),
2699
 
    GI_CONST_BITMAP(SQL_ISV_CONSTRAINT_TABLE_USAGE),
2700
 
    GI_CONST_BITMAP(SQL_ISV_DOMAIN_CONSTRAINTS),
2701
 
    GI_CONST_BITMAP(SQL_ISV_DOMAINS),
2702
 
    GI_CONST_BITMAP(SQL_ISV_KEY_COLUMN_USAGE),
2703
 
    GI_CONST_BITMAP(SQL_ISV_REFERENTIAL_CONSTRAINTS),
2704
 
    GI_CONST_BITMAP(SQL_ISV_SCHEMATA),
2705
 
    GI_CONST_BITMAP(SQL_ISV_SQL_LANGUAGES),
2706
 
    GI_CONST_BITMAP(SQL_ISV_TABLE_CONSTRAINTS),
2707
 
    GI_CONST_BITMAP(SQL_ISV_TABLE_PRIVILEGES),
2708
 
    GI_CONST_BITMAP(SQL_ISV_TABLES),
2709
 
    GI_CONST_BITMAP(SQL_ISV_TRANSLATIONS),
2710
 
    GI_CONST_BITMAP(SQL_ISV_USAGE_PRIVILEGES),
2711
 
    GI_CONST_BITMAP(SQL_ISV_VIEW_COLUMN_USAGE),
2712
 
    GI_CONST_BITMAP(SQL_ISV_VIEWS),
2713
 
    GI_CONST_BITMAP(SQL_ISV_VIEW_TABLE_USAGE),
2714
 
    GI_CONST_BITMAP(SQL_LCK_EXCLUSIVE),
2715
 
    GI_CONST_BITMAP(SQL_LCK_NO_CHANGE),
2716
 
    GI_CONST_BITMAP(SQL_LCK_UNLOCK),
2717
 
    GI_CONST_BITMAP(SQL_NC_END),
2718
 
    GI_CONST_BITMAP(SQL_NC_HIGH),
2719
 
    GI_CONST_BITMAP(SQL_NC_LOW),
2720
 
    GI_CONST_BITMAP(SQL_NC_START),
2721
 
    GI_CONST_BITMAP(SQL_NNC_NON_NULL),
2722
 
    GI_CONST_BITMAP(SQL_NNC_NULL),
2723
 
    GI_CONST_BITMAP(SQL_OAC_LEVEL1),
2724
 
    GI_CONST_BITMAP(SQL_OAC_LEVEL2),
2725
 
    GI_CONST_BITMAP(SQL_OAC_NONE),
2726
 
    GI_CONST_BITMAP(SQL_OIC_CORE),
2727
 
    GI_CONST_BITMAP(SQL_OIC_LEVEL1),
2728
 
    GI_CONST_BITMAP(SQL_OIC_LEVEL2),
2729
 
    GI_CONST_BITMAP(SQL_OJ_ALL_COMPARISON_OPS),
2730
 
    GI_CONST_BITMAP(SQL_OJ_FULL),
2731
 
    GI_CONST_BITMAP(SQL_OJ_INNER),
2732
 
    GI_CONST_BITMAP(SQL_OJ_LEFT),
2733
 
    GI_CONST_BITMAP(SQL_OJ_NESTED),
2734
 
    GI_CONST_BITMAP(SQL_OJ_NOT_ORDERED),
2735
 
    GI_CONST_BITMAP(SQL_OJ_RIGHT),
2736
 
    GI_CONST_BITMAP(SQL_OSCC_COMPLIANT),
2737
 
    GI_CONST_BITMAP(SQL_OSCC_NOT_COMPLIANT),
2738
 
    GI_CONST_BITMAP(SQL_OSC_CORE),
2739
 
    GI_CONST_BITMAP(SQL_OSC_EXTENDED),
2740
 
    GI_CONST_BITMAP(SQL_OSC_MINIMUM),
2741
 
    GI_CONST_BITMAP(SQL_OU_DML_STATEMENTS),
2742
 
    GI_CONST_BITMAP(SQL_OU_INDEX_DEFINITION),
2743
 
    GI_CONST_BITMAP(SQL_OU_PRIVILEGE_DEFINITION),
2744
 
    GI_CONST_BITMAP(SQL_OU_PROCEDURE_INVOCATION),
2745
 
    GI_CONST_BITMAP(SQL_OU_TABLE_DEFINITION),
2746
 
    GI_CONST_BITMAP(SQL_PARC_BATCH),
2747
 
    GI_CONST_BITMAP(SQL_PARC_NO_BATCH),
2748
 
    GI_CONST_BITMAP(SQL_PAS_BATCH),
2749
 
    GI_CONST_BITMAP(SQL_PAS_NO_BATCH),
2750
 
    GI_CONST_BITMAP(SQL_PAS_NO_SELECT),
2751
 
    GI_CONST_BITMAP(SQL_POS_ADD),
2752
 
    GI_CONST_BITMAP(SQL_POS_DELETE),
2753
 
    GI_CONST_BITMAP(SQL_POS_POSITION),
2754
 
    GI_CONST_BITMAP(SQL_POS_REFRESH),
2755
 
    GI_CONST_BITMAP(SQL_POS_UPDATE),
2756
 
    GI_CONST_BITMAP(SQL_PS_POSITIONED_DELETE),
2757
 
    GI_CONST_BITMAP(SQL_PS_POSITIONED_UPDATE),
2758
 
    GI_CONST_BITMAP(SQL_PS_SELECT_FOR_UPDATE),
2759
 
    GI_CONST_BITMAP(SQL_QL_END),
2760
 
    GI_CONST_BITMAP(SQL_QL_START),
2761
 
    GI_CONST_BITMAP(SQL_QU_DML_STATEMENTS),
2762
 
    GI_CONST_BITMAP(SQL_QU_INDEX_DEFINITION),
2763
 
    GI_CONST_BITMAP(SQL_QU_PRIVILEGE_DEFINITION),
2764
 
    GI_CONST_BITMAP(SQL_QU_PROCEDURE_INVOCATION),
2765
 
    GI_CONST_BITMAP(SQL_QU_TABLE_DEFINITION),
2766
 
    GI_CONST_BITMAP(SQL_SCC_ISO92_CLI),
2767
 
    GI_CONST_BITMAP(SQL_SCCO_LOCK),
2768
 
    GI_CONST_BITMAP(SQL_SCCO_OPT_ROWVER),
2769
 
    GI_CONST_BITMAP(SQL_SCCO_OPT_TIMESTAMP),
2770
 
    GI_CONST_BITMAP(SQL_SCCO_OPT_VALUES),
2771
 
    GI_CONST_BITMAP(SQL_SCCO_READ_ONLY),
2772
 
    GI_CONST_BITMAP(SQL_SCC_XOPEN_CLI_VERSION1),
2773
 
    GI_CONST_BITMAP(SQL_SC_FIPS127_2_TRANSITIONAL),
2774
 
    GI_CONST_BITMAP(SQL_SC_NON_UNIQUE),
2775
 
    GI_CONST_BITMAP(SQL_SC_SQL92_ENTRY),
2776
 
    GI_CONST_BITMAP(SQL_SC_SQL92_FULL),
2777
 
    GI_CONST_BITMAP(SQL_SC_SQL92_INTERMEDIATE),
2778
 
    GI_CONST_BITMAP(SQL_SC_TRY_UNIQUE),
2779
 
    GI_CONST_BITMAP(SQL_SC_UNIQUE),
2780
 
    GI_CONST_BITMAP(SQL_SDF_CURRENT_DATE),
2781
 
    GI_CONST_BITMAP(SQL_SDF_CURRENT_TIME),
2782
 
    GI_CONST_BITMAP(SQL_SDF_CURRENT_TIMESTAMP),
2783
 
    GI_CONST_BITMAP(SQL_SFKD_CASCADE),
2784
 
    GI_CONST_BITMAP(SQL_SFKD_NO_ACTION),
2785
 
    GI_CONST_BITMAP(SQL_SFKD_SET_DEFAULT),
2786
 
    GI_CONST_BITMAP(SQL_SFKD_SET_NULL),
2787
 
    GI_CONST_BITMAP(SQL_SFKU_CASCADE),
2788
 
    GI_CONST_BITMAP(SQL_SFKU_NO_ACTION),
2789
 
    GI_CONST_BITMAP(SQL_SFKU_SET_DEFAULT),
2790
 
    GI_CONST_BITMAP(SQL_SFKU_SET_NULL),
2791
 
    GI_CONST_BITMAP(SQL_SG_DELETE_TABLE),
2792
 
    GI_CONST_BITMAP(SQL_SG_INSERT_COLUMN),
2793
 
    GI_CONST_BITMAP(SQL_SG_INSERT_TABLE),
2794
 
    GI_CONST_BITMAP(SQL_SG_REFERENCES_COLUMN),
2795
 
    GI_CONST_BITMAP(SQL_SG_REFERENCES_TABLE),
2796
 
    GI_CONST_BITMAP(SQL_SG_SELECT_TABLE),
2797
 
    GI_CONST_BITMAP(SQL_SG_UPDATE_COLUMN),
2798
 
    GI_CONST_BITMAP(SQL_SG_UPDATE_TABLE),
2799
 
    GI_CONST_BITMAP(SQL_SG_USAGE_ON_CHARACTER_SET),
2800
 
    GI_CONST_BITMAP(SQL_SG_USAGE_ON_COLLATION),
2801
 
    GI_CONST_BITMAP(SQL_SG_USAGE_ON_DOMAIN),
2802
 
    GI_CONST_BITMAP(SQL_SG_USAGE_ON_TRANSLATION),
2803
 
    GI_CONST_BITMAP(SQL_SG_WITH_GRANT_OPTION),
2804
 
    GI_CONST_BITMAP(SQL_SNVF_BIT_LENGTH),
2805
 
    GI_CONST_BITMAP(SQL_SNVF_CHARACTER_LENGTH),
2806
 
    GI_CONST_BITMAP(SQL_SNVF_CHAR_LENGTH),
2807
 
    GI_CONST_BITMAP(SQL_SNVF_EXTRACT),
2808
 
    GI_CONST_BITMAP(SQL_SNVF_OCTET_LENGTH),
2809
 
    GI_CONST_BITMAP(SQL_SNVF_POSITION),
2810
 
    GI_CONST_BITMAP(SQL_SO_DYNAMIC),
2811
 
    GI_CONST_BITMAP(SQL_SO_FORWARD_ONLY),
2812
 
    GI_CONST_BITMAP(SQL_SO_KEYSET_DRIVEN),
2813
 
    GI_CONST_BITMAP(SQL_SO_MIXED),
2814
 
    GI_CONST_BITMAP(SQL_SO_STATIC),
2815
 
    GI_CONST_BITMAP(SQL_SP_BETWEEN),
2816
 
    GI_CONST_BITMAP(SQL_SP_COMPARISON),
2817
 
    GI_CONST_BITMAP(SQL_SP_EXISTS),
2818
 
    GI_CONST_BITMAP(SQL_SP_IN),
2819
 
    GI_CONST_BITMAP(SQL_SP_ISNOTNULL),
2820
 
    GI_CONST_BITMAP(SQL_SP_ISNULL),
2821
 
    GI_CONST_BITMAP(SQL_SP_LIKE),
2822
 
    GI_CONST_BITMAP(SQL_SP_MATCH_FULL),
2823
 
    GI_CONST_BITMAP(SQL_SP_MATCH_PARTIAL),
2824
 
    GI_CONST_BITMAP(SQL_SP_MATCH_UNIQUE_FULL),
2825
 
    GI_CONST_BITMAP(SQL_SP_MATCH_UNIQUE_PARTIAL),
2826
 
    GI_CONST_BITMAP(SQL_SP_OVERLAPS),
2827
 
    GI_CONST_BITMAP(SQL_SP_QUANTIFIED_COMPARISON),
2828
 
    GI_CONST_BITMAP(SQL_SP_UNIQUE),
2829
 
    GI_CONST_BITMAP(SQL_SQ_COMPARISON),
2830
 
    GI_CONST_BITMAP(SQL_SQ_CORRELATED_SUBQUERIES),
2831
 
    GI_CONST_BITMAP(SQL_SQ_EXISTS),
2832
 
    GI_CONST_BITMAP(SQL_SQ_IN),
2833
 
    GI_CONST_BITMAP(SQL_SQ_QUANTIFIED),
2834
 
    GI_CONST_BITMAP(SQL_SR_CASCADE),
2835
 
    GI_CONST_BITMAP(SQL_SR_DELETE_TABLE),
2836
 
    GI_CONST_BITMAP(SQL_SR_GRANT_OPTION_FOR),
2837
 
    GI_CONST_BITMAP(SQL_SR_INSERT_COLUMN),
2838
 
    GI_CONST_BITMAP(SQL_SR_INSERT_TABLE),
2839
 
    GI_CONST_BITMAP(SQL_SRJO_CORRESPONDING_CLAUSE),
2840
 
    GI_CONST_BITMAP(SQL_SRJO_CROSS_JOIN),
2841
 
    GI_CONST_BITMAP(SQL_SRJO_EXCEPT_JOIN),
2842
 
    GI_CONST_BITMAP(SQL_SRJO_FULL_OUTER_JOIN),
2843
 
    GI_CONST_BITMAP(SQL_SRJO_INNER_JOIN),
2844
 
    GI_CONST_BITMAP(SQL_SRJO_INTERSECT_JOIN),
2845
 
    GI_CONST_BITMAP(SQL_SRJO_LEFT_OUTER_JOIN),
2846
 
    GI_CONST_BITMAP(SQL_SRJO_NATURAL_JOIN),
2847
 
    GI_CONST_BITMAP(SQL_SRJO_RIGHT_OUTER_JOIN),
2848
 
    GI_CONST_BITMAP(SQL_SRJO_UNION_JOIN),
2849
 
    GI_CONST_BITMAP(SQL_SR_REFERENCES_COLUMN),
2850
 
    GI_CONST_BITMAP(SQL_SR_REFERENCES_TABLE),
2851
 
    GI_CONST_BITMAP(SQL_SR_RESTRICT),
2852
 
    GI_CONST_BITMAP(SQL_SR_SELECT_TABLE),
2853
 
    GI_CONST_BITMAP(SQL_SR_UPDATE_COLUMN),
2854
 
    GI_CONST_BITMAP(SQL_SR_UPDATE_TABLE),
2855
 
    GI_CONST_BITMAP(SQL_SR_USAGE_ON_CHARACTER_SET),
2856
 
    GI_CONST_BITMAP(SQL_SR_USAGE_ON_COLLATION),
2857
 
    GI_CONST_BITMAP(SQL_SR_USAGE_ON_DOMAIN),
2858
 
    GI_CONST_BITMAP(SQL_SR_USAGE_ON_TRANSLATION),
2859
 
    GI_CONST_BITMAP(SQL_SRVC_DEFAULT),
2860
 
    GI_CONST_BITMAP(SQL_SRVC_NULL),
2861
 
    GI_CONST_BITMAP(SQL_SRVC_ROW_SUBQUERY),
2862
 
    GI_CONST_BITMAP(SQL_SRVC_VALUE_EXPRESSION),
2863
 
    GI_CONST_BITMAP(SQL_SS_ADDITIONS),
2864
 
    GI_CONST_BITMAP(SQL_SS_DELETIONS),
2865
 
    GI_CONST_BITMAP(SQL_SSF_CONVERT),
2866
 
    GI_CONST_BITMAP(SQL_SSF_LOWER),
2867
 
    GI_CONST_BITMAP(SQL_SSF_SUBSTRING),
2868
 
    GI_CONST_BITMAP(SQL_SSF_TRANSLATE),
2869
 
    GI_CONST_BITMAP(SQL_SSF_TRIM_BOTH),
2870
 
    GI_CONST_BITMAP(SQL_SSF_TRIM_LEADING),
2871
 
    GI_CONST_BITMAP(SQL_SSF_TRIM_TRAILING),
2872
 
    GI_CONST_BITMAP(SQL_SSF_UPPER),
2873
 
    GI_CONST_BITMAP(SQL_SS_UPDATES),
2874
 
    GI_CONST_BITMAP(SQL_SU_DML_STATEMENTS),
2875
 
    GI_CONST_BITMAP(SQL_SU_INDEX_DEFINITION),
2876
 
    GI_CONST_BITMAP(SQL_SU_PRIVILEGE_DEFINITION),
2877
 
    GI_CONST_BITMAP(SQL_SU_PROCEDURE_INVOCATION),
2878
 
    GI_CONST_BITMAP(SQL_SU_TABLE_DEFINITION),
2879
 
    GI_CONST_BITMAP(SQL_SVE_CASE),
2880
 
    GI_CONST_BITMAP(SQL_SVE_CAST),
2881
 
    GI_CONST_BITMAP(SQL_SVE_COALESCE),
2882
 
    GI_CONST_BITMAP(SQL_SVE_NULLIF),
2883
 
    GI_CONST_BITMAP(SQL_TC_ALL),
2884
 
    GI_CONST_BITMAP(SQL_TC_DDL_COMMIT),
2885
 
    GI_CONST_BITMAP(SQL_TC_DDL_IGNORE),
2886
 
    GI_CONST_BITMAP(SQL_TC_DML),
2887
 
    GI_CONST_BITMAP(SQL_TC_NONE),
2888
 
    GI_CONST_BITMAP(SQL_TRANSACTION_READ_COMMITTED),
2889
 
    GI_CONST_BITMAP(SQL_TRANSACTION_READ_UNCOMMITTED),
2890
 
    GI_CONST_BITMAP(SQL_TRANSACTION_REPEATABLE_READ),
2891
 
    GI_CONST_BITMAP(SQL_TRANSACTION_SERIALIZABLE),
2892
 
    GI_CONST_BITMAP(SQL_TXN_READ_COMMITTED),
2893
 
    GI_CONST_BITMAP(SQL_TXN_READ_UNCOMMITTED),
2894
 
    GI_CONST_BITMAP(SQL_TXN_REPEATABLE_READ),
2895
 
    GI_CONST_BITMAP(SQL_TXN_SERIALIZABLE),
2896
 
#ifdef SQL_TXN_VERSIONING
2897
 
    GI_CONST_BITMAP(SQL_TXN_VERSIONING),
2898
 
#endif
2899
 
    GI_CONST_BITMAP(SQL_US_UNION),
2900
 
    GI_CONST_BITMAP(SQL_US_UNION_ALL),
2901
 
    GI_CONST_BITMAP(SQL_U_UNION),
2902
 
    GI_CONST_BITMAP(SQL_U_UNION_ALL),
2903
 
 
2904
 
    /* end of table */
2905
 
    GI_CONST_BITMAP_END
2906
 
};
2907
 
 
2908
 
static VALUE
2909
 
dbc_getinfo(int argc, VALUE *argv, VALUE self)
2910
 
{
2911
 
    DBC *p = get_dbc(self);
2912
 
    VALUE which, vtype;
2913
 
    SQLRETURN ret;
2914
 
    int i, k, info = -1, maptype = -1, info_found = 0;
2915
 
    char buffer[513], *string = NULL;
2916
 
    SQLSMALLINT len_in = sizeof (buffer) - 1, len_out;
2917
 
 
2918
 
    rb_scan_args(argc, argv, "11", &which, &vtype);
2919
 
    switch (TYPE(which)) {
2920
 
    default:
2921
 
        string = STR2CSTR(rb_any_to_s(which));
2922
 
        goto doString;
2923
 
    case T_STRING:
2924
 
        string = STR2CSTR(which);
2925
 
    doString:
2926
 
        for (i = 0; get_info_map[i].name != NULL; i++) {
2927
 
            if (strcmp(string, get_info_map[i].name) == 0) {
2928
 
                info = get_info_map[i].info;
2929
 
                maptype = get_info_map[i].maptype;
2930
 
                info_found = 2;
2931
 
                break;
2932
 
            }
2933
 
        }
2934
 
        break;
2935
 
    case T_FLOAT:
2936
 
    case T_BIGNUM:
2937
 
        k = (int) NUM2DBL(which);
2938
 
        goto doInt;
2939
 
    case T_FIXNUM:
2940
 
        k = FIX2INT(which);
2941
 
    doInt:
2942
 
        info = k;
2943
 
        info_found = 1;
2944
 
        for (i = 0; get_info_map[i].name != NULL; i++) {
2945
 
            if (k == get_info_map[i].info) {
2946
 
                info = get_info_map[i].info;
2947
 
                maptype = get_info_map[i].maptype;
2948
 
                info_found = 3;
2949
 
                break;
2950
 
            }
2951
 
        }
2952
 
        break;
2953
 
    }
2954
 
    switch (info_found) {
2955
 
    case 0:
2956
 
        rb_raise(Cerror,
2957
 
                 set_err("Invalid info type for ODBC::Connection.get_info",
2958
 
                         0));
2959
 
        return Qnil;
2960
 
    case 1:
2961
 
        sprintf(buffer, "Unknown info type %d for ODBC::Connection.get_info",
2962
 
                info);
2963
 
        set_err(buffer, 1);
2964
 
        break;
2965
 
    }
2966
 
    if (vtype != Qnil) {
2967
 
        switch (TYPE(vtype)) {
2968
 
        case T_FIXNUM:
2969
 
            maptype = FIX2INT(vtype);
2970
 
            break;
2971
 
        case T_BIGNUM:
2972
 
        case T_FLOAT:
2973
 
            maptype = (int) NUM2DBL(vtype);
2974
 
            break;
2975
 
        default:
2976
 
            rb_raise(rb_eTypeError, "need number for sql_type");
2977
 
            return Qnil;
2978
 
        }
2979
 
        switch (maptype) {
2980
 
        case SQL_NUMERIC:
2981
 
        case SQL_DECIMAL:
2982
 
        case SQL_INTEGER:
2983
 
        case SQL_FLOAT:
2984
 
        case SQL_REAL:
2985
 
        case SQL_DOUBLE:
2986
 
        case SQL_C_ULONG:
2987
 
#ifdef SQL_BIGINT
2988
 
        case SQL_BIGINT:
2989
 
#endif
2990
 
#ifdef SQL_C_UBIGINT
2991
 
        case SQL_C_UBIGINT:
2992
 
#endif
2993
 
            maptype = SQL_C_LONG;
2994
 
            break;
2995
 
        case SQL_SMALLINT:
2996
 
        case SQL_TINYINT:
2997
 
        case SQL_C_USHORT:
2998
 
        case SQL_C_UTINYINT:
2999
 
            maptype = SQL_C_SHORT;
3000
 
            break;
3001
 
        default:
3002
 
            maptype = SQL_C_CHAR;
3003
 
            break;
3004
 
        }
3005
 
    }
3006
 
    memset(buffer, 0, sizeof (buffer));
3007
 
    ret = SQLGetInfo(p->hdbc, (SQLUSMALLINT) info,
3008
 
                     (SQLPOINTER) buffer, len_in, &len_out);
3009
 
    if (!SQL_SUCCEEDED(ret)) {
3010
 
        rb_raise(Cerror, "%s",
3011
 
                 get_err(SQL_NULL_HENV, p->hdbc, SQL_NULL_HSTMT));
3012
 
    }
3013
 
    switch (maptype) {
3014
 
    case SQL_C_SHORT:
3015
 
        return INT2NUM(*((SQLUSMALLINT *) buffer));
3016
 
    case SQL_C_LONG:
3017
 
        return INT2NUM(*((SQLUINTEGER *) buffer));
3018
 
    default:
3019
 
    case SQL_C_CHAR:
3020
 
        return rb_str_new(buffer, len_out);
3021
 
    }
3022
 
    return Qnil;
3023
 
}
3024
 
 
3025
 
/*
3026
 
 *----------------------------------------------------------------------
3027
 
 *
3028
 
 *      Fill column type array for statement.
3029
 
 *
3030
 
 *----------------------------------------------------------------------
3031
 
 */
3032
 
 
3033
 
static COLTYPE *
3034
 
make_coltypes(SQLHSTMT hstmt, int ncols, char **msgp)
3035
 
{
3036
 
    int i;
3037
 
    COLTYPE *ret = NULL;
3038
 
    SQLLEN type, size;
3039
 
 
3040
 
    for (i = 0; i < ncols; i++) {
3041
 
        SQLUSMALLINT ic = i + 1;
3042
 
 
3043
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3044
 
                       SQLColAttributes(hstmt, ic,
3045
 
                                        SQL_COLUMN_TYPE, NULL, 0, NULL,
3046
 
                                        &type),
3047
 
                       msgp, "SQLColAttributes(SQL_COLUMN_TYPE)")) {
3048
 
            return ret;
3049
 
        }
3050
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3051
 
                       SQLColAttributes(hstmt, ic,
3052
 
                                        SQL_COLUMN_DISPLAY_SIZE,
3053
 
                                        NULL, 0, NULL, &size),
3054
 
                       msgp, "SQLColAttributes(SQL_COLUMN_DISPLAY_SIZE)")) {
3055
 
            return ret;
3056
 
        }
3057
 
    }
3058
 
    ret = ALLOC_N(COLTYPE, ncols);
3059
 
    if (ret == NULL) {
3060
 
        if (msgp != NULL) {
3061
 
            *msgp = set_err("Out of memory", 0);
3062
 
        }
3063
 
        return NULL;
3064
 
    }
3065
 
    for (i = 0; i < ncols; i++) {
3066
 
        SQLUSMALLINT ic = i + 1;
3067
 
 
3068
 
        callsql(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3069
 
                SQLColAttributes(hstmt, ic,
3070
 
                                 SQL_COLUMN_TYPE,
3071
 
                                 NULL, 0, NULL, &type),
3072
 
                "SQLColAttributes(SQL_COLUMN_TYPE)");
3073
 
        callsql(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3074
 
                SQLColAttributes(hstmt, ic,
3075
 
                                 SQL_COLUMN_DISPLAY_SIZE,
3076
 
                                 NULL, 0, NULL, &size),
3077
 
                "SQLColAttributes(SQL_COLUMN_DISPLAY_SIZE)");
3078
 
        switch (type) {
3079
 
#ifdef SQL_BIT
3080
 
        case SQL_BIT:
3081
 
#endif
3082
 
#ifdef SQL_TINYINT
3083
 
        case SQL_TINYINT:
3084
 
#endif
3085
 
        case SQL_SMALLINT:
3086
 
        case SQL_INTEGER:
3087
 
            type = SQL_C_LONG;
3088
 
            size = sizeof (SQLINTEGER);
3089
 
            break;
3090
 
        case SQL_FLOAT:
3091
 
        case SQL_DOUBLE:
3092
 
        case SQL_REAL:
3093
 
            type = SQL_C_DOUBLE;
3094
 
            size = sizeof (double);
3095
 
            break;
3096
 
        case SQL_DATE:
3097
 
#ifdef SQL_TYPE_DATE
3098
 
        case SQL_TYPE_DATE:
3099
 
#endif
3100
 
            type = SQL_C_DATE;
3101
 
            size = sizeof (DATE_STRUCT);
3102
 
            break;
3103
 
        case SQL_TIME:
3104
 
#ifdef SQL_TYPE_TIME
3105
 
        case SQL_TYPE_TIME:
3106
 
#endif
3107
 
            type = SQL_C_TIME;
3108
 
            size = sizeof (TIME_STRUCT);
3109
 
            break;
3110
 
        case SQL_TIMESTAMP:
3111
 
#ifdef SQL_TYPE_TIMESTAMP
3112
 
        case SQL_TYPE_TIMESTAMP:
3113
 
#endif
3114
 
            type = SQL_C_TIMESTAMP;
3115
 
            size = sizeof (TIMESTAMP_STRUCT);
3116
 
            break;
3117
 
        case SQL_LONGVARBINARY:
3118
 
            type = SQL_C_BINARY;
3119
 
            size = SQL_NO_TOTAL;
3120
 
            break;
3121
 
        case SQL_LONGVARCHAR:
3122
 
#ifdef UNICODE
3123
 
        case SQL_WLONGVARCHAR:
3124
 
            type = SQL_C_WCHAR;
3125
 
#else
3126
 
            type = SQL_C_CHAR;
3127
 
#endif
3128
 
            size = SQL_NO_TOTAL;
3129
 
            break;
3130
 
#ifdef SQL_BIGINT
3131
 
        case SQL_BIGINT:
3132
 
            if (sizeof (SQLBIGINT) == sizeof (SQLINTEGER)) {
3133
 
                type = SQL_C_LONG;
3134
 
                size = sizeof (SQLINTEGER);
3135
 
            } else {
3136
 
                type = SQL_C_SBIGINT;
3137
 
                size = sizeof (SQLBIGINT);
3138
 
            }
3139
 
            break;
3140
 
#endif
3141
 
#ifdef SQL_UBIGINT
3142
 
        case SQL_UBIGINT:
3143
 
            if (sizeof (SQLBIGINT) == sizeof (SQLINTEGER)) {
3144
 
                type = SQL_C_LONG;
3145
 
                size = sizeof (SQLINTEGER);
3146
 
            } else {
3147
 
                type = SQL_C_UBIGINT;
3148
 
                size = sizeof (SQLBIGINT);
3149
 
            }
3150
 
            break;
3151
 
#endif
3152
 
        default:
3153
 
#ifdef UNICODE
3154
 
            type = SQL_C_WCHAR;
3155
 
            if (size != SQL_NO_TOTAL) {
3156
 
                size *= sizeof (SQLWCHAR);
3157
 
                size += sizeof (SQLWCHAR);
3158
 
            }
3159
 
#else
3160
 
            type = SQL_C_CHAR;
3161
 
            if (size != SQL_NO_TOTAL) {
3162
 
                size += 1;
3163
 
            }
3164
 
#endif
3165
 
            break;
3166
 
        }
3167
 
        ret[i].type = type;
3168
 
        ret[i].size = size;
3169
 
    }
3170
 
    return ret;
3171
 
}
3172
 
 
3173
 
/*
3174
 
 *----------------------------------------------------------------------
3175
 
 *
3176
 
 *      Fill parameter info array for statement.
3177
 
 *
3178
 
 *----------------------------------------------------------------------
3179
 
 */
3180
 
 
3181
 
static PINFO *
3182
 
make_pinfo(SQLHSTMT hstmt, int nump, char **msgp)
3183
 
{
3184
 
    int i;
3185
 
    PINFO *pinfo = NULL;
3186
 
 
3187
 
    pinfo = ALLOC_N(PINFO, nump);
3188
 
    if (pinfo == NULL) {
3189
 
        if (msgp != NULL) {
3190
 
            *msgp = set_err("Out of memory", 0);
3191
 
        }
3192
 
        return NULL;
3193
 
    }
3194
 
    for (i = 0; i < nump; i++) {
3195
 
        pinfo[i].iotype = SQL_PARAM_INPUT;
3196
 
        pinfo[i].outsize = 0;
3197
 
        pinfo[i].outbuf = NULL;
3198
 
        pinfo[i].rlen = SQL_NULL_DATA;
3199
 
        pinfo[i].ctype = SQL_C_CHAR;
3200
 
        pinfo[i].outtype = SQL_CHAR;
3201
 
        pinfo[i].coldef_max = 0;
3202
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3203
 
                       SQLDescribeParam(hstmt, (SQLUSMALLINT) (i + 1),
3204
 
                                        &pinfo[i].type, &pinfo[i].coldef,
3205
 
                                        &pinfo[i].scale,
3206
 
                                        &pinfo[i].nullable),
3207
 
                       NULL, "SQLDescribeParam")) {
3208
 
            pinfo[i].type = SQL_VARCHAR;
3209
 
            pinfo[i].coldef = 0;
3210
 
            pinfo[i].scale = 0;
3211
 
            pinfo[i].nullable = SQL_NULLABLE_UNKNOWN;
3212
 
            pinfo[i].override = 0;
3213
 
        }
3214
 
    }
3215
 
    return pinfo;
3216
 
}
3217
 
 
3218
 
static void
3219
 
retain_pinfo_override(STMT *q, int nump, PINFO *pinfo)
3220
 
{
3221
 
    if ((q->pinfo != NULL) && (q->nump == nump)) {
3222
 
        int i;
3223
 
 
3224
 
        for (i = 0; i < nump; i++) {
3225
 
            pinfo[i].iotype = q->pinfo[i].iotype;
3226
 
            pinfo[i].rlen = q->pinfo[i].rlen;
3227
 
            pinfo[i].ctype = q->pinfo[i].ctype;
3228
 
            pinfo[i].outtype = q->pinfo[i].outtype;
3229
 
            pinfo[i].outsize = q->pinfo[i].outsize;
3230
 
            if (q->pinfo[i].outbuf != NULL) {
3231
 
                pinfo[i].outbuf = q->pinfo[i].outbuf;
3232
 
                q->pinfo[i].outbuf = NULL;
3233
 
            }
3234
 
            if (q->pinfo[i].override) {
3235
 
                pinfo[i].override = q->pinfo[i].override;
3236
 
                pinfo[i].type = q->pinfo[i].type;
3237
 
                pinfo[i].coldef = q->pinfo[i].coldef;
3238
 
                pinfo[i].scale = q->pinfo[i].scale;
3239
 
            }
3240
 
        }
3241
 
    }
3242
 
}
3243
 
 
3244
 
/*
3245
 
 *----------------------------------------------------------------------
3246
 
 *
3247
 
 *      Wrap SQLHSTMT into struct/VALUE.
3248
 
 *
3249
 
 *----------------------------------------------------------------------
3250
 
 */
3251
 
 
3252
 
static VALUE
3253
 
wrap_stmt(VALUE dbc, DBC *p, SQLHSTMT hstmt, STMT **qp)
3254
 
{
3255
 
    VALUE stmt = Qnil;
3256
 
    STMT *q;
3257
 
 
3258
 
    stmt = Data_Make_Struct(Cstmt, STMT, mark_stmt, free_stmt, q);
3259
 
    tracemsg(2, fprintf(stderr, "ObjAlloc: STMT %p\n", q););
3260
 
    list_init(&q->link, offsetof(STMT, link));
3261
 
    q->self = stmt;
3262
 
    q->hstmt = hstmt;
3263
 
    q->dbc = dbc;
3264
 
    q->dbcp = NULL;
3265
 
    q->pinfo = NULL;
3266
 
    q->coltypes = NULL;
3267
 
    q->colnames = q->dbufs = NULL;
3268
 
    q->fetchc = 0;
3269
 
    q->upc = p->upc;
3270
 
    q->usef = 0;
3271
 
    rb_iv_set(q->self, "@_a", rb_ary_new());
3272
 
    rb_iv_set(q->self, "@_h", rb_hash_new());
3273
 
    link_stmt(q, p);
3274
 
    if (qp != NULL) {
3275
 
        *qp = q;
3276
 
    }
3277
 
    return stmt;
3278
 
}
3279
 
 
3280
 
/*
3281
 
 *----------------------------------------------------------------------
3282
 
 *
3283
 
 *      Create statement with result.
3284
 
 *
3285
 
 *----------------------------------------------------------------------
3286
 
 */
3287
 
 
3288
 
static VALUE
3289
 
make_result(VALUE dbc, SQLHSTMT hstmt, VALUE result, int mode)
3290
 
{
3291
 
    DBC *p;
3292
 
    STMT *q;
3293
 
    SQLSMALLINT cols = 0, nump;
3294
 
    COLTYPE *coltypes = NULL;
3295
 
    PINFO *pinfo = NULL;
3296
 
    char *msg = NULL;
3297
 
 
3298
 
    Data_Get_Struct(dbc, DBC, p);
3299
 
    if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3300
 
                   SQLNumParams(hstmt, &nump), NULL, "SQLNumParams")) {
3301
 
        nump = 0;
3302
 
    }
3303
 
    if (nump > 0) {
3304
 
        pinfo = make_pinfo(hstmt, nump, &msg);
3305
 
        if (pinfo == NULL) {
3306
 
            goto error;
3307
 
        }
3308
 
    }
3309
 
    if ((mode & MAKERES_PREPARE) ||
3310
 
        (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3311
 
                   SQLNumResultCols(hstmt, &cols), NULL,
3312
 
                   "SQLNumResultCols"))) {
3313
 
        cols = 0;
3314
 
    }
3315
 
    if (cols > 0) {
3316
 
        coltypes = make_coltypes(hstmt, cols, &msg);
3317
 
        if (coltypes == NULL) {
3318
 
            goto error;
3319
 
        }
3320
 
    }
3321
 
    if (result == Qnil) {
3322
 
        result = wrap_stmt(dbc, p, hstmt, &q);
3323
 
    } else {
3324
 
        Data_Get_Struct(result, STMT, q);
3325
 
        retain_pinfo_override(q, nump, pinfo);
3326
 
        free_stmt_sub(q);
3327
 
        if (q->dbc != dbc) {
3328
 
            unlink_stmt(q);
3329
 
            q->dbc = dbc;
3330
 
            link_stmt(q, p);
3331
 
        }
3332
 
        q->hstmt = hstmt;
3333
 
    }
3334
 
    q->nump = nump;
3335
 
    q->pinfo = pinfo;
3336
 
    q->ncols = cols;
3337
 
    q->coltypes = coltypes;
3338
 
    if ((mode & MAKERES_BLOCK) && rb_block_given_p()) {
3339
 
        if (mode & MAKERES_NOCLOSE) {
3340
 
            return rb_yield(result);
3341
 
        }
3342
 
        return rb_ensure(rb_yield, result, stmt_close, result);
3343
 
    }
3344
 
    return result;
3345
 
error:
3346
 
    callsql(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3347
 
            SQLFreeStmt(hstmt, SQL_DROP), "SQLFreeStmt(SQL_DROP)");
3348
 
    if (result != Qnil) {
3349
 
        Data_Get_Struct(result, STMT, q);
3350
 
        if (q->hstmt == hstmt) {
3351
 
            q->hstmt = SQL_NULL_HSTMT;
3352
 
            unlink_stmt(q);
3353
 
        }
3354
 
    }
3355
 
    if (pinfo != NULL) {
3356
 
        xfree(pinfo);
3357
 
    }
3358
 
    if (coltypes != NULL) {
3359
 
        xfree(coltypes);
3360
 
    }
3361
 
    rb_raise(Cerror, "%s", msg);
3362
 
    return Qnil;
3363
 
}
3364
 
 
3365
 
static char *
3366
 
upcase_if(char *string, int upc)
3367
 
{
3368
 
    if (upc && (string != NULL)) {
3369
 
        unsigned char *p = (unsigned char *) string;
3370
 
 
3371
 
        while (*p != '\0') {
3372
 
#ifdef UNICODE
3373
 
            if ((*p < 0x80) && ISLOWER(*p))
3374
 
#else
3375
 
            if (ISLOWER(*p))
3376
 
#endif
3377
 
            {
3378
 
                *p = toupper(*p);
3379
 
            }
3380
 
            ++p;
3381
 
        }
3382
 
    }
3383
 
    return string;
3384
 
}
3385
 
 
3386
 
/*
3387
 
 *----------------------------------------------------------------------
3388
 
 *
3389
 
 *      Constructor: make column from statement.
3390
 
 *
3391
 
 *----------------------------------------------------------------------
3392
 
 */
3393
 
 
3394
 
static VALUE
3395
 
make_col(SQLHSTMT hstmt, int i, int upc)
3396
 
{
3397
 
    VALUE obj, v;
3398
 
    SQLUSMALLINT ic = i + 1;
3399
 
    SQLLEN iv = 0;
3400
 
#ifdef UNICODE
3401
 
    SQLWCHAR name[SQL_MAX_MESSAGE_LENGTH];
3402
 
#else
3403
 
    char name[SQL_MAX_MESSAGE_LENGTH];
3404
 
#endif
3405
 
    char *msg;
3406
 
    SQLSMALLINT name_len;
3407
 
 
3408
 
    name[0] = 0;
3409
 
    if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3410
 
                   SQLColAttributes(hstmt, ic, SQL_COLUMN_LABEL, name,
3411
 
                                    (SQLSMALLINT) sizeof (name),
3412
 
                                    &name_len, NULL),
3413
 
                   &msg, "SQLColAttributes(SQL_COLUMN_LABEL)")) {
3414
 
        rb_raise(Cerror, "%s", msg);
3415
 
    }
3416
 
    obj = rb_obj_alloc(Ccolumn);
3417
 
    if (name_len >= sizeof (name)) {
3418
 
        name_len = sizeof (name) - 1;
3419
 
    }
3420
 
    if (name_len > 0) {
3421
 
        name[name_len / sizeof (name[0])] = 0;
3422
 
    }
3423
 
#ifdef UNICODE
3424
 
    if (upc) {
3425
 
        int len = uc_strlen(name);
3426
 
        char tmpbuf[1];
3427
 
        char *tmp = xmalloc(len);
3428
 
 
3429
 
        if (tmp == NULL) {
3430
 
            tmp = tmpbuf;
3431
 
            len = 0;
3432
 
        }
3433
 
        mkutf(tmp, name, len);
3434
 
        rb_iv_set(obj, "@name", rb_tainted_str_new2(upcase_if(tmp, 1)));
3435
 
        if ((tmp != NULL) && (tmp != tmpbuf)) {
3436
 
            xfree(tmp);
3437
 
        }
3438
 
    } else {
3439
 
        rb_iv_set(obj, "@name", uc_tainted_str_new2(name));
3440
 
    }
3441
 
#else
3442
 
    rb_iv_set(obj, "@name", rb_tainted_str_new2(upcase_if(name, upc)));
3443
 
#endif
3444
 
    v = Qnil;
3445
 
    name[0] = 0;
3446
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3447
 
                  SQLColAttributes(hstmt, ic, SQL_COLUMN_TABLE_NAME, name,
3448
 
                                   (SQLSMALLINT) sizeof (name),
3449
 
                                   &name_len, NULL),
3450
 
                  NULL, "SQLColAttributes(SQL_COLUMN_TABLE_NAME)")) {
3451
 
        if (name_len > sizeof (name)) {
3452
 
            name_len = sizeof (name) - 1;
3453
 
        }
3454
 
        if (name_len > 0) {
3455
 
            name[name_len / sizeof (name[0])] = 0;
3456
 
        }
3457
 
#ifdef UNICODE
3458
 
        v = uc_tainted_str_new2(name);
3459
 
#else
3460
 
        v = rb_tainted_str_new2(name);
3461
 
#endif
3462
 
    }
3463
 
    rb_iv_set(obj, "@table", v);
3464
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3465
 
                  SQLColAttributes(hstmt, ic, SQL_COLUMN_TYPE, NULL,
3466
 
                                   0, NULL, &iv),
3467
 
                  NULL, "SQLColAttributes(SQL_COLUMN_TYPE)")) {
3468
 
        v = INT2NUM(iv);
3469
 
    } else {
3470
 
        v = INT2NUM(SQL_UNKNOWN_TYPE);
3471
 
    }
3472
 
    rb_iv_set(obj, "@type", v);
3473
 
    v = Qnil;
3474
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3475
 
                  SQLColAttributes(hstmt, ic,
3476
 
#if (ODBCVER >= 0x0300)
3477
 
                                   SQL_DESC_LENGTH,
3478
 
#else
3479
 
                                   SQL_COLUMN_LENGTH,
3480
 
#endif
3481
 
                                   NULL, 0, NULL, &iv),
3482
 
                  NULL,
3483
 
#if (ODBCVER >= 0x0300)
3484
 
                  "SQLColAttributes(SQL_DESC_LENGTH)"
3485
 
#else
3486
 
                  "SQLColAttributes(SQL_COLUMN_LENGTH)"
3487
 
#endif
3488
 
        )) {
3489
 
        v = INT2NUM(iv);
3490
 
    } else if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3491
 
                         SQLColAttributes(hstmt, ic,
3492
 
                                          SQL_COLUMN_DISPLAY_SIZE, NULL,
3493
 
                                          0, NULL, &iv),
3494
 
                         NULL, "SQLColAttributes(SQL_COLUMN_DISPLAY_SIZE)")) {
3495
 
        v = INT2NUM(iv);
3496
 
    }
3497
 
    rb_iv_set(obj, "@length", v);
3498
 
    v = Qnil;
3499
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3500
 
                  SQLColAttributes(hstmt, ic, SQL_COLUMN_NULLABLE, NULL,
3501
 
                                   0, NULL, &iv),
3502
 
                  NULL, "SQLColAttributes(SQL_COLUMN_NULLABLE)")) {
3503
 
        v = (iv == SQL_NO_NULLS) ? Qfalse : Qtrue;
3504
 
    }
3505
 
    rb_iv_set(obj, "@nullable", v);
3506
 
    v = Qnil;
3507
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3508
 
                  SQLColAttributes(hstmt, ic, SQL_COLUMN_SCALE, NULL,
3509
 
                                   0, NULL, &iv),
3510
 
                  NULL, "SQLColAttributes(SQL_COLUMN_SCALE)")) {
3511
 
        v = INT2NUM(iv);
3512
 
    }
3513
 
    rb_iv_set(obj, "@scale", v);
3514
 
    v = Qnil;
3515
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3516
 
                  SQLColAttributes(hstmt, ic, SQL_COLUMN_PRECISION, NULL,
3517
 
                                   0, NULL, &iv),
3518
 
                  NULL, "SQLColAttributes(SQL_COLUMN_PRECISION)")) {
3519
 
        v = INT2NUM(iv);
3520
 
    }
3521
 
    rb_iv_set(obj, "@precision", v);
3522
 
    v = Qnil;
3523
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3524
 
                  SQLColAttributes(hstmt, ic, SQL_COLUMN_SEARCHABLE, NULL,
3525
 
                                   0, NULL, &iv),
3526
 
                  NULL, "SQLColAttributes(SQL_COLUMN_SEARCHABLE)")) {
3527
 
        v = (iv == SQL_NO_NULLS) ? Qfalse : Qtrue;
3528
 
    }
3529
 
    rb_iv_set(obj, "@searchable", v);
3530
 
    v = Qnil;
3531
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3532
 
                  SQLColAttributes(hstmt, ic, SQL_COLUMN_UNSIGNED, NULL,
3533
 
                                   0, NULL, &iv),
3534
 
                  NULL, "SQLColAttributes(SQL_COLUMN_UNSIGNED)")) {
3535
 
        v = (iv == SQL_NO_NULLS) ? Qfalse : Qtrue;
3536
 
    }
3537
 
    rb_iv_set(obj, "@unsigned", v);
3538
 
    v = Qnil;
3539
 
#ifdef SQL_COLUMN_AUTO_INCREMENT
3540
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3541
 
                  SQLColAttributes(hstmt, ic, SQL_COLUMN_AUTO_INCREMENT, NULL,
3542
 
                                   0, NULL, &iv),
3543
 
                  NULL, "SQLColAttributes(SQL_COLUMN_AUTO_INCREMENT)")) {
3544
 
        v = (iv == SQL_FALSE) ? Qfalse : Qtrue;
3545
 
    }
3546
 
#endif
3547
 
    rb_iv_set(obj, "@autoincrement", v);
3548
 
    return obj;
3549
 
}
3550
 
 
3551
 
/*
3552
 
 *----------------------------------------------------------------------
3553
 
 *
3554
 
 *      Constructor: make parameter from statement.
3555
 
 *
3556
 
 *----------------------------------------------------------------------
3557
 
 */
3558
 
 
3559
 
static VALUE
3560
 
make_par(STMT *q, int i)
3561
 
{
3562
 
    VALUE obj;
3563
 
    int v;
3564
 
 
3565
 
    obj = rb_obj_alloc(Cparam);
3566
 
    v = q->pinfo ? q->pinfo[i].type : SQL_VARCHAR;
3567
 
    rb_iv_set(obj, "@type", INT2NUM(v));
3568
 
    v = q->pinfo ? q->pinfo[i].coldef : 0;
3569
 
    rb_iv_set(obj, "@precision", INT2NUM(v));
3570
 
    v = q->pinfo ? q->pinfo[i].scale : 0;
3571
 
    rb_iv_set(obj, "@scale", INT2NUM(v));
3572
 
    v = q->pinfo ? q->pinfo[i].nullable : SQL_NULLABLE_UNKNOWN;
3573
 
    rb_iv_set(obj, "@nullable", INT2NUM(v));
3574
 
    v = q->pinfo ? q->pinfo[i].iotype : SQL_PARAM_INPUT;
3575
 
    rb_iv_set(obj, "@iotype", INT2NUM(v));
3576
 
    v = q->pinfo ? q->pinfo[i].outsize : 0;
3577
 
    rb_iv_set(obj, "@output_size", INT2NUM(v));
3578
 
    v = q->pinfo ? q->pinfo[i].outtype : SQL_CHAR;
3579
 
    rb_iv_set(obj, "@output_type", INT2NUM(v));
3580
 
    return obj;
3581
 
}
3582
 
 
3583
 
/*
3584
 
 *----------------------------------------------------------------------
3585
 
 *
3586
 
 *      Query tables/columns/keys/indexes/types of data source.
3587
 
 *
3588
 
 *----------------------------------------------------------------------
3589
 
 */
3590
 
 
3591
 
static VALUE
3592
 
dbc_info(int argc, VALUE *argv, VALUE self, int mode)
3593
 
{
3594
 
    DBC *p = get_dbc(self);
3595
 
    VALUE which = Qnil, which2 = Qnil, which3 = Qnil;
3596
 
#ifdef UNICODE
3597
 
    SQLWCHAR *swhich = NULL, *swhich2 = NULL;
3598
 
#else
3599
 
    SQLCHAR *swhich = NULL, *swhich2 = NULL;
3600
 
#endif
3601
 
    char *msg, *argspec = NULL;
3602
 
    SQLHSTMT hstmt;
3603
 
    int needstr = 1, itype = SQL_ALL_TYPES;
3604
 
    int iid = SQL_BEST_ROWID, iscope = SQL_SCOPE_CURROW;
3605
 
 
3606
 
    if (p->hdbc == SQL_NULL_HDBC) {
3607
 
        rb_raise(Cerror, set_err("No connection", 0));
3608
 
    }
3609
 
    switch (mode) {
3610
 
    case INFO_TYPES:
3611
 
        needstr = 0;
3612
 
        /* FALL THRU */
3613
 
    case INFO_TABLES:
3614
 
    case INFO_PRIMKEYS:
3615
 
    case INFO_TPRIV:
3616
 
    case INFO_PROCS:
3617
 
        argspec = "01";
3618
 
        break;
3619
 
    case INFO_COLUMNS:
3620
 
        argspec = "02";
3621
 
        break;
3622
 
    case INFO_INDEXES:
3623
 
    case INFO_FORKEYS:
3624
 
    case INFO_PROCCOLS:
3625
 
        argspec = "11";
3626
 
        break;
3627
 
    case INFO_SPECCOLS:
3628
 
        argspec = "12";
3629
 
        break;
3630
 
    default:
3631
 
        rb_raise(Cerror, set_err("Invalid info mode", 0));
3632
 
        break;
3633
 
    }
3634
 
    rb_scan_args(argc, argv, argspec, &which, &which2, &which3);
3635
 
    if (which != Qnil) {
3636
 
        if (needstr) {
3637
 
            Check_Type(which, T_STRING);
3638
 
#ifdef UNICODE
3639
 
            swhich = (SQLWCHAR *) which;
3640
 
#else
3641
 
            swhich = (SQLCHAR *) STR2CSTR(which);
3642
 
#endif
3643
 
        } else {
3644
 
            itype = NUM2INT(which);
3645
 
        }
3646
 
    }
3647
 
    if (which2 != Qnil) {
3648
 
        if (mode == INFO_SPECCOLS) {
3649
 
            iid = NUM2INT(which2);
3650
 
        } else if (mode != INFO_INDEXES) {
3651
 
            Check_Type(which2, T_STRING);
3652
 
#ifdef UNICODE
3653
 
            swhich2 = (SQLWCHAR *) which2;
3654
 
#else
3655
 
            swhich2 = (SQLCHAR *) STR2CSTR(which2);
3656
 
#endif
3657
 
        }
3658
 
    }
3659
 
#ifdef UNICODE
3660
 
    if (swhich != NULL) {
3661
 
        swhich = uc_from_utf((unsigned char *) STR2CSTR((VALUE) swhich), -1);
3662
 
        if (swhich == NULL) {
3663
 
            rb_raise(Cerror, set_err("Out of memory", 0));
3664
 
        }
3665
 
    }
3666
 
    if (swhich2 != NULL) {
3667
 
        swhich2 = uc_from_utf((unsigned char *) STR2CSTR((VALUE) swhich2), -1);
3668
 
        if (swhich2 == NULL) {
3669
 
            uc_free(swhich);
3670
 
            rb_raise(Cerror, set_err("Out of memory", 0));
3671
 
        }
3672
 
    }
3673
 
#endif
3674
 
    if (which3 != Qnil) {
3675
 
        iscope = NUM2INT(which3);
3676
 
    }
3677
 
    if (!succeeded(SQL_NULL_HENV, p->hdbc, SQL_NULL_HSTMT,
3678
 
                   SQLAllocStmt(p->hdbc, &hstmt), &msg, "SQLAllocStmt")) {
3679
 
#ifdef UNICODE
3680
 
        uc_free(swhich);
3681
 
        uc_free(swhich2);
3682
 
#endif
3683
 
        rb_raise(Cerror, "%s", msg);
3684
 
    }
3685
 
    switch (mode) {
3686
 
    case INFO_TABLES:
3687
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3688
 
                       SQLTables(hstmt, NULL, 0, NULL, 0,
3689
 
                                 swhich, (swhich == NULL) ? 0 : SQL_NTS,
3690
 
                                 NULL, 0),
3691
 
                       &msg, "SQLTables")) {
3692
 
            goto error;
3693
 
        }
3694
 
        break;
3695
 
    case INFO_COLUMNS:
3696
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3697
 
                       SQLColumns(hstmt, NULL, 0, NULL, 0,
3698
 
                                  swhich, (swhich == NULL) ? 0 : SQL_NTS,
3699
 
                                  swhich2, (swhich2 == NULL) ? 0 : SQL_NTS),
3700
 
                       &msg, "SQLColumns")) {
3701
 
            goto error;
3702
 
        }
3703
 
        break;
3704
 
    case INFO_PRIMKEYS:
3705
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3706
 
                       SQLPrimaryKeys(hstmt, NULL, 0, NULL, 0,
3707
 
                                      swhich, (swhich == NULL) ? 0 : SQL_NTS),
3708
 
                       &msg, "SQLPrimaryKeys")) {
3709
 
            goto error;
3710
 
        }
3711
 
        break;
3712
 
    case INFO_INDEXES:
3713
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3714
 
                       SQLStatistics(hstmt, NULL, 0, NULL, 0,
3715
 
                                     swhich, (swhich == NULL) ? 0 : SQL_NTS,
3716
 
                                     (SQLUSMALLINT) (RTEST(which2) ?
3717
 
                                      SQL_INDEX_UNIQUE : SQL_INDEX_ALL),
3718
 
                                     SQL_ENSURE),
3719
 
                       &msg, "SQLStatistics")) {
3720
 
            goto error;
3721
 
        }
3722
 
        break;
3723
 
    case INFO_TYPES:
3724
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3725
 
                       SQLGetTypeInfo(hstmt, (SQLSMALLINT) itype),
3726
 
                       &msg, "SQLGetTypeInfo")) {
3727
 
            goto error;
3728
 
        }
3729
 
        break;
3730
 
    case INFO_FORKEYS:
3731
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3732
 
                       SQLForeignKeys(hstmt, NULL, 0, NULL, 0,
3733
 
                                      swhich, (swhich == NULL) ? 0 : SQL_NTS,
3734
 
                                      NULL, 0, NULL, 0,
3735
 
                                      swhich2, (swhich2 == NULL) ? 0 : SQL_NTS),
3736
 
                       &msg, "SQLForeignKeys")) {
3737
 
            goto error;
3738
 
        }
3739
 
        break;
3740
 
    case INFO_TPRIV:
3741
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3742
 
                       SQLTablePrivileges(hstmt, NULL, 0, NULL, 0, swhich,
3743
 
                                          (swhich == NULL) ? 0 : SQL_NTS),
3744
 
                       &msg, "SQLTablePrivileges")) {
3745
 
            goto error;
3746
 
        }
3747
 
        break;
3748
 
    case INFO_PROCS:
3749
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3750
 
                       SQLProcedures(hstmt, NULL, 0, NULL, 0,
3751
 
                                     swhich, (swhich == NULL) ? 0 : SQL_NTS),
3752
 
                       &msg, "SQLProcedures")) {
3753
 
            goto error;
3754
 
        }
3755
 
        break;
3756
 
    case INFO_PROCCOLS:
3757
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3758
 
                       SQLProcedureColumns(hstmt, NULL, 0, NULL, 0,
3759
 
                                           swhich,
3760
 
                                           (swhich == NULL) ? 0 : SQL_NTS,
3761
 
                                           swhich2,
3762
 
                                           (swhich2 == NULL) ? 0 : SQL_NTS),
3763
 
                       &msg, "SQLProcedureColumns")) {
3764
 
            goto error;
3765
 
        }
3766
 
        break;
3767
 
    case INFO_SPECCOLS:
3768
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3769
 
                       SQLSpecialColumns(hstmt, (SQLUSMALLINT) iid,
3770
 
                                         NULL, 0, NULL, 0,
3771
 
                                         swhich,
3772
 
                                         (swhich == NULL) ? 0 : SQL_NTS,
3773
 
                                         (SQLUSMALLINT) iscope,
3774
 
                                         SQL_NULLABLE),
3775
 
                       &msg, "SQLSpecialColumns")) {
3776
 
            goto error;
3777
 
        }
3778
 
        break;
3779
 
    }
3780
 
#ifdef UNICODE
3781
 
    uc_free(swhich);
3782
 
    uc_free(swhich2);
3783
 
#endif
3784
 
    return make_result(self, hstmt, Qnil, MAKERES_BLOCK);
3785
 
error:
3786
 
#ifdef UNICODE
3787
 
    uc_free(swhich);
3788
 
    uc_free(swhich2);
3789
 
#endif
3790
 
    callsql(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3791
 
            SQLFreeStmt(hstmt, SQL_DROP), "SQLFreeStmt(SQL_DROP)");
3792
 
    rb_raise(Cerror, "%s", msg);
3793
 
    return Qnil;
3794
 
}
3795
 
 
3796
 
static VALUE
3797
 
dbc_tables(int argc, VALUE *argv, VALUE self)
3798
 
{
3799
 
    return dbc_info(argc, argv, self, INFO_TABLES);
3800
 
}
3801
 
 
3802
 
static VALUE
3803
 
dbc_columns(int argc, VALUE *argv, VALUE self)
3804
 
{
3805
 
    return dbc_info(argc, argv, self, INFO_COLUMNS);
3806
 
}
3807
 
 
3808
 
static VALUE
3809
 
dbc_primkeys(int argc, VALUE *argv, VALUE self)
3810
 
{
3811
 
    return dbc_info(argc, argv, self, INFO_PRIMKEYS);
3812
 
}
3813
 
 
3814
 
static VALUE
3815
 
dbc_indexes(int argc, VALUE *argv, VALUE self)
3816
 
{
3817
 
    return dbc_info(argc, argv, self, INFO_INDEXES);
3818
 
}
3819
 
 
3820
 
static VALUE
3821
 
dbc_types(int argc, VALUE *argv, VALUE self)
3822
 
{
3823
 
    return dbc_info(argc, argv, self, INFO_TYPES);
3824
 
}
3825
 
 
3826
 
static VALUE
3827
 
dbc_forkeys(int argc, VALUE *argv, VALUE self)
3828
 
{
3829
 
    return dbc_info(argc, argv, self, INFO_FORKEYS);
3830
 
}
3831
 
 
3832
 
static VALUE
3833
 
dbc_tpriv(int argc, VALUE *argv, VALUE self)
3834
 
{
3835
 
    return dbc_info(argc, argv, self, INFO_TPRIV);
3836
 
}
3837
 
 
3838
 
static VALUE
3839
 
dbc_procs(int argc, VALUE *argv, VALUE self)
3840
 
{
3841
 
    return dbc_info(argc, argv, self, INFO_PROCS);
3842
 
}
3843
 
 
3844
 
static VALUE
3845
 
dbc_proccols(int argc, VALUE *argv, VALUE self)
3846
 
{
3847
 
    return dbc_info(argc, argv, self, INFO_PROCCOLS);
3848
 
}
3849
 
 
3850
 
static VALUE
3851
 
dbc_speccols(int argc, VALUE *argv, VALUE self)
3852
 
{
3853
 
    return dbc_info(argc, argv, self, INFO_SPECCOLS);
3854
 
}
3855
 
 
3856
 
/*
3857
 
 *----------------------------------------------------------------------
3858
 
 *
3859
 
 *      Transaction stuff.
3860
 
 *
3861
 
 *----------------------------------------------------------------------
3862
 
 */
3863
 
 
3864
 
static VALUE
3865
 
dbc_trans(VALUE self, int what)
3866
 
{
3867
 
    ENV *e;
3868
 
    SQLHDBC dbc = SQL_NULL_HDBC;
3869
 
    char *msg;
3870
 
 
3871
 
    e = get_env(self);
3872
 
    if (rb_obj_is_kind_of(self, Cdbc) == Qtrue) {
3873
 
        DBC *d;
3874
 
 
3875
 
        d = get_dbc(self);
3876
 
        dbc = d->hdbc;
3877
 
    }
3878
 
    if (!succeeded(e->henv, dbc, SQL_NULL_HSTMT,
3879
 
#if (ODBCVER >= 0x0300)
3880
 
                   SQLEndTran((SQLSMALLINT)
3881
 
                              ((dbc == SQL_NULL_HDBC) ? SQL_HANDLE_ENV :
3882
 
                                                        SQL_HANDLE_DBC),
3883
 
                              (dbc == SQL_NULL_HDBC) ? e->henv : dbc,
3884
 
                              (SQLSMALLINT) what),
3885
 
                   &msg, "SQLEndTran"
3886
 
#else
3887
 
                   SQLTransact(e->henv, dbc, (SQLUSMALLINT) what),
3888
 
                   &msg, "SQLTransact"
3889
 
#endif
3890
 
       )) {
3891
 
        rb_raise(Cerror, "%s", msg);
3892
 
    }
3893
 
    return Qnil;
3894
 
}
3895
 
 
3896
 
static VALUE
3897
 
dbc_commit(VALUE self)
3898
 
{
3899
 
    return dbc_trans(self, SQL_COMMIT);
3900
 
}
3901
 
 
3902
 
static VALUE
3903
 
dbc_rollback(VALUE self)
3904
 
{
3905
 
    return dbc_trans(self, SQL_ROLLBACK);
3906
 
}
3907
 
 
3908
 
static VALUE
3909
 
dbc_nop(VALUE self)
3910
 
{
3911
 
    return Qnil;
3912
 
}
3913
 
 
3914
 
static VALUE
3915
 
dbc_transbody(VALUE self)
3916
 
{
3917
 
    return rb_yield(rb_ary_entry(self, 0));
3918
 
}
3919
 
 
3920
 
static VALUE
3921
 
dbc_transfail(VALUE self, VALUE err)
3922
 
{
3923
 
    rb_ary_store(self, 1, err);
3924
 
    dbc_rollback(rb_ary_entry(self, 0));
3925
 
    return Qundef;
3926
 
}
3927
 
 
3928
 
static VALUE
3929
 
dbc_transaction(VALUE self)
3930
 
{
3931
 
    VALUE a, ret;
3932
 
 
3933
 
    if (!rb_block_given_p()) {
3934
 
        rb_raise(rb_eArgError, "block required");
3935
 
    }
3936
 
    rb_ensure(dbc_commit, self, dbc_nop, self);
3937
 
    a = rb_ary_new2(2);
3938
 
    rb_ary_store(a, 0, self);
3939
 
    rb_ary_store(a, 1, Qnil);
3940
 
    if ((ret = rb_rescue2(dbc_transbody, a, dbc_transfail, a,
3941
 
                          rb_eException)) != Qundef) {
3942
 
        dbc_commit(self);
3943
 
        return ret;
3944
 
    }
3945
 
    ret = rb_ary_entry(a, 1);
3946
 
    rb_exc_raise(rb_exc_new3(CLASS_OF(ret), ret));
3947
 
    return Qnil;
3948
 
}
3949
 
 
3950
 
/*
3951
 
 *----------------------------------------------------------------------
3952
 
 *
3953
 
 *      Environment attribute handling.
3954
 
 *
3955
 
 *----------------------------------------------------------------------
3956
 
 */
3957
 
 
3958
 
#if (ODBCVER >= 0x0300)
3959
 
static VALUE
3960
 
do_attr(int argc, VALUE *argv, VALUE self, int op)
3961
 
{
3962
 
    SQLHENV henv = SQL_NULL_HENV;
3963
 
    VALUE val;
3964
 
    SQLLEN v = 0;
3965
 
    SQLPOINTER vp;
3966
 
    SQLINTEGER l;
3967
 
    char *msg;
3968
 
 
3969
 
    if (self != Modbc) {
3970
 
        henv = get_env(self)->henv;
3971
 
    }
3972
 
    rb_scan_args(argc, argv, "01", &val);
3973
 
    if (val == Qnil) {
3974
 
        if (!succeeded(henv, SQL_NULL_HDBC, SQL_NULL_HSTMT,
3975
 
                       SQLGetEnvAttr(henv, (SQLINTEGER) op,
3976
 
                                     (SQLPOINTER) &v, sizeof (v), &l),
3977
 
                       &msg, "SQLGetEnvAttr(%d)", op)) {
3978
 
            rb_raise(Cerror, "%s", msg);
3979
 
        }
3980
 
        return rb_int2inum(v);
3981
 
    }
3982
 
    v = NUM2INT(val);
3983
 
    vp = (SQLPOINTER) v;
3984
 
    if (!succeeded(henv, SQL_NULL_HDBC, SQL_NULL_HSTMT,
3985
 
                   SQLSetEnvAttr(henv, (SQLINTEGER) op, vp, SQL_IS_INTEGER),
3986
 
                   &msg, "SQLSetEnvAttr(%d)", op)) {
3987
 
        rb_raise(Cerror, "%s", msg);
3988
 
    }
3989
 
    return Qnil;
3990
 
}
3991
 
#endif
3992
 
 
3993
 
static VALUE
3994
 
env_cpooling(int argc, VALUE *argv, VALUE self)
3995
 
{
3996
 
#if (ODBCVER >= 0x0300)
3997
 
    return do_attr(argc, argv, self, SQL_ATTR_CONNECTION_POOLING);
3998
 
#else
3999
 
    rb_raise(Cerror, set_err("Unsupported in ODBC < 3.0", 0));
4000
 
    return Qnil;
4001
 
#endif
4002
 
}
4003
 
 
4004
 
static VALUE
4005
 
env_cpmatch(int argc, VALUE *argv, VALUE self)
4006
 
{
4007
 
#if (ODBCVER >= 0x0300)
4008
 
    return do_attr(argc, argv, self, SQL_ATTR_CP_MATCH);
4009
 
#else
4010
 
    rb_raise(Cerror, set_err("Unsupported in ODBC < 3.0", 0));
4011
 
    return Qnil;
4012
 
#endif
4013
 
}
4014
 
 
4015
 
static VALUE
4016
 
env_odbcver(int argc, VALUE *argv, VALUE self)
4017
 
{
4018
 
#if (ODBCVER >= 0x0300)
4019
 
    return do_attr(argc, argv, self, SQL_ATTR_ODBC_VERSION);
4020
 
#else
4021
 
    VALUE val;
4022
 
 
4023
 
    rb_scan_args(argc, argv, "01", &val);
4024
 
    if (val == Qnil) {
4025
 
        return rb_int2inum(ODBCVER >> 8);
4026
 
    }
4027
 
    rb_raise(Cerror, set_err("Unsupported in ODBC < 3.0", 0));
4028
 
#endif
4029
 
}
4030
 
 
4031
 
/*
4032
 
 *----------------------------------------------------------------------
4033
 
 *
4034
 
 *      Connection/statement option handling.
4035
 
 *
4036
 
 *      Note:
4037
 
 *      ODBC 2 allows statement options to be set using SQLSetConnectOption,
4038
 
 *      establishing the statement option as a default for any hstmts
4039
 
 *      later allocated for that hdbc. This feature was deprecated in
4040
 
 *      ODBC 3.x and may not work with ODBC 3.x drivers.
4041
 
 *
4042
 
 *      Although the Database class includes attribute accessors for
4043
 
 *      statement-level options, a safer alternative, if using an ODBC 3
4044
 
 *      driver, is to set the option directly on the Statement instance.
4045
 
 *
4046
 
 *----------------------------------------------------------------------
4047
 
 */
4048
 
 
4049
 
#define OPT_LEVEL_STMT         1
4050
 
#define OPT_LEVEL_DBC          2
4051
 
#define OPT_LEVEL_BOTH         (OPT_LEVEL_STMT | OPT_LEVEL_DBC)
4052
 
 
4053
 
#define OPT_CONST_INT(x, level) { #x, x, level }
4054
 
#define OPT_CONST_END    { NULL, -1 }
4055
 
static struct {
4056
 
    char *name;
4057
 
    int option;
4058
 
    int level;
4059
 
} option_map[] = {
4060
 
 
4061
 
    /* yielding ints */
4062
 
    OPT_CONST_INT(SQL_AUTOCOMMIT, OPT_LEVEL_DBC),
4063
 
    OPT_CONST_INT(SQL_NOSCAN, OPT_LEVEL_BOTH),
4064
 
    OPT_CONST_INT(SQL_CONCURRENCY, OPT_LEVEL_BOTH),
4065
 
    OPT_CONST_INT(SQL_QUERY_TIMEOUT, OPT_LEVEL_BOTH),
4066
 
    OPT_CONST_INT(SQL_MAX_ROWS, OPT_LEVEL_BOTH),
4067
 
    OPT_CONST_INT(SQL_MAX_LENGTH, OPT_LEVEL_BOTH),
4068
 
    OPT_CONST_INT(SQL_ROWSET_SIZE, OPT_LEVEL_BOTH),
4069
 
    OPT_CONST_INT(SQL_CURSOR_TYPE, OPT_LEVEL_BOTH),
4070
 
 
4071
 
    /* end of table */
4072
 
    OPT_CONST_END
4073
 
};
4074
 
 
4075
 
static VALUE
4076
 
do_option(int argc, VALUE *argv, VALUE self, int isstmt, int op)
4077
 
{
4078
 
    DBC *p = NULL;
4079
 
    STMT *q = NULL;
4080
 
    VALUE val, val2;
4081
 
    SQLINTEGER v;
4082
 
    char *msg;
4083
 
    int level = isstmt ? OPT_LEVEL_STMT : OPT_LEVEL_DBC;
4084
 
 
4085
 
    rb_scan_args(argc, argv, (op == -1) ? "11" : "01", &val, &val2);
4086
 
    if (isstmt) {
4087
 
        Data_Get_Struct(self, STMT, q);
4088
 
        if (q->dbc == Qnil) {
4089
 
            rb_raise(Cerror, set_err("Stale ODBC::Statement", 0));
4090
 
        }
4091
 
        if (q->hstmt == SQL_NULL_HSTMT) {
4092
 
            rb_raise(Cerror, set_err("No statement", 0));
4093
 
        }
4094
 
    } else {
4095
 
        p = get_dbc(self);
4096
 
        if (p->hdbc == SQL_NULL_HDBC) {
4097
 
            rb_raise(Cerror, set_err("No connection", 0));
4098
 
        }
4099
 
    }
4100
 
    if (op == -1) {
4101
 
        char *string;
4102
 
        int i, op_found = 0;
4103
 
 
4104
 
        switch (TYPE(val)) {
4105
 
        default:
4106
 
            string = STR2CSTR(rb_any_to_s(val));
4107
 
            goto doString;
4108
 
        case T_STRING:
4109
 
            string = STR2CSTR(val);
4110
 
        doString:
4111
 
            for (i = 0; option_map[i].name != NULL; i++) {
4112
 
                if (strcmp(string, option_map[i].name) == 0) {
4113
 
                    op = option_map[i].option;
4114
 
                    level = option_map[i].level;
4115
 
                    op_found = 3;
4116
 
                    break;
4117
 
                }
4118
 
            }
4119
 
            break;
4120
 
        case T_FLOAT:
4121
 
        case T_BIGNUM:
4122
 
            op = (int) NUM2DBL(val);
4123
 
            goto doInt;
4124
 
        case T_FIXNUM:
4125
 
            op = FIX2INT(val);
4126
 
        doInt:
4127
 
            op_found = 1;
4128
 
            for (i = 0; option_map[i].name != NULL; i++) {
4129
 
                if (op == option_map[i].option) {
4130
 
                    level = option_map[i].level;
4131
 
                    op_found = 2;
4132
 
                    break;
4133
 
                }
4134
 
            }
4135
 
            break;
4136
 
        }
4137
 
        if (!op_found) {
4138
 
            rb_raise(Cerror, set_err("Unknown option", 0));
4139
 
            return Qnil;
4140
 
        }
4141
 
        val = val2;
4142
 
    }
4143
 
    if ((isstmt && (!(level & OPT_LEVEL_STMT))) ||
4144
 
        (!isstmt && (!(level & OPT_LEVEL_DBC)))) {
4145
 
        rb_raise(Cerror, set_err("Invalid option type for this level", 0));
4146
 
        return Qnil;
4147
 
    }
4148
 
    if (val == Qnil) {
4149
 
        if (p != NULL) {
4150
 
            if (!succeeded(SQL_NULL_HENV, p->hdbc, SQL_NULL_HSTMT,
4151
 
                           SQLGetConnectOption(p->hdbc, (SQLUSMALLINT) op,
4152
 
                                               (SQLPOINTER) &v),
4153
 
                           &msg, "SQLGetConnectOption(%d)", op)) {
4154
 
                rb_raise(Cerror, "%s", msg);
4155
 
            }
4156
 
        } else {
4157
 
            if (!succeeded(SQL_NULL_HENV, SQL_NULL_HSTMT, q->hstmt,
4158
 
                           SQLGetStmtOption(q->hstmt, (SQLUSMALLINT) op,
4159
 
                                            (SQLPOINTER) &v),
4160
 
                           &msg, "SQLGetStmtOption(%d)", op)) {
4161
 
                rb_raise(Cerror, "%s", msg);
4162
 
            }
4163
 
        }
4164
 
    }
4165
 
    switch (op) {
4166
 
    case SQL_AUTOCOMMIT:
4167
 
        if (val == Qnil) {
4168
 
            return v ? Qtrue : Qfalse;
4169
 
        }
4170
 
        v = (TYPE(val) == T_FIXNUM) ?  
4171
 
            (FIX2INT(val) ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF) : 
4172
 
            (RTEST(val) ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
4173
 
        break;
4174
 
 
4175
 
    case SQL_NOSCAN:
4176
 
        if (val == Qnil) {
4177
 
            return v ? Qtrue : Qfalse;
4178
 
        }
4179
 
        v = (TYPE(val) == T_FIXNUM) ?  
4180
 
            (FIX2INT(val) ? SQL_NOSCAN_ON : SQL_NOSCAN_OFF) : 
4181
 
            (RTEST(val) ? SQL_NOSCAN_ON : SQL_NOSCAN_OFF);
4182
 
        break;
4183
 
 
4184
 
    case SQL_CONCURRENCY:
4185
 
    case SQL_QUERY_TIMEOUT:
4186
 
    case SQL_MAX_ROWS:
4187
 
    case SQL_MAX_LENGTH:
4188
 
    case SQL_ROWSET_SIZE:
4189
 
    case SQL_CURSOR_TYPE:
4190
 
    default:
4191
 
        if (val == Qnil) {
4192
 
            return rb_int2inum(v);
4193
 
        }
4194
 
        Check_Type(val, T_FIXNUM);
4195
 
        v = FIX2INT(val);
4196
 
        if (op == SQL_ROWSET_SIZE) {
4197
 
            rb_raise(Cerror, set_err("Read only attribute", 0));
4198
 
        }
4199
 
        break;
4200
 
    }
4201
 
    if (p != NULL) {
4202
 
        if (!succeeded(SQL_NULL_HENV, p->hdbc, SQL_NULL_HSTMT,
4203
 
                       SQLSetConnectOption(p->hdbc, (SQLUSMALLINT) op,
4204
 
                                           (SQLUINTEGER) v),
4205
 
                       &msg, "SQLSetConnectOption(%d)", op)) {
4206
 
            rb_raise(Cerror, "%s", msg);
4207
 
        }
4208
 
    } else {
4209
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, 
4210
 
                       SQLSetStmtOption(q->hstmt, (SQLUSMALLINT) op,
4211
 
                                        (SQLUINTEGER) v),
4212
 
                       &msg, "SQLSetStmtOption(%d)", op)) {
4213
 
            rb_raise(Cerror, "%s", msg);
4214
 
        }
4215
 
    }
4216
 
    return Qnil;
4217
 
}
4218
 
 
4219
 
static VALUE
4220
 
dbc_autocommit(int argc, VALUE *argv, VALUE self)
4221
 
{
4222
 
    return do_option(argc, argv, self, 0, SQL_AUTOCOMMIT);
4223
 
}
4224
 
 
4225
 
static VALUE
4226
 
dbc_concurrency(int argc, VALUE *argv, VALUE self)
4227
 
{
4228
 
    return do_option(argc, argv, self, 0, SQL_CONCURRENCY);
4229
 
}
4230
 
 
4231
 
static VALUE
4232
 
dbc_maxrows(int argc, VALUE *argv, VALUE self)
4233
 
{
4234
 
    return do_option(argc, argv, self, 0, SQL_MAX_ROWS);
4235
 
}
4236
 
 
4237
 
static VALUE
4238
 
dbc_timeout(int argc, VALUE *argv, VALUE self)
4239
 
{
4240
 
    return do_option(argc, argv, self, 0, SQL_QUERY_TIMEOUT);
4241
 
}
4242
 
 
4243
 
static VALUE
4244
 
dbc_maxlength(int argc, VALUE *argv, VALUE self)
4245
 
{
4246
 
    return do_option(argc, argv, self, 0, SQL_MAX_LENGTH);
4247
 
}
4248
 
 
4249
 
static VALUE
4250
 
dbc_rowsetsize(int argc, VALUE *argv, VALUE self)
4251
 
{
4252
 
    return do_option(argc, argv, self, 0, SQL_ROWSET_SIZE);
4253
 
}
4254
 
 
4255
 
static VALUE
4256
 
dbc_cursortype(int argc, VALUE *argv, VALUE self)
4257
 
{
4258
 
    return do_option(argc, argv, self, 0, SQL_CURSOR_TYPE);
4259
 
}
4260
 
 
4261
 
static VALUE
4262
 
dbc_noscan(int argc, VALUE *argv, VALUE self)
4263
 
{
4264
 
    return do_option(argc, argv, self, 0, SQL_NOSCAN);
4265
 
}
4266
 
 
4267
 
static VALUE
4268
 
dbc_getsetoption(int argc, VALUE *argv, VALUE self)
4269
 
{
4270
 
    return do_option(argc, argv, self, 0, -1);
4271
 
}
4272
 
 
4273
 
static VALUE
4274
 
stmt_concurrency(int argc, VALUE *argv, VALUE self)
4275
 
{
4276
 
    return do_option(argc, argv, self, 1, SQL_CONCURRENCY);
4277
 
}
4278
 
 
4279
 
static VALUE
4280
 
stmt_maxrows(int argc, VALUE *argv, VALUE self)
4281
 
{
4282
 
    return do_option(argc, argv, self, 1, SQL_MAX_ROWS);
4283
 
}
4284
 
 
4285
 
static VALUE
4286
 
stmt_timeout(int argc, VALUE *argv, VALUE self)
4287
 
{
4288
 
    return do_option(argc, argv, self, 1, SQL_QUERY_TIMEOUT);
4289
 
}
4290
 
 
4291
 
static VALUE
4292
 
stmt_maxlength(int argc, VALUE *argv, VALUE self)
4293
 
{
4294
 
    return do_option(argc, argv, self, 1, SQL_MAX_LENGTH);
4295
 
}
4296
 
 
4297
 
static VALUE
4298
 
stmt_rowsetsize(int argc, VALUE *argv, VALUE self)
4299
 
{
4300
 
    return do_option(argc, argv, self, 1, SQL_ROWSET_SIZE);
4301
 
}
4302
 
 
4303
 
static VALUE
4304
 
stmt_cursortype(int argc, VALUE *argv, VALUE self)
4305
 
{
4306
 
    return do_option(argc, argv, self, 1, SQL_CURSOR_TYPE);
4307
 
}
4308
 
 
4309
 
static VALUE
4310
 
stmt_noscan(int argc, VALUE *argv, VALUE self)
4311
 
{
4312
 
    return do_option(argc, argv, self, 1, SQL_NOSCAN);
4313
 
}
4314
 
 
4315
 
static VALUE
4316
 
stmt_getsetoption(int argc, VALUE *argv, VALUE self)
4317
 
{
4318
 
    return do_option(argc, argv, self, 1, -1);
4319
 
}
4320
 
 
4321
 
/*
4322
 
 *----------------------------------------------------------------------
4323
 
 *
4324
 
 *      Scan literal date/time/timestamp to TIMESTAMP_STRUCT.
4325
 
 *
4326
 
 *----------------------------------------------------------------------
4327
 
 */
4328
 
 
4329
 
static int
4330
 
scan_dtts(VALUE str, int do_d, int do_t, TIMESTAMP_STRUCT *ts)
4331
 
{
4332
 
    int yy = 0, mm = 0, dd = 0, hh = 0, mmm = 0, ss = 0, ff = 0, i;
4333
 
    char c, *cstr = STR2CSTR(str);
4334
 
 
4335
 
    memset(ts, 0, sizeof (TIMESTAMP_STRUCT));
4336
 
    if (((sscanf(cstr, "{ts '%d-%d-%d %d:%d:%d.%d' %c",
4337
 
                 &yy, &mm, &dd, &hh, &mmm, &ss, &ff, &c) == 8) ||
4338
 
         (sscanf(cstr, "{ts '%d-%d-%d %d:%d:%d' %c",
4339
 
                 &yy, &mm, &dd, &hh, &mmm, &ss, &c) == 7)) &&
4340
 
        (c == '}')) {
4341
 
        ts->year = yy;
4342
 
        ts->month = mm;
4343
 
        ts->day = dd;
4344
 
        ts->hour = hh;
4345
 
        ts->minute = mmm;
4346
 
        ts->second = ss;
4347
 
        ts->fraction = ff;
4348
 
        return 1;
4349
 
    }
4350
 
    if (do_d &&
4351
 
        (sscanf(cstr, "{d '%d-%d-%d' %c", &yy, &mm, &dd, &c) == 4) &&
4352
 
        (c == '}')) {
4353
 
        ts->year = yy;
4354
 
        ts->month = mm;
4355
 
        ts->day = dd;
4356
 
        return 1;
4357
 
    }
4358
 
    if (do_t && 
4359
 
        (sscanf(cstr, "{t '%d:%d:%d' %c", &hh, &mmm, &ss, &c) == 4) &&
4360
 
        (c == '}')) {
4361
 
        ts->hour = yy;
4362
 
        ts->minute = mmm;
4363
 
        ts->second = ss;
4364
 
        return 1;
4365
 
    }
4366
 
    ff = ss = 0;
4367
 
    i = sscanf(cstr, "%d-%d-%d %d:%d:%d%c%d",
4368
 
               &yy, &mm, &dd, &hh, &mmm, &ss, &c, &ff);
4369
 
    if (i >= 5) {
4370
 
        if ((i > 6) && (strchr(". \t", c) == NULL)) {
4371
 
            goto next;
4372
 
        }
4373
 
        ts->year = yy;
4374
 
        ts->month = mm;
4375
 
        ts->day = dd;
4376
 
        ts->hour = hh;
4377
 
        ts->minute = mmm;
4378
 
        ts->second = ss;
4379
 
        ts->fraction = ff;
4380
 
        return 1;
4381
 
    }
4382
 
next:
4383
 
    ff = ss = 0;
4384
 
    if (do_d && (sscanf(cstr, "%d-%d-%d", &yy, &mm, &dd) == 3)) {
4385
 
        ts->year = yy;
4386
 
        ts->month = mm;
4387
 
        ts->day = dd;
4388
 
        return 1;
4389
 
    }
4390
 
    if (do_t && (sscanf(cstr, "%d:%d:%d", &hh, &mmm, &ss) == 3)) {
4391
 
        ts->hour = hh;
4392
 
        ts->minute = mmm;
4393
 
        ts->second = ss;
4394
 
        return 1;
4395
 
    }
4396
 
    return 0;
4397
 
}
4398
 
 
4399
 
/*
4400
 
 *----------------------------------------------------------------------
4401
 
 *
4402
 
 *      Date methods.
4403
 
 *
4404
 
 *----------------------------------------------------------------------
4405
 
 */
4406
 
 
4407
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
4408
 
static VALUE
4409
 
date_alloc(VALUE self)
4410
 
{
4411
 
    DATE_STRUCT *date;
4412
 
    VALUE obj = Data_Make_Struct(self, DATE_STRUCT, 0, xfree, date);
4413
 
 
4414
 
    memset(date, 0, sizeof (*date));
4415
 
    return obj;
4416
 
}
4417
 
#else
4418
 
static VALUE
4419
 
date_new(int argc, VALUE *argv, VALUE self)
4420
 
{
4421
 
    DATE_STRUCT *date;
4422
 
    VALUE obj = Data_Make_Struct(self, DATE_STRUCT, 0, xfree, date);
4423
 
    
4424
 
    rb_obj_call_init(obj, argc, argv);
4425
 
    return obj;
4426
 
}
4427
 
#endif
4428
 
 
4429
 
static VALUE
4430
 
date_load1(VALUE self, VALUE str, int load)
4431
 
{
4432
 
    TIMESTAMP_STRUCT tss;
4433
 
 
4434
 
    if (scan_dtts(str, 1, 0, &tss)) {
4435
 
        DATE_STRUCT *date;
4436
 
        VALUE obj;
4437
 
 
4438
 
        if (load) {
4439
 
            obj = Data_Make_Struct(self, DATE_STRUCT, 0, xfree, date);
4440
 
        } else {
4441
 
            obj = self;
4442
 
            Data_Get_Struct(self, DATE_STRUCT, date);
4443
 
        }
4444
 
        date->year = tss.year;
4445
 
        date->month = tss.month;
4446
 
        date->day = tss.day;
4447
 
        return obj;
4448
 
    }
4449
 
    if (load > 0) {
4450
 
        rb_raise(rb_eTypeError, "marshaled ODBC::Date format error");
4451
 
    }
4452
 
    return Qnil;
4453
 
}
4454
 
 
4455
 
static VALUE
4456
 
date_load(VALUE self, VALUE str)
4457
 
{
4458
 
    return date_load1(self, str, 1);
4459
 
}
4460
 
 
4461
 
static VALUE
4462
 
date_init(int argc, VALUE *argv, VALUE self)
4463
 
{
4464
 
    DATE_STRUCT *date;
4465
 
    VALUE d, m, y;
4466
 
 
4467
 
    rb_scan_args(argc, argv, "03", &y, &m, &d);
4468
 
    if (rb_obj_is_kind_of(y, Cdate) == Qtrue) {
4469
 
        DATE_STRUCT *date2;
4470
 
 
4471
 
        if (argc > 1) {
4472
 
            rb_raise(rb_eArgError, "wrong # arguments");
4473
 
        }
4474
 
        Data_Get_Struct(self, DATE_STRUCT, date);
4475
 
        Data_Get_Struct(y, DATE_STRUCT, date2);
4476
 
        *date = *date2;
4477
 
        return self;
4478
 
    }
4479
 
    if (rb_obj_is_kind_of(y, Ctimestamp) == Qtrue) {
4480
 
        TIMESTAMP_STRUCT *ts;
4481
 
 
4482
 
        if (argc > 1) {
4483
 
            rb_raise(rb_eArgError, "wrong # arguments");
4484
 
        }
4485
 
        Data_Get_Struct(self, DATE_STRUCT, date);
4486
 
        Data_Get_Struct(y, TIMESTAMP_STRUCT, ts);
4487
 
        date->year  = ts->year;
4488
 
        date->month = ts->month;
4489
 
        date->day   = ts->day;
4490
 
        return self;
4491
 
    }
4492
 
    if (rb_obj_is_kind_of(y, rb_cTime) == Qtrue) {
4493
 
        if (argc > 1) {
4494
 
            rb_raise(rb_eArgError, "wrong # arguments");
4495
 
        }
4496
 
        d = rb_funcall(y, IDday, 0, NULL);
4497
 
        m = rb_funcall(y, IDmonth, 0, NULL);
4498
 
        y = rb_funcall(y, IDyear, 0, NULL);
4499
 
    } else if (rb_obj_is_kind_of(y, rb_cDate) == Qtrue) {
4500
 
        if (argc > 1) {
4501
 
            rb_raise(rb_eArgError, "wrong # arguments");
4502
 
        }
4503
 
        d = rb_funcall(y, IDmday, 0, NULL);
4504
 
        m = rb_funcall(y, IDmonth, 0, NULL);
4505
 
        y = rb_funcall(y, IDyear, 0, NULL);
4506
 
    } else if ((argc == 1) && (rb_obj_is_kind_of(y, rb_cString) == Qtrue)) {
4507
 
        if (date_load1(self, y, 0) != Qnil) {
4508
 
            return self;
4509
 
        }
4510
 
    }
4511
 
    Data_Get_Struct(self, DATE_STRUCT, date);
4512
 
    date->year  = (y == Qnil) ? 0 : NUM2INT(y);
4513
 
    date->month = (m == Qnil) ? 0 : NUM2INT(m);
4514
 
    date->day   = (d == Qnil) ? 0 : NUM2INT(d);
4515
 
    return self;
4516
 
}
4517
 
 
4518
 
static VALUE
4519
 
date_clone(VALUE self)
4520
 
{
4521
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
4522
 
    VALUE obj = rb_obj_alloc(CLASS_OF(self));
4523
 
    DATE_STRUCT *date1, *date2;
4524
 
 
4525
 
    Data_Get_Struct(self, DATE_STRUCT, date1);
4526
 
    Data_Get_Struct(obj, DATE_STRUCT, date2);
4527
 
    *date2 = *date1;
4528
 
    return obj;
4529
 
#else
4530
 
    return date_new(1, &self, CLASS_OF(self));
4531
 
#endif
4532
 
}
4533
 
 
4534
 
static VALUE
4535
 
date_to_s(VALUE self)
4536
 
{
4537
 
    DATE_STRUCT *date;
4538
 
    char buf[128];
4539
 
 
4540
 
    Data_Get_Struct(self, DATE_STRUCT, date);
4541
 
    sprintf(buf, "%04d-%02d-%02d", date->year, date->month, date->day);
4542
 
    return rb_str_new2(buf);
4543
 
}
4544
 
 
4545
 
static VALUE
4546
 
date_dump(VALUE self, VALUE depth)
4547
 
{
4548
 
    return date_to_s(self);
4549
 
}
4550
 
 
4551
 
static VALUE
4552
 
date_inspect(VALUE self)
4553
 
{
4554
 
    VALUE s = rb_str_new2("#<ODBC::Date: ");
4555
 
 
4556
 
    s = rb_str_append(s, date_to_s(self));
4557
 
    return rb_str_append(s, rb_str_new2(">"));
4558
 
}
4559
 
 
4560
 
static VALUE
4561
 
date_year(int argc, VALUE *argv, VALUE self)
4562
 
{
4563
 
    DATE_STRUCT *date;
4564
 
    VALUE v;
4565
 
 
4566
 
    rb_scan_args(argc, argv, "01", &v);
4567
 
    Data_Get_Struct(self, DATE_STRUCT, date);
4568
 
    if (v == Qnil) {
4569
 
        return INT2NUM(date->year);
4570
 
    }
4571
 
    date->year = NUM2INT(v);
4572
 
    return self;
4573
 
}
4574
 
 
4575
 
static VALUE
4576
 
date_month(int argc, VALUE *argv, VALUE self)
4577
 
{
4578
 
    DATE_STRUCT *date;
4579
 
    VALUE v;
4580
 
 
4581
 
    rb_scan_args(argc, argv, "01", &v);
4582
 
    Data_Get_Struct(self, DATE_STRUCT, date);
4583
 
    if (v == Qnil) {
4584
 
        return INT2NUM(date->month);
4585
 
    }
4586
 
    date->month = NUM2INT(v);
4587
 
    return self;
4588
 
}
4589
 
 
4590
 
static VALUE
4591
 
date_day(int argc, VALUE *argv, VALUE self)
4592
 
{
4593
 
    DATE_STRUCT *date;
4594
 
    VALUE v;
4595
 
 
4596
 
    rb_scan_args(argc, argv, "01", &v);
4597
 
    Data_Get_Struct(self, DATE_STRUCT, date);
4598
 
    if (v == Qnil) {
4599
 
        return INT2NUM(date->day);
4600
 
    }
4601
 
    date->day = NUM2INT(v);
4602
 
    return self;
4603
 
}
4604
 
 
4605
 
static VALUE
4606
 
date_cmp(VALUE self, VALUE date)
4607
 
{
4608
 
    DATE_STRUCT *date1, *date2;
4609
 
 
4610
 
    if (rb_obj_is_kind_of(date, Cdate) != Qtrue) {
4611
 
        rb_raise(rb_eTypeError, "need ODBC::Date as argument");
4612
 
    }
4613
 
    Data_Get_Struct(self, DATE_STRUCT, date1);
4614
 
    Data_Get_Struct(date, DATE_STRUCT, date2);
4615
 
    if (date1->year < date2->year) {
4616
 
        return INT2FIX(-1);
4617
 
    }
4618
 
    if (date1->year == date2->year) {
4619
 
        if (date1->month < date2->month) {
4620
 
            return INT2FIX(-1);
4621
 
        }
4622
 
        if (date1->month == date2->month) {
4623
 
            if (date1->day < date2->day) {
4624
 
                return INT2FIX(-1);
4625
 
            }
4626
 
            if (date1->day == date2->day) {
4627
 
                return INT2FIX(0);
4628
 
            }
4629
 
        }
4630
 
    }
4631
 
    return INT2FIX(1);
4632
 
}
4633
 
 
4634
 
/*
4635
 
 *----------------------------------------------------------------------
4636
 
 *
4637
 
 *      Time methods.
4638
 
 *
4639
 
 *----------------------------------------------------------------------
4640
 
 */
4641
 
 
4642
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
4643
 
static VALUE
4644
 
time_alloc(VALUE self)
4645
 
{
4646
 
    TIME_STRUCT *time;
4647
 
    VALUE obj = Data_Make_Struct(self, TIME_STRUCT, 0, xfree, time);
4648
 
 
4649
 
    memset(time, 0, sizeof (*time));
4650
 
    return obj;
4651
 
}
4652
 
#else
4653
 
static VALUE
4654
 
time_new(int argc, VALUE *argv, VALUE self)
4655
 
{
4656
 
    TIME_STRUCT *time;
4657
 
    VALUE obj = Data_Make_Struct(self, TIME_STRUCT, 0, xfree, time);
4658
 
    
4659
 
    rb_obj_call_init(obj, argc, argv);
4660
 
    return obj;
4661
 
}
4662
 
#endif
4663
 
 
4664
 
static VALUE
4665
 
time_load1(VALUE self, VALUE str, int load)
4666
 
{
4667
 
    TIMESTAMP_STRUCT tss;
4668
 
 
4669
 
    if (scan_dtts(str, 0, 1, &tss)) {
4670
 
        TIME_STRUCT *time;
4671
 
        VALUE obj;
4672
 
       
4673
 
        if (load) {
4674
 
            obj = Data_Make_Struct(self, TIME_STRUCT, 0, xfree, time);
4675
 
        } else {
4676
 
            obj = self;
4677
 
            Data_Get_Struct(self, TIME_STRUCT, time);
4678
 
        }
4679
 
        time->hour = tss.hour;
4680
 
        time->minute = tss.minute;
4681
 
        time->second = tss.second;
4682
 
        return obj;
4683
 
    }
4684
 
    if (load > 0) {
4685
 
        rb_raise(rb_eTypeError, "marshaled ODBC::Time format error");
4686
 
    }
4687
 
    return Qnil;
4688
 
}
4689
 
 
4690
 
static VALUE
4691
 
time_load(VALUE self, VALUE str)
4692
 
{
4693
 
    return time_load1(self, str, 1);
4694
 
}
4695
 
 
4696
 
static VALUE
4697
 
time_init(int argc, VALUE *argv, VALUE self)
4698
 
{
4699
 
    TIME_STRUCT *time;
4700
 
    VALUE h, m, s;
4701
 
 
4702
 
    rb_scan_args(argc, argv, "03", &h, &m, &s);
4703
 
    if (rb_obj_is_kind_of(h, Ctime) == Qtrue) {
4704
 
        TIME_STRUCT *time2;
4705
 
 
4706
 
        if (argc > 1) {
4707
 
            rb_raise(rb_eArgError, "wrong # arguments");
4708
 
        }
4709
 
        Data_Get_Struct(self, TIME_STRUCT, time);
4710
 
        Data_Get_Struct(h, TIME_STRUCT, time2);
4711
 
        *time = *time2;
4712
 
        return self;
4713
 
    }
4714
 
    if (rb_obj_is_kind_of(h, Ctimestamp) == Qtrue) {
4715
 
        TIMESTAMP_STRUCT *ts;
4716
 
 
4717
 
        if (argc > 1) {
4718
 
            rb_raise(rb_eArgError, "wrong # arguments");
4719
 
        }
4720
 
        Data_Get_Struct(self, TIME_STRUCT, time);
4721
 
        Data_Get_Struct(h, TIMESTAMP_STRUCT, ts);
4722
 
        time->hour   = ts->hour;
4723
 
        time->minute = ts->minute;
4724
 
        time->second = ts->second;
4725
 
        return self;
4726
 
    }
4727
 
    if (rb_obj_is_kind_of(h, rb_cTime) == Qtrue) {
4728
 
        if (argc > 1) {
4729
 
            rb_raise(rb_eArgError, "wrong # arguments");
4730
 
        }
4731
 
        s = rb_funcall(h, IDsec, 0, NULL);
4732
 
        m = rb_funcall(h, IDmin, 0, NULL);
4733
 
        h = rb_funcall(h, IDhour, 0, NULL);
4734
 
    } else if ((argc == 1) && (rb_obj_is_kind_of(h, rb_cString) == Qtrue)) {
4735
 
        if (time_load1(self, h, 0) != Qnil) {
4736
 
            return self;
4737
 
        }
4738
 
    }
4739
 
    Data_Get_Struct(self, TIME_STRUCT, time);
4740
 
    time->hour   = (h == Qnil) ? 0 : NUM2INT(h);
4741
 
    time->minute = (m == Qnil) ? 0 : NUM2INT(m);
4742
 
    time->second = (s == Qnil) ? 0 : NUM2INT(s);
4743
 
    return self;
4744
 
}
4745
 
 
4746
 
static VALUE
4747
 
time_clone(VALUE self)
4748
 
{
4749
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
4750
 
    VALUE obj = rb_obj_alloc(CLASS_OF(self));
4751
 
    TIME_STRUCT *time1, *time2;
4752
 
 
4753
 
    Data_Get_Struct(self, TIME_STRUCT, time1);
4754
 
    Data_Get_Struct(obj, TIME_STRUCT, time2);
4755
 
    *time2 = *time1;
4756
 
    return obj;
4757
 
#else
4758
 
    return time_new(1, &self, CLASS_OF(self));
4759
 
#endif
4760
 
}
4761
 
 
4762
 
static VALUE
4763
 
time_to_s(VALUE self)
4764
 
{
4765
 
    TIME_STRUCT *time;
4766
 
    char buf[128];
4767
 
 
4768
 
    Data_Get_Struct(self, TIME_STRUCT, time);
4769
 
    sprintf(buf, "%02d:%02d:%02d", time->hour, time->minute, time->second);
4770
 
    return rb_str_new2(buf);
4771
 
}
4772
 
 
4773
 
static VALUE
4774
 
time_dump(VALUE self, VALUE depth)
4775
 
{
4776
 
    return time_to_s(self);
4777
 
}
4778
 
 
4779
 
static VALUE
4780
 
time_inspect(VALUE self)
4781
 
{
4782
 
    VALUE s = rb_str_new2("#<ODBC::Time: ");
4783
 
 
4784
 
    s = rb_str_append(s, time_to_s(self));
4785
 
    return rb_str_append(s, rb_str_new2(">"));
4786
 
}
4787
 
 
4788
 
static VALUE
4789
 
time_hour(int argc, VALUE *argv, VALUE self)
4790
 
{
4791
 
    TIME_STRUCT *time;
4792
 
    VALUE v;
4793
 
 
4794
 
    rb_scan_args(argc, argv, "01", &v);
4795
 
    Data_Get_Struct(self, TIME_STRUCT, time);
4796
 
    if (v == Qnil) {
4797
 
        return INT2NUM(time->hour);
4798
 
    }
4799
 
    time->hour = NUM2INT(v);
4800
 
    return self;
4801
 
}
4802
 
 
4803
 
static VALUE
4804
 
time_min(int argc, VALUE *argv, VALUE self)
4805
 
{
4806
 
    TIME_STRUCT *time;
4807
 
    VALUE v;
4808
 
 
4809
 
    rb_scan_args(argc, argv, "01", &v);
4810
 
    Data_Get_Struct(self, TIME_STRUCT, time);
4811
 
    if (v == Qnil) {
4812
 
        return INT2NUM(time->minute);
4813
 
    }
4814
 
    time->minute = NUM2INT(v);
4815
 
    return self;
4816
 
}
4817
 
 
4818
 
static VALUE
4819
 
time_sec(int argc, VALUE *argv, VALUE self)
4820
 
{
4821
 
    TIME_STRUCT *time;
4822
 
    VALUE v;
4823
 
 
4824
 
    rb_scan_args(argc, argv, "01", &v);
4825
 
    Data_Get_Struct(self, TIME_STRUCT, time);
4826
 
    if (v == Qnil) {
4827
 
        return INT2NUM(time->second);
4828
 
    }
4829
 
    time->second = NUM2INT(v);
4830
 
    return self;
4831
 
}
4832
 
 
4833
 
static VALUE
4834
 
time_cmp(VALUE self, VALUE time)
4835
 
{
4836
 
    TIME_STRUCT *time1, *time2;
4837
 
 
4838
 
    if (rb_obj_is_kind_of(time, Ctime) != Qtrue) {
4839
 
        rb_raise(rb_eTypeError, "need ODBC::Time as argument");
4840
 
    }
4841
 
    Data_Get_Struct(self, TIME_STRUCT, time1);
4842
 
    Data_Get_Struct(time, TIME_STRUCT, time2);
4843
 
    if (time1->hour < time2->hour) {
4844
 
        return INT2FIX(-1);
4845
 
    }
4846
 
    if (time1->hour == time2->hour) {
4847
 
        if (time1->minute < time2->minute) {
4848
 
            return INT2FIX(-1);
4849
 
        }
4850
 
        if (time1->minute == time2->minute) {
4851
 
            if (time1->second < time2->second) {
4852
 
                return INT2FIX(-1);
4853
 
            }
4854
 
            if (time1->second == time2->second) {
4855
 
                return INT2FIX(0);
4856
 
            }
4857
 
        }
4858
 
    }
4859
 
    return INT2FIX(1);
4860
 
}
4861
 
 
4862
 
/*
4863
 
 *----------------------------------------------------------------------
4864
 
 *
4865
 
 *      TimeStamp methods.
4866
 
 *
4867
 
 *----------------------------------------------------------------------
4868
 
 */
4869
 
 
4870
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
4871
 
static VALUE
4872
 
timestamp_alloc(VALUE self)
4873
 
{
4874
 
    TIMESTAMP_STRUCT *ts;
4875
 
    VALUE obj = Data_Make_Struct(self, TIMESTAMP_STRUCT, 0, xfree, ts);
4876
 
 
4877
 
    memset(ts, 0, sizeof (*ts));
4878
 
    return obj;
4879
 
}
4880
 
#else
4881
 
static VALUE
4882
 
timestamp_new(int argc, VALUE *argv, VALUE self)
4883
 
{
4884
 
    TIMESTAMP_STRUCT *ts;
4885
 
    VALUE obj = Data_Make_Struct(self, TIMESTAMP_STRUCT, 0, xfree, ts);
4886
 
 
4887
 
    rb_obj_call_init(obj, argc, argv);
4888
 
    return obj;
4889
 
}
4890
 
#endif
4891
 
 
4892
 
static VALUE
4893
 
timestamp_load1(VALUE self, VALUE str, int load)
4894
 
{
4895
 
    TIMESTAMP_STRUCT tss;
4896
 
 
4897
 
    if (scan_dtts(str, !load, !load, &tss)) {
4898
 
        TIMESTAMP_STRUCT *ts;
4899
 
        VALUE obj;
4900
 
 
4901
 
        if (load) {
4902
 
            obj = Data_Make_Struct(self, TIMESTAMP_STRUCT, 0, xfree, ts);
4903
 
        } else {
4904
 
            obj = self;
4905
 
            Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
4906
 
        }
4907
 
        *ts = tss;
4908
 
        return obj;
4909
 
    }
4910
 
    if (load > 0) {
4911
 
        rb_raise(rb_eTypeError, "marshaled ODBC::TimeStamp format error");
4912
 
    }
4913
 
    return Qnil;
4914
 
}
4915
 
 
4916
 
static VALUE
4917
 
timestamp_load(VALUE self, VALUE str)
4918
 
{
4919
 
    return timestamp_load1(self, str, 1);
4920
 
}
4921
 
 
4922
 
static VALUE
4923
 
timestamp_init(int argc, VALUE *argv, VALUE self)
4924
 
{
4925
 
    TIMESTAMP_STRUCT *ts;
4926
 
    VALUE d, m, y, hh, mm, ss, f;
4927
 
 
4928
 
    rb_scan_args(argc, argv, "07", &y, &m, &d, &hh, &mm, &ss, &f);
4929
 
    if (rb_obj_is_kind_of(y, Ctimestamp) == Qtrue) {
4930
 
        TIMESTAMP_STRUCT *ts2;
4931
 
 
4932
 
        if (argc > 1) {
4933
 
            rb_raise(rb_eArgError, "wrong # arguments");
4934
 
        }
4935
 
        Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
4936
 
        Data_Get_Struct(y, TIMESTAMP_STRUCT, ts2);
4937
 
        *ts = *ts2;
4938
 
        return self;
4939
 
    }
4940
 
    if (rb_obj_is_kind_of(y, Cdate) == Qtrue) {
4941
 
        DATE_STRUCT *date;
4942
 
 
4943
 
        if (argc > 1) {
4944
 
            if (argc > 2) {
4945
 
                rb_raise(rb_eArgError, "wrong # arguments");
4946
 
            }
4947
 
            if (rb_obj_is_kind_of(m, Ctime) == Qtrue) {
4948
 
                TIME_STRUCT *time;
4949
 
 
4950
 
                Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
4951
 
                Data_Get_Struct(m, TIME_STRUCT, time);
4952
 
                ts->hour   = time->hour;
4953
 
                ts->minute = time->minute;
4954
 
                ts->second = time->second;
4955
 
            } else {
4956
 
                rb_raise(rb_eArgError, "need ODBC::Time argument");
4957
 
            }
4958
 
        }
4959
 
        Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
4960
 
        Data_Get_Struct(y, DATE_STRUCT, date);
4961
 
        ts->year = date->year;
4962
 
        ts->year = date->year;
4963
 
        ts->year = date->year;
4964
 
        ts->fraction = 0;
4965
 
        return self;
4966
 
    }
4967
 
    if (rb_obj_is_kind_of(y, rb_cTime) == Qtrue) {
4968
 
        if (argc > 1) {
4969
 
            rb_raise(rb_eArgError, "wrong # arguments");
4970
 
        }
4971
 
        f  = rb_funcall(y, IDusec, 0, NULL);
4972
 
        ss = rb_funcall(y, IDsec, 0, NULL);
4973
 
        mm = rb_funcall(y, IDmin, 0, NULL);
4974
 
        hh = rb_funcall(y, IDhour, 0, NULL);
4975
 
        d  = rb_funcall(y, IDday, 0, NULL);
4976
 
        m  = rb_funcall(y, IDmonth, 0, NULL);
4977
 
        y  = rb_funcall(y, IDyear, 0, NULL);
4978
 
        f = INT2NUM(NUM2INT(f) * 1000);
4979
 
    } else if (rb_obj_is_kind_of(y, rb_cDate) == Qtrue) {
4980
 
        if (argc > 1) {
4981
 
            rb_raise(rb_eArgError, "wrong # arguments");
4982
 
        }
4983
 
        f  = INT2FIX(0);
4984
 
        ss = INT2FIX(0);
4985
 
        mm = INT2FIX(0);
4986
 
        hh = INT2FIX(0);
4987
 
        d  = rb_funcall(y, IDmday, 0, NULL);
4988
 
        m  = rb_funcall(y, IDmonth, 0, NULL);
4989
 
        y  = rb_funcall(y, IDyear, 0, NULL);
4990
 
    } else if ((argc == 1) && (rb_obj_is_kind_of(y, rb_cString) == Qtrue)) {
4991
 
        if (timestamp_load1(self, y, 0) != Qnil) {
4992
 
            return self;
4993
 
        }
4994
 
    }
4995
 
    Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
4996
 
    ts->year     = (y  == Qnil) ? 0 : NUM2INT(y);
4997
 
    ts->month    = (m  == Qnil) ? 0 : NUM2INT(m);
4998
 
    ts->day      = (d  == Qnil) ? 0 : NUM2INT(d);
4999
 
    ts->hour     = (hh == Qnil) ? 0 : NUM2INT(hh);
5000
 
    ts->minute   = (mm == Qnil) ? 0 : NUM2INT(mm);
5001
 
    ts->second   = (ss == Qnil) ? 0 : NUM2INT(ss);
5002
 
    ts->fraction = (f  == Qnil) ? 0 : NUM2INT(f);
5003
 
    return self;
5004
 
}
5005
 
 
5006
 
static VALUE
5007
 
timestamp_clone(VALUE self)
5008
 
{
5009
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
5010
 
    VALUE obj = rb_obj_alloc(CLASS_OF(self));
5011
 
    TIMESTAMP_STRUCT *ts1, *ts2;
5012
 
 
5013
 
    Data_Get_Struct(self, TIMESTAMP_STRUCT, ts1);
5014
 
    Data_Get_Struct(obj, TIMESTAMP_STRUCT, ts2);
5015
 
    *ts2 = *ts1;
5016
 
    return obj;
5017
 
#else
5018
 
    return timestamp_new(1, &self, CLASS_OF(self));
5019
 
#endif
5020
 
}
5021
 
 
5022
 
static VALUE
5023
 
timestamp_to_s(VALUE self)
5024
 
{
5025
 
    TIMESTAMP_STRUCT *ts;
5026
 
    char buf[256];
5027
 
 
5028
 
    Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
5029
 
    sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d %u",
5030
 
            ts->year, ts->month, ts->day,
5031
 
            ts->hour, ts->minute, ts->second,
5032
 
            (unsigned int) ts->fraction);
5033
 
    return rb_str_new2(buf);
5034
 
}
5035
 
 
5036
 
static VALUE
5037
 
timestamp_dump(VALUE self, VALUE depth)
5038
 
{
5039
 
    return timestamp_to_s(self);
5040
 
}
5041
 
 
5042
 
static VALUE
5043
 
timestamp_inspect(VALUE self)
5044
 
{
5045
 
    VALUE s = rb_str_new2("#<ODBC::TimeStamp: \"");
5046
 
 
5047
 
    s = rb_str_append(s, timestamp_to_s(self));
5048
 
    return rb_str_append(s, rb_str_new2("\">"));
5049
 
}
5050
 
 
5051
 
static VALUE
5052
 
timestamp_year(int argc, VALUE *argv, VALUE self)
5053
 
{
5054
 
    TIMESTAMP_STRUCT *ts;
5055
 
    VALUE v;
5056
 
 
5057
 
    rb_scan_args(argc, argv, "01", &v);
5058
 
    Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
5059
 
    if (v == Qnil) {
5060
 
        return INT2NUM(ts->year);
5061
 
    }
5062
 
    ts->year = NUM2INT(v);
5063
 
    return self;
5064
 
}
5065
 
 
5066
 
static VALUE
5067
 
timestamp_month(int argc, VALUE *argv, VALUE self)
5068
 
{
5069
 
    TIMESTAMP_STRUCT *ts;
5070
 
    VALUE v;
5071
 
 
5072
 
    rb_scan_args(argc, argv, "01", &v);
5073
 
    Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
5074
 
    if (v == Qnil) {
5075
 
        return INT2NUM(ts->month);
5076
 
    }
5077
 
    ts->month = NUM2INT(v);
5078
 
    return self;
5079
 
}
5080
 
 
5081
 
static VALUE
5082
 
timestamp_day(int argc, VALUE *argv, VALUE self)
5083
 
{
5084
 
    TIMESTAMP_STRUCT *ts;
5085
 
    VALUE v;
5086
 
 
5087
 
    rb_scan_args(argc, argv, "01", &v);
5088
 
    Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
5089
 
    if (v == Qnil) {
5090
 
        return INT2NUM(ts->day);
5091
 
    }
5092
 
    ts->day = NUM2INT(v);
5093
 
    return self;
5094
 
}
5095
 
 
5096
 
static VALUE
5097
 
timestamp_hour(int argc, VALUE *argv, VALUE self)
5098
 
{
5099
 
    TIMESTAMP_STRUCT *ts;
5100
 
    VALUE v;
5101
 
 
5102
 
    rb_scan_args(argc, argv, "01", &v);
5103
 
    Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
5104
 
    if (v == Qnil) {
5105
 
        return INT2NUM(ts->hour);
5106
 
    }
5107
 
    ts->hour = NUM2INT(v);
5108
 
    return self;
5109
 
}
5110
 
 
5111
 
static VALUE
5112
 
timestamp_min(int argc, VALUE *argv, VALUE self)
5113
 
{
5114
 
    TIMESTAMP_STRUCT *ts;
5115
 
    VALUE v;
5116
 
 
5117
 
    rb_scan_args(argc, argv, "01", &v);
5118
 
    Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
5119
 
    if (v == Qnil) {
5120
 
        return INT2NUM(ts->minute);
5121
 
    }
5122
 
    ts->minute = NUM2INT(v);
5123
 
    return self;
5124
 
}
5125
 
 
5126
 
static VALUE
5127
 
timestamp_sec(int argc, VALUE *argv, VALUE self)
5128
 
{
5129
 
    TIMESTAMP_STRUCT *ts;
5130
 
    VALUE v;
5131
 
 
5132
 
    rb_scan_args(argc, argv, "01", &v);
5133
 
    Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
5134
 
    if (v == Qnil) {
5135
 
        return INT2NUM(ts->second);
5136
 
    }
5137
 
    ts->second = NUM2INT(v);
5138
 
    return self;
5139
 
}
5140
 
 
5141
 
static VALUE
5142
 
timestamp_fraction(int argc, VALUE *argv, VALUE self)
5143
 
{
5144
 
    TIMESTAMP_STRUCT *ts;
5145
 
    VALUE v;
5146
 
 
5147
 
    rb_scan_args(argc, argv, "01", &v);
5148
 
    Data_Get_Struct(self, TIMESTAMP_STRUCT, ts);
5149
 
    if (v == Qnil) {
5150
 
        return INT2NUM(ts->fraction);
5151
 
    }
5152
 
    ts->fraction = NUM2INT(v);
5153
 
    return self;
5154
 
}
5155
 
 
5156
 
static VALUE
5157
 
timestamp_cmp(VALUE self, VALUE timestamp)
5158
 
{
5159
 
    TIMESTAMP_STRUCT *ts1, *ts2;
5160
 
 
5161
 
    if (rb_obj_is_kind_of(timestamp, Ctimestamp) != Qtrue) {
5162
 
        rb_raise(rb_eTypeError, "need ODBC::TimeStamp as argument");
5163
 
    }
5164
 
    Data_Get_Struct(self, TIMESTAMP_STRUCT, ts1);
5165
 
    Data_Get_Struct(timestamp, TIMESTAMP_STRUCT, ts2);
5166
 
    if (ts1->year < ts2->year) {
5167
 
        return INT2FIX(-1);
5168
 
    }
5169
 
    if (ts1->year == ts2->year) {
5170
 
        if (ts1->month < ts2->month) {
5171
 
            return INT2FIX(-1);
5172
 
        }
5173
 
        if (ts1->month == ts2->month) {
5174
 
            if (ts1->day < ts2->day) {
5175
 
                return INT2FIX(-1);
5176
 
            }
5177
 
            if (ts1->day == ts2->day) {
5178
 
                if (ts1->hour < ts2->hour) {
5179
 
                    return INT2FIX(-1);
5180
 
                }
5181
 
                if (ts1->hour == ts2->hour) {
5182
 
                    if (ts1->minute < ts2->minute) {
5183
 
                        return INT2FIX(-1);
5184
 
                    }
5185
 
                    if (ts1->minute == ts2->minute) {
5186
 
                        if (ts1->second < ts2->second) {
5187
 
                            return INT2FIX(-1);
5188
 
                        }
5189
 
                        if (ts1->second == ts2->second) {
5190
 
                            if (ts1->fraction < ts2->fraction) {
5191
 
                                return INT2FIX(-1);
5192
 
                            }
5193
 
                            if (ts1->fraction == ts2->fraction) {
5194
 
                                return INT2FIX(0);
5195
 
                            }
5196
 
                        }
5197
 
                    }
5198
 
                }
5199
 
            }
5200
 
        }
5201
 
    }
5202
 
    return INT2FIX(1);
5203
 
}
5204
 
 
5205
 
/*
5206
 
 *----------------------------------------------------------------------
5207
 
 *
5208
 
 *      Statement methods.
5209
 
 *
5210
 
 *----------------------------------------------------------------------
5211
 
 */
5212
 
 
5213
 
static VALUE
5214
 
stmt_drop(VALUE self)
5215
 
{
5216
 
    STMT *q;
5217
 
 
5218
 
    Data_Get_Struct(self, STMT, q);
5219
 
    if (q->hstmt != SQL_NULL_HSTMT) {
5220
 
        callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5221
 
                SQLFreeStmt(q->hstmt, SQL_DROP), "SQLFreeStmt(SQL_DROP)");
5222
 
        q->hstmt = SQL_NULL_HSTMT;
5223
 
        unlink_stmt(q);
5224
 
    }
5225
 
    free_stmt_sub(q);
5226
 
    return self;
5227
 
}
5228
 
 
5229
 
static VALUE
5230
 
stmt_close(VALUE self)
5231
 
{
5232
 
    STMT *q;
5233
 
 
5234
 
    Data_Get_Struct(self, STMT, q);
5235
 
    if (q->hstmt != SQL_NULL_HSTMT) {
5236
 
        callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5237
 
                SQLFreeStmt(q->hstmt, SQL_CLOSE), "SQLFreeStmt(SQL_CLOSE)");
5238
 
    }
5239
 
    free_stmt_sub(q);
5240
 
    return self;
5241
 
}
5242
 
 
5243
 
static VALUE
5244
 
stmt_cancel(VALUE self)
5245
 
{
5246
 
    STMT *q;
5247
 
    char *msg;
5248
 
 
5249
 
    Data_Get_Struct(self, STMT, q);
5250
 
    if (q->hstmt != SQL_NULL_HSTMT) {
5251
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5252
 
                       SQLCancel(q->hstmt), &msg, "SQLCancel")) {
5253
 
            rb_raise(Cerror, "%s", msg);
5254
 
        }
5255
 
    }
5256
 
    return self;
5257
 
}
5258
 
 
5259
 
static void
5260
 
check_ncols(STMT *q)
5261
 
{
5262
 
    if ((q->hstmt != SQL_NULL_HSTMT) && (q->ncols <= 0) &&
5263
 
        (q->coltypes == NULL)) {
5264
 
        COLTYPE *coltypes = NULL;
5265
 
        SQLSMALLINT cols = 0;
5266
 
        
5267
 
        if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5268
 
                      SQLNumResultCols(q->hstmt, &cols), NULL,
5269
 
                      "SQLNumResultCols")
5270
 
            && (cols > 0)) {
5271
 
            coltypes = make_coltypes(q->hstmt, cols, NULL);
5272
 
            if (coltypes != NULL) {
5273
 
                q->ncols = cols;
5274
 
                q->coltypes = coltypes;
5275
 
            }
5276
 
        }
5277
 
    }
5278
 
}
5279
 
 
5280
 
static VALUE
5281
 
stmt_ncols(VALUE self)
5282
 
{
5283
 
    STMT *q;
5284
 
 
5285
 
    Data_Get_Struct(self, STMT, q);
5286
 
    check_ncols(q);
5287
 
    return INT2FIX(q->ncols);
5288
 
}
5289
 
 
5290
 
static VALUE
5291
 
stmt_nrows(VALUE self)
5292
 
{
5293
 
    STMT *q;
5294
 
    SQLLEN rows = 0;
5295
 
    char *msg;
5296
 
 
5297
 
    Data_Get_Struct(self, STMT, q);
5298
 
    if ((q->hstmt != SQL_NULL_HSTMT) &&
5299
 
        (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5300
 
                    SQLRowCount(q->hstmt, &rows), &msg, "SQLRowCount"))) {
5301
 
        rb_raise(Cerror, "%s", msg);
5302
 
    }
5303
 
    return INT2NUM(rows);
5304
 
}
5305
 
 
5306
 
static VALUE
5307
 
stmt_nparams(VALUE self)
5308
 
{
5309
 
    STMT *q;
5310
 
 
5311
 
    Data_Get_Struct(self, STMT, q);
5312
 
    return INT2FIX(q->nump);
5313
 
}
5314
 
 
5315
 
static int
5316
 
param_num_check(STMT *q, VALUE pnum, int mkpinfo, int needout)
5317
 
{
5318
 
    int vnum;
5319
 
 
5320
 
    Check_Type(pnum, T_FIXNUM);
5321
 
    vnum = NUM2INT(pnum);
5322
 
    if (mkpinfo && (q->pinfo == NULL)) {
5323
 
        char *msg = NULL;
5324
 
        SQLSMALLINT nump = 0;
5325
 
 
5326
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5327
 
                       SQLNumParams(q->hstmt, &nump), NULL, "SQLNumParams")) {
5328
 
            nump = 0;
5329
 
        }
5330
 
        if (nump > 0) {
5331
 
            PINFO *pinfo = make_pinfo(q->hstmt, nump, &msg);
5332
 
 
5333
 
            if (pinfo == NULL) {
5334
 
                rb_raise(Cerror, "%s", msg);
5335
 
            }
5336
 
            q->pinfo = pinfo;
5337
 
            if (q->pinfo != NULL) {
5338
 
                q->nump = nump;
5339
 
            }
5340
 
        }
5341
 
    }
5342
 
    if ((q->pinfo == NULL) || (vnum < 0) || (vnum >= q->nump)) {
5343
 
        rb_raise(rb_eArgError, "parameter number out of bounds");
5344
 
    }
5345
 
    if (needout) {
5346
 
        if ((q->pinfo[vnum].iotype != SQL_PARAM_OUTPUT) &&
5347
 
            (q->pinfo[vnum].iotype != SQL_PARAM_INPUT_OUTPUT)) {
5348
 
            rb_raise(Cerror, "not an output parameter");
5349
 
        }
5350
 
    }
5351
 
    return vnum;
5352
 
}
5353
 
 
5354
 
static VALUE
5355
 
stmt_param_type(int argc, VALUE *argv, VALUE self)
5356
 
{
5357
 
    VALUE pnum, ptype, pcoldef, pscale;
5358
 
    int vnum;
5359
 
    STMT *q;
5360
 
 
5361
 
    rb_scan_args(argc, argv, "13", &pnum, &ptype, &pcoldef, &pscale);
5362
 
    Data_Get_Struct(self, STMT, q);
5363
 
    vnum = param_num_check(q, pnum, 1, 0);
5364
 
    if (argc > 1) {
5365
 
        int vtype, vcoldef, vscale;
5366
 
 
5367
 
        Check_Type(ptype, T_FIXNUM);
5368
 
        vtype = NUM2INT(ptype);
5369
 
        if (argc > 2) {
5370
 
            Check_Type(pcoldef, T_FIXNUM);
5371
 
            vcoldef = NUM2INT(pcoldef);
5372
 
            if (argc > 3) {
5373
 
                Check_Type(pscale, T_FIXNUM);
5374
 
                vscale = NUM2INT(pscale);
5375
 
                q->pinfo[vnum].scale = vscale;
5376
 
            }
5377
 
            q->pinfo[vnum].coldef = vcoldef;
5378
 
        }
5379
 
        q->pinfo[vnum].type = vtype;
5380
 
        q->pinfo[vnum].override = 1;
5381
 
        return Qnil;
5382
 
    }
5383
 
    return INT2NUM(q->pinfo[vnum].type);
5384
 
}
5385
 
 
5386
 
static VALUE
5387
 
stmt_param_iotype(int argc, VALUE *argv, VALUE self)
5388
 
{
5389
 
    VALUE pnum, piotype;
5390
 
    int vnum, viotype;
5391
 
    STMT *q;
5392
 
 
5393
 
    rb_scan_args(argc, argv, "11", &pnum, &piotype);
5394
 
    Data_Get_Struct(self, STMT, q);
5395
 
    vnum = param_num_check(q, pnum, 1, 0);
5396
 
    if (argc > 1) {
5397
 
        Check_Type(piotype, T_FIXNUM);
5398
 
        viotype = NUM2INT(piotype);
5399
 
        switch (viotype) {
5400
 
        case SQL_PARAM_INPUT:
5401
 
        case SQL_PARAM_INPUT_OUTPUT:
5402
 
        case SQL_PARAM_OUTPUT:
5403
 
            q->pinfo[vnum].iotype = viotype;
5404
 
            break;
5405
 
        }
5406
 
    }
5407
 
    return INT2NUM(q->pinfo[vnum].iotype);
5408
 
}
5409
 
 
5410
 
static VALUE
5411
 
stmt_param_output_value(int argc, VALUE *argv, VALUE self)
5412
 
{
5413
 
    VALUE pnum, v;
5414
 
    int vnum;
5415
 
    STMT *q;
5416
 
 
5417
 
    rb_scan_args(argc, argv, "10", &pnum);
5418
 
    Data_Get_Struct(self, STMT, q);
5419
 
    vnum = param_num_check(q, pnum, 0, 1);
5420
 
    v = Qnil;
5421
 
    if (q->pinfo[vnum].rlen == SQL_NULL_DATA) {
5422
 
        return v;
5423
 
    }
5424
 
    if (q->pinfo[vnum].outbuf == NULL) {
5425
 
        rb_raise(Cerror, "no output value available");
5426
 
    }
5427
 
    switch (q->pinfo[vnum].ctype) {
5428
 
    case SQL_C_LONG:
5429
 
        v = INT2NUM(*((SQLINTEGER *) q->pinfo[vnum].outbuf));
5430
 
        break;
5431
 
    case SQL_C_DOUBLE:
5432
 
        v = rb_float_new(*((double *) q->pinfo[vnum].outbuf));
5433
 
        break;
5434
 
    case SQL_C_DATE:
5435
 
        {
5436
 
            DATE_STRUCT *date;
5437
 
 
5438
 
            v = Data_Make_Struct(Cdate, DATE_STRUCT, 0, xfree, date);
5439
 
            *date = *((DATE_STRUCT *) q->pinfo[vnum].outbuf);
5440
 
        }
5441
 
        break;
5442
 
    case SQL_C_TIME:
5443
 
        {
5444
 
            TIME_STRUCT *time;
5445
 
 
5446
 
            v = Data_Make_Struct(Ctime, TIME_STRUCT, 0, xfree, time);
5447
 
            *time = *((TIME_STRUCT *) q->pinfo[vnum].outbuf);
5448
 
        }
5449
 
        break;
5450
 
    case SQL_C_TIMESTAMP:
5451
 
        {
5452
 
            TIMESTAMP_STRUCT *ts;
5453
 
 
5454
 
            v = Data_Make_Struct(Ctimestamp, TIMESTAMP_STRUCT,
5455
 
                                 0, xfree, ts);
5456
 
            *ts = *((TIMESTAMP_STRUCT *) q->pinfo[vnum].outbuf);
5457
 
        }
5458
 
        break;
5459
 
#ifdef UNICODE
5460
 
    case SQL_C_WCHAR:
5461
 
        v = uc_tainted_str_new((SQLWCHAR *) q->pinfo[vnum].outbuf,
5462
 
                               q->pinfo[vnum].rlen / sizeof (SQLWCHAR));
5463
 
        break;
5464
 
#endif
5465
 
    case SQL_C_CHAR:
5466
 
        v = rb_tainted_str_new(q->pinfo[vnum].outbuf, q->pinfo[vnum].rlen);
5467
 
        break;
5468
 
    }
5469
 
    return v;
5470
 
}
5471
 
 
5472
 
static VALUE
5473
 
stmt_param_output_size(int argc, VALUE *argv, VALUE self)
5474
 
{
5475
 
    VALUE pnum, psize;
5476
 
    int vnum, vsize;
5477
 
    STMT *q;
5478
 
 
5479
 
    rb_scan_args(argc, argv, "11", &pnum, &psize);
5480
 
    Data_Get_Struct(self, STMT, q);
5481
 
    vnum = param_num_check(q, pnum, 0, 1);
5482
 
    if (argc > 1) {
5483
 
        Check_Type(psize, T_FIXNUM);
5484
 
        vsize = NUM2INT(psize);
5485
 
        if ((vsize > 0) && (vsize < 4 * sizeof (double))) {
5486
 
            vsize = 4 * sizeof (double);
5487
 
        }
5488
 
        q->pinfo[vnum].outsize = (vsize > 0) ? vsize : 0;
5489
 
    }
5490
 
    return INT2NUM(q->pinfo[vnum].outsize);
5491
 
}
5492
 
 
5493
 
static VALUE
5494
 
stmt_param_output_type(int argc, VALUE *argv, VALUE self)
5495
 
{
5496
 
    VALUE pnum, ptype;
5497
 
    int vnum, vtype;
5498
 
    STMT *q;
5499
 
 
5500
 
    rb_scan_args(argc, argv, "11", &pnum, &ptype);
5501
 
    Data_Get_Struct(self, STMT, q);
5502
 
    vnum = param_num_check(q, pnum, 0, 1);
5503
 
    if (argc > 1) {
5504
 
        Check_Type(ptype, T_FIXNUM);
5505
 
        vtype = NUM2INT(ptype);
5506
 
        q->pinfo[vnum].outtype = vtype;
5507
 
    }
5508
 
    return INT2NUM(q->pinfo[vnum].outtype);
5509
 
}
5510
 
 
5511
 
static VALUE
5512
 
stmt_cursorname(int argc, VALUE *argv, VALUE self)
5513
 
{
5514
 
    VALUE cn = Qnil;
5515
 
    STMT *q;
5516
 
#ifdef UNICODE
5517
 
    SQLWCHAR cname[SQL_MAX_MESSAGE_LENGTH];
5518
 
    SQLWCHAR *cp;
5519
 
#else
5520
 
    SQLCHAR cname[SQL_MAX_MESSAGE_LENGTH];
5521
 
    SQLCHAR *cp;
5522
 
#endif
5523
 
    char *msg;
5524
 
    SQLSMALLINT cnLen = 0;
5525
 
 
5526
 
    rb_scan_args(argc, argv, "01", &cn);
5527
 
    Data_Get_Struct(self, STMT, q);
5528
 
    if (cn == Qnil) {
5529
 
        if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5530
 
                       SQLGetCursorName(q->hstmt, (SQLTCHAR *) cname,
5531
 
                                        (SQLSMALLINT) sizeof (cname), &cnLen),
5532
 
                       &msg, "SQLGetCursorName")) {
5533
 
            rb_raise(Cerror, "%s", msg);
5534
 
        }
5535
 
#ifdef UNICODE
5536
 
        cnLen = (cnLen == 0) ? uc_strlen(cname) : (cnLen / sizeof (SQLWCHAR));
5537
 
        return uc_tainted_str_new(cname, cnLen);
5538
 
#else
5539
 
        cnLen = (cnLen == 0) ? strlen((char *) cname) : cnLen;
5540
 
        return rb_tainted_str_new((char *) cname, cnLen);
5541
 
#endif
5542
 
    }
5543
 
    if (TYPE(cn) != T_STRING) {
5544
 
        cn = rb_any_to_s(cn);
5545
 
    }
5546
 
#ifdef UNICODE
5547
 
    cp = uc_from_utf((unsigned char *) STR2CSTR(cn), -1);
5548
 
    if (cp == NULL) {
5549
 
        rb_raise(Cerror, set_err("Out of memory", 0));
5550
 
    }
5551
 
#else
5552
 
    cp = (SQLCHAR *) STR2CSTR(cn);
5553
 
#endif
5554
 
    if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5555
 
                   SQLSetCursorName(q->hstmt, cp, SQL_NTS),
5556
 
                   &msg, "SQLSetCursorName")) {
5557
 
#ifdef UNICODE
5558
 
        uc_free(cp);
5559
 
#endif
5560
 
        rb_raise(Cerror, "%s", msg);
5561
 
    }
5562
 
#ifdef UNICODE
5563
 
    uc_free(cp);
5564
 
#endif
5565
 
    return cn;
5566
 
}
5567
 
 
5568
 
static VALUE
5569
 
stmt_column(int argc, VALUE *argv, VALUE self)
5570
 
{
5571
 
    STMT *q;
5572
 
    VALUE col;
5573
 
 
5574
 
    rb_scan_args(argc, argv, "1", &col);
5575
 
    Check_Type(col, T_FIXNUM);
5576
 
    Data_Get_Struct(self, STMT, q);
5577
 
    check_ncols(q);
5578
 
    return make_col(q->hstmt, FIX2INT(col), q->upc);
5579
 
}
5580
 
 
5581
 
static VALUE
5582
 
stmt_columns(int argc, VALUE *argv, VALUE self)
5583
 
{
5584
 
    STMT *q;
5585
 
    int i;
5586
 
    VALUE res, as_ary = Qfalse;
5587
 
 
5588
 
    rb_scan_args(argc, argv, "01", &as_ary);
5589
 
    Data_Get_Struct(self, STMT, q);
5590
 
    check_ncols(q);
5591
 
    if (rb_block_given_p()) {
5592
 
        for (i = 0; i < q->ncols; i++) {
5593
 
            rb_yield(make_col(q->hstmt, i, q->upc));
5594
 
        }
5595
 
        return self;
5596
 
    }
5597
 
    if (RTEST(as_ary)) {
5598
 
        res = rb_ary_new2(q->ncols);
5599
 
    } else {
5600
 
        res = rb_hash_new();
5601
 
    }
5602
 
    for (i = 0; i < q->ncols; i++) {
5603
 
        VALUE obj;
5604
 
 
5605
 
        obj = make_col(q->hstmt, i, q->upc);
5606
 
        if (RTEST(as_ary)) {
5607
 
            rb_ary_store(res, i, obj);
5608
 
        } else {
5609
 
            VALUE name = rb_iv_get(obj, "@name");
5610
 
 
5611
 
            if (rb_funcall(res, IDkeyp, 1, name) == Qtrue) {
5612
 
                char buf[32];
5613
 
 
5614
 
                sprintf(buf, "#%d", i);
5615
 
                name = rb_str_dup(name);
5616
 
                name = rb_obj_taint(rb_str_cat2(name, buf));
5617
 
            }
5618
 
            rb_hash_aset(res, name, obj);
5619
 
        }
5620
 
    }
5621
 
    return res;
5622
 
}
5623
 
 
5624
 
static VALUE
5625
 
stmt_param(int argc, VALUE *argv, VALUE self)
5626
 
{
5627
 
    STMT *q;
5628
 
    VALUE par;
5629
 
    int i;
5630
 
 
5631
 
    rb_scan_args(argc, argv, "1", &par);
5632
 
    Check_Type(par, T_FIXNUM);
5633
 
    Data_Get_Struct(self, STMT, q);
5634
 
    i = FIX2INT(par);
5635
 
    if ((i < 0) || (i >= q->nump)) {
5636
 
        rb_raise(Cerror, set_err("Parameter out of bounds", 0));
5637
 
    }
5638
 
    return make_par(q, i);
5639
 
}
5640
 
 
5641
 
static VALUE
5642
 
stmt_params(VALUE self)
5643
 
{
5644
 
    STMT *q;
5645
 
    int i;
5646
 
    VALUE res;
5647
 
 
5648
 
    Data_Get_Struct(self, STMT, q);
5649
 
    if (rb_block_given_p()) {
5650
 
        for (i = 0; i < q->nump; i++) {
5651
 
            rb_yield(make_par(q, i));
5652
 
        }
5653
 
        return self;
5654
 
    }
5655
 
    res = rb_ary_new2(q->nump);
5656
 
    for (i = 0; i < q->nump; i++) {
5657
 
        VALUE obj;
5658
 
 
5659
 
        obj = make_par(q, i);
5660
 
        rb_ary_store(res, i, obj);
5661
 
    }
5662
 
    return res;
5663
 
}
5664
 
 
5665
 
static VALUE
5666
 
do_fetch(STMT *q, int mode)
5667
 
{
5668
 
    int i, offc;
5669
 
    char **bufs, *msg;
5670
 
    VALUE res;
5671
 
 
5672
 
    if (q->ncols <= 0) {
5673
 
        rb_raise(Cerror, set_err("No columns in result set", 0));
5674
 
    }
5675
 
    if (++q->fetchc >= 500) {
5676
 
        q->fetchc = 0;
5677
 
        start_gc();
5678
 
    }
5679
 
    bufs = q->dbufs;
5680
 
    if (bufs == NULL) {
5681
 
        int need = sizeof (char *) * q->ncols, needp;
5682
 
        char *p;
5683
 
 
5684
 
        need = LEN_ALIGN(need);
5685
 
        needp = need;
5686
 
        for (i = 0; i < q->ncols; i++) {
5687
 
            if (q->coltypes[i].size != SQL_NO_TOTAL) {
5688
 
                need += LEN_ALIGN(q->coltypes[i].size);
5689
 
            }
5690
 
        }
5691
 
        p = ALLOC_N(char, need);
5692
 
        if (p == NULL) {
5693
 
            rb_raise(Cerror, set_err("Out of memory", 0));
5694
 
        }
5695
 
        q->dbufs = bufs = (char **) p;
5696
 
        p += needp;
5697
 
        for (i = 0; i < q->ncols; i++) {
5698
 
            int len = q->coltypes[i].size;
5699
 
 
5700
 
            if (len == SQL_NO_TOTAL) {
5701
 
                bufs[i] = NULL;
5702
 
            } else {
5703
 
                bufs[i] = p;
5704
 
                p += LEN_ALIGN(len);
5705
 
            }
5706
 
        }
5707
 
    }
5708
 
    switch (mode & DOFETCH_MODES) {
5709
 
    case DOFETCH_HASH:
5710
 
    case DOFETCH_HASH2:
5711
 
    case DOFETCH_HASHK:
5712
 
    case DOFETCH_HASHK2:
5713
 
        if (q->colnames == NULL) {
5714
 
            int need = sizeof (char *) * 4 * q->ncols + sizeof (char *);
5715
 
            int max_len[2] = { 0, 0 };
5716
 
            char **na, *p;
5717
 
#ifdef UNICODE
5718
 
            SQLWCHAR name[SQL_MAX_MESSAGE_LENGTH];
5719
 
#else
5720
 
            char name[SQL_MAX_MESSAGE_LENGTH];
5721
 
#endif
5722
 
            SQLSMALLINT name_len;
5723
 
 
5724
 
            for (i = 0; i < q->ncols; i++) {
5725
 
                int need_len;
5726
 
 
5727
 
                name[0] = 0;
5728
 
                if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5729
 
                               SQLColAttributes(q->hstmt,
5730
 
                                                (SQLUSMALLINT) (i + 1),
5731
 
                                                SQL_COLUMN_TABLE_NAME,
5732
 
                                                name,
5733
 
                                                sizeof (name),
5734
 
                                                &name_len, NULL),
5735
 
                               &msg,
5736
 
                               "SQLColAttributes(SQL_COLUMN_TABLE_NAME)")) {
5737
 
                    rb_raise(Cerror, "%s", msg);
5738
 
                }
5739
 
                if (name_len >= sizeof (name)) {
5740
 
                    name_len = sizeof (name) - 1;
5741
 
                }
5742
 
                if (name_len > 0) {
5743
 
                    name[name_len / sizeof (name[0])] = 0;
5744
 
                }
5745
 
#ifdef UNICODE
5746
 
                need_len = 6 * (uc_strlen(name) + 1);
5747
 
#else
5748
 
                need_len = 2 * (strlen(name) + 1);
5749
 
#endif
5750
 
                need += need_len;
5751
 
                if (max_len[0] < need_len) {
5752
 
                    max_len[0] = need_len;
5753
 
                }
5754
 
                name[0] = 0;
5755
 
                if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5756
 
                               SQLColAttributes(q->hstmt,
5757
 
                                                (SQLUSMALLINT) (i + 1),
5758
 
                                                SQL_COLUMN_LABEL, name,
5759
 
                                                sizeof (name),
5760
 
                                                &name_len, NULL),
5761
 
                               &msg, "SQLColAttributes(SQL_COLUMN_LABEL)")) {
5762
 
                    rb_raise(Cerror, "%s", msg);
5763
 
                }
5764
 
                if (name_len >= sizeof (name)) {
5765
 
                    name_len = sizeof (name) - 1;
5766
 
                }
5767
 
                if (name_len > 0) {
5768
 
                    name[name_len / sizeof (name[0])] = 0;
5769
 
                }
5770
 
#ifdef UNICODE
5771
 
                need_len = 6 * 2 * (uc_strlen(name) + 1);
5772
 
#else
5773
 
                need_len = 2 * (strlen(name) + 1);
5774
 
#endif
5775
 
                need += need_len;
5776
 
                if (max_len[1] < need_len) {
5777
 
                    max_len[1] = need_len;
5778
 
                }
5779
 
            }
5780
 
            need += max_len[0] + max_len[1] + 32;
5781
 
            p = ALLOC_N(char, need);
5782
 
            if (p == NULL) {
5783
 
                rb_raise(Cerror, set_err("Out of memory", 0));
5784
 
            }
5785
 
            na = (char **) p;
5786
 
            p += sizeof (char *) * 4 * q->ncols + sizeof (char *);
5787
 
            for (i = 0; i < q->ncols; i++) {
5788
 
                char *p0;
5789
 
 
5790
 
                name[0] = 0;
5791
 
                callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5792
 
                        SQLColAttributes(q->hstmt, (SQLUSMALLINT) (i + 1),
5793
 
                                         SQL_COLUMN_TABLE_NAME, name,
5794
 
                                         sizeof (name), &name_len, NULL),
5795
 
                        "SQLColAttributes(SQL_COLUMN_TABLE_NAME)");
5796
 
                if (name_len >= sizeof (name)) {
5797
 
                    name_len = sizeof (name) - 1;
5798
 
                }
5799
 
                if (name_len > 0) {
5800
 
                    name[name_len / sizeof (name[0])] = 0;
5801
 
                }
5802
 
                na[i + q->ncols] = p;
5803
 
#ifdef UNICODE
5804
 
                p += mkutf(p, name, uc_strlen(name));
5805
 
#else
5806
 
                strcpy(p, name);
5807
 
#endif
5808
 
                strcat(p, ".");
5809
 
                p += strlen(p);
5810
 
                p0 = p;
5811
 
                name[0] = 0;
5812
 
                callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5813
 
                        SQLColAttributes(q->hstmt, (SQLUSMALLINT) (i + 1),
5814
 
                                         SQL_COLUMN_LABEL, name,
5815
 
                                         sizeof (name), &name_len, NULL),
5816
 
                        "SQLColAttributes(SQL_COLUMN_LABEL)");
5817
 
                if (name_len >= sizeof (name)) {
5818
 
                    name_len = sizeof (name) - 1;
5819
 
                }
5820
 
                if (name_len > 0) {
5821
 
                    name[name_len / sizeof (name[0])] = 0;
5822
 
                }
5823
 
                na[i] = p;
5824
 
#ifdef UNICODE
5825
 
                p += mkutf(p, name, uc_strlen(name)) + 1;
5826
 
#else
5827
 
                strcpy(p, name);
5828
 
                p += strlen(p) + 1;
5829
 
#endif
5830
 
                na[i + 3 * q->ncols] = p;
5831
 
                strcpy(p, na[i + q->ncols]);
5832
 
                p += p0 - na[i + q->ncols];
5833
 
                na[i + 2 * q->ncols] = upcase_if(p, 1);
5834
 
                p += strlen(p) + 1;
5835
 
            }
5836
 
            /* reserved space for later adjustments */
5837
 
            na[4 * q->ncols] = p;
5838
 
            q->colnames = na;
5839
 
        }
5840
 
        /* FALL THRU */
5841
 
    case DOFETCH_HASHN:
5842
 
        if (mode & DOFETCH_BANG) {
5843
 
            res = rb_iv_get(q->self, "@_h");
5844
 
            if (res == Qnil) {
5845
 
                res = rb_hash_new();
5846
 
                rb_iv_set(q->self, "@_h", res);
5847
 
            }
5848
 
        } else {
5849
 
            res = rb_hash_new();
5850
 
        }
5851
 
        break;
5852
 
    default:
5853
 
        if (mode & DOFETCH_BANG) {
5854
 
            res = rb_iv_get(q->self, "@_a");
5855
 
            if (res == Qnil) {
5856
 
                res = rb_ary_new2(q->ncols);
5857
 
                rb_iv_set(q->self, "@_a", res);
5858
 
            } else {
5859
 
                rb_ary_clear(res);
5860
 
            }
5861
 
        } else {
5862
 
            res = rb_ary_new2(q->ncols);
5863
 
        }
5864
 
    }
5865
 
    offc = q->upc ? (2 * q->ncols) : 0;
5866
 
    for (i = 0; i < q->ncols; i++) {
5867
 
        SQLLEN curlen, totlen;
5868
 
        SQLSMALLINT type = q->coltypes[i].type;
5869
 
        VALUE v, name;
5870
 
        char *valp, *freep = NULL;
5871
 
 
5872
 
        curlen = q->coltypes[i].size;
5873
 
        if (curlen == SQL_NO_TOTAL) {
5874
 
            SQLLEN chunksize = SEGSIZE;   
5875
 
 
5876
 
            totlen = 0;
5877
 
#ifdef UNICODE
5878
 
            valp = ALLOC_N(char, chunksize + sizeof (SQLWCHAR));
5879
 
#else
5880
 
            valp = ALLOC_N(char, chunksize + 1);
5881
 
#endif
5882
 
            freep = valp;
5883
 
            while ((curlen == SQL_NO_TOTAL) || (curlen > chunksize)) {
5884
 
                SQLRETURN rc;
5885
 
                int ret;
5886
 
 
5887
 
                rc = SQLGetData(q->hstmt, (SQLUSMALLINT) (i + 1),
5888
 
                                type, (SQLPOINTER) (valp + totlen),
5889
 
#ifdef UNICODE
5890
 
                                ((type == SQL_C_CHAR) || (type == SQL_C_WCHAR)) ?
5891
 
                                (chunksize + sizeof (SQLWCHAR)) : chunksize,
5892
 
#else
5893
 
                                (type == SQL_C_CHAR) ?
5894
 
                                (chunksize + 1) : chunksize,
5895
 
#endif
5896
 
                                &curlen);
5897
 
                if (rc == SQL_NO_DATA) {
5898
 
                    if (curlen == SQL_NO_TOTAL) {
5899
 
                        curlen = totlen;
5900
 
                    }
5901
 
                    break;
5902
 
                }
5903
 
                ret = succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5904
 
                                rc, &msg, "SQLGetData");
5905
 
                if (!ret) {
5906
 
                    xfree(valp);
5907
 
                    rb_raise(Cerror, "%s", msg);
5908
 
                }
5909
 
                if (curlen == SQL_NULL_DATA) {
5910
 
                    break;
5911
 
                }
5912
 
                if (curlen == SQL_NO_TOTAL) {
5913
 
                    totlen += chunksize;
5914
 
                } else if (curlen > chunksize) {
5915
 
                    totlen += chunksize;
5916
 
                    chunksize = curlen - chunksize;
5917
 
                } else {
5918
 
                    totlen += curlen;
5919
 
                    break;
5920
 
                }
5921
 
#ifdef UNICODE
5922
 
                REALLOC_N(valp, char, totlen + chunksize + sizeof (SQLWCHAR));
5923
 
#else
5924
 
                REALLOC_N(valp, char, totlen + chunksize + 1);
5925
 
#endif
5926
 
                if (valp == NULL) {
5927
 
                    if (freep != NULL) {
5928
 
                        xfree(freep);
5929
 
                    }
5930
 
                    rb_raise(Cerror, set_err("Out of memory", 0));
5931
 
                }
5932
 
                freep = valp;
5933
 
            }
5934
 
            if (totlen > 0) {
5935
 
                curlen = totlen;
5936
 
            }
5937
 
        } else {
5938
 
            totlen = curlen;
5939
 
            valp = bufs[i];
5940
 
            if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
5941
 
                           SQLGetData(q->hstmt, (SQLUSMALLINT) (i + 1), type,
5942
 
                                      (SQLPOINTER) valp, totlen, &curlen),
5943
 
                           &msg, "SQLGetData")) {
5944
 
                rb_raise(Cerror, "%s", msg);
5945
 
            }
5946
 
        }
5947
 
        if (curlen == SQL_NULL_DATA) {
5948
 
            v = Qnil;
5949
 
        } else {
5950
 
            switch (type) {
5951
 
            case SQL_C_LONG:
5952
 
                v = INT2NUM(*((SQLINTEGER *) valp));
5953
 
                break;
5954
 
            case SQL_C_DOUBLE:
5955
 
                v = rb_float_new(*((double *) valp));
5956
 
                break;
5957
 
#ifdef SQL_C_SBIGINT
5958
 
            case SQL_C_SBIGINT:
5959
 
#ifdef LL2NUM
5960
 
                v = LL2NUM(*((SQLBIGINT *) valp));
5961
 
#else
5962
 
                v = INT2NUM(*((SQLBIGINT *) valp));
5963
 
#endif
5964
 
                break;
5965
 
#endif
5966
 
#ifdef SQL_C_UBIGINT
5967
 
            case SQL_C_UBIGINT:
5968
 
#ifdef LL2NUM
5969
 
                v = ULL2NUM(*((SQLBIGINT *) valp));
5970
 
#else
5971
 
                v = UINT2NUM(*((SQLBIGINT *) valp));
5972
 
#endif
5973
 
                break;
5974
 
#endif
5975
 
            case SQL_C_DATE:
5976
 
                {
5977
 
                    DATE_STRUCT *date;
5978
 
 
5979
 
                    v = Data_Make_Struct(Cdate, DATE_STRUCT, 0, xfree, date);
5980
 
                    *date = *(DATE_STRUCT *) valp;
5981
 
                }
5982
 
                break;
5983
 
            case SQL_C_TIME:
5984
 
                {
5985
 
                    TIME_STRUCT *time;
5986
 
 
5987
 
                    v = Data_Make_Struct(Ctime, TIME_STRUCT, 0, xfree, time);
5988
 
                    *time = *(TIME_STRUCT *) valp;
5989
 
                }
5990
 
                break;
5991
 
            case SQL_C_TIMESTAMP:
5992
 
                {
5993
 
                    TIMESTAMP_STRUCT *ts;
5994
 
 
5995
 
                    v = Data_Make_Struct(Ctimestamp, TIMESTAMP_STRUCT,
5996
 
                                         0, xfree, ts);
5997
 
                    *ts = *(TIMESTAMP_STRUCT *) valp;
5998
 
                }
5999
 
                break;
6000
 
#ifdef UNICODE
6001
 
            case SQL_C_WCHAR:
6002
 
                v = uc_tainted_str_new((SQLWCHAR *) valp,
6003
 
                                       curlen / sizeof (SQLWCHAR));
6004
 
                break;
6005
 
#endif
6006
 
            default:
6007
 
                v = rb_tainted_str_new(valp, curlen);
6008
 
                break;
6009
 
            }
6010
 
        }
6011
 
        if (freep != NULL) {
6012
 
            xfree(freep);
6013
 
        }
6014
 
        switch (mode & DOFETCH_MODES) {
6015
 
        case DOFETCH_HASH:
6016
 
            valp = q->colnames[i + offc];
6017
 
            goto doaset;
6018
 
        case DOFETCH_HASH2:
6019
 
            valp = q->colnames[i + offc + q->ncols];
6020
 
        doaset:
6021
 
            name = rb_tainted_str_new2(valp);
6022
 
            if (rb_funcall(res, IDkeyp, 1, name) == Qtrue) {
6023
 
                char *p;
6024
 
 
6025
 
                p = q->colnames[4 * q->ncols];
6026
 
                sprintf(p, "#%d", i);
6027
 
                name = rb_str_cat2(name, p);
6028
 
            }
6029
 
            rb_hash_aset(res, name, v);
6030
 
            break;
6031
 
        case DOFETCH_HASHK:
6032
 
            valp = q->colnames[i + offc];
6033
 
            goto dokset;
6034
 
        case DOFETCH_HASHK2:
6035
 
            valp = q->colnames[i + offc + q->ncols];
6036
 
        dokset:
6037
 
            name = ID2SYM(rb_intern(valp));
6038
 
            if (rb_funcall(res, IDkeyp, 1, name) == Qtrue) {
6039
 
                char *p;
6040
 
 
6041
 
                p = q->colnames[4 * q->ncols];
6042
 
                sprintf(p, "%s#%d", valp, i);
6043
 
                name = ID2SYM(rb_intern(p));
6044
 
            }
6045
 
            rb_hash_aset(res, name, v);
6046
 
            break;
6047
 
        case DOFETCH_HASHN:
6048
 
            name = INT2NUM(i);
6049
 
            rb_hash_aset(res, name, v);
6050
 
            break;
6051
 
        default:
6052
 
            rb_ary_push(res, v);
6053
 
        }
6054
 
    }
6055
 
    return res;
6056
 
}
6057
 
 
6058
 
static VALUE
6059
 
stmt_fetch1(VALUE self, int bang)
6060
 
{
6061
 
    STMT *q;
6062
 
    SQLRETURN ret;
6063
 
    char *msg, *err;
6064
 
#if (ODBCVER < 0x0300)
6065
 
    SQLUINTEGER nRows;
6066
 
    SQLUSMALLINT rowStat[1];
6067
 
#endif
6068
 
 
6069
 
    Data_Get_Struct(self, STMT, q);
6070
 
    if (q->ncols <= 0) {
6071
 
        return Qnil;
6072
 
    }
6073
 
    if (q->usef) {
6074
 
        goto usef;
6075
 
    }
6076
 
#if (ODBCVER < 0x0300)
6077
 
    msg = "SQLExtendedFetch(SQL_FETCH_NEXT)";
6078
 
    ret = SQLExtendedFetch(q->hstmt, SQL_FETCH_NEXT, 0, &nRows, rowStat);
6079
 
#else
6080
 
    msg = "SQLFetchScroll(SQL_FETCH_NEXT)";
6081
 
    ret = SQLFetchScroll(q->hstmt, SQL_FETCH_NEXT, 0);
6082
 
#endif
6083
 
    if (ret == SQL_NO_DATA) {
6084
 
        (void) tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, msg);
6085
 
        return Qnil;
6086
 
    }
6087
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, &err, msg)) {
6088
 
        return do_fetch(q, DOFETCH_ARY | (bang ? DOFETCH_BANG : 0));
6089
 
    }
6090
 
    if ((err != NULL) &&
6091
 
        ((strncmp(err, "IM001", 5) == 0) ||
6092
 
         (strncmp(err, "HYC00", 5) == 0))) {
6093
 
usef:
6094
 
        /* Fallback to SQLFetch() when others not implemented */
6095
 
        msg = "SQLFetch";
6096
 
        q->usef = 1;
6097
 
        ret = SQLFetch(q->hstmt);
6098
 
        if (ret == SQL_NO_DATA) {
6099
 
            (void) tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, msg);
6100
 
            return Qnil;
6101
 
        }
6102
 
        if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret,
6103
 
                      &err, msg)) {
6104
 
            return do_fetch(q, DOFETCH_ARY | (bang ? DOFETCH_BANG : 0));
6105
 
        }
6106
 
    }
6107
 
    rb_raise(Cerror, "%s", err);
6108
 
    return Qnil;
6109
 
}
6110
 
 
6111
 
static VALUE
6112
 
stmt_fetch(VALUE self)
6113
 
{
6114
 
    if (rb_block_given_p()) {
6115
 
        return stmt_each(self);
6116
 
    }
6117
 
    return stmt_fetch1(self, 0);
6118
 
}
6119
 
 
6120
 
static VALUE
6121
 
stmt_fetch_bang(VALUE self)
6122
 
{
6123
 
    if (rb_block_given_p()) {
6124
 
        return stmt_each(self);
6125
 
    }
6126
 
    return stmt_fetch1(self, 1);
6127
 
}
6128
 
 
6129
 
static VALUE
6130
 
stmt_fetch_first1(VALUE self, int bang, int nopos)
6131
 
{
6132
 
    STMT *q;
6133
 
    SQLRETURN ret;
6134
 
    char *msg, *err;
6135
 
#if (ODBCVER < 0x0300)
6136
 
    SQLUINTEGER nRows;
6137
 
    SQLUSMALLINT rowStat[1];
6138
 
#endif
6139
 
 
6140
 
    Data_Get_Struct(self, STMT, q);
6141
 
    if (q->ncols <= 0) {
6142
 
        return Qnil;
6143
 
    }
6144
 
    if (nopos) {
6145
 
        goto dofetch;
6146
 
    }
6147
 
#if (ODBCVER < 0x0300)
6148
 
    msg = "SQLExtendedFetch(SQL_FETCH_FIRST)";
6149
 
    ret = SQLExtendedFetch(q->hstmt, SQL_FETCH_FIRST, 0, &nRows, rowStat);
6150
 
#else
6151
 
    msg = "SQLFetchScroll(SQL_FETCH_FIRST)";
6152
 
    ret = SQLFetchScroll(q->hstmt, SQL_FETCH_FIRST, 0);
6153
 
#endif
6154
 
    if (ret == SQL_NO_DATA) {
6155
 
        (void) tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, msg);
6156
 
        return Qnil;
6157
 
    }
6158
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, &err, msg)) {
6159
 
dofetch:
6160
 
        return do_fetch(q, DOFETCH_ARY | (bang ? DOFETCH_BANG : 0));
6161
 
    }
6162
 
    rb_raise(Cerror, "%s", err);
6163
 
    return Qnil;
6164
 
}
6165
 
 
6166
 
static VALUE
6167
 
stmt_fetch_first(VALUE self)
6168
 
{
6169
 
    return stmt_fetch_first1(self, 0, 0);
6170
 
}
6171
 
 
6172
 
static VALUE
6173
 
stmt_fetch_first_bang(VALUE self)
6174
 
{
6175
 
    return stmt_fetch_first1(self, 1, 0);
6176
 
}
6177
 
 
6178
 
static VALUE
6179
 
stmt_fetch_scroll1(int argc, VALUE *argv, VALUE self, int bang)
6180
 
{
6181
 
    STMT *q;
6182
 
    VALUE dir, offs;
6183
 
    SQLRETURN ret;
6184
 
    int idir, ioffs = 1;
6185
 
    char msg[128], *err;
6186
 
#if (ODBCVER < 0x0300)
6187
 
    SQLUINTEGER nRows;
6188
 
    SQLUSMALLINT rowStat[1];
6189
 
#endif
6190
 
 
6191
 
    rb_scan_args(argc, argv, "11", &dir, &offs);
6192
 
    idir = NUM2INT(dir);
6193
 
    if (offs != Qnil) {
6194
 
        ioffs = NUM2INT(offs);
6195
 
    }
6196
 
    Data_Get_Struct(self, STMT, q);
6197
 
    if (q->ncols <= 0) {
6198
 
        return Qnil;
6199
 
    }
6200
 
#if (ODBCVER < 0x0300)
6201
 
    sprintf(msg, "SQLExtendedFetch(%d)", idir);
6202
 
    ret = SQLExtendedFetch(q->hstmt, (SQLSMALLINT) idir, (SQLINTEGER) ioffs,
6203
 
                           &nRows, rowStat);
6204
 
#else
6205
 
    sprintf(msg, "SQLFetchScroll(%d)", idir);
6206
 
    ret = SQLFetchScroll(q->hstmt, (SQLSMALLINT) idir, (SQLINTEGER) ioffs);
6207
 
#endif
6208
 
    if (ret == SQL_NO_DATA) {
6209
 
        (void) tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, msg);
6210
 
        return Qnil;
6211
 
    }
6212
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, &err, msg)) {
6213
 
        return do_fetch(q, DOFETCH_ARY | (bang ? DOFETCH_BANG : 0));
6214
 
    }
6215
 
    rb_raise(Cerror, "%s", err);
6216
 
    return Qnil;
6217
 
}
6218
 
 
6219
 
static VALUE
6220
 
stmt_fetch_scroll(int argc, VALUE *argv, VALUE self)
6221
 
{
6222
 
    return stmt_fetch_scroll1(argc, argv, self, 0);
6223
 
}
6224
 
 
6225
 
static VALUE
6226
 
stmt_fetch_scroll_bang(int argc, VALUE *argv, VALUE self)
6227
 
{
6228
 
    return stmt_fetch_scroll1(argc, argv, self, 1);
6229
 
}
6230
 
 
6231
 
static VALUE
6232
 
stmt_fetch_many(VALUE self, VALUE arg)
6233
 
{
6234
 
    int i, max = 0, all = arg == Qnil;
6235
 
    VALUE res;
6236
 
 
6237
 
    if (!all) {
6238
 
        max = NUM2INT(arg);
6239
 
    }
6240
 
    res = rb_ary_new();
6241
 
    for (i = 0; all || (i < max); i++) {
6242
 
        VALUE v = stmt_fetch1(self, 0);
6243
 
 
6244
 
        if (v == Qnil) {
6245
 
            break;
6246
 
        }
6247
 
        rb_ary_push(res, v);
6248
 
    }
6249
 
    return (i == 0) ? Qnil : res;
6250
 
}
6251
 
 
6252
 
static VALUE
6253
 
stmt_fetch_all(VALUE self)
6254
 
{
6255
 
    return stmt_fetch_many(self, Qnil);
6256
 
}
6257
 
 
6258
 
static int
6259
 
stmt_hash_mode(int argc, VALUE *argv, VALUE self)
6260
 
{
6261
 
    VALUE withtab = Qnil, usesym = Qnil;
6262
 
    int mode = DOFETCH_HASH;
6263
 
 
6264
 
    rb_scan_args(argc, argv, "02", &withtab, &usesym);
6265
 
    if ((withtab != Qtrue) && (withtab != Qfalse) && (withtab != Modbc) &&
6266
 
        (rb_obj_is_kind_of(withtab, rb_cHash) == Qtrue)) {
6267
 
        VALUE v;
6268
 
 
6269
 
        v = rb_hash_aref(withtab, ID2SYM(IDkey));
6270
 
        if (v == ID2SYM(IDSymbol)) {
6271
 
            mode = DOFETCH_HASHK;
6272
 
        } else if (v == ID2SYM(IDString)) {
6273
 
            mode = DOFETCH_HASH;
6274
 
        } else if (v == ID2SYM(IDFixnum)) {
6275
 
            mode = DOFETCH_HASHN;
6276
 
        } else {
6277
 
            rb_raise(Cerror, "Unsupported key mode");
6278
 
        }
6279
 
        if (mode != DOFETCH_HASHN) {
6280
 
            v = rb_hash_aref(withtab, ID2SYM(IDtable_names));
6281
 
            if (RTEST(v)) {
6282
 
                mode = (mode == DOFETCH_HASHK)
6283
 
                     ? DOFETCH_HASHK2 : DOFETCH_HASH2;
6284
 
            }
6285
 
        }
6286
 
        return mode;
6287
 
    }
6288
 
    if (withtab == Modbc) {
6289
 
        return DOFETCH_HASHN;
6290
 
    }
6291
 
    mode = RTEST(withtab) ? DOFETCH_HASH2 : DOFETCH_HASH;
6292
 
    if (RTEST(usesym)) {
6293
 
        mode = (mode == DOFETCH_HASH2) ? DOFETCH_HASHK2 : DOFETCH_HASHK;
6294
 
    }
6295
 
    return mode;
6296
 
}
6297
 
 
6298
 
static VALUE
6299
 
stmt_fetch_hash1(int argc, VALUE *argv, VALUE self, int bang)
6300
 
{
6301
 
    STMT *q;
6302
 
    SQLRETURN ret;
6303
 
    int mode = stmt_hash_mode(argc, argv, self);
6304
 
    char *msg, *err;
6305
 
#if (ODBCVER < 0x0300)
6306
 
    SQLUINTEGER nRows;
6307
 
    SQLUSMALLINT rowStat[1];
6308
 
#endif
6309
 
 
6310
 
    Data_Get_Struct(self, STMT, q);
6311
 
    if (q->ncols <= 0) {
6312
 
        return Qnil;
6313
 
    }
6314
 
    if (q->usef) {
6315
 
        goto usef;
6316
 
    }
6317
 
#if (ODBCVER < 0x0300)
6318
 
    msg = "SQLExtendedFetch(SQL_FETCH_NEXT)";
6319
 
    ret = SQLExtendedFetch(q->hstmt, SQL_FETCH_NEXT, 0, &nRows, rowStat);
6320
 
#else
6321
 
    msg = "SQLFetchScroll(SQL_FETCH_NEXT)";
6322
 
    ret = SQLFetchScroll(q->hstmt, SQL_FETCH_NEXT, 0);
6323
 
#endif
6324
 
    if (ret == SQL_NO_DATA) {
6325
 
        (void) tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, msg);
6326
 
        return Qnil;
6327
 
    }
6328
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, &err, msg)) {
6329
 
        return do_fetch(q, mode | (bang ? DOFETCH_BANG : 0));
6330
 
    }
6331
 
    if ((err != NULL) &&
6332
 
        ((strncmp(err, "IM001", 5) == 0) ||
6333
 
         (strncmp(err, "HYC00", 5) == 0))) {
6334
 
usef:
6335
 
        /* Fallback to SQLFetch() when others not implemented */
6336
 
        msg = "SQLFetch";
6337
 
        q->usef = 1;
6338
 
        ret = SQLFetch(q->hstmt);
6339
 
        if (ret == SQL_NO_DATA) {
6340
 
            (void) tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, msg);
6341
 
            return Qnil;
6342
 
        }
6343
 
        if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret,
6344
 
                      &err, msg)) {
6345
 
            return do_fetch(q, mode | (bang ? DOFETCH_BANG : 0));
6346
 
        }
6347
 
    }
6348
 
    rb_raise(Cerror, "%s", err);
6349
 
    return Qnil;
6350
 
}
6351
 
 
6352
 
static VALUE
6353
 
stmt_fetch_hash(int argc, VALUE *argv, VALUE self)
6354
 
{
6355
 
    if (rb_block_given_p()) {
6356
 
        return stmt_each_hash(argc, argv, self);
6357
 
    }
6358
 
    return stmt_fetch_hash1(argc, argv, self, 0);
6359
 
}
6360
 
 
6361
 
static VALUE
6362
 
stmt_fetch_hash_bang(int argc, VALUE *argv, VALUE self)
6363
 
{
6364
 
    if (rb_block_given_p()) {
6365
 
        return stmt_each_hash(argc, argv, self);
6366
 
    }
6367
 
    return stmt_fetch_hash1(argc, argv, self, 1);
6368
 
}
6369
 
 
6370
 
static VALUE
6371
 
stmt_fetch_first_hash1(int argc, VALUE *argv, VALUE self, int bang, int nopos)
6372
 
{
6373
 
    STMT *q;
6374
 
    SQLRETURN ret;
6375
 
    int mode = stmt_hash_mode(argc, argv, self);
6376
 
    char *msg, *err;
6377
 
#if (ODBCVER < 0x0300)
6378
 
    SQLUINTEGER nRows;
6379
 
    SQLUSMALLINT rowStat[1];
6380
 
#endif
6381
 
 
6382
 
    Data_Get_Struct(self, STMT, q);
6383
 
    if (q->ncols <= 0) {
6384
 
        return Qnil;
6385
 
    }
6386
 
    if (nopos) {
6387
 
        goto dofetch;
6388
 
    }
6389
 
#if (ODBCVER < 0x0300)
6390
 
    msg = "SQLExtendedFetch(SQL_FETCH_FIRST)";
6391
 
    ret = SQLExtendedFetch(q->hstmt, SQL_FETCH_FIRST, 0, &nRows, rowStat);
6392
 
#else
6393
 
    msg = "SQLFetchScroll(SQL_FETCH_FIRST)";
6394
 
    ret = SQLFetchScroll(q->hstmt, SQL_FETCH_FIRST, 0);
6395
 
#endif
6396
 
    if (ret == SQL_NO_DATA) {
6397
 
        (void) tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, msg);
6398
 
        return Qnil;
6399
 
    }
6400
 
    if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt, ret, &err, msg)) {
6401
 
dofetch:
6402
 
        return do_fetch(q, mode | (bang ? DOFETCH_BANG : 0));
6403
 
    }
6404
 
    rb_raise(Cerror, "%s", err);
6405
 
    return Qnil;
6406
 
}
6407
 
 
6408
 
static VALUE
6409
 
stmt_fetch_first_hash(int argc, VALUE *argv, VALUE self)
6410
 
{
6411
 
    return stmt_fetch_first_hash1(argc, argv, self, 0, 0);
6412
 
}
6413
 
 
6414
 
static VALUE
6415
 
stmt_each(VALUE self)
6416
 
{
6417
 
    VALUE row;
6418
 
    STMT *q;
6419
 
#if (ODBCVER < 0x0300)
6420
 
    SQLUINTEGER nRows;
6421
 
    SQLUSMALLINT rowStat[1];
6422
 
#endif
6423
 
 
6424
 
    Data_Get_Struct(self, STMT, q);
6425
 
#if (ODBCVER < 0x0300)
6426
 
    switch (callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6427
 
                    SQLExtendedFetch(q->hstmt, SQL_FETCH_FIRST, 0, &nRows,
6428
 
                                     rowStat),
6429
 
                    "SQLExtendedFetch(SQL_FETCH_FIRST)"))
6430
 
#else
6431
 
    switch (callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6432
 
                    SQLFetchScroll(q->hstmt, SQL_FETCH_FIRST, 0),
6433
 
                    "SQLFetchScroll(SQL_FETCH_FIRST)"))
6434
 
#endif
6435
 
    {
6436
 
    case SQL_NO_DATA:
6437
 
        row = Qnil;
6438
 
        break;
6439
 
    case SQL_SUCCESS:
6440
 
    case SQL_SUCCESS_WITH_INFO:
6441
 
        row = stmt_fetch_first1(self, 0, 1);
6442
 
        break;
6443
 
    default:
6444
 
        row = stmt_fetch1(self, 0);
6445
 
    }
6446
 
    while (row != Qnil) {
6447
 
        rb_yield(row);
6448
 
        row = stmt_fetch1(self, 0);
6449
 
    }
6450
 
    return self;
6451
 
}
6452
 
 
6453
 
static VALUE
6454
 
stmt_each_hash(int argc, VALUE *argv, VALUE self)
6455
 
{
6456
 
    VALUE row, withtab[2];
6457
 
    STMT *q;
6458
 
    int mode = stmt_hash_mode(argc, argv, self);
6459
 
#if (ODBCVER < 0x0300)
6460
 
    SQLUINTEGER nRows;
6461
 
    SQLUSMALLINT rowStat[1];
6462
 
#endif
6463
 
 
6464
 
    if (mode == DOFETCH_HASHN) {
6465
 
        withtab[0] = Modbc;
6466
 
        withtab[1] = Qfalse;
6467
 
    } else {
6468
 
        withtab[0] = ((mode == DOFETCH_HASH2) || (mode == DOFETCH_HASHK2))
6469
 
                   ? Qtrue : Qfalse;
6470
 
        withtab[1] = ((mode == DOFETCH_HASHK) || (mode == DOFETCH_HASHK2))
6471
 
                   ? Qtrue : Qfalse;
6472
 
    }
6473
 
    Data_Get_Struct(self, STMT, q);
6474
 
#if (ODBCVER < 0x0300)
6475
 
    switch (callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6476
 
                    SQLExtendedFetch(q->hstmt, SQL_FETCH_FIRST, 0, &nRows,
6477
 
                                     rowStat),
6478
 
                    "SQLExtendedFetch(SQL_FETCH_FIRST)"))
6479
 
#else
6480
 
    switch (callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6481
 
                    SQLFetchScroll(q->hstmt, SQL_FETCH_FIRST, 0),
6482
 
                    "SQLFetchScroll(SQL_FETCH_FIRST)"))
6483
 
#endif
6484
 
    {
6485
 
    case SQL_NO_DATA:
6486
 
        row = Qnil;
6487
 
        break;
6488
 
    case SQL_SUCCESS:
6489
 
    case SQL_SUCCESS_WITH_INFO:
6490
 
        row = stmt_fetch_first_hash1(2, withtab, self, 0, 1);
6491
 
        break;
6492
 
    default:
6493
 
        row = stmt_fetch_hash1(2, withtab, self, 0);
6494
 
    }
6495
 
    while (row != Qnil) {
6496
 
        rb_yield(row);
6497
 
        row = stmt_fetch_hash1(2, withtab, self, 0);
6498
 
    }
6499
 
    return self;
6500
 
}
6501
 
 
6502
 
static VALUE
6503
 
stmt_more_results(VALUE self)
6504
 
{
6505
 
    STMT *q;
6506
 
 
6507
 
    if (rb_block_given_p()) {
6508
 
        rb_raise(rb_eArgError, "block not allowed");
6509
 
    }
6510
 
    Data_Get_Struct(self, STMT, q);
6511
 
    if (q->hstmt == SQL_NULL_HSTMT) {
6512
 
        return Qfalse;
6513
 
    }
6514
 
    switch (tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6515
 
                     SQLMoreResults(q->hstmt), "SQLMoreResults")) {
6516
 
    case SQL_NO_DATA:
6517
 
        return Qfalse;
6518
 
    case SQL_SUCCESS:
6519
 
    case SQL_SUCCESS_WITH_INFO:
6520
 
        make_result(q->dbc, q->hstmt, self, 0);
6521
 
        break;
6522
 
    default:
6523
 
        rb_raise(Cerror, "%s",
6524
 
                 get_err(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt));
6525
 
    }
6526
 
    return Qtrue;
6527
 
}
6528
 
 
6529
 
static VALUE
6530
 
stmt_prep_int(int argc, VALUE *argv, VALUE self, int mode)
6531
 
{
6532
 
    DBC *p = get_dbc(self);
6533
 
    STMT *q = NULL;
6534
 
    VALUE sql, dbc, stmt;
6535
 
    SQLHSTMT hstmt;
6536
 
#ifdef UNICODE
6537
 
    SQLWCHAR *ssql = NULL;
6538
 
#else
6539
 
    SQLCHAR *ssql = NULL;
6540
 
#endif
6541
 
    char *csql = NULL, *msg = NULL;
6542
 
 
6543
 
    if (rb_obj_is_kind_of(self, Cstmt) == Qtrue) {
6544
 
        Data_Get_Struct(self, STMT, q);
6545
 
        if (q->hstmt == SQL_NULL_HSTMT) {
6546
 
            if (!succeeded(SQL_NULL_HENV, p->hdbc, q->hstmt,
6547
 
                           SQLAllocStmt(p->hdbc, &q->hstmt),
6548
 
                           &msg, "SQLAllocStmt")) {
6549
 
                rb_raise(Cerror, "%s", msg);
6550
 
            }
6551
 
        } else if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6552
 
                              SQLFreeStmt(q->hstmt, SQL_CLOSE),
6553
 
                              &msg, "SQLFreeStmt(SQL_CLOSE)")) {
6554
 
            rb_raise(Cerror, "%s", msg);
6555
 
        }
6556
 
        hstmt = q->hstmt;
6557
 
        stmt = self;
6558
 
        dbc = q->dbc;
6559
 
    } else {
6560
 
        if (!succeeded(SQL_NULL_HENV, p->hdbc, SQL_NULL_HSTMT,
6561
 
                       SQLAllocStmt(p->hdbc, &hstmt),
6562
 
                       &msg, "SQLAllocStmt")) {
6563
 
            rb_raise(Cerror, "%s", msg);
6564
 
        }
6565
 
        stmt = Qnil;
6566
 
        dbc = self;
6567
 
    }
6568
 
    rb_scan_args(argc, argv, "1", &sql);
6569
 
    Check_Type(sql, T_STRING);
6570
 
#ifdef UNICODE
6571
 
    csql = STR2CSTR(sql);
6572
 
    ssql = uc_from_utf((unsigned char *) csql, -1);
6573
 
    if (ssql == NULL) {
6574
 
        rb_raise(Cerror, set_err("Out of memory", 0));
6575
 
    }
6576
 
#else
6577
 
    csql = STR2CSTR(sql);
6578
 
    ssql = (SQLCHAR *) csql;
6579
 
#endif
6580
 
    if ((mode & MAKERES_EXECD)) {
6581
 
        SQLRETURN ret;
6582
 
 
6583
 
        if (!succeeded_nodata(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
6584
 
                              (ret = SQLExecDirect(hstmt, ssql, SQL_NTS)),
6585
 
                              &msg, "SQLExecDirect('%s')", csql)) {
6586
 
            goto sqlerr;
6587
 
        }
6588
 
        if (ret == SQL_NO_DATA) {
6589
 
#ifdef UNICODE
6590
 
            uc_free(ssql);
6591
 
#endif
6592
 
            return Qnil;
6593
 
        }
6594
 
    } else if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
6595
 
                          SQLPrepare(hstmt, ssql, SQL_NTS),
6596
 
                          &msg, "SQLPrepare('%s')", csql)) {
6597
 
sqlerr:
6598
 
#ifdef UNICODE
6599
 
        uc_free(ssql);
6600
 
#endif
6601
 
        callsql(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
6602
 
                SQLFreeStmt(hstmt, SQL_DROP), "SQLFreeStmt(SQL_DROP)");
6603
 
        if (q != NULL) {
6604
 
            q->hstmt = SQL_NULL_HSTMT;
6605
 
            unlink_stmt(q);
6606
 
        }
6607
 
        rb_raise(Cerror, "%s", msg);
6608
 
    } else {
6609
 
        mode |= MAKERES_PREPARE;
6610
 
    }
6611
 
#ifdef UNICODE
6612
 
    uc_free(ssql);
6613
 
#endif
6614
 
    return make_result(dbc, hstmt, stmt, mode);
6615
 
}
6616
 
 
6617
 
static VALUE
6618
 
stmt_prep(int argc, VALUE *argv, VALUE self)
6619
 
{
6620
 
    return stmt_prep_int(argc, argv, self, MAKERES_BLOCK);
6621
 
}
6622
 
 
6623
 
static int
6624
 
bind_one_param(int pnum, VALUE arg, STMT *q, char **msgp, int *outpp)
6625
 
{
6626
 
    SQLPOINTER valp = (SQLPOINTER) &q->pinfo[pnum].buffer;
6627
 
    SQLSMALLINT ctype, stype;
6628
 
    SQLINTEGER vlen, rlen;
6629
 
    SQLUINTEGER coldef;
6630
 
    long llen;
6631
 
    int retry = 1;
6632
 
#ifdef UNICODE
6633
 
    SQLWCHAR *up;
6634
 
 
6635
 
    q->pinfo[pnum].tofree = NULL;
6636
 
#endif
6637
 
    switch (TYPE(arg)) {
6638
 
    case T_STRING:
6639
 
#ifdef UNICODE
6640
 
        ctype = SQL_C_WCHAR;
6641
 
        up = (SQLWCHAR *) rb_str2cstr(arg, &llen);
6642
 
        if (llen != strlen((char *) up)) {
6643
 
            ctype = SQL_C_BINARY;
6644
 
            valp = (SQLPOINTER) up;
6645
 
            rlen = llen;
6646
 
            vlen = rlen + 1;
6647
 
            break;
6648
 
        }
6649
 
        up = uc_from_utf((unsigned char *) up, llen);
6650
 
        if (up == NULL) {
6651
 
            goto oom;
6652
 
        }
6653
 
        *(SQLWCHAR **) valp = up;
6654
 
        rlen = uc_strlen(up) * sizeof (SQLWCHAR);
6655
 
        vlen = rlen + sizeof (SQLWCHAR);
6656
 
        q->pinfo[pnum].tofree = up;
6657
 
#else
6658
 
        ctype = SQL_C_CHAR;
6659
 
        valp = (SQLPOINTER) rb_str2cstr(arg, &llen);
6660
 
        rlen = llen;
6661
 
        if (rlen != strlen((char *) valp)) {
6662
 
            ctype = SQL_C_BINARY;
6663
 
        }
6664
 
        vlen = rlen + 1;
6665
 
#endif
6666
 
        break;
6667
 
    case T_FIXNUM:
6668
 
        ctype = SQL_C_LONG;
6669
 
        *(SQLINTEGER *) valp = FIX2INT(arg);
6670
 
        rlen = 1;
6671
 
        vlen = sizeof (SQLINTEGER);
6672
 
        break;
6673
 
    case T_FLOAT:
6674
 
        ctype = SQL_C_DOUBLE;
6675
 
        *(double *) valp = NUM2DBL(arg);
6676
 
        rlen = 1;
6677
 
        vlen = sizeof (double);
6678
 
        break;
6679
 
    case T_NIL:
6680
 
        ctype = SQL_C_CHAR;
6681
 
        valp = NULL;
6682
 
        rlen = SQL_NULL_DATA;
6683
 
        vlen = 0;
6684
 
        break;
6685
 
    case T_SYMBOL:
6686
 
        ctype = SQL_C_CHAR;
6687
 
        valp = NULL;
6688
 
        vlen = 0;
6689
 
        if (arg == ID2SYM(IDNULL)) {
6690
 
            rlen = SQL_NULL_DATA;
6691
 
        } else if (arg == ID2SYM(IDdefault)) {
6692
 
            rlen = SQL_DEFAULT_PARAM;
6693
 
        }
6694
 
        /* fall through */
6695
 
    default:
6696
 
        if (rb_obj_is_kind_of(arg, Cdate) == Qtrue) {
6697
 
            DATE_STRUCT *date;
6698
 
 
6699
 
            ctype = SQL_C_DATE;
6700
 
            Data_Get_Struct(arg, DATE_STRUCT, date);
6701
 
            valp = (SQLPOINTER) date;
6702
 
            rlen = 1;
6703
 
            vlen = sizeof (DATE_STRUCT);
6704
 
            break;
6705
 
        }
6706
 
        if (rb_obj_is_kind_of(arg, Ctime) == Qtrue) {
6707
 
            TIME_STRUCT *time;
6708
 
 
6709
 
            ctype = SQL_C_TIME;
6710
 
            Data_Get_Struct(arg, TIME_STRUCT, time);
6711
 
            valp = (SQLPOINTER) time;
6712
 
            rlen = 1;
6713
 
            vlen = sizeof (TIME_STRUCT);
6714
 
            break;
6715
 
        }
6716
 
        if (rb_obj_is_kind_of(arg, Ctimestamp) == Qtrue) {
6717
 
            TIMESTAMP_STRUCT *ts;
6718
 
 
6719
 
            ctype = SQL_C_TIMESTAMP;
6720
 
            Data_Get_Struct(arg, TIMESTAMP_STRUCT, ts);
6721
 
            valp = (SQLPOINTER) ts;
6722
 
            rlen = 1;
6723
 
            vlen = sizeof (TIMESTAMP_STRUCT);
6724
 
            break;
6725
 
        }
6726
 
        ctype = SQL_C_CHAR;
6727
 
        valp = (SQLPOINTER *) rb_str2cstr(rb_str_to_str(arg), &llen);
6728
 
        rlen = llen;
6729
 
        if (rlen != strlen((char *) valp)) {
6730
 
            ctype = SQL_C_BINARY;
6731
 
        }
6732
 
        vlen = rlen + 1;
6733
 
        break;
6734
 
    }
6735
 
    stype = q->pinfo[pnum].type;
6736
 
    coldef = q->pinfo[pnum].coldef;
6737
 
    q->pinfo[pnum].rlen = rlen;
6738
 
    q->pinfo[pnum].ctype = ctype;
6739
 
    if (coldef == 0) {
6740
 
        switch (ctype) {
6741
 
        case SQL_C_LONG:
6742
 
            coldef = 10;
6743
 
            break;
6744
 
        case SQL_C_DOUBLE:
6745
 
            coldef = 15;
6746
 
            if (stype == SQL_VARCHAR) {
6747
 
                stype = SQL_DOUBLE;
6748
 
            }
6749
 
            break;
6750
 
        case SQL_C_DATE:
6751
 
            coldef = 10;
6752
 
            break;
6753
 
        case SQL_C_TIME:
6754
 
            coldef = 8;
6755
 
            break;
6756
 
        case SQL_C_TIMESTAMP:
6757
 
            coldef = 19;
6758
 
            break;
6759
 
        default:
6760
 
            /*
6761
 
             * Patch adopted from the Perl DBD::ODBC module ...
6762
 
             * per patch from Paul G. Weiss, who was experiencing re-preparing
6763
 
             * of queries when the size of the bound string's were increasing
6764
 
             * for example select * from tabtest where name = ?
6765
 
             * then executing with 'paul' and then 'thomas' would cause
6766
 
             * SQLServer to prepare the query twice, but if we ran 'thomas'
6767
 
             * then 'paul', it would not re-prepare the query.  The key seems
6768
 
             * to be allocating enough space for the largest parameter.
6769
 
             * TBD: the default for this should be a tunable parameter.
6770
 
             */
6771
 
            if ((stype == SQL_VARCHAR) &&
6772
 
                (q->pinfo[pnum].iotype != SQL_PARAM_INPUT_OUTPUT) &&
6773
 
                (q->pinfo[pnum].iotype != SQL_PARAM_OUTPUT)) {
6774
 
                if (q->pinfo[pnum].coldef_max == 0) {
6775
 
                    q->pinfo[pnum].coldef_max = (vlen > 128) ? vlen : 128;
6776
 
                } else {
6777
 
                    /* bump up max, if needed */
6778
 
                    if (vlen > q->pinfo[pnum].coldef_max) {
6779
 
                        q->pinfo[pnum].coldef_max = vlen;
6780
 
                    }
6781
 
                }
6782
 
                coldef = q->pinfo[pnum].coldef_max;
6783
 
            } else {
6784
 
                coldef = vlen;
6785
 
            }
6786
 
            break;
6787
 
        }
6788
 
    }
6789
 
    if ((q->pinfo[pnum].iotype == SQL_PARAM_INPUT_OUTPUT) ||
6790
 
        (q->pinfo[pnum].iotype == SQL_PARAM_OUTPUT)) {
6791
 
        if (valp == NULL) {
6792
 
            if (q->pinfo[pnum].outsize > 0) {
6793
 
                if (q->pinfo[pnum].outbuf != NULL) {
6794
 
                    xfree(q->pinfo[pnum].outbuf);
6795
 
                }
6796
 
                q->pinfo[pnum].outbuf = xmalloc(q->pinfo[pnum].outsize);
6797
 
                if (q->pinfo[pnum].outbuf == NULL) {
6798
 
                    goto oom;
6799
 
                }
6800
 
                ctype = q->pinfo[pnum].ctype = q->pinfo[pnum].outtype;
6801
 
                outpp[0]++;
6802
 
                valp = q->pinfo[pnum].outbuf;
6803
 
                vlen = q->pinfo[pnum].outsize;
6804
 
            }
6805
 
        } else {
6806
 
            if (q->pinfo[pnum].outbuf != NULL) {
6807
 
                xfree(q->pinfo[pnum].outbuf);
6808
 
            }
6809
 
            q->pinfo[pnum].outbuf = xmalloc(vlen);
6810
 
            if (q->pinfo[pnum].outbuf == NULL) {
6811
 
oom:
6812
 
#ifdef UNICODE
6813
 
                if (q->pinfo[pnum].tofree != NULL) {
6814
 
                    uc_free(q->pinfo[pnum].tofree);
6815
 
                    q->pinfo[pnum].tofree = NULL;
6816
 
                }
6817
 
#endif
6818
 
                *msgp = set_err("Out of memory", 0);
6819
 
                return -1;
6820
 
            }
6821
 
#ifdef UNICODE
6822
 
            if (ctype == SQL_C_WCHAR) {
6823
 
                memcpy(q->pinfo[pnum].outbuf, *(SQLWCHAR **) valp, vlen);
6824
 
            } else
6825
 
#endif
6826
 
            memcpy(q->pinfo[pnum].outbuf, valp, vlen);
6827
 
#ifdef UNICODE
6828
 
            if (ctype == SQL_C_WCHAR) {
6829
 
                *(SQLWCHAR **) valp = (SQLWCHAR *) q->pinfo[pnum].outbuf;
6830
 
            } else
6831
 
#endif
6832
 
            valp = q->pinfo[pnum].outbuf;
6833
 
            outpp[0]++;
6834
 
        }
6835
 
    }
6836
 
retry:
6837
 
#ifdef UNICODE
6838
 
    if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6839
 
                   SQLBindParameter(q->hstmt, (SQLUSMALLINT) (pnum + 1),
6840
 
                                    q->pinfo[pnum].iotype,
6841
 
                                    ctype, stype, coldef,
6842
 
                                    q->pinfo[pnum].scale,
6843
 
                                    (ctype == SQL_C_WCHAR) ?
6844
 
                                    *(SQLWCHAR **) valp : valp,
6845
 
                                    vlen, &q->pinfo[pnum].rlen),
6846
 
                   msgp, "SQLBindParameter(%d)", pnum + 1))
6847
 
#else
6848
 
    if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6849
 
                   SQLBindParameter(q->hstmt, (SQLUSMALLINT) (pnum + 1),
6850
 
                                    q->pinfo[pnum].iotype,
6851
 
                                    ctype, stype, coldef,
6852
 
                                    q->pinfo[pnum].scale,
6853
 
                                    valp, vlen, &q->pinfo[pnum].rlen),
6854
 
                   msgp, "SQLBindParameter(%d)", pnum + 1))
6855
 
#endif
6856
 
    {
6857
 
        if (retry) {
6858
 
            retry = 0;
6859
 
            if (stype == SQL_VARCHAR) {
6860
 
                /* maybe MS Jet memo field */
6861
 
                stype = SQL_LONGVARCHAR;
6862
 
                goto retry;
6863
 
            }
6864
 
#ifdef UNICODE
6865
 
            if (stype == SQL_WVARCHAR) {
6866
 
                stype = SQL_WLONGVARCHAR;
6867
 
                goto retry;
6868
 
            }
6869
 
#endif
6870
 
        }
6871
 
        return -1;
6872
 
    }
6873
 
    return 0;
6874
 
}
6875
 
 
6876
 
static VALUE
6877
 
stmt_exec_int(int argc, VALUE *argv, VALUE self, int mode)
6878
 
{
6879
 
    STMT *q;
6880
 
    int i, argnum, has_out_parms = 0;
6881
 
    char *msg = NULL;
6882
 
    SQLRETURN ret;
6883
 
 
6884
 
    Data_Get_Struct(self, STMT, q);
6885
 
    if (argc > q->nump - (EXEC_PARMXOUT(mode) < 0 ? 0 : 1)) {
6886
 
        rb_raise(Cerror, set_err("Too much parameters", 0));
6887
 
    }
6888
 
    if (q->hstmt == SQL_NULL_HSTMT) {
6889
 
        rb_raise(Cerror, set_err("Stale ODBC::Statement", 0));
6890
 
    }
6891
 
    if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6892
 
                   SQLFreeStmt(q->hstmt, SQL_CLOSE),
6893
 
                   &msg, "SQLFreeStmt(SQL_CLOSE)")) {
6894
 
        goto error;
6895
 
    }
6896
 
    callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6897
 
            SQLFreeStmt(q->hstmt, SQL_RESET_PARAMS),
6898
 
            "SQLFreeStmt(SQL_RESET_PARMS)");
6899
 
    for (i = argnum = 0; i < q->nump; i++) {
6900
 
        VALUE arg;
6901
 
 
6902
 
        if (i == EXEC_PARMXOUT(mode)) {
6903
 
            if (bind_one_param(i, Qnil, q, &msg, &has_out_parms) < 0) {
6904
 
                goto error;
6905
 
            }
6906
 
            continue;
6907
 
        }
6908
 
        arg = argnum < argc ? argv[argnum++] : Qnil;
6909
 
        if (bind_one_param(i, arg, q, &msg, &has_out_parms) < 0) {
6910
 
            goto error;
6911
 
        }
6912
 
    }
6913
 
    if (!succeeded_nodata(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6914
 
                          (ret = SQLExecute(q->hstmt)),
6915
 
                          &msg, "SQLExecute")) {
6916
 
error:
6917
 
#ifdef UNICODE
6918
 
        for (i = 0; i < q->nump; i++) {
6919
 
            if (q->pinfo[i].tofree != NULL) {
6920
 
                uc_free(q->pinfo[i].tofree);
6921
 
                q->pinfo[i].tofree = NULL;
6922
 
            }
6923
 
        }
6924
 
#endif
6925
 
        callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6926
 
                SQLFreeStmt(q->hstmt, SQL_DROP), "SQLFreeStmt(SQL_DROP)");
6927
 
        q->hstmt = SQL_NULL_HSTMT;
6928
 
        unlink_stmt(q);
6929
 
        rb_raise(Cerror, "%s", msg);
6930
 
    }
6931
 
#ifdef UNICODE
6932
 
    for (i = 0; i < q->nump; i++) {
6933
 
        if (q->pinfo[i].tofree != NULL) {
6934
 
            uc_free(q->pinfo[i].tofree);
6935
 
            q->pinfo[i].tofree = NULL;
6936
 
        }
6937
 
    }
6938
 
#endif
6939
 
    if (!has_out_parms) {
6940
 
        callsql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6941
 
                SQLFreeStmt(q->hstmt, SQL_RESET_PARAMS),
6942
 
                "SQLFreeStmt(SQL_RESET_PARAMS)");
6943
 
    }
6944
 
    if (ret == SQL_NO_DATA) {
6945
 
        return Qnil;
6946
 
    }
6947
 
    return make_result(q->dbc, q->hstmt, self, mode);
6948
 
}
6949
 
 
6950
 
static VALUE
6951
 
stmt_exec(int argc, VALUE *argv, VALUE self)
6952
 
{
6953
 
    return stmt_exec_int(argc, argv, self, MAKERES_BLOCK);
6954
 
}
6955
 
 
6956
 
static VALUE
6957
 
stmt_run(int argc, VALUE *argv, VALUE self)
6958
 
{
6959
 
    if (argc < 1) {
6960
 
        rb_raise(rb_eArgError, "wrong # of arguments");
6961
 
    }
6962
 
    if (argc == 1) {
6963
 
        return stmt_prep_int(1, argv, self,
6964
 
                             MAKERES_EXECD | MAKERES_BLOCK);
6965
 
    }
6966
 
    return stmt_exec(argc - 1, argv + 1, stmt_prep_int(1, argv, self, 0));
6967
 
}
6968
 
 
6969
 
static VALUE
6970
 
stmt_do(int argc, VALUE *argv, VALUE self)
6971
 
{
6972
 
    VALUE stmt;
6973
 
    
6974
 
    if (argc < 1) {
6975
 
        rb_raise(rb_eArgError, "wrong # of arguments");
6976
 
    }
6977
 
    if (argc == 1) {
6978
 
        stmt = stmt_prep_int(1, argv, self,
6979
 
                             MAKERES_EXECD | MAKERES_BLOCK | MAKERES_NOCLOSE);
6980
 
    } else {
6981
 
        stmt = stmt_prep_int(1, argv, self, 0);
6982
 
        stmt_exec_int(argc - 1, argv + 1, stmt,
6983
 
                      MAKERES_BLOCK | MAKERES_NOCLOSE);
6984
 
    }
6985
 
    return rb_ensure(stmt_nrows, stmt, stmt_drop, stmt);
6986
 
}
6987
 
 
6988
 
static VALUE
6989
 
stmt_ignorecase(int argc, VALUE *argv, VALUE self)
6990
 
{
6991
 
    VALUE onoff = Qnil;
6992
 
    int *flag = NULL;
6993
 
 
6994
 
    rb_scan_args(argc, argv, "01", &onoff);
6995
 
    if (rb_obj_is_kind_of(self, Cstmt) == Qtrue) {
6996
 
        STMT *q;
6997
 
 
6998
 
        Data_Get_Struct(self, STMT, q);
6999
 
        flag = &q->upc;
7000
 
    } else if (rb_obj_is_kind_of(self, Cdbc) == Qtrue) {
7001
 
        DBC *p;
7002
 
 
7003
 
        Data_Get_Struct(self, DBC, p);
7004
 
        flag = &p->upc;
7005
 
    } else {
7006
 
        rb_raise(rb_eTypeError, "ODBC::Statement or ODBC::Database expected");
7007
 
        return Qnil;
7008
 
    }
7009
 
    if (argc > 0) {
7010
 
        *flag = RTEST(onoff);
7011
 
    }
7012
 
    return *flag ? Qtrue : Qfalse;
7013
 
}
7014
 
 
7015
 
/*
7016
 
 *----------------------------------------------------------------------
7017
 
 *
7018
 
 *      Create statement without implicit SQL prepare or execute.
7019
 
 *
7020
 
 *----------------------------------------------------------------------
7021
 
 */
7022
 
static VALUE
7023
 
stmt_new(VALUE self)
7024
 
{
7025
 
    DBC *p;
7026
 
    SQLHSTMT hstmt;
7027
 
    char *msg = NULL;
7028
 
 
7029
 
    Data_Get_Struct(self, DBC, p);
7030
 
    if (!succeeded(SQL_NULL_HENV, p->hdbc, SQL_NULL_HSTMT,
7031
 
                   SQLAllocStmt(p->hdbc, &hstmt),
7032
 
                   &msg, "SQLAllocStmt")) {
7033
 
        rb_raise(Cerror, "%s", msg);
7034
 
    }
7035
 
    return wrap_stmt(self, p, hstmt, NULL);
7036
 
}
7037
 
 
7038
 
/*
7039
 
 *----------------------------------------------------------------------
7040
 
 *
7041
 
 *      Procedures with statements.
7042
 
 *
7043
 
 *----------------------------------------------------------------------
7044
 
 */
7045
 
 
7046
 
static VALUE
7047
 
stmt_proc_init(int argc, VALUE *argv, VALUE self)
7048
 
{
7049
 
    VALUE stmt = (argc > 0) ? argv[0] : Qnil;
7050
 
 
7051
 
    if (rb_obj_is_kind_of(stmt, Cstmt) == Qtrue) {
7052
 
        rb_iv_set(self, "@statement", stmt);
7053
 
        rb_iv_set(self, "@return_output_param", (argc > 1) ? argv[1] : Qnil);
7054
 
        return self;
7055
 
    }
7056
 
    rb_raise(rb_eTypeError, "need ODBC::Statement as argument");
7057
 
    return Qnil;
7058
 
}
7059
 
 
7060
 
static VALUE
7061
 
stmt_proc_call(int argc, VALUE *argv, VALUE self)
7062
 
{
7063
 
    VALUE stmt, val;
7064
 
 
7065
 
    stmt = rb_iv_get(self, "@statement");
7066
 
    val = rb_iv_get(self, "@return_output_param");
7067
 
    if (RTEST(val)) {
7068
 
        int parnum = NUM2INT(val);
7069
 
 
7070
 
        stmt_exec_int(argc, argv, stmt, EXEC_PARMXNULL(parnum));
7071
 
        rb_call_super(1, &stmt);
7072
 
        return stmt_param_output_value(1, &val, stmt);
7073
 
    }
7074
 
    stmt_exec_int(argc, argv, stmt, 0);
7075
 
    return rb_call_super(1, &stmt);
7076
 
}
7077
 
 
7078
 
static VALUE
7079
 
stmt_proc(int argc, VALUE *argv, VALUE self)
7080
 
{
7081
 
    VALUE sql, ptype, psize, pnum = Qnil, stmt, args[2];
7082
 
    int parnum = 0;
7083
 
 
7084
 
    rb_scan_args(argc, argv, "13", &sql, &ptype, &psize, &pnum);
7085
 
    if (!rb_block_given_p()) {
7086
 
        rb_raise(rb_eArgError, "block required");
7087
 
    }
7088
 
    stmt = stmt_prep_int(1, &sql, self, 0);
7089
 
    if (argc == 1) {
7090
 
        return rb_funcall(Cproc, IDnew, 1, stmt);
7091
 
    }
7092
 
    if ((argc < 4) || (pnum == Qnil)) {
7093
 
        pnum = INT2NUM(parnum);
7094
 
    } else {
7095
 
        parnum = NUM2INT(pnum);
7096
 
    }
7097
 
    args[0] = pnum;
7098
 
    args[1] = INT2NUM(SQL_PARAM_OUTPUT);
7099
 
    stmt_param_iotype(2, args, stmt);
7100
 
    args[1] = ptype;
7101
 
    stmt_param_output_type(2, args, stmt);
7102
 
    if (argc > 2) {
7103
 
        args[1] = psize;
7104
 
    } else {
7105
 
        args[1] = INT2NUM(256);
7106
 
    }
7107
 
    stmt_param_output_size(2, args, stmt);
7108
 
    return rb_funcall(Cproc, IDnew, 2, stmt, pnum);
7109
 
}
7110
 
 
7111
 
static VALUE
7112
 
stmt_procwrap(int argc, VALUE *argv, VALUE self)
7113
 
{
7114
 
    VALUE arg0 = Qnil, arg1 = Qnil;
7115
 
 
7116
 
    rb_scan_args(argc, argv, "02", &arg0, &arg1);
7117
 
    if (rb_obj_is_kind_of(self, Cstmt) == Qtrue) {
7118
 
        if (arg1 != Qnil) {
7119
 
            rb_raise(rb_eArgError, "wrong # arguments");
7120
 
        }
7121
 
        arg1 = arg0;
7122
 
        arg0 = self;
7123
 
    } else if (rb_obj_is_kind_of(arg0, Cstmt) != Qtrue) {
7124
 
        rb_raise(rb_eTypeError, "need ODBC::Statement as 1st argument");
7125
 
    }
7126
 
    return rb_funcall(Cproc, IDnew, 2, arg0, arg1);
7127
 
}
7128
 
 
7129
 
/*
7130
 
 *----------------------------------------------------------------------
7131
 
 *
7132
 
 *      Module functions.
7133
 
 *
7134
 
 *----------------------------------------------------------------------
7135
 
 */
7136
 
 
7137
 
static VALUE
7138
 
mod_dbcdisc(VALUE dbc)
7139
 
{
7140
 
    return dbc_disconnect(0, NULL, dbc);
7141
 
}
7142
 
 
7143
 
static VALUE
7144
 
mod_connect(int argc, VALUE *argv, VALUE self)
7145
 
{
7146
 
    VALUE dbc = dbc_new(argc, argv, self);
7147
 
 
7148
 
    if (rb_block_given_p()) {
7149
 
        return rb_ensure(rb_yield, dbc, mod_dbcdisc, dbc);
7150
 
    }
7151
 
    return dbc;
7152
 
}
7153
 
 
7154
 
static VALUE
7155
 
mod_2time(int argc, VALUE *argv, VALUE self)
7156
 
{
7157
 
    VALUE a1, a2;
7158
 
    VALUE y, m, d, hh, mm, ss, us;
7159
 
    int once = 0;
7160
 
 
7161
 
    rb_scan_args(argc, argv, "11", &a1, &a2);
7162
 
again:
7163
 
    if (rb_obj_is_kind_of(a1, Ctimestamp) == Qtrue) {
7164
 
        TIMESTAMP_STRUCT *ts;
7165
 
 
7166
 
        if (argc > 1) {
7167
 
            rb_raise(rb_eArgError, "wrong # arguments(2 for 1)");
7168
 
        }
7169
 
        Data_Get_Struct(a1, TIMESTAMP_STRUCT, ts);
7170
 
        y = INT2NUM(ts->year);
7171
 
        m = INT2NUM(ts->month);
7172
 
        d = INT2NUM(ts->day);
7173
 
        hh = INT2NUM(ts->hour);
7174
 
        mm = INT2NUM(ts->minute);
7175
 
        ss = INT2NUM(ts->second);
7176
 
        us = INT2NUM(ts->fraction / 1000);
7177
 
        goto mktime;
7178
 
    }
7179
 
    if (rb_obj_is_kind_of(a1, Cdate) == Qtrue) {
7180
 
        DATE_STRUCT *date;
7181
 
 
7182
 
        if (a2 != Qnil) {
7183
 
            if (rb_obj_is_kind_of(a2, Ctime) == Qtrue) {
7184
 
                TIME_STRUCT *time;
7185
 
 
7186
 
                Data_Get_Struct(a2, TIME_STRUCT, time);
7187
 
                hh = INT2NUM(time->hour);
7188
 
                mm = INT2NUM(time->minute);
7189
 
                ss = INT2NUM(time->second);
7190
 
            } else {
7191
 
                rb_raise(rb_eTypeError, "expecting ODBC::Time");
7192
 
            }
7193
 
        } else {
7194
 
            hh = INT2FIX(0);
7195
 
            mm = INT2FIX(0);
7196
 
            ss = INT2FIX(0);
7197
 
        }
7198
 
        Data_Get_Struct(a1, DATE_STRUCT, date);
7199
 
        y = INT2NUM(date->year);
7200
 
        m = INT2NUM(date->month);
7201
 
        d = INT2NUM(date->day);
7202
 
        us = INT2FIX(0);
7203
 
    }
7204
 
    if (rb_obj_is_kind_of(a1, Ctime) == Qtrue) {
7205
 
        TIME_STRUCT *time;
7206
 
 
7207
 
        if (a2 != Qnil) {
7208
 
            if (rb_obj_is_kind_of(a2, Cdate) == Qtrue) {
7209
 
                DATE_STRUCT *date;
7210
 
 
7211
 
                Data_Get_Struct(a2, DATE_STRUCT, date);
7212
 
                y = INT2NUM(date->year);
7213
 
                m = INT2NUM(date->month);
7214
 
                d = INT2NUM(date->day);
7215
 
            } else {
7216
 
                rb_raise(rb_eTypeError, "expecting ODBC::Date");
7217
 
            }
7218
 
        } else {
7219
 
            VALUE now = rb_funcall(rb_cTime, IDnow, 0, NULL);
7220
 
 
7221
 
            y = rb_funcall(rb_cTime, IDyear, 1, now);
7222
 
            m = rb_funcall(rb_cTime, IDmonth, 1, now);
7223
 
            d = rb_funcall(rb_cTime, IDday, 1, now);
7224
 
        }
7225
 
        Data_Get_Struct(a1, TIME_STRUCT, time);
7226
 
        hh = INT2NUM(time->hour);
7227
 
        mm = INT2NUM(time->minute);
7228
 
        ss = INT2NUM(time->second);
7229
 
        us = INT2FIX(0);
7230
 
mktime:
7231
 
        return rb_funcall(rb_cTime, IDlocal, 7, y, m, d, hh, mm, ss, us);
7232
 
    }
7233
 
    if ((!once) && ((m = timestamp_load1(Ctimestamp, a1, -1)) != Qnil)) {
7234
 
        a1 = m;
7235
 
        once++;
7236
 
        goto again;
7237
 
    }
7238
 
    if ((!once) && ((m = date_load1(Cdate, a1, -1)) != Qnil)) {
7239
 
        a1 = m;
7240
 
        if ((argc > 1) && ((m = time_load1(Ctime, a2, -1)) != Qnil)) {
7241
 
            a2 = m;
7242
 
        }
7243
 
        once++;
7244
 
        goto again;
7245
 
    }
7246
 
    if ((!once) && ((m = time_load1(Ctime, a1, -1)) != Qnil)) {
7247
 
        a1 = m;
7248
 
        if ((argc > 1) && ((m = date_load1(Cdate, a2, -1)) != Qnil)) {
7249
 
            a2 = m;
7250
 
        }
7251
 
        once++;
7252
 
        goto again;
7253
 
    }
7254
 
    rb_raise(rb_eTypeError,
7255
 
             "expecting ODBC::TimeStamp or ODBC::Date/Time or String");
7256
 
    return Qnil;
7257
 
}
7258
 
 
7259
 
static VALUE
7260
 
mod_2date(VALUE self, VALUE arg)
7261
 
{
7262
 
    VALUE y, m, d;
7263
 
    int once = 0;
7264
 
 
7265
 
again:
7266
 
    if (rb_obj_is_kind_of(arg, Cdate) == Qtrue) {
7267
 
        DATE_STRUCT *date;
7268
 
 
7269
 
        Data_Get_Struct(arg, DATE_STRUCT, date);
7270
 
        y = INT2NUM(date->year);
7271
 
        m = INT2NUM(date->month);
7272
 
        d = INT2NUM(date->day);
7273
 
        goto mkdate;
7274
 
    }
7275
 
    if (rb_obj_is_kind_of(arg, Ctimestamp) == Qtrue){
7276
 
        TIMESTAMP_STRUCT *ts;
7277
 
 
7278
 
        Data_Get_Struct(arg, TIMESTAMP_STRUCT, ts);
7279
 
        y = INT2NUM(ts->year);
7280
 
        m = INT2NUM(ts->month);
7281
 
        d = INT2NUM(ts->day);
7282
 
mkdate:
7283
 
        return rb_funcall(rb_cDate, IDnew, 3, y, m, d);
7284
 
    }
7285
 
    if ((!once) &&
7286
 
        (((m = date_load1(Cdate, arg, -1)) != Qnil) ||
7287
 
         ((m = timestamp_load1(Ctimestamp, arg, -1)) != Qnil))) {
7288
 
        arg = m;
7289
 
        once++;
7290
 
        goto again;
7291
 
    }
7292
 
    rb_raise(rb_eTypeError, "expecting ODBC::Date/Timestamp or String");
7293
 
    return Qnil;
7294
 
}
7295
 
 
7296
 
static VALUE
7297
 
mod_trace(int argc, VALUE *argv, VALUE self)
7298
 
{
7299
 
    VALUE v = Qnil;
7300
 
 
7301
 
    rb_scan_args(argc, argv, "01", &v);
7302
 
#ifdef TRACING
7303
 
    if (argc > 0) {
7304
 
        tracing = NUM2INT(v);
7305
 
    }
7306
 
    return INT2NUM(tracing);
7307
 
#else
7308
 
    return INT2NUM(0);
7309
 
#endif
7310
 
}
7311
 
 
7312
 
/*
7313
 
 *----------------------------------------------------------------------
7314
 
 *
7315
 
 *      Table of constants and intern'ed string mappings.
7316
 
 *
7317
 
 *----------------------------------------------------------------------
7318
 
 */
7319
 
 
7320
 
#define O_CONST(x)    { #x, x }
7321
 
#define O_CONSTU(x)   { #x, SQL_UNKNOWN_TYPE }
7322
 
#define O_CONST2(x,y) { #x, y }
7323
 
#define O_CONST_END   { NULL, -1 }
7324
 
 
7325
 
static struct {
7326
 
    const char *name;
7327
 
    int value;
7328
 
} o_const[] = {
7329
 
    O_CONST(SQL_CURSOR_FORWARD_ONLY),
7330
 
    O_CONST(SQL_CURSOR_KEYSET_DRIVEN),
7331
 
    O_CONST(SQL_CURSOR_DYNAMIC),
7332
 
    O_CONST(SQL_CURSOR_STATIC),
7333
 
    O_CONST(SQL_CONCUR_READ_ONLY),
7334
 
    O_CONST(SQL_CONCUR_LOCK),
7335
 
    O_CONST(SQL_CONCUR_ROWVER),
7336
 
    O_CONST(SQL_CONCUR_VALUES),
7337
 
    O_CONST(SQL_FETCH_NEXT),
7338
 
    O_CONST(SQL_FETCH_FIRST),
7339
 
    O_CONST(SQL_FETCH_LAST),
7340
 
    O_CONST(SQL_FETCH_PRIOR),
7341
 
    O_CONST(SQL_FETCH_ABSOLUTE),
7342
 
    O_CONST(SQL_FETCH_RELATIVE),
7343
 
    O_CONST(SQL_UNKNOWN_TYPE),
7344
 
    O_CONST(SQL_CHAR),
7345
 
    O_CONST(SQL_NUMERIC),
7346
 
    O_CONST(SQL_DECIMAL),
7347
 
    O_CONST(SQL_INTEGER),
7348
 
    O_CONST(SQL_SMALLINT),
7349
 
    O_CONST(SQL_FLOAT),
7350
 
    O_CONST(SQL_REAL),
7351
 
    O_CONST(SQL_DOUBLE),
7352
 
    O_CONST(SQL_VARCHAR),
7353
 
#ifdef SQL_DATETIME
7354
 
    O_CONST(SQL_DATETIME),
7355
 
#else
7356
 
    O_CONSTU(SQL_DATETIME),
7357
 
#endif
7358
 
#ifdef SQL_DATE
7359
 
    O_CONST(SQL_DATE),
7360
 
#else
7361
 
    O_CONSTU(SQL_DATE),
7362
 
#endif
7363
 
#ifdef SQL_TYPE_DATE
7364
 
    O_CONST(SQL_TYPE_DATE),
7365
 
#else
7366
 
    O_CONSTU(SQL_TYPE_DATE),
7367
 
#endif
7368
 
#ifdef SQL_TIME
7369
 
    O_CONST(SQL_TIME),
7370
 
#else
7371
 
    O_CONSTU(SQL_TIME),
7372
 
#endif
7373
 
#ifdef SQL_TYPE_TIME
7374
 
    O_CONST(SQL_TYPE_TIME),
7375
 
#else
7376
 
    O_CONSTU(SQL_TYPE_TIME),
7377
 
#endif
7378
 
#ifdef SQL_TIMESTAMP
7379
 
    O_CONST(SQL_TIMESTAMP),
7380
 
#else
7381
 
    O_CONSTU(SQL_TIMESTAMP),
7382
 
#endif
7383
 
#ifdef SQL_TYPE_TIMESTAMP
7384
 
    O_CONST(SQL_TYPE_TIMESTAMP),
7385
 
#else
7386
 
    O_CONSTU(SQL_TYPE_TIMESTAMP),
7387
 
#endif
7388
 
#ifdef SQL_LONGVARCHAR
7389
 
    O_CONST(SQL_LONGVARCHAR),
7390
 
#else
7391
 
    O_CONSTU(SQL_LONGVARCHAR),
7392
 
#endif
7393
 
#ifdef SQL_BINARY
7394
 
    O_CONST(SQL_BINARY),
7395
 
#else
7396
 
    O_CONSTU(SQL_BINARY),
7397
 
#endif
7398
 
#ifdef SQL_VARBINARY
7399
 
    O_CONST(SQL_VARBINARY),
7400
 
#else
7401
 
    O_CONSTU(SQL_VARBINARY),
7402
 
#endif
7403
 
#ifdef SQL_LONGVARBINARY
7404
 
    O_CONST(SQL_LONGVARBINARY),
7405
 
#else
7406
 
    O_CONSTU(SQL_LONGVARBINARY),
7407
 
#endif
7408
 
#ifdef SQL_BIGINT
7409
 
    O_CONST(SQL_BIGINT),
7410
 
#else
7411
 
    O_CONSTU(SQL_BIGINT),
7412
 
#endif
7413
 
#ifdef SQL_TINYINT
7414
 
    O_CONST(SQL_TINYINT),
7415
 
#else
7416
 
    O_CONSTU(SQL_TINYINT),
7417
 
#endif
7418
 
#ifdef SQL_BIT
7419
 
    O_CONST(SQL_BIT),
7420
 
#else
7421
 
    O_CONSTU(SQL_BIT),
7422
 
#endif
7423
 
#ifdef SQL_GUID
7424
 
    O_CONST(SQL_GUID),
7425
 
#else
7426
 
    O_CONSTU(SQL_GUID),
7427
 
#endif
7428
 
#ifdef SQL_WCHAR
7429
 
    O_CONST(SQL_WCHAR),
7430
 
#else
7431
 
    O_CONSTU(SQL_WCHAR),
7432
 
#endif
7433
 
#ifdef SQL_WVARCHAR
7434
 
    O_CONST(SQL_WVARCHAR),
7435
 
#else
7436
 
    O_CONSTU(SQL_WVARCHAR),
7437
 
#endif
7438
 
#ifdef SQL_WLONGVARCHAR
7439
 
    O_CONST(SQL_WLONGVARCHAR),
7440
 
#else
7441
 
    O_CONSTU(SQL_WLONGVARCHAR),
7442
 
#endif
7443
 
#ifdef SQL_ATTR_ODBC_VERSION
7444
 
    O_CONST(SQL_OV_ODBC2),
7445
 
    O_CONST(SQL_OV_ODBC3),
7446
 
#else
7447
 
    O_CONST2(SQL_OV_ODBC2, 2),
7448
 
    O_CONST2(SQL_OV_ODBC3, 3),
7449
 
#endif
7450
 
#ifdef SQL_ATTR_CONNECTION_POOLING
7451
 
    O_CONST(SQL_CP_OFF),
7452
 
    O_CONST(SQL_CP_ONE_PER_DRIVER),
7453
 
    O_CONST(SQL_CP_ONE_PER_HENV),
7454
 
    O_CONST(SQL_CP_DEFAULT),
7455
 
#else
7456
 
    O_CONST2(SQL_CP_OFF, 0),
7457
 
    O_CONST2(SQL_CP_ONE_PER_DRIVER, 0),
7458
 
    O_CONST2(SQL_CP_ONE_PER_HENV, 0),
7459
 
    O_CONST2(SQL_CP_DEFAULT, 0),
7460
 
#endif
7461
 
#ifdef SQL_ATTR_CP_MATCH
7462
 
    O_CONST(SQL_CP_STRICT_MATCH),
7463
 
    O_CONST(SQL_CP_RELAXED_MATCH),
7464
 
    O_CONST(SQL_CP_MATCH_DEFAULT),
7465
 
#else
7466
 
    O_CONST2(SQL_CP_STRICT_MATCH, 0),
7467
 
    O_CONST2(SQL_CP_RELAXED_MATCH, 0),
7468
 
    O_CONST2(SQL_CP_MATCH_DEFAULT, 0),
7469
 
#endif
7470
 
#ifdef SQL_SCOPE_CURROW
7471
 
    O_CONST(SQL_SCOPE_CURROW),
7472
 
#else
7473
 
    O_CONST2(SQL_SCOPE_CURROW, 0),
7474
 
#endif
7475
 
#ifdef SQL_SCOPE_TRANSACTION
7476
 
    O_CONST(SQL_SCOPE_TRANSACTION),
7477
 
#else
7478
 
    O_CONST2(SQL_SCOPE_TRANSACTION, 0),
7479
 
#endif
7480
 
#ifdef SQL_SCOPE_SESSION
7481
 
    O_CONST(SQL_SCOPE_SESSION),
7482
 
#else
7483
 
    O_CONST2(SQL_SCOPE_SESSION, 0),
7484
 
#endif
7485
 
#ifdef SQL_BEST_ROWID
7486
 
    O_CONST(SQL_BEST_ROWID),
7487
 
#else
7488
 
    O_CONST2(SQL_BEST_ROWID, 0),
7489
 
#endif
7490
 
#ifdef SQL_ROWVER
7491
 
    O_CONST(SQL_ROWVER),
7492
 
#else
7493
 
    O_CONST2(SQL_ROWVER, 0),
7494
 
#endif
7495
 
    O_CONST(SQL_PARAM_TYPE_UNKNOWN),
7496
 
    O_CONST(SQL_PARAM_INPUT),
7497
 
    O_CONST(SQL_PARAM_OUTPUT),
7498
 
    O_CONST(SQL_PARAM_INPUT_OUTPUT),
7499
 
    O_CONST(SQL_DEFAULT_PARAM),
7500
 
    O_CONST(SQL_RETURN_VALUE),
7501
 
    O_CONST(SQL_RESULT_COL),
7502
 
    O_CONST(SQL_PT_UNKNOWN),
7503
 
    O_CONST(SQL_PT_PROCEDURE),
7504
 
    O_CONST(SQL_PT_FUNCTION),
7505
 
 
7506
 
    /* end of table */
7507
 
    O_CONST_END
7508
 
};
7509
 
 
7510
 
static struct {
7511
 
    ID *idp;
7512
 
    const char *str;
7513
 
} ids[] = {
7514
 
    { &IDstart, "start" },
7515
 
    { &IDatatinfo, "@@info" },
7516
 
    { &IDataterror, "@@error" },
7517
 
    { &IDkeys, "keys" },
7518
 
    { &IDatattrs, "@attrs" },
7519
 
    { &IDday, "day" },
7520
 
    { &IDmonth, "month" },
7521
 
    { &IDyear, "year" },
7522
 
    { &IDmday, "mday" },
7523
 
    { &IDsec, "sec" },
7524
 
    { &IDmin, "min" },
7525
 
    { &IDhour, "hour" },
7526
 
    { &IDusec, "usec" },
7527
 
    { &IDkeyp, "key?" },
7528
 
    { &IDkey, "key" },
7529
 
    { &IDSymbol, "Symbol" },
7530
 
    { &IDString, "String" },
7531
 
    { &IDFixnum, "Fixnum" },
7532
 
    { &IDtable_names, "table_names" },
7533
 
    { &IDnew, "new" },
7534
 
    { &IDnow, "now" },
7535
 
    { &IDlocal, "local" },
7536
 
    { &IDname, "name" },
7537
 
    { &IDtable, "table" },
7538
 
    { &IDtype, "type" },
7539
 
    { &IDlength, "length" },
7540
 
    { &IDnullable, "nullable" },
7541
 
    { &IDscale, "scale" },
7542
 
    { &IDprecision, "precision" },
7543
 
    { &IDsearchable, "searchable" },
7544
 
    { &IDunsigned, "unsigned" },
7545
 
    { &IDiotype, "iotype" },
7546
 
    { &IDoutput_size, "output_size" },
7547
 
    { &IDoutput_type, "output_type" },
7548
 
    { &IDdescr, "descr" },
7549
 
    { &IDstatement, "statement" },
7550
 
    { &IDreturn_output_param, "return_output_param" },
7551
 
    { &IDattrs, "attrs" },
7552
 
    { &IDNULL, "NULL" },
7553
 
    { &IDdefault, "default" }
7554
 
};
7555
 
 
7556
 
/*
7557
 
 *----------------------------------------------------------------------
7558
 
 *
7559
 
 *      Module initializer.
7560
 
 *
7561
 
 *----------------------------------------------------------------------
7562
 
 */
7563
 
 
7564
 
void
7565
 
#ifdef UNICODE
7566
 
Init_odbc_utf8()
7567
 
#else
7568
 
Init_odbc()
7569
 
#endif
7570
 
{
7571
 
    int i;
7572
 
    char *modname = "ODBC";
7573
 
    ID modid = rb_intern(modname);
7574
 
    VALUE v = Qnil;
7575
 
 
7576
 
    rb_require("date");
7577
 
    rb_cDate = rb_eval_string("Date");
7578
 
 
7579
 
    if (rb_const_defined(rb_cObject, modid)) {
7580
 
        v = rb_const_get(rb_cObject, modid); 
7581
 
        if (TYPE(v) != T_MODULE) {
7582
 
            rb_raise(rb_eTypeError, "%s already defined", modname);
7583
 
        }
7584
 
    }
7585
 
    if (v != Qnil) {
7586
 
#ifdef UNICODE
7587
 
        modname = "ODBC_UTF8";
7588
 
#else
7589
 
        modname = "ODBC_NONE";
7590
 
#endif
7591
 
    }
7592
 
 
7593
 
    for (i = 0; i < sizeof (ids) / sizeof (ids[0]); i++) {
7594
 
        *(ids[i].idp) = rb_intern(ids[i].str);
7595
 
    }
7596
 
 
7597
 
    Modbc = rb_define_module(modname);
7598
 
    Cobj = rb_define_class_under(Modbc, "Object", rb_cObject);
7599
 
    rb_define_class_variable(Cobj, "@@error", Qnil);
7600
 
    rb_define_class_variable(Cobj, "@@info", Qnil);
7601
 
 
7602
 
    Cenv = rb_define_class_under(Modbc, "Environment", Cobj);
7603
 
    Cdbc = rb_define_class_under(Modbc, "Database", Cenv);
7604
 
    Cstmt = rb_define_class_under(Modbc, "Statement", Cdbc);
7605
 
    rb_include_module(Cstmt, rb_mEnumerable);
7606
 
 
7607
 
    Ccolumn = rb_define_class_under(Modbc, "Column", Cobj);
7608
 
    rb_attr(Ccolumn, IDname, 1, 0, Qfalse);
7609
 
    rb_attr(Ccolumn, IDtable, 1, 0, Qfalse);
7610
 
    rb_attr(Ccolumn, IDtype, 1, 0, Qfalse);
7611
 
    rb_attr(Ccolumn, IDlength, 1, 0, Qfalse);
7612
 
    rb_attr(Ccolumn, IDnullable, 1, 0, Qfalse);
7613
 
    rb_attr(Ccolumn, IDscale, 1, 0, Qfalse);
7614
 
    rb_attr(Ccolumn, IDprecision, 1, 0, Qfalse);
7615
 
    rb_attr(Ccolumn, IDsearchable, 1, 0, Qfalse);
7616
 
    rb_attr(Ccolumn, IDunsigned, 1, 0, Qfalse);
7617
 
 
7618
 
    Cparam = rb_define_class_under(Modbc, "Parameter", Cobj);
7619
 
    rb_attr(Cparam, IDtype, 1, 0, Qfalse);
7620
 
    rb_attr(Cparam, IDprecision, 1, 0, Qfalse);
7621
 
    rb_attr(Cparam, IDscale, 1, 0, Qfalse);
7622
 
    rb_attr(Cparam, IDnullable, 1, 0, Qfalse);
7623
 
    rb_attr(Cparam, IDiotype, 1, 0, Qfalse);
7624
 
    rb_attr(Cparam, IDoutput_size, 1, 0, Qfalse);
7625
 
    rb_attr(Cparam, IDoutput_type, 1, 0, Qfalse);
7626
 
 
7627
 
    Cdsn = rb_define_class_under(Modbc, "DSN", Cobj);
7628
 
    rb_attr(Cdsn, IDname, 1, 1, Qfalse);
7629
 
    rb_attr(Cdsn, IDdescr, 1, 1, Qfalse);
7630
 
 
7631
 
    Cdrv = rb_define_class_under(Modbc, "Driver", Cobj);
7632
 
    rb_attr(Cdrv, IDname, 1, 1, Qfalse);
7633
 
    rb_attr(Cdrv, IDattrs, 1, 1, Qfalse);
7634
 
 
7635
 
    Cerror = rb_define_class_under(Modbc, "Error", rb_eStandardError);
7636
 
 
7637
 
    Cproc = rb_define_class("ODBCProc", rb_cProc);
7638
 
 
7639
 
    Cdate = rb_define_class_under(Modbc, "Date", Cobj);
7640
 
    rb_include_module(Cdate, rb_mComparable);
7641
 
    Ctime = rb_define_class_under(Modbc, "Time", Cobj);
7642
 
    rb_include_module(Ctime, rb_mComparable);
7643
 
    Ctimestamp = rb_define_class_under(Modbc, "TimeStamp", Cobj);
7644
 
    rb_include_module(Ctimestamp, rb_mComparable);
7645
 
 
7646
 
    /* module functions */
7647
 
    rb_define_module_function(Modbc, "trace", mod_trace, -1);
7648
 
    rb_define_module_function(Modbc, "trace=", mod_trace, -1);
7649
 
    rb_define_module_function(Modbc, "connect", mod_connect, -1);
7650
 
    rb_define_module_function(Modbc, "datasources", dbc_dsns, 0);
7651
 
    rb_define_module_function(Modbc, "drivers", dbc_drivers, 0);
7652
 
    rb_define_module_function(Modbc, "error", dbc_error, 0);
7653
 
    rb_define_module_function(Modbc, "info", dbc_warn, 0);
7654
 
    rb_define_module_function(Modbc, "clear_error", dbc_clrerror, 0);
7655
 
    rb_define_module_function(Modbc, "newenv", env_new, 0);
7656
 
    rb_define_module_function(Modbc, "to_time", mod_2time, -1);
7657
 
    rb_define_module_function(Modbc, "to_date", mod_2date, 1);
7658
 
    rb_define_module_function(Modbc, "connection_pooling", env_cpooling, -1);
7659
 
    rb_define_module_function(Modbc, "connection_pooling=", env_cpooling, -1);
7660
 
    rb_define_module_function(Modbc, "raise", dbc_raise, 1);
7661
 
 
7662
 
    /* singleton methods and constructors */
7663
 
    rb_define_singleton_method(Cobj, "error", dbc_error, 0);
7664
 
    rb_define_singleton_method(Cobj, "info", dbc_warn, 0);
7665
 
    rb_define_singleton_method(Cobj, "clear_error", dbc_clrerror, 0);
7666
 
    rb_define_singleton_method(Cobj, "raise", dbc_raise, 1);
7667
 
    rb_define_alloc_func(Cenv, env_new);
7668
 
    rb_define_singleton_method(Cenv, "connect", dbc_new, -1);
7669
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
7670
 
    rb_define_alloc_func(Cdbc, dbc_alloc);
7671
 
#else
7672
 
    rb_define_alloc_func(Cdbc, dbc_new);
7673
 
    rb_define_alloc_func(Cdsn, dsn_new);
7674
 
    rb_define_alloc_func(Cdrv, drv_new);
7675
 
#endif
7676
 
    rb_define_method(Cdsn, "initialize", dsn_init, 0);
7677
 
    rb_define_method(Cdrv, "initialize", drv_init, 0);
7678
 
    rb_define_method(Cdbc, "newstmt", stmt_new, 0);
7679
 
 
7680
 
    /* common (Cobj) methods */
7681
 
    rb_define_method(Cobj, "error", dbc_error, 0);
7682
 
    rb_define_method(Cobj, "info", dbc_warn, 0);
7683
 
    rb_define_method(Cobj, "clear_error", dbc_clrerror, 0);
7684
 
    rb_define_method(Cobj, "raise", dbc_raise, 1);
7685
 
 
7686
 
    /* common (Cenv) methods */
7687
 
    rb_define_method(Cenv, "connect", dbc_new, -1);
7688
 
    rb_define_method(Cenv, "environment", env_of, 0);
7689
 
    rb_define_method(Cenv, "transaction", dbc_transaction, 0);
7690
 
    rb_define_method(Cenv, "commit", dbc_commit, 0);
7691
 
    rb_define_method(Cenv, "rollback", dbc_rollback, 0);
7692
 
    rb_define_method(Cenv, "connection_pooling", env_cpooling, -1);
7693
 
    rb_define_method(Cenv, "connection_pooling=", env_cpooling, -1);
7694
 
    rb_define_method(Cenv, "cp_match", env_cpmatch, -1);
7695
 
    rb_define_method(Cenv, "cp_match=", env_cpmatch, -1);
7696
 
    rb_define_method(Cenv, "odbc_version", env_odbcver, -1);
7697
 
    rb_define_method(Cenv, "odbc_version=", env_odbcver, -1);
7698
 
 
7699
 
    /* management things (odbcinst.h) */
7700
 
    rb_define_module_function(Modbc, "add_dsn", dbc_adddsn, -1);
7701
 
    rb_define_module_function(Modbc, "config_dsn", dbc_confdsn, -1);
7702
 
    rb_define_module_function(Modbc, "del_dsn", dbc_deldsn, -1);
7703
 
    rb_define_module_function(Modbc, "write_file_dsn", dbc_wfdsn, -1);
7704
 
    rb_define_module_function(Modbc, "read_file_dsn", dbc_rfdsn, -1);
7705
 
 
7706
 
    /* connection (database) methods */
7707
 
    rb_define_method(Cdbc, "initialize", dbc_connect, -1);
7708
 
    rb_define_method(Cdbc, "connect", dbc_connect, -1);
7709
 
    rb_define_method(Cdbc, "connected?", dbc_connected, 0);
7710
 
    rb_define_method(Cdbc, "drvconnect", dbc_drvconnect, 1);
7711
 
    rb_define_method(Cdbc, "drop_all", dbc_dropall, 0);
7712
 
    rb_define_method(Cdbc, "disconnect", dbc_disconnect, -1);
7713
 
    rb_define_method(Cdbc, "tables", dbc_tables, -1);
7714
 
    rb_define_method(Cdbc, "columns", dbc_columns, -1);
7715
 
    rb_define_method(Cdbc, "primary_keys", dbc_primkeys, -1);
7716
 
    rb_define_method(Cdbc, "indexes", dbc_indexes, -1);
7717
 
    rb_define_method(Cdbc, "types", dbc_types, -1);
7718
 
    rb_define_method(Cdbc, "foreign_keys", dbc_forkeys, -1);
7719
 
    rb_define_method(Cdbc, "table_privileges", dbc_tpriv, -1);
7720
 
    rb_define_method(Cdbc, "procedures", dbc_procs, -1);
7721
 
    rb_define_method(Cdbc, "procedure_columns", dbc_proccols, -1);
7722
 
    rb_define_method(Cdbc, "special_columns", dbc_speccols, -1);
7723
 
    rb_define_method(Cdbc, "get_info", dbc_getinfo, -1);
7724
 
    rb_define_method(Cdbc, "prepare", stmt_prep, -1);
7725
 
    rb_define_method(Cdbc, "run", stmt_run, -1);
7726
 
    rb_define_method(Cdbc, "do", stmt_do, -1);
7727
 
    rb_define_method(Cdbc, "proc", stmt_proc, -1);
7728
 
 
7729
 
    /* connection options */
7730
 
    rb_define_method(Cdbc, "get_option", dbc_getsetoption, -1);
7731
 
    rb_define_method(Cdbc, "set_option", dbc_getsetoption, -1);
7732
 
    rb_define_method(Cdbc, "autocommit", dbc_autocommit, -1);
7733
 
    rb_define_method(Cdbc, "autocommit=", dbc_autocommit, -1);
7734
 
    rb_define_method(Cdbc, "concurrency", dbc_concurrency, -1);
7735
 
    rb_define_method(Cdbc, "concurrency=", dbc_concurrency, -1);
7736
 
    rb_define_method(Cdbc, "maxrows", dbc_maxrows, -1);
7737
 
    rb_define_method(Cdbc, "maxrows=", dbc_maxrows, -1);
7738
 
    rb_define_method(Cdbc, "timeout", dbc_timeout, -1);
7739
 
    rb_define_method(Cdbc, "timeout=", dbc_timeout, -1);
7740
 
    rb_define_method(Cdbc, "maxlength", dbc_maxlength, -1);
7741
 
    rb_define_method(Cdbc, "maxlength=", dbc_maxlength, -1);
7742
 
    rb_define_method(Cdbc, "rowsetsize", dbc_rowsetsize, -1);
7743
 
    rb_define_method(Cdbc, "cursortype", dbc_cursortype, -1);
7744
 
    rb_define_method(Cdbc, "cursortype=", dbc_cursortype, -1);
7745
 
    rb_define_method(Cdbc, "noscan", dbc_noscan, -1);
7746
 
    rb_define_method(Cdbc, "noscan=", dbc_noscan, -1);
7747
 
    rb_define_method(Cdbc, "ignorecase", stmt_ignorecase, -1);
7748
 
    rb_define_method(Cdbc, "ignorecase=", stmt_ignorecase, -1);
7749
 
 
7750
 
    /* statement methods */
7751
 
    rb_define_method(Cstmt, "drop", stmt_drop, 0);
7752
 
    rb_define_method(Cstmt, "close", stmt_close, 0);
7753
 
    rb_define_method(Cstmt, "cancel", stmt_cancel, 0);
7754
 
    rb_define_method(Cstmt, "column", stmt_column, -1);
7755
 
    rb_define_method(Cstmt, "columns", stmt_columns, -1);
7756
 
    rb_define_method(Cstmt, "parameter", stmt_param, -1);
7757
 
    rb_define_method(Cstmt, "parameters", stmt_params, 0);
7758
 
    rb_define_method(Cstmt, "param_type", stmt_param_type, -1);
7759
 
    rb_define_method(Cstmt, "param_iotype", stmt_param_iotype, -1);
7760
 
    rb_define_method(Cstmt, "param_output_size", stmt_param_output_size, -1);
7761
 
    rb_define_method(Cstmt, "param_output_type", stmt_param_output_type, -1);
7762
 
    rb_define_method(Cstmt, "param_output_value", stmt_param_output_value, -1);
7763
 
    rb_define_method(Cstmt, "ncols", stmt_ncols, 0);
7764
 
    rb_define_method(Cstmt, "nrows", stmt_nrows, 0);
7765
 
    rb_define_method(Cstmt, "nparams", stmt_nparams, 0);
7766
 
    rb_define_method(Cstmt, "cursorname", stmt_cursorname, -1);
7767
 
    rb_define_method(Cstmt, "cursorname=", stmt_cursorname, -1);
7768
 
    rb_define_method(Cstmt, "fetch", stmt_fetch, 0);
7769
 
    rb_define_method(Cstmt, "fetch!", stmt_fetch_bang, 0);
7770
 
    rb_define_method(Cstmt, "fetch_first", stmt_fetch_first, 0);
7771
 
    rb_define_method(Cstmt, "fetch_first!", stmt_fetch_first_bang, 0);
7772
 
    rb_define_method(Cstmt, "fetch_scroll", stmt_fetch_scroll, -1);
7773
 
    rb_define_method(Cstmt, "fetch_scroll!", stmt_fetch_scroll_bang, -1);
7774
 
    rb_define_method(Cstmt, "fetch_hash", stmt_fetch_hash, -1);
7775
 
    rb_define_method(Cstmt, "fetch_hash!", stmt_fetch_hash_bang, -1);
7776
 
    rb_define_method(Cstmt, "fetch_first_hash", stmt_fetch_first_hash, 0);
7777
 
    rb_define_method(Cstmt, "fetch_many", stmt_fetch_many, 1);
7778
 
    rb_define_method(Cstmt, "fetch_all", stmt_fetch_all, 0);
7779
 
    rb_define_method(Cstmt, "each", stmt_each, 0);
7780
 
    rb_define_method(Cstmt, "each_hash", stmt_each_hash, -1);
7781
 
    rb_define_method(Cstmt, "execute", stmt_exec, -1);
7782
 
    rb_define_method(Cstmt, "make_proc", stmt_procwrap, -1);
7783
 
    rb_define_method(Cstmt, "more_results", stmt_more_results, 0);
7784
 
    rb_define_method(Cstmt, "prepare", stmt_prep, -1);
7785
 
    rb_define_method(Cstmt, "run", stmt_run, -1);
7786
 
    rb_define_singleton_method(Cstmt, "make_proc", stmt_procwrap, -1);
7787
 
 
7788
 
    /* statement options */
7789
 
    rb_define_method(Cstmt, "get_option", stmt_getsetoption, -1);
7790
 
    rb_define_method(Cstmt, "set_option", stmt_getsetoption, -1);
7791
 
    rb_define_method(Cstmt, "concurrency", stmt_concurrency, -1);
7792
 
    rb_define_method(Cstmt, "concurrency=", stmt_concurrency, -1);
7793
 
    rb_define_method(Cstmt, "maxrows", stmt_maxrows, -1);
7794
 
    rb_define_method(Cstmt, "maxrows=", stmt_maxrows, -1);
7795
 
    rb_define_method(Cstmt, "timeout", stmt_timeout, -1);
7796
 
    rb_define_method(Cstmt, "timeout=", stmt_timeout, -1);
7797
 
    rb_define_method(Cstmt, "maxlength", stmt_maxlength, -1);
7798
 
    rb_define_method(Cstmt, "maxlength=", stmt_maxlength, -1);
7799
 
    rb_define_method(Cstmt, "cursortype", stmt_cursortype, -1);
7800
 
    rb_define_method(Cstmt, "cursortype=", stmt_cursortype, -1);
7801
 
    rb_define_method(Cstmt, "noscan", stmt_noscan, -1);
7802
 
    rb_define_method(Cstmt, "noscan=", stmt_noscan, -1);
7803
 
    rb_define_method(Cstmt, "rowsetsize", stmt_rowsetsize, -1);
7804
 
 
7805
 
    /* data type methods */
7806
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
7807
 
    rb_define_alloc_func(Cdate, date_alloc);
7808
 
#else
7809
 
    rb_define_singleton_method(Cdate, "new", date_new, -1);
7810
 
#endif
7811
 
    rb_define_singleton_method(Cdate, "_load", date_load, 1);
7812
 
    rb_define_method(Cdate, "initialize", date_init, -1);
7813
 
    rb_define_method(Cdate, "clone", date_clone, 0);
7814
 
    rb_define_method(Cdate, "to_s", date_to_s, 0);
7815
 
    rb_define_method(Cdate, "_dump", date_dump, 1);
7816
 
    rb_define_method(Cdate, "inspect", date_inspect, 0);
7817
 
    rb_define_method(Cdate, "year", date_year, -1);
7818
 
    rb_define_method(Cdate, "month", date_month, -1);
7819
 
    rb_define_method(Cdate, "day", date_day, -1);
7820
 
    rb_define_method(Cdate, "year=", date_year, -1);
7821
 
    rb_define_method(Cdate, "month=", date_month, -1);
7822
 
    rb_define_method(Cdate, "day=", date_day, -1);
7823
 
    rb_define_method(Cdate, "<=>", date_cmp, 1);
7824
 
 
7825
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
7826
 
    rb_define_alloc_func(Ctime, time_alloc);
7827
 
#else
7828
 
    rb_define_singleton_method(Ctime, "new", time_new, -1);
7829
 
#endif
7830
 
    rb_define_singleton_method(Ctime, "_load", time_load, 1);
7831
 
    rb_define_method(Ctime, "initialize", time_init, -1);
7832
 
    rb_define_method(Ctime, "clone", time_clone, 0);
7833
 
    rb_define_method(Ctime, "to_s", time_to_s, 0);
7834
 
    rb_define_method(Ctime, "_dump", time_dump, 1);
7835
 
    rb_define_method(Ctime, "inspect", time_inspect, 0);
7836
 
    rb_define_method(Ctime, "hour", time_hour, -1);
7837
 
    rb_define_method(Ctime, "minute", time_min, -1);
7838
 
    rb_define_method(Ctime, "second", time_sec, -1);
7839
 
    rb_define_method(Ctime, "hour=", time_hour, -1);
7840
 
    rb_define_method(Ctime, "minute=", time_min, -1);
7841
 
    rb_define_method(Ctime, "second=", time_sec, -1);
7842
 
    rb_define_method(Ctime, "<=>", time_cmp, 1);
7843
 
 
7844
 
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
7845
 
    rb_define_alloc_func(Ctimestamp, timestamp_alloc);
7846
 
#else
7847
 
    rb_define_singleton_method(Ctimestamp, "new", timestamp_new, -1);
7848
 
#endif
7849
 
    rb_define_singleton_method(Ctimestamp, "_load", timestamp_load, 1);
7850
 
    rb_define_method(Ctimestamp, "initialize", timestamp_init, -1);
7851
 
    rb_define_method(Ctimestamp, "clone", timestamp_clone, 0);
7852
 
    rb_define_method(Ctimestamp, "to_s", timestamp_to_s, 0);
7853
 
    rb_define_method(Ctimestamp, "_dump", timestamp_dump, 1);
7854
 
    rb_define_method(Ctimestamp, "inspect", timestamp_inspect, 0);
7855
 
    rb_define_method(Ctimestamp, "year", timestamp_year, -1);
7856
 
    rb_define_method(Ctimestamp, "month", timestamp_month, -1);
7857
 
    rb_define_method(Ctimestamp, "day", timestamp_day, -1);
7858
 
    rb_define_method(Ctimestamp, "hour", timestamp_hour, -1);
7859
 
    rb_define_method(Ctimestamp, "minute", timestamp_min, -1);
7860
 
    rb_define_method(Ctimestamp, "second", timestamp_sec, -1);
7861
 
    rb_define_method(Ctimestamp, "fraction", timestamp_fraction, -1);
7862
 
    rb_define_method(Ctimestamp, "year=", timestamp_year, -1);
7863
 
    rb_define_method(Ctimestamp, "month=", timestamp_month, -1);
7864
 
    rb_define_method(Ctimestamp, "day=", timestamp_day, -1);
7865
 
    rb_define_method(Ctimestamp, "hour=", timestamp_hour, -1);
7866
 
    rb_define_method(Ctimestamp, "minute=", timestamp_min, -1);
7867
 
    rb_define_method(Ctimestamp, "second=", timestamp_sec, -1);
7868
 
    rb_define_method(Ctimestamp, "fraction=", timestamp_fraction, -1);
7869
 
    rb_define_method(Ctimestamp, "<=>", timestamp_cmp, 1);
7870
 
 
7871
 
    /* procedure methods */
7872
 
    rb_define_method(Cproc, "initialize", stmt_proc_init, -1);
7873
 
    rb_define_method(Cproc, "call", stmt_proc_call, -1);
7874
 
    rb_define_method(Cproc, "[]", stmt_proc_call, -1);
7875
 
    rb_attr(Cproc, IDstatement, 1, 0, Qfalse);
7876
 
    rb_attr(Cproc, IDreturn_output_param, 1, 0, Qfalse);
7877
 
#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
7878
 
    rb_enable_super(Cproc, "call");
7879
 
    rb_enable_super(Cproc, "[]");
7880
 
#endif
7881
 
 
7882
 
    /* constants */
7883
 
    for (i = 0; o_const[i].name != NULL; i++) {
7884
 
        rb_define_const(Modbc, o_const[i].name,
7885
 
                        INT2NUM(o_const[i].value));
7886
 
    }
7887
 
    for (i = 0; get_info_map[i].name != NULL; i++) {
7888
 
        rb_define_const(Modbc, get_info_map[i].name,
7889
 
                        INT2NUM(get_info_map[i].info));
7890
 
    }
7891
 
    for (i = 0; get_info_bitmap[i].name != NULL; i++) {
7892
 
        rb_define_const(Modbc, get_info_bitmap[i].name,
7893
 
                        INT2NUM(get_info_bitmap[i].bits));
7894
 
    }
7895
 
    for (i = 0; option_map[i].name != NULL; i++) {
7896
 
        rb_define_const(Modbc, option_map[i].name,
7897
 
                        INT2NUM(option_map[i].option));
7898
 
    }
7899
 
 
7900
 
#ifdef TRACING
7901
 
    if (ruby_verbose) {
7902
 
        tracing = -1;
7903
 
    }
7904
 
#endif
7905
 
}