00001
00014
#include "sqliteodbc.h"
00015
00016
#ifdef SQLITE_UTF8
00017
#include <sqlucode.h>
00018
#endif
00019
00020
#ifdef _WIN32
00021
#define ODBC_INI "ODBC.INI"
00022
#else
00023 #define ODBC_INI ".odbc.ini"
00024
#endif
00025
00026
#undef min
00027 #define min(a, b) ((a) < (b) ? (a) : (b))
00028
#undef max
00029 #define max(a, b) ((a) < (b) ? (b) : (a))
00030
00031 #define array_size(x) (sizeof (x) / sizeof (x[0]))
00032
00033 #define stringify1(s) #s
00034 #define stringify(s) stringify1(s)
00035
00036 #define verinfo(maj, min, lev) ((maj) << 16 | (min) << 8 | (lev))
00037
00038
00039
00040
#ifdef SQLITE_UTF8
00041
#define SCOL_VARCHAR SQL_WVARCHAR
00042
#define SCOL_CHAR SQL_WCHAR
00043
#else
00044 #define SCOL_VARCHAR SQL_VARCHAR
00045 #define SCOL_CHAR SQL_CHAR
00046
#endif
00047
00048 #define ENV_MAGIC 0x53544145
00049 #define DBC_MAGIC 0x53544144
00050 #define DEAD_MAGIC 0xdeadbeef
00051
00052
#ifdef MEMORY_DEBUG
00053
00054
static void *
00055 xmalloc_(
int n,
char *file,
int line)
00056 {
00057
int nn = n + 4 *
sizeof (
long);
00058
long *p;
00059
00060 p = malloc(nn);
00061
if (!p) {
00062
#if (MEMORY_DEBUG > 1)
00063
fprintf(stderr,
"malloc\t%d\tNULL\t%s:%d\n", n, file, line);
00064
#endif
00065
return NULL;
00066 }
00067 p[0] = 0xdead1234;
00068 nn = nn /
sizeof (
long) - 1;
00069 p[1] = n;
00070 p[nn] = 0xdead5678;
00071
#if (MEMORY_DEBUG > 1)
00072
fprintf(stderr,
"malloc\t%d\t%p\t%s:%d\n", n, &p[2], file, line);
00073
#endif
00074
return (
void *) &p[2];
00075 }
00076
00077
static void *
00078 xrealloc_(
void *old,
int n,
char *file,
int line)
00079 {
00080
int nn = n + 4 *
sizeof (
long), nnn;
00081
long *p, *pp;
00082
00083
if (n == 0) {
00084
return xmalloc_(n, file, line);
00085 }
00086 p = &((
long *) old)[-2];
00087
if (p[0] != 0xdead1234) {
00088 fprintf(stderr,
"*** low end corruption @ %p\n", old);
00089 abort();
00090 }
00091 nnn = p[1] + 4 *
sizeof (
long);
00092 nnn = nnn /
sizeof (
long) - 1;
00093
if (p[nnn] != 0xdead5678) {
00094 fprintf(stderr,
"*** high end corruption @ %p\n", old);
00095 abort();
00096 }
00097 pp = realloc(p, nn);
00098
if (!pp) {
00099
#if (MEMORY_DEBUG > 1)
00100
fprintf(stderr,
"realloc\t%p,%d\tNULL\t%s:%d\n", old, n, file, line);
00101
#endif
00102
return NULL;
00103 }
00104
#if (MEMORY_DEBUG > 1)
00105
fprintf(stderr,
"realloc\t%p,%d\t%p\t%s:%d\n", old, n, &pp[2], file, line);
00106
#endif
00107
p = pp;
00108
if (n > p[1]) {
00109 memset(p + p[1], 0, 3 *
sizeof (
long));
00110 }
00111 p[1] = n;
00112 nn = nn /
sizeof (
long) - 1;
00113 p[nn] = 0xdead5678;
00114
return (
void *) &p[2];
00115 }
00116
00117
static void
00118 xfree_(
void *x,
char *file,
int line)
00119 {
00120
long *p;
00121
int n;
00122
00123 p = &((
long *) x)[-2];
00124
if (p[0] != 0xdead1234) {
00125 fprintf(stderr,
"*** low end corruption @ %p\n", x);
00126 abort();
00127 }
00128 n = p[1] + 4 *
sizeof (
long);
00129 n = n /
sizeof (
long) - 1;
00130
if (p[n] != 0xdead5678) {
00131 fprintf(stderr,
"*** high end corruption @ %p\n", x);
00132 abort();
00133 }
00134
#if (MEMORY_DEBUG > 1)
00135
fprintf(stderr,
"free\t%p\t\t%s:%d\n", x, file, line);
00136
#endif
00137
free(p);
00138 }
00139
00140
static void
00141 xfree__(
void *x)
00142 {
00143 xfree_(x,
"unknown location", 0);
00144 }
00145
00146
static char *
00147 xstrdup_(
char *str,
char *file,
int line)
00148 {
00149
char *p;
00150
00151
if (!str) {
00152
#if (MEMORY_DEBUG > 1)
00153
fprintf(stderr,
"strdup\tNULL\tNULL\t%s:%d\n", file, line);
00154
#endif
00155
return NULL;
00156 }
00157 p = xmalloc_(strlen(str) + 1, file, line);
00158
if (p) {
00159 strcpy(p, str);
00160 }
00161
#if (MEMORY_DEBUG > 1)
00162
fprintf(stderr,
"strdup\t%p\t%p\t%s:%d\n", str, p, file, line);
00163
#endif
00164
return p;
00165 }
00166
00167
#define xmalloc(x) xmalloc_(x, __FILE__, __LINE__)
00168
#define xrealloc(x,y) xrealloc_(x, y, __FILE__, __LINE__)
00169
#define xfree(x) xfree_(x, __FILE__, __LINE__)
00170
#define xstrdup(x) xstrdup_(x, __FILE__, __LINE__)
00171
00172
#else
00173
00174 #define xmalloc(x) malloc(x)
00175 #define xrealloc(x,y) realloc(x, y)
00176 #define xfree(x) free(x)
00177 #define xstrdup(x) strdup_(x)
00178
00179
#endif
00180
00181
#ifdef _WIN32
00182
#define vsnprintf _vsnprintf
00183
#define snprintf _snprintf
00184
#define strncasecmp _strnicmp
00185
#endif
00186
00187
00188
00189
00190
00191 static const char upper_chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00192 static const char lower_chars[] =
"abcdefghijklmnopqrstuvwxyz";
00193
00194
static int
00195 TOLOWER(
int c)
00196 {
00197
if (c) {
00198
char *p = strchr(
upper_chars, c);
00199
00200
if (p) {
00201 c =
lower_chars[p -
upper_chars];
00202 }
00203 }
00204
return c;
00205 }
00206
00207
00208
00209
00210
00211 static const char digit_chars[] =
"0123456789";
00212
00213 #define ISDIGIT(c) \
00214
((c) && strchr(digit_chars, (c)) != NULL)
00215
00216
00217
00218
00219
00220 static const char space_chars[] =
" \f\n\r\t\v";
00221
00222 #define ISSPACE(c) \
00223
((c) && strchr(space_chars, (c)) != NULL)
00224
00225
00226
00227
00228
00229 static const char id_chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00230
"abcdefghijklmnopqrstuvwxyz"
00231
"_0123456789";
00232
00233 #define ISIDCHAR(c) \
00234
((c) && strchr(id_chars, (c)) != NULL)
00235
00241
static void unbindcols(
STMT *s);
00242
00250
static SQLRETURN
mkbindcols(
STMT *s,
int ncols);
00251
00263
static void freeresult(
STMT *s,
int clrcols);
00264
00271
static SQLRETURN
freestmt(HSTMT
stmt);
00272
00287
static SQLRETURN
substparam(
STMT *s,
int pnum,
char **out,
int *size);
00288
00294
static void freedyncols(
STMT *s);
00295
00302
static SQLRETURN
drvexecute(SQLHSTMT
stmt);
00303
00310
static char *
00311 strdup_(
const char *str)
00312 {
00313
char *p = NULL;
00314
00315
if (str) {
00316 p =
xmalloc(strlen(str) + 1);
00317
if (p) {
00318 strcpy(p, str);
00319 }
00320 }
00321
return p;
00322 }
00323
00324
#ifdef SQLITE_UTF8
00325
00331
static int
00332 uc_strlen(SQLWCHAR *str)
00333 {
00334
int len = 0;
00335
00336
if (str) {
00337
while (*str) {
00338 ++len;
00339 ++str;
00340 }
00341 }
00342
return len;
00343 }
00344
00353
static SQLWCHAR *
00354 uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src,
int len)
00355 {
00356
int i = 0;
00357
00358
while (i < len) {
00359
if (!src[i]) {
00360
break;
00361 }
00362 dest[i] = src[i];
00363 ++i;
00364 }
00365
if (i < len) {
00366 dest[i] = 0;
00367 }
00368
return dest;
00369 }
00370
00378
static void
00379 uc_from_utf_buf(
unsigned char *str, SQLWCHAR *uc,
int ucLen)
00380 {
00381 ucLen = ucLen /
sizeof (SQLWCHAR);
00382
if (!uc || ucLen < 0) {
00383
return;
00384 }
00385 uc[0] = 0;
00386
if (str) {
00387
int i = 0;
00388
00389
while (*str && i < ucLen) {
00390
unsigned char c = str[0];
00391
00392
if (c < 0xc0) {
00393 uc[i++] = c;
00394 ++str;
00395 }
else if (c < 0xe0) {
00396
if ((str[1] & 0xc0) == 0x80) {
00397
unsigned long t = ((c & 0x1f) << 6) | (str[1] & 0x3f);
00398
00399 uc[i++] = t;
00400 str += 2;
00401 }
else {
00402 uc[i++] = c;
00403 ++str;
00404 }
00405 }
else if (c < 0xf0) {
00406
if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80) {
00407
unsigned long t = ((c & 0x0f) << 12) |
00408 ((str[1] & 0x3f) << 6) | (str[2] & 0x3f);
00409
00410 uc[i++] = t;
00411 str += 3;
00412 }
else {
00413 uc[i++] = c;
00414 ++str;
00415 }
00416 }
else if (c < 0xf8) {
00417
if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
00418 (str[3] & 0xc0) == 0x80) {
00419
unsigned long t = ((c & 0x03) << 18) |
00420 ((str[1] & 0x3f) << 12) | ((str[2] & 0x3f) << 6) |
00421 (str[4] & 0x3f);
00422
00423 uc[i++] = t;
00424 str += 4;
00425 }
else {
00426 uc[i++] = c;
00427 ++str;
00428 }
00429 }
else if (c < 0xfc) {
00430
if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
00431 (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) {
00432
unsigned long t = ((c & 0x01) << 24) |
00433 ((str[1] & 0x3f) << 18) | ((str[2] & 0x3f) << 12) |
00434 ((str[4] & 0x3f) << 6) | (str[5] & 0x3f);
00435
00436 uc[i++] = t;
00437 str += 5;
00438 }
else {
00439 uc[i++] = c;
00440 ++str;
00441 }
00442 }
else {
00443
00444 ++str;
00445 }
00446 }
00447
if (i < ucLen) {
00448 uc[i] = 0;
00449 }
00450 }
00451 }
00452
00460
static SQLWCHAR *
00461 uc_from_utf(
unsigned char *str,
int len)
00462 {
00463 SQLWCHAR *uc = NULL;
00464
00465
if (str) {
00466
if (len == SQL_NTS) {
00467 len = strlen(str);
00468 }
00469 len =
sizeof (SQLWCHAR) * (len + 1);
00470 uc =
xmalloc(len);
00471
if (uc) {
00472 uc_from_utf_buf(str, uc, len);
00473 }
00474 }
00475
return uc;
00476 }
00477
00485
static char *
00486 uc_to_utf(SQLWCHAR *str,
int len)
00487 {
00488
int i;
00489
char *cp, *ret = NULL;
00490
00491
if (!str) {
00492
return ret;
00493 }
00494
if (len == SQL_NTS) {
00495 len = uc_strlen(str);
00496 }
else {
00497 len = len /
sizeof (SQLWCHAR);
00498 }
00499 cp =
xmalloc(len * 6 + 1);
00500
if (!cp) {
00501
return ret;
00502 }
00503 ret = cp;
00504
for (i = 0; i < len; i++) {
00505
unsigned long c = str[i];
00506
00507
if (c < 0xc0) {
00508 *cp++ = c;
00509 }
else if (c < 0x800) {
00510 *cp++ = 0xc0 | ((c >> 6) & 0x1f);
00511 *cp++ = 0x80 | (c & 0x3f);
00512 }
else if (c < 0x10000) {
00513 *cp++ = 0xe0 | ((c >> 12) & 0x0f);
00514 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00515 *cp++ = 0x80 | (c & 0x3f);
00516 }
else if (c < 0x200000) {
00517 *cp++ = 0xf0 | ((c >> 18) & 0x07);
00518 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00519 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00520 *cp++ = 0x80 | (c & 0x3f);
00521 }
else if (c < 0x4000000) {
00522 *cp++ = 0xf8 | ((c >> 24) & 0x03);
00523 *cp++ = 0x80 | ((c >> 18) & 0x3f);
00524 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00525 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00526 *cp++ = 0x80 | (c & 0x3f);
00527 }
else if (c < 0x80000000) {
00528 *cp++ = 0xfc | ((c >> 31) & 0x01);
00529 *cp++ = 0x80 | ((c >> 24) & 0x3f);
00530 *cp++ = 0x80 | ((c >> 18) & 0x3f);
00531 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00532 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00533 *cp++ = 0x80 | (c & 0x3f);
00534 }
00535 }
00536 *cp =
'\0';
00537
return ret;
00538 }
00539
00547
static char *
00548 uc_to_utf_c(SQLWCHAR *str,
int len)
00549 {
00550
if (len != SQL_NTS) {
00551 len = len *
sizeof (SQLWCHAR);
00552 }
00553
return uc_to_utf(str, len);
00554 }
00555
00560
static void
00561 uc_free(
void *str)
00562 {
00563
if (str) {
00564
xfree(str);
00565 }
00566 }
00567
#endif
00568
00569
#ifdef USE_DLOPEN_FOR_GPPS
00570
00571
#include <dlfcn.h>
00572
00573
#define SQLGetPrivateProfileString(A,B,C,D,E,F) drvgpps(d,A,B,C,D,E,F)
00574
00575
00576
00577
00578
00579
00580
00581
00582
static void
00583
drvgetgpps(
DBC *d)
00584 {
00585
void *lib;
00586 int (*gpps)();
00587
00588 lib = dlopen(
"libodbcinst.so", RTLD_LAZY);
00589
if (!lib) {
00590 lib = dlopen(
"libiodbcinst.so", RTLD_LAZY);
00591 }
00592
if (lib) {
00593 gpps = (int (*)()) dlsym(lib,
"SQLGetPrivateProfileString");
00594
if (!gpps) {
00595 dlclose(lib);
00596
return;
00597 }
00598 d->instlib = lib;
00599 d->gpps = gpps;
00600 }
00601 }
00602
00603
static void
00604
drvrelgpps(
DBC *d)
00605 {
00606
if (d->instlib) {
00607 dlclose(d->instlib);
00608 d->instlib = 0;
00609 }
00610 }
00611
00612
static int
00613 drvgpps(
DBC *d,
char *sect,
char *ent,
char *def,
char *buf,
00614
int bufsiz,
char *fname)
00615 {
00616
if (d->gpps) {
00617
return d->gpps(sect, ent, def, buf, bufsiz, fname);
00618 }
00619 strncpy(buf, def, bufsiz);
00620 buf[bufsiz - 1] =
'\0';
00621
return 1;
00622 }
00623
#else
00624 #define drvgetgpps(d)
00625 #define drvrelgpps(d)
00626
#endif
00627
00636
#if defined(__GNUC__) && (__GNUC__ >= 2)
00637
static void setstatd(
DBC *,
int,
char *,
char *, ...)
00638 __attribute__((format (printf, 3, 5)));
00639 #endif
00640
00641 static
void
00642 setstatd(
DBC *d,
int naterr,
char *msg,
char *st, ...)
00643 {
00644 va_list ap;
00645
00646
if (!d) {
00647
return;
00648 }
00649 d->naterr = naterr;
00650 d->logmsg[0] =
'\0';
00651
if (msg) {
00652
int count;
00653
00654 va_start(ap, st);
00655 count = vsnprintf(d->logmsg, sizeof (d->logmsg), msg, ap);
00656 va_end(ap);
00657
if (count < 0) {
00658 d->logmsg[
sizeof (d->logmsg) - 1] =
'\0';
00659 }
00660 }
00661
if (!st) {
00662 st =
"?????";
00663 }
00664 strncpy(d->sqlstate, st, 5);
00665 d->sqlstate[5] =
'\0';
00666 }
00667
00676
#if defined(__GNUC__) && (__GNUC__ >= 2)
00677
static void setstat(
STMT *,
int,
char *,
char *, ...)
00678 __attribute__((format (printf, 3, 5)));
00679 #endif
00680
00681 static
void
00682 setstat(
STMT *s,
int naterr,
char *msg,
char *st, ...)
00683 {
00684 va_list ap;
00685
00686
if (!s) {
00687
return;
00688 }
00689 s->naterr = naterr;
00690 s->logmsg[0] =
'\0';
00691
if (msg) {
00692
int count;
00693
00694 va_start(ap, st);
00695 count = vsnprintf(s->logmsg, sizeof (s->logmsg), msg, ap);
00696 va_end(ap);
00697
if (count < 0) {
00698 s->logmsg[
sizeof (s->logmsg) - 1] =
'\0';
00699 }
00700 }
00701
if (!st) {
00702 st =
"?????";
00703 }
00704 strncpy(s->sqlstate, st, 5);
00705 s->sqlstate[5] =
'\0';
00706 }
00707
00714
static SQLRETURN
00715 drvunimpldbc(HDBC
dbc)
00716 {
00717
DBC *d;
00718
00719
if (dbc == SQL_NULL_HDBC) {
00720
return SQL_INVALID_HANDLE;
00721 }
00722 d = (
DBC *) dbc;
00723
setstatd(d, -1,
"not supported",
"IM001");
00724
return SQL_ERROR;
00725 }
00726
00733
static SQLRETURN
00734 drvunimplstmt(HSTMT
stmt)
00735 {
00736
STMT *s;
00737
00738
if (stmt == SQL_NULL_HSTMT) {
00739
return SQL_INVALID_HANDLE;
00740 }
00741 s = (
STMT *) stmt;
00742
setstat(s, -1,
"not supported",
"IM001");
00743
return SQL_ERROR;
00744 }
00745
00751
static void
00752 freep(
void *x)
00753 {
00754
if (x && ((
char **) x)[0]) {
00755
xfree(((
char **) x)[0]);
00756 ((
char **) x)[0] = NULL;
00757 }
00758 }
00759
00766
static SQLRETURN
00767 nomem(
STMT *s)
00768 {
00769
setstat(s, -1,
"out of memory", (*s->
ov3) ?
"HY000" :
"S1000");
00770
return SQL_ERROR;
00771 }
00772
00779
static SQLRETURN
00780 noconn(
STMT *s)
00781 {
00782
setstat(s, -1,
"not connected", (*s->
ov3) ?
"HY000" :
"S1000");
00783
return SQL_ERROR;
00784 }
00785
00793
#if defined(HAVE_SQLITEATOF) && HAVE_SQLITEATOF
00794
00795
extern double sqliteAtoF(
char *data,
char **endp);
00796
00797
#define ln_strtod sqliteAtoF
00798
00799
#else
00800
00801
static double
00802 ln_strtod(
const char *data,
char **endp)
00803 {
00804
#if defined(HAVE_LOCALECONV) || defined(_WIN32)
00805
struct lconv *lc;
00806
char buf[128], *p, *end;
00807
double value;
00808
00809 lc = localeconv();
00810
if (lc && lc->decimal_point && lc->decimal_point[0] &&
00811 lc->decimal_point[0] !=
'.') {
00812 strncpy(buf, data,
sizeof (buf) - 1);
00813 buf[
sizeof (buf) - 1] =
'\0';
00814 p = strchr(buf,
'.');
00815
if (p) {
00816 *p = lc->decimal_point[0];
00817 }
00818 p = buf;
00819 }
else {
00820 p = (
char *) data;
00821 }
00822 value = strtod(p, &end);
00823 end = (
char *) data + (end - p);
00824
if (endp) {
00825 *endp = end;
00826 }
00827
return value;
00828
#else
00829
return strtod(data, endp);
00830
#endif
00831
}
00832
00833
#endif
00834
00835
#if !defined(HAVE_SQLITEMPRINTF) || !HAVE_SQLITEMPRINTF
00836
00842
static void
00843 ln_sprintfg(
char *buf,
double value)
00844 {
00845
#if defined(HAVE_LOCALECONV) || defined(_WIN32)
00846
struct lconv *lc;
00847
char *p;
00848
00849 sprintf(buf,
"%.16g", value);
00850 lc = localeconv();
00851
if (lc && lc->decimal_point && lc->decimal_point[0] &&
00852 lc->decimal_point[0] !=
'.') {
00853 p = strchr(buf, lc->decimal_point[0]);
00854
if (p) {
00855 *p =
'.';
00856 }
00857 }
00858
#else
00859
sprintf(buf,
"%.16g", value);
00860
#endif
00861
}
00862
#endif
00863
00872
static int
00873 busy_handler(
void *udata,
const char *table,
int count)
00874 {
00875
DBC *d = (
DBC *) udata;
00876
long t1;
00877
int ret = 0;
00878
#ifndef _WIN32
00879
struct timeval tv;
00880
#endif
00881
00882
if (d->
timeout <= 0) {
00883
return ret;
00884 }
00885
if (count <= 1) {
00886
#ifdef _WIN32
00887
d->
t0 = GetTickCount();
00888
#else
00889
gettimeofday(&tv, NULL);
00890 d->
t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
00891
#endif
00892
}
00893
#ifdef _WIN32
00894
t1 = GetTickCount();
00895
#else
00896
gettimeofday(&tv, NULL);
00897 t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
00898
#endif
00899
if (t1 - d->
t0 > d->
timeout) {
00900
goto done;
00901
return 0;
00902 }
00903
#ifdef _WIN32
00904
Sleep(10);
00905
#else
00906
#ifdef HAVE_USLEEP
00907
usleep(10000);
00908
#else
00909
tv.tv_sec = 0;
00910 tv.tv_usec = 10000;
00911 select(0, NULL, NULL, NULL, &tv);
00912
#endif
00913
#endif
00914
ret = 1;
00915 done:
00916
return ret;
00917 }
00918
00935
static int
00936 setsqliteopts(sqlite *x,
DBC *d)
00937 {
00938
int count = 0, step = 0, rc;
00939
00940
while (step < 4) {
00941
if (step < 1) {
00942 rc = sqlite_exec(x,
"PRAGMA full_column_names = on;",
00943 NULL, NULL, NULL);
00944 }
else if (step < 2) {
00945 rc = sqlite_exec(x,
"PRAGMA count_changes = on;",
00946 NULL, NULL, NULL);
00947 }
else if (step < 3) {
00948 rc = sqlite_exec(x,
"PRAGMA empty_result_callbacks = on;",
00949 NULL, NULL, NULL);
00950 }
else {
00951 rc = sqlite_exec(x,
"PRAGMA show_datatypes = on;",
00952 NULL, NULL, NULL);
00953 }
00954
if (rc != SQLITE_OK) {
00955
if (rc != SQLITE_BUSY ||
00956 !
busy_handler((
void *) d, NULL, ++count)) {
00957
return rc;
00958 }
00959
continue;
00960 }
00961 count = 0;
00962 ++step;
00963 }
00964 sqlite_busy_handler(x,
busy_handler, (
void *) d);
00965
#if HAVE_ENCDEC
00966
{
00967
char *fname;
00968
static void hextobin_func(sqlite_func *context,
00969
int argc,
const char **argv);
00970
static void bintohex_func(sqlite_func *context,
00971
int argc,
const char **argv);
00972
00973 fname =
"hextobin";
00974 sqlite_create_function(x, fname, 1, hextobin_func, 0);
00975 sqlite_function_type(x, fname, SQLITE_TEXT);
00976 fname =
"bintohex";
00977 sqlite_create_function(x, fname, 1, bintohex_func, 0);
00978 sqlite_function_type(x, fname, SQLITE_TEXT);
00979 }
00980
#endif
00981
{
00982
char *fname;
00983
static void time_func(sqlite_func *context,
00984
int argc,
const char **argv);
00985
00986 fname =
"current_time_local";
00987 sqlite_create_function(x, fname, 0,
time_func, (
void *) 0);
00988 sqlite_function_type(x, fname, SQLITE_TEXT);
00989 fname =
"current_time_utc";
00990 sqlite_create_function(x, fname, 0,
time_func, (
void *) 1);
00991 sqlite_function_type(x, fname, SQLITE_TEXT);
00992 fname =
"current_date_local";
00993 sqlite_create_function(x, fname, 0,
time_func, (
void *) 2);
00994 sqlite_function_type(x, fname, SQLITE_TEXT);
00995 fname =
"current_date_utc";
00996 sqlite_create_function(x, fname, 0,
time_func, (
void *) 3);
00997 sqlite_function_type(x, fname, SQLITE_TEXT);
00998 fname =
"current_datetime_local";
00999 sqlite_create_function(x, fname, 0,
time_func, (
void *) 4);
01000 sqlite_function_type(x, fname, SQLITE_TEXT);
01001 fname =
"current_datetime_utc";
01002 sqlite_create_function(x, fname, 0,
time_func, (
void *) 5);
01003 sqlite_function_type(x, fname, SQLITE_TEXT);
01004 fname =
"current_timestamp_local";
01005 sqlite_create_function(x, fname, 0,
time_func, (
void *) 4);
01006 sqlite_function_type(x, fname, SQLITE_TEXT);
01007 fname =
"current_timestamp_utc";
01008 sqlite_create_function(x, fname, 0,
time_func, (
void *) 5);
01009 sqlite_function_type(x, fname, SQLITE_TEXT);
01010 }
01011
return SQLITE_OK;
01012 }
01013
01023
static void
01024 freerows(
char **rowp)
01025 {
01026
int size, i;
01027
01028
if (!rowp) {
01029
return;
01030 }
01031 --rowp;
01032 size = (
int) rowp[0];
01033
for (i = 1; i <= size; i++) {
01034
freep(&rowp[i]);
01035 }
01036
freep(&rowp);
01037 }
01038
01048
static int
01049 mapsqltype(
const char *
typename,
int *nosign,
int ov3,
int nowchar)
01050 {
01051
char *p, *q;
01052
int testsign = 0, result;
01053
01054
#ifdef SQLITE_UTF8
01055
result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
01056
#else
01057
result = SQL_VARCHAR;
01058
#endif
01059
if (!
typename) {
01060
return result;
01061 }
01062 q = p =
xmalloc(strlen(
typename) + 1);
01063
if (!p) {
01064
return result;
01065 }
01066 strcpy(p,
typename);
01067
while (*q) {
01068 *q =
TOLOWER(*q);
01069 ++q;
01070 }
01071
if (strncmp(p,
"inter", 5) == 0) {
01072 }
else if (strncmp(p,
"int", 3) == 0 ||
01073 strncmp(p,
"mediumint", 9) == 0) {
01074 testsign = 1;
01075 result = SQL_INTEGER;
01076 }
else if (strncmp(p,
"numeric", 7) == 0) {
01077 result = SQL_DOUBLE;
01078 }
else if (strncmp(p,
"tinyint", 7) == 0) {
01079 testsign = 1;
01080 result = SQL_TINYINT;
01081 }
else if (strncmp(p,
"smallint", 8) == 0) {
01082 testsign = 1;
01083 result = SQL_SMALLINT;
01084 }
else if (strncmp(p,
"float", 5) == 0) {
01085 result = SQL_DOUBLE;
01086 }
else if (strncmp(p,
"double", 6) == 0 ||
01087 strncmp(p,
"real", 4) == 0) {
01088 result = SQL_DOUBLE;
01089 }
else if (strncmp(p,
"timestamp", 9) == 0) {
01090
#ifdef SQL_TYPE_TIMESTAMP
01091
result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
01092
#else
01093
result = SQL_TIMESTAMP;
01094
#endif
01095
}
else if (strncmp(p,
"datetime", 8) == 0) {
01096
#ifdef SQL_TYPE_TIMESTAMP
01097
result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
01098
#else
01099
result = SQL_TIMESTAMP;
01100
#endif
01101
}
else if (strncmp(p,
"time", 4) == 0) {
01102
#ifdef SQL_TYPE_TIME
01103
result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
01104
#else
01105
result = SQL_TIME;
01106
#endif
01107
}
else if (strncmp(p,
"date", 4) == 0) {
01108
#ifdef SQL_TYPE_DATE
01109
result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
01110
#else
01111
result = SQL_DATE;
01112
#endif
01113
#ifdef SQL_LONGVARCHAR
01114
}
else if (strncmp(p,
"text", 4) == 0) {
01115
#ifdef SQLITE_UTF8
01116
result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
01117
#else
01118
result = SQL_LONGVARCHAR;
01119
#endif
01120
#ifdef SQLITE_UTF8
01121
}
else if (strncmp(p,
"wtext", 5) == 0 ||
01122 strncmp(p,
"wvarchar", 8) == 0 ||
01123 strncmp(p,
"longwvarchar", 12) == 0) {
01124 result = SQL_WLONGVARCHAR;
01125
#endif
01126
#endif
01127
#if HAVE_ENCDEC
01128
}
else if (strncmp(p,
"binary", 6) == 0 ||
01129 strncmp(p,
"varbinary", 9) == 0 ||
01130 strncmp(p,
"bytea", 5) == 0 ||
01131 strncmp(p,
"blob", 4) == 0 ||
01132 strncmp(p,
"tinyblob", 8) == 0 ||
01133 strncmp(p,
"mediumblob", 10) == 0) {
01134 result = SQL_VARBINARY;
01135 }
else if (strncmp(p,
"longbinary", 10) == 0 ||
01136 strncmp(p,
"longvarbinary", 13) == 0 ||
01137 strncmp(p,
"longblob", 8) == 0) {
01138 result = SQL_LONGVARBINARY;
01139
#endif
01140
}
01141
if (nosign) {
01142
if (testsign) {
01143 *nosign = strstr(p,
"unsigned") != NULL;
01144 }
else {
01145 *nosign = 1;
01146 }
01147 }
01148
xfree(p);
01149
return result;
01150 }
01151
01161
static void
01162 getmd(
const char *
typename,
int sqltype,
int *mp,
int *dp)
01163 {
01164
int m = 0, d = 0;
01165
01166
switch (sqltype) {
01167
case SQL_INTEGER: m = 10; d = 9;
break;
01168
case SQL_TINYINT: m = 4; d = 3;
break;
01169
case SQL_SMALLINT: m = 6; d = 5;
break;
01170
case SQL_FLOAT: m = 25; d = 24;
break;
01171
case SQL_DOUBLE: m = 54; d = 53;
break;
01172
case SQL_VARCHAR: m = 255; d = 0;
break;
01173
#ifdef SQLITE_UTF8
01174
#ifdef SQL_WVARCHAR
01175
case SQL_WVARCHAR: m = 255; d = 0;
break;
01176
#endif
01177
#endif
01178
#ifdef SQL_TYPE_DATE
01179
case SQL_TYPE_DATE:
01180
#endif
01181
case SQL_DATE: m = 10; d = 0;
break;
01182
#ifdef SQL_TYPE_TIME
01183
case SQL_TYPE_TIME:
01184
#endif
01185
case SQL_TIME: m = 8; d = 0;
break;
01186
#ifdef SQL_TYPE_TIMESTAMP
01187
case SQL_TYPE_TIMESTAMP:
01188
#endif
01189
case SQL_TIMESTAMP: m = 32; d = 0;
break;
01190
#ifdef SQL_LONGVARCHAR
01191
case SQL_LONGVARCHAR : m = 65536; d = 0;
break;
01192
#endif
01193
#ifdef SQLITE_UTF8
01194
#ifdef SQL_WLONGVARCHAR
01195
case SQL_WLONGVARCHAR: m = 65536; d = 0;
break;
01196
#endif
01197
#endif
01198
#if HAVE_ENCDEC
01199
case SQL_VARBINARY: m = 255; d = 0;
break;
01200
case SQL_LONGVARBINARY: m = 65536; d = 0;
break;
01201
#endif
01202
}
01203
if (m &&
typename) {
01204
int mm, dd;
01205
01206
if (sscanf(
typename,
"%*[^(](%d)", &mm) == 1) {
01207 m = d = mm;
01208 }
else if (sscanf(
typename,
"%*[^(](%d,%d)", &mm, &dd) == 2) {
01209 m = mm;
01210 d = dd;
01211 }
01212 }
01213
if (mp) {
01214 *mp = m;
01215 }
01216
if (dp) {
01217 *dp = d;
01218 }
01219 }
01220
01230
static int
01231 mapdeftype(
int type,
int stype,
int nosign,
int nowchar)
01232 {
01233
if (type == SQL_C_DEFAULT) {
01234
switch (stype) {
01235
case SQL_INTEGER:
01236 type = nosign > 0 ? SQL_C_ULONG : SQL_C_LONG;
01237
break;
01238
case SQL_TINYINT:
01239 type = nosign > 0 ? SQL_C_UTINYINT : SQL_C_TINYINT;
01240
break;
01241
case SQL_SMALLINT:
01242 type = nosign > 0 ? SQL_C_USHORT : SQL_C_SHORT;
01243
break;
01244
case SQL_FLOAT:
01245 type = SQL_C_FLOAT;
01246
break;
01247
case SQL_DOUBLE:
01248 type = SQL_C_DOUBLE;
01249
break;
01250
case SQL_TIMESTAMP:
01251 type = SQL_C_TIMESTAMP;
01252
break;
01253
case SQL_TIME:
01254 type = SQL_C_TIME;
01255
break;
01256
case SQL_DATE:
01257 type = SQL_C_DATE;
01258
break;
01259
#ifdef SQL_C_TYPE_TIMESTAMP
01260
case SQL_TYPE_TIMESTAMP:
01261 type = SQL_C_TYPE_TIMESTAMP;
01262
break;
01263
#endif
01264
#ifdef SQL_C_TYPE_TIME
01265
case SQL_TYPE_TIME:
01266 type = SQL_C_TYPE_TIME;
01267
break;
01268
#endif
01269
#ifdef SQL_C_TYPE_DATE
01270
case SQL_TYPE_DATE:
01271 type = SQL_C_TYPE_DATE;
01272
break;
01273
#endif
01274
#ifdef SQLITE_UTF8
01275
case SQL_WVARCHAR:
01276
case SQL_WCHAR:
01277
#ifdef SQL_WLONGVARCHAR
01278
case SQL_WLONGVARCHAR:
01279
#endif
01280
type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
01281
break;
01282
#endif
01283
#if HAVE_ENCDEC
01284
case SQL_BINARY:
01285
case SQL_VARBINARY:
01286
case SQL_LONGVARBINARY:
01287 type = SQL_C_BINARY;
01288
break;
01289
#endif
01290
default:
01291 type = SQL_C_CHAR;
01292 }
01293 }
01294
#ifdef SQLITE_UTF8
01295
if (nowchar) {
01296
switch (type) {
01297
case SQL_C_WCHAR:
01298 type = SQL_C_CHAR;
01299
break;
01300 }
01301 }
01302
#endif
01303
return type;
01304 }
01305
01318
static char *
01319 fixupsql(
char *sql,
int sqlLen,
int *nparam,
int *isselect,
char **errmsg,
01320
int version,
char ***namepp)
01321 {
01322
char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
01323
int np = 0, size;
01324
char **npp = NULL, *ncp = NULL;
01325
01326 *errmsg = NULL;
01327
if (sqlLen != SQL_NTS) {
01328 qz = q =
xmalloc(sqlLen + 1);
01329
if (!qz) {
01330
return NULL;
01331 }
01332 memcpy(q, sql, sqlLen);
01333 q[sqlLen] =
'\0';
01334 size = sqlLen * 4;
01335 }
else {
01336 size = strlen(sql) * 4;
01337 }
01338 size +=
sizeof (
char *) - 1;
01339 size &= ~(
sizeof (
char *) - 1);
01340 p =
xmalloc(2 * size + size *
sizeof (
char *) / 2);
01341
if (!p) {
01342 errout:
01343
freep(&qz);
01344
return NULL;
01345 }
01346 out = p;
01347 npp = (
char **) (out + size);
01348 ncp = (
char *) npp + size *
sizeof (
char *) / 2;
01349
while (*q) {
01350
switch (*q) {
01351
case '\'':
01352
case '\"':
01353
if (q == inq) {
01354 inq = NULL;
01355 }
else if (!inq) {
01356 inq = q + 1;
01357
01358
while (*inq) {
01359
if (*inq == *q) {
01360
if (inq[1] == *q) {
01361 inq++;
01362 }
else {
01363
break;
01364 }
01365 }
01366 inq++;
01367 }
01368 }
01369 *p++ = *q;
01370
break;
01371
case '?':
01372
if (inq) {
01373 *p++ = *q;
01374 }
else {
01375 *p++ =
'%';
01376 *p++ =
'Q';
01377 npp[np] = ncp;
01378 *ncp =
'\0';
01379 ++ncp;
01380 np++;
01381 }
01382
break;
01383
case ':':
01384
case '@':
01385
if (inq) {
01386 *p++ = *q;
01387 }
else {
01388
int n = -1;
01389
01390
do {
01391 ++q;
01392 ++n;
01393 }
while (*q &&
ISIDCHAR(*q));
01394
if (n > 0) {
01395 *p++ =
'%';
01396 *p++ =
'Q';
01397 npp[np] = ncp;
01398 memcpy(ncp, q - n, n);
01399 ncp[n] =
'\0';
01400 ncp += n + 1;
01401 np++;
01402 }
01403 --q;
01404 }
01405
break;
01406
case ';':
01407
if (inq) {
01408 *p++ = *q;
01409 }
else {
01410
do {
01411 ++q;
01412 }
while (*q &&
ISSPACE(*q));
01413
if (*q) {
01414
freep(&out);
01415 *errmsg =
"only one SQL statement allowed";
01416
goto errout;
01417 }
01418 --q;
01419 }
01420
break;
01421
case '%':
01422 *p++ =
'%';
01423 *p++ =
'%';
01424
break;
01425
case '{':
01426
01427
if (!inq) {
01428
char *end = q + 1;
01429
01430
while (*end && *end !=
'}') {
01431 ++end;
01432 }
01433
if (*end ==
'}') {
01434
char *start = q + 1;
01435
char *end2 = end - 1;
01436
01437
while (start < end2 && *start !=
'\'') {
01438 ++start;
01439 }
01440
while (end2 > start && *end2 !=
'\'') {
01441 --end2;
01442 }
01443
if (*start ==
'\'' && *end2 ==
'\'') {
01444
while (start <= end2) {
01445 *p++ = *start;
01446 ++start;
01447 }
01448 q = end;
01449
break;
01450 }
01451 }
01452 }
01453
01454
default:
01455 *p++ = *q;
01456 }
01457 ++q;
01458 }
01459
freep(&qz);
01460 *p =
'\0';
01461
if (nparam) {
01462 *nparam = np;
01463 }
01464
if (isselect) {
01465 p = out;
01466
while (*p &&
ISSPACE(*q)) {
01467 ++p;
01468 }
01469 *isselect = strncasecmp(p,
"select", 6) == 0;
01470 }
01471
if (namepp) {
01472 *namepp = npp;
01473 }
01474
return out;
01475 }
01476
01485
static int
01486 findcol(
char **cols,
int ncols,
char *name)
01487 {
01488
int i;
01489
01490
if (cols) {
01491
for (i = 0; i < ncols; i++) {
01492
if (strcmp(cols[i], name) == 0) {
01493
return i;
01494 }
01495 }
01496 }
01497
return -1;
01498 }
01499
01517
static void
01518 fixupdyncols(
STMT *s, sqlite *sqlite,
const char **types)
01519 {
01520
int i, k, pk, t, r, nrows, ncols, doautoinc = 0;
01521
char **rowp, *flagp, flags[128];
01522
01523
if (!s->
dyncols) {
01524
return;
01525 }
01526
01527
if (s->
dcols > 1) {
01528
char *table = s->
dyncols[0].
table;
01529
01530
for (i = 1; table[0] && i < s->
dcols; i++) {
01531
if (strcmp(s->
dyncols[i].
table, table)) {
01532
break;
01533 }
01534 }
01535
if (i >= s->
dcols) {
01536
for (i = 0; i < s->
dcols; i++) {
01537 s->
dyncols[i].
label = s->
dyncols[i].
column;
01538 }
01539 }
01540 }
else if (s->
dcols == 1) {
01541 s->
dyncols[0].
label = s->
dyncols[0].
column;
01542 }
01543
if (types) {
01544
for (i = 0; i < s->
dcols; i++) {
01545
freep(&s->
dyncols[i].
typename);
01546 s->
dyncols[i].
typename =
xstrdup(types[i] ? types[i] :
"text");
01547 s->
dyncols[i].
type =
01548
mapsqltype(types[i], &s->
dyncols[i].
nosign, *s->
ov3,
01549 s->
nowchar);
01550
getmd(types[i], s->
dyncols[i].
type, &s->
dyncols[i].
size, NULL);
01551
#ifdef SQL_LONGVARCHAR
01552
if (s->
dyncols[i].
type == SQL_VARCHAR &&
01553 s->
dyncols[i].
size > 255) {
01554 s->
dyncols[i].
type = SQL_LONGVARCHAR;
01555 }
01556
#endif
01557
#ifdef SQLITE_UTF8
01558
#ifdef SQL_WLONGVARCHAR
01559
if (s->
dyncols[i].
type == SQL_WVARCHAR &&
01560 s->
dyncols[i].
size > 255) {
01561 s->
dyncols[i].
type = SQL_WLONGVARCHAR;
01562 }
01563
#endif
01564
#endif
01565
#if HAVE_ENCDEC
01566
if (s->
dyncols[i].
type == SQL_VARBINARY &&
01567 s->
dyncols[i].
size > 255) {
01568 s->
dyncols[i].
type = SQL_LONGVARBINARY;
01569 }
01570
#endif
01571
if (types[i] && strlen(types[i]) == 7 &&
01572 strncasecmp(types[i],
"integer", 7) == 0) {
01573 doautoinc++;
01574 s->
dyncols[i].
autoinc = -1;
01575 }
else {
01576 s->
dyncols[i].
autoinc = 0;
01577 }
01578 }
01579
if (!doautoinc) {
01580
return;
01581 }
01582 }
01583
if (s->
dcols >
array_size(flags)) {
01584 flagp =
xmalloc(
sizeof (flags[0]) * s->
dcols);
01585
if (flagp == NULL) {
01586
return;
01587 }
01588 }
else {
01589 flagp = flags;
01590 }
01591 memset(flagp, 0,
sizeof (flags[0]) * s->
dcols);
01592
for (i = 0; i < s->
dcols; i++) {
01593 s->
dyncols[i].
autoinc = 0;
01594 }
01595
for (i = 0; i < s->
dcols; i++) {
01596
int ret, lastpk = -1, autoinccount = 0;
01597
01598
if (!s->
dyncols[i].
table[0]) {
01599
continue;
01600 }
01601
if (flagp[i]) {
01602
continue;
01603 }
01604 ret = sqlite_get_table_printf(sqlite,
01605
"PRAGMA table_info('%q')", &rowp,
01606 &nrows, &ncols, NULL,
01607 s->
dyncols[i].
table);
01608
if (ret != SQLITE_OK) {
01609
continue;
01610 }
01611 k =
findcol(rowp, ncols,
"name");
01612 t =
findcol(rowp, ncols,
"type");
01613 pk =
findcol(rowp, ncols,
"pk");
01614
if (k < 0 || t < 0) {
01615
goto freet;
01616 }
01617
for (r = 1; r <= nrows; r++) {
01618
int m;
01619
01620
for (m = i; m < s->
dcols; m++) {
01621
if (!flagp[m] &&
01622 strcmp(s->
dyncols[m].
column, rowp[r * ncols + k]) == 0 &&
01623 strcmp(s->
dyncols[m].
table, s->
dyncols[i].
table) == 0) {
01624
char *
typename = rowp[r * ncols + t];
01625
01626 flagp[m] = 1;
01627
freep(&s->
dyncols[m].
typename);
01628 s->
dyncols[m].
typename =
xstrdup(
typename);
01629 s->
dyncols[m].
type =
01630
mapsqltype(
typename, &s->
dyncols[m].
nosign, *s->
ov3,
01631 s->
nowchar);
01632
getmd(
typename, s->
dyncols[m].
type, &s->
dyncols[m].
size,
01633 NULL);
01634
#ifdef SQL_LONGVARCHAR
01635
if (s->
dyncols[m].
type == SQL_VARCHAR &&
01636 s->
dyncols[m].
size > 255) {
01637 s->
dyncols[m].
type = SQL_LONGVARCHAR;
01638 }
01639
#endif
01640
#ifdef SQLITE_UTF8
01641
#ifdef SQL_WLONGVARCHAR
01642
if (s->
dyncols[i].
type == SQL_WVARCHAR &&
01643 s->
dyncols[i].
size > 255) {
01644 s->
dyncols[i].
type = SQL_WLONGVARCHAR;
01645 }
01646
#endif
01647
#endif
01648
#if HAVE_ENCDEC
01649
if (s->
dyncols[i].
type == SQL_VARBINARY &&
01650 s->
dyncols[i].
size > 255) {
01651 s->
dyncols[i].
type = SQL_LONGVARBINARY;
01652 }
01653
#endif
01654
if (pk >= 0 && strcmp(rowp[r * ncols + pk],
"1") == 0) {
01655
if (++autoinccount > 1) {
01656
if (lastpk >= 0) {
01657 s->
dyncols[lastpk].
autoinc = 0;
01658 lastpk = -1;
01659 }
01660 }
else {
01661 lastpk = m;
01662
if (strlen(
typename) == 7 &&
01663 strncasecmp(
typename,
"integer", 7) == 0) {
01664 s->
dyncols[m].
autoinc = 1;
01665 }
01666 }
01667 }
01668 }
01669 }
01670 }
01671 freet:
01672 sqlite_free_table(rowp);
01673 }
01674
if (flagp != flags) {
01675
freep(&flagp);
01676 }
01677 }
01678
01686
static int
01687 getmdays(
int year,
int month)
01688 {
01689
static const int mdays[] = {
01690 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
01691 };
01692
int mday;
01693
01694
if (month < 1) {
01695
return 0;
01696 }
01697 mday = mdays[(month - 1) % 12];
01698
if (mday == 28 && year % 4 == 0 &&
01699 (!(year % 100 == 0) || year % 400 == 0)) {
01700 mday++;
01701 }
01702
return mday;
01703 }
01704
01715
static int
01716 str2date(
char *str, DATE_STRUCT *ds)
01717 {
01718
int i, err = 0;
01719
char *p, *q;
01720
01721 ds->year = ds->month = ds->day = 0;
01722 p = str;
01723
while (*p && !
ISDIGIT(*p)) {
01724 ++p;
01725 }
01726 q = p;
01727 i = 0;
01728
while (*q && !
ISDIGIT(*q)) {
01729 ++i;
01730 ++q;
01731 }
01732
if (i >= 8) {
01733
char buf[8];
01734
01735 strncpy(buf, p + 0, 4); buf[4] =
'\0';
01736 ds->year = strtol(buf, NULL, 10);
01737 strncpy(buf, p + 4, 2); buf[2] =
'\0';
01738 ds->month = strtol(buf, NULL, 10);
01739 strncpy(buf, p + 6, 2); buf[2] =
'\0';
01740 ds->day = strtol(buf, NULL, 10);
01741
goto done;
01742 }
01743 i = 0;
01744
while (i < 3) {
01745
int n;
01746
01747 q = NULL;
01748 n = strtol(p, &q, 10);
01749
if (!q || q == p) {
01750
if (*q ==
'\0') {
01751
if (i == 0) {
01752 err = 1;
01753 }
01754
goto done;
01755 }
01756 }
01757
if (*q ==
'-' || *q ==
'/' || *q ==
'\0' || i == 2) {
01758
switch (i) {
01759
case 0: ds->year = n;
break;
01760
case 1: ds->month = n;
break;
01761
case 2: ds->day = n;
break;
01762 }
01763 ++i;
01764
if (*q) {
01765 ++q;
01766 }
01767 }
else {
01768 i = 0;
01769
while (*q && !
ISDIGIT(*q)) {
01770 ++q;
01771 }
01772 }
01773 p = q;
01774 }
01775 done:
01776
01777
if (err ||
01778 ds->month < 1 || ds->month > 12 ||
01779 ds->day < 1 || ds->day >
getmdays(ds->year, ds->month)) {
01780
return -1;
01781 }
01782
return 0;
01783 }
01784
01795
static int
01796 str2time(
char *str, TIME_STRUCT *ts)
01797 {
01798
int i, err = 0;
01799
char *p, *q;
01800
01801 ts->hour = ts->minute = ts->second = 0;
01802 p = str;
01803
while (*p && !
ISDIGIT(*p)) {
01804 ++p;
01805 }
01806 q = p;
01807 i = 0;
01808
while (*q &&
ISDIGIT(*q)) {
01809 ++i;
01810 ++q;
01811 }
01812
if (i >= 6) {
01813
char buf[4];
01814
01815 strncpy(buf, p + 0, 2); buf[2] =
'\0';
01816 ts->hour = strtol(buf, NULL, 10);
01817 strncpy(buf, p + 2, 2); buf[2] =
'\0';
01818 ts->minute = strtol(buf, NULL, 10);
01819 strncpy(buf, p + 4, 2); buf[2] =
'\0';
01820 ts->second = strtol(buf, NULL, 10);
01821
goto done;
01822 }
01823 i = 0;
01824
while (i < 3) {
01825
int n;
01826
01827 q = NULL;
01828 n = strtol(p, &q, 10);
01829
if (!q || q == p) {
01830
if (*q ==
'\0') {
01831
if (i == 0) {
01832 err = 1;
01833 }
01834
goto done;
01835 }
01836 }
01837
if (*q ==
':' || *q ==
'\0' || i == 2) {
01838
switch (i) {
01839
case 0: ts->hour = n;
break;
01840
case 1: ts->minute = n;
break;
01841
case 2: ts->second = n;
break;
01842 }
01843 ++i;
01844
if (*q) {
01845 ++q;
01846 }
01847 }
else {
01848 i = 0;
01849
while (*q && !
ISDIGIT(*q)) {
01850 ++q;
01851 }
01852 }
01853 p = q;
01854 }
01855 done:
01856
01857
if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
01858
return -1;
01859 }
01860
return 0;
01861 }
01862
01878
static int
01879 str2timestamp(
char *str, TIMESTAMP_STRUCT *tss)
01880 {
01881
int i, m, n, err = 0;
01882
char *p, *q, in =
'\0';
01883
01884 tss->year = tss->month = tss->day = 0;
01885 tss->hour = tss->minute = tss->second = 0;
01886 tss->fraction = 0;
01887 p = str;
01888
while (*p && !
ISDIGIT(*p)) {
01889 ++p;
01890 }
01891 q = p;
01892 i = 0;
01893
while (*q &&
ISDIGIT(*q)) {
01894 ++i;
01895 ++q;
01896 }
01897
if (i >= 14) {
01898
char buf[16];
01899
01900 strncpy(buf, p + 0, 4); buf[4] =
'\0';
01901 tss->year = strtol(buf, NULL, 10);
01902 strncpy(buf, p + 4, 2); buf[2] =
'\0';
01903 tss->month = strtol(buf, NULL, 10);
01904 strncpy(buf, p + 6, 2); buf[2] =
'\0';
01905 tss->day = strtol(buf, NULL, 10);
01906 strncpy(buf, p + 8, 2); buf[2] =
'\0';
01907 tss->hour = strtol(buf, NULL, 10);
01908 strncpy(buf, p + 10, 2); buf[2] =
'\0';
01909 tss->minute = strtol(buf, NULL, 10);
01910 strncpy(buf, p + 12, 2); buf[2] =
'\0';
01911 tss->second = strtol(buf, NULL, 10);
01912
if (i > 14) {
01913 m = i - 14;
01914 strncpy(buf, p + 14, m);
01915
while (m < 9) {
01916 buf[m] =
'0';
01917 ++m;
01918 }
01919 buf[m] =
'\0';
01920 tss->fraction = strtol(buf, NULL, 0);
01921 }
01922 m = 7;
01923
goto done;
01924 }
01925 m = i = 0;
01926
while ((m & 7) != 7) {
01927 q = NULL;
01928 n = strtol(p, &q, 10);
01929
if (!q || q == p) {
01930
if (*q ==
'\0') {
01931
if (m < 1) {
01932 err = 1;
01933 }
01934
goto done;
01935 }
01936 }
01937
if (in ==
'\0') {
01938
switch (*q) {
01939
case '-':
01940
case '/':
01941
if ((m & 1) == 0) {
01942 in = *q;
01943 i = 0;
01944 }
01945
break;
01946
case ':':
01947
if ((m & 2) == 0) {
01948 in = *q;
01949 i = 0;
01950 }
01951
break;
01952
case ' ':
01953
case '.':
01954
break;
01955
default:
01956 in =
'\0';
01957 i = 0;
01958
break;
01959 }
01960 }
01961
switch (in) {
01962
case '-':
01963
case '/':
01964
switch (i) {
01965
case 0: tss->year = n;
break;
01966
case 1: tss->month = n;
break;
01967
case 2: tss->day = n;
break;
01968 }
01969
if (++i >= 3) {
01970 i = 0;
01971 m |= 1;
01972
if (!(m & 2)) {
01973 m |= 8;
01974 }
01975
goto skip;
01976 }
else {
01977 ++q;
01978 }
01979
break;
01980
case ':':
01981
switch (i) {
01982
case 0: tss->hour = n;
break;
01983
case 1: tss->minute = n;
break;
01984
case 2: tss->second = n;
break;
01985 }
01986
if (++i >= 3) {
01987 i = 0;
01988 m |= 2;
01989
if (*q ==
'.') {
01990 in =
'.';
01991
goto skip2;
01992 }
01993
if (*q ==
' ') {
01994
if ((m & 1) == 0) {
01995
char *e = NULL;
01996
01997 strtol(q + 1, &e, 10);
01998
if (e && *e ==
'-') {
01999
goto skip;
02000 }
02001 }
02002 in =
'.';
02003
goto skip2;
02004 }
02005
goto skip;
02006 }
else {
02007 ++q;
02008 }
02009
break;
02010
case '.':
02011
if (++i >= 1) {
02012
int ndig = q - p;
02013
02014
if (p[0] ==
'+' || p[0] ==
'-') {
02015 ndig--;
02016 }
02017
while (ndig < 9) {
02018 n = n * 10;
02019 ++ndig;
02020 }
02021 tss->fraction = n;
02022 m |= 4;
02023 i = 0;
02024 }
02025
default:
02026 skip:
02027 in =
'\0';
02028 skip2:
02029
while (*q && !
ISDIGIT(*q)) {
02030 ++q;
02031 }
02032 }
02033 p = q;
02034 }
02035
if ((m & 7) > 1 && (m & 8)) {
02036
02037
if (p > str &&
ISDIGIT(*p)) {
02038
int nn, sign;
02039
02040 q = p - 1;
02041
if (*q !=
'+' && *q !=
'-') {
02042
goto done;
02043 }
02044 sign = *q ==
'+' ? -1 : 1;
02045 q = NULL;
02046 n = strtol(p, &q, 10);
02047
if (!q || *q++ !=
':' || !
ISDIGIT(*q)) {
02048
goto done;
02049 }
02050 p = q;
02051 q = NULL;
02052 nn = strtol(p, &q, 0);
02053 tss->minute += nn * sign;
02054
if ((SQLSMALLINT) tss->minute < 0) {
02055 tss->hour -= 1;
02056 tss->minute += 60;
02057 }
else if (tss->minute >= 60) {
02058 tss->hour += 1;
02059 tss->minute -= 60;
02060 }
02061 tss->hour += n * sign;
02062
if ((SQLSMALLINT) tss->hour < 0) {
02063 tss->day -= 1;
02064 tss->hour += 24;
02065 }
else if (tss->hour >= 24) {
02066 tss->day += 1;
02067 tss->hour -= 24;
02068 }
02069
if ((
short) tss->day < 1 || tss->day >= 28) {
02070
int mday, pday, pmon;
02071
02072 mday =
getmdays(tss->year, tss->month);
02073 pmon = tss->month - 1;
02074
if (pmon < 1) {
02075 pmon = 12;
02076 }
02077 pday =
getmdays(tss->year, pmon);
02078
if ((SQLSMALLINT) tss->day < 1) {
02079 tss->month -= 1;
02080 tss->day = pday;
02081 }
else if (tss->day > mday) {
02082 tss->month += 1;
02083 tss->day = 1;
02084 }
02085
if ((SQLSMALLINT) tss->month < 1) {
02086 tss->year -= 1;
02087 tss->month = 12;
02088 }
else if (tss->month > 12) {
02089 tss->year += 1;
02090 tss->month = 1;
02091 }
02092 }
02093 }
02094 }
02095 done:
02096
02097
if (err ||
02098 tss->month < 1 || tss->month > 12 ||
02099 tss->day < 1 || tss->day >
getmdays(tss->year, tss->month) ||
02100 tss->hour > 23 || tss->minute > 60 || tss->second > 60) {
02101
return -1;
02102 }
02103
return (m & 7) < 1 ? -1 : 0;
02104 }
02105
02112
static int
02113 getbool(
char *string)
02114 {
02115
if (string) {
02116
return string[0] && strchr(
"Yy123456789Tt", string[0]) != NULL;
02117 }
02118
return 0;
02119 }
02120
02121
#if defined(HAVE_SQLITETRACE) && HAVE_SQLITETRACE
02122
02127
static void
02128 dbtrace(
void *arg,
const char *msg)
02129 {
02130
DBC *d = (
DBC *) arg;
02131
02132
if (msg && d->trace) {
02133
int len = strlen(msg);
02134
02135
if (len > 0) {
02136
char *end =
"\n";
02137
02138
if (msg[len - 1] !=
';') {
02139 end =
";\n";
02140 }
02141 fprintf(d->trace,
"%s%s", msg, end);
02142 fflush(d->trace);
02143 }
02144 }
02145 }
02146
02153
static void
02154
dbtracerc(
DBC *d,
int rc,
char *err)
02155 {
02156
if (rc != SQLITE_OK && d->trace) {
02157 fprintf(d->trace,
"-- SQLITE ERROR CODE %d", rc);
02158 fprintf(d->trace, err ?
": %s\n" :
"\n", err);
02159 fflush(d->trace);
02160 }
02161 }
02162
#else
02163
02164 #define dbtracerc(a,b,c)
02165
02166
#endif
02167
02178
static SQLRETURN
02179 dbopen(
DBC *d,
char *name,
char *dsn,
char *sflag,
char *busy)
02180 {
02181
char *errp = NULL, *endp = NULL;
02182
int tmp, busyto = 1000;
02183
02184
if (d->
sqlite) {
02185 sqlite_close(d->
sqlite);
02186 d->
sqlite = NULL;
02187 }
02188 d->
sqlite = sqlite_open(name, 0, &errp);
02189
if (d->
sqlite == NULL) {
02190 connfail:
02191
setstatd(d, -1, errp ? errp :
"connect failed",
02192 (*d->
ov3) ?
"HY000" :
"S1000");
02193
if (errp) {
02194 sqlite_freemem(errp);
02195 errp = NULL;
02196 }
02197
return SQL_ERROR;
02198 }
02199
if (errp) {
02200 sqlite_freemem(errp);
02201 errp = NULL;
02202 }
02203
#if defined(HAVE_SQLITETRACE) && HAVE_SQLITETRACE
02204
if (d->trace) {
02205 sqlite_trace(d->
sqlite, dbtrace, d);
02206 }
02207
#endif
02208
d->
step_enable =
getbool(sflag);
02209 d->
curtype = d->
step_enable ?
02210 SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
02211 tmp = strtol(busy, &endp, 0);
02212
if (endp && *endp ==
'\0' && endp != busy) {
02213 busyto = tmp;
02214 }
02215
if (busyto < 1 || busyto > 1000000) {
02216 busyto = 1000000;
02217 }
02218 d->
timeout = busyto;
02219
if (
setsqliteopts(d->
sqlite, d) != SQLITE_OK) {
02220 sqlite_close(d->
sqlite);
02221 d->
sqlite = NULL;
02222
goto connfail;
02223 }
02224
freep(&d->
dbname);
02225 d->
dbname =
xstrdup(name);
02226
freep(&d->
dsn);
02227 d->
dsn =
xstrdup(dsn);
02228
return SQL_SUCCESS;
02229 }
02230
02237
static int
02238 vm_step(
STMT *s)
02239 {
02240
DBC *d = (
DBC *) s->
dbc;
02241
char **rowd = NULL, *errp = NULL;
02242
const char **values, **cols;
02243
int i, ncols, rc;
02244
02245
if (s != d->
vm_stmt || !s->
vm) {
02246
setstat(s, -1,
"stale statement", (*s->
ov3) ?
"HY000" :
"S1000");
02247
return SQL_ERROR;
02248 }
02249 rc = sqlite_step(s->
vm, &ncols, &values, &cols);
02250
if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
02251 ++d->
vm_rownum;
02252
if (d->
vm_rownum == 0 && cols && ncols > 0) {
02253
int size;
02254
char *p;
02255
COL *dyncols;
02256
02257
for (i = size = 0; i < ncols; i++) {
02258 size += 3 + 3 * strlen(cols[i]);
02259 }
02260 dyncols =
xmalloc(ncols *
sizeof (
COL) + size);
02261
if (!dyncols) {
02262
freedyncols(s);
02263 s->
ncols = 0;
02264 sqlite_finalize(s->
vm, NULL);
02265 s->
vm = NULL;
02266 d->
vm_stmt = NULL;
02267
return nomem(s);
02268 }
02269 p = (
char *) (dyncols + ncols);
02270
for (i = 0; i < ncols; i++) {
02271
char *q;
02272
02273 dyncols[i].
db = ((
DBC *) (s->
dbc))->dbname;
02274 strcpy(p, cols[i]);
02275 dyncols[i].
label = p;
02276 p += strlen(p) + 1;
02277 q = strchr(cols[i],
'.');
02278
if (q) {
02279 dyncols[i].
table = p;
02280 strncpy(p, cols[i], q - cols[i]);
02281 p[q - cols[i]] =
'\0';
02282 p += strlen(p) + 1;
02283 strcpy(p, q + 1);
02284 dyncols[i].
column = p;
02285 p += strlen(p) + 1;
02286 }
else {
02287 dyncols[i].
table =
"";
02288 strcpy(p, cols[i]);
02289 dyncols[i].
column = p;
02290 p += strlen(p) + 1;
02291 }
02292
#ifdef SQL_LONGVARCHAR
02293
dyncols[i].
type = SQL_LONGVARCHAR;
02294 dyncols[i].
size = 65536;
02295
#else
02296
dyncols[i].
type = SQL_VARCHAR;
02297 dyncols[i].
size = 255;
02298
#endif
02299
dyncols[i].
index = i;
02300 dyncols[i].
scale = 0;
02301 dyncols[i].
prec = 0;
02302 dyncols[i].
nosign = 1;
02303 dyncols[i].
autoinc = -1;
02304 dyncols[i].
typename = NULL;
02305 }
02306
freedyncols(s);
02307 s->
ncols = s->
dcols = ncols;
02308 s->
dyncols = s->
cols = dyncols;
02309
fixupdyncols(s, d->
sqlite, cols + ncols);
02310
mkbindcols(s, s->
ncols);
02311 }
02312
if (!cols || ncols <= 0) {
02313
goto killvm;
02314 }
02315
if (!values) {
02316
if (rc == SQLITE_DONE) {
02317
freeresult(s, 0);
02318 s->
nrows = 0;
02319 sqlite_finalize(s->
vm, NULL);
02320 s->
vm = NULL;
02321 d->
vm_stmt = NULL;
02322
return SQL_SUCCESS;
02323 }
02324
goto killvm;
02325 }
02326 rowd =
xmalloc((1 + 2 * ncols) *
sizeof (
char *));
02327
if (rowd) {
02328 rowd[0] = (
char *) (ncols * 2);
02329 ++rowd;
02330
for (i = 0; i < ncols; i++) {
02331 rowd[i] = NULL;
02332 rowd[i + ncols] =
xstrdup(values[i]);
02333 }
02334
for (i = 0; i < ncols; i++) {
02335
if (values[i] && !rowd[i + ncols]) {
02336
freerows(rowd);
02337 rowd = 0;
02338
break;
02339 }
02340 }
02341 }
02342
if (rowd) {
02343
freeresult(s, 0);
02344 s->
nrows = 1;
02345 s->
rows = rowd;
02346
if (rc == SQLITE_DONE) {
02347 sqlite_finalize(s->
vm, NULL);
02348 s->
vm = NULL;
02349 d->
vm_stmt = NULL;
02350 }
02351
return SQL_SUCCESS;
02352 }
02353 }
02354 killvm:
02355 sqlite_finalize(s->
vm, &errp);
02356 s->
vm = NULL;
02357 d->
vm_stmt = NULL;
02358
setstat(s, rc,
"%s (%d)", (*s->
ov3) ?
"HY000" :
"S1000",
02359 errp ? errp :
"unknown error", rc);
02360
if (errp) {
02361 sqlite_freemem(errp);
02362 errp = NULL;
02363 }
02364
return SQL_ERROR;
02365 }
02366
02372
static void
02373 vm_end(
STMT *s)
02374 {
02375
DBC *d;
02376
02377
if (!s || !s->
vm) {
02378
return;
02379 }
02380 d = (
DBC *) s->
dbc;
02381 sqlite_finalize(s->
vm, NULL);
02382 s->
vm = NULL;
02383 d->
vm_stmt = NULL;
02384 }
02385
02391
static void
02392 vm_end_if(
STMT *s)
02393 {
02394
DBC *d = (
DBC *) s->
dbc;
02395
02396
if (d && d->
vm_stmt == s) {
02397
vm_end(s);
02398 }
02399 }
02400
02408
static SQLRETURN
02409 vm_start(
STMT *s,
char **params)
02410 {
02411
DBC *d = (
DBC *) s->
dbc;
02412
char *errp = NULL, *sql = NULL;
02413
const char *endp;
02414 sqlite_vm *vm;
02415
int rc;
02416
02417 sql = sqlite_vmprintf(s->
query, (
char *) params);
02418
if (!sql) {
02419
return nomem(s);
02420 }
02421 rc = sqlite_compile(d->
sqlite, sql, &endp, &vm, &errp);
02422
dbtracerc(d, rc, errp);
02423 sqlite_freemem(sql);
02424
if (rc != SQLITE_OK) {
02425
setstat(s, rc,
"%s (%d)", (*s->
ov3) ?
"HY000" :
"S1000",
02426 errp ? errp :
"unknown error", rc);
02427
if (errp) {
02428 sqlite_freemem(errp);
02429 errp = NULL;
02430 }
02431
return SQL_ERROR;
02432 }
02433 s->
vm = vm;
02434 d->
vm_stmt = s;
02435 d->
vm_rownum = -1;
02436
return SQL_SUCCESS;
02437 }
02438
02443 SQLRETURN SQL_API
02444 SQLBulkOperations(SQLHSTMT
stmt, SQLSMALLINT oper)
02445 {
02446
return drvunimplstmt(stmt);
02447 }
02448
02449
#ifndef SQLITE_UTF8
02450
02454 SQLRETURN SQL_API
02455 SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
02456 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
02457 SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
02458 {
02459
if (env == SQL_NULL_HENV) {
02460
return SQL_INVALID_HANDLE;
02461 }
02462
return SQL_ERROR;
02463 }
02464
#endif
02465
02466
#ifdef SQLITE_UTF8
02467
02471 SQLRETURN SQL_API
02472 SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
02473 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
02474 SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
02475 {
02476
if (env == SQL_NULL_HENV) {
02477
return SQL_INVALID_HANDLE;
02478 }
02479
return SQL_ERROR;
02480 }
02481
#endif
02482
02483
#ifndef SQLITE_UTF8
02484
02488 SQLRETURN SQL_API
02489 SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
02490 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
02491 SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
02492 {
02493
if (env == SQL_NULL_HENV) {
02494
return SQL_INVALID_HANDLE;
02495 }
02496
return SQL_ERROR;
02497 }
02498
#endif
02499
02500
#ifdef SQLITE_UTF8
02501
02505 SQLRETURN SQL_API
02506 SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
02507 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
02508 SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
02509 {
02510
if (env == SQL_NULL_HENV) {
02511
return SQL_INVALID_HANDLE;
02512 }
02513
return SQL_ERROR;
02514 }
02515
#endif
02516
02517
#ifndef SQLITE_UTF8
02518
02522 SQLRETURN SQL_API
02523 SQLBrowseConnect(SQLHDBC
dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
02524 SQLCHAR *connout, SQLSMALLINT connoutMax,
02525 SQLSMALLINT *connoutLen)
02526 {
02527
return drvunimpldbc(dbc);
02528 }
02529
#endif
02530
02531
#ifdef SQLITE_UTF8
02532
02536 SQLRETURN SQL_API
02537 SQLBrowseConnectW(SQLHDBC
dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
02538 SQLWCHAR *connout, SQLSMALLINT connoutMax,
02539 SQLSMALLINT *connoutLen)
02540 {
02541
return drvunimpldbc(dbc);
02542 }
02543
#endif
02544
02552
static void
02553 time_func(sqlite_func *context,
int argc,
const char **argv)
02554 {
02555
char buf[128];
02556
int what = (
int) sqlite_user_data(context);
02557
#ifdef _WIN32
02558
SYSTEMTIME st;
02559
02560
if (what & 1) {
02561 GetSystemTime(&st);
02562 }
else {
02563 GetLocalTime(&st);
02564 }
02565
if (what & 4) {
02566 sprintf(buf,
"%04d-%02d-%02d %02d:%02d:%02d",
02567 st.wYear, st.wMonth, st.wDay,
02568 st.wHour, st.wMinute, st.wSecond);
02569 }
else if (what & 2) {
02570 sprintf(buf,
"%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
02571 }
else {
02572 sprintf(buf,
"%02d:%02d:%02d", st.wHour, st.wMinute, st.wSecond);
02573 }
02574
#else
02575
time_t t;
02576
struct tm tm;
02577
02578 time(&t);
02579
if (what & 1) {
02580
#ifdef HAVE_GMTIME_R
02581
gmtime_r(&t, &tm);
02582
#else
02583
tm = *gmtime(&t);
02584
#endif
02585
}
else {
02586
#ifdef HAVE_LOCALTIME_R
02587
localtime_r(&t, &tm);
02588
#else
02589
tm = *localtime(&t);
02590
#endif
02591
}
02592
if (what & 4) {
02593 sprintf(buf,
"%04d-%02d-%02d %02d:%02d:%02d",
02594 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
02595 tm.tm_hour, tm.tm_min, tm.tm_sec);
02596 }
else if (what & 2) {
02597 sprintf(buf,
"%04d-%02d-%02d",
02598 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
02599 }
else {
02600 sprintf(buf,
"%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);
02601 }
02602
#endif
02603
sqlite_set_result_string(context, buf, -1);
02604 }
02605
02606
#if HAVE_ENCDEC
02607
static const char hexdigits[] =
"0123456789ABCDEFabcdef";
02608
02616
static void
02617 hextobin_func(sqlite_func *context,
int argc,
const char **argv)
02618 {
02619
int i, len;
02620
char *bin, *p;
02621
02622
if (argc < 1) {
02623
return;
02624 }
02625
if (!argv[0]) {
02626 sqlite_set_result_string(context,
"NULL", 4);
02627
return;
02628 }
02629 len = strlen(argv[0]) / 2;
02630 bin =
xmalloc(len + 1);
02631
if (!bin) {
02632 oom:
02633 sqlite_set_result_error(context,
"out of memory", -1);
02634
return;
02635 }
02636
if (len <= 0) {
02637 sqlite_set_result_string(context, bin, 0);
02638
freep(&bin);
02639
return;
02640 }
02641
for (i = 0, p = (
char *) argv[0]; i < len; i++) {
02642
char *x;
02643
int v;
02644
02645
if (!*p || !(x = strchr(hexdigits, *p))) {
02646
goto converr;
02647 }
02648 v = x - hexdigits;
02649 bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
02650 ++p;
02651
if (!*p || !(x = strchr(hexdigits, *p))) {
02652 converr:
02653
freep(&bin);
02654 sqlite_set_result_error(context,
"conversion error", -1);
02655
return;
02656 }
02657 v = x - hexdigits;
02658 bin[i] |= (v >= 16) ? (v - 6) : v;
02659 ++p;
02660 }
02661 i = sqlite_encode_binary(bin, len, 0);
02662 p =
xmalloc(i + 1);
02663
if (!p) {
02664
freep(&bin);
02665
goto oom;
02666 }
02667 i = sqlite_encode_binary(bin, len, p);
02668 sqlite_set_result_string(context, p, i);
02669
freep(&bin);
02670
freep(&p);
02671 }
02672
02680
static void
02681 bintohex_func(sqlite_func *context,
int argc,
const char **argv)
02682 {
02683
int i, k, len;
02684
char *bin, *p;
02685
02686
if (argc < 1) {
02687
return;
02688 }
02689
if (!argv[0]) {
02690 empty:
02691 sqlite_set_result_string(context,
"", 0);
02692
return;
02693 }
02694 bin =
xmalloc(strlen(argv[0]) + 1);
02695
if (!bin) {
02696 oom:
02697 sqlite_set_result_error(context,
"out of memory", -1);
02698
return;
02699 }
02700 len = sqlite_decode_binary(argv[0], bin);
02701
if (len < 0) {
02702
freep(&bin);
02703 sqlite_set_result_error(context,
"error decoding binary data", -1);
02704
return;
02705 }
02706
if (len == 0) {
02707
goto empty;
02708 }
02709 p =
xmalloc(len * 2 + 1);
02710
if (!p) {
02711
goto oom;
02712 }
02713
for (i = 0, k = 0; i < len; i++) {
02714 p[k++] = hexdigits[(bin[i] >> 4) & 0x0f];
02715 p[k++] = hexdigits[bin[i] & 0x0f];
02716 }
02717 p[k] =
'\0';
02718 sqlite_set_result_string(context, p, k);
02719
freep(&bin);
02720
freep(&p);
02721 }
02722
02730
static SQLRETURN
02731 hextobin(
STMT *s,
BINDPARM *p)
02732 {
02733
int i, len = strlen(p->
param) / 2;
02734
char *bin =
xmalloc(len + 1), *pp;
02735
02736
if (!bin) {
02737
return nomem(s);
02738 }
02739
if (len <= 0) {
02740 bin[0] =
'\0';
02741
if (p->
param == p->
ind) {
02742
freep(&p->
param);
02743 }
02744 p->
param = p->
ind = bin;
02745 p->
len = 0;
02746
return SQL_SUCCESS;
02747 }
02748
for (i = 0, pp = (
char *) p->
param; i < len; i++) {
02749
char *x;
02750
int v;
02751
02752
if (!*pp || !(x = strchr(hexdigits, *pp))) {
02753
goto converr;
02754 }
02755 v = x - hexdigits;
02756 bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
02757 ++pp;
02758
if (!*pp || !(x = strchr(hexdigits, *pp))) {
02759 converr:
02760
freep(&bin);
02761
setstat(s, -1,
"conversion error", (*s->
ov3) ?
"HY000" :
"S1000");
02762
return SQL_ERROR;
02763 }
02764 v = x - hexdigits;
02765 bin[i] |= (v >= 16) ? (v - 6) : v;
02766 ++pp;
02767 }
02768 i = sqlite_encode_binary(bin, len, 0);
02769 pp =
xmalloc(i + 1);
02770
if (!pp) {
02771
freep(&bin);
02772
return nomem(s);
02773 }
02774 p->
len = sqlite_encode_binary(bin, len, pp);
02775
if (p->
param == p->
ind) {
02776
freep(&p->
param);
02777 }
02778 p->
param = p->
ind = pp;
02779
freep(&bin);
02780
return SQL_SUCCESS;
02781 }
02782
#endif
02783
02792 SQLRETURN SQL_API
02793 SQLPutData(SQLHSTMT
stmt, SQLPOINTER data, SQLINTEGER len)
02794 {
02795
STMT *s;
02796
int i, dlen, done = 0;
02797
BINDPARM *p;
02798
02799
if (stmt == SQL_NULL_HSTMT) {
02800
return SQL_INVALID_HANDLE;
02801 }
02802 s = (
STMT *) stmt;
02803
if (!s->
query || s->
nparams <= 0) {
02804 seqerr:
02805
setstat(s, -1,
"sequence error",
"HY010");
02806
return SQL_ERROR;
02807 }
02808
for (i = 0; i < s->
nparams; i++) {
02809 p = &s->
bindparms[i];
02810
if (p->
need) {
02811
int type =
mapdeftype(p->
type, p->
stype, -1, s->
nowchar);
02812
02813
if (len == SQL_NULL_DATA) {
02814
freep(&p->
param);
02815 p->
ind = &p->
len;
02816 p->
len = SQL_NULL_DATA;
02817 p->
need = 0;
02818 }
else
02819
#if HAVE_ENCDEC
02820
if (type == SQL_C_BINARY) {
02821
if (len <= 0) {
02822
setstat(s, -1,
"invalid length",
"HY090");
02823
return SQL_ERROR;
02824 }
02825
goto putd;
02826 }
else
02827
#endif
02828
#ifdef SQLITE_UTF8
02829
if (type != SQL_C_CHAR && type != SQL_C_WCHAR)
02830
#else
02831
if (type != SQL_C_CHAR)
02832
#endif
02833
{
02834
int size = 0;
02835
02836
switch (type) {
02837
case SQL_C_TINYINT:
02838
case SQL_C_UTINYINT:
02839
case SQL_C_STINYINT:
02840 size =
sizeof (
char);
02841
break;
02842
case SQL_C_SHORT:
02843
case SQL_C_USHORT:
02844
case SQL_C_SSHORT:
02845 size =
sizeof (
short);
02846
break;
02847
case SQL_C_LONG:
02848
case SQL_C_ULONG:
02849
case SQL_C_SLONG:
02850 size =
sizeof (
long);
02851
break;
02852
case SQL_C_FLOAT:
02853 size =
sizeof (
float);
02854
break;
02855
case SQL_C_DOUBLE:
02856 size =
sizeof (
double);
02857
break;
02858
#ifdef SQL_C_TYPE_DATE
02859
case SQL_C_TYPE_DATE:
02860
#endif
02861
case SQL_C_DATE:
02862 size =
sizeof (DATE_STRUCT);
02863
break;
02864
#ifdef SQL_C_TYPE_DATE
02865
case SQL_C_TYPE_TIME:
02866
#endif
02867
case SQL_C_TIME:
02868 size =
sizeof (TIME_STRUCT);
02869
break;
02870
#ifdef SQL_C_TYPE_DATE
02871
case SQL_C_TYPE_TIMESTAMP:
02872
#endif
02873
case SQL_C_TIMESTAMP:
02874 size =
sizeof (TIMESTAMP_STRUCT);
02875
break;
02876 }
02877
freep(&p->
param);
02878 p->
param =
xmalloc(size);
02879
if (!p->
param) {
02880
return nomem(s);
02881 }
02882 memcpy(p->
param, data, size);
02883 p->
len = size;
02884 p->
need = 0;
02885 }
else if (len == SQL_NTS) {
02886
char *dp = data;
02887
02888
#ifdef SQLITE_UTF8
02889
if (p->
type == SQL_C_WCHAR) {
02890 dp = uc_to_utf(data, len);
02891
if (!dp) {
02892
return nomem(s);
02893 }
02894 }
02895
#endif
02896
dlen = strlen(dp);
02897
freep(&p->
param);
02898 p->
param =
xmalloc(dlen + 1);
02899
if (!p->
param) {
02900
#ifdef SQLITE_UTF8
02901
if (dp != data) {
02902 uc_free(dp);
02903 }
02904
#endif
02905
return nomem(s);
02906 }
02907 strcpy(p->
param, dp);
02908
#ifdef SQLITE_UTF8
02909
if (dp != data) {
02910 uc_free(dp);
02911 }
02912
#endif
02913
p->
len = dlen;
02914 p->
need = 0;
02915 }
else if (len <= 0) {
02916
setstat(s, -1,
"invalid length",
"HY090");
02917
return SQL_ERROR;
02918 }
else {
02919
#if HAVE_ENCDEC
02920
putd:
02921
#endif
02922
dlen =
min(p->
len - p->
offs, len);
02923
if (!p->
param) {
02924
setstat(s, -1,
"no memory for parameter",
"HY013");
02925
return SQL_ERROR;
02926 }
02927 memcpy((
char *) p->
param + p->
offs, data, dlen);
02928 p->
offs += dlen;
02929
if (p->
offs >= p->
len) {
02930
#ifdef SQLITE_UTF8
02931
if (p->
type == SQL_C_WCHAR) {
02932
char *dp = uc_to_utf(p->
param, p->
len);
02933
char *np;
02934
int nlen;
02935
02936
if (!dp) {
02937
return nomem(s);
02938 }
02939 nlen = strlen(dp);
02940 np =
xmalloc(nlen + 1);
02941
if (!np) {
02942 uc_free(dp);
02943
return nomem(s);
02944 }
02945 strcpy(np, dp);
02946 uc_free(dp);
02947
freep(&p->
param);
02948 p->
param = p->
ind = np;
02949 p->
len = nlen;
02950 }
else {
02951 *((
char *) p->
param + p->
len) =
'\0';
02952 }
02953
#else
02954
*((
char *) p->
param + p->
len) =
'\0';
02955
#endif
02956
#if HAVE_ENCDEC
02957
if ((p->
stype == SQL_BINARY ||
02958 p->
stype == SQL_VARBINARY ||
02959 p->
stype == SQL_LONGVARBINARY) &&
02960
#ifdef SQLITE_UTF8
02961
(type == SQL_C_CHAR || type == SQL_C_WCHAR)
02962
#else
02963
type == SQL_C_CHAR
02964
#endif
02965
) {
02966
if (hextobin(s, p) != SQL_SUCCESS) {
02967
return SQL_ERROR;
02968 }
02969 }
else if (type == SQL_C_BINARY) {
02970
int bsize;
02971
char *bin;
02972
02973 bsize = sqlite_encode_binary(p->
param, p->
len, 0);
02974 bin =
xmalloc(bsize + 1);
02975
if (!bin) {
02976
return nomem(s);
02977 }
02978 p->
len = sqlite_encode_binary(p->
param, p->
len, bin);
02979
freep(&p->
param);
02980 p->
param = p->
ind = bin;
02981 }
02982
#endif
02983
p->
need = 0;
02984 }
02985 }
02986 done = 1;
02987
break;
02988 }
02989 }
02990
if (!done) {
02991
goto seqerr;
02992 }
02993
for (i = 0; i < s->
nparams; i++) {
02994 p = &s->
bindparms[i];
02995
if (p->
need) {
02996
return SQL_NEED_DATA;
02997 }
02998 }
02999
return drvexecute(stmt);
03000 }
03001
03007
static SQLRETURN
03008 freeparams(
STMT *s)
03009 {
03010
if (s->
bindparms) {
03011
int n;
03012
03013
for (n = 0; n < s->
nbindparms; n++) {
03014
if (s->
bindparms[n].
ind && s->
bindparms[n].
param) {
03015
freep(&s->
bindparms[n].
param);
03016 }
03017 memset(&s->
bindparms[n], 0, sizeof (
BINDPARM));
03018 }
03019 }
03020
return SQL_SUCCESS;
03021 }
03022
03023
03024
03025
static SQLRETURN
03026 substparam(
STMT *s,
int pnum,
char **out,
int *size)
03027 {
03028
char buf[256];
03029
int type, len = 0;
03030
BINDPARM *p;
03031
double dval;
03032
03033
if (!s->
bindparms || pnum < 0 || pnum >= s->
nbindparms) {
03034
goto error;
03035 }
03036 p = &s->
bindparms[pnum];
03037 type =
mapdeftype(p->
type, p->
stype, -1, s->
nowchar);
03038
if (p->
need) {
03039
if (!p->
param) {
03040 p->
len = SQL_LEN_DATA_AT_EXEC(*p->
lenp);
03041
if (p->
len <= 0 && p->
len != SQL_NTS && p->
len != SQL_NULL_DATA) {
03042
setstat(s, -1,
"invalid length",
"HY009");
03043
return SQL_ERROR;
03044 }
03045
if (p->
len > 0) {
03046 p->
param =
xmalloc(p->
len + 1);
03047
if (!p->
param) {
03048
return nomem(s);
03049 }
03050 }
03051 }
03052
return SQL_NEED_DATA;
03053 }
03054
if (!p->
param || (p->
lenp && *p->
lenp == SQL_NULL_DATA)) {
03055 strcpy(buf,
"NULL");
03056
goto bind;
03057 }
03058
switch (type) {
03059
case SQL_C_CHAR:
03060
#ifdef SQLITE_UTF8
03061
case SQL_C_WCHAR:
03062
#endif
03063
#if HAVE_ENCDEC
03064
case SQL_C_BINARY:
03065
#endif
03066
break;
03067
case SQL_C_UTINYINT:
03068 sprintf(buf,
"%d", *((
unsigned char *) p->
param));
03069
goto bind;
03070
case SQL_C_TINYINT:
03071
case SQL_C_STINYINT:
03072 sprintf(buf,
"%d", *((
char *) p->
param));
03073
goto bind;
03074
case SQL_C_USHORT:
03075 sprintf(buf,
"%d", *((
unsigned short *) p->
param));
03076
goto bind;
03077
case SQL_C_SHORT:
03078
case SQL_C_SSHORT:
03079 sprintf(buf,
"%d", *((
short *) p->
param));
03080
goto bind;
03081
case SQL_C_ULONG:
03082
case SQL_C_LONG:
03083
case SQL_C_SLONG:
03084 sprintf(buf,
"%ld", *((
long *) p->
param));
03085
goto bind;
03086
case SQL_C_FLOAT:
03087 dval = *((
float *) p->
param);
03088
goto dodouble;
03089
case SQL_C_DOUBLE:
03090 dval = *((
double *) p->
param);
03091 dodouble:
03092
#if defined(HAVE_SQLITEMPRINTF) && HAVE_SQLITEMPRINTF
03093
{
03094
char *buf2 = sqlite_mprintf(
"%.16g", dval);
03095
03096
if (buf2) {
03097 strcpy(buf, buf2);
03098 sqlite_freemem(buf2);
03099 }
else {
03100 strcpy(buf,
"NULL");
03101 }
03102 }
03103
#else
03104
ln_sprintfg(buf, dval);
03105
#endif
03106
goto bind;
03107
#ifdef SQL_C_TYPE_DATE
03108
case SQL_C_TYPE_DATE:
03109
#endif
03110
case SQL_C_DATE:
03111 sprintf(buf,
"%04d-%02d-%02d",
03112 ((DATE_STRUCT *) p->
param)->year,
03113 ((DATE_STRUCT *) p->
param)->month,
03114 ((DATE_STRUCT *) p->
param)->day);
03115
goto bind;
03116
#ifdef SQL_C_TYPE_TIME
03117
case SQL_C_TYPE_TIME:
03118
#endif
03119
case SQL_C_TIME:
03120 sprintf(buf,
"%02d:%02d:%02d",
03121 ((TIME_STRUCT *) p->
param)->hour,
03122 ((TIME_STRUCT *) p->
param)->minute,
03123 ((TIME_STRUCT *) p->
param)->second);
03124
goto bind;
03125
#ifdef SQL_C_TYPE_TIMESTAMP
03126
case SQL_C_TYPE_TIMESTAMP:
03127
#endif
03128
case SQL_C_TIMESTAMP:
03129 sprintf(buf,
"%04d-%02d-%02d %02d:%02d:%02d.%d",
03130 ((TIMESTAMP_STRUCT *) p->
param)->year,
03131 ((TIMESTAMP_STRUCT *) p->
param)->month,
03132 ((TIMESTAMP_STRUCT *) p->
param)->day,
03133 ((TIMESTAMP_STRUCT *) p->
param)->hour,
03134 ((TIMESTAMP_STRUCT *) p->
param)->minute,
03135 ((TIMESTAMP_STRUCT *) p->
param)->second,
03136 (
int) ((TIMESTAMP_STRUCT *) p->
param)->fraction);
03137 bind:
03138
if (out) {
03139 strcpy(*out, buf);
03140 *out += strlen(buf) + 1;
03141 }
03142
if (size) {
03143 *size += strlen(buf) + 1;
03144 }
03145
return SQL_SUCCESS;
03146
default:
03147
goto error;
03148 }
03149
if (p->
ind) {
03150 len = p->
len;
03151 }
else if (!p->
lenp) {
03152
if (!(p->
max != SQL_NTS || p->
max == SQL_SETPARAM_VALUE_MAX)) {
03153 error:
03154
setstat(s, -1,
"invalid parameter", (*s->
ov3) ?
"07009" :
"S1093");
03155
return SQL_ERROR;
03156 }
03157 }
else {
03158 len = *p->
lenp == SQL_NTS ? strlen(p->
param) : *p->
lenp;
03159 }
03160
if (out) {
03161
if (p->
max == SQL_NTS || p->
max == SQL_SETPARAM_VALUE_MAX) {
03162 strcpy(*out, p->
param);
03163 *out += strlen(p->
param) + 1;
03164 }
else {
03165
if (len > 0) {
03166 memcpy(*out, p->
param, len);
03167 *out += len;
03168 }
03169 **out =
'\0';
03170 *out += 1;
03171 }
03172 }
03173
if (size) {
03174
if (p->
max == SQL_NTS || p->
max == SQL_SETPARAM_VALUE_MAX) {
03175 *size += strlen(p->
param) + 1;
03176 }
else {
03177 *size += len > 0 ? len + 1 : 1;
03178 }
03179 }
03180
return SQL_SUCCESS;
03181 }
03182
03198
static SQLRETURN
03199 drvbindparam(SQLHSTMT
stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
03200 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
03201 SQLSMALLINT scale,
03202 SQLPOINTER data, SQLINTEGER buflen, SQLINTEGER *len)
03203 {
03204
STMT *s;
03205
BINDPARM *p;
03206
03207
if (stmt == SQL_NULL_HSTMT) {
03208
return SQL_INVALID_HANDLE;
03209 }
03210 s = (
STMT *) stmt;
03211
if (pnum == 0) {
03212
setstat(s, -1,
"invalid parameter", (*s->
ov3) ?
"07009" :
"S1093");
03213
return SQL_ERROR;
03214 }
03215
if (!data && (!len || (*len != SQL_NULL_DATA &&
03216 *len > SQL_LEN_DATA_AT_EXEC_OFFSET))) {
03217
setstat(s, -1,
"invalid buffer",
"HY003");
03218
return SQL_ERROR;
03219 }
03220
if (len && *len < 0 && *len > SQL_LEN_DATA_AT_EXEC_OFFSET &&
03221 *len != SQL_NTS && *len != SQL_NULL_DATA) {
03222
setstat(s, -1,
"invalid length reference",
"HY009");
03223
return SQL_ERROR;
03224 }
03225
#if 0
03226
if (iotype != SQL_PARAM_INPUT)
03227
return SQL_ERROR;
03228
#endif
03229
--pnum;
03230
if (s->
bindparms) {
03231
if (pnum >= s->
nbindparms) {
03232
BINDPARM *newparms;
03233
03234 newparms =
xrealloc(s->
bindparms,
03235 (pnum + 1) * sizeof (
BINDPARM));
03236
if (!newparms) {
03237 outofmem:
03238
return nomem(s);
03239 }
03240 s->
bindparms = newparms;
03241 memset(&s->
bindparms[s->
nbindparms], 0,
03242 (pnum - s->
nbindparms) * sizeof (BINDPARM));
03243 s->
nbindparms = pnum + 1;
03244 }
03245 }
else {
03246
int npar =
max(10, pnum + 1);
03247
03248 s->
bindparms =
xmalloc(npar *
sizeof (
BINDPARM));
03249
if (!s->
bindparms) {
03250
goto outofmem;
03251 }
03252 memset(s->
bindparms, 0, npar * sizeof (BINDPARM));
03253 s->
nbindparms = npar;
03254 }
03255 p = &s->
bindparms[pnum];
03256 p->
type = buftype;
03257 p->
stype = ptype;
03258 p->
max = buflen;
03259 p->
inc = buflen;
03260 p->
lenp = (
int *) len;
03261 p->
offs = 0;
03262 p->
len = 0;
03263
if (p->
lenp) {
03264
#ifdef SQLITE_UTF8
03265
if (buftype == SQL_C_WCHAR) {
03266
if (*p->
lenp == SQL_NTS) {
03267 p->
max = buflen = uc_strlen(data);
03268 }
else if (*p->
lenp >= 0) {
03269 p->
max = buflen = *p->
lenp;
03270 }
03271 }
else
03272
#endif
03273
if (buftype == SQL_C_CHAR) {
03274
if (*p->
lenp == SQL_NTS) {
03275 p->
len = p->
max = buflen = strlen(data);
03276 }
else if (*p->
lenp >= 0) {
03277 p->
len = p->
max = buflen = *p->
lenp;
03278 }
03279 }
03280 }
03281
if (p->
lenp && *p->
lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
03282 p->
param = NULL;
03283 p->
ind = data;
03284 p->
need = 1;
03285 }
else if (p->
lenp && *p->
lenp == SQL_NULL_DATA) {
03286 p->
param = NULL;
03287 p->
ind = NULL;
03288 p->
need = 0;
03289 }
else {
03290
#if HAVE_ENCDEC
03291
int chkbin = 1;
03292
#endif
03293
03294
#ifdef SQLITE_UTF8
03295
if (buftype == SQL_C_WCHAR) {
03296 p->
ind = uc_to_utf(data, buflen);
03297
if (!p->
ind) {
03298
goto outofmem;
03299 }
03300 p->
param = p->
ind;
03301 p->
len = strlen(p->
param);
03302 }
else
03303
#endif
03304
#if HAVE_ENCDEC
03305
if (buftype == SQL_C_BINARY) {
03306
int bsize;
03307
03308 p->
len = *p->
lenp;
03309
if (p->
len < 0) {
03310
setstat(s, -1,
"invalid length reference",
"HY009");
03311
return SQL_ERROR;
03312 }
03313 bsize = sqlite_encode_binary(data, p->
len, 0);
03314 p->
ind =
xmalloc(bsize + 1);
03315
if (!p->
ind) {
03316
goto outofmem;
03317 }
03318 p->
param = p->
ind;
03319 p->
len = sqlite_encode_binary(data, p->
len, p->
param);
03320 chkbin = 0;
03321 }
else
03322
#endif
03323
if (buftype == SQL_C_CHAR) {
03324 p->
param = data;
03325 p->
ind = NULL;
03326 }
else {
03327 p->
param = data;
03328 p->
ind = NULL;
03329
#if HAVE_ENCDEC
03330
chkbin = 0;
03331
#endif
03332
}
03333
#if HAVE_ENCDEC
03334
if (chkbin) {
03335
if (ptype == SQL_BINARY ||
03336 ptype == SQL_VARBINARY ||
03337 ptype == SQL_LONGVARBINARY) {
03338
if (hextobin(s, p) != SQL_SUCCESS) {
03339
return SQL_ERROR;
03340 }
03341 }
03342 }
03343
#endif
03344
p->
need = 0;
03345 }
03346 p->
param0 = p->
param;
03347
return SQL_SUCCESS;
03348 }
03349
03365 SQLRETURN SQL_API
03366 SQLBindParameter(SQLHSTMT
stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
03367 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
03368 SQLSMALLINT scale,
03369 SQLPOINTER data, SQLINTEGER buflen, SQLINTEGER *len)
03370 {
03371
return drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
03372 scale, data, buflen, len);
03373 }
03374
03388 SQLRETURN SQL_API
03389 SQLBindParam(SQLHSTMT
stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
03390 SQLSMALLINT ptype, SQLUINTEGER lenprec,
03391 SQLSMALLINT scale, SQLPOINTER val,
03392 SQLINTEGER *lenp)
03393 {
03394
return drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
03395 lenprec, scale, val, 0, lenp);
03396 }
03397
03405 SQLRETURN SQL_API
03406 SQLNumParams(SQLHSTMT
stmt, SQLSMALLINT *nparam)
03407 {
03408
STMT *s;
03409 SQLSMALLINT dummy;
03410
03411
if (stmt == SQL_NULL_HSTMT) {
03412
return SQL_INVALID_HANDLE;
03413 }
03414 s = (
STMT *) stmt;
03415
if (!nparam) {
03416 nparam = &dummy;
03417 }
03418 *nparam = s->
nparams;
03419
return SQL_SUCCESS;
03420 }
03421
03429 SQLRETURN SQL_API
03430 SQLParamData(SQLHSTMT
stmt, SQLPOINTER *p)
03431 {
03432
STMT *s;
03433
int i;
03434 SQLPOINTER dummy;
03435
03436
if (stmt == SQL_NULL_HSTMT) {
03437
return SQL_INVALID_HANDLE;
03438 }
03439 s = (
STMT *) stmt;
03440
if (!p) {
03441 p = &dummy;
03442 }
03443
for (i = 0; i < s->
nparams; i++) {
03444
if (s->
bindparms[i].
need) {
03445 *p = (SQLPOINTER) s->
bindparms[i].
ind;
03446
return SQL_NEED_DATA;
03447 }
03448 }
03449
return SQL_SUCCESS;
03450 }
03451
03463 SQLRETURN SQL_API
03464 SQLDescribeParam(SQLHSTMT
stmt, UWORD pnum, SWORD *dtype, UDWORD *size,
03465 SWORD *decdigits, SWORD *nullable)
03466 {
03467
STMT *s;
03468
03469
if (stmt == SQL_NULL_HSTMT) {
03470
return SQL_INVALID_HANDLE;
03471 }
03472 s = (
STMT *) stmt;
03473 --pnum;
03474
if (pnum >= s->
nparams) {
03475
setstat(s, -1,
"invalid parameter index",
03476 (*s->
ov3) ?
"HY000" :
"S1000");
03477
return SQL_ERROR;
03478 }
03479
if (dtype) {
03480
#ifdef SQL_LONGVARCHAR
03481
#ifdef SQLITE_UTF8
03482
*dtype = s->
nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
03483
#else
03484
*dtype = SQL_LONGVARCHAR;
03485
#endif
03486
#else
03487
#ifdef SQLITE_UTF8
03488
*dtype = s->
nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
03489
#else
03490
*dtype = SQL_VARCHAR;
03491
#endif
03492
#endif
03493
}
03494
if (size) {
03495
#ifdef SQL_LONGVARCHAR
03496
*size = 65536;
03497
#else
03498
*size = 255;
03499
#endif
03500
}
03501
if (decdigits) {
03502 *decdigits = 0;
03503 }
03504
if (nullable) {
03505 *nullable = SQL_NULLABLE;
03506 }
03507
return SQL_SUCCESS;
03508 }
03509
03523 SQLRETURN SQL_API
03524 SQLSetParam(SQLHSTMT
stmt, SQLUSMALLINT par, SQLSMALLINT type,
03525 SQLSMALLINT sqltype, SQLUINTEGER coldef,
03526 SQLSMALLINT scale, SQLPOINTER val, SQLINTEGER *nval)
03527 {
03528
return drvbindparam(stmt, par, SQL_PARAM_INPUT,
03529 type, sqltype, coldef, scale, val,
03530 SQL_SETPARAM_VALUE_MAX, nval);
03531 }
03532
03537 SQLRETURN SQL_API
03538 SQLParamOptions(SQLHSTMT
stmt, UDWORD rows, UDWORD *rowp)
03539 {
03540
return drvunimplstmt(stmt);
03541 }
03542
03543
#ifndef SQLITE_UTF8
03544
03548 SQLRETURN SQL_API
03549 SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
03550 SQLSMALLINT fieldid, SQLPOINTER value,
03551 SQLINTEGER buflen, SQLINTEGER *strlen)
03552 {
03553
return SQL_ERROR;
03554 }
03555
#endif
03556
03557
#ifdef SQLITE_UTF8
03558
03562 SQLRETURN SQL_API
03563 SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
03564 SQLSMALLINT fieldid, SQLPOINTER value,
03565 SQLINTEGER buflen, SQLINTEGER *strlen)
03566 {
03567
return SQL_ERROR;
03568 }
03569
#endif
03570
03571
#ifndef SQLITE_UTF8
03572
03576 SQLRETURN SQL_API
03577 SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
03578 SQLSMALLINT fieldid, SQLPOINTER value,
03579 SQLINTEGER buflen)
03580 {
03581
return SQL_ERROR;
03582 }
03583
#endif
03584
03585
#ifdef SQLITE_UTF8
03586
03590 SQLRETURN SQL_API
03591 SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
03592 SQLSMALLINT fieldid, SQLPOINTER value,
03593 SQLINTEGER buflen)
03594 {
03595
return SQL_ERROR;
03596 }
03597
#endif
03598
03599
#ifndef SQLITE_UTF8
03600
03604 SQLRETURN SQL_API
03605 SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
03606 SQLCHAR *name, SQLSMALLINT buflen,
03607 SQLSMALLINT *strlen, SQLSMALLINT *type,
03608 SQLSMALLINT *subtype, SQLINTEGER *len,
03609 SQLSMALLINT *prec, SQLSMALLINT *scale,
03610 SQLSMALLINT *nullable)
03611 {
03612
return SQL_ERROR;
03613 }
03614
#endif
03615
03616
#ifdef SQLITE_UTF8
03617
03621 SQLRETURN SQL_API
03622 SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
03623 SQLWCHAR *name, SQLSMALLINT buflen,
03624 SQLSMALLINT *strlen, SQLSMALLINT *type,
03625 SQLSMALLINT *subtype, SQLINTEGER *len,
03626 SQLSMALLINT *prec, SQLSMALLINT *scale,
03627 SQLSMALLINT *nullable)
03628 {
03629
return SQL_ERROR;
03630 }
03631
#endif
03632
03637 SQLRETURN SQL_API
03638 SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
03639 SQLSMALLINT type, SQLSMALLINT subtype,
03640 SQLINTEGER len, SQLSMALLINT prec,
03641 SQLSMALLINT scale, SQLPOINTER data,
03642 SQLINTEGER *strlen, SQLINTEGER *indicator)
03643 {
03644
return SQL_ERROR;
03645 }
03646
03655
static SQLRETURN
03656 mkresultset(HSTMT
stmt,
COL *colspec,
int ncols)
03657 {
03658
STMT *s;
03659
DBC *d;
03660
03661
if (stmt == SQL_NULL_HSTMT) {
03662
return SQL_INVALID_HANDLE;
03663 }
03664 s = (
STMT *) stmt;
03665
if (s->
dbc == SQL_NULL_HDBC) {
03666
noconn:
03667
return noconn(s);
03668 }
03669 d = (
DBC *) s->
dbc;
03670
if (!d->
sqlite) {
03671
goto noconn;
03672 }
03673
vm_end_if(s);
03674
freeresult(s, 0);
03675 s->
ncols = ncols;
03676 s->
cols = colspec;
03677
mkbindcols(s, s->
ncols);
03678 s->
nrows = 0;
03679 s->
rowp = -1;
03680
return SQL_SUCCESS;
03681 }
03682
03687 static COL tablePrivSpec[] = {
03688 {
"SYSTEM",
"TABLEPRIV",
"TABLE_QUALIFIER",
SCOL_VARCHAR, 50 },
03689 {
"SYSTEM",
"TABLEPRIV",
"TABLE_OWNER",
SCOL_VARCHAR, 50 },
03690 {
"SYSTEM",
"TABLEPRIV",
"TABLE_NAME",
SCOL_VARCHAR, 255 },
03691 {
"SYSTEM",
"TABLEPRIV",
"GRANTOR",
SCOL_VARCHAR, 50 },
03692 {
"SYSTEM",
"TABLEPRIV",
"GRANTEE",
SCOL_VARCHAR, 50 },
03693 {
"SYSTEM",
"TABLEPRIV",
"PRIVILEGE",
SCOL_VARCHAR, 50 },
03694 {
"SYSTEM",
"TABLEPRIV",
"IS_GRANTABLE",
SCOL_VARCHAR, 50 }
03695 };
03696
03697
#ifndef SQLITE_UTF8
03698
03710 SQLRETURN SQL_API
03711 SQLTablePrivileges(SQLHSTMT
stmt,
03712 SQLCHAR *catalog, SQLSMALLINT catalogLen,
03713 SQLCHAR *schema, SQLSMALLINT schemaLen,
03714 SQLCHAR *table, SQLSMALLINT tableLen)
03715 {
03716
return mkresultset(stmt,
tablePrivSpec,
array_size(
tablePrivSpec));
03717 }
03718
#endif
03719
03720
#if !defined(HAVE_UNIXODBC) || !HAVE_UNIXODBC
03721
#ifdef SQLITE_UTF8
03722
03734 SQLRETURN SQL_API
03735 SQLTablePrivilegesW(SQLHSTMT
stmt,
03736 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
03737 SQLWCHAR *schema, SQLSMALLINT schemaLen,
03738 SQLWCHAR *table, SQLSMALLINT tableLen)
03739 {
03740
return mkresultset(stmt, tablePrivSpec,
array_size(tablePrivSpec));
03741 }
03742
#endif
03743
#endif
03744
03749 static COL colPrivSpec[] = {
03750 {
"SYSTEM",
"COLPRIV",
"TABLE_QUALIFIER",
SCOL_VARCHAR, 50 },
03751 {
"SYSTEM",
"COLPRIV",
"TABLE_OWNER",
SCOL_VARCHAR, 50 },
03752 {
"SYSTEM",
"COLPRIV",
"TABLE_NAME",
SCOL_VARCHAR, 255 },
03753 {
"SYSTEM",
"COLPRIV",
"GRANTOR",
SCOL_VARCHAR, 50 },
03754 {
"SYSTEM",
"COLPRIV",
"GRANTEE",
SCOL_VARCHAR, 50 },
03755 {
"SYSTEM",
"COLPRIV",
"PRIVILEGE",
SCOL_VARCHAR, 50 },
03756 {
"SYSTEM",
"COLPRIV",
"IS_GRANTABLE",
SCOL_VARCHAR, 50 }
03757 };
03758
03759
#ifndef SQLITE_UTF8
03760
03774 SQLRETURN SQL_API
03775 SQLColumnPrivileges(SQLHSTMT stmt,
03776 SQLCHAR *catalog, SQLSMALLINT catalogLen,
03777 SQLCHAR *schema, SQLSMALLINT schemaLen,
03778 SQLCHAR *table, SQLSMALLINT tableLen,
03779 SQLCHAR *column, SQLSMALLINT columnLen)
03780 {
03781
return mkresultset(stmt,
colPrivSpec,
array_size(
colPrivSpec));
03782 }
03783
#endif
03784
03785
#if !defined(HAVE_UNIXODBC) || !HAVE_UNIXODBC
03786
#ifdef SQLITE_UTF8
03787
03801 SQLRETURN SQL_API
03802 SQLColumnPrivilegesW(SQLHSTMT stmt,
03803 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
03804 SQLWCHAR *schema, SQLSMALLINT schemaLen,
03805 SQLWCHAR *table, SQLSMALLINT tableLen,
03806 SQLWCHAR *column, SQLSMALLINT columnLen)
03807 {
03808
return mkresultset(stmt, colPrivSpec,
array_size(colPrivSpec));
03809 }
03810
#endif
03811
#endif
03812
03817 static COL pkeySpec[] = {
03818 {
"SYSTEM",
"PRIMARYKEY",
"TABLE_QUALIFIER",
SCOL_VARCHAR, 50 },
03819 {
"SYSTEM",
"PRIMARYKEY",
"TABLE_OWNER",
SCOL_VARCHAR, 50 },
03820 {
"SYSTEM",
"PRIMARYKEY",
"TABLE_NAME",
SCOL_VARCHAR, 255 },
03821 {
"SYSTEM",
"PRIMARYKEY",
"COLUMN_NAME",
SCOL_VARCHAR, 255 },
03822 {
"SYSTEM",
"PRIMARYKEY",
"KEY_SEQ", SQL_SMALLINT, 50 },
03823 {
"SYSTEM",
"PRIMARYKEY",
"PK_NAME",
SCOL_VARCHAR, 50 }
03824 };
03825
03838
static SQLRETURN
03839 drvprimarykeys(SQLHSTMT stmt,
03840 SQLCHAR *cat, SQLSMALLINT catLen,
03841 SQLCHAR *schema, SQLSMALLINT schemaLen,
03842 SQLCHAR *table, SQLSMALLINT tableLen)
03843 {
03844
STMT *s;
03845
DBC *d;
03846 SQLRETURN sret;
03847
int i, size, ret, nrows, ncols, offs, namec, uniquec;
03848
char **rowp, *errp = NULL, tname[512];
03849
03850 sret =
mkresultset(stmt,
pkeySpec,
array_size(
pkeySpec));
03851
if (sret != SQL_SUCCESS) {
03852
return sret;
03853 }
03854 s = (
STMT *) stmt;
03855 d = (
DBC *) s->
dbc;
03856
if (!table || table[0] ==
'\0' || table[0] ==
'%') {
03857
setstat(s, -1,
"need table name", (*s->
ov3) ?
"HY000" :
"S1000");
03858
return SQL_ERROR;
03859 }
03860
if (tableLen == SQL_NTS) {
03861 size =
sizeof (tname) - 1;
03862 }
else {
03863 size =
min(
sizeof (tname) - 1, tableLen);
03864 }
03865 strncpy(tname, table, size);
03866 tname[size] =
'\0';
03867 ret = sqlite_get_table_printf(d->
sqlite,
03868
"PRAGMA index_list('%q')", &rowp,
03869 &nrows, &ncols, &errp, tname);
03870
if (ret != SQLITE_OK) {
03871
setstat(s, ret,
"%s (%d)", (*s->
ov3) ?
"HY000" :
"S1000",
03872 errp ? errp :
"unknown error", ret);
03873
if (errp) {
03874 sqlite_freemem(errp);
03875 errp = NULL;
03876 }
03877
return SQL_ERROR;
03878 }
03879
if (errp) {
03880 sqlite_freemem(errp);
03881 errp = NULL;
03882 }
03883
if (ncols * nrows <= 0) {
03884 nodata:
03885 sqlite_free_table(rowp);
03886
03887 ret = sqlite_get_table_printf(d->
sqlite,
03888
"PRAGMA table_info('%q')", &rowp,
03889 &nrows, &ncols, NULL, tname);
03890
if (ret == SQLITE_OK) {
03891
int typec, roffs;
03892
03893 namec =
findcol(rowp, ncols,
"name");
03894 uniquec =
findcol(rowp, ncols,
"pk");
03895 typec =
findcol(rowp, ncols,
"type");
03896
if (namec < 0 || uniquec < 0 || typec < 0) {
03897
goto nodata2;
03898 }
03899
for (i = 1; i <= nrows; i++) {
03900
if (*rowp[i * ncols + uniquec] !=
'0' &&
03901 strlen(rowp[i * ncols + typec]) == 7 &&
03902 strncasecmp(rowp[i * ncols + typec],
"integer", 7) == 0) {
03903
break;
03904 }
03905 }
03906
if (i > nrows) {
03907
goto nodata2;
03908 }
03909 size = (1 + 1) *
array_size(
pkeySpec);
03910 s->
rows =
xmalloc((size + 1) *
sizeof (
char *));
03911
if (!s->
rows) {
03912 s->
nrows = 0;
03913
return nomem(s);
03914 }
03915 s->
rows[0] = (
char *) size;
03916 s->
rows += 1;
03917 memset(s->
rows, 0, sizeof (
char *) * size);
03918 s->
rowfree =
freerows;
03919 s->
nrows = 1;
03920 roffs = s->
ncols;
03921 s->
rows[roffs + 0] =
xstrdup(
"");
03922 s->
rows[roffs + 1] =
xstrdup(
"");
03923 s->
rows[roffs + 2] =
xstrdup(tname);
03924 s->
rows[roffs + 3] =
xstrdup(rowp[i * ncols + namec]);
03925 s->
rows[roffs + 4] =
xstrdup(
"1");
03926 nodata2:
03927 sqlite_free_table(rowp);
03928 }
03929
return SQL_SUCCESS;
03930 }
03931 size = 0;
03932 namec =
findcol(rowp, ncols,
"name");
03933 uniquec =
findcol(rowp, ncols,
"unique");
03934
if (namec < 0 || uniquec < 0) {
03935
goto nodata;
03936 }
03937
for (i = 1; i <= nrows; i++) {
03938
int nnrows, nncols;
03939
char **rowpp;
03940
03941
if (*rowp[i * ncols + uniquec] !=
'0') {
03942 ret = sqlite_get_table_printf(d->
sqlite,
03943
"PRAGMA index_info('%q')", &rowpp,
03944 &nnrows, &nncols, NULL,
03945 rowp[i * ncols + namec]);
03946
if (ret == SQLITE_OK) {
03947 size += nnrows;
03948 sqlite_free_table(rowpp);
03949 }
03950 }
03951 }
03952
if (size == 0) {
03953
goto nodata;
03954 }
03955 s->
nrows = size;
03956 size = (size + 1) *
array_size(
pkeySpec);
03957 s->
rows =
xmalloc((size + 1) *
sizeof (
char *));
03958
if (!s->
rows) {
03959 s->
nrows = 0;
03960
return nomem(s);
03961 }
03962 s->
rows[0] = (
char *) size;
03963 s->
rows += 1;
03964 memset(s->
rows, 0, sizeof (
char *) * size);
03965 s->
rowfree =
freerows;
03966 offs = 0;
03967
for (i = 1; i <= nrows; i++) {
03968
int nnrows, nncols;
03969
char **rowpp;
03970
03971
if (*rowp[i * ncols + uniquec] !=
'0') {
03972
int k;
03973
03974 ret = sqlite_get_table_printf(d->
sqlite,
03975
"PRAGMA index_info('%q')", &rowpp,
03976 &nnrows, &nncols, NULL,
03977 rowp[i * ncols + namec]);
03978
if (ret != SQLITE_OK) {
03979
continue;
03980 }
03981
for (k = 0; nnrows && k < nncols; k++) {
03982
if (strcmp(rowpp[k],
"name") == 0) {
03983
int m;
03984
03985
for (m = 1; m <= nnrows; m++) {
03986
int roffs = (offs + m) * s->
ncols;
03987
03988 s->
rows[roffs + 0] =
xstrdup(
"");
03989 s->
rows[roffs + 1] =
xstrdup(
"");
03990 s->
rows[roffs + 2] =
xstrdup(tname);
03991 s->
rows[roffs + 3] =
xstrdup(rowpp[m * nncols + k]);
03992 s->
rows[roffs + 5] =
xstrdup(rowp[i * ncols + namec]);
03993 }
03994 }
else if (strcmp(rowpp[k],
"seqno") == 0) {
03995
int m;
03996
03997
for (m = 1; m <= nnrows; m++) {
03998
int roffs = (offs + m) * s->
ncols;
03999
int pos = m - 1;
04000
char buf[32];
04001
04002 sscanf(rowpp[m * nncols + k],
"%d", &pos);
04003 sprintf(buf,
"%d", pos + 1);
04004 s->
rows[roffs + 4] =
xstrdup(buf);
04005 }
04006 }
04007 }
04008 offs += nnrows;
04009 sqlite_free_table(rowpp);
04010 }
04011 }
04012 sqlite_free_table(rowp);
04013
return SQL_SUCCESS;
04014 }
04015
04016
#ifndef SQLITE_UTF8
04017
04029 SQLRETURN SQL_API
04030 SQLPrimaryKeys(SQLHSTMT stmt,
04031 SQLCHAR *cat, SQLSMALLINT catLen,
04032 SQLCHAR *schema, SQLSMALLINT schemaLen,
04033 SQLCHAR *table, SQLSMALLINT tableLen)
04034 {
04035
return drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
04036 table, tableLen);
04037 }
04038
#endif
04039
04040
#ifdef SQLITE_UTF8
04041
04053 SQLRETURN SQL_API
04054 SQLPrimaryKeysW(SQLHSTMT stmt,
04055 SQLWCHAR *cat, SQLSMALLINT catLen,
04056 SQLWCHAR *schema, SQLSMALLINT schemaLen,
04057 SQLWCHAR *table, SQLSMALLINT tableLen)
04058 {
04059
char *c = NULL, *s = NULL, *t = NULL;
04060 SQLRETURN ret;
04061
04062
if (cat) {
04063 c = uc_to_utf_c(cat, catLen);
04064
if (!c) {
04065 ret =
nomem((
STMT *) stmt);
04066
goto done;
04067 }
04068 }
04069
if (schema) {
04070 s = uc_to_utf_c(schema, schemaLen);
04071
if (!s) {
04072 ret =
nomem((
STMT *) stmt);
04073
goto done;
04074 }
04075 }
04076
if (table) {
04077 t = uc_to_utf_c(table, tableLen);
04078
if (!t) {
04079 ret =
nomem((
STMT *) stmt);
04080
goto done;
04081 }
04082 }
04083 ret =
drvprimarykeys(stmt, c, SQL_NTS, s, SQL_NTS, t, SQL_NTS);
04084 done:
04085 uc_free(t);
04086 uc_free(s);
04087 uc_free(c);
04088
return ret;
04089 }
04090
#endif
04091
04096 static COL scolSpec[] = {
04097 {
"SYSTEM",
"COLUMN",
"SCOPE", SQL_SMALLINT, 1 },
04098 {
"SYSTEM",
"COLUMN",
"COLUMN_NAME",
SCOL_VARCHAR, 255 },
04099 {
"SYSTEM",
"COLUMN",
"DATA_TYPE", SQL_SMALLINT, 50 },
04100 {
"SYSTEM",
"COLUMN",
"TYPE_NAME",
SCOL_VARCHAR, 50 },
04101 {
"SYSTEM",
"COLUMN",
"PRECISION", SQL_INTEGER, 50 },
04102 {
"SYSTEM",
"COLUMN",
"LENGTH", SQL_INTEGER, 50 },
04103 {
"SYSTEM",
"COLUMN",
"DECIMAL_DIGITS", SQL_INTEGER, 50 },
04104 {
"SYSTEM",
"COLUMN",
"PSEUDO_COLUMN", SQL_SMALLINT, 1 },
04105 {
"SYSTEM",
"COLUMN",
"NULLABLE", SQL_SMALLINT, 1 }
04106 };
04107
04123
static SQLRETURN
04124 drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT
id,
04125 SQLCHAR *cat, SQLSMALLINT catLen,
04126 SQLCHAR *schema, SQLSMALLINT schemaLen,
04127 SQLCHAR *table, SQLSMALLINT tableLen,
04128 SQLUSMALLINT scope, SQLUSMALLINT nullable)
04129 {
04130
STMT *s;
04131
DBC *d;
04132 SQLRETURN sret;
04133
int i, size, ret, nrows, ncols, nnnrows, nnncols, offs;
04134
int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
04135
int notnullcc = -1, mkrowid = 0;
04136
char *errp = NULL, tname[512];
04137
char **rowp = NULL, **rowppp = NULL;
04138
04139 sret =
mkresultset(stmt,
scolSpec,
array_size(
scolSpec));
04140
if (sret != SQL_SUCCESS) {
04141
return sret;
04142 }
04143 s = (
STMT *) stmt;
04144 d = (
DBC *) s->
dbc;
04145
if (!table || table[0] ==
'\0' || table[0] ==
'%') {
04146
setstat(s, -1,
"need table name", (*s->
ov3) ?
"HY000" :
"S1000");
04147
return SQL_ERROR;
04148 }
04149
if (tableLen == SQL_NTS) {
04150 size =
sizeof (tname) - 1;
04151 }
else {
04152 size =
min(
sizeof (tname) - 1, tableLen);
04153 }
04154 strncpy(tname, table, size);
04155 tname[size] =
'\0';
04156
if (
id != SQL_BEST_ROWID) {
04157
return SQL_SUCCESS;
04158 }
04159 ret = sqlite_get_table_printf(d->
sqlite,
"PRAGMA index_list('%q')",
04160 &rowp, &nrows, &ncols, &errp, tname);
04161
if (ret != SQLITE_OK) {
04162 doerr:
04163
setstat(s, ret,
"%s (%d)", (*s->
ov3) ?
"HY000" :
"S1000",
04164 errp ? errp :
"unknown error", ret);
04165
if (errp) {
04166 sqlite_freemem(errp);
04167 errp = NULL;
04168 }
04169
return SQL_ERROR;
04170 }
04171
if (errp) {
04172 sqlite_freemem(errp);
04173 errp = NULL;
04174 }
04175 size = 0;
04176
if (ncols * nrows <= 0) {
04177
goto nodata_but_rowid;
04178 }
04179 ret = sqlite_get_table_printf(d->
sqlite,
"PRAGMA table_info('%q')",
04180 &rowppp, &nnnrows, &nnncols, &errp, tname);
04181
if (ret != SQLITE_OK) {
04182 sqlite_free_table(rowp);
04183
goto doerr;
04184 }
04185
if (errp) {
04186 sqlite_freemem(errp);
04187 errp = NULL;
04188 }
04189 namec =
findcol(rowp, ncols,
"name");
04190 uniquec =
findcol(rowp, ncols,
"unique");
04191
if (namec < 0 || uniquec < 0) {
04192
goto nodata_but_rowid;
04193 }
04194 namecc =
findcol(rowppp, nnncols,
"name");
04195 typecc =
findcol(rowppp, nnncols,
"type");
04196 notnullcc =
findcol(rowppp, nnncols,
"notnull");
04197
for (i = 1; i <= nrows; i++) {
04198
int nnrows, nncols;
04199
char **rowpp;
04200
04201
if (*rowp[i * ncols + uniquec] !=
'0') {
04202 ret = sqlite_get_table_printf(d->
sqlite,
04203
"PRAGMA index_info('%q')", &rowpp,
04204 &nnrows, &nncols, NULL,
04205 rowp[i * ncols + namec]);
04206
if (ret == SQLITE_OK) {
04207 size += nnrows;
04208 sqlite_free_table(rowpp);
04209 }
04210 }
04211 }
04212 nodata_but_rowid:
04213
if (size == 0) {
04214 size = 1;
04215 mkrowid = 1;
04216 }
04217 s->
nrows = size;
04218 size = (size + 1) *
array_size(
scolSpec);
04219 s->
rows =
xmalloc((size + 1) *
sizeof (
char *));
04220
if (!s->
rows) {
04221 s->
nrows = 0;
04222 sqlite_free_table(rowp);
04223 sqlite_free_table(rowppp);
04224
return nomem(s);
04225 }
04226 s->
rows[0] = (
char *) size;
04227 s->
rows += 1;
04228 memset(s->
rows, 0, sizeof (
char *) * size);
04229 s->
rowfree =
freerows;
04230
if (mkrowid) {
04231 s->
nrows = 0;
04232
goto mkrowid;
04233 }
04234 offs = 0;
04235
for (i = 1; i <= nrows; i++) {
04236
int nnrows, nncols;
04237
char **rowpp;
04238
04239
if (*rowp[i * ncols + uniquec] !=
'0') {
04240
int k;
04241
04242 ret = sqlite_get_table_printf(d->
sqlite,
04243
"PRAGMA index_info('%q')", &rowpp,
04244 &nnrows, &nncols, NULL,
04245 rowp[i * ncols + namec]);
04246
if (ret != SQLITE_OK) {
04247
continue;
04248 }
04249
for (k = 0; nnrows && k < nncols; k++) {
04250
if (strcmp(rowpp[k],
"name") == 0) {
04251
int m;
04252
04253
for (m = 1; m <= nnrows; m++) {
04254
int roffs = (offs + m) * s->
ncols;
04255
04256 s->
rows[roffs + 0] =
04257
xstrdup(
stringify(SQL_SCOPE_SESSION));
04258 s->
rows[roffs + 1] =
xstrdup(rowpp[m * nncols + k]);
04259 s->
rows[roffs + 4] =
xstrdup(
"0");
04260 s->
rows[roffs + 7] =
04261
xstrdup(
stringify(SQL_PC_NOT_PSEUDO));
04262
if (namecc >= 0 && typecc >= 0) {
04263
int ii;
04264
04265
for (ii = 1; ii <= nnnrows; ii++) {
04266
if (strcmp(rowppp[ii * nnncols + namecc],
04267 rowpp[m * nncols + k]) == 0) {
04268
char *typen = rowppp[ii * nnncols + typecc];
04269
int sqltype, mm, dd, isnullable = 0;
04270
char buf[32];
04271
04272 s->
rows[roffs + 3] =
xstrdup(typen);
04273 sqltype =
mapsqltype(typen, NULL, *s->
ov3,
04274 s->
nowchar);
04275
getmd(typen, sqltype, &mm, &dd);
04276
#ifdef SQL_LONGVARCHAR
04277
if (sqltype == SQL_VARCHAR && mm > 255) {
04278 sqltype = SQL_LONGVARCHAR;
04279 }
04280
#endif
04281
#ifdef SQLITE_UTF8
04282
#ifdef SQL_WLONGVARCHAR
04283
if (sqltype == SQL_WVARCHAR && mm > 255) {
04284 sqltype = SQL_WLONGVARCHAR;
04285 }
04286
#endif
04287
#endif
04288
#if HAVE_ENCDEC
04289
if (sqltype == SQL_VARBINARY && mm > 255) {
04290 sqltype = SQL_LONGVARBINARY;
04291 }
04292
#endif
04293
sprintf(buf,
"%d", sqltype);
04294 s->
rows[roffs + 2] =
xstrdup(buf);
04295 sprintf(buf,
"%d", mm);
04296 s->
rows[roffs + 5] =
xstrdup(buf);
04297 sprintf(buf,
"%d", dd);
04298 s->
rows[roffs + 6] =
xstrdup(buf);
04299
if (notnullcc >= 0) {
04300
char *inp =
04301 rowppp[ii * nnncols + notnullcc];
04302
04303 isnullable = inp[0] !=
'0';
04304 }
04305 sprintf(buf,
"%d", isnullable);
04306 s->
rows[roffs + 8] =
xstrdup(buf);
04307 }
04308 }
04309 }
04310 }
04311 }
04312 }
04313 offs += nnrows;
04314 sqlite_free_table(rowpp);
04315 }
04316 }
04317
if (nullable == SQL_NO_NULLS) {
04318
for (i = 1; i < s->
nrows; i++) {
04319
if (s->
rows[i * s->
ncols + 8][0] ==
'0') {
04320
int m, i1 = i + 1;
04321
04322
for (m = 0; m < s->
ncols; m++) {
04323
freep(&s->
rows[i * s->
ncols + m]);
04324 }
04325 size = s->
ncols *
sizeof (
char *) * (s->
nrows - i1);
04326
if (size > 0) {
04327 memmove(s->
rows + i * s->
ncols,
04328 s->
rows + i1 * s->
ncols,
04329 size);
04330 memset(s->
rows + s->
nrows * s->
ncols, 0,
04331 s->
ncols * sizeof (
char *));
04332 }
04333 s->
nrows--;
04334 --i;
04335 }
04336 }
04337 }
04338 mkrowid:
04339 sqlite_free_table(rowp);
04340 sqlite_free_table(rowppp);
04341
if (s->
nrows == 0) {
04342 s->
rows[s->
ncols + 0] =
xstrdup(
stringify(SQL_SCOPE_SESSION));
04343 s->
rows[s->
ncols + 1] =
xstrdup(
"_ROWID_");
04344 s->
rows[s->
ncols + 2] =
xstrdup(
stringify(SQL_INTEGER));
04345 s->
rows[s->
ncols + 3] =
xstrdup(
"integer");
04346 s->
rows[s->
ncols + 4] =
xstrdup(
"0");
04347 s->
rows[s->
ncols + 5] =
xstrdup(
"10");
04348 s->
rows[s->
ncols + 6] =
xstrdup(
"9");
04349 s->
rows[s->
ncols + 7] =
xstrdup(
stringify(SQL_PC_PSEUDO));
04350 s->
rows[s->
ncols + 8] =
xstrdup(
stringify(SQL_FALSE));
04351 s->
nrows = 1;
04352 }
04353
return SQL_SUCCESS;
04354 }
04355
04356
#ifndef SQLITE_UTF8
04357
04372 SQLRETURN SQL_API
04373 SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT
id,
04374 SQLCHAR *cat, SQLSMALLINT catLen,
04375 SQLCHAR *schema, SQLSMALLINT schemaLen,
04376 SQLCHAR *table, SQLSMALLINT tableLen,
04377 SQLUSMALLINT scope, SQLUSMALLINT nullable)
04378 {
04379
return drvspecialcolumns(stmt,
id, cat, catLen, schema, schemaLen,
04380 table, tableLen, scope, nullable);
04381 }
04382
#endif
04383
04384
#ifdef SQLITE_UTF8
04385
04400 SQLRETURN SQL_API
04401 SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT
id,
04402 SQLWCHAR *cat, SQLSMALLINT catLen,
04403 SQLWCHAR *schema, SQLSMALLINT schemaLen,
04404 SQLWCHAR *table, SQLSMALLINT tableLen,
04405 SQLUSMALLINT scope, SQLUSMALLINT nullable)
04406 {
04407
char *c = NULL, *s = NULL, *t = NULL;
04408 SQLRETURN ret;
04409
04410
if (cat) {
04411 c = uc_to_utf_c(cat, catLen);
04412
if (!c) {
04413 ret =
nomem((
STMT *) stmt);
04414
goto done;
04415 }
04416 }
04417
if (schema) {
04418 s = uc_to_utf_c(schema, schemaLen);
04419
if (!s) {
04420 ret =
nomem((
STMT *) stmt);
04421
goto done;
04422 }
04423 }
04424
if (table) {
04425 t = uc_to_utf_c(table, tableLen);
04426
if (!t) {
04427 ret =
nomem((
STMT *) stmt);
04428
goto done;
04429 }
04430 }
04431 ret =
drvspecialcolumns(stmt,
id, c, SQL_NTS, s, SQL_NTS, t, SQL_NTS,
04432 scope, nullable);
04433 done:
04434 uc_free(t);
04435 uc_free(s);
04436 uc_free(c);
04437
return ret;
04438 }
04439
#endif
04440
04445 static COL fkeySpec[] = {
04446 {
"SYSTEM",
"FOREIGNKEY",
"PKTABLE_QUALIFIER",
SCOL_VARCHAR, 50 },
04447 {
"SYSTEM",
"FOREIGNKEY",
"PKTABLE_OWNER",
SCOL_VARCHAR, 50 },
04448 {
"SYSTEM",
"FOREIGNKEY",
"PKTABLE_NAME",
SCOL_VARCHAR, 255 },
04449 {
"SYSTEM",
"FOREIGNKEY",
"PKCOLUMN_NAME",
SCOL_VARCHAR, 255 },
04450 {
"SYSTEM",
"FOREIGNKEY",
"FKTABLE_QUALIFIER",
SCOL_VARCHAR, 50 },
04451 {
"SYSTEM",
"FOREIGNKEY",
"FKTABLE_OWNER",
SCOL_VARCHAR, 50 },
04452 {
"SYSTEM",
"FOREIGNKEY",
"FKTABLE_NAME",
SCOL_VARCHAR, 255 },
04453 {
"SYSTEM",
"FOREIGNKEY",
"FKCOLUMN_NAME",
SCOL_VARCHAR, 255 },
04454 {
"SYSTEM",
"FOREIGNKEY",
"KEY_SEQ", SQL_SMALLINT, 5 },
04455 {
"SYSTEM",
"FOREIGNKEY",
"UPDATE_RULE", SQL_SMALLINT, 5 },
04456 {
"SYSTEM",
"FOREIGNKEY",
"DELETE_RULE", SQL_SMALLINT, 5 },
04457 {
"SYSTEM",
"FOREIGNKEY",
"FK_NAME",
SCOL_VARCHAR, 255 },
04458 {
"SYSTEM",
"FOREIGNKEY",
"PK_NAME",
SCOL_VARCHAR, 255 },
04459 {
"SYSTEM",
"FOREIGNKEY",
"DEFERRABILITY", SQL_SMALLINT, 5 }
04460 };
04461
04480
static SQLRETURN SQL_API
04481 drvforeignkeys(SQLHSTMT stmt,
04482 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
04483 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
04484 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
04485 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
04486 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
04487 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
04488 {
04489
STMT *s;
04490
DBC *d;
04491 SQLRETURN sret;
04492
int i, size, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
04493
char **rowp, *errp = NULL, pname[512], fname[512];
04494
04495 sret =
mkresultset(stmt,
fkeySpec,
array_size(
fkeySpec));
04496
if (sret != SQL_SUCCESS) {
04497
return sret;
04498 }
04499 s = (
STMT *) stmt;
04500 d = (
DBC *) s->
dbc;
04501
if ((!PKtable || PKtable[0] ==
'\0' || PKtable[0] ==
'%') &&
04502 (!FKtable || FKtable[0] ==
'\0' || FKtable[0] ==
'%')) {
04503
setstat(s, -1,
"need table name", (*s->
ov3) ?
"HY000" :
"S1000");
04504
return SQL_ERROR;
04505 }
04506 size = 0;
04507
if (PKtable) {
04508
if (PKtableLen == SQL_NTS) {
04509 size =
sizeof (pname) - 1;
04510 }
else {
04511 size =
min(
sizeof (pname) - 1, PKtableLen);
04512 }
04513 strncpy(pname, PKtable, size);
04514 }
04515 pname[size] =
'\0';
04516 size = 0;
04517
if (FKtable) {
04518
if (FKtableLen == SQL_NTS) {
04519 size =
sizeof (fname) - 1;
04520 }
else {
04521 size =
min(
sizeof (fname) - 1, FKtableLen);
04522 }
04523 strncpy(fname, FKtable, size);
04524 }
04525 fname[size] =
'\0';
04526
if (fname[0] !=
'\0') {
04527
int plen;
04528
04529 ret = sqlite_get_table_printf(d->
sqlite,
04530
"PRAGMA foreign_key_list('%q')", &rowp,
04531 &nrows, &ncols, &errp, fname);
04532
if (ret != SQLITE_OK) {
04533
setstat(s, ret,
"%s (%d)", (*s->
ov3) ?
"HY000" :
"S1000",
04534 errp ? errp :
"unknown error", ret);
04535
if (errp) {
04536 sqlite_freemem(errp);
04537 errp = NULL;
04538 }
04539
return SQL_ERROR;
04540 }
04541
if (errp) {
04542 sqlite_freemem(errp);
04543 errp = NULL;
04544 }
04545
if (ncols * nrows <= 0) {
04546 nodata:
04547 sqlite_free_table(rowp);
04548
return SQL_SUCCESS;
04549 }
04550 size = 0;
04551 namec =
findcol(rowp, ncols,
"table");
04552 seqc =
findcol(rowp, ncols,
"seq");
04553 fromc =
findcol(rowp, ncols,
"from");
04554 toc =
findcol(rowp, ncols,
"to");
04555
if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
04556
goto nodata;
04557 }
04558 plen = strlen(pname);
04559
for (i = 1; i <= nrows; i++) {
04560
char *ptab = rowp[i * ncols + namec];
04561
04562
if (plen && ptab) {
04563
int len = strlen(ptab);
04564
04565
if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
04566
continue;
04567 }
04568 }
04569 size++;
04570 }
04571
if (size == 0) {
04572
goto nodata;
04573 }
04574 s->
nrows = size;
04575 size = (size + 1) *
array_size(
fkeySpec);
04576 s->
rows =
xmalloc((size + 1) *
sizeof (
char *));
04577
if (!s->
rows) {
04578 s->
nrows = 0;
04579
return nomem(s);
04580 }
04581 s->
rows[0] = (
char *) size;
04582 s->
rows += 1;
04583 memset(s->
rows, 0, sizeof (
char *) * size);
04584 s->
rowfree =
freerows;
04585 offs = 0;
04586
for (i = 1; i <= nrows; i++) {
04587
int pos = 0, roffs = (offs + 1) * s->
ncols;
04588
char *ptab = rowp[i * ncols + namec];
04589
char buf[32];
04590
04591
if (plen && ptab) {
04592
int len = strlen(ptab);
04593
04594
if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
04595
continue;
04596 }
04597 }
04598 s->
rows[roffs + 0] =
xstrdup(
"");
04599 s->
rows[roffs + 1] =
xstrdup(
"");
04600 s->
rows[roffs + 2] =
xstrdup(ptab);
04601 s->
rows[roffs + 3] =
xstrdup(rowp[i * ncols + toc]);
04602 s->
rows[roffs + 4] =
xstrdup(
"");
04603 s->
rows[roffs + 5] =
xstrdup(
"");
04604 s->
rows[roffs + 6] =
xstrdup(fname);
04605 s->
rows[roffs + 7] =
xstrdup(rowp[i * ncols + fromc]);
04606 sscanf(rowp[i * ncols + seqc],
"%d", &pos);
04607 sprintf(buf,
"%d", pos + 1);
04608 s->
rows[roffs + 8] =
xstrdup(buf);
04609 s->
rows[roffs + 9] =
xstrdup(
stringify(SQL_NO_ACTION));
04610 s->
rows[roffs + 10] =
xstrdup(
stringify(SQL_NO_ACTION));
04611 s->
rows[roffs + 11] = NULL;
04612 s->
rows[roffs + 12] = NULL;
04613 s->
rows[roffs + 13] =
xstrdup(
stringify(SQL_NOT_DEFERRABLE));
04614 offs++;
04615 }
04616 sqlite_free_table(rowp);
04617 }
else {
04618
int nnrows, nncols, plen = strlen(pname);
04619
char **rowpp;
04620
04621 ret = sqlite_get_table(d->
sqlite,
04622
"select name from sqlite_master "
04623
"where type='table'", &rowp,
04624 &nrows, &ncols, &errp);
04625
if (ret != SQLITE_OK) {
04626
setstat(s, ret,
"%s (%d)", (*s->
ov3) ?
"HY000" :
"S1000",
04627 errp ? errp :
"unknown error", ret);
04628
if (errp) {
04629 sqlite_freemem(errp);
04630 errp = NULL;
04631 }
04632
return SQL_ERROR;
04633 }
04634
if (errp) {
04635 sqlite_freemem(errp);
04636 errp = NULL;
04637 }
04638
if (ncols * nrows <= 0) {
04639
goto nodata;
04640 }
04641 size = 0;
04642
for (i = 1; i <= nrows; i++) {
04643
int k, len;
04644
04645
if (!rowp[i]) {
04646
continue;
04647 }
04648 len = strlen(rowp[i]);
04649
if (len == plen && strncasecmp(pname, rowp[i], plen) == 0) {
04650
continue;
04651 }
04652 ret = sqlite_get_table_printf(d->
sqlite,
04653
"PRAGMA foreign_key_list('%q')",
04654 &rowpp,
04655 &nnrows, &nncols, NULL, rowp[i]);
04656
if (ret != SQLITE_OK || nncols * nnrows <= 0) {
04657 sqlite_free_table(rowpp);
04658
continue;
04659 }
04660 namec =
findcol(rowpp, nncols,
"table");
04661 seqc =
findcol(rowpp, nncols,
"seq");
04662 fromc =
findcol(rowpp, nncols,
"from");
04663 toc =
findcol(rowpp, nncols,
"to");
04664
if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
04665 sqlite_free_table(rowpp);
04666
continue;
04667 }
04668
for (k = 1; k <= nnrows; k++) {
04669
char *ptab = rowpp[k * nncols + namec];
04670
04671
if (plen && ptab) {
04672 len = strlen(ptab);
04673
if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
04674
continue;
04675 }
04676 }
04677 size++;
04678 }
04679 sqlite_free_table(rowpp);
04680 }
04681
if (size == 0) {
04682
goto nodata;
04683 }
04684 s->
nrows = size;
04685 size = (size + 1) *
array_size(
fkeySpec);
04686 s->
rows =
xmalloc((size + 1) *
sizeof (
char *));
04687
if (!s->
rows) {
04688 s->
nrows = 0;
04689
return nomem(s);
04690 }
04691 s->
rows[0] = (
char *) size;
04692 s->
rows += 1;
04693 memset(s->
rows, 0, sizeof (
char *) * size);
04694 s->
rowfree =
freerows;
04695 offs = 0;
04696
for (i = 1; i <= nrows; i++) {
04697
int k, len;
04698
04699
if (!rowp[i]) {
04700
continue;
04701 }
04702 len = strlen(rowp[i]);
04703
if (len == plen && strncasecmp(pname, rowp[i], plen) == 0) {
04704
continue;
04705 }
04706 ret = sqlite_get_table_printf(d->
sqlite,
04707
"PRAGMA foreign_key_list('%q')",
04708 &rowpp,
04709 &nnrows, &nncols, NULL, rowp[i]);
04710
if (ret != SQLITE_OK || nncols * nnrows <= 0) {
04711 sqlite_free_table(rowpp);
04712
continue;
04713 }
04714 namec =
findcol(rowpp, nncols,
"table");
04715 seqc =
findcol(rowpp, nncols,
"seq");
04716 fromc =
findcol(rowpp, nncols,
"from");
04717 toc =
findcol(rowpp, nncols,
"to");
04718
if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
04719 sqlite_free_table(rowpp);
04720
continue;
04721 }
04722
for (k = 1; k <= nnrows; k++) {
04723
int pos = 0, roffs = (offs + 1) * s->
ncols;
04724
char *ptab = rowpp[k * nncols + namec];
04725
char buf[32];
04726
04727
if (plen && ptab) {
04728 len = strlen(ptab);
04729
if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
04730
continue;
04731 }
04732 }
04733 s->
rows[roffs + 0] =
xstrdup(
"");
04734 s->
rows[roffs + 1] =
xstrdup(
"");
04735 s->
rows[roffs + 2] =
xstrdup(ptab);
04736 s->
rows[roffs + 3] =
xstrdup(rowpp[k * nncols + toc]);
04737 s->
rows[roffs + 4] =
xstrdup(
"");
04738 s->
rows[roffs + 5] =
xstrdup(
"");
04739 s->
rows[roffs + 6] =
xstrdup(rowp[i]);
04740 s->
rows[roffs + 7] =
xstrdup(rowpp[k * nncols + fromc]);
04741 sscanf(rowpp[k * nncols + seqc],
"%d", &pos);
04742 sprintf(buf,
"%d", pos + 1);
04743 s->
rows[roffs + 8] =
xstrdup(buf);
04744 s->
rows[roffs + 9] =
xstrdup(
stringify(SQL_NO_ACTION));
04745 s->
rows[roffs + 10] =
xstrdup(
stringify(SQL_NO_ACTION));
04746 s->
rows[roffs + 11] = NULL;
04747 s->
rows[roffs + 12] = NULL;
04748 s->
rows[roffs + 13] =
xstrdup(
stringify(SQL_NOT_DEFERRABLE));
04749 offs++;
04750 }
04751 sqlite_free_table(rowpp);
04752 }
04753 sqlite_free_table(rowp);
04754 }
04755
return SQL_SUCCESS;
04756 }
04757
04758
#ifndef SQLITE_UTF8
04759
04777 SQLRETURN SQL_API
04778 SQLForeignKeys(SQLHSTMT stmt,
04779 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
04780 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
04781 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
04782 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
04783 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
04784 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
04785 {
04786
return drvforeignkeys(stmt,
04787 PKcatalog, PKcatalogLen,
04788 PKschema, PKschemaLen, PKtable, PKtableLen,
04789 FKcatalog, FKcatalogLen,
04790 FKschema, FKschemaLen,
04791 FKtable, FKtableLen);
04792 }
04793
#endif
04794
04795
#ifdef SQLITE_UTF8
04796
04814 SQLRETURN SQL_API
04815 SQLForeignKeysW(SQLHSTMT stmt,
04816 SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
04817 SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
04818 SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
04819 SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
04820 SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
04821 SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
04822 {
04823
char *pc = NULL, *ps = NULL, *pt = NULL;
04824
char *fc = NULL, *fs = NULL, *ft = NULL;
04825 SQLRETURN ret;
04826
04827
if (PKcatalog) {
04828 pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
04829
if (!pc) {
04830 ret =
nomem((
STMT *) stmt);
04831
goto done;
04832 }
04833 }
04834
if (PKschema) {
04835 ps = uc_to_utf_c(PKschema, PKschemaLen);
04836
if (!ps) {
04837 ret =
nomem((
STMT *) stmt);
04838
goto done;
04839 }
04840 }
04841
if (PKtable) {
04842 pt = uc_to_utf_c(PKtable, PKtableLen);
04843
if (!pt) {
04844 ret =
nomem((
STMT *) stmt);
04845
goto done;
04846 }
04847 }
04848
if (FKcatalog) {
04849 fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
04850
if (!fc) {
04851 ret =
nomem((
STMT *) stmt);
04852
goto done;
04853 }
04854 }
04855
if (FKschema) {
04856 fs = uc_to_utf_c(FKschema, FKschemaLen);
04857
if (!fs) {
04858 ret =
nomem((
STMT *) stmt);
04859
goto done;
04860 }
04861 }
04862
if (FKtable) {
04863 ft = uc_to_utf_c(FKtable, FKtableLen);
04864
if (!ft) {
04865 ret =
nomem((
STMT *) stmt);
04866
goto done;
04867 }
04868 }
04869 ret =
drvforeignkeys(stmt, pc, SQL_NTS, ps, SQL_NTS, pt, SQL_NTS,
04870 fc, SQL_NTS, fs, SQL_NTS, ft, SQL_NTS);
04871 done:
04872 uc_free(ft);
04873 uc_free(fs);
04874 uc_free(fc);
04875 uc_free(pt);
04876 uc_free(ps);
04877 uc_free(pc);
04878
return ret;
04879 }
04880
#endif
04881
04889
static SQLRETURN
04890 endtran(
DBC *d, SQLSMALLINT comptype)
04891 {
04892
int fail = 0, ret;
04893
char *sql, *errp = NULL;
04894
04895
if (!d->
sqlite) {
04896
setstatd(d, -1,
"not connected", (*d->
ov3) ?
"HY000" :
"S1000");
04897
return SQL_ERROR;
04898 }
04899
if (d->
autocommit || !d->
intrans) {
04900
return SQL_SUCCESS;
04901 }
04902
switch (comptype) {
04903
case SQL_COMMIT:
04904 sql =
"COMMIT TRANSACTION";
04905
goto doit;
04906
case SQL_ROLLBACK:
04907 rollback:
04908 sql =
"ROLLBACK TRANSACTION";
04909 doit:
04910 d->
intrans = 0;
04911 ret = sqlite_exec(d->
sqlite, sql, NULL, NULL, &errp);
04912
dbtracerc(d, ret, errp);
04913
if (ret != SQLITE_OK) {
04914
if (!fail) {
04915
setstatd(d, ret,
"%s", (*d->
ov3) ?
"HY000" :
"S1000",
04916 errp ? errp :
"transaction failed");
04917
if (errp) {
04918 sqlite_freemem(errp);
04919 errp = NULL;
04920 }
04921 fail = 1;
04922
goto rollback;
04923 }
04924
if (errp) {
04925 sqlite_freemem(errp);
04926 errp = NULL;
04927 }
04928
return SQL_ERROR;
04929 }
04930
if (errp) {
04931 sqlite_freemem(errp);
04932 errp = NULL;
04933 }
04934
return SQL_SUCCESS;
04935 }
04936
setstatd(d, -1,
"invalid completion type", (*d->
ov3) ?
"HY000" :
"S1000");
04937
return SQL_ERROR;
04938 }
04939
04948
static SQLRETURN
04949 drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
04950 {
04951
DBC *d;
04952
int fail = 0;
04953
04954
switch (type) {
04955
case SQL_HANDLE_DBC:
04956
if (handle == SQL_NULL_HDBC) {
04957
return SQL_INVALID_HANDLE;
04958 }
04959 d = (
DBC *) handle;
04960
return endtran(d, comptype);
04961
case SQL_HANDLE_ENV:
04962
if (handle == SQL_NULL_HENV) {
04963
return SQL_INVALID_HANDLE;
04964 }
04965 d = ((
ENV *) handle)->dbcs;
04966
while (d) {
04967 SQLRETURN ret;
04968
04969 ret =
endtran(d, comptype);
04970
if (ret != SQL_SUCCESS) {
04971 fail++;
04972 comptype = SQL_ROLLBACK;
04973 }
04974 d = d->
next;
04975 }
04976
return fail ? SQL_ERROR : SQL_SUCCESS;
04977 }
04978
return SQL_INVALID_HANDLE;
04979 }
04980
04989 SQLRETURN SQL_API
04990 SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
04991 {
04992
return drvendtran(type, handle, comptype);
04993 }
04994
05003 SQLRETURN SQL_API
05004 SQLTransact(SQLHENV env, SQLHDBC
dbc, UWORD type)
05005 {
05006
if (env != SQL_NULL_HENV) {
05007
return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
05008 }
05009
return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
05010 }
05011
05016 SQLRETURN SQL_API
05017 SQLCopyDesc(SQLHDESC source, SQLHDESC target)
05018 {
05019
return SQL_ERROR;
05020 }
05021
05022
#ifndef SQLITE_UTF8
05023
05034 SQLRETURN SQL_API
05035 SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
05036 SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
05037 {
05038
int outLen = 0;
05039
05040
if (sqlinLen == SQL_NTS) {
05041 sqlinLen = strlen(sqlin);
05042 }
05043
if (sql) {
05044
if (sqlMax > 0) {
05045 strncpy(sql, sqlin, sqlMax - 1);
05046 sqlin[sqlMax - 1] =
'\0';
05047 outLen =
min(sqlMax - 1, sqlinLen);
05048 }
05049 }
else {
05050 outLen = sqlinLen;
05051 }
05052
if (sqlLen) {
05053 *sqlLen = outLen;
05054 }
05055
if (sql && outLen < sqlinLen) {
05056
setstat((
STMT *) stmt, -1,
"data right truncated",
"01004");
05057
return SQL_SUCCESS_WITH_INFO;
05058 }
05059
return SQL_SUCCESS;
05060 }
05061
#endif
05062
05063
#ifdef SQLITE_UTF8
05064
05075 SQLRETURN SQL_API
05076 SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
05077 SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
05078 {
05079
int outLen = 0;
05080
05081
if (sqlinLen == SQL_NTS) {
05082 sqlinLen = uc_strlen(sqlin);
05083 }
05084
if (sql) {
05085
if (sqlMax > 0) {
05086 uc_strncpy(sql, sqlin, sqlMax - 1);
05087 sqlin[sqlMax - 1] = 0;
05088 outLen =
min(sqlMax - 1, sqlinLen);
05089 }
05090 }
else {
05091 outLen = sqlinLen;
05092 }
05093
if (sqlLen) {
05094 *sqlLen = outLen;
05095 }
05096
if (sql && outLen < sqlinLen) {
05097
setstat((
STMT *) stmt, -1,
"data right truncated",
"01004");
05098
return SQL_SUCCESS_WITH_INFO;
05099 }
05100
return SQL_SUCCESS;
05101 }
05102
#endif
05103
05108 static COL procSpec[] = {
05109 {
"SYSTEM",
"PROCEDURE",
"PROCEDURE_QUALIFIER",
SCOL_VARCHAR, 50 },
05110 {
"SYSTEM",
"PROCEDURE",
"PROCEDURE_OWNER",
SCOL_VARCHAR, 50 },
05111 {
"SYSTEM",
"PROCEDURE",
"PROCEDURE_NAME",
SCOL_VARCHAR, 255 },
05112 {
"SYSTEM",
"PROCEDURE",
"NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
05113 {
"SYSTEM",
"PROCEDURE",
"NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
05114 {
"SYSTEM",
"PROCEDURE",
"NUM_RESULT_SETS", SQL_SMALLINT, 5 },
05115 {
"SYSTEM",
"PROCEDURE",
"REMARKS",
SCOL_VARCHAR, 255 },
05116 {
"SYSTEM",
"PROCEDURE",
"PROCEDURE_TYPE", SQL_SMALLINT, 5 }
05117 };
05118
05119
#ifndef SQLITE_UTF8
05120
05132 SQLRETURN SQL_API
05133 SQLProcedures(SQLHSTMT stmt,
05134 SQLCHAR *catalog, SQLSMALLINT catalogLen,
05135 SQLCHAR *schema, SQLSMALLINT schemaLen,
05136 SQLCHAR *proc, SQLSMALLINT procLen)
05137 {
05138
return mkresultset(stmt,
procSpec,
array_size(
procSpec));
05139 }
05140
#endif
05141
05142
#ifdef SQLITE_UTF8
05143
05155 SQLRETURN SQL_API
05156 SQLProceduresW(SQLHSTMT stmt,
05157 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
05158 SQLWCHAR *schema, SQLSMALLINT schemaLen,
05159 SQLWCHAR *proc, SQLSMALLINT procLen)
05160 {
05161
return mkresultset(stmt, procSpec,
array_size(procSpec));
05162 }
05163
#endif
05164
05169 static COL procColSpec[] = {
05170 {
"SYSTEM",
"PROCCOL",
"PROCEDURE_QUALIFIER",
SCOL_VARCHAR, 50 },
05171 {
"SYSTEM",
"PROCCOL",
"PROCEDURE_OWNER",
SCOL_VARCHAR, 50 },
05172 {
"SYSTEM",
"PROCCOL",
"PROCEDURE_NAME",
SCOL_VARCHAR, 255 },
05173 {
"SYSTEM",
"PROCCOL",
"COLUMN_NAME",
SCOL_VARCHAR, 255 },
05174 {
"SYSTEM",
"PROCCOL",
"COLUMN_TYPE", SQL_SMALLINT, 5 },
05175 {
"SYSTEM",
"PROCCOL",
"DATA_TYPE", SQL_SMALLINT, 5 },
05176 {
"SYSTEM",
"PROCCOL",
"TYPE_NAME",
SCOL_VARCHAR, 50 },
05177 {
"SYSTEM",
"PROCCOL",
"PRECISION", SQL_INTEGER, 10 },
05178 {
"SYSTEM",
"PROCCOL",
"LENGTH", SQL_INTEGER, 10 },
05179 {
"SYSTEM",
"PROCCOL",
"RADIX", SQL_SMALLINT, 5 },
05180 {
"SYSTEM",
"PROCCOL",
"SCALE", SQL_SMALLINT, 5 },
05181 {
"SYSTEM",
"PROCCOL",
"NULLABLE", SQL_SMALLINT, 5 },
05182 {
"SYSTEM",
"PROCCOL",
"REMARKS",
SCOL_VARCHAR, 50 },
05183 {
"SYSTEM",
"PROCCOL",
"COLUMN_DEF",
SCOL_VARCHAR, 50 },
05184 {
"SYSTEM",
"PROCCOL",
"SQL_DATA_TYPE", SQL_SMALLINT, 5 },
05185 {
"SYSTEM",
"PROCCOL",
"SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
05186 {
"SYSTEM",
"PROCCOL",
"CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
05187 {
"SYSTEM",
"PROCCOL",
"ORDINAL_POSITION", SQL_SMALLINT, 5 },
05188 {
"SYSTEM",
"PROCCOL",
"IS_NULLABLE",
SCOL_VARCHAR, 50 }
05189 };
05190
05191
#ifndef SQLITE_UTF8
05192
05206 SQLRETURN SQL_API
05207 SQLProcedureColumns(SQLHSTMT stmt,
05208 SQLCHAR *catalog, SQLSMALLINT catalogLen,
05209 SQLCHAR *schema, SQLSMALLINT schemaLen,
05210 SQLCHAR *proc, SQLSMALLINT procLen,
05211 SQLCHAR *column, SQLSMALLINT columnLen)
05212 {
05213
return mkresultset(stmt,
procColSpec,
array_size(
procColSpec));
05214
05215 }
05216
#endif
05217
05218
#ifdef SQLITE_UTF8
05219
05234 SQLRETURN SQL_API
05235 SQLProcedureColumnsW(SQLHSTMT stmt,
05236 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
05237 SQLWCHAR *schema, SQLSMALLINT schemaLen,
05238 SQLWCHAR *proc, SQLSMALLINT procLen,
05239 SQLWCHAR *column, SQLSMALLINT columnLen)
05240 {
05241
return mkresultset(stmt, procColSpec,
array_size(procColSpec));
05242 }
05243
#endif
05244
05255 SQLRETURN SQL_API
05256 SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
05257 SQLINTEGER len, SQLINTEGER *lenp)
05258 {
05259
ENV *e;
05260
05261
if (env == SQL_NULL_HENV) {
05262
return SQL_INVALID_HANDLE;
05263 }
05264 e = (
ENV *) env;
05265
if (!e || e->
magic !=
ENV_MAGIC) {
05266
return SQL_INVALID_HANDLE;
05267 }
05268
switch (attr) {
05269
case SQL_ATTR_CONNECTION_POOLING:
05270
return SQL_ERROR;
05271
case SQL_ATTR_CP_MATCH:
05272
return SQL_NO_DATA;
05273
case SQL_ATTR_OUTPUT_NTS:
05274
if (val) {
05275 *((SQLINTEGER *) val) = SQL_TRUE;
05276 }
05277
if (lenp) {
05278 *lenp =
sizeof (SQLINTEGER);
05279 }
05280
return SQL_SUCCESS;
05281
case SQL_ATTR_ODBC_VERSION:
05282
if (val) {
05283 *((SQLINTEGER *) val) = e->
ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
05284 }
05285
if (lenp) {
05286 *lenp =
sizeof (SQLINTEGER);
05287 }
05288
return SQL_SUCCESS;
05289 }
05290
return SQL_ERROR;
05291 }
05292
05302 SQLRETURN SQL_API
05303 SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
05304 {
05305
ENV *e;
05306
05307
if (env == SQL_NULL_HENV) {
05308
return SQL_INVALID_HANDLE;
05309 }
05310 e = (
ENV *) env;
05311
if (!e || e->
magic !=
ENV_MAGIC) {
05312
return SQL_INVALID_HANDLE;
05313 }
05314
switch (attr) {
05315
case SQL_ATTR_CONNECTION_POOLING:
05316
return SQL_SUCCESS;
05317
case SQL_ATTR_CP_MATCH:
05318
return SQL_NO_DATA;
05319
case SQL_ATTR_OUTPUT_NTS:
05320
if ((SQLINTEGER) val == SQL_TRUE) {
05321
return SQL_SUCCESS;
05322 }
05323
return SQL_ERROR;
05324
case SQL_ATTR_ODBC_VERSION:
05325
if (!val) {
05326
return SQL_ERROR;
05327 }
05328
if ((SQLINTEGER) val == SQL_OV_ODBC2) {
05329 e->
ov3 = 0;
05330
return SQL_SUCCESS;
05331 }
05332
if ((SQLINTEGER) val == SQL_OV_ODBC3) {
05333 e->
ov3 = 1;
05334
return SQL_SUCCESS;
05335 }
05336
return SQL_ERROR;
05337 }
05338
return SQL_ERROR;
05339 }
05340
05354
static SQLRETURN
05355 drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
05356 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
05357 SQLSMALLINT buflen, SQLSMALLINT *msglen)
05358 {
05359
DBC *d = NULL;
05360
STMT *s = NULL;
05361
int len, naterr;
05362
char *logmsg, *sqlst;
05363
05364
if (handle == SQL_NULL_HANDLE) {
05365
return SQL_INVALID_HANDLE;
05366 }
05367
if (sqlstate) {
05368 sqlstate[0] =
'\0';
05369 }
05370
if (msg && buflen > 0) {
05371 msg[0] =
'\0';
05372 }
05373
if (msglen) {
05374 *msglen = 0;
05375 }
05376
if (nativeerr) {
05377 *nativeerr = 0;
05378 }
05379
switch (htype) {
05380
case SQL_HANDLE_ENV:
05381
case SQL_HANDLE_DESC:
05382
return SQL_NO_DATA;
05383
case SQL_HANDLE_DBC:
05384 d = (
DBC *) handle;
05385 logmsg = d->
logmsg;
05386 sqlst = d->
sqlstate;
05387 naterr = d->
naterr;
05388
break;
05389
case SQL_HANDLE_STMT:
05390 s = (
STMT *) handle;
05391 logmsg = s->
logmsg;
05392 sqlst = s->
sqlstate;
05393 naterr = s->
naterr;
05394
break;
05395
default:
05396
return SQL_INVALID_HANDLE;
05397 }
05398
if (buflen < 0) {
05399
return SQL_ERROR;
05400 }
05401
if (recno > 1) {
05402
return SQL_NO_DATA;
05403 }
05404 len = strlen(logmsg);
05405
if (len == 0) {
05406
return SQL_NO_DATA;
05407 }
05408
if (nativeerr) {
05409 *nativeerr = naterr;
05410 }
05411
if (sqlstate) {
05412 strcpy(sqlstate, sqlst);
05413 }
05414
if (msglen) {
05415 *msglen = len;
05416 }
05417
if (len >= buflen) {
05418
if (msg && buflen > 0) {
05419 strncpy(msg, logmsg, buflen);
05420 msg[buflen - 1] =
'\0';
05421 logmsg[0] =
'\0';
05422 }
05423 }
else if (msg) {
05424 strcpy(msg, logmsg);
05425 logmsg[0] =
'\0';
05426 }
05427
return SQL_SUCCESS;
05428 }
05429
05430
#ifndef SQLITE_UTF8
05431
05444 SQLRETURN SQL_API
05445 SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
05446 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
05447 SQLSMALLINT buflen, SQLSMALLINT *msglen)
05448 {
05449
return drvgetdiagrec(htype, handle, recno, sqlstate,
05450 nativeerr, msg, buflen, msglen);
05451 }
05452
#endif
05453
05454
#if !defined(HAVE_UNIXODBC) || !HAVE_UNIXODBC
05455
#ifdef SQLITE_UTF8
05456
05470 SQLRETURN SQL_API
05471 SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
05472 SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
05473 SQLSMALLINT buflen, SQLSMALLINT *msglen)
05474 {
05475
char state[16];
05476 SQLSMALLINT len;
05477 SQLRETURN ret;
05478
05479 ret =
drvgetdiagrec(htype, handle, recno, state,
05480 nativeerr, (
char *) msg, buflen, &len);
05481
if (ret == SQL_SUCCESS) {
05482
if (sqlstate) {
05483 uc_from_utf_buf(state, sqlstate, 6 *
sizeof (SQLWCHAR));
05484 }
05485
if (msg) {
05486
if (len > 0) {
05487 SQLWCHAR *m = NULL;
05488
05489 m = uc_from_utf((
char *) msg, len);
05490
if (m) {
05491
if (buflen) {
05492 uc_strncpy(msg, m, buflen);
05493 len =
min(buflen, uc_strlen(m));
05494 }
else {
05495 len = uc_strlen(m);
05496 }
05497 uc_free(m);
05498 }
else {
05499 len = 0;
05500 }
05501 }
05502
if (len <= 0) {
05503 len = 0;
05504
if (buflen > 0) {
05505 msg[0] = 0;
05506 }
05507 }
05508 }
else {
05509 len = 0;
05510 }
05511
if (msglen) {
05512 *msglen = len;
05513 }
05514 }
else if (ret == SQL_NO_DATA) {
05515
if (sqlstate) {
05516 sqlstate[0] = 0;
05517 }
05518
if (msg) {
05519
if (buflen > 0) {
05520 msg[0] = 0;
05521 }
05522 }
05523
if (msglen) {
05524 *msglen = 0;
05525 }
05526 }
05527
return ret;
05528 }
05529
#endif
05530
#endif
05531
05532
#ifndef SQLITE_UTF8
05533
05537 SQLRETURN SQL_API
05538 SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
05539 SQLSMALLINT
id, SQLPOINTER info,
05540 SQLSMALLINT buflen, SQLSMALLINT *strlen)
05541 {
05542
return SQL_ERROR;
05543 }
05544
#endif
05545
05546
#ifdef SQLITE_UTF8
05547
05551 SQLRETURN SQL_API
05552 SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
05553 SQLSMALLINT
id, SQLPOINTER info,
05554 SQLSMALLINT buflen, SQLSMALLINT *strlen)
05555 {
05556
return SQL_ERROR;
05557 }
05558
#endif
05559
05570
static SQLRETURN
05571 drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
05572 SQLINTEGER bufmax, SQLINTEGER *buflen)
05573 {
05574
STMT *s = (
STMT *) stmt;
05575 SQLUINTEGER *uval = (SQLUINTEGER *) val;
05576
05577
switch (attr) {
05578
case SQL_ATTR_CURSOR_TYPE:
05579 *uval = s->
curtype;
05580
return SQL_SUCCESS;
05581
case SQL_ATTR_CURSOR_SCROLLABLE:
05582 *uval = s->
curtype != SQL_CURSOR_FORWARD_ONLY ?
05583 SQL_SCROLLABLE : SQL_NONSCROLLABLE;
05584
return SQL_SUCCESS;
05585
#ifdef SQL_ATTR_CURSOR_SENSITIVITY
05586
case SQL_ATTR_CURSOR_SENSITIVITY:
05587 *uval = SQL_UNSPECIFIED;
05588
return SQL_SUCCESS;
05589
#endif
05590
case SQL_ATTR_ROW_NUMBER:
05591 {
05592
STMT *s = (
STMT *) stmt;
05593
DBC *d = (
DBC *) s->
dbc;
05594
05595
if (s == d->
vm_stmt) {
05596 *uval = d->
vm_rownum < 0 ?
05597 SQL_ROW_NUMBER_UNKNOWN : d->
vm_rownum;
05598 }
05599 }
05600 *uval = s->
rowp < 0 ? SQL_ROW_NUMBER_UNKNOWN : s->
rowp;
05601
return SQL_SUCCESS;
05602
case SQL_ATTR_ASYNC_ENABLE:
05603 *uval = SQL_ASYNC_ENABLE_OFF;
05604
return SQL_SUCCESS;
05605
case SQL_CONCURRENCY:
05606 *uval = SQL_CONCUR_LOCK;
05607
return SQL_SUCCESS;
05608
case SQL_ATTR_RETRIEVE_DATA:
05609 *uval = SQL_RD_ON;
05610
return SQL_SUCCESS;
05611
case SQL_ROWSET_SIZE:
05612
case SQL_ATTR_ROW_ARRAY_SIZE:
05613 *uval = s->
rowset_size;
05614
return SQL_SUCCESS;
05615
05616
case SQL_ATTR_IMP_ROW_DESC:
05617
case SQL_ATTR_APP_ROW_DESC:
05618
case SQL_ATTR_IMP_PARAM_DESC:
05619
case SQL_ATTR_APP_PARAM_DESC:
05620 *((SQLHDESC *) val) = (SQLHDESC)
DEAD_MAGIC;
05621
return SQL_SUCCESS;
05622
case SQL_ATTR_ROW_STATUS_PTR:
05623 *((SQLUSMALLINT **) val) = s->
row_status;
05624
return SQL_SUCCESS;
05625
case SQL_ATTR_ROWS_FETCHED_PTR:
05626 *((SQLUINTEGER **) val) = s->
row_count;
05627
return SQL_SUCCESS;
05628
case SQL_ATTR_USE_BOOKMARKS: {
05629
STMT *s = (
STMT *) stmt;
05630
05631 *(SQLUINTEGER *) val = s->
bkmrk ? SQL_UB_ON : SQL_UB_OFF;
05632
return SQL_SUCCESS;
05633 }
05634
case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
05635 *((SQLUINTEGER **) val) = s->
bind_offs;
05636
return SQL_SUCCESS;
05637
case SQL_ATTR_PARAM_BIND_TYPE:
05638 *((SQLUINTEGER *) val) = SQL_PARAM_BIND_BY_COLUMN;
05639
return SQL_SUCCESS;
05640
case SQL_ATTR_PARAM_OPERATION_PTR:
05641 *((SQLUSMALLINT **) val) = s->
parm_oper;
05642
return SQL_SUCCESS;
05643
case SQL_ATTR_PARAM_STATUS_PTR:
05644 *((SQLUSMALLINT **) val) = s->
parm_status;
05645
return SQL_SUCCESS;
05646
case SQL_ATTR_PARAMS_PROCESSED_PTR:
05647 *((SQLUINTEGER **) val) = s->
parm_proc;
05648
return SQL_SUCCESS;
05649
case SQL_ATTR_PARAMSET_SIZE:
05650 *((SQLUINTEGER *) val) = s->
paramset_size;
05651
return SQL_SUCCESS;
05652
case SQL_ATTR_ROW_BIND_TYPE:
05653 *(SQLUINTEGER *) val = s->
bind_type;
05654
return SQL_SUCCESS;
05655 }
05656
return drvunimplstmt(stmt);
05657 }
05658
05659
#if (defined(HAVE_UNIXODBC) && HAVE_UNIXODBC) || !defined(SQLITE_UTF8)
05660
05670 SQLRETURN SQL_API
05671 SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
05672 SQLINTEGER bufmax, SQLINTEGER *buflen)
05673 {
05674
return drvgetstmtattr(stmt, attr, val, bufmax, buflen);
05675 }
05676
#endif
05677
05678
#ifdef SQLITE_UTF8
05679
05689 SQLRETURN SQL_API
05690 SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
05691 SQLINTEGER bufmax, SQLINTEGER *buflen)
05692 {
05693
return drvgetstmtattr(stmt, attr, val, bufmax, buflen);
05694 }
05695
#endif
05696
05706
static SQLRETURN
05707 drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
05708 SQLINTEGER buflen)
05709 {
05710
STMT *s = (
STMT *) stmt;
05711
05712
switch (attr) {
05713
case SQL_ATTR_CURSOR_TYPE:
05714
if ((SQLUINTEGER) val == SQL_CURSOR_FORWARD_ONLY) {
05715 s->
curtype = SQL_CURSOR_FORWARD_ONLY;
05716 }
else {
05717 s->
curtype = SQL_CURSOR_STATIC;
05718 }
05719
if ((SQLUINTEGER) val != SQL_CURSOR_FORWARD_ONLY &&
05720 (SQLUINTEGER) val != SQL_CURSOR_STATIC) {
05721
goto e01s02;
05722 }
05723
return SQL_SUCCESS;
05724
case SQL_ATTR_CURSOR_SCROLLABLE:
05725
if ((SQLUINTEGER) val == SQL_NONSCROLLABLE) {
05726 s->
curtype = SQL_CURSOR_FORWARD_ONLY;
05727 }
else {
05728 s->
curtype = SQL_CURSOR_STATIC;
05729 }
05730
return SQL_SUCCESS;
05731
case SQL_ATTR_ASYNC_ENABLE:
05732
if ((SQLUINTEGER) val != SQL_ASYNC_ENABLE_OFF) {
05733 e01s02:
05734
setstat(s, -1,
"option value changed",
"01S02");
05735
return SQL_SUCCESS_WITH_INFO;
05736 }
05737
return SQL_SUCCESS;
05738
case SQL_CONCURRENCY:
05739
if ((SQLUINTEGER) val != SQL_CONCUR_LOCK) {
05740
goto e01s02;
05741 }
05742
return SQL_SUCCESS;
05743
case SQL_ATTR_QUERY_TIMEOUT:
05744
return SQL_SUCCESS;
05745
case SQL_ATTR_RETRIEVE_DATA:
05746
if ((SQLUINTEGER) val != SQL_RD_ON &&
05747 (SQLUINTEGER) val != SQL_RD_OFF) {
05748
goto e01s02;
05749 }
05750
return SQL_SUCCESS;
05751
case SQL_ROWSET_SIZE:
05752
case SQL_ATTR_ROW_ARRAY_SIZE:
05753
if ((SQLUINTEGER) val < 1) {
05754
setstat(s, -1,
"invalid rowset size",
"HY000");
05755
return SQL_ERROR;
05756 }
else {
05757 SQLUSMALLINT *rst = &s->
row_status1;
05758
05759
if ((SQLUINTEGER) val > 1) {
05760 rst =
xmalloc(
sizeof (SQLUSMALLINT) * (SQLUINTEGER) val);
05761
if (!rst) {
05762
return nomem(s);
05763 }
05764 }
05765
if (s->
row_status0 != &s->
row_status1) {
05766
freep(&s->
row_status0);
05767 }
05768 s->
row_status0 = rst;
05769 s->
rowset_size = (SQLUINTEGER) val;
05770 }
05771
return SQL_SUCCESS;
05772
case SQL_ATTR_ROW_STATUS_PTR:
05773 s->
row_status = (SQLUSMALLINT *) val;
05774
return SQL_SUCCESS;
05775
case SQL_ATTR_ROWS_FETCHED_PTR:
05776 s->
row_count = (SQLUINTEGER *) val;
05777
return SQL_SUCCESS;
05778
case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
05779 s->
bind_offs = (SQLUINTEGER *) val;
05780
return SQL_SUCCESS;
05781
case SQL_ATTR_PARAM_BIND_TYPE:
05782
if ((SQLUINTEGER) val != SQL_PARAM_BIND_BY_COLUMN) {
05783
goto e01s02;
05784 }
05785
return SQL_SUCCESS;
05786
case SQL_ATTR_PARAM_OPERATION_PTR:
05787 s->
parm_oper = (SQLUSMALLINT *) val;
05788
return SQL_SUCCESS;
05789
case SQL_ATTR_PARAM_STATUS_PTR:
05790 s->
parm_status = (SQLUSMALLINT *) val;
05791
return SQL_SUCCESS;
05792
case SQL_ATTR_PARAMS_PROCESSED_PTR:
05793 s->
parm_proc = (SQLUINTEGER *) val;
05794
return SQL_SUCCESS;
05795
case SQL_ATTR_PARAMSET_SIZE:
05796
if ((SQLUINTEGER) val < 1) {
05797
goto e01s02;
05798 }
05799 s->
paramset_size = (SQLUINTEGER) val;
05800 s->
paramset_count = 0;
05801
return SQL_SUCCESS;
05802
case SQL_ATTR_ROW_BIND_TYPE:
05803 s->
bind_type = (SQLUINTEGER) val;
05804
return SQL_SUCCESS;
05805
case SQL_ATTR_USE_BOOKMARKS:
05806
if ((SQLUINTEGER) val != SQL_UB_OFF &&
05807 (SQLUINTEGER) val != SQL_UB_ON) {
05808
goto e01s02;
05809 }
05810 s->
bkmrk = (SQLUINTEGER) val == SQL_UB_ON;
05811
return SQL_SUCCESS;
05812 }
05813
return drvunimplstmt(stmt);
05814 }
05815
05816
#if (defined(HAVE_UNIXODBC) && HAVE_UNIXODBC) || !defined(SQLITE_UTF8)
05817
05826 SQLRETURN SQL_API
05827 SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
05828 SQLINTEGER buflen)
05829 {
05830
return drvsetstmtattr(stmt, attr, val, buflen);
05831 }
05832
#endif
05833
05834
#ifdef SQLITE_UTF8
05835
05844 SQLRETURN SQL_API
05845 SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
05846 SQLINTEGER buflen)
05847 {
05848
return drvsetstmtattr(stmt, attr, val, buflen);
05849 }
05850
#endif
05851
05860
static SQLRETURN
05861 drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
05862 {
05863
STMT *s = (
STMT *) stmt;
05864 SQLUINTEGER *ret = (SQLUINTEGER *) param;
05865
05866
switch (opt) {
05867
case SQL_CURSOR_TYPE:
05868 *ret = s->
curtype;
05869
return SQL_SUCCESS;
05870
case SQL_ROW_NUMBER:
05871 {
05872
DBC *d = (
DBC *) s->
dbc;
05873
05874
if (s == d->
vm_stmt) {
05875 *ret = d->
vm_rownum < 0 ?
05876 SQL_ROW_NUMBER_UNKNOWN : d->
vm_rownum;
05877 }
05878 }
05879 *ret = s->
rowp < 0 ? SQL_ROW_NUMBER_UNKNOWN : s->
rowp;
05880
return SQL_SUCCESS;
05881
case SQL_ASYNC_ENABLE:
05882 *ret = SQL_ASYNC_ENABLE_OFF;
05883
return SQL_SUCCESS;
05884
case SQL_CONCURRENCY:
05885 *ret = SQL_CONCUR_LOCK;
05886
return SQL_SUCCESS;
05887
case SQL_ATTR_RETRIEVE_DATA:
05888 *ret = SQL_RD_ON;
05889
return SQL_SUCCESS;
05890
case SQL_ROWSET_SIZE:
05891
case SQL_ATTR_ROW_ARRAY_SIZE:
05892 *ret = s->
rowset_size;
05893
return SQL_SUCCESS;
05894 }
05895
return drvunimplstmt(stmt);
05896 }
05897
05906 SQLRETURN SQL_API
05907 SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
05908 {
05909
return drvgetstmtoption(stmt, opt, param);
05910 }
05911
05912
#ifdef SQLITE_UTF8
05913
05921 SQLRETURN SQL_API
05922 SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
05923 {
05924
return drvgetstmtoption(stmt, opt, param);
05925 }
05926
#endif
05927
05936
static SQLRETURN
05937 drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
05938 {
05939
STMT *s = (
STMT *) stmt;
05940
05941
switch (opt) {
05942
case SQL_CURSOR_TYPE:
05943
if (param == SQL_CURSOR_FORWARD_ONLY) {
05944 s->
curtype = param;
05945 }
else {
05946 s->
curtype = SQL_CURSOR_STATIC;
05947 }
05948
if (param != SQL_CURSOR_FORWARD_ONLY &&
05949 param != SQL_CURSOR_STATIC) {
05950
goto e01s02;
05951 }
05952
return SQL_SUCCESS;
05953
case SQL_ASYNC_ENABLE:
05954
if (param != SQL_ASYNC_ENABLE_OFF) {
05955
goto e01s02;
05956 }
05957
return SQL_SUCCESS;
05958
case SQL_CONCURRENCY:
05959
if (param != SQL_CONCUR_LOCK) {
05960
goto e01s02;
05961 }
05962
return SQL_SUCCESS;
05963
case SQL_QUERY_TIMEOUT:
05964
return SQL_SUCCESS;
05965
case SQL_RETRIEVE_DATA:
05966
if (param != SQL_RD_ON && param != SQL_RD_OFF) {
05967 e01s02:
05968
setstat(s, -1,
"option value changed",
"01S02");
05969
return SQL_SUCCESS_WITH_INFO;
05970 }
05971
return SQL_SUCCESS;
05972
case SQL_ROWSET_SIZE:
05973
case SQL_ATTR_ROW_ARRAY_SIZE:
05974
if (param < 1) {
05975
setstat(s, -1,
"invalid rowset size",
"HY000");
05976
return SQL_ERROR;
05977 }
else {
05978 SQLUSMALLINT *rst = &s->
row_status1;
05979
05980
if (param > 1) {
05981 rst =
xmalloc(
sizeof (SQLUSMALLINT) * param);
05982
if (!rst) {
05983
return nomem(s);
05984 }
05985 }
05986
if (s->
row_status0 != &s->
row_status1) {
05987
freep(&s->
row_status0);
05988 }
05989 s->
row_status0 = rst;
05990 s->
rowset_size = param;
05991 }
05992
return SQL_SUCCESS;
05993 }
05994
return drvunimplstmt(stmt);
05995 }
05996
06005 SQLRETURN SQL_API
06006 SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
06007 {
06008
return drvsetstmtoption(stmt, opt, param);
06009 }
06010
06011
#ifdef SQLITE_UTF8
06012
06020 SQLRETURN SQL_API
06021 SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
06022 {
06023
return drvsetstmtoption(stmt, opt, param);
06024 }
06025
#endif
06026
06031 SQLRETURN SQL_API
06032 SQLSetPos(SQLHSTMT stmt, SQLUSMALLINT row, SQLUSMALLINT op, SQLUSMALLINT lock)
06033 {
06034
return drvunimplstmt(stmt);
06035 }
06036
06041 SQLRETURN SQL_API
06042 SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLINTEGER rowkeyset,
06043 SQLUSMALLINT rowset)
06044 {
06045
return drvunimplstmt(stmt);
06046 }
06047
06048 #define strmak(dst, src, max, lenp) { \
06049
int len = strlen(src); \
06050
int cnt = min(len + 1, max); \
06051
strncpy(dst, src, cnt); \
06052
*lenp = (cnt > len) ? len : cnt; \
06053
}
06054
06065
static SQLRETURN
06066 drvgetinfo(SQLHDBC
dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
06067 SQLSMALLINT *valLen)
06068 {
06069
DBC *d;
06070
char dummyc[16];
06071 SQLSMALLINT dummy;
06072
static char drvname[] =
06073
#ifdef _WIN32
06074
"sqliteodbc.dll";
06075
#else
06076
"sqliteodbc.so";
06077
#endif
06078
06079
if (dbc == SQL_NULL_HDBC) {
06080
return SQL_INVALID_HANDLE;
06081 }
06082 d = (
DBC *) dbc;
06083
if (valMax) {
06084 valMax--;
06085 }
06086
if (!valLen) {
06087 valLen = &dummy;
06088 }
06089
if (!val) {
06090 val = dummyc;
06091 valMax =
sizeof (dummyc) - 1;
06092 }
06093
switch (type) {
06094
case SQL_MAX_USER_NAME_LEN:
06095 *((SQLSMALLINT *) val) = 16;
06096 *valLen =
sizeof (SQLSMALLINT);
06097
break;
06098
case SQL_USER_NAME:
06099
strmak(val,
"", valMax, valLen);
06100
break;
06101
case SQL_DRIVER_ODBC_VER:
06102
#if 0
06103
strmak(val, (*d->
ov3) ?
"03.00" :
"02.50", valMax, valLen);
06104
#else
06105
strmak(val,
"03.00", valMax, valLen);
06106
#endif
06107
break;
06108
case SQL_ACTIVE_CONNECTIONS:
06109
case SQL_ACTIVE_STATEMENTS:
06110 *((SQLSMALLINT *) val) = 0;
06111 *valLen =
sizeof (SQLSMALLINT);
06112
break;
06113
#ifdef SQL_ASYNC_MODE
06114
case SQL_ASYNC_MODE:
06115 *((SQLUINTEGER *) val) = SQL_AM_NONE;
06116 *valLen =
sizeof (SQLUINTEGER);
06117
break;
06118
#endif
06119
#ifdef SQL_CREATE_TABLE
06120
case SQL_CREATE_TABLE:
06121 *((SQLUINTEGER *) val) = 0;
06122 *valLen =
sizeof (SQLUINTEGER);
06123
break;
06124
#endif
06125
#ifdef SQL_CREATE_VIEW
06126
case SQL_CREATE_VIEW:
06127 *((SQLUINTEGER *) val) = 0;
06128 *valLen =
sizeof (SQLUINTEGER);
06129
break;
06130
#endif
06131
case SQL_DATA_SOURCE_NAME:
06132
strmak(val, (d->
dsn ? d->
dsn :
""), valMax, valLen);
06133
break;
06134
case SQL_DRIVER_NAME:
06135
strmak(val, drvname, valMax, valLen);
06136
break;
06137
case SQL_DRIVER_VER:
06138
strmak(val,
"02.50", valMax, valLen);
06139
break;
06140
case SQL_FETCH_DIRECTION:
06141 *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
06142 SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
06143 *valLen =
sizeof (SQLUINTEGER);
06144
break;
06145
case SQL_ODBC_VER:
06146
strmak(val, (*d->
ov3) ?
"03.00" :
"02.50", valMax, valLen);
06147
break;
06148
case SQL_ODBC_SAG_CLI_CONFORMANCE:
06149 *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
06150 *valLen =
sizeof (SQLSMALLINT);
06151
break;
06152
case SQL_STANDARD_CLI_CONFORMANCE:
06153 *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
06154 *valLen =
sizeof (SQLUINTEGER);
06155
break;
06156
case SQL_SERVER_NAME:
06157
case SQL_DATABASE_NAME:
06158
strmak(val, (d->
dbname ? d->
dbname :
""), valMax, valLen);
06159
break;
06160
case SQL_SEARCH_PATTERN_ESCAPE:
06161
strmak(val,
"", valMax, valLen);
06162
break;
06163
case SQL_ODBC_SQL_CONFORMANCE:
06164 *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
06165 *valLen =
sizeof (SQLSMALLINT);
06166
break;
06167
case SQL_ODBC_API_CONFORMANCE:
06168 *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
06169 *valLen =
sizeof (SQLSMALLINT);
06170
break;
06171
case SQL_DBMS_NAME:
06172
strmak(val,
"SQLite", valMax, valLen);
06173
break;
06174
case SQL_DBMS_VER:
06175
strmak(val, SQLITE_VERSION, valMax, valLen);
06176
break;
06177
case SQL_NEED_LONG_DATA_LEN:
06178
strmak(val,
"Y", valMax, valLen);
06179
break;
06180
case SQL_ROW_UPDATES:
06181
case SQL_ACCESSIBLE_PROCEDURES:
06182
case SQL_PROCEDURES:
06183
case SQL_EXPRESSIONS_IN_ORDERBY:
06184
case SQL_ODBC_SQL_OPT_IEF:
06185
case SQL_LIKE_ESCAPE_CLAUSE:
06186
case SQL_ORDER_BY_COLUMNS_IN_SELECT:
06187
case SQL_OUTER_JOINS:
06188
case SQL_COLUMN_ALIAS:
06189
case SQL_ACCESSIBLE_TABLES:
06190
case SQL_MULT_RESULT_SETS:
06191
case SQL_MULTIPLE_ACTIVE_TXN:
06192
case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
06193
strmak(val,
"N", valMax, valLen);
06194
break;
06195
case SQL_DATA_SOURCE_READ_ONLY:
06196
strmak(val,
"N", valMax, valLen);
06197
break;
06198
#ifdef SQL_OJ_CAPABILITIES
06199
case SQL_OJ_CAPABILITIES:
06200 *((SQLUINTEGER *) val) = 0;
06201 *valLen =
sizeof (SQLUINTEGER);
06202
break;
06203
#endif
06204
#ifdef SQL_MAX_IDENTIFIER_LEN
06205
case SQL_MAX_IDENTIFIER_LEN:
06206 *((SQLUSMALLINT *) val) = 255;
06207 *valLen =
sizeof (SQLUSMALLINT);
06208
break;
06209
#endif
06210
case SQL_CONCAT_NULL_BEHAVIOR:
06211 *((SQLSMALLINT *) val) = SQL_CB_NULL;
06212 *valLen =
sizeof (SQLSMALLINT);
06213
break;
06214
case SQL_CURSOR_COMMIT_BEHAVIOR:
06215
case SQL_CURSOR_ROLLBACK_BEHAVIOR:
06216 *((SQLSMALLINT *) val) = SQL_CB_DELETE;
06217 *valLen =
sizeof (SQLSMALLINT);
06218
break;
06219
#ifdef SQL_CURSOR_SENSITIVITY
06220
case SQL_CURSOR_SENSITIVITY:
06221 *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
06222 *valLen =
sizeof (SQLUINTEGER);
06223
break;
06224
#endif
06225
case SQL_DEFAULT_TXN_ISOLATION:
06226 *((SQLUINTEGER *) val) = SQL_TXN_READ_UNCOMMITTED;
06227 *valLen =
sizeof (SQLUINTEGER);
06228
break;
06229
#ifdef SQL_DESCRIBE_PARAMETER
06230
case SQL_DESCRIBE_PARAMETER:
06231
strmak(val,
"Y", valMax, valLen);
06232
break;
06233
#endif
06234
case SQL_TXN_ISOLATION_OPTION:
06235 *((SQLUINTEGER *) val) = SQL_TXN_READ_UNCOMMITTED;
06236 *valLen =
sizeof (SQLUINTEGER);
06237
break;
06238
case SQL_IDENTIFIER_CASE:
06239 *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
06240 *valLen =
sizeof (SQLSMALLINT);
06241
break;
06242
case SQL_IDENTIFIER_QUOTE_CHAR:
06243
strmak(val,
"\"", valMax, valLen);
06244
break;
06245
case SQL_MAX_TABLE_NAME_LEN:
06246
case SQL_MAX_COLUMN_NAME_LEN:
06247 *((SQLSMALLINT *) val) = 255;
06248 *valLen =
sizeof (SQLSMALLINT);
06249
break;
06250
case SQL_MAX_CURSOR_NAME_LEN:
06251 *((SWORD *) val) = 255;
06252 *valLen =
sizeof (SWORD);
06253
break;
06254
case SQL_MAX_PROCEDURE_NAME_LEN:
06255 *((SQLSMALLINT *) val) = 0;
06256
break;
06257
case SQL_MAX_QUALIFIER_NAME_LEN:
06258
case SQL_MAX_OWNER_NAME_LEN:
06259 *((SQLSMALLINT *) val) = 255;
06260
break;
06261
case SQL_OWNER_TERM:
06262
strmak(val,
"owner", valMax, valLen);
06263
break;
06264
case SQL_PROCEDURE_TERM:
06265
strmak(val,
"procedure", valMax, valLen);
06266
break;
06267
case SQL_QUALIFIER_NAME_SEPARATOR:
06268
strmak(val,
".", valMax, valLen);
06269
break;
06270
case SQL_QUALIFIER_TERM:
06271
strmak(val,
"database", valMax, valLen);
06272
break;
06273
case SQL_QUALIFIER_USAGE:
06274 *((SQLUINTEGER *) val) = 0;
06275 *valLen =
sizeof (SQLUINTEGER);
06276
break;
06277
case SQL_SCROLL_CONCURRENCY:
06278 *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
06279 *valLen =
sizeof (SQLUINTEGER);
06280
break;
06281
case SQL_SCROLL_OPTIONS:
06282 *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
06283 *valLen =
sizeof (SQLUINTEGER);
06284
break;
06285
case SQL_TABLE_TERM:
06286
strmak(val,
"table", valMax, valLen);
06287
break;
06288
case SQL_TXN_CAPABLE:
06289 *((SQLSMALLINT *) val) = SQL_TC_ALL;
06290 *valLen =
sizeof (SQLSMALLINT);
06291
break;
06292
case SQL_CONVERT_FUNCTIONS:
06293 *((SQLUINTEGER *) val) = 0;
06294 *valLen =
sizeof (SQLUINTEGER);
06295
break;
06296
case SQL_SYSTEM_FUNCTIONS:
06297
case SQL_NUMERIC_FUNCTIONS:
06298
case SQL_STRING_FUNCTIONS:
06299
case SQL_TIMEDATE_FUNCTIONS:
06300 *((SQLUINTEGER *) val) = 0;
06301 *valLen =
sizeof (SQLUINTEGER);
06302
break;
06303
case SQL_CONVERT_BIGINT:
06304
case SQL_CONVERT_BIT:
06305
case SQL_CONVERT_CHAR:
06306
case SQL_CONVERT_DATE:
06307
case SQL_CONVERT_DECIMAL:
06308
case SQL_CONVERT_DOUBLE:
06309
case SQL_CONVERT_FLOAT:
06310
case SQL_CONVERT_INTEGER:
06311
case SQL_CONVERT_LONGVARCHAR:
06312
case SQL_CONVERT_NUMERIC:
06313
case SQL_CONVERT_REAL:
06314
case SQL_CONVERT_SMALLINT:
06315
case SQL_CONVERT_TIME:
06316
case SQL_CONVERT_TIMESTAMP:
06317
case SQL_CONVERT_TINYINT:
06318
case SQL_CONVERT_VARCHAR:
06319 *((SQLUINTEGER *) val) =
06320 SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
06321 SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
06322 SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
06323 SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
06324 SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
06325 *valLen =
sizeof (SQLUINTEGER);
06326
break;
06327
case SQL_CONVERT_BINARY:
06328
case SQL_CONVERT_VARBINARY:
06329
case SQL_CONVERT_LONGVARBINARY:
06330 *((SQLUINTEGER *) val) = 0;
06331 *valLen =
sizeof (SQLUINTEGER);
06332
break;
06333
case SQL_POSITIONED_STATEMENTS:
06334
case SQL_LOCK_TYPES:
06335 *((SQLUINTEGER *) val) = 0;
06336 *valLen =
sizeof (SQLUINTEGER);
06337
break;
06338
case SQL_BOOKMARK_PERSISTENCE:
06339 *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
06340 *valLen =
sizeof (SQLUINTEGER);
06341
break;
06342
case SQL_OWNER_USAGE:
06343
case SQL_SUBQUERIES:
06344
case SQL_UNION:
06345
case SQL_TIMEDATE_ADD_INTERVALS:
06346
case SQL_TIMEDATE_DIFF_INTERVALS:
06347 *((SQLUINTEGER *) val) = 0;
06348 *valLen =
sizeof (SQLUINTEGER);
06349
break;
06350
case SQL_QUOTED_IDENTIFIER_CASE:
06351 *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
06352 *valLen =
sizeof (SQLUSMALLINT);
06353
break;
06354
case SQL_POS_OPERATIONS:
06355 *((SQLUINTEGER *) val) = 0;
06356 *valLen =
sizeof (SQLUINTEGER);
06357
break;
06358
case SQL_ALTER_TABLE:
06359 *((SQLUINTEGER *) val) = 0;
06360 *valLen =
sizeof (SQLUINTEGER);
06361
break;
06362
case SQL_CORRELATION_NAME:
06363 *((SQLSMALLINT *) val) = SQL_CN_DIFFERENT;
06364 *valLen =
sizeof (SQLSMALLINT);
06365
break;
06366
case SQL_NON_NULLABLE_COLUMNS:
06367 *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
06368 *valLen =
sizeof (SQLSMALLINT);
06369
break;
06370
case SQL_NULL_COLLATION:
06371 *((SQLSMALLINT *) val) = SQL_NC_START;
06372 *valLen =
sizeof(SQLSMALLINT);
06373
break;
06374
case SQL_MAX_COLUMNS_IN_GROUP_BY:
06375
case SQL_MAX_COLUMNS_IN_ORDER_BY:
06376
case SQL_MAX_COLUMNS_IN_SELECT:
06377
case SQL_MAX_COLUMNS_IN_TABLE:
06378
case SQL_MAX_ROW_SIZE:
06379
case SQL_MAX_TABLES_IN_SELECT:
06380 *((SQLSMALLINT *) val) = 0;
06381 *valLen =
sizeof (SQLSMALLINT);
06382
break;
06383
case SQL_MAX_BINARY_LITERAL_LEN:
06384
case SQL_MAX_CHAR_LITERAL_LEN:
06385 *((SQLUINTEGER *) val) = 0;
06386 *valLen =
sizeof (SQLUINTEGER);
06387
break;
06388
case SQL_MAX_COLUMNS_IN_INDEX:
06389 *((SQLSMALLINT *) val) = 0;
06390 *valLen =
sizeof (SQLSMALLINT);
06391
break;
06392
case SQL_MAX_INDEX_SIZE:
06393 *((SQLUINTEGER *) val) = 0;
06394 *valLen =
sizeof(SQLUINTEGER);
06395
break;
06396
#ifdef SQL_MAX_IDENTIFIER_LENGTH
06397
case SQL_MAX_IDENTIFIER_LENGTH:
06398 *((SQLUINTEGER *) val) = 255;
06399 *valLen =
sizeof (SQLUINTEGER);
06400
break;
06401
#endif
06402
case SQL_MAX_STATEMENT_LEN:
06403 *((SQLUINTEGER *) val) = 16384;
06404 *valLen =
sizeof (SQLUINTEGER);
06405
break;
06406
case SQL_QUALIFIER_LOCATION:
06407 *((SQLSMALLINT *) val) = SQL_QL_START;
06408 *valLen =
sizeof (SQLSMALLINT);
06409
break;
06410
case SQL_GETDATA_EXTENSIONS:
06411 *((SQLUINTEGER *) val) =
06412 SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
06413 *valLen =
sizeof (SQLUINTEGER);
06414
break;
06415
case SQL_STATIC_SENSITIVITY:
06416 *((SQLUINTEGER *) val) = 0;
06417 *valLen =
sizeof (SQLUINTEGER);
06418
break;
06419
case SQL_FILE_USAGE:
06420 *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
06421 *valLen =
sizeof (SQLSMALLINT);
06422
break;
06423
case SQL_GROUP_BY:
06424 *((SQLSMALLINT *) val) = 0;
06425 *valLen =
sizeof (SQLSMALLINT);
06426
break;
06427
case SQL_KEYWORDS:
06428
strmak(val,
"SELECT,DROP,DELETE,UPDATE,INSERT,"
06429
"INTO,VALUES,TABLE,FROM,SET,WHERE,AND,CURRENT,OF",
06430 valMax, valLen);
06431
break;
06432
case SQL_SPECIAL_CHARACTERS:
06433
strmak(val,
"", valMax, valLen);
06434
break;
06435
case SQL_BATCH_SUPPORT:
06436
case SQL_BATCH_ROW_COUNT:
06437
case SQL_PARAM_ARRAY_ROW_COUNTS:
06438 *((SQLUINTEGER *) val) = 0;
06439 *valLen =
sizeof (SQLUINTEGER);
06440
break;
06441
case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
06442 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
06443 *valLen =
sizeof (SQLUINTEGER);
06444
break;
06445
case SQL_STATIC_CURSOR_ATTRIBUTES1:
06446 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
06447 SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK;
06448 *valLen =
sizeof (SQLUINTEGER);
06449
break;
06450
case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
06451
case SQL_STATIC_CURSOR_ATTRIBUTES2:
06452 *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
06453 SQL_CA2_LOCK_CONCURRENCY;
06454 *valLen =
sizeof (SQLUINTEGER);
06455
break;
06456
case SQL_KEYSET_CURSOR_ATTRIBUTES1:
06457
case SQL_KEYSET_CURSOR_ATTRIBUTES2:
06458
case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
06459
case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
06460 *((SQLUINTEGER *) val) = 0;
06461 *valLen =
sizeof (SQLUINTEGER);
06462
break;
06463
case SQL_ODBC_INTERFACE_CONFORMANCE:
06464 *((SQLUINTEGER *) val) = SQL_OIC_CORE;
06465 *valLen =
sizeof (SQLUINTEGER);
06466
break;
06467
default:
06468
setstatd(d, -1,
"unsupported info option %d",
06469 (*d->
ov3) ?
"HYC00" :
"S1C00", type);
06470
return SQL_ERROR;
06471 }
06472
return SQL_SUCCESS;
06473 }
06474
06475
#if (defined(HAVE_UNIXODBC) && HAVE_UNIXODBC) || !defined(SQLITE_UTF8)
06476
06486 SQLRETURN SQL_API
06487 SQLGetInfo(SQLHDBC
dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
06488 SQLSMALLINT *valLen)
06489 {
06490
return drvgetinfo(dbc, type, val, valMax, valLen);
06491 }
06492
#endif
06493
06494
#ifdef SQLITE_UTF8
06495
06505 SQLRETURN SQL_API
06506 SQLGetInfoW(SQLHDBC
dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
06507 SQLSMALLINT *valLen)
06508 {
06509 SQLRETURN ret;
06510 SQLSMALLINT len;
06511
06512 ret =
drvgetinfo(dbc, type, val, valMax, &len);
06513
if (ret == SQL_SUCCESS) {
06514 SQLWCHAR *v = NULL;
06515
06516
switch (type) {
06517
case SQL_USER_NAME:
06518
case SQL_DRIVER_ODBC_VER:
06519
case SQL_DATA_SOURCE_NAME:
06520
case SQL_DRIVER_NAME:
06521
case SQL_DRIVER_VER:
06522
case SQL_ODBC_VER:
06523
case SQL_SERVER_NAME:
06524
case SQL_DATABASE_NAME:
06525
case SQL_SEARCH_PATTERN_ESCAPE:
06526
case SQL_DBMS_NAME:
06527
case SQL_DBMS_VER:
06528
case SQL_NEED_LONG_DATA_LEN:
06529
case SQL_ROW_UPDATES:
06530
case SQL_ACCESSIBLE_PROCEDURES:
06531
case SQL_PROCEDURES:
06532
case SQL_EXPRESSIONS_IN_ORDERBY:
06533
case SQL_ODBC_SQL_OPT_IEF:
06534
case SQL_LIKE_ESCAPE_CLAUSE:
06535
case SQL_ORDER_BY_COLUMNS_IN_SELECT:
06536
case SQL_OUTER_JOINS:
06537
case SQL_COLUMN_ALIAS:
06538
case SQL_ACCESSIBLE_TABLES:
06539
case SQL_MULT_RESULT_SETS:
06540
case SQL_MULTIPLE_ACTIVE_TXN:
06541
case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
06542
case SQL_DATA_SOURCE_READ_ONLY:
06543
#ifdef SQL_DESCRIBE_PARAMETER
06544
case SQL_DESCRIBE_PARAMETER:
06545
#endif
06546
case SQL_IDENTIFIER_QUOTE_CHAR:
06547
case SQL_OWNER_TERM:
06548
case SQL_PROCEDURE_TERM:
06549
case SQL_QUALIFIER_NAME_SEPARATOR:
06550
case SQL_QUALIFIER_TERM:
06551
case SQL_TABLE_TERM:
06552
case SQL_KEYWORDS:
06553
case SQL_SPECIAL_CHARACTERS:
06554
if (val) {
06555
if (len > 0) {
06556 v = uc_from_utf((
char *) val, len);
06557
if (v) {
06558
int vmax = valMax /
sizeof (SQLWCHAR);
06559
06560 uc_strncpy(val, v, vmax);
06561 len =
min(vmax, uc_strlen(v));
06562 uc_free(v);
06563 }
else {
06564 len = 0;
06565 }
06566 }
06567
if (len <= 0) {
06568 len = 0;
06569
if (valMax >=
sizeof (SQLWCHAR)) {
06570 *((SQLWCHAR *)val) = 0;
06571 }
06572 }
06573 }
else {
06574 len = 0;
06575 }
06576
break;
06577 }
06578
if (valLen) {
06579 *valLen = len;
06580 }
06581 }
06582
return ret;
06583 }
06584
#endif
06585
06594 SQLRETURN SQL_API
06595 SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
06596 SQLUSMALLINT *flags)
06597 {
06598
DBC *d;
06599
int i;
06600 SQLUSMALLINT exists[100];
06601
06602
if (dbc == SQL_NULL_HDBC) {
06603
return SQL_INVALID_HANDLE;
06604 }
06605 d = (
DBC *) dbc;
06606
for (i = 0; i <
array_size(exists); i++) {
06607 exists[i] = SQL_FALSE;
06608 }
06609 exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
06610 exists[SQL_API_SQLFETCH] = SQL_TRUE;
06611 exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
06612 exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
06613 exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
06614 exists[SQL_API_SQLFREEENV] = SQL_TRUE;
06615 exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
06616 exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
06617 exists[SQL_API_SQLCANCEL] = SQL_TRUE;
06618 exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
06619 exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
06620 exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
06621 exists[SQL_API_SQLCONNECT] = SQL_TRUE;
06622 exists[SQL_API_SQLPREPARE] = SQL_TRUE;
06623 exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
06624 exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
06625 exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
06626 exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
06627 exists[SQL_API_SQLERROR] = SQL_TRUE;
06628 exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
06629 exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
06630 exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
06631 exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
06632 exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
06633 exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
06634 exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
06635 exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
06636 exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
06637 exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
06638 exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
06639 exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
06640 exists[SQL_API_SQLGETDATA] = SQL_TRUE;
06641 exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
06642 exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
06643 exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
06644 exists[SQL_API_SQLGETINFO] = SQL_TRUE;
06645 exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
06646 exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
06647 exists[SQL_API_SQLTABLES] = SQL_TRUE;
06648 exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
06649 exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
06650 exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
06651 exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
06652 exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
06653 exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
06654 exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
06655 exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
06656 exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
06657 exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
06658 exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
06659 exists[SQL_API_SQLSETPOS] = SQL_FALSE;
06660 exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
06661 exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
06662 exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
06663 exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_FALSE;
06664 exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
06665
if (func == SQL_API_ALL_FUNCTIONS) {
06666 memcpy(flags, exists,
sizeof (exists));
06667 }
else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
06668
int i;
06669
#define SET_EXISTS(x) \
06670
flags[(x) >> 4] |= (1 << ((x) & 0xF))
06671
#define CLR_EXISTS(x) \
06672
flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
06673
06674 memset(flags, 0,
06675
sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
06676
for (i = 0; i <
array_size(exists); i++) {
06677
if (exists[i]) {
06678 flags[i >> 4] |= (1 << (i & 0xF));
06679 }
06680 }
06681
SET_EXISTS(SQL_API_SQLALLOCHANDLE);
06682
SET_EXISTS(SQL_API_SQLFREEHANDLE);
06683
SET_EXISTS(SQL_API_SQLGETSTMTATTR);
06684
SET_EXISTS(SQL_API_SQLSETSTMTATTR);
06685
SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
06686
SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
06687
SET_EXISTS(SQL_API_SQLGETENVATTR);
06688
SET_EXISTS(SQL_API_SQLSETENVATTR);
06689
SET_EXISTS(SQL_API_SQLCLOSECURSOR);
06690
SET_EXISTS(SQL_API_SQLBINDPARAM);
06691
#if !defined(HAVE_UNIXODBC) || !HAVE_UNIXODBC
06692
06693
06694
06695
06696
06697
SET_EXISTS(SQL_API_SQLGETDIAGREC);
06698
#endif
06699
SET_EXISTS(SQL_API_SQLFETCHSCROLL);
06700
SET_EXISTS(SQL_API_SQLENDTRAN);
06701 }
else {
06702
if (func <
array_size(exists)) {
06703 *flags = exists[func];
06704 }
else {
06705
switch (func) {
06706
case SQL_API_SQLALLOCHANDLE:
06707
case SQL_API_SQLFREEHANDLE:
06708
case SQL_API_SQLGETSTMTATTR:
06709
case SQL_API_SQLSETSTMTATTR:
06710
case SQL_API_SQLGETCONNECTATTR:
06711
case SQL_API_SQLSETCONNECTATTR:
06712
case SQL_API_SQLGETENVATTR:
06713
case SQL_API_SQLSETENVATTR:
06714
case SQL_API_SQLCLOSECURSOR:
06715
case SQL_API_SQLBINDPARAM:
06716
#if !defined(HAVE_UNIXODBC) || !HAVE_UNIXODBC
06717
06718
06719
06720
06721
06722
case SQL_API_SQLGETDIAGREC:
06723
#endif
06724
case SQL_API_SQLFETCHSCROLL:
06725
case SQL_API_SQLENDTRAN:
06726 *flags = SQL_TRUE;
06727
break;
06728
default:
06729 *flags = SQL_FALSE;
06730 }
06731 }
06732 }
06733
return SQL_SUCCESS;
06734 }
06735
06742
static SQLRETURN
06743 drvallocenv(SQLHENV *env)
06744 {
06745
ENV *e;
06746
06747
if (env == NULL) {
06748
return SQL_INVALID_HANDLE;
06749 }
06750 e = (
ENV *)
xmalloc(
sizeof (
ENV));
06751
if (e == NULL) {
06752 *env = SQL_NULL_HENV;
06753
return SQL_ERROR;
06754 }
06755 e->
magic =
ENV_MAGIC;
06756 e->
ov3 = 0;
06757 e->
dbcs = NULL;
06758 *env = (SQLHENV) e;
06759
return SQL_SUCCESS;
06760 }
06761
06768 SQLRETURN SQL_API
06769 SQLAllocEnv(SQLHENV *env)
06770 {
06771
return drvallocenv(env);
06772 }
06773
06780
static SQLRETURN
06781 drvfreeenv(SQLHENV env)
06782 {
06783
ENV *e;
06784
06785
if (env == SQL_NULL_HENV) {
06786
return SQL_INVALID_HANDLE;
06787 }
06788 e = (
ENV *) env;
06789
if (e->
magic !=
ENV_MAGIC) {
06790
return SQL_SUCCESS;
06791 }
06792
if (e->
dbcs) {
06793
return SQL_ERROR;
06794 }
06795 e->
magic =
DEAD_MAGIC;
06796
xfree(e);
06797
return SQL_SUCCESS;
06798 }
06799
06806 SQLRETURN SQL_API
06807 SQLFreeEnv(SQLHENV env)
06808 {
06809
return drvfreeenv(env);
06810 }
06811
06819
static SQLRETURN
06820 drvallocconnect(SQLHENV env, SQLHDBC *dbc)
06821 {
06822
DBC *d;
06823
ENV *e;
06824
const char *verstr;
06825
int maj = 0,
min = 0, lev = 0;
06826
06827
if (dbc == NULL) {
06828
return SQL_ERROR;
06829 }
06830 d = (
DBC *)
xmalloc(
sizeof (
DBC));
06831
if (d == NULL) {
06832 *dbc = SQL_NULL_HDBC;
06833
return SQL_ERROR;
06834 }
06835 memset(d, 0,
sizeof (
DBC));
06836 d->
curtype = SQL_CURSOR_STATIC;
06837
#if HAVE_LIBVERSION
06838
verstr = sqlite_libversion();
06839
#else
06840
verstr = sqlite_version;
06841
#endif
06842
sscanf(verstr,
"%d.%d.%d", &maj, &
min, &lev);
06843 d->
version =
verinfo(maj & 0xFF,
min & 0xFF, lev & 0xFF);
06844
if (d->
version <
verinfo(2, 8, 0)) {
06845
xfree(d);
06846
return SQL_ERROR;
06847 }
06848 d->
ov3 = &d->
ov3val;
06849 e = (
ENV *) env;
06850
if (e->
magic ==
ENV_MAGIC) {
06851
DBC *n, *p;
06852
06853 d->
env = e;
06854 d->
ov3 = &e->
ov3;
06855 p = NULL;
06856 n = e->
dbcs;
06857
while (n) {
06858 p = n;
06859 n = n->
next;
06860 }
06861
if (p) {
06862 p->
next = d;
06863 }
else {
06864 e->
dbcs = d;
06865 }
06866 }
06867 d->
autocommit = 1;
06868 d->
magic =
DBC_MAGIC;
06869 *dbc = (SQLHDBC) d;
06870
drvgetgpps(d);
06871
return SQL_SUCCESS;
06872 }
06873
06881 SQLRETURN SQL_API
06882 SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
06883 {
06884
return drvallocconnect(env, dbc);
06885 }
06886
06893
static SQLRETURN
06894 drvfreeconnect(SQLHDBC dbc)
06895 {
06896
DBC *d;
06897
ENV *e;
06898
06899
if (dbc == SQL_NULL_HDBC) {
06900
return SQL_INVALID_HANDLE;
06901 }
06902 d = (
DBC *) dbc;
06903
if (d->
magic !=
DBC_MAGIC) {
06904
return SQL_INVALID_HANDLE;
06905 }
06906
if (d->
sqlite) {
06907
setstatd(d, -1,
"not disconnected", (*d->
ov3) ?
"HY000" :
"S1000");
06908
return SQL_ERROR;
06909 }
06910
while (d->
stmt) {
06911
freestmt((HSTMT) d->
stmt);
06912 }
06913 e = d->
env;
06914
if (e && e->
magic ==
ENV_MAGIC) {
06915
DBC *n, *p;
06916
06917 p = NULL;
06918 n = e->
dbcs;
06919
while (n) {
06920
if (n == d) {
06921
break;
06922 }
06923 p = n;
06924 n = n->
next;
06925 }
06926
if (n) {
06927
if (p) {
06928 p->
next = d->
next;
06929 }
else {
06930 e->
dbcs = d->
next;
06931 }
06932 }
06933 }
06934
drvrelgpps(d);
06935 d->
magic =
DEAD_MAGIC;
06936
#if defined(HAVE_SQLITETRACE) && HAVE_SQLITETRACE
06937
if (d->trace) {
06938 fclose(d->trace);
06939 }
06940
#endif
06941
xfree(d);
06942
return SQL_SUCCESS;
06943 }
06944
06951 SQLRETURN SQL_API
06952 SQLFreeConnect(SQLHDBC dbc)
06953 {
06954
return drvfreeconnect(dbc);
06955 }
06956
06967
static SQLRETURN
06968 drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
06969 SQLINTEGER bufmax, SQLINTEGER *buflen)
06970 {
06971
DBC *d;
06972 SQLINTEGER dummy;
06973
06974
if (dbc == SQL_NULL_HDBC) {
06975
return SQL_INVALID_HANDLE;
06976 }
06977 d = (
DBC *) dbc;
06978
if (!val) {
06979 val = (SQLPOINTER) &dummy;
06980 }
06981
if (!buflen) {
06982 buflen = &dummy;
06983 }
06984
switch (attr) {
06985
case SQL_ATTR_CONNECTION_DEAD:
06986 *((SQLINTEGER *) val) = d->
sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
06987 *buflen =
sizeof (SQLINTEGER);
06988
break;
06989
case SQL_ATTR_ACCESS_MODE:
06990 *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
06991 *buflen =
sizeof (SQLINTEGER);
06992
break;
06993
case SQL_ATTR_AUTOCOMMIT:
06994 *((SQLINTEGER *) val) =
06995 d->
autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
06996 *buflen =
sizeof (SQLINTEGER);
06997
break;
06998
case SQL_ATTR_LOGIN_TIMEOUT:
06999 *((SQLINTEGER *) val) = 100;
07000 *buflen =
sizeof (SQLINTEGER);
07001
break;
07002
case SQL_ATTR_ODBC_CURSORS:
07003 *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
07004 *buflen =
sizeof (SQLINTEGER);
07005
break;
07006
case SQL_ATTR_PACKET_SIZE:
07007 *((SQLINTEGER *) val) = 16384;
07008 *buflen =
sizeof (SQLINTEGER);
07009
break;
07010
case SQL_ATTR_TXN_ISOLATION:
07011 *((SQLINTEGER *) val) = SQL_TXN_READ_UNCOMMITTED;
07012 *buflen =
sizeof (SQLINTEGER);
07013
break;
07014
case SQL_ATTR_TRACE:
07015
case SQL_ATTR_TRACEFILE:
07016
case SQL_ATTR_QUIET_MODE:
07017
case SQL_ATTR_TRANSLATE_OPTION:
07018
case SQL_ATTR_KEYSET_SIZE:
07019
case SQL_ATTR_QUERY_TIMEOUT:
07020
case SQL_ATTR_PARAM_BIND_TYPE:
07021
case SQL_ATTR_CURRENT_CATALOG:
07022 *((SQLINTEGER *) val) = 0;
07023 *buflen =
sizeof (SQLINTEGER);
07024
break;
07025
case SQL_ATTR_ROW_BIND_TYPE:
07026 *((SQLUINTEGER *) val) = SQL_BIND_BY_COLUMN;
07027 *buflen =
sizeof (SQLUINTEGER);
07028
break;
07029
case SQL_ATTR_USE_BOOKMARKS:
07030 *((SQLINTEGER *) val) = SQL_UB_OFF;
07031 *buflen =
sizeof (SQLINTEGER);
07032
break;
07033
case SQL_ATTR_ASYNC_ENABLE:
07034 *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
07035 *buflen =
sizeof (SQLINTEGER);
07036
break;
07037
case SQL_ATTR_NOSCAN:
07038 *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
07039 *buflen =
sizeof (SQLINTEGER);
07040
break;
07041
case SQL_ATTR_CONCURRENCY:
07042 *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
07043 *buflen =
sizeof (SQLINTEGER);
07044
break;
07045
case SQL_ATTR_SIMULATE_CURSOR:
07046 *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
07047 *buflen =
sizeof (SQLINTEGER);
07048
break;
07049
case SQL_ATTR_MAX_ROWS:
07050
case SQL_ATTR_MAX_LENGTH:
07051 *((SQLINTEGER *) val) = 1000000000;
07052 *buflen =
sizeof (SQLINTEGER);
07053
break;
07054
case SQL_ATTR_CURSOR_TYPE:
07055 *((SQLINTEGER *) val) = d->
curtype;
07056 *buflen =
sizeof (SQLINTEGER);
07057
break;
07058
case SQL_ATTR_RETRIEVE_DATA:
07059 *((SQLINTEGER *) val) = SQL_RD_ON;
07060 *buflen =
sizeof (SQLINTEGER);
07061
break;
07062
default:
07063 *((SQLINTEGER *) val) = 0;
07064 *buflen =
sizeof (SQLINTEGER);
07065
setstatd(d, -1,
"unsupported connect attribute %d",
07066 (*d->
ov3) ?
"HYC00" :
"S1C00", (
int) attr);
07067
return SQL_ERROR;
07068 }
07069
return SQL_SUCCESS;
07070 }
07071
07072
#ifndef SQLITE_UTF8
07073
07083 SQLRETURN SQL_API
07084 SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
07085 SQLINTEGER bufmax, SQLINTEGER *buflen)
07086 {
07087
return drvgetconnectattr(dbc, attr, val, bufmax, buflen);
07088 }
07089
#endif
07090
07091
#ifdef SQLITE_UTF8
07092
07102 SQLRETURN SQL_API
07103 SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
07104 SQLINTEGER bufmax, SQLINTEGER *buflen)
07105 {
07106
return drvgetconnectattr(dbc, attr, val, bufmax, buflen);
07107 }
07108
#endif
07109
07119
static SQLRETURN
07120 drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
07121 SQLINTEGER len)
07122 {
07123
DBC *d;
07124
07125
if (dbc == SQL_NULL_HDBC) {
07126
return SQL_INVALID_HANDLE;
07127 }
07128 d = (
DBC *) dbc;
07129
switch (attr) {
07130
case SQL_AUTOCOMMIT:
07131
if (len == SQL_IS_INTEGER) {
07132 d->
autocommit = (SQLINTEGER) val == SQL_AUTOCOMMIT_ON;
07133
goto doit;
07134 }
07135
if (val && len >=
sizeof (SQLINTEGER)) {
07136 d->
autocommit = *((SQLINTEGER *) val) == SQL_AUTOCOMMIT_ON;
07137 doit:
07138
if (d->
autocommit && d->
intrans) {
07139
return endtran(d, SQL_COMMIT);
07140 }
else if (!d->
autocommit) {
07141
vm_end(d->
vm_stmt);
07142 }
07143 }
07144
break;
07145
default:
07146
setstatd(d, -1,
"option value changed",
"01S02");
07147
return SQL_SUCCESS_WITH_INFO;
07148 }
07149
return SQL_SUCCESS;
07150 }
07151
07152
#ifndef SQLITE_UTF8
07153
07162 SQLRETURN SQL_API
07163 SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
07164 SQLINTEGER len)
07165 {
07166
return drvsetconnectattr(dbc, attr, val, len);
07167 }
07168
#endif
07169
07170
#ifdef SQLITE_UTF8
07171
07180 SQLRETURN SQL_API
07181 SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
07182 SQLINTEGER len)
07183 {
07184
return drvsetconnectattr(dbc, attr, val, len);
07185 }
07186
#endif
07187
07196
static SQLRETURN
07197 drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
07198 {
07199
DBC *d;
07200 SQLINTEGER dummy;
07201
07202
if (dbc == SQL_NULL_HDBC) {
07203
return SQL_INVALID_HANDLE;
07204 }
07205 d = (
DBC *) dbc;
07206
if (!param) {
07207 param = (SQLPOINTER) &dummy;
07208 }
07209
switch (opt) {
07210
case SQL_ACCESS_MODE:
07211 *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
07212
break;
07213
case SQL_AUTOCOMMIT:
07214 *((SQLINTEGER *) param) =
07215 d->
autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
07216
break;
07217
case SQL_LOGIN_TIMEOUT:
07218 *((SQLINTEGER *) param) = 100;
07219
break;
07220
case SQL_ODBC_CURSORS:
07221 *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
07222
break;
07223
case SQL_PACKET_SIZE:
07224 *((SQLINTEGER *) param) = 16384;
07225
break;
07226
case SQL_TXN_ISOLATION:
07227 *((SQLINTEGER *) param) = SQL_TXN_READ_UNCOMMITTED;
07228
break;
07229
case SQL_OPT_TRACE:
07230
case SQL_OPT_TRACEFILE:
07231
case SQL_QUIET_MODE:
07232
case SQL_TRANSLATE_DLL:
07233
case SQL_TRANSLATE_OPTION:
07234
case SQL_KEYSET_SIZE:
07235
case SQL_QUERY_TIMEOUT:
07236
case SQL_BIND_TYPE:
07237
case SQL_CURRENT_QUALIFIER:
07238 *((SQLINTEGER *) param) = 0;
07239
break;
07240
case SQL_USE_BOOKMARKS:
07241 *((SQLINTEGER *) param) = SQL_UB_OFF;
07242
break;
07243
case SQL_ASYNC_ENABLE:
07244 *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
07245
break;
07246
case SQL_NOSCAN:
07247 *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
07248
break;
07249
case SQL_CONCURRENCY:
07250 *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
07251
break;
07252
case SQL_SIMULATE_CURSOR:
07253 *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
07254
break;
07255
case SQL_ROWSET_SIZE:
07256
case SQL_MAX_ROWS:
07257
case SQL_MAX_LENGTH:
07258 *((SQLINTEGER *) param) = 1000000000;
07259
break;
07260
case SQL_CURSOR_TYPE:
07261 *((SQLINTEGER *) param) = d->
curtype;
07262
break;
07263
case SQL_RETRIEVE_DATA:
07264 *((SQLINTEGER *) param) = SQL_RD_ON;
07265
break;
07266
default:
07267 *((SQLINTEGER *) param) = 0;
07268
setstatd(d, -1,
"unsupported connect option %d",
07269 (*d->
ov3) ?
"HYC00" :
"S1C00", opt);
07270
return SQL_ERROR;
07271 }
07272
return SQL_SUCCESS;
07273 }
07274
07275
#ifndef SQLITE_UTF8
07276
07284 SQLRETURN SQL_API
07285 SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
07286 {
07287
return drvgetconnectoption(dbc, opt, param);
07288 }
07289
#endif
07290
07291
#ifdef SQLITE_UTF8
07292
07300 SQLRETURN SQL_API
07301 SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
07302 {
07303
return drvgetconnectoption(dbc, opt, param);
07304 }
07305
#endif
07306
07315
static SQLRETURN
07316 drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
07317 {
07318
DBC *d;
07319
07320
if (dbc == SQL_NULL_HDBC) {
07321
return SQL_INVALID_HANDLE;
07322 }
07323 d = (
DBC *) dbc;
07324
switch (opt) {
07325
case SQL_AUTOCOMMIT:
07326 d->
autocommit = param == SQL_AUTOCOMMIT_ON;
07327
if (d->
autocommit && d->
intrans) {
07328
return endtran(d, SQL_COMMIT);
07329 }
else if (!d->
autocommit) {
07330
vm_end(d->
vm_stmt);
07331 }
07332
break;
07333
default:
07334
setstatd(d, -1,
"option value changed",
"01S02");
07335
return SQL_SUCCESS_WITH_INFO;
07336 }
07337
return SQL_SUCCESS;
07338 }
07339
07340
#ifndef SQLITE_UTF8
07341
07349 SQLRETURN SQL_API
07350 SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
07351 {
07352
return drvsetconnectoption(dbc, opt, param);
07353 }
07354
#endif
07355
07356
#ifdef SQLITE_UTF8
07357
07365 SQLRETURN SQL_API
07366 SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
07367 {
07368
return drvsetconnectoption(dbc, opt, param);
07369 }
07370
#endif
07371
07372
#if defined(WITHOUT_DRIVERMGR) || !defined(_WIN32)
07373
07384
static int
07385 getdsnattr(
char *dsn,
char *attr,
char *out,
int outLen)
07386 {
07387
char *str = dsn, *start;
07388
int len = strlen(attr);
07389
07390
while (*str) {
07391
while (*str && *str ==
';') {
07392 ++str;
07393 }
07394 start = str;
07395
if ((str = strchr(str,
'=')) == NULL) {
07396
return 0;
07397 }
07398
if (str - start == len &&
07399
#ifdef _WIN32
07400
_strnicmp(start, attr, len) == 0
07401
#else
07402
strncasecmp(start, attr, len) == 0
07403
#endif
07404
) {
07405 start = ++str;
07406
while (*str && *str !=
';') {
07407 ++str;
07408 }
07409 len =
min(outLen - 1, str - start);
07410 strncpy(out, start, len);
07411 out[len] =
'\0';
07412
return 1;
07413 }
07414
while (*str && *str !=
';') {
07415 ++str;
07416 }
07417 }
07418
return 0;
07419 }
07420
#endif
07421
07430
static SQLRETURN
07431 drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen)
07432 {
07433
DBC *d;
07434
int len;
07435
char buf[SQL_MAX_MESSAGE_LENGTH], dbname[SQL_MAX_MESSAGE_LENGTH / 4];
07436
char busy[SQL_MAX_MESSAGE_LENGTH / 4];
07437
char sflag[32], nwflag[32];
07438
#if defined(HAVE_SQLITETRACE) && HAVE_SQLITETRACE
07439
char tracef[SQL_MAX_MESSAGE_LENGTH];
07440
#endif
07441
07442
if (dbc == SQL_NULL_HDBC) {
07443
return SQL_INVALID_HANDLE;
07444 }
07445 d = (
DBC *) dbc;
07446
if (d->
magic !=
DBC_MAGIC) {
07447
return SQL_INVALID_HANDLE;
07448 }
07449
if (d->
sqlite != NULL) {
07450
setstatd(d, -1,
"connection already established",
"08002");
07451
return SQL_ERROR;
07452 }
07453 buf[0] =
'\0';
07454
if (dsnLen == SQL_NTS) {
07455 len =
sizeof (buf) - 1;
07456 }
else {
07457 len =
min(
sizeof (buf) - 1, dsnLen);
07458 }
07459
if (dsn != NULL) {
07460 strncpy(buf, dsn, len);
07461 }
07462 buf[len] =
'\0';
07463
if (buf[0] ==
'\0') {
07464
setstatd(d, -1,
"invalid DSN", (*d->
ov3) ?
"HY090" :
"S1090");
07465
return SQL_ERROR;
07466 }
07467 busy[0] =
'\0';
07468 dbname[0] =
'\0';
07469
#ifdef WITHOUT_DRIVERMGR
07470
getdsnattr(buf,
"database", dbname,
sizeof (dbname));
07471
if (dbname[0] ==
'\0') {
07472 strncpy(dbname, buf,
sizeof (dbname));
07473 dbname[
sizeof (dbname) - 1] =
'\0';
07474 }
07475
getdsnattr(buf,
"timeout", busy,
sizeof (busy));
07476 sflag[0] =
'\0';
07477 nwflag[0] =
'\0';
07478
getdsnattr(buf,
"stepapi", sflag,
sizeof (sflag));
07479
getdsnattr(buf,
"nowchar", nwflag,
sizeof (nwflag));
07480
#else
07481
SQLGetPrivateProfileString(buf,
"timeout",
"1000",
07482 busy,
sizeof (busy),
ODBC_INI);
07483 SQLGetPrivateProfileString(buf,
"database",
"",
07484 dbname,
sizeof (dbname),
ODBC_INI);
07485 SQLGetPrivateProfileString(buf,
"stepapi",
"",
07486 sflag,
sizeof (sflag),
ODBC_INI);
07487 SQLGetPrivateProfileString(buf,
"nowchar",
"",
07488 nwflag,
sizeof (nwflag),
ODBC_INI);
07489
#endif
07490
#if defined(HAVE_SQLITETRACE) && HAVE_SQLITETRACE
07491
tracef[0] =
'\0';
07492
#ifdef WITHOUT_DRIVERMGR
07493
getsdnattr(buf,
"tracefile", tracef,
sizeof (tracef));
07494
#else
07495
SQLGetPrivateProfileString(buf,
"tracefile",
"",
07496 tracef,
sizeof (tracef),
ODBC_INI);
07497
#endif
07498
if (tracef[0] !=
'\0') {
07499 d->trace = fopen(tracef,
"a");
07500 }
07501
#endif
07502
d->
nowchar =
getbool(nwflag);
07503
return dbopen(d, dbname, dsn, sflag, busy);
07504 }
07505
07506
#ifndef SQLITE_UTF8
07507
07519 SQLRETURN SQL_API
07520 SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
07521 SQLCHAR *uid, SQLSMALLINT uidLen,
07522 SQLCHAR *pass, SQLSMALLINT passLen)
07523 {
07524
return drvconnect(dbc, dsn, dsnLen);
07525 }
07526
#endif
07527
07528
#ifdef SQLITE_UTF8
07529
07541 SQLRETURN SQL_API
07542 SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
07543 SQLWCHAR *uid, SQLSMALLINT uidLen,
07544 SQLWCHAR *pass, SQLSMALLINT passLen)
07545 {
07546
char *dsna = NULL;
07547 SQLRETURN ret;
07548
07549
if (dsn) {
07550 dsna = uc_to_utf_c(dsn, dsnLen);
07551
if (!dsna) {
07552
DBC *d = (
DBC *) dbc;
07553
07554
setstatd(d, -1,
"out of memory", (*d->
ov3) ?
"HY000" :
"S1000");
07555
return SQL_ERROR;
07556 }
07557 }
07558 ret =
drvconnect(dbc, dsna, SQL_NTS);
07559 uc_free(dsna);
07560
return ret;
07561 }
07562
#endif
07563
07570 SQLRETURN SQL_API
07571 SQLDisconnect(SQLHDBC dbc)
07572 {
07573
DBC *d;
07574
07575
if (dbc == SQL_NULL_HDBC) {
07576
return SQL_INVALID_HANDLE;
07577 }
07578 d = (
DBC *) dbc;
07579
if (d->
magic !=
DBC_MAGIC) {
07580
return SQL_INVALID_HANDLE;
07581 }
07582
if (d->
intrans) {
07583
setstatd(d, -1,
"incomplete transaction",
"25000");
07584
return SQL_ERROR;
07585 }
07586
if (d->
vm_stmt) {
07587
vm_end(d->
vm_stmt);
07588 }
07589
if (d->
sqlite) {
07590 sqlite_close(d->
sqlite);
07591 d->
sqlite = NULL;
07592 }
07593
freep(&d->
dbname);
07594
freep(&d->
dsn);
07595
return SQL_SUCCESS;
07596 }
07597
07598
#if defined(WITHOUT_DRIVERMGR) || !defined(_WIN32)
07599
07613
static SQLRETURN
07614 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
07615 SQLCHAR *connIn, SQLSMALLINT connInLen,
07616 SQLCHAR *connOut, SQLSMALLINT connOutMax,
07617 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
07618 {
07619
DBC *d;
07620
int len;
07621
char buf[SQL_MAX_MESSAGE_LENGTH], dbname[SQL_MAX_MESSAGE_LENGTH / 4];
07622
char dsn[SQL_MAX_MESSAGE_LENGTH / 4], busy[SQL_MAX_MESSAGE_LENGTH / 4];
07623
char sflag[32];
07624
#if defined(HAVE_SQLITETRACE) && HAVE_SQLITETRACE
07625
char tracef[SQL_MAX_MESSAGE_LENGTH];
07626
#endif
07627
07628
if (dbc == SQL_NULL_HDBC || hwnd != NULL) {
07629
return SQL_INVALID_HANDLE;
07630 }
07631
if (drvcompl != SQL_DRIVER_COMPLETE &&
07632 drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
07633 drvcompl != SQL_DRIVER_PROMPT &&
07634 drvcompl != SQL_DRIVER_NOPROMPT) {
07635
return SQL_NO_DATA;
07636 }
07637 d = (
DBC *) dbc;
07638
if (d->
sqlite) {
07639
setstatd(d, -1,
"connection already established",
"08002");
07640
return SQL_ERROR;
07641 }
07642 buf[0] =
'\0';
07643
if (connInLen == SQL_NTS) {
07644 len =
sizeof (buf) - 1;
07645 }
else {
07646 len =
min(connInLen,
sizeof (buf) - 1);
07647 }
07648
if (connIn != NULL) {
07649 strncpy(buf, connIn, len);
07650 }
07651 buf[len] =
'\0';
07652
if (!buf[0]) {
07653
setstatd(d, -1,
"invalid connect attributes",
07654 (*d->
ov3) ?
"HY090" :
"S1090");
07655
return SQL_ERROR;
07656 }
07657 dsn[0] =
'\0';
07658
getdsnattr(buf,
"DSN", dsn,
sizeof (dsn));
07659
07660
07661
if (!dsn[0] && !strchr(buf,
';') && !strchr(buf,
'=')) {
07662 strncpy(dsn, buf,
sizeof (dsn) - 1);
07663 dsn[
sizeof (dsn) - 1] =
'\0';
07664 }
07665
07666 busy[0] =
'\0';
07667
getdsnattr(buf,
"timeout", busy,
sizeof (busy));
07668
#ifndef WITHOUT_DRIVERMGR
07669
if (dsn[0] && !busy[0]) {
07670 SQLGetPrivateProfileString(dsn,
"timeout",
"1000",
07671 busy,
sizeof (busy),
ODBC_INI);
07672 }
07673
#endif
07674
dbname[0] =
'\0';
07675
getdsnattr(buf,
"database", dbname,
sizeof (dbname));
07676
#ifndef WITHOUT_DRIVERMGR
07677
if (dsn[0] && !dbname[0]) {
07678 SQLGetPrivateProfileString(dsn,
"database",
"",
07679 dbname,
sizeof (dbname),
ODBC_INI);
07680 }
07681
#endif
07682
sflag[0] =
'\0';
07683
getdsnattr(buf,
"stepapi", sflag,
sizeof (sflag));
07684
#ifndef WITHOUT_DRIVERMGR
07685
if (dsn[0] && !sflag[0]) {
07686 SQLGetPrivateProfileString(dsn,
"stepapi",
"",
07687 sflag,
sizeof (sflag),
ODBC_INI);
07688 }
07689
#endif
07690
if (!dbname[0] && !dsn[0]) {
07691 strcpy(dsn,
"SQLite");
07692 strncpy(dbname, buf,
sizeof (dbname));
07693 dbname[
sizeof (dbname) - 1] =
'\0';
07694 }
07695
#if defined(HAVE_SQLITETRACE) && HAVE_SQLITETRACE
07696
tracef[0] =
'\0';
07697
getdsnattr(buf,
"tracefile", tracef,
sizeof (tracef));
07698
#ifndef WITHOUT_DRIVERMGR
07699
if (dsn[0] && !tracef[0]) {
07700 SQLGetPrivateProfileString(dsn,
"tracefile",
"",
07701 tracef,
sizeof (tracef),
ODBC_INI);
07702 }
07703
#endif
07704
#endif
07705
if (connOut || connOutLen) {
07706
int count;
07707
07708 buf[0] =
'\0';
07709 count = snprintf(buf,
sizeof (buf),
07710 #
if defined(HAVE_SQLITETRACE) && HAVE_SQLITETRACE
07711
"DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
07712
"Tracefile=%s",
07713 dsn, dbname, sflag, busy, tracef
07714 #
else
07715
"DSN=%s;Database=%s;StepAPI=%s;Timeout=%s",
07716 dsn, dbname, sflag, busy
07717 #endif
07718 );
07719
if (count < 0) {
07720 buf[
sizeof (buf) - 1] =
'\0';
07721 }
07722 len =
min(connOutMax - 1, strlen(buf));
07723
if (connOut) {
07724 strncpy(connOut, buf, len);
07725 connOut[len] =
'\0';
07726 }
07727
if (connOutLen) {
07728 *connOutLen = len;
07729 }
07730 }
07731
#if defined(HAVE_SQLITETRACE) && HAVE_SQLITETRACE
07732
if (tracef[0] !=
'\0') {
07733 d->trace = fopen(tracef,
"a");
07734 }
07735
#endif
07736
return dbopen(d, dbname, dsn, sflag, busy);
07737 }
07738
#endif
07739
07740
07741
07742
static SQLRETURN
07743 freestmt(SQLHSTMT stmt)
07744 {
07745
STMT *s;
07746
DBC *d;
07747
07748
if (stmt == SQL_NULL_HSTMT) {
07749
return SQL_INVALID_HANDLE;
07750 }
07751 s = (
STMT *) stmt;
07752
freeresult(s, 1);
07753
freep(&s->
query);
07754 d = (
DBC *) s->
dbc;
07755
if (d && d->
magic ==
DBC_MAGIC) {
07756
STMT *p, *n;
07757
07758 p = NULL;
07759 n = d->
stmt;
07760
while (n) {
07761
if (n == s) {
07762
break;
07763 }
07764 p = n;
07765 n = n->
next;
07766 }
07767
if (n) {
07768
if (p) {
07769 p->
next = s->
next;
07770 }
else {
07771 d->
stmt = s->
next;
07772 }
07773 }
07774 }
07775
freeparams(s);
07776
freep(&s->
bindparms);
07777
if (s->
row_status0 != &s->
row_status1) {
07778
freep(&s->
row_status0);
07779 s->
rowset_size = 1;
07780 s->
row_status0 = &s->
row_status1;
07781 }
07782
xfree(s);
07783
return SQL_SUCCESS;
07784 }
07785
07793
static SQLRETURN
07794 drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
07795 {
07796
DBC *d;
07797
STMT *s, *sl, *pl;
07798
07799
if (dbc == SQL_NULL_HDBC) {
07800
return SQL_INVALID_HANDLE;
07801 }
07802 d = (
DBC *) dbc;
07803
if (d->
magic !=
DBC_MAGIC || stmt == NULL) {
07804
return SQL_INVALID_HANDLE;
07805 }
07806 s = (
STMT *)
xmalloc(
sizeof (
STMT));
07807
if (s == NULL) {
07808 *stmt = SQL_NULL_HSTMT;
07809
return SQL_ERROR;
07810 }
07811 *stmt = (SQLHSTMT) s;
07812 memset(s, 0,
sizeof (
STMT));
07813 s->
dbc = dbc;
07814 s->
ov3 = d->
ov3;
07815 s->
nowchar = d->
nowchar;
07816 s->
curtype = d->
curtype;
07817 s->
row_status0 = &s->
row_status1;
07818 s->
rowset_size = 1;
07819 s->
bind_type = SQL_BIND_BY_COLUMN;
07820 s->
paramset_size = 1;
07821 sprintf(s->
cursorname,
"CUR_%08lX", (
long) *stmt);
07822 sl = d->
stmt;
07823 pl = NULL;
07824
while (sl) {
07825 pl = sl;
07826 sl = sl->
next;
07827 }
07828
if (pl) {
07829 pl->
next = s;
07830 }
else {
07831 d->
stmt = s;
07832 }
07833
return SQL_SUCCESS;
07834 }
07835
07843 SQLRETURN SQL_API
07844 SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
07845 {
07846
return drvallocstmt(dbc, stmt);
07847 }
07848
07856
static SQLRETURN
07857 drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
07858 {
07859
STMT *s;
07860
07861
if (stmt == SQL_NULL_HSTMT) {
07862
return SQL_INVALID_HANDLE;
07863 }
07864 s = (
STMT *) stmt;
07865
switch (opt) {
07866
case SQL_RESET_PARAMS:
07867
freeparams(s);
07868
break;
07869
case SQL_UNBIND:
07870
unbindcols(s);
07871
break;
07872
case SQL_CLOSE:
07873
vm_end_if(s);
07874
freeresult(s, 0);
07875
break;
07876
case SQL_DROP:
07877
vm_end_if(s);
07878
return freestmt(stmt);
07879
default:
07880
setstat(s, -1,
"unsupported option", (*s->
ov3) ?
"HYC00" :
"S1C00");
07881
return SQL_ERROR;
07882 }
07883
return SQL_SUCCESS;
07884 }
07885
07893 SQLRETURN SQL_API
07894 SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
07895 {
07896
return drvfreestmt(stmt, opt);
07897 }
07898
07905 SQLRETURN SQL_API
07906 SQLCancel(SQLHSTMT stmt)
07907 {
07908
return drvfreestmt(stmt, SQL_CLOSE);
07909 }
07910
07920
static SQLRETURN
07921 drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
07922 SQLSMALLINT *lenp)
07923 {
07924
STMT *s;
07925
07926
if (stmt == SQL_NULL_HSTMT) {
07927
return SQL_INVALID_HANDLE;
07928 }
07929 s = (
STMT *) stmt;
07930
if (lenp && !cursor) {
07931 *lenp = strlen(s->
cursorname);
07932
return SQL_SUCCESS;
07933 }
07934
if (cursor) {
07935
if (buflen > 0) {
07936 strncpy(cursor, s->
cursorname, buflen - 1);
07937 cursor[buflen - 1] =
'\0';
07938 }
07939
if (lenp) {
07940 *lenp =
min(strlen(s->
cursorname), buflen - 1);
07941 }
07942 }
07943
return SQL_SUCCESS;
07944 }
07945
07946
#ifndef SQLITE_UTF8
07947
07956 SQLRETURN SQL_API
07957 SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
07958 SQLSMALLINT *lenp)
07959 {
07960
return drvgetcursorname(stmt, cursor, buflen, lenp);
07961 }
07962
#endif
07963
07964
#ifdef SQLITE_UTF8
07965
07974 SQLRETURN SQL_API
07975 SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
07976 SQLSMALLINT *lenp)
07977 {
07978 SQLRETURN ret;
07979 SQLSMALLINT len;
07980
07981 ret =
drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
07982
if (ret == SQL_SUCCESS) {
07983 SQLWCHAR *c = NULL;
07984
07985
if (cursor) {
07986 c = uc_from_utf((
char *) cursor, len);
07987
if (!c) {
07988
return nomem((
STMT *) stmt);
07989 }
07990 len = uc_strlen(c);
07991
if (buflen > 0) {
07992 uc_strncpy(cursor, c, buflen - 1);
07993 cursor[buflen - 1] = 0;
07994 }
07995 uc_free(c);
07996 }
07997
if (lenp) {
07998 *lenp =
min(len, buflen - 1);
07999 }
08000 }
08001
return ret;
08002 }
08003
#endif
08004
08013
static SQLRETURN
08014 drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
08015 {
08016
STMT *s;
08017
08018
if (stmt == SQL_NULL_HSTMT) {
08019
return SQL_INVALID_HANDLE;
08020 }
08021 s = (
STMT *) stmt;
08022
if (!cursor ||
08023 !((cursor[0] >=
'A' && cursor[0] <=
'Z') ||
08024 (cursor[0] >=
'a' && cursor[0] <=
'z'))) {
08025
setstat(s, -1,
"invalid cursor name", (*s->
ov3) ?
"HYC00" :
"S1C00");
08026
return SQL_ERROR;
08027 }
08028
if (len == SQL_NTS) {
08029 len =
sizeof (s->
cursorname) - 1;
08030 }
else {
08031 len =
min(
sizeof (s->
cursorname) - 1, len);
08032 }
08033 strncpy(s->
cursorname, cursor, len);
08034 s->
cursorname[len] =
'\0';
08035
return SQL_SUCCESS;
08036 }
08037
08038
#ifndef SQLITE_UTF8
08039
08047 SQLRETURN SQL_API
08048 SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
08049 {
08050
return drvsetcursorname(stmt, cursor, len);
08051 }
08052
#endif
08053
08054
#ifdef SQLITE_UTF8
08055
08063 SQLRETURN SQL_API
08064 SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
08065 {
08066
char *c = NULL;
08067 SQLRETURN ret;
08068
08069
if (cursor) {
08070 c = uc_to_utf_c(cursor, len);
08071
if (!c) {
08072
return nomem((
STMT *) stmt);
08073 }
08074 }
08075 ret =
drvsetcursorname(stmt, c, SQL_NTS);
08076 uc_free(c);
08077
return ret;
08078 }
08079
#endif
08080
08087 SQLRETURN SQL_API
08088 SQLCloseCursor(SQLHSTMT stmt)
08089 {
08090
return drvfreestmt(stmt, SQL_CLOSE);
08091 }
08092
08093
#if defined(WITHOUT_DRIVERMGR) || !defined(HAVE_IODBC) || defined(_WIN32)
08094
08103 SQLRETURN SQL_API
08104 SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
08105 {
08106 SQLRETURN ret;
08107
08108
switch (type) {
08109
case SQL_HANDLE_ENV:
08110 ret =
drvallocenv((SQLHENV *) output);
08111
if (ret == SQL_SUCCESS) {
08112
ENV *e = (
ENV *) *output;
08113
08114
if (e && e->
magic ==
ENV_MAGIC) {
08115 e->
ov3 = 1;
08116 }
08117 }
08118
return ret;
08119
case SQL_HANDLE_DBC:
08120
return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
08121
case SQL_HANDLE_STMT:
08122
return drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
08123 }
08124
return SQL_ERROR;
08125 }
08126
#endif
08127
08128
#if defined(WITHOUT_DRIVERMGR) || !defined(HAVE_IODBC) || defined(_WIN32)
08129
08137 SQLRETURN SQL_API
08138 SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
08139 {
08140
switch (type) {
08141
case SQL_HANDLE_ENV:
08142
return drvfreeenv((SQLHENV) h);
08143
case SQL_HANDLE_DBC:
08144
return drvfreeconnect((SQLHDBC) h);
08145
case SQL_HANDLE_STMT:
08146
return drvfreestmt((SQLHSTMT) h, SQL_DROP);
08147 }
08148
return SQL_ERROR;
08149 }
08150
#endif
08151
08157
static void
08158 freedyncols(
STMT *s)
08159 {
08160
if (s->
dyncols) {
08161
int i;
08162
08163
for (i = 0; i < s->
dcols; i++) {
08164
freep(&s->
dyncols[i].
typename);
08165 }
08166
if (s->
cols == s->
dyncols) {
08167 s->
cols = NULL;
08168 s->
ncols = 0;
08169 }
08170
freep(&s->
dyncols);
08171 }
08172 s->
dcols = 0;
08173 }
08174
08175
08176
08177
static void
08178 freeresult(
STMT *s,
int clrcols)
08179 {
08180
#if HAVE_ENCDEC
08181
freep(&s->bincache);
08182
freep(&s->hexcache);
08183 s->bincell = NULL;
08184
#endif
08185
if (s->
rows) {
08186
if (s->
rowfree) {
08187 s->
rowfree(s->
rows);
08188 s->
rowfree = NULL;
08189 }
08190 s->
rows = NULL;
08191 }
08192 s->
nrows = -1;
08193
if (clrcols > 0) {
08194
freep(&s->
bindcols);
08195 s->
nbindcols = 0;
08196 }
08197
if (clrcols) {
08198
freedyncols(s);
08199 s->
cols = NULL;
08200 s->
ncols = 0;
08201 }
08202 }
08203
08204
08205
08206
static void
08207 unbindcols(
STMT *s)
08208 {
08209
int i;
08210
08211 s->
bkmrkcol.
type = -1;
08212 s->
bkmrkcol.
max = 0;
08213 s->
bkmrkcol.
lenp = NULL;
08214 s->
bkmrkcol.
valp = NULL;
08215 s->
bkmrkcol.
index = 0;
08216 s->
bkmrkcol.
offs = 0;
08217
for (i = 0; s->
bindcols && i < s->
nbindcols; i++) {
08218 s->
bindcols[i].
type = -1;
08219 s->
bindcols[i].
max = 0;
08220 s->
bindcols[i].
lenp = NULL;
08221 s->
bindcols[i].
valp = NULL;
08222 s->
bindcols[i].
index = i;
08223 s->
bindcols[i].
offs = 0;
08224 }
08225 }
08226
08227
08228
08229
static SQLRETURN
08230 mkbindcols(
STMT *s,
int ncols)
08231 {
08232
if (s->
bindcols) {
08233
if (s->
nbindcols < ncols) {
08234
int i;
08235
BINDCOL *bindcols =
08236
xrealloc(s->
bindcols, ncols * sizeof (
BINDCOL));
08237
08238
if (!bindcols) {
08239
return nomem(s);
08240 }
08241
for (i = s->
nbindcols; i < ncols; i++) {
08242 bindcols[i].
type = -1;
08243 bindcols[i].
max = 0;
08244 bindcols[i].
lenp = NULL;
08245 bindcols[i].
valp = NULL;
08246 bindcols[i].
index = i;
08247 bindcols[i].
offs = 0;
08248 }
08249 s->
bindcols = bindcols;
08250 s->
nbindcols = ncols;
08251 }
08252 }
else if (ncols > 0) {
08253 s->
bindcols = (
BINDCOL *)
xmalloc(ncols *
sizeof (
BINDCOL));
08254
if (!s->
bindcols) {
08255
return nomem(s);
08256 }
08257 s->
nbindcols = ncols;
08258
unbindcols(s);
08259 }
08260
return SQL_SUCCESS;
08261 }
08262
08276
static SQLRETURN
08277 getrowdata(
STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
08278 SQLPOINTER val, SQLINTEGER len, SQLINTEGER *lenp,
int partial)
08279 {
08280
char **data, valdummy[16];
08281 SQLINTEGER dummy;
08282
int valnull = 0;
08283
int type = otype;
08284
08285
if (!s->
rows) {
08286
return SQL_NO_DATA;
08287 }
08288
if (col >= s->
ncols) {
08289
setstat(s, -1,
"invalid column", (*s->
ov3) ?
"07009" :
"S1002");
08290
return SQL_ERROR;
08291 }
08292
if (s->
rowp < 0 || s->
rowp >= s->
nrows) {
08293
return SQL_NO_DATA;
08294 }
08295 type =
mapdeftype(type, s->
cols[col].
type, s->
cols[col].
nosign ? 1 : 0,
08296 s->
nowchar);
08297
#if HAVE_ENCDEC
08298
if (otype == SQL_C_CHAR) {
08299
switch (s->
cols[col].
type) {
08300
case SQL_BINARY:
08301
case SQL_VARBINARY:
08302
case SQL_LONGVARBINARY:
08303 type = SQL_C_BINARY;
08304
break;
08305 }
08306
#ifdef SQLITE_UTF8
08307
}
else if (otype == SQL_C_WCHAR) {
08308
switch (s->
cols[col].
type) {
08309
case SQL_BINARY:
08310
case SQL_VARBINARY:
08311
case SQL_LONGVARBINARY:
08312 type = SQL_C_BINARY;
08313
break;
08314 }
08315
#endif
08316
}
08317
#endif
08318
data = s->
rows + s->
ncols + (s->
rowp * s->
ncols) + col;
08319
if (!lenp) {
08320 lenp = &dummy;
08321 }
08322
if (!val) {
08323 valnull = 1;
08324 val = (SQLPOINTER) valdummy;
08325 }
08326
if (*data == NULL) {
08327 *lenp = SQL_NULL_DATA;
08328
switch (type) {
08329
case SQL_C_UTINYINT:
08330
case SQL_C_TINYINT:
08331
case SQL_C_STINYINT:
08332 *((
char *) val) = 0;
08333
break;
08334
case SQL_C_USHORT:
08335
case SQL_C_SHORT:
08336
case SQL_C_SSHORT:
08337 *((
short *) val) = 0;
08338
break;
08339
case SQL_C_ULONG:
08340
case SQL_C_LONG:
08341
case SQL_C_SLONG:
08342 *((
long *) val) = 0;
08343
break;
08344
case SQL_C_FLOAT:
08345 *((
float *) val) = 0;
08346
break;
08347
case SQL_C_DOUBLE:
08348 *((
double *) val) = 0;
08349
break;
08350
case SQL_C_BINARY:
08351
case SQL_C_CHAR:
08352
#ifdef SQLITE_UTF8
08353
case SQL_C_WCHAR:
08354
if (otype == SQL_C_WCHAR) {
08355 *((SQLWCHAR *) val) =
'\0';
08356 }
else {
08357 *((
char *) val) =
'\0';
08358 }
08359
#else
08360
*((
char *) val) =
'\0';
08361
#endif
08362
break;
08363
#ifdef SQL_C_TYPE_DATE
08364
case SQL_C_TYPE_DATE:
08365
#endif
08366
case SQL_C_DATE:
08367 memset((DATE_STRUCT *) val, 0,
sizeof (DATE_STRUCT));
08368
break;
08369
#ifdef SQL_C_TYPE_TIME
08370
case SQL_C_TYPE_TIME:
08371
#endif
08372
case SQL_C_TIME:
08373 memset((TIME_STRUCT *) val, 0,
sizeof (TIME_STRUCT));
08374
break;
08375
#ifdef SQL_C_TYPE_TIMESTAMP
08376
case SQL_C_TYPE_TIMESTAMP:
08377
#endif
08378
case SQL_C_TIMESTAMP:
08379 memset((TIMESTAMP_STRUCT *) val, 0,
sizeof (TIMESTAMP_STRUCT));
08380
break;
08381
default:
08382
return SQL_ERROR;
08383 }
08384 }
else {
08385
char *endp = NULL;
08386
08387
switch (type) {
08388
case SQL_C_UTINYINT:
08389
case SQL_C_TINYINT:
08390
case SQL_C_STINYINT:
08391 *((
char *) val) = strtol(*data, &endp, 0);
08392
if (endp && endp == *data) {
08393 *lenp = SQL_NULL_DATA;
08394 }
else {
08395 *lenp =
sizeof (
char);
08396 }
08397
break;
08398
case SQL_C_USHORT:
08399
case SQL_C_SHORT:
08400
case SQL_C_SSHORT:
08401 *((
short *) val) = strtol(*data, &endp, 0);
08402
if (endp && endp == *data) {
08403 *lenp = SQL_NULL_DATA;
08404 }
else {
08405 *lenp =
sizeof (
short);
08406 }
08407
break;
08408
case SQL_C_ULONG:
08409
case SQL_C_LONG:
08410
case SQL_C_SLONG:
08411 *((
int *) val) = strtol(*data, &endp, 0);
08412
if (endp && endp == *data) {
08413 *lenp = SQL_NULL_DATA;
08414 }
else {
08415 *lenp =
sizeof (
int);
08416 }
08417
break;
08418
case SQL_C_FLOAT:
08419 *((
float *) val) =
ln_strtod(*data, &endp);
08420
if (endp && endp == *data) {
08421 *lenp = SQL_NULL_DATA;
08422 }
else {
08423 *lenp =
sizeof (
float);
08424 }
08425
break;
08426
case SQL_C_DOUBLE:
08427 *((
double *) val) =
ln_strtod(*data, &endp);
08428
if (endp && endp == *data) {
08429 *lenp = SQL_NULL_DATA;
08430 }
else {
08431 *lenp =
sizeof (
double);
08432 }
08433
break;
08434
case SQL_C_BINARY:
08435
#if HAVE_ENCDEC
08436
{
08437
int dlen, offs = 0;
08438
char *bin, *hex = NULL;
08439
08440
if (*data == s->bincell && s->bincache) {
08441 bin = s->bincache;
08442 dlen = s->binlen;
08443 }
else {
08444
freep(&s->bincache);
08445
freep(&s->hexcache);
08446 s->bincell = NULL;
08447 dlen = strlen(*data);
08448 bin =
xmalloc(dlen + 1);
08449
if (!bin) {
08450
return nomem(s);
08451 }
08452 dlen = sqlite_decode_binary(*data, bin);
08453
if (dlen < 0) {
08454
freep(&bin);
08455
setstat(s, -1,
"error decoding binary data",
08456 (*s->
ov3) ?
"HY000" :
"S1000");
08457
return SQL_ERROR;
08458 }
08459 s->bincache = bin;
08460 s->binlen = dlen;
08461 s->bincell = *data;
08462 }
08463
#ifdef SQLITE_UTF8
08464
if (otype == SQL_C_CHAR || otype == SQL_C_WCHAR) {
08465
#else
08466
if (otype == SQL_C_CHAR) {
08467
#endif
08468
if (s->hexcache) {
08469 hex = s->hexcache;
08470 }
else {
08471
int i, k;
08472
08473 hex =
xmalloc(dlen * 2 + 1);
08474
if (!hex) {
08475
return nomem(s);
08476 }
08477
for (i = 0, k = 0; i < dlen; i++) {
08478 hex[k++] = hexdigits[(bin[i] >> 4) & 0x0f];
08479 hex[k++] = hexdigits[bin[i] & 0x0f];
08480 }
08481 hex[k] =
'\0';
08482 s->hexcache = hex;
08483 }
08484 }
08485
if (otype == SQL_C_CHAR) {
08486 bin = hex;
08487 dlen = dlen * 2;
08488 }
08489
#ifdef SQLITE_UTF8
08490
else if (otype == SQL_C_WCHAR) {
08491 bin = hex;
08492 dlen = dlen * 2 *
sizeof (SQLWCHAR);
08493 }
08494
#endif
08495
if (partial && len && s->
bindcols) {
08496
if (dlen && s->
bindcols[col].
offs >= dlen) {
08497 s->
bindcols[col].
offs = 0;
08498
return SQL_NO_DATA;
08499 }
08500 offs = s->
bindcols[col].
offs;
08501 dlen -= offs;
08502 }
08503
if (val && !valnull && len) {
08504
int max =
min(len, dlen);
08505
08506
#ifdef SQLITE_UTF8
08507
if (otype == SQL_C_WCHAR) {
08508
int i;
08509 SQLWCHAR *valw = (SQLWCHAR *) val;
08510
08511
for (i = 0; i <
max; i++) {
08512 valw[i] = bin[i + offs];
08513 }
08514 }
else
08515
#endif
08516
memcpy(val, bin + offs,
max);
08517 }
08518
if (valnull || len < 1) {
08519 *lenp = dlen;
08520 }
else {
08521 *lenp =
min(len, dlen);
08522
if (*lenp == len && *lenp != dlen) {
08523 *lenp = SQL_NO_TOTAL;
08524 }
08525 }
08526
if (!valnull) {
08527
if (otype == SQL_C_CHAR) {
08528 ((
char *) val)[len - 1] =
'\0';
08529 }
08530
#ifdef SQLITE_UTF8
08531
else if (otype == SQL_C_WCHAR) {
08532 ((SQLWCHAR *) val)[len /
sizeof (SQLWCHAR) - 1] = 0;
08533 }
08534
#endif
08535
}
08536
if (partial && len && s->
bindcols) {
08537
if (*lenp == SQL_NO_TOTAL) {
08538 s->
bindcols[col].
offs += len;
08539
setstat(s, -1,
"data right truncated",
"01004");
08540
if (s->
bindcols[col].
lenp) {
08541 *s->
bindcols[col].
lenp = dlen;
08542 }
08543
return SQL_SUCCESS_WITH_INFO;
08544 }
08545 s->
bindcols[col].
offs += *lenp;
08546 }
08547
break;
08548 }
08549
#endif
08550
#ifdef SQLITE_UTF8
08551
case SQL_C_WCHAR:
08552
#endif
08553
case SQL_C_CHAR: {
08554
int doz;
08555
int dlen = strlen(*data);
08556
int offs = 0;
08557
08558
#ifdef SQLITE_UTF8
08559
SQLWCHAR *ucdata = NULL;
08560
08561 doz = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? 1 : 0;
08562
if (otype == SQL_C_WCHAR) {
08563 ucdata = uc_from_utf(*data, dlen);
08564
if (!ucdata) {
08565
return nomem(s);
08566 }
08567 dlen = uc_strlen(ucdata) *
sizeof (SQLWCHAR);
08568 }
08569
#else
08570
doz = type == SQL_C_CHAR ? 1 : 0;
08571
#endif
08572
if (partial && len && s->
bindcols) {
08573
if (dlen && s->
bindcols[col].
offs >= dlen) {
08574 s->
bindcols[col].
offs = 0;
08575
#ifdef SQLITE_UTF8
08576
uc_free(ucdata);
08577
#endif
08578
return SQL_NO_DATA;
08579 }
08580 offs = s->
bindcols[col].
offs;
08581 dlen -= offs;
08582 }
08583
if (val && !valnull && len) {
08584
#ifdef SQLITE_UTF8
08585
if (otype == SQL_C_WCHAR) {
08586 uc_strncpy(val, ucdata + offs /
sizeof (SQLWCHAR),
08587 (len - doz) /
sizeof (SQLWCHAR));
08588 }
else {
08589 strncpy(val, *data + offs, len - doz);
08590 }
08591
#else
08592
strncpy(val, *data + offs, len - doz);
08593
#endif
08594
}
08595
if (valnull || len < 1) {
08596 *lenp = dlen;
08597 }
else {
08598 *lenp =
min(len - doz, dlen);
08599
if (*lenp == len - doz && *lenp != dlen) {
08600 *lenp = SQL_NO_TOTAL;
08601 }
08602 }
08603
if (len && !valnull && doz) {
08604
#ifdef SQLITE_UTF8
08605
if (otype == SQL_C_WCHAR) {
08606 ((SQLWCHAR *) val)[len /
sizeof (SQLWCHAR) - 1] = 0;
08607 }
else {
08608 ((
char *) val)[len - 1] =
'\0';
08609 }
08610
#else
08611
((
char *) val)[len - 1] =
'\0';
08612
#endif
08613
}
08614
#ifdef SQLITE_UTF8
08615
uc_free(ucdata);
08616
#endif
08617
if (partial && len && s->
bindcols) {
08618
if (*lenp == SQL_NO_TOTAL) {
08619 s->
bindcols[col].
offs += len - doz;
08620
setstat(s, -1,
"data right truncated",
"01004");
08621
if (s->
bindcols[col].
lenp) {
08622 *s->
bindcols[col].
lenp = dlen;
08623 }
08624
return SQL_SUCCESS_WITH_INFO;
08625 }
08626 s->
bindcols[col].
offs += *lenp;
08627 }
08628
break;
08629 }
08630
#ifdef SQL_C_TYPE_DATE
08631
case SQL_C_TYPE_DATE:
08632
#endif
08633
case SQL_C_DATE:
08634
if (
str2date(*data, (DATE_STRUCT *) val) < 0) {
08635 *lenp = SQL_NULL_DATA;
08636 }
else {
08637 *lenp =
sizeof (DATE_STRUCT);
08638 }
08639
break;
08640
#ifdef SQL_C_TYPE_TIME
08641
case SQL_C_TYPE_TIME:
08642
#endif
08643
case SQL_C_TIME:
08644
if (
str2time(*data, (TIME_STRUCT *) val) < 0) {
08645 *lenp = SQL_NULL_DATA;
08646 }
else {
08647 *lenp =
sizeof (TIME_STRUCT);
08648 }
08649
break;
08650
#ifdef SQL_C_TYPE_TIMESTAMP
08651
case SQL_C_TYPE_TIMESTAMP:
08652
#endif
08653
case SQL_C_TIMESTAMP:
08654
if (
str2timestamp(*data, (TIMESTAMP_STRUCT *) val) < 0) {
08655 *lenp = SQL_NULL_DATA;
08656 }
else {
08657 *lenp =
sizeof (TIMESTAMP_STRUCT);
08658 }
08659
break;
08660
default:
08661
return SQL_ERROR;
08662 }
08663 }
08664
return SQL_SUCCESS;
08665 }
08666
08678 SQLRETURN SQL_API
08679 SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
08680 SQLPOINTER val, SQLINTEGER max, SQLINTEGER *lenp)
08681 {
08682
STMT *s;
08683
08684
if (stmt == SQL_NULL_HSTMT) {
08685
return SQL_INVALID_HANDLE;
08686 }
08687 s = (
STMT *) stmt;
08688
if (col < 1) {
08689
if (col == 0 && s->
bkmrk && type == SQL_C_BOOKMARK) {
08690 s->
bkmrkcol.
type = type;
08691 s->
bkmrkcol.
max =
max;
08692 s->
bkmrkcol.
lenp = lenp;
08693 s->
bkmrkcol.
valp = val;
08694 s->
bkmrkcol.
offs = 0;
08695
if (lenp) {
08696 *lenp = 0;
08697 }
08698
return SQL_SUCCESS;
08699 }
08700
setstat(s, -1,
"invalid column", (*s->
ov3) ?
"07009" :
"S1002");
08701
return SQL_ERROR;
08702 }
08703
if (
mkbindcols(s, col) != SQL_SUCCESS) {
08704
return SQL_ERROR;
08705 }
08706 --col;
08707
if (type == SQL_C_DEFAULT) {
08708 type =
mapdeftype(type, s->
cols[col].
type, 0, s->
nowchar);
08709 }
else {
08710
switch (type) {
08711
case SQL_C_LONG:
08712
case SQL_C_ULONG:
08713
case SQL_C_SLONG:
08714
case SQL_C_TINYINT:
08715
case SQL_C_UTINYINT:
08716
case SQL_C_STINYINT:
08717
case SQL_C_SHORT:
08718
case SQL_C_USHORT:
08719
case SQL_C_SSHORT:
08720
case SQL_C_FLOAT:
08721
case SQL_C_DOUBLE:
08722
case SQL_C_TIMESTAMP:
08723
case SQL_C_TIME:
08724
case SQL_C_DATE:
08725
case SQL_C_CHAR:
08726
#ifdef SQLITE_UTF8
08727
case SQL_C_WCHAR:
08728
#endif
08729
#ifdef SQL_C_TYPE_DATE
08730
case SQL_C_TYPE_DATE:
08731
#endif
08732
#ifdef SQL_C_TYPE_TIME
08733
case SQL_C_TYPE_TIME:
08734
#endif
08735
#ifdef SQL_C_TYPE_TIMESTAMP
08736
case SQL_C_TYPE_TIMESTAMP:
08737
#endif
08738
break;
08739
#if HAVE_ENCDEC
08740
case SQL_C_BINARY:
08741
break;
08742
#endif
08743
default:
08744
setstat(s, -1,
"invalid type %d",
"HY003", type);
08745
return SQL_ERROR;
08746 }
08747 }
08748
if (
max < 0) {
08749
setstat(s, -1,
"invalid length",
"HY090");
08750
return SQL_ERROR;
08751 }
08752 s->
bindcols[col].
type = type;
08753 s->
bindcols[col].
max =
max;
08754 s->
bindcols[col].
lenp = lenp;
08755 s->
bindcols[col].
valp = val;
08756 s->
bindcols[col].
offs = 0;
08757
if (lenp) {
08758 *lenp = 0;
08759 }
08760
return SQL_SUCCESS;
08761 }
08762
08767 static COL tableSpec[] = {
08768 {
"SYSTEM",
"COLUMN",
"TABLE_QUALIFIER",
SCOL_VARCHAR, 50 },
08769 {
"SYSTEM",
"COLUMN",
"TABLE_OWNER",
SCOL_VARCHAR, 50 },
08770 {
"SYSTEM",
"COLUMN",
"TABLE_NAME",
SCOL_VARCHAR, 255 },
08771 {
"SYSTEM",
"COLUMN",
"TABLE_TYPE",
SCOL_VARCHAR, 50 },
08772 {
"SYSTEM",
"COLUMN",
"REMARKS",
SCOL_VARCHAR, 50 }
08773 };
08774
08789
static SQLRETURN
08790 drvtables(SQLHSTMT stmt,
08791 SQLCHAR *cat, SQLSMALLINT catLen,
08792 SQLCHAR *schema, SQLSMALLINT schemaLen,
08793 SQLCHAR *table, SQLSMALLINT tableLen,
08794 SQLCHAR *type, SQLSMALLINT typeLen)
08795 {
08796 SQLRETURN ret;
08797
STMT *s;
08798
DBC *d;
08799
int ncols, rc;
08800
char *errp = NULL, tname[512];
08801
char *where =
"(type = 'table' or type = 'view')";
08802
08803 ret =
mkresultset(stmt,
tableSpec,
array_size(
tableSpec));
08804
if (ret != SQL_SUCCESS) {
08805
return ret;
08806 }
08807 s = (
STMT *) stmt;
08808 d = (
DBC *) s->
dbc;
08809
if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] ==
'%') {
08810
int size = 3 *
array_size(
tableSpec);
08811
08812 s->
rows =
xmalloc(size *
sizeof (
char *));
08813
if (!s->
rows) {
08814 s->
nrows = 0;
08815
return nomem(s);
08816 }
08817 memset(s->
rows, 0, sizeof (
char *) * size);
08818 s->
ncols =
array_size(
tableSpec);
08819 s->
rows[s->
ncols + 0] =
"";
08820 s->
rows[s->
ncols + 1] =
"";
08821 s->
rows[s->
ncols + 2] =
"";
08822 s->
rows[s->
ncols + 3] =
"TABLE";
08823 s->
rows[s->
ncols + 5] =
"";
08824 s->
rows[s->
ncols + 6] =
"";
08825 s->
rows[s->
ncols + 7] =
"";
08826 s->
rows[s->
ncols + 8] =
"VIEW";
08827
#ifdef MEMORY_DEBUG
08828
s->
rowfree = xfree__;
08829
#else
08830
s->
rowfree = free;
08831
#endif
08832
s->
nrows = 2;
08833 s->
rowp = -1;
08834
return SQL_SUCCESS;
08835 }
08836
if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] ==
'%') {
08837
int size = 2 *
array_size(
tableSpec);
08838
08839 s->
rows =
xmalloc(size *
sizeof (
char *));
08840
if (!s->
rows) {
08841 s->
nrows = 0;
08842
return nomem(s);
08843 }
08844 memset(s->
rows, 0, sizeof (
char *) * size);
08845 s->
ncols =
array_size(
tableSpec);
08846 s->
rows[s->
ncols + 0] =
"";
08847 s->
rows[s->
ncols + 1] =
"";
08848 s->
rows[s->
ncols + 2] = d->
dbname;
08849 s->
rows[s->
ncols + 3] =
"CATALOG";
08850
#ifdef MEMORY_DEBUG
08851
s->
rowfree = xfree__;
08852
#else
08853
s->
rowfree = free;
08854
#endif
08855
s->
nrows = 1;
08856 s->
rowp = -1;
08857
return SQL_SUCCESS;
08858 }
08859
if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
08860 schema[0] ==
'%') {
08861
if ((!cat || catLen == 0 || !cat[0]) &&
08862 (!table || tableLen == 0 || !table[0])) {
08863
int size = 2 *
array_size(
tableSpec);
08864
08865 s->
rows =
xmalloc(size *
sizeof (
char *));
08866
if (!s->
rows) {
08867 s->
nrows = 0;
08868
return nomem(s);
08869 }
08870 memset(s->
rows, 0, sizeof (
char *) * size);
08871 s->
ncols =
array_size(
tableSpec);
08872 s->
rows[s->
ncols + 1] =
"";
08873
#ifdef MEMORY_DEBUG
08874
s->
rowfree = xfree__;
08875
#else
08876
s->
rowfree = free;
08877
#endif
08878
s->
nrows = 1;
08879 s->
rowp = -1;
08880
return SQL_SUCCESS;
08881 }
08882 }
08883
if (type) {
08884
char tmp[256], *t;
08885
int with_view = 0, with_table = 0;
08886
08887
if (typeLen == SQL_NTS) {
08888 strncpy(tmp, type,
sizeof (tmp));
08889 tmp[
sizeof (tmp) - 1] =
'\0';
08890 }
else {
08891
int len =
min(
sizeof (tmp) - 1, typeLen);
08892
08893 strncpy(tmp, type, len);
08894 tmp[len] =
'\0';
08895 }
08896 t = tmp;
08897
while (*t) {
08898 *t =
TOLOWER(*t);
08899 t++;
08900 }
08901 t = tmp;
08902
while (t) {
08903
if (t[0] ==
'\'') {
08904 ++t;
08905 }
08906
if (strncmp(t,
"table", 5) == 0) {
08907 with_table++;
08908 }
else if (strncmp(t,
"view", 4) == 0) {
08909 with_view++;
08910 }
08911 t = strchr(t,
',');
08912
if (t) {
08913 ++t;
08914 }
08915 }
08916
if (with_view && with_table) {
08917
08918 }
else if (with_view && !with_table) {
08919 where =
"type = 'view'";
08920 }
else if (!with_view && with_table) {
08921 where =
"type = 'table'";
08922 }
else {
08923 s->
rowp = -1;
08924
return SQL_SUCCESS;
08925 }
08926 }
08927 strcpy(tname,
"%");
08928
if (table && (tableLen > 0 || tableLen == SQL_NTS) && table[0] !=
'%') {
08929
int size;
08930
08931
if (tableLen == SQL_NTS) {
08932 size =
sizeof (tname) - 1;
08933 }
else {
08934 size =
min(
sizeof (tname) - 1, tableLen);
08935 }
08936 strncpy(tname, table, size);
08937 tname[size] =
'\0';
08938 }
08939 rc = sqlite_get_table_printf(d->
sqlite,
08940
"select '' as 'TABLE_QUALIFIER', "
08941
"'' as 'TABLE_OWNER', "
08942
"tbl_name as 'TABLE_NAME', "
08943
"upper(type) as 'TABLE_TYPE', "
08944
"NULL as 'REMARKS' "
08945
"from sqlite_master where %s"
08946
"and tbl_name like '%q'",
08947 &s->
rows, &s->
nrows, &ncols, &errp,
08948 where, tname);
08949
if (rc == SQLITE_OK) {
08950
if (ncols != s->
ncols) {
08951
freeresult(s, 0);
08952 s->
nrows = 0;
08953 }
else {
08954 s->
rowfree = sqlite_free_table;
08955 }
08956 }
else {
08957 s->
nrows = 0;
08958 s->
rows = NULL;
08959 s->
rowfree = NULL;
08960 }
08961
if (errp) {
08962 sqlite_freemem(errp);
08963 errp = NULL;
08964 }
08965 s->
rowp = -1;
08966
return SQL_SUCCESS;
08967 }
08968
08969
#ifndef SQLITE_UTF8
08970
08984 SQLRETURN SQL_API
08985 SQLTables(SQLHSTMT stmt,
08986 SQLCHAR *cat, SQLSMALLINT catLen,
08987 SQLCHAR *schema, SQLSMALLINT schemaLen,
08988 SQLCHAR *table, SQLSMALLINT tableLen,
08989 SQLCHAR *type, SQLSMALLINT typeLen)
08990 {
08991
return drvtables(stmt, cat, catLen, schema, schemaLen,
08992 table, tableLen, type, typeLen);
08993 }
08994
#endif
08995
08996
#ifdef SQLITE_UTF8
08997
09011 SQLRETURN SQL_API
09012 SQLTablesW(SQLHSTMT stmt,
09013 SQLWCHAR *cat, SQLSMALLINT catLen,
09014 SQLWCHAR *schema, SQLSMALLINT schemaLen,
09015 SQLWCHAR *table, SQLSMALLINT tableLen,
09016 SQLWCHAR *type, SQLSMALLINT typeLen)
09017 {
09018
char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
09019 SQLRETURN ret;
09020
09021
if (cat) {
09022 c = uc_to_utf_c(cat, catLen);
09023
if (!c) {
09024 ret =
nomem((
STMT *) stmt);
09025
goto done;
09026 }
09027 }
09028
if (schema) {
09029 s = uc_to_utf_c(schema, schemaLen);
09030
if (!s) {
09031 ret =
nomem((
STMT *) stmt);
09032
goto done;
09033 }
09034 }
09035
if (table) {
09036 t = uc_to_utf_c(table, tableLen);
09037
if (!t) {
09038 ret =
nomem((
STMT *) stmt);
09039
goto done;
09040 }
09041 }
09042
if (type) {
09043 y = uc_to_utf_c(type, typeLen);
09044
if (!y) {
09045 ret =
nomem((
STMT *) stmt);
09046
goto done;
09047 }
09048 }
09049 ret =
drvtables(stmt, c, SQL_NTS, s, SQL_NTS,
09050 t, SQL_NTS, y, SQL_NTS);
09051 done:
09052 uc_free(y);
09053 uc_free(t);
09054 uc_free(s);
09055 uc_free(c);
09056
return ret;
09057 }
09058
#endif
09059
09064 static COL colSpec[] = {
09065 {
"SYSTEM",
"COLUMN",
"TABLE_QUALIFIER",
SCOL_VARCHAR, 50 },
09066 {
"SYSTEM",
"COLUMN",
"TABLE_OWNER",
SCOL_VARCHAR, 50 },
09067 {
"SYSTEM",
"COLUMN",
"TABLE_NAME",
SCOL_VARCHAR, 255 },
09068 {
"SYSTEM",
"COLUMN",
"COLUMN_NAME",
SCOL_VARCHAR, 255 },
09069 {
"SYSTEM",
"COLUMN",
"DATA_TYPE", SQL_SMALLINT, 50 },
09070 {
"SYSTEM",
"COLUMN",
"TYPE_NAME",
SCOL_VARCHAR, 50 },
09071 {
"SYSTEM",
"COLUMN",
"PRECISION", SQL_INTEGER, 50 },
09072 {
"SYSTEM",
"COLUMN",
"LENGTH", SQL_INTEGER, 50 },
09073 {
"SYSTEM",
"COLUMN",
"RADIX", SQL_SMALLINT, 50 },
09074 {
"SYSTEM",
"COLUMN",
"SCALE", SQL_SMALLINT, 50 },
09075 {
"SYSTEM",
"COLUMN",
"NULLABLE", SQL_SMALLINT, 50 },
09076 {
"SYSTEM",
"COLUMN",
"REMARKS",
SCOL_VARCHAR, 50 },
09077 {
"SYSTEM",
"COLUMN",
"COLUMN_DEF",
SCOL_VARCHAR, 50 },
09078 {
"SYSTEM",
"COLUMN",
"SQL_DATA_TYPE", SQL_SMALLINT, 50 },
09079 {
"SYSTEM",
"COLUMN",
"SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
09080 {
"SYSTEM",
"COLUMN",
"CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
09081 {
"SYSTEM",
"COLUMN",
"ORDINAL_POSITION", SQL_SMALLINT, 50 },
09082 {
"SYSTEM",
"COLUMN",
"IS_NULLABLE",
SCOL_VARCHAR, 50 }
09083 };
09084
09099
static SQLRETURN
09100 drvcolumns(SQLHSTMT stmt,
09101 SQLCHAR *cat, SQLSMALLINT catLen,
09102 SQLCHAR *schema, SQLSMALLINT schemaLen,
09103 SQLCHAR *table, SQLSMALLINT tableLen,
09104 SQLCHAR *col, SQLSMALLINT colLen)
09105 {
09106 SQLRETURN sret;
09107
STMT *s;
09108
DBC *d;
09109
int ret, nrows, ncols, size, i, k;
09110
char *errp = NULL, tname[512], **rowp;
09111
09112 sret =
mkresultset(stmt,
colSpec,
array_size(
colSpec));
09113
if (sret != SQL_SUCCESS) {
09114
return sret;
09115 }
09116 s = (
STMT *) stmt;
09117 d = (
DBC *) s->
dbc;
09118
if (!table || table[0] ==
'\0' || table[0] ==
'%') {
09119
setstat(s, -1,
"need table name", (*s->
ov3) ?
"HY000" :
"S1000");
09120
return SQL_ERROR;
09121 }
09122
if (tableLen == SQL_NTS) {
09123 size =
sizeof (tname) - 1;
09124 }
else {
09125 size =
min(
sizeof (tname) - 1, tableLen);
09126 }
09127 strncpy(tname, table, size);
09128 tname[size] =
'\0';
09129 ret = sqlite_get_table_printf(d->
sqlite,
"PRAGMA table_info('%q')", &rowp,
09130 &nrows, &ncols, &errp, tname);
09131
if (ret != SQLITE_OK) {
09132
setstat(s, ret,
"%s (%d)", (*s->
ov3) ?
"HY000" :
"S1000",
09133 errp ? errp :
"unknown error", ret);
09134
if (errp) {
09135 sqlite_freemem(errp);
09136 errp = NULL;
09137 }
09138
return SQL_ERROR;
09139 }
09140
if (errp) {
09141 sqlite_freemem(errp);
09142 errp = NULL;
09143 }
09144
if (ncols * nrows <= 0) {
09145 sqlite_free_table(rowp);
09146
return SQL_NO_DATA;
09147 }
09148 size =
array_size(
colSpec) * (nrows + 1);
09149 s->
rows =
xmalloc((size + 1) *
sizeof (
char *));
09150
if (!s->
rows) {
09151
return nomem(s);
09152 }
09153 s->
rows[0] = (
char *) size;
09154 s->
rows += 1;
09155 memset(s->
rows, 0, sizeof (
char *) * size);
09156 s->
rowfree =
freerows;
09157 s->
nrows = nrows;
09158
for (i = 1; i <= s->
nrows; i++) {
09159 s->
rows[
array_size(
colSpec) * i + 0] =
xstrdup(
"");
09160 s->
rows[
array_size(
colSpec) * i + 1] =
xstrdup(
"");
09161 s->
rows[
array_size(
colSpec) * i + 2] =
xstrdup(tname);
09162 s->
rows[
array_size(
colSpec) * i + 8] =
xstrdup(
"10");
09163 s->
rows[
array_size(
colSpec) * i + 9] =
xstrdup(
"0");
09164 s->
rows[
array_size(
colSpec) * i + 15] =
xstrdup(
"16384");
09165 }
09166
for (k = 0; k < ncols; k++) {
09167
if (strcmp(rowp[k],
"cid") == 0) {
09168
for (i = 1; i <= s->
nrows; i++) {
09169
char buf[256];
09170
int coln = i;
09171
09172 sscanf(rowp[i * ncols + k],
"%d", &coln);
09173 sprintf(buf,
"%d", coln + 1);
09174 s->
rows[
array_size(
colSpec) * i + 16] =
xstrdup(buf);
09175 }
09176 }
else if (strcmp(rowp[k],
"name") == 0) {
09177
for (i = 1; i <= s->
nrows; i++) {
09178 s->
rows[
array_size(
colSpec) * i + 3] =
09179
xstrdup(rowp[i * ncols + k]);
09180 }
09181 }
else if (strcmp(rowp[k],
"notnull") == 0) {
09182
for (i = 1; i <= s->
nrows; i++) {
09183
if (*rowp[i * ncols + k] !=
'0') {
09184 s->
rows[
array_size(
colSpec) * i + 10] =
09185
xstrdup(
stringify(SQL_FALSE));
09186 }
else {
09187 s->
rows[
array_size(
colSpec) * i + 10] =
09188
xstrdup(
stringify(SQL_TRUE));
09189 }
09190 s->
rows[
array_size(
colSpec) * i + 17] =
09191
xstrdup(*rowp[i * ncols + k] !=
'0' ?
"NO" :
"YES");
09192 }
09193 }
else if (strcmp(rowp[k],
"dflt_value") == 0) {
09194
for (i = 1; i <= s->
nrows; i++) {
09195
char *dflt = rowp[i * ncols + k];
09196
09197 s->
rows[
array_size(
colSpec) * i + 12] =
09198
xstrdup(dflt ? dflt :
"NULL");
09199 }
09200 }
else if (strcmp(rowp[k],
"type") == 0) {
09201
for (i = 1; i <= s->
nrows; i++) {
09202
char *
typename = rowp[i * ncols + k];
09203
int sqltype, m, d;
09204
char buf[256];
09205
09206 s->
rows[
array_size(
colSpec) * i + 5] =
xstrdup(
typename);
09207 sqltype =
mapsqltype(
typename, NULL, *s->
ov3, s->
nowchar);
09208
getmd(
typename, sqltype, &m, &d);
09209
#ifdef SQL_LONGVARCHAR
09210
if (sqltype == SQL_VARCHAR && m > 255) {
09211 sqltype = SQL_LONGVARCHAR;
09212 }
09213
#endif
09214
#ifdef SQLITE_UTF8
09215
#ifdef SQL_WLONGVARCHAR
09216
if (sqltype == SQL_WVARCHAR && m > 255) {
09217 sqltype = SQL_WLONGVARCHAR;
09218 }
09219
#endif
09220
#endif
09221
#if HAVE_ENCDEC
09222
if (sqltype == SQL_VARBINARY && m > 255) {
09223 sqltype = SQL_LONGVARBINARY;
09224 }
09225
#endif
09226
sprintf(buf,
"%d", sqltype);
09227 s->
rows[
array_size(
colSpec) * i + 4] =
xstrdup(buf);
09228 s->
rows[
array_size(
colSpec) * i + 13] =
xstrdup(buf);
09229 sprintf(buf,
"%d", m);
09230 s->
rows[
array_size(
colSpec) * i + 7] =
xstrdup(buf);
09231 sprintf(buf,
"%d", d);
09232 s->
rows[
array_size(
colSpec) * i + 6] =
xstrdup(buf);
09233 }
09234 }
09235 }
09236 sqlite_free_table(rowp);
09237
return SQL_SUCCESS;
09238 }
09239
09240
#ifndef SQLITE_UTF8
09241
09255 SQLRETURN SQL_API
09256 SQLColumns(SQLHSTMT stmt,
09257 SQLCHAR *cat, SQLSMALLINT catLen,
09258 SQLCHAR *schema, SQLSMALLINT schemaLen,
09259 SQLCHAR *table, SQLSMALLINT tableLen,
09260 SQLCHAR *col, SQLSMALLINT colLen)
09261 {
09262
return drvcolumns(stmt, cat, catLen, schema, schemaLen,
09263 table, tableLen, col, colLen);
09264 }
09265
#endif
09266
09267
#ifdef SQLITE_UTF8
09268
09282 SQLRETURN SQL_API
09283 SQLColumnsW(SQLHSTMT stmt,
09284 SQLWCHAR *cat, SQLSMALLINT catLen,
09285 SQLWCHAR *schema, SQLSMALLINT schemaLen,
09286 SQLWCHAR *table, SQLSMALLINT tableLen,
09287 SQLWCHAR *col, SQLSMALLINT colLen)
09288 {
09289
char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
09290 SQLRETURN ret;
09291
09292
if (cat) {
09293 c = uc_to_utf_c(cat, catLen);
09294
if (!c) {
09295 ret =
nomem((
STMT *) stmt);
09296
goto done;
09297 }
09298 }
09299
if (schema) {
09300 s = uc_to_utf_c(schema, schemaLen);
09301
if (!s) {
09302 ret =
nomem((
STMT *) stmt);
09303
goto done;
09304 }
09305 }
09306
if (table) {
09307 t = uc_to_utf_c(table, tableLen);
09308
if (!t) {
09309 ret =
nomem((
STMT *) stmt);
09310
goto done;
09311 }
09312 }
09313
if (col) {
09314 k = uc_to_utf_c(col, colLen);
09315
if (!k) {
09316 ret =
nomem((
STMT *) stmt);
09317
goto done;
09318 }
09319 }
09320 ret =
drvcolumns(stmt, c, SQL_NTS, s, SQL_NTS,
09321 t, SQL_NTS, k, SQL_NTS);
09322 done:
09323 uc_free(k);
09324 uc_free(t);
09325 uc_free(s);
09326 uc_free(c);
09327
return ret;
09328
09329 }
09330
#endif
09331
09336 static COL typeSpec[] = {
09337 {
"SYSTEM",
"TYPE",
"TYPE_NAME",
SCOL_VARCHAR, 50 },
09338 {
"SYSTEM",
"TYPE",
"DATA_TYPE", SQL_SMALLINT, 2 },
09339 {
"SYSTEM",
"TYPE",
"PRECISION", SQL_INTEGER, 4 },
09340 {
"SYSTEM",
"TYPE",
"LITERAL_PREFIX",
SCOL_VARCHAR, 50 },
09341 {
"SYSTEM",
"TYPE",
"LITERAL_SUFFIX",
SCOL_VARCHAR, 50 },
09342 {
"SYSTEM",
"TYPE",
"CREATE_PARAMS",
SCOL_VARCHAR, 50 },
09343 {
"SYSTEM",
"TYPE",
"NULLABLE", SQL_SMALLINT, 2 },
09344 {
"SYSTEM",
"TYPE",
"CASE_SENSITIVE", SQL_SMALLINT, 2 },
09345 {
"SYSTEM",
"TYPE",
"SEARCHABLE", SQL_SMALLINT, 2 },
09346 {
"SYSTEM",
"TYPE",
"UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
09347 {
"SYSTEM",
"TYPE",
"MONEY", SQL_SMALLINT, 2 },
09348 {
"SYSTEM",
"TYPE",
"AUTO_INCREMENT", SQL_SMALLINT, 2 },
09349 {
"SYSTEM",
"TYPE",
"LOCAL_TYPE_NAME",
SCOL_VARCHAR, 50 },
09350 {
"SYSTEM",
"TYPE",
"MINIMUM_SCALE", SQL_SMALLINT, 2 },
09351 {
"SYSTEM",
"TYPE",
"MAXIMUM_SCALE", SQL_SMALLINT, 2 }
09352 };
09353
09363
static void
09364 mktypeinfo(
STMT *s,
int row,
char *
typename,
int type,
int tind)
09365 {
09366
int offs = row *
array_size(
typeSpec);
09367
char *tcode, *crpar = NULL, *quote = NULL, *sign =
stringify(SQL_FALSE);
09368
static char tcodes[32 * 32];
09369
09370
if (tind <= 0) {
09371 tind = row;
09372 }
09373 tcode = tcodes + tind * 32;
09374 sprintf(tcode,
"%d", type);
09375 s->
rows[offs + 0] =
typename;
09376 s->
rows[offs + 1] = tcode;
09377
switch (type) {
09378
default:
09379
#ifdef SQL_LONGVARCHAR
09380
case SQL_LONGVARCHAR:
09381
#ifdef SQLITE_UTF8
09382
case SQL_WLONGVARCHAR:
09383
#endif
09384
crpar =
"length";
09385 quote =
"'";
09386 sign = NULL;
09387 s->
rows[offs + 2] =
"65536";
09388
break;
09389
#endif
09390
case SQL_CHAR:
09391
case SQL_VARCHAR:
09392
#ifdef SQLITE_UTF8
09393
case SQL_WCHAR:
09394
case SQL_WVARCHAR:
09395
#endif
09396
s->
rows[offs + 2] =
"255";
09397 crpar =
"length";
09398 quote =
"'";
09399 sign = NULL;
09400
break;
09401
case SQL_TINYINT:
09402 s->
rows[offs + 2] =
"3";
09403
break;
09404
case SQL_SMALLINT:
09405 s->
rows[offs + 2] =
"5";
09406
break;
09407
case SQL_INTEGER:
09408 s->
rows[offs + 2] =
"7";
09409
break;
09410
case SQL_FLOAT:
09411 s->
rows[offs + 2] =
"7";
09412
break;
09413
case SQL_DOUBLE:
09414 s->
rows[offs + 2] =
"15";
09415
break;
09416
#ifdef SQL_TYPE_DATE
09417
case SQL_TYPE_DATE:
09418
#endif
09419
case SQL_DATE:
09420 s->
rows[offs + 2] =
"10";
09421 quote =
"'";
09422 sign = NULL;
09423
break;
09424
#ifdef SQL_TYPE_TIME
09425
case SQL_TYPE_TIME:
09426
#endif
09427
case SQL_TIME:
09428 s->
rows[offs + 2] =
"8";
09429 quote =
"'";
09430 sign = NULL;
09431
break;
09432
#ifdef SQL_TYPE_TIMESTAMP
09433
case SQL_TYPE_TIMESTAMP:
09434
#endif
09435
case SQL_TIMESTAMP:
09436 s->
rows[offs + 2] =
"32";
09437 quote =
"'";
09438 sign = NULL;
09439
break;
09440
#if HAVE_ENCDEC
09441
case SQL_VARBINARY:
09442 sign = NULL;
09443 s->
rows[offs + 2] =
"255";
09444
break;
09445
case SQL_LONGVARBINARY:
09446 sign = NULL;
09447 s->
rows[offs + 2] =
"65536";
09448
break;
09449
#endif
09450
}
09451 s->
rows[offs + 3] = s->
rows[offs + 4] = quote;
09452 s->
rows[offs + 5] = crpar;
09453 s->
rows[offs + 6] =
stringify(SQL_NULLABLE);
09454 s->
rows[offs + 7] =
stringify(SQL_FALSE);
09455 s->
rows[offs + 8] =
stringify(SQL_SEARCHABLE);
09456 s->
rows[offs + 9] = sign;
09457 s->
rows[offs + 10] =
stringify(SQL_FALSE);
09458 s->
rows[offs + 11] =
stringify(SQL_FALSE);
09459 s->
rows[offs + 12] =
typename;
09460 s->
rows[offs + 13] = NULL;
09461 s->
rows[offs + 14] = NULL;
09462 }
09463
09472
static int
09473 typeinfosort(
const void *a,
const void *b)
09474 {
09475
char **pa = (
char **) a;
09476
char **pb = (
char **) b;
09477
int na, nb;
09478
09479 na = strtol(pa[1], NULL, 0);
09480 nb = strtol(pb[1], NULL, 0);
09481
return na - nb;
09482 }
09483
09491
static SQLRETURN
09492 drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
09493 {
09494 SQLRETURN ret;
09495
STMT *s;
09496
DBC *d;
09497
09498 ret =
mkresultset(stmt,
typeSpec,
array_size(
typeSpec));
09499
if (ret != SQL_SUCCESS) {
09500
return ret;
09501 }
09502 s = (
STMT *) stmt;
09503 d = (
DBC *) s->
dbc;
09504
#ifdef SQLITE_UTF8
09505
#ifdef SQL_LONGVARCHAR
09506
#ifdef SQL_WLONGVARCHAR
09507
if (s->
nowchar) {
09508 s->
nrows = sqltype == SQL_ALL_TYPES ? 13 : 1;
09509 }
else {
09510 s->
nrows = sqltype == SQL_ALL_TYPES ? 17 : 1;
09511 }
09512
#else
09513
if (s->
nowchar) {
09514 s->
nrows = sqltype == SQL_ALL_TYPES ? 12 : 1;
09515 }
else {
09516 s->
nrows = sqltype == SQL_ALL_TYPES ? 16 : 1;
09517 }
09518
#endif
09519
#else
09520
s->
nrows = sqltype == SQL_ALL_TYPES ? 15 : 1;
09521
#endif
09522
#else
09523
#ifdef SQL_LONGVARCHAR
09524
s->
nrows = sqltype == SQL_ALL_TYPES ? 13 : 1;
09525
#else
09526
s->
nrows = sqltype == SQL_ALL_TYPES ? 12 : 1;
09527
#endif
09528
#endif
09529
#if HAVE_ENCDEC
09530
if (sqltype == SQL_ALL_TYPES) {
09531 s->
nrows += 2;
09532 }
09533
#endif
09534
s->
rows = (
char **)
xmalloc(
sizeof (
char *) * (s->
nrows + 1)
09535 *
array_size(
typeSpec));
09536
if (!s->
rows) {
09537 s->
nrows = 0;
09538
return nomem(s);
09539 }
09540
#ifdef MEMORY_DEBUG
09541
s->
rowfree = xfree__;
09542
#else
09543
s->
rowfree = free;
09544
#endif
09545
memset(s->
rows, 0,
09546 sizeof (
char *) * (s->
nrows + 1) *
array_size(
typeSpec));
09547
if (sqltype == SQL_ALL_TYPES) {
09548
int cc = 1;
09549
09550
mktypeinfo(s, cc++,
"varchar", SQL_VARCHAR, 0);
09551
mktypeinfo(s, cc++,
"tinyint", SQL_TINYINT, 0);
09552
mktypeinfo(s, cc++,
"smallint", SQL_SMALLINT, 0);
09553
mktypeinfo(s, cc++,
"integer", SQL_INTEGER, 0);
09554
mktypeinfo(s, cc++,
"float", SQL_FLOAT, 0);
09555
mktypeinfo(s, cc++,
"double", SQL_DOUBLE, 0);
09556
#ifdef SQL_TYPE_DATE
09557
mktypeinfo(s, cc++,
"date", (*s->
ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
09558
#else
09559
mktypeinfo(s, cc++,
"date", SQL_DATE, 0);
09560
#endif
09561
#ifdef SQL_TYPE_TIME
09562
mktypeinfo(s, cc++,
"time", (*s->
ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
09563
#else
09564
mktypeinfo(s, cc++,
"time", SQL_TIME, 0);
09565
#endif
09566
#ifdef SQL_TYPE_TIMESTAMP
09567
mktypeinfo(s, cc++,
"timestamp",
09568 (*s->
ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
09569
#else
09570
mktypeinfo(s, cc++,
"timestamp", SQL_TIMESTAMP, 0);
09571
#endif
09572
mktypeinfo(s, cc++,
"char", SQL_CHAR, 0);
09573
mktypeinfo(s, cc++,
"numeric", SQL_DOUBLE, 0);
09574
#ifdef SQL_LONGVARCHAR
09575
mktypeinfo(s, cc++,
"text", SQL_LONGVARCHAR, 0);
09576
mktypeinfo(s, cc++,
"longvarchar", SQL_LONGVARCHAR, 0);
09577
#else
09578
mktypeinfo(s, cc++,
"text", SQL_VARCHAR, 0);
09579
#endif
09580
#ifdef SQLITE_UTF8
09581
if (!s->
nowchar) {
09582
mktypeinfo(s, cc++,
"wvarchar", SQL_WVARCHAR, 0);
09583
#ifdef SQL_LONGVARCHAR
09584
mktypeinfo(s, cc++,
"wchar", SQL_WCHAR, 0);
09585
mktypeinfo(s, cc++,
"wtext", SQL_WLONGVARCHAR, 0);
09586
#ifdef SQL_WLONGVARCHAR
09587
mktypeinfo(s, cc++,
"longwvarchar", SQL_WLONGVARCHAR, 0);
09588
#endif
09589
#else
09590
mktypeinfo(s, cc++,
"wvarchar", SQL_WVARCHAR, 0);
09591
mktypeinfo(s, cc++,
"wchar", SQL_WCHAR, 0);
09592
mktypeinfo(s, cc++,
"wtext", SQL_WVARCHAR, 0);
09593
#endif
09594
}
09595
#endif
09596
#if HAVE_ENCDEC
09597
mktypeinfo(s, cc++,
"varbinary", SQL_VARBINARY, 0);
09598
mktypeinfo(s, cc++,
"longvarbinary", SQL_LONGVARBINARY, 0);
09599
#endif
09600
qsort(s->
rows +
array_size(
typeSpec), s->
nrows,
09601 sizeof (
char *) *
array_size(
typeSpec),
typeinfosort);
09602 }
else {
09603
switch (sqltype) {
09604
case SQL_CHAR:
09605
mktypeinfo(s, 1,
"char", SQL_CHAR, 10);
09606
break;
09607
case SQL_VARCHAR:
09608
mktypeinfo(s, 1,
"varchar", SQL_VARCHAR, 1);
09609
break;
09610
case SQL_TINYINT:
09611
mktypeinfo(s, 1,
"tinyint", SQL_TINYINT, 2);
09612
break;
09613
case SQL_SMALLINT:
09614
mktypeinfo(s, 1,
"smallint", SQL_SMALLINT, 3);
09615
break;
09616
case SQL_INTEGER:
09617
mktypeinfo(s, 1,
"integer", SQL_INTEGER, 4);
09618
break;
09619
case SQL_FLOAT:
09620
mktypeinfo(s, 1,
"float", SQL_FLOAT, 5);
09621
break;
09622
case SQL_DOUBLE:
09623
mktypeinfo(s, 1,
"double", SQL_DOUBLE, 6);
09624
break;
09625
#ifdef SQL_TYPE_DATE
09626
case SQL_TYPE_DATE:
09627
mktypeinfo(s, 1,
"date", SQL_TYPE_DATE, 25);
09628
break;
09629
#endif
09630
case SQL_DATE:
09631
mktypeinfo(s, 1,
"date", SQL_DATE, 7);
09632
break;
09633
#ifdef SQL_TYPE_TIME
09634
case SQL_TYPE_TIME:
09635
mktypeinfo(s, 1,
"date", SQL_TYPE_TIME, 26);
09636
break;
09637
#endif
09638
case SQL_TIME:
09639
mktypeinfo(s, 1,
"time", SQL_TIME, 8);
09640
break;
09641
#ifdef SQL_TYPE_TIMESTAMP
09642
case SQL_TYPE_TIMESTAMP:
09643
mktypeinfo(s, 1,
"date", SQL_TYPE_TIMESTAMP, 27);
09644
break;
09645
#endif
09646
case SQL_TIMESTAMP:
09647
mktypeinfo(s, 1,
"timestamp", SQL_TIMESTAMP, 9);
09648
break;
09649
#ifdef SQL_LONGVARCHAR
09650
case SQL_LONGVARCHAR:
09651
mktypeinfo(s, 1,
"longvarchar", SQL_LONGVARCHAR, 12);
09652
break;
09653
#endif
09654
#ifdef SQLITE_UTF8
09655
#ifdef SQL_WCHAR
09656
case SQL_WCHAR:
09657
mktypeinfo(s, 1,
"wchar", SQL_WCHAR, 18);
09658
break;
09659
#endif
09660
#ifdef SQL_WVARCHAR
09661
case SQL_WVARCHAR:
09662
mktypeinfo(s, 1,
"wvarchar", SQL_WVARCHAR, 19);
09663
break;
09664
#endif
09665
#ifdef SQL_WLONGVARCHAR
09666
case SQL_WLONGVARCHAR:
09667
mktypeinfo(s, 1,
"longwvarchar", SQL_WLONGVARCHAR, 20);
09668
break;
09669
#endif
09670
#endif
09671
#if HAVE_ENCDEC
09672
case SQL_VARBINARY:
09673
mktypeinfo(s, 1,
"varbinary", SQL_VARBINARY, 30);
09674
break;
09675
case SQL_LONGVARBINARY:
09676
mktypeinfo(s, 1,
"longvarbinary", SQL_LONGVARBINARY, 31);
09677
break;
09678
#endif
09679
default:
09680 s->
nrows = 0;
09681
return SQL_NO_DATA;
09682 }
09683 }
09684
return SQL_SUCCESS;
09685 }
09686
09687
#ifndef SQLITE_UTF8
09688
09695 SQLRETURN SQL_API
09696 SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
09697 {
09698
return drvgettypeinfo(stmt, sqltype);
09699 }
09700
#endif
09701
09702
#ifdef SQLITE_UTF8
09703
09710 SQLRETURN SQL_API
09711 SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
09712 {
09713
return drvgettypeinfo(stmt, sqltype);
09714 }
09715
#endif
09716
09721 static COL statSpec[] = {
09722 {
"SYSTEM",
"STATISTICS",
"TABLE_QUALIFIER",
SCOL_VARCHAR, 50 },
09723 {
"SYSTEM",
"STATISTICS",
"TABLE_OWNER",
SCOL_VARCHAR, 50 },
09724 {
"SYSTEM",
"STATISTICS",
"TABLE_NAME",
SCOL_VARCHAR, 255 },
09725 {
"SYSTEM",
"STATISTICS",
"NON_UNIQUE", SQL_SMALLINT, 50 },
09726 {
"SYSTEM",
"STATISTICS",
"INDEX_QUALIFIER",
SCOL_VARCHAR, 255 },
09727 {
"SYSTEM",
"STATISTICS",
"INDEX_NAME",
SCOL_VARCHAR, 255 },
09728 {
"SYSTEM",
"STATISTICS",
"TYPE", SQL_SMALLINT, 50 },
09729 {
"SYSTEM",
"STATISTICS",
"ORDINAL_POSITION", SQL_SMALLINT, 50 },
09730 {
"SYSTEM",
"STATISTICS",
"COLUMN_NAME",
SCOL_VARCHAR, 255 },
09731 {
"SYSTEM",
"STATISTICS",
"ASC_OR_DESC",
SCOL_CHAR, 1 },
09732 {
"SYSTEM",
"STATISTICS",
"CARDINALITY", SQL_INTEGER, 50 },
09733 {
"SYSTEM",
"STATISTICS",
"PAGES", SQL_INTEGER, 50 },
09734 {
"SYSTEM",
"STATISTICS",
"FILTER_CONDITION",
SCOL_VARCHAR, 255 }
09735 };
09736
09751
static SQLRETURN
09752 drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
09753 SQLCHAR *schema, SQLSMALLINT schemaLen,
09754 SQLCHAR *table, SQLSMALLINT tableLen,
09755 SQLUSMALLINT itype, SQLUSMALLINT resv)
09756 {
09757 SQLRETURN sret;
09758
STMT *s;
09759
DBC *d;
09760
int i, size, ret, nrows, ncols, offs, namec, uniquec;
09761
char **rowp, *errp = NULL, tname[512];
09762
09763 sret =
mkresultset(stmt,
statSpec,
array_size(
statSpec));
09764
if (sret != SQL_SUCCESS) {
09765
return sret;
09766 }
09767 s = (
STMT *) stmt;
09768 d = (
DBC *) s->
dbc;
09769
if (!table || table[0] ==
'\0' || table[0] ==
'%') {
09770
setstat(s, -1,
"need table name", (*s->
ov3) ?
"HY000" :
"S1000");
09771
return SQL_ERROR;
09772 }
09773
if (tableLen == SQL_NTS) {
09774 size =
sizeof (tname) - 1;
09775 }
else {
09776 size =
min(
sizeof (tname) - 1, tableLen);
09777 }
09778 strncpy(tname, table, size);
09779 tname[size] =
'\0';
09780 ret = sqlite_get_table_printf(d->
sqlite,
09781
"PRAGMA index_list('%q')", &rowp,
09782 &nrows, &ncols, &errp, tname);
09783
if (ret != SQLITE_OK) {
09784
setstat(s, ret,
"%s (%d)", (*s->
ov3) ?
"HY000" :
"S1000",
09785 errp ? errp :
"unknown error", ret);
09786
if (errp) {
09787 sqlite_freemem(errp);
09788 errp = NULL;
09789 }
09790
return SQL_ERROR;
09791 }
09792
if (errp) {
09793 sqlite_freemem(errp);
09794 errp = NULL;
09795 }
09796
if (ncols * nrows <= 0) {
09797 nodata:
09798 sqlite_free_table(rowp);
09799
09800
if (itype == SQL_INDEX_UNIQUE) {
09801 ret = sqlite_get_table_printf(d->
sqlite,
09802
"PRAGMA table_info('%q')", &rowp,
09803 &nrows, &ncols, NULL, tname);
09804
if (ret == SQLITE_OK) {
09805
int colid, typec, roffs;
09806
09807 namec =
findcol(rowp, ncols,
"name");
09808 uniquec =
findcol(rowp, ncols,
"pk");
09809 typec =
findcol(rowp, ncols,
"type");
09810 colid =
findcol(rowp, ncols,
"cid");
09811
if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
09812
goto nodata2;
09813 }
09814
for (i = 1; i <= nrows; i++) {
09815
if (*rowp[i * ncols + uniquec] !=
'0' &&
09816 strlen(rowp[i * ncols + typec]) == 7 &&
09817 strncasecmp(rowp[i * ncols + typec],
"integer", 7)
09818 == 0) {
09819
break;
09820 }
09821 }
09822
if (i > nrows) {
09823
goto nodata2;
09824 }
09825 size = (1 + 1) *
array_size(
statSpec);
09826 s->
rows =
xmalloc((size + 1) *
sizeof (
char *));
09827
if (!s->
rows) {
09828 s->
nrows = 0;
09829
return nomem(s);
09830 }
09831 s->
rows[0] = (
char *) size;
09832 s->
rows += 1;
09833 memset(s->
rows, 0, sizeof (
char *) * size);
09834 s->
rowfree =
freerows;
09835 s->
nrows = 1;
09836 roffs = s->
ncols;
09837 s->
rows[roffs + 0] =
xstrdup(
"");
09838 s->
rows[roffs + 1] =
xstrdup(
"");
09839 s->
rows[roffs + 2] =
xstrdup(tname);
09840 s->
rows[roffs + 3] =
xstrdup(
stringify(SQL_FALSE));
09841 s->
rows[roffs + 4] =
xstrdup(
"");
09842 s->
rows[roffs + 5] =
xstrdup(
"");
09843 s->
rows[roffs + 6] =
xstrdup(
stringify(SQL_INDEX_OTHER));
09844 s->
rows[roffs + 7] =
xstrdup(
"1");
09845 s->
rows[roffs + 8] =
xstrdup(rowp[i * ncols + namec]);
09846 s->
rows[roffs + 9] =
xstrdup(
"A");
09847 nodata2:
09848 sqlite_free_table(rowp);
09849 }
09850 }
09851
return SQL_SUCCESS;
09852 }
09853 size = 0;
09854 namec =
findcol(rowp, ncols,
"name");
09855 uniquec =
findcol(rowp, ncols,
"unique");
09856
if (namec < 0 || uniquec < 0) {
09857
goto nodata;
09858 }
09859
for (i = 1; i <= nrows; i++) {
09860
int nnrows, nncols;
09861
char **rowpp;
09862
int isuniq;
09863
09864 isuniq = *rowp[i * ncols + uniquec] !=
'0';
09865
if (isuniq || itype == SQL_INDEX_ALL) {
09866 ret = sqlite_get_table_printf(d->
sqlite,
09867
"PRAGMA index_info('%q')", &rowpp,
09868 &nnrows, &nncols, NULL,
09869 rowp[i * ncols + namec]);
09870
if (ret == SQLITE_OK) {
09871 size += nnrows;
09872 sqlite_free_table(rowpp);
09873 }
09874 }
09875 }
09876
if (size == 0) {
09877
goto nodata;
09878 }
09879 s->
nrows = size;
09880 size = (size + 1) *
array_size(
statSpec);
09881 s->
rows =
xmalloc((size + 1) *
sizeof (
char *));
09882
if (!s->
rows) {
09883 s->
nrows = 0;
09884
return nomem(s);
09885 }
09886 s->
rows[0] = (
char *) size;
09887 s->
rows += 1;
09888 memset(s->
rows, 0, sizeof (
char *) * size);
09889 s->
rowfree =
freerows;
09890 offs = 0;
09891
for (i = 1; i <= nrows; i++) {
09892
int nnrows, nncols;
09893
char **rowpp;
09894
09895
if (*rowp[i * ncols + uniquec] !=
'0' || itype == SQL_INDEX_ALL) {
09896
int k;
09897
09898 ret = sqlite_get_table_printf(d->
sqlite,
09899
"PRAGMA index_info('%q')", &rowpp,
09900 &nnrows, &nncols, NULL,
09901 rowp[i * ncols + namec]);
09902
if (ret != SQLITE_OK) {
09903
continue;
09904 }
09905
for (k = 0; nnrows && k < nncols; k++) {
09906
if (strcmp(rowpp[k],
"name") == 0) {
09907
int m;
09908
09909
for (m = 1; m <= nnrows; m++) {
09910
int roffs = (offs + m) * s->
ncols;
09911
int isuniq;
09912
09913 isuniq = *rowp[i * ncols + uniquec] !=
'0';
09914 s->
rows[roffs + 0] =
xstrdup(
"");
09915 s->
rows[roffs + 1] =
xstrdup(
"");
09916 s->
rows[roffs + 2] =
xstrdup(tname);
09917
if (isuniq) {
09918 s->
rows[roffs + 3] =
xstrdup(
stringify(SQL_FALSE));
09919 }
else {
09920 s->
rows[roffs + 3] =
xstrdup(
stringify(SQL_TRUE));
09921 }
09922 s->
rows[roffs + 4] =
xstrdup(
"");
09923 s->
rows[roffs + 5] =
xstrdup(rowp[i * ncols + namec]);
09924 s->
rows[roffs + 6] =
09925
xstrdup(
stringify(SQL_INDEX_OTHER));
09926 s->
rows[roffs + 8] =
xstrdup(rowpp[m * nncols + k]);
09927 s->
rows[roffs + 9] =
xstrdup(
"A");
09928 }
09929 }
else if (strcmp(rowpp[k],
"seqno") == 0) {
09930
int m;
09931
09932
for (m = 1; m <= nnrows; m++) {
09933
int roffs = (offs + m) * s->
ncols;
09934
int pos = m - 1;
09935
char buf[32];
09936
09937 sscanf(rowpp[m * nncols + k],
"%d", &pos);
09938 sprintf(buf,
"%d", pos + 1);
09939 s->
rows[roffs + 7] =
xstrdup(buf);
09940 }
09941 }
09942 }
09943 offs += nnrows;
09944 sqlite_free_table(rowpp);
09945 }
09946 }
09947 sqlite_free_table(rowp);
09948
return SQL_SUCCESS;
09949 }
09950
09951
#ifndef SQLITE_UTF8
09952
09966 SQLRETURN SQL_API
09967 SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
09968 SQLCHAR *schema, SQLSMALLINT schemaLen,
09969 SQLCHAR *table, SQLSMALLINT tableLen,
09970 SQLUSMALLINT itype, SQLUSMALLINT resv)
09971 {
09972
return drvstatistics(stmt, cat, catLen, schema, schemaLen,
09973 table, tableLen, itype, resv);
09974 }
09975
#endif
09976
09977
#ifdef SQLITE_UTF8
09978
09992 SQLRETURN SQL_API
09993 SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
09994 SQLWCHAR *schema, SQLSMALLINT schemaLen,
09995 SQLWCHAR *table, SQLSMALLINT tableLen,
09996 SQLUSMALLINT itype, SQLUSMALLINT resv)
09997 {
09998
char *c = NULL, *s = NULL, *t = NULL;
09999 SQLRETURN ret;
10000
10001
if (cat) {
10002 c = uc_to_utf_c(cat, catLen);
10003
if (!c) {
10004 ret =
nomem((
STMT *) stmt);
10005
goto done;
10006 }
10007 }
10008
if (schema) {
10009 s = uc_to_utf_c(schema, schemaLen);
10010
if (!s) {
10011 ret =
nomem((
STMT *) stmt);
10012
goto done;
10013 }
10014 }
10015
if (table) {
10016 t = uc_to_utf_c(table, tableLen);
10017
if (!t) {
10018 ret =
nomem((
STMT *) stmt);
10019
goto done;
10020 }
10021 }
10022 ret =
drvstatistics(stmt, c, SQL_NTS, s, SQL_NTS, t, SQL_NTS,
10023 itype, resv);
10024 done:
10025 uc_free(t);
10026 uc_free(s);
10027 uc_free(c);
10028
return ret;
10029 }
10030
#endif
10031
10043 SQLRETURN SQL_API
10044 SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
10045 SQLPOINTER val, SQLINTEGER len, SQLINTEGER *lenp)
10046 {
10047
STMT *s;
10048
10049
if (stmt == SQL_NULL_HSTMT) {
10050
return SQL_INVALID_HANDLE;
10051 }
10052 s = (
STMT *) stmt;
10053
if (col == 0 && s->
bkmrk && type == SQL_C_BOOKMARK) {
10054 *((
long *) val) = s->
rowp;
10055
if (lenp) {
10056 *lenp =
sizeof (
long);
10057 }
10058
return SQL_SUCCESS;
10059 }
10060
if (col < 1 || col > s->
ncols) {
10061
setstat(s, -1,
"invalid column", (*s->
ov3) ?
"07009" :
"S1002");
10062
return SQL_ERROR;
10063 }
10064 --col;
10065
return getrowdata(s, col, type, val, len, lenp, 1);
10066 }
10067
10075
static SQLRETURN
10076 dofetchbind(
STMT *s,
int rsi)
10077 {
10078
int ret, i, withinfo = 0;
10079
10080 s->
row_status0[rsi] = SQL_ROW_SUCCESS;
10081
if (s->
bkmrk && s->
bkmrkcol.
valp) {
10082
long *val;
10083
10084
if (s->
bind_type != SQL_BIND_BY_COLUMN) {
10085 val = (
long *) ((
char *) s->
bkmrkcol.
valp + s->
bind_type * rsi);
10086 }
else {
10087 val = (
long *) s->
bkmrkcol.
valp + rsi;
10088 }
10089 *val = s->
rowp;
10090
if (s->
bkmrkcol.
lenp) {
10091
if (s->
bind_type != SQL_BIND_BY_COLUMN) {
10092 SQLINTEGER *ival = (SQLINTEGER *)
10093 ((
char *) s->
bkmrkcol.
lenp + s->
bind_type * rsi);
10094 *ival =
sizeof (
long);
10095 }
else {
10096 s->
bkmrkcol.
lenp[rsi] =
sizeof (
long);
10097 }
10098 }
10099 }
10100 ret = SQL_SUCCESS;
10101
for (i = 0; s->
bindcols && i < s->
ncols; i++) {
10102
BINDCOL *b = &s->
bindcols[i];
10103 SQLPOINTER dp = 0;
10104 SQLINTEGER *lp = 0;
10105
10106 b->
offs = 0;
10107
if (b->
valp) {
10108
if (s->
bind_type != SQL_BIND_BY_COLUMN) {
10109 dp = (SQLPOINTER) ((
char *) b->
valp + s->
bind_type * rsi);
10110 }
else {
10111 dp = (SQLPOINTER) ((
char *) b->
valp + b->
max * rsi);
10112 }
10113 }
10114
if (b->
lenp) {
10115
if (s->
bind_type != SQL_BIND_BY_COLUMN) {
10116 lp = (SQLINTEGER *) ((
char *) b->
lenp + s->
bind_type * rsi);
10117 }
else {
10118 lp = b->
lenp + rsi;
10119 }
10120 }
10121
if (dp || lp) {
10122 ret =
getrowdata(s, (SQLUSMALLINT) i, b->
type, dp, b->
max, lp, 0);
10123
if (!SQL_SUCCEEDED(ret)) {
10124 s->
row_status0[rsi] = SQL_ROW_ERROR;
10125
break;
10126 }
10127
if (ret != SQL_SUCCESS) {
10128 withinfo = 1;
10129
#ifdef SQL_ROW_SUCCESS_WITH_INFO
10130
s->
row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
10131
#endif
10132
}
10133 }
10134 }
10135
if (SQL_SUCCEEDED(ret)) {
10136 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10137 }
10138
return ret;
10139 }
10140
10147 SQLRETURN SQL_API
10148 SQLFetch(SQLHSTMT stmt)
10149 {
10150
STMT *s;
10151
int i, withinfo = 0;
10152 SQLRETURN ret;
10153
10154
if (stmt == SQL_NULL_HSTMT) {
10155
return SQL_INVALID_HANDLE;
10156 }
10157 s = (
STMT *) stmt;
10158
for (i = 0; i < s->
rowset_size; i++) {
10159 s->
row_status0[i] = SQL_ROW_NOROW;
10160 }
10161
if (s->
row_status) {
10162 memcpy(s->
row_status, s->
row_status0,
10163 sizeof (SQLUSMALLINT) * s->
rowset_size);
10164 }
10165 s->
row_count0 = 0;
10166
if (s->
row_count) {
10167 *s->
row_count = s->
row_count0;
10168 }
10169
if (!s->
bindcols) {
10170
for (i = 0; i < s->
rowset_size; i++) {
10171 s->
row_status0[i] = SQL_ROW_ERROR;
10172 }
10173
return SQL_ERROR;
10174 }
10175 ret = SQL_SUCCESS;
10176 i = 0;
10177
if (((
DBC *) (s->
dbc))->vm_stmt == s && s->
vm) {
10178 s->
rowp = 0;
10179
for (; i < s->
rowset_size; i++) {
10180 ret =
vm_step(s);
10181
if (ret != SQL_SUCCESS) {
10182 s->
row_status0[i] = SQL_ROW_ERROR;
10183
break;
10184 }
10185
if (s->
nrows < 1) {
10186
break;
10187 }
10188 ret =
dofetchbind(s, i);
10189
if (!SQL_SUCCEEDED(ret)) {
10190
break;
10191 }
else if (ret == SQL_SUCCESS_WITH_INFO) {
10192 withinfo = 1;
10193 }
10194 }
10195 }
else if (s->
rows && s->
nrows > 0) {
10196
for (; i < s->
rowset_size; i++) {
10197 ++s->
rowp;
10198
if (s->
rowp < 0 || s->
rowp >= s->
nrows) {
10199
break;
10200 }
10201 ret =
dofetchbind(s, i);
10202
if (!SQL_SUCCEEDED(ret)) {
10203
break;
10204 }
else if (ret == SQL_SUCCESS_WITH_INFO) {
10205 withinfo = 1;
10206 }
10207 }
10208 }
10209
if (i == 0) {
10210
if (SQL_SUCCEEDED(ret)) {
10211
return SQL_NO_DATA;
10212 }
10213
return ret;
10214 }
10215
if (SQL_SUCCEEDED(ret)) {
10216 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10217 }
10218
if (s->
row_status) {
10219 memcpy(s->
row_status, s->
row_status0,
10220 sizeof (SQLUSMALLINT) * s->
rowset_size);
10221 }
10222 s->
row_count0 = i;
10223
if (s->
row_count) {
10224 *s->
row_count = s->
row_count0;
10225 }
10226
return ret;
10227 }
10228
10237
static SQLRETURN
10238 drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
10239 {
10240
STMT *s;
10241
int i, withinfo = 0;
10242 SQLRETURN ret;
10243
10244
if (stmt == SQL_NULL_HSTMT) {
10245
return SQL_INVALID_HANDLE;
10246 }
10247 s = (
STMT *) stmt;
10248
for (i = 0; i < s->
rowset_size; i++) {
10249 s->
row_status0[i] = SQL_ROW_NOROW;
10250 }
10251
if (s->
row_status) {
10252 memcpy(s->
row_status, s->
row_status0,
10253 sizeof (SQLUSMALLINT) * s->
rowset_size);
10254 }
10255 s->
row_count0 = 0;
10256
if (s->
row_count) {
10257 *s->
row_count = s->
row_count0;
10258 }
10259
if (!s->
bindcols) {
10260
for (i = 0; i < s->
rowset_size; i++) {
10261 s->
row_status0[i] = SQL_ROW_ERROR;
10262 }
10263 ret = SQL_ERROR;
10264
goto done;
10265 }
10266
if (s->
curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
10267
setstat(s, -1,
"wrong fetch direction",
"01000");
10268
return SQL_ERROR;
10269 }
10270 ret = SQL_SUCCESS;
10271 i = 0;
10272
if (((
DBC *) (s->
dbc))->vm_stmt == s && s->
vm) {
10273 s->
rowp = 0;
10274
for (; i < s->
rowset_size; i++) {
10275 ret =
vm_step(s);
10276
if (ret != SQL_SUCCESS) {
10277 s->
row_status0[i] = SQL_ROW_ERROR;
10278
break;
10279 }
10280
if (s->
nrows < 1) {
10281
break;
10282 }
10283 ret =
dofetchbind(s, i);
10284
if (!SQL_SUCCEEDED(ret)) {
10285
break;
10286 }
else if (ret == SQL_SUCCESS_WITH_INFO) {
10287 withinfo = 1;
10288 }
10289 }
10290 }
else if (s->
rows) {
10291
switch (orient) {
10292
case SQL_FETCH_NEXT:
10293
if (s->
nrows < 1) {
10294
return SQL_NO_DATA;
10295 }
10296
if (s->
rowp < 0) {
10297 s->
rowp = -1;
10298 }
else {
10299 s->
rowp += s->
rowset_size - 1;
10300 }
10301
if (s->
rowp >= s->
nrows) {
10302 s->
rowp = s->
nrows;
10303
return SQL_NO_DATA;
10304 }
10305
break;
10306
case SQL_FETCH_PRIOR:
10307
if (s->
nrows < 1) {
10308 s->
rowp = -1;
10309
return SQL_NO_DATA;
10310 }
10311 s->
rowp -= s->
rowset_size + 1;
10312
if (s->
rowp < 0) {
10313 s->
rowp = -1;
10314
return SQL_NO_DATA;
10315 }
10316
break;
10317
case SQL_FETCH_FIRST:
10318
if (s->
nrows < 1) {
10319
return SQL_NO_DATA;
10320 }
10321 s->
rowp = -1;
10322
break;
10323
case SQL_FETCH_LAST:
10324
if (s->
nrows < 1) {
10325
return SQL_NO_DATA;
10326 }
10327 s->
rowp = s->
nrows - s->
rowset_size - 1;
10328
if (--s->
rowp < -1) {
10329 s->
rowp = -1;
10330 }
10331
break;
10332
case SQL_FETCH_ABSOLUTE:
10333
if (offset == 0) {
10334 s->
rowp = -1;
10335
return SQL_NO_DATA;
10336 }
else if (offset < 0) {
10337
if (0 - offset <= s->
nrows) {
10338 s->
rowp = s->
nrows + offset + 1;
10339
break;
10340 }
10341 s->
rowp = 0;
10342
return SQL_NO_DATA;
10343 }
else if (offset > s->
nrows) {
10344 s->
rowp = s->
nrows;
10345
return SQL_NO_DATA;
10346 }
10347 s->
rowp = offset - 1;
10348
break;
10349
case SQL_FETCH_RELATIVE:
10350
if (offset >= 0) {
10351 s->
rowp += offset - 1;
10352
if (s->
rowp + offset > s->
nrows) {
10353 s->
rowp = s->
nrows;
10354
return SQL_NO_DATA;
10355 }
10356 }
else {
10357
if (s->
rowp + offset < 0) {
10358 s->
rowp = 0;
10359
return SQL_NO_DATA;
10360 }
10361 s->
rowp += offset - 1;
10362 }
10363
break;
10364
case SQL_FETCH_BOOKMARK:
10365
if (s->
bkmrk) {
10366
if (offset < 0 || offset >= s->
nrows) {
10367
return SQL_NO_DATA;
10368 }
10369 s->
rowp = offset - 1;
10370
break;
10371 }
10372
10373
default:
10374 s->
row_status0[0] = SQL_ROW_ERROR;
10375 ret = SQL_ERROR;
10376
goto done;
10377 }
10378
for (; i < s->
rowset_size; i++) {
10379 ++s->
rowp;
10380
if (s->
rowp < 0 || s->
rowp >= s->
nrows) {
10381
break;
10382 }
10383 ret =
dofetchbind(s, i);
10384
if (!SQL_SUCCEEDED(ret)) {
10385
break;
10386 }
else if (ret == SQL_SUCCESS_WITH_INFO) {
10387 withinfo = 1;
10388 }
10389 }
10390 }
10391 done:
10392
if (i == 0) {
10393
if (SQL_SUCCEEDED(ret)) {
10394
return SQL_NO_DATA;
10395 }
10396
return ret;
10397 }
10398
if (SQL_SUCCEEDED(ret)) {
10399 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10400 }
10401
if (s->
row_status) {
10402 memcpy(s->
row_status, s->
row_status0,
10403 sizeof (SQLUSMALLINT) * s->
rowset_size);
10404 }
10405 s->
row_count0 = i;
10406
if (s->
row_count) {
10407 *s->
row_count = s->
row_count0;
10408 }
10409
return ret;
10410 }
10411
10420 SQLRETURN SQL_API
10421 SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
10422 {
10423
return drvfetchscroll(stmt, orient, offset);
10424 }
10425
10436 SQLRETURN SQL_API
10437 SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLINTEGER offset,
10438 SQLUINTEGER *rowcount, SQLUSMALLINT *rowstatus)
10439 {
10440
STMT *s;
10441 SQLRETURN ret;
10442 SQLUSMALLINT *rst;
10443
10444
if (stmt == SQL_NULL_HSTMT) {
10445
return SQL_INVALID_HANDLE;
10446 }
10447 s = (
STMT *) stmt;
10448
10449 rst = s->
row_status;
10450 s->
row_status = 0;
10451 ret =
drvfetchscroll(stmt, orient, offset);
10452 s->
row_status = rst;
10453
if (rowstatus) {
10454 memcpy(rowstatus, s->
row_status0,
10455 sizeof (SQLUSMALLINT) * s->
rowset_size);
10456 }
10457
if (rowcount) {
10458 *rowcount = s->
row_count0;
10459 }
10460
return ret;
10461 }
10462
10470 SQLRETURN SQL_API
10471 SQLRowCount(SQLHSTMT stmt, SQLINTEGER *nrows)
10472 {
10473
STMT *s;
10474
10475
if (stmt == SQL_NULL_HSTMT) {
10476
return SQL_INVALID_HANDLE;
10477 }
10478 s = (
STMT *) stmt;
10479
if (nrows) {
10480 *nrows = s->
nrows;
10481 }
10482
return SQL_SUCCESS;
10483 }
10484
10492 SQLRETURN SQL_API
10493 SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
10494 {
10495
STMT *s;
10496
10497
if (stmt == SQL_NULL_HSTMT) {
10498
return SQL_INVALID_HANDLE;
10499 }
10500 s = (
STMT *) stmt;
10501
if (ncols) {
10502 *ncols = s->
ncols;
10503 }
10504
return SQL_SUCCESS;
10505 }
10506
10521
static SQLRETURN
10522 drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
10523 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
10524 SQLSMALLINT *type, SQLUINTEGER *size,
10525 SQLSMALLINT *digits, SQLSMALLINT *nullable)
10526 {
10527
STMT *s;
10528
COL *c;
10529
int didname = 0;
10530
10531
if (stmt == SQL_NULL_HSTMT) {
10532
return SQL_INVALID_HANDLE;
10533 }
10534 s = (
STMT *) stmt;
10535
if (!s->
cols) {
10536
setstat(s, -1,
"no columns", (*s->
ov3) ?
"07009" :
"S1002");
10537
return SQL_ERROR;
10538 }
10539
if (col < 1 || col > s->
ncols) {
10540
setstat(s, -1,
"invalid column", (*s->
ov3) ?
"07009" :
"S1002");
10541
return SQL_ERROR;
10542 }
10543 c = s->
cols + col - 1;
10544
if (name && nameMax > 0) {
10545 strncpy(name, c->
column, nameMax);
10546 name[nameMax - 1] =
'\0';
10547 didname = 1;
10548 }
10549
if (nameLen) {
10550
if (didname) {
10551 *nameLen = strlen(name);
10552 }
else {
10553 *nameLen = strlen(c->
column);
10554 }
10555 }
10556
if (type) {
10557 *type = c->
type;
10558
#ifdef SQLITE_UTF8
10559
if (s->
nowchar) {
10560
switch (c->
type) {
10561
case SQL_WCHAR:
10562 *type = SQL_CHAR;
10563
break;
10564
case SQL_WVARCHAR:
10565 *type = SQL_VARCHAR;
10566
break;
10567
#ifdef SQL_LONGVARCHAR
10568
case SQL_WLONGVARCHAR:
10569 *type = SQL_LONGVARCHAR;
10570
break;
10571
#endif
10572
}
10573 }
10574
#endif
10575
}
10576
if (size) {
10577 *size = c->
size;
10578 }
10579
if (digits) {
10580 *digits = 0;
10581 }
10582
if (nullable) {
10583 *nullable = 1;
10584 }
10585
return SQL_SUCCESS;
10586 }
10587
10588
#ifndef SQLITE_UTF8
10589
10603 SQLRETURN SQL_API
10604 SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
10605 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
10606 SQLSMALLINT *type, SQLUINTEGER *size,
10607 SQLSMALLINT *digits, SQLSMALLINT *nullable)
10608 {
10609
return drvdescribecol(stmt, col, name, nameMax, nameLen,
10610 type, size, digits, nullable);
10611 }
10612
#endif
10613
10614
#ifdef SQLITE_UTF8
10615
10629 SQLRETURN SQL_API
10630 SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
10631 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
10632 SQLSMALLINT *type, SQLUINTEGER *size,
10633 SQLSMALLINT *digits, SQLSMALLINT *nullable)
10634 {
10635 SQLRETURN ret;
10636 SQLSMALLINT len;
10637
10638 ret =
drvdescribecol(stmt, col, (
char *) name, nameMax, &len,
10639 type, size, digits, nullable);
10640
if (ret == SQL_SUCCESS) {
10641
if (name) {
10642
if (len > 0) {
10643 SQLWCHAR *n = NULL;
10644
10645 n = uc_from_utf((
char *) name, len);
10646
if (n) {
10647 uc_strncpy(name, n, nameMax);
10648 len =
min(nameMax, uc_strlen(n));
10649 uc_free(n);
10650 }
else {
10651 len = 0;
10652 }
10653 }
10654
if (len <= 0) {
10655 len = 0;
10656
if (nameMax > 0) {
10657 name[0] = 0;
10658 }
10659 }
10660 }
else {
10661 len = 0;
10662 }
10663
if (nameLen) {
10664 *nameLen = len;
10665 }
10666 }
10667
return ret;
10668 }
10669
#endif
10670
10683
static SQLRETURN
10684 drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT
id,
10685 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
10686 SQLINTEGER *val2)
10687 {
10688
STMT *s;
10689
COL *c;
10690 SQLSMALLINT dummy;
10691
char *valc = (
char *) val;
10692
10693
if (stmt == SQL_NULL_HSTMT) {
10694
return SQL_INVALID_HANDLE;
10695 }
10696 s = (
STMT *) stmt;
10697
if (!s->
cols) {
10698
return SQL_ERROR;
10699 }
10700
if (!valLen) {
10701 valLen = &dummy;
10702 }
10703
if (
id == SQL_COLUMN_COUNT) {
10704
if (val2) {
10705 *val2 = s->
ncols;
10706 }
10707 *valLen =
sizeof (
int);
10708
return SQL_SUCCESS;
10709 }
10710
if (
id == SQL_COLUMN_TYPE && col == 0) {
10711
if (val2) {
10712 *val2 = SQL_INTEGER;
10713 }
10714 *valLen =
sizeof (
int);
10715
return SQL_SUCCESS;
10716 }
10717
#ifdef SQL_DESC_OCTET_LENGTH
10718
if (
id == SQL_DESC_OCTET_LENGTH && col == 0) {
10719
if (val2) {
10720 *val2 = 4;
10721 }
10722 *valLen =
sizeof (
int);
10723
return SQL_SUCCESS;
10724 }
10725
#endif
10726
if (col < 1 || col > s->
ncols) {
10727
setstat(s, -1,
"invalid column", (*s->
ov3) ?
"07009":
"S1002");
10728
return SQL_ERROR;
10729 }
10730 c = s->
cols + col - 1;
10731
10732
switch (
id) {
10733
case SQL_COLUMN_LABEL:
10734
if (c->
label) {
10735
if (valc && valMax > 0) {
10736 strncpy(valc, c->
label, valMax);
10737 valc[valMax - 1] =
'\0';
10738 }
10739
if (valLen) {
10740 *valLen = strlen(c->
label);
10741 }
10742
goto checkLen;
10743 }
10744
10745
case SQL_COLUMN_NAME:
10746
case SQL_DESC_NAME:
10747
if (valc && valMax > 0) {
10748 strncpy(valc, c->
column, valMax);
10749 valc[valMax - 1] =
'\0';
10750 }
10751 *valLen = strlen(c->
column);
10752 checkLen:
10753
if (*valLen >= valMax) {
10754
setstat(s, -1,
"data right truncated",
"01004");
10755
return SQL_SUCCESS_WITH_INFO;
10756 }
10757
return SQL_SUCCESS;
10758
case SQL_COLUMN_TYPE:
10759
case SQL_DESC_TYPE:
10760
#ifdef SQLITE_UTF8
10761
{
10762
int type = c->
type;
10763
10764
if (s->
nowchar) {
10765
switch (type) {
10766
case SQL_WCHAR:
10767 type = SQL_CHAR;
10768
break;
10769
case SQL_WVARCHAR:
10770 type = SQL_VARCHAR;
10771
break;
10772
#ifdef SQL_LONGVARCHAR
10773
case SQL_WLONGVARCHAR:
10774 type = SQL_LONGVARCHAR;
10775
break;
10776 }
10777 }
10778
if (val2) {
10779 *val2 = type;
10780 }
10781
#endif
10782
}
10783
#else
10784
if (val2) {
10785 *val2 = c->
type;
10786 }
10787
#endif
10788
*valLen =
sizeof (
int);
10789
return SQL_SUCCESS;
10790
case SQL_COLUMN_DISPLAY_SIZE:
10791
if (val2) {
10792 *val2 = c->
size;
10793 }
10794 *valLen =
sizeof (
int);
10795
return SQL_SUCCESS;
10796
case SQL_COLUMN_UNSIGNED:
10797
if (val2) {
10798 *val2 = c->
nosign ? SQL_TRUE : SQL_FALSE;
10799 }
10800 *valLen =
sizeof (
int);
10801
return SQL_SUCCESS;
10802
case SQL_COLUMN_SCALE:
10803
case SQL_DESC_SCALE:
10804
if (val2) {
10805 *val2 = c->
scale;
10806 }
10807 *valLen =
sizeof (
int);
10808
return SQL_SUCCESS;
10809
case SQL_COLUMN_PRECISION:
10810
case SQL_DESC_PRECISION:
10811
if (val2) {
10812 *val2 = c->
prec;
10813 }
10814 *valLen =
sizeof (
int);
10815
return SQL_SUCCESS;
10816
case SQL_COLUMN_MONEY:
10817
if (val2) {
10818 *val2 = SQL_FALSE;
10819 }
10820 *valLen =
sizeof (
int);
10821
return SQL_SUCCESS;
10822
case SQL_COLUMN_AUTO_INCREMENT:
10823
if (val2) {
10824 *val2 = c->
autoinc > 0 ? SQL_TRUE : SQL_FALSE;
10825 }
10826 *valLen =
sizeof (
int);
10827
return SQL_SUCCESS;
10828
case SQL_COLUMN_LENGTH:
10829
case SQL_DESC_LENGTH:
10830
if (val2) {
10831 *val2 = c->
size;
10832 }
10833 *valLen =
sizeof (
int);
10834
return SQL_SUCCESS;
10835
case SQL_COLUMN_NULLABLE:
10836
case SQL_DESC_NULLABLE:
10837
if (val2) {
10838 *val2 = SQL_NULLABLE;
10839 }
10840 *valLen =
sizeof (
int);
10841
return SQL_SUCCESS;
10842
case SQL_COLUMN_SEARCHABLE:
10843
if (val2) {
10844 *val2 = SQL_SEARCHABLE;
10845 }
10846 *valLen =
sizeof (
int);
10847
return SQL_SUCCESS;
10848
case SQL_COLUMN_CASE_SENSITIVE:
10849
if (val2) {
10850 *val2 = SQL_TRUE;
10851 }
10852 *valLen =
sizeof (
int);
10853
return SQL_SUCCESS;
10854
case SQL_COLUMN_UPDATABLE:
10855
if (val2) {
10856 *val2 = SQL_TRUE;
10857 }
10858 *valLen =
sizeof (
int);
10859
return SQL_SUCCESS;
10860
case SQL_COLUMN_TYPE_NAME: {
10861
char *tn = c->
typename ? c->
typename :
"varchar";
10862
10863
if (valc && valMax > 0) {
10864 strncpy(valc, tn, valMax);
10865 valc[valMax - 1] =
'\0';
10866 }
10867 *valLen = strlen(tn);
10868
goto checkLen;
10869 }
10870
case SQL_COLUMN_OWNER_NAME:
10871
case SQL_COLUMN_QUALIFIER_NAME: {
10872
char *z =
"";
10873
10874
if (valc && valMax > 0) {
10875 strncpy(valc, z, valMax);
10876 valc[valMax - 1] =
'\0';
10877 }
10878 *valLen = strlen(z);
10879
goto checkLen;
10880 }
10881
case SQL_COLUMN_TABLE_NAME:
10882
#if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
10883
case SQL_DESC_TABLE_NAME:
10884
#endif
10885
if (valc && valMax > 0) {
10886 strncpy(valc, c->
table, valMax);
10887 valc[valMax - 1] =
'\0';
10888 }
10889 *valLen = strlen(c->
table);
10890
goto checkLen;
10891 }
10892
setstat(s, -1,
"unsupported column attributes %d",
"HY091",
id);
10893
return SQL_ERROR;
10894 }
10895
10896
#ifndef SQLITE_UTF8
10897
10909 SQLRETURN SQL_API
10910 SQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT
id,
10911 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
10912 SQLINTEGER *val2)
10913 {
10914
return drvcolattributes(stmt, col,
id, val, valMax, valLen, val2);
10915 }
10916
#endif
10917
10918
#ifdef SQLITE_UTF8
10919
10931 SQLRETURN SQL_API
10932 SQLColAttributesW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT
id,
10933 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
10934 SQLINTEGER *val2)
10935 {
10936 SQLRETURN ret;
10937 SQLSMALLINT len;
10938
10939 ret =
drvcolattributes(stmt, col,
id, val, valMax, &len, val2);
10940
if (ret == SQL_SUCCESS) {
10941 SQLWCHAR *v = NULL;
10942
10943
switch (
id) {
10944
case SQL_COLUMN_LABEL:
10945
case SQL_COLUMN_NAME:
10946
case SQL_DESC_NAME:
10947
case SQL_COLUMN_TYPE_NAME:
10948
case SQL_COLUMN_OWNER_NAME:
10949
case SQL_COLUMN_QUALIFIER_NAME:
10950
case SQL_COLUMN_TABLE_NAME:
10951
#if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
10952
case SQL_DESC_TABLE_NAME:
10953
#endif
10954
if (val && valMax > 0) {
10955
int vmax = valMax /
sizeof (SQLWCHAR);
10956
10957 v = uc_from_utf((
char *) val, SQL_NTS);
10958
if (v) {
10959 uc_strncpy(val, v, vmax);
10960 uc_free(v);
10961 }
10962
if (vmax > 0) {
10963 v = (SQLWCHAR *) val;
10964 v[vmax - 1] =
'\0';
10965 }
10966 }
10967
if (len <= 0) {
10968 len = 0;
10969 }
10970
break;
10971 }
10972
if (valLen) {
10973 *valLen = len;
10974 }
10975 }
10976
return ret;
10977 }
10978
#endif
10979
10992
static SQLRETURN
10993 drvcolattribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT
id,
10994 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
10995 SQLPOINTER val2)
10996 {
10997
STMT *s;
10998
COL *c;
10999
int v = 0;
11000
char *valc = (
char *) val;
11001
11002
if (stmt == SQL_NULL_HSTMT) {
11003
return SQL_INVALID_HANDLE;
11004 }
11005 s = (
STMT *) stmt;
11006
if (!s->
cols) {
11007
return SQL_ERROR;
11008 }
11009
if (col < 1 || col > s->
ncols) {
11010
setstat(s, -1,
"invalid column", (*s->
ov3) ?
"07009" :
"S1002");
11011
return SQL_ERROR;
11012 }
11013 c = s->
cols + col - 1;
11014
switch (
id) {
11015
case SQL_DESC_CATALOG_NAME:
11016
if (valc && valMax > 0) {
11017 strncpy(valc, c->
db, valMax);
11018 valc[valMax - 1] =
'\0';
11019 }
11020
if (valLen) {
11021 *valLen = strlen(c->
db);
11022 }
11023 checkLen:
11024
if (valLen && *valLen >= valMax) {
11025
setstat(s, -1,
"data right truncated",
"01004");
11026
return SQL_SUCCESS_WITH_INFO;
11027 }
11028
break;
11029
case SQL_COLUMN_LENGTH:
11030
case SQL_DESC_LENGTH:
11031 v = c->
size;
11032
break;
11033
case SQL_COLUMN_LABEL:
11034
if (c->
label) {
11035
if (valc && valMax > 0) {
11036 strncpy(valc, c->
label, valMax);
11037 valc[valMax - 1] =
'\0';
11038 }
11039
if (valLen) {
11040 *valLen = strlen(c->
label);
11041 }
11042
goto checkLen;
11043 }
11044
11045
case SQL_COLUMN_NAME:
11046
case SQL_DESC_NAME:
11047
if (valc && valMax > 0) {
11048 strncpy(valc, c->
column, valMax);
11049 valc[valMax - 1] =
'\0';
11050 }
11051
if (valLen) {
11052 *valLen = strlen(c->
column);
11053
goto checkLen;
11054 }
11055
break;
11056
case SQL_DESC_TYPE_NAME: {
11057
char *tn = c->
typename ? c->
typename :
"varchar";
11058
11059
if (valc && valMax > 0) {
11060 strncpy(valc, tn, valMax);
11061 valc[valMax - 1] =
'\0';
11062 }
11063
if (valLen) {
11064 *valLen = strlen(tn);
11065
goto checkLen;
11066 }
11067
break;
11068 }
11069
case SQL_DESC_OCTET_LENGTH:
11070 v = c->
size;
11071
break;
11072
#if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
11073
case SQL_COLUMN_TABLE_NAME:
11074
#endif
11075
case SQL_DESC_TABLE_NAME:
11076
if (valc && valMax > 0) {
11077 strncpy(valc, c->
table, valMax);
11078 valc[valMax - 1] =
'\0';
11079 }
11080
if (valLen) {
11081 *valLen = strlen(c->
table);
11082
goto checkLen;
11083 }
11084
break;
11085
case SQL_DESC_TYPE:
11086 v = c->
type;
11087
#ifdef SQLITE_UTF8
11088
if (s->
nowchar) {
11089
switch (v) {
11090
case SQL_WCHAR:
11091 v = SQL_CHAR;
11092
break;
11093
case SQL_WVARCHAR:
11094 v = SQL_VARCHAR;
11095
break;
11096
#ifdef SQL_LONGVARCHAR
11097
case SQL_WLONGVARCHAR:
11098 v = SQL_LONGVARCHAR;
11099
break;
11100
#endif
11101
}
11102 }
11103
#endif
11104
break;
11105
case SQL_DESC_CONCISE_TYPE:
11106
switch (c->
type) {
11107
case SQL_INTEGER:
11108 v = SQL_C_LONG;
11109
break;
11110
case SQL_TINYINT:
11111 v = SQL_C_TINYINT;
11112
break;
11113
case SQL_SMALLINT:
11114 v = SQL_C_SHORT;
11115
break;
11116
case SQL_FLOAT:
11117 v = SQL_C_FLOAT;
11118
break;
11119
case SQL_DOUBLE:
11120 v = SQL_C_DOUBLE;
11121
break;
11122
case SQL_TIMESTAMP:
11123 v = SQL_C_TIMESTAMP;
11124
break;
11125
case SQL_TIME:
11126 v = SQL_C_TIME;
11127
break;
11128
case SQL_DATE:
11129 v = SQL_C_DATE;
11130
break;
11131
#ifdef SQL_C_TYPE_TIMESTAMP
11132
case SQL_TYPE_TIMESTAMP:
11133 v = SQL_C_TYPE_TIMESTAMP;
11134
break;
11135
#endif
11136
#ifdef SQL_C_TYPE_TIME
11137
case SQL_TYPE_TIME:
11138 v = SQL_C_TYPE_TIME;
11139
break;
11140
#endif
11141
#ifdef SQL_C_TYPE_DATE
11142
case SQL_TYPE_DATE:
11143 v = SQL_C_TYPE_DATE;
11144
break;
11145
#endif
11146
default:
11147
#ifdef SQLITE_UTF8
11148
v = s->
nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
11149
#else
11150
v = SQL_C_CHAR;
11151
#endif
11152
break;
11153 }
11154
break;
11155
case SQL_DESC_UPDATABLE:
11156 v = SQL_TRUE;
11157
break;
11158
case SQL_COLUMN_DISPLAY_SIZE:
11159 v = c->
size;
11160
break;
11161
case SQL_COLUMN_UNSIGNED:
11162 v = c->
nosign ? SQL_TRUE : SQL_FALSE;
11163
break;
11164
case SQL_COLUMN_SEARCHABLE:
11165 v = SQL_SEARCHABLE;
11166
break;
11167
case SQL_COLUMN_SCALE:
11168
case SQL_DESC_SCALE:
11169 v = c->
scale;
11170
break;
11171
case SQL_COLUMN_PRECISION:
11172
case SQL_DESC_PRECISION:
11173 v = c->
prec;
11174
break;
11175
case SQL_COLUMN_MONEY:
11176 v = SQL_FALSE;
11177
break;
11178
case SQL_COLUMN_AUTO_INCREMENT:
11179 v = c->
autoinc > 0 ? SQL_TRUE : SQL_FALSE;
11180
break;
11181
case SQL_DESC_NULLABLE:
11182 v = SQL_NULLABLE;
11183
break;
11184
default:
11185
setstat(s, -1,
"unsupported column attribute %d",
"HY091",
id);
11186
return SQL_ERROR;
11187 }
11188
if (val2) {
11189 *(
int *) val2 = v;
11190 }
11191
return SQL_SUCCESS;
11192 }
11193
11194
#ifndef SQLITE_UTF8
11195
11207 SQLRETURN SQL_API
11208 SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT
id,
11209 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
11210 SQLPOINTER val2)
11211 {
11212
return drvcolattribute(stmt, col,
id, val, valMax, valLen, val2);
11213 }
11214
#endif
11215
11216
#ifdef SQLITE_UTF8
11217
11229 SQLRETURN SQL_API
11230 SQLColAttributeW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT
id,
11231 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
11232 SQLPOINTER val2)
11233 {
11234 SQLRETURN ret;
11235 SQLSMALLINT len;
11236
11237 ret =
drvcolattribute(stmt, col,
id, val, valMax, &len, val2);
11238
if (ret == SQL_SUCCESS) {
11239 SQLWCHAR *v = NULL;
11240
11241
switch (
id) {
11242
case SQL_DESC_CATALOG_NAME:
11243
case SQL_COLUMN_LABEL:
11244
case SQL_DESC_NAME:
11245
case SQL_DESC_TABLE_NAME:
11246
case SQL_DESC_TYPE_NAME:
11247
if (val && valMax > 0) {
11248
int vmax = valMax /
sizeof (SQLWCHAR);
11249
11250 v = uc_from_utf((
char *) val, SQL_NTS);
11251
if (v) {
11252 uc_strncpy(val, v, vmax);
11253 uc_free(v);
11254 }
11255
if (vmax > 0) {
11256 v = (SQLWCHAR *) val;
11257 v[vmax - 1] =
'\0';
11258 }
11259 }
11260
if (len <= 0) {
11261 len = 0;
11262 }
11263
break;
11264 }
11265
if (valLen) {
11266 *valLen = len;
11267 }
11268 }
11269
return ret;
11270 }
11271
#endif
11272
11286
static SQLRETURN
11287 drverror(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
11288 SQLCHAR *sqlState, SQLINTEGER *nativeErr,
11289 SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
11290 {
11291 SQLCHAR dummy0[6];
11292 SQLINTEGER dummy1;
11293 SQLSMALLINT dummy2;
11294
11295
if (env == SQL_NULL_HENV &&
11296 dbc == SQL_NULL_HDBC &&
11297 stmt == SQL_NULL_HSTMT) {
11298
return SQL_INVALID_HANDLE;
11299 }
11300
if (sqlState) {
11301 sqlState[0] =
'\0';
11302 }
else {
11303 sqlState = dummy0;
11304 }
11305
if (!nativeErr) {
11306 nativeErr = &dummy1;
11307 }
11308 *nativeErr = 0;
11309
if (!errlen) {
11310 errlen = &dummy2;
11311 }
11312 *errlen = 0;
11313
if (errmsg) {
11314
if (errmax > 0) {
11315 errmsg[0] =
'\0';
11316 }
11317 }
else {
11318 errmsg = dummy0;
11319 errmax = 0;
11320 }
11321
if (stmt) {
11322
STMT *s = (
STMT *) stmt;
11323
11324
if (s->
logmsg[0] ==
'\0') {
11325
goto noerr;
11326 }
11327 *nativeErr = s->
naterr;
11328 strcpy(sqlState, s->
sqlstate);
11329
if (errmax == SQL_NTS) {
11330 strcpy(errmsg,
"[SQLite]");
11331 strcat(errmsg, s->
logmsg);
11332 *errlen = strlen(errmsg);
11333 }
else {
11334 strncpy(errmsg,
"[SQLite]", errmax);
11335
if (errmax - 8 > 0) {
11336 strncpy(errmsg + 8, s->
logmsg, errmax - 8);
11337 }
11338 *errlen =
min(strlen(s->
logmsg) + 8, errmax);
11339 }
11340 s->
logmsg[0] =
'\0';
11341
return SQL_SUCCESS;
11342 }
11343
if (dbc) {
11344
DBC *d = (
DBC *) dbc;
11345
11346
if (d->
magic !=
DBC_MAGIC || d->
logmsg[0] ==
'\0') {
11347
goto noerr;
11348 }
11349 *nativeErr = d->
naterr;
11350 strcpy(sqlState, d->
sqlstate);
11351
if (errmax == SQL_NTS) {
11352 strcpy(errmsg,
"[SQLite]");
11353 strcat(errmsg, d->
logmsg);
11354 *errlen = strlen(errmsg);
11355 }
else {
11356 strncpy(errmsg,
"[SQLite]", errmax);
11357
if (errmax - 8 > 0) {
11358 strncpy(errmsg + 8, d->
logmsg, errmax - 8);
11359 }
11360 *errlen =
min(strlen(d->
logmsg) + 8, errmax);
11361 }
11362 d->
logmsg[0] =
'\0';
11363
return SQL_SUCCESS;
11364 }
11365 noerr:
11366 sqlState[0] =
'\0';
11367 errmsg[0] =
'\0';
11368 *nativeErr = 0;
11369 *errlen = 0;
11370
return SQL_NO_DATA_FOUND;
11371 }
11372
11373
#ifndef SQLITE_UTF8
11374
11387 SQLRETURN SQL_API
11388 SQLError(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
11389 SQLCHAR *sqlState, SQLINTEGER *nativeErr,
11390 SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
11391 {
11392
return drverror(env, dbc, stmt, sqlState, nativeErr,
11393 errmsg, errmax, errlen);
11394 }
11395
#endif
11396
11397
#ifdef SQLITE_UTF8
11398
11411 SQLRETURN SQL_API
11412 SQLErrorW(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
11413 SQLWCHAR *sqlState, SQLINTEGER *nativeErr,
11414 SQLWCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
11415 {
11416
char state[16];
11417 SQLSMALLINT len;
11418 SQLRETURN ret;
11419
11420 ret =
drverror(env, dbc, stmt, state, nativeErr,
11421 (
char *) errmsg, errmax, &len);
11422
if (ret == SQL_SUCCESS) {
11423
if (sqlState) {
11424 uc_from_utf_buf(state, sqlState, 6 *
sizeof (SQLWCHAR));
11425 }
11426
if (errmsg) {
11427
if (len > 0) {
11428 SQLWCHAR *e = NULL;
11429
11430 e = uc_from_utf((
char *) errmsg, len);
11431
if (e) {
11432
if (errmax > 0) {
11433 uc_strncpy(errmsg, e, errmax);
11434 len =
min(errmax, uc_strlen(e));
11435 }
else {
11436 len = uc_strlen(e);
11437 }
11438 uc_free(e);
11439 }
else {
11440 len = 0;
11441 }
11442 }
11443
if (len <= 0) {
11444 len = 0;
11445
if (errmax > 0) {
11446 errmsg[0] = 0;
11447 }
11448 }
11449 }
else {
11450 len = 0;
11451 }
11452
if (errlen) {
11453 *errlen = len;
11454 }
11455 }
else if (ret == SQL_NO_DATA) {
11456
if (sqlState) {
11457 sqlState[0] = 0;
11458 }
11459
if (errmsg) {
11460
if (errmax > 0) {
11461 errmsg[0] = 0;
11462 }
11463 }
11464
if (errlen) {
11465 *errlen = 0;
11466 }
11467 }
11468
return ret;
11469 }
11470
#endif
11471
11478 SQLRETURN SQL_API
11479 SQLMoreResults(SQLHSTMT stmt)
11480 {
11481
if (stmt == SQL_NULL_HSTMT) {
11482
return SQL_INVALID_HANDLE;
11483 }
11484
return SQL_NO_DATA;
11485 }
11486
11496
static int
11497 selcb(
void *arg,
int ncols,
char **values,
char **cols)
11498 {
11499
STMT *s = (
STMT *) arg;
11500
11501
if (ncols > 0) {
11502
int i, size;
11503
char *p;
11504
COL *dyncols;
11505
DBC *d = (
DBC *) s->
dbc;
11506
11507
for (i = size = 0; i < ncols; i++) {
11508 size += 3 + 3 * strlen(cols[i]);
11509 }
11510 dyncols =
xmalloc(ncols *
sizeof (
COL) + size);
11511
if (!dyncols) {
11512
freedyncols(s);
11513 s->
ncols = 0;
11514
return 1;
11515 }
11516 p = (
char *) (dyncols + ncols);
11517
for (i = 0; i < ncols; i++) {
11518
char *q;
11519
11520 dyncols[i].
db = ((
DBC *) (s->
dbc))->dbname;
11521 strcpy(p, cols[i]);
11522 dyncols[i].
label = p;
11523 p += strlen(p) + 1;
11524 q = strchr(cols[i],
'.');
11525
if (q) {
11526 dyncols[i].
table = p;
11527 strncpy(p, cols[i], q - cols[i]);
11528 p[q - cols[i]] =
'\0';
11529 p += strlen(p) + 1;
11530 strcpy(p, q + 1);
11531 dyncols[i].
column = p;
11532 p += strlen(p) + 1;
11533 }
else {
11534 dyncols[i].
table =
"";
11535 strcpy(p, cols[i]);
11536 dyncols[i].
column = p;
11537 p += strlen(p) + 1;
11538 }
11539
#ifdef SQL_LONGVARCHAR
11540
dyncols[i].
type = SQL_LONGVARCHAR;
11541 dyncols[i].
size = 65536;
11542
#else
11543
dyncols[i].
type = SQL_VARCHAR;
11544 dyncols[i].
size = 256;
11545
#endif
11546
dyncols[i].
index = i;
11547 dyncols[i].
scale = 0;
11548 dyncols[i].
prec = 0;
11549 dyncols[i].
nosign = 1;
11550 dyncols[i].
autoinc = -1;
11551 dyncols[i].
typename = NULL;
11552 }
11553
freedyncols(s);
11554 s->
dyncols = s->
cols = dyncols;
11555 s->
dcols = ncols;
11556
fixupdyncols(s, d->
sqlite, (
const char **) cols + ncols);
11557 }
11558 s->
ncols = ncols;
11559
return 1;
11560 }
11561
11570
static SQLRETURN
11571 drvprepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
11572 {
11573
STMT *s;
11574
DBC *d;
11575
char *errp = NULL;
11576
11577
if (stmt == SQL_NULL_HSTMT) {
11578
return SQL_INVALID_HANDLE;
11579 }
11580 s = (
STMT *) stmt;
11581
if (s->
dbc == SQL_NULL_HDBC) {
11582
noconn:
11583
return noconn(s);
11584 }
11585 d = s->
dbc;
11586
if (!d->
sqlite) {
11587
goto noconn;
11588 }
11589
vm_end(s);
11590
freep(&s->
query);
11591 s->
query =
fixupsql(query, queryLen, &s->
nparams, &s->
isselect, &errp,
11592 d->
version, &s->
parmnames);
11593
if (!s->
query) {
11594
if (errp) {
11595
setstat(s, -1, errp, (*s->
ov3) ?
"HY000" :
"S1000");
11596
return SQL_ERROR;
11597 }
11598
return nomem(s);
11599 }
11600 errp = NULL;
11601
freeresult(s, -1);
11602
if (s->
isselect) {
11603
int ret;
11604
char **params = NULL;
11605
11606
if (s->
nparams) {
11607
int i;
11608
11609 params =
xmalloc(s->
nparams * sizeof (
char *));
11610
if (!params) {
11611
return nomem(s);
11612 }
11613
for (i = 0; i < s->
nparams; i++) {
11614 params[i] = NULL;
11615 }
11616 }
11617 ret = sqlite_exec_vprintf(d->
sqlite, s->
query,
selcb, s,
11618 &errp, (
char *) params);
11619
if (ret != SQLITE_ABORT && ret != SQLITE_OK) {
11620
dbtracerc(d, ret, errp);
11621
freep(¶ms);
11622
setstat(s, ret,
"%s (%d)", (*s->
ov3) ?
"HY000" :
"S1000",
11623 errp ? errp :
"unknown error", ret);
11624
if (errp) {
11625 sqlite_freemem(errp);
11626 errp = NULL;
11627 }
11628
return SQL_ERROR;
11629 }
11630
freep(¶ms);
11631
if (errp) {
11632 sqlite_freemem(errp);
11633 errp = NULL;
11634 }
11635 }
11636
mkbindcols(s, s->
ncols);
11637
if (s->
nparams) {
11638 s->
paramset_count = 0;
11639 }
11640
return SQL_SUCCESS;
11641 }
11642
11643
11644
11645
static SQLRETURN
11646 drvexecute(SQLHSTMT stmt)
11647 {
11648
STMT *s;
11649
DBC *d;
11650
char *errp = NULL, **params = NULL;
11651
int rc, i, size, ncols;
11652 SQLRETURN ret;
11653
11654
if (stmt == SQL_NULL_HSTMT) {
11655
return SQL_INVALID_HANDLE;
11656 }
11657 s = (
STMT *) stmt;
11658
if (s->
dbc == SQL_NULL_HDBC) {
11659
noconn:
11660
return noconn(s);
11661 }
11662 d = (
DBC *) s->
dbc;
11663
if (!d->
sqlite) {
11664
goto noconn;
11665 }
11666
if (!s->
query) {
11667
setstat(s, -1,
"no query prepared", (*s->
ov3) ?
"HY000" :
"S1000");
11668
return SQL_ERROR;
11669 }
11670
if (s->
nbindparms < s->
nparams) {
11671
setstat(s, -1,
"unbound parameters in query",
11672 (*s->
ov3) ?
"HY000" :
"S1000");
11673
return SQL_ERROR;
11674 }
11675 again:
11676
vm_end(s);
11677
for (i = size = 0; i < s->
nparams; i++) {
11678 ret =
substparam(s, i, NULL, &size);
11679
if (ret != SQL_SUCCESS) {
11680
goto cleanup;
11681 }
11682 }
11683
if (s->
nparams) {
11684
char *p;
11685
11686 params =
xmalloc(s->
nparams * sizeof (
char *) + size);
11687
if (!params) {
11688 ret =
nomem(s);
11689
goto cleanup;
11690 }
11691 p = (
char *) (params + s->
nparams);
11692
for (i = 0; i < s->
nparams; i++) {
11693
int len = 0;
11694
11695 params[i] = p;
11696
substparam(s, i, &p, NULL);
11697
if (s->
bindparms[i].
ind) {
11698 len = s->
bindparms[i].
len;
11699 }
else if (s->
bindparms[i].
lenp) {
11700 len = *s->
bindparms[i].
lenp;
11701 }
11702
if (len == SQL_NULL_DATA) {
11703 params[i] = NULL;
11704 }
11705 }
11706 }
11707
freeresult(s, 0);
11708
if (!d->
autocommit && !d->
intrans) {
11709 rc = sqlite_exec(d->
sqlite,
"BEGIN TRANSACTION", NULL, NULL, &errp);
11710
dbtracerc(d, rc, errp);
11711
if (rc != SQLITE_OK) {
11712
freep(¶ms);
11713
setstat(s, rc,
"%s (%d)", (*s->
ov3) ?
"HY000" :
"S1000",
11714 errp ? errp :
"unknown error", rc);
11715
if (errp) {
11716 sqlite_freemem(errp);
11717 errp = NULL;
11718 }
11719 ret = SQL_ERROR;
11720
goto cleanup;
11721 }
11722 d->
intrans = 1;
11723
if (errp) {
11724 sqlite_freemem(errp);
11725 errp = NULL;
11726 }
11727 }
11728
if (s->
isselect && !d->
intrans &&
11729 s->
curtype == SQL_CURSOR_FORWARD_ONLY &&
11730 d->
step_enable && s->
nparams == 0 && d->
vm_stmt == NULL) {
11731 s->
nrows = -1;
11732 ret =
vm_start(s, params);
11733
if (ret == SQL_SUCCESS) {
11734
freep(¶ms);
11735
goto done2;
11736 }
11737 }
11738 rc = sqlite_get_table_vprintf(d->
sqlite, s->
query, &s->
rows,
11739 &s->
nrows, &ncols, &errp, (
char *) params);
11740
dbtracerc(d, rc, errp);
11741
if (rc != SQLITE_OK) {
11742
freep(¶ms);
11743
setstat(s, rc,
"%s (%d)", (*s->
ov3) ?
"HY000" :
"S1000",
11744 errp ? errp :
"unknown error", rc);
11745
if (errp) {
11746 sqlite_freemem(errp);
11747 errp = NULL;
11748 }
11749 ret = SQL_ERROR;
11750
goto cleanup;
11751 }
11752
freep(¶ms);
11753
if (errp) {
11754 sqlite_freemem(errp);
11755 errp = NULL;
11756 }
11757 s->
rowfree = sqlite_free_table;
11758
if (ncols == 1 && !s->
isselect) {
11759
11760
11761
11762
11763
if (strcmp(s->
rows[0],
"rows inserted") == 0 ||
11764 strcmp(s->
rows[0],
"rows updated") == 0 ||
11765 strcmp(s->
rows[0],
"rows deleted") == 0) {
11766
int nrows = 0;
11767
11768 nrows = strtol(s->
rows[1], NULL, 0);
11769
freeresult(s, -1);
11770 s->
nrows = nrows;
11771
goto done;
11772 }
11773 }
11774
if (s->
ncols != ncols) {
11775
int size;
11776
char *p;
11777
COL *dyncols;
11778
11779
for (i = size = 0; i < ncols; i++) {
11780 size += 3 + 3 * strlen(s->
rows[i]);
11781 }
11782
if (size == 0) {
11783
freeresult(s, -1);
11784
goto done;
11785 }
11786 dyncols =
xmalloc(ncols *
sizeof (
COL) + size);
11787
if (!dyncols) {
11788 ret =
nomem(s);
11789
goto cleanup;
11790 }
11791 p = (
char *) (dyncols + ncols);
11792
for (i = 0; i < ncols; i++) {
11793
char *q;
11794
11795 dyncols[i].
db = d->
dbname;
11796 strcpy(p, s->
rows[i]);
11797 dyncols[i].
label = p;
11798 p += strlen(p) + 1;
11799 q = strchr(s->
rows[i],
'.');
11800
if (q) {
11801 dyncols[i].
table = p;
11802 strncpy(p, s->
rows[i], q - s->
rows[i]);
11803 p[q - s->
rows[i]] =
'\0';
11804 p += strlen(p) + 1;
11805 dyncols[i].
column = q + 1;
11806 }
else {
11807 dyncols[i].
table =
"";
11808 dyncols[i].
column = s->
rows[i];
11809 }
11810
#ifdef SQL_LONGVARCHAR
11811
dyncols[i].
type = SQL_LONGVARCHAR;
11812 dyncols[i].
size = 65536;
11813
#else
11814
dyncols[i].
type = SQL_VARCHAR;
11815 dyncols[i].
size = 255;
11816
#endif
11817
dyncols[i].
index = i;
11818 dyncols[i].
scale = 0;
11819 dyncols[i].
prec = 0;
11820 dyncols[i].
nosign = 1;
11821 dyncols[i].
autoinc = -1;
11822 dyncols[i].
typename = NULL;
11823 }
11824
freedyncols(s);
11825 s->
ncols = s->
dcols = ncols;
11826 s->
dyncols = s->
cols = dyncols;
11827
fixupdyncols(s, d->
sqlite, NULL);
11828 }
11829 done:
11830
mkbindcols(s, s->
ncols);
11831 done2:
11832 ret = SQL_SUCCESS;
11833 s->
rowp = -1;
11834
if (s->
nparams) {
11835 s->
paramset_count++;
11836 s->
paramset_nrows += s->
nrows;
11837
if (s->
paramset_count < s->
paramset_size) {
11838
for (i = 0; i < s->
nparams; i++) {
11839
BINDPARM *p = &s->
bindparms[i];
11840
11841
if (p->
param && p->
inc > 0) {
11842 p->
param = (
char *) p->
param + p->
inc;
11843 }
11844 }
11845
goto again;
11846 }
11847 }
11848 cleanup:
11849
if (s->
nparams) {
11850
for (i = 0; i < s->
nparams; i++) {
11851
BINDPARM *p = &s->
bindparms[i];
11852
11853 p->
param = p->
param0;
11854 }
11855 s->
nrows = s->
paramset_nrows;
11856 s->
paramset_count = 0;
11857 s->
paramset_nrows = 0;
11858 }
11859
return ret;
11860 }
11861
11862
#ifndef SQLITE_UTF8
11863
11871 SQLRETURN SQL_API
11872 SQLPrepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
11873 {
11874
return drvprepare(stmt, query, queryLen);
11875 }
11876
#endif
11877
11878
#ifdef SQLITE_UTF8
11879
11887 SQLRETURN SQL_API
11888 SQLPrepareW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
11889 {
11890 SQLRETURN ret;
11891
char *q = uc_to_utf_c(query, queryLen);
11892
11893
if (!q) {
11894
return nomem((
STMT *) stmt);
11895 }
11896 ret =
drvprepare(stmt, q, SQL_NTS);
11897 uc_free(q);
11898
return ret;
11899 }
11900
#endif
11901
11908 SQLRETURN SQL_API
11909 SQLExecute(SQLHSTMT stmt)
11910 {
11911
return drvexecute(stmt);
11912 }
11913
11914
#ifndef SQLITE_UTF8
11915
11923 SQLRETURN SQL_API
11924 SQLExecDirect(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
11925 {
11926
if (
drvprepare(stmt, query, queryLen) != SQL_SUCCESS) {
11927
return SQL_ERROR;
11928 }
11929
return drvexecute(stmt);
11930 }
11931
#endif
11932
11933
#ifdef SQLITE_UTF8
11934
11942 SQLRETURN SQL_API
11943 SQLExecDirectW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
11944 {
11945 SQLRETURN ret;
11946
char *q = uc_to_utf_c(query, queryLen);
11947
11948
if (!q) {
11949
return nomem((
STMT *) stmt);
11950 }
11951 ret =
drvprepare(stmt, q, SQL_NTS);
11952 uc_free(q);
11953
if (ret == SQL_SUCCESS) {
11954
return drvexecute(stmt);
11955 }
11956
return ret;
11957 }
11958
#endif
11959
11960
#ifdef _WIN32
11961
#ifndef WITHOUT_DRIVERMGR
11962
11963
11964
11965
11966
11967
#include <windowsx.h>
11968
#include <winuser.h>
11969
#include "resource.h"
11970
11971
#define stricmp _stricmp
11972
11973
static HINSTANCE NEAR hModule;
11974
11975
#define MAXPATHLEN (255+1)
11976
#define MAXKEYLEN (15+1)
11977
#define MAXDESC (255+1)
11978
#define MAXDSNAME (32+1)
11979
#define MAXTONAME (32+1)
11980
#define MAXDBNAME (255+1)
11981
11982
11983
11984
#define KEY_DSN 0
11985
#define KEY_DESC 1
11986
#define KEY_DBNAME 2
11987
#define KEY_BUSY 3
11988
#define KEY_DRIVER 4
11989
#define KEY_NOWCHAR 5
11990
#define KEY_STEPAPI 6
11991
#define NUMOFKEYS 7
11992
11993
typedef struct {
11994 BOOL supplied;
11995
char attr[MAXPATHLEN];
11996 } ATTR;
11997
11998
typedef struct {
11999 SQLHWND parent;
12000 LPCSTR driver;
12001 ATTR attr[NUMOFKEYS];
12002
char DSN[MAXDSNAME];
12003 BOOL newDSN;
12004 BOOL defDSN;
12005 } SETUPDLG;
12006
12007
static struct {
12008
char *key;
12009
int ikey;
12010 } attrLookup[] = {
12011 {
"DSN", KEY_DSN },
12012 {
"DESC", KEY_DESC },
12013 {
"Description", KEY_DESC},
12014 {
"Database", KEY_DBNAME },
12015 {
"Timeout", KEY_BUSY },
12016 {
"Driver", KEY_DRIVER },
12017 {
"NoWCHAR", KEY_NOWCHAR },
12018 {
"StepAPI", KEY_STEPAPI },
12019 { NULL, 0 }
12020 };
12021
12028
static void
12029 ParseAttributes(LPCSTR attribs, SETUPDLG *setupdlg)
12030 {
12031
char *str = (
char *) attribs, *start, key[MAXKEYLEN];
12032
int elem, nkey;
12033
12034
while (*str) {
12035 start = str;
12036
if ((str = strchr(str,
'=')) == NULL) {
12037
return;
12038 }
12039 elem = -1;
12040 nkey = str - start;
12041
if (nkey <
sizeof (key)) {
12042
int i;
12043
12044 memcpy(key, start, nkey);
12045 key[nkey] =
'\0';
12046
for (i = 0; attrLookup[i].key; i++) {
12047
if (stricmp(attrLookup[i].key, key) == 0) {
12048 elem = attrLookup[i].ikey;
12049
break;
12050 }
12051 }
12052 }
12053 start = ++str;
12054
while (*str && *str !=
';') {
12055 ++str;
12056 }
12057
if (elem >= 0) {
12058
int end =
min(str - start,
sizeof (setupdlg->attr[elem].attr) - 1);
12059
12060 setupdlg->attr[elem].supplied = TRUE;
12061 memcpy(setupdlg->attr[elem].attr, start, end);
12062 setupdlg->attr[elem].attr[end] =
'\0';
12063 }
12064 ++str;
12065 }
12066 }
12067
12075
static BOOL
12076 SetDSNAttributes(HWND parent, SETUPDLG *setupdlg)
12077 {
12078
char *dsn = setupdlg->attr[KEY_DSN].attr;
12079
12080
if (setupdlg->newDSN && strlen(dsn) == 0) {
12081
return FALSE;
12082 }
12083
if (!SQLWriteDSNToIni(dsn, setupdlg->driver)) {
12084
if (parent) {
12085
char buf[MAXPATHLEN], msg[MAXPATHLEN];
12086
12087 LoadString(hModule, IDS_BADDSN, buf,
sizeof (buf));
12088 wsprintf(msg, buf, dsn);
12089 LoadString(hModule, IDS_MSGTITLE, buf,
sizeof (buf));
12090 MessageBox(parent, msg, buf,
12091 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
12092 MB_SETFOREGROUND);
12093 }
12094
return FALSE;
12095 }
12096
if (parent || setupdlg->attr[KEY_DESC].supplied) {
12097 SQLWritePrivateProfileString(dsn,
"Description",
12098 setupdlg->attr[KEY_DESC].attr,
12099 ODBC_INI);
12100 }
12101
if (parent || setupdlg->attr[KEY_DBNAME].supplied) {
12102 SQLWritePrivateProfileString(dsn,
"Database",
12103 setupdlg->attr[KEY_DBNAME].attr,
12104 ODBC_INI);
12105 }
12106
if (parent || setupdlg->attr[KEY_BUSY].supplied) {
12107 SQLWritePrivateProfileString(dsn,
"Timeout",
12108 setupdlg->attr[KEY_BUSY].attr,
12109 ODBC_INI);
12110 }
12111
if (parent || setupdlg->attr[KEY_NOWCHAR].supplied) {
12112 SQLWritePrivateProfileString(dsn,
"NoWCHAR",
12113 setupdlg->attr[KEY_NOWCHAR].attr,
12114 ODBC_INI);
12115 }
12116
if (parent || setupdlg->attr[KEY_STEPAPI].supplied) {
12117 SQLWritePrivateProfileString(dsn,
"StepAPI",
12118 setupdlg->attr[KEY_STEPAPI].attr,
12119 ODBC_INI);
12120 }
12121
if (setupdlg->attr[KEY_DSN].supplied &&
12122 stricmp(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr)) {
12123 SQLRemoveDSNFromIni(setupdlg->DSN);
12124 }
12125
return TRUE;
12126 }
12127
12133
static void
12134 GetAttributes(SETUPDLG *setupdlg)
12135 {
12136
char *dsn = setupdlg->attr[KEY_DSN].attr;
12137
12138
if (!setupdlg->attr[KEY_DESC].supplied) {
12139 SQLGetPrivateProfileString(dsn,
"Description",
"",
12140 setupdlg->attr[KEY_DESC].attr,
12141 sizeof (setupdlg->attr[KEY_DESC].attr),
12142 ODBC_INI);
12143 }
12144
if (!setupdlg->attr[KEY_DBNAME].supplied) {
12145 SQLGetPrivateProfileString(dsn,
"Database",
"",
12146 setupdlg->attr[KEY_DBNAME].attr,
12147 sizeof (setupdlg->attr[KEY_DBNAME].attr),
12148 ODBC_INI);
12149 }
12150
if (!setupdlg->attr[KEY_BUSY].supplied) {
12151 SQLGetPrivateProfileString(dsn,
"Timeout",
"1000",
12152 setupdlg->attr[KEY_BUSY].attr,
12153 sizeof (setupdlg->attr[KEY_BUSY].attr),
12154 ODBC_INI);
12155 }
12156
if (!setupdlg->attr[KEY_NOWCHAR].supplied) {
12157 SQLGetPrivateProfileString(dsn,
"NoWCHAR",
"",
12158 setupdlg->attr[KEY_NOWCHAR].attr,
12159 sizeof (setupdlg->attr[KEY_NOWCHAR].attr),
12160 ODBC_INI);
12161 }
12162
if (!setupdlg->attr[KEY_STEPAPI].supplied) {
12163 SQLGetPrivateProfileString(dsn,
"StepAPI",
"0",
12164 setupdlg->attr[KEY_STEPAPI].attr,
12165 sizeof (setupdlg->attr[KEY_STEPAPI].attr),
12166 ODBC_INI);
12167 }
12168 }
12169
12175
static void
12176 GetDBFile(HWND hdlg)
12177 {
12178 SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
12179 OPENFILENAME ofn;
12180
12181 memset(&ofn, 0,
sizeof (ofn));
12182 ofn.lStructSize =
sizeof (ofn);
12183 ofn.hwndOwner = hdlg;
12184 ofn.hInstance = (HINSTANCE) GetWindowLong(hdlg, GWL_HINSTANCE);
12185 ofn.lpstrFile = (LPTSTR) setupdlg->attr[KEY_DBNAME].attr;
12186 ofn.nMaxFile = MAXPATHLEN;
12187 ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST |
12188 OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST;
12189
if (GetOpenFileName(&ofn)) {
12190 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
12191 setupdlg->attr[KEY_DBNAME].supplied = TRUE;
12192 }
12193 }
12194
12204
static BOOL CALLBACK
12205 ConfigDlgProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
12206 {
12207 SETUPDLG *setupdlg = NULL;
12208
12209
switch (wmsg) {
12210
case WM_INITDIALOG:
12211 SetWindowLong(hdlg, DWL_USER, lparam);
12212 setupdlg = (SETUPDLG *) lparam;
12213 GetAttributes(setupdlg);
12214 SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
12215 SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
12216 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
12217 SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
12218 CheckDlgButton(hdlg, IDC_NOWCHAR,
12219
getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
12220 BST_CHECKED : BST_UNCHECKED);
12221 CheckDlgButton(hdlg, IDC_STEPAPI,
12222
getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
12223 BST_CHECKED : BST_UNCHECKED);
12224
if (setupdlg->defDSN) {
12225 EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
12226 EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
12227 }
else {
12228 SendDlgItemMessage(hdlg, IDC_DSNAME,
12229 EM_LIMITTEXT, (WPARAM) (MAXDSNAME - 1), 0L);
12230 SendDlgItemMessage(hdlg, IDC_DESC,
12231 EM_LIMITTEXT, (WPARAM) (MAXDESC - 1), 0L);
12232 SendDlgItemMessage(hdlg, IDC_DBNAME,
12233 EM_LIMITTEXT, (WPARAM) (MAXDBNAME - 1), 0L);
12234 SendDlgItemMessage(hdlg, IDC_TONAME,
12235 EM_LIMITTEXT, (WPARAM) (MAXTONAME - 1), 0L);
12236 }
12237
return TRUE;
12238
case WM_COMMAND:
12239
switch (GET_WM_COMMAND_ID(wparam, lparam)) {
12240
case IDC_DSNAME:
12241
if (GET_WM_COMMAND_CMD(wparam, lparam) == EN_CHANGE) {
12242
char item[MAXDSNAME];
12243
12244 EnableWindow(GetDlgItem(hdlg, IDOK),
12245 GetDlgItemText(hdlg, IDC_DSNAME,
12246 item,
sizeof (item)));
12247
return TRUE;
12248 }
12249
break;
12250
case IDC_BROWSE:
12251 GetDBFile(hdlg);
12252
break;
12253
case IDOK:
12254 setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
12255
if (!setupdlg->defDSN) {
12256 GetDlgItemText(hdlg, IDC_DSNAME,
12257 setupdlg->attr[KEY_DSN].attr,
12258 sizeof (setupdlg->attr[KEY_DSN].attr));
12259 }
12260 GetDlgItemText(hdlg, IDC_DESC,
12261 setupdlg->attr[KEY_DESC].attr,
12262 sizeof (setupdlg->attr[KEY_DESC].attr));
12263 GetDlgItemText(hdlg, IDC_DBNAME,
12264 setupdlg->attr[KEY_DBNAME].attr,
12265 sizeof (setupdlg->attr[KEY_DBNAME].attr));
12266 GetDlgItemText(hdlg, IDC_TONAME,
12267 setupdlg->attr[KEY_BUSY].attr,
12268 sizeof (setupdlg->attr[KEY_BUSY].attr));
12269 strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
12270 IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED ?
12271
"1" :
"0");
12272 strcpy(setupdlg->attr[KEY_STEPAPI].attr,
12273 IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED ?
12274
"1" :
"0");
12275 SetDSNAttributes(hdlg, setupdlg);
12276
12277
case IDCANCEL:
12278 EndDialog(hdlg, wparam);
12279
return TRUE;
12280 }
12281
break;
12282 }
12283
return FALSE;
12284 }
12285
12295 BOOL INSTAPI
12296 ConfigDSN(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attribs)
12297 {
12298 BOOL success;
12299 SETUPDLG *setupdlg;
12300
12301 setupdlg = (SETUPDLG *)
xmalloc(
sizeof (SETUPDLG));
12302
if (setupdlg == NULL) {
12303
return FALSE;
12304 }
12305 memset(setupdlg, 0,
sizeof (SETUPDLG));
12306
if (attribs) {
12307 ParseAttributes(attribs, setupdlg);
12308 }
12309
if (setupdlg->attr[KEY_DSN].supplied) {
12310 strcpy(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr);
12311 }
else {
12312 setupdlg->DSN[0] =
'\0';
12313 }
12314
if (request == ODBC_REMOVE_DSN) {
12315
if (!setupdlg->attr[KEY_DSN].supplied) {
12316 success = FALSE;
12317 }
else {
12318 success = SQLRemoveDSNFromIni(setupdlg->attr[KEY_DSN].attr);
12319 }
12320 }
else {
12321 setupdlg->parent = hwnd;
12322 setupdlg->driver = driver;
12323 setupdlg->newDSN = request == ODBC_ADD_DSN;
12324 setupdlg->defDSN = stricmp(setupdlg->attr[KEY_DSN].attr,
12325
"Default") == 0;
12326
if (hwnd) {
12327 success = DialogBoxParam(hModule, MAKEINTRESOURCE(CONFIGDSN),
12328 hwnd, (DLGPROC) ConfigDlgProc,
12329 (LONG) setupdlg) == IDOK;
12330 }
else if (setupdlg->attr[KEY_DSN].supplied) {
12331 success = SetDSNAttributes(hwnd, setupdlg);
12332 }
else {
12333 success = FALSE;
12334 }
12335 }
12336
xfree(setupdlg);
12337
return success;
12338 }
12339
12349
static BOOL CALLBACK
12350 DriverConnectProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
12351 {
12352 SETUPDLG *setupdlg;
12353
12354
switch (wmsg) {
12355
case WM_INITDIALOG:
12356 SetWindowLong(hdlg, DWL_USER, lparam);
12357 setupdlg = (SETUPDLG *) lparam;
12358 SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
12359 SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
12360 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
12361 SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
12362 SendDlgItemMessage(hdlg, IDC_DSNAME,
12363 EM_LIMITTEXT, (WPARAM) (MAXDSNAME - 1), 0L);
12364 SendDlgItemMessage(hdlg, IDC_DESC,
12365 EM_LIMITTEXT, (WPARAM) (MAXDESC - 1), 0L);
12366 SendDlgItemMessage(hdlg, IDC_DBNAME,
12367 EM_LIMITTEXT, (WORD)(MAXDBNAME - 1), 0L);
12368 SendDlgItemMessage(hdlg, IDC_TONAME,
12369 EM_LIMITTEXT, (WORD)(MAXTONAME - 1), 0L);
12370 CheckDlgButton(hdlg, IDC_NOWCHAR,
12371
getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
12372 BST_CHECKED : BST_UNCHECKED);
12373 CheckDlgButton(hdlg, IDC_STEPAPI,
12374
getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
12375 BST_CHECKED : BST_UNCHECKED);
12376
return TRUE;
12377
case WM_COMMAND:
12378
switch (GET_WM_COMMAND_ID(wparam, lparam)) {
12379
case IDC_BROWSE:
12380 GetDBFile(hdlg);
12381
break;
12382
case IDOK:
12383 setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
12384 GetDlgItemText(hdlg, IDC_DSNAME,
12385 setupdlg->attr[KEY_DSN].attr,
12386 sizeof (setupdlg->attr[KEY_DSN].attr));
12387 GetDlgItemText(hdlg, IDC_DBNAME,
12388 setupdlg->attr[KEY_DBNAME].attr,
12389 sizeof (setupdlg->attr[KEY_DBNAME].attr));
12390 GetDlgItemText(hdlg, IDC_TONAME,
12391 setupdlg->attr[KEY_BUSY].attr,
12392 sizeof (setupdlg->attr[KEY_BUSY].attr));
12393 strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
12394 IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED ?
12395
"1" :
"0");
12396 strcpy(setupdlg->attr[KEY_STEPAPI].attr,
12397 IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED ?
12398
"1" :
"0");
12399
12400
case IDCANCEL:
12401 EndDialog(hdlg, GET_WM_COMMAND_ID(wparam, lparam) == IDOK);
12402
return TRUE;
12403 }
12404 }
12405
return FALSE;
12406 }
12407
12421
static SQLRETURN
12422
drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
12423 SQLCHAR *connIn, SQLSMALLINT connInLen,
12424 SQLCHAR *connOut, SQLSMALLINT connOutMax,
12425 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
12426 {
12427 BOOL maybeprompt, prompt = FALSE;
12428
DBC *d;
12429 SETUPDLG *setupdlg;
12430
short ret;
12431 SQLRETURN rc;
12432
12433
if (dbc == SQL_NULL_HDBC) {
12434
return SQL_INVALID_HANDLE;
12435 }
12436 d = (
DBC *) dbc;
12437
if (d->
sqlite) {
12438
setstatd(d, -1,
"connection already established",
"08002");
12439
return SQL_ERROR;
12440 }
12441 setupdlg = (SETUPDLG *)
xmalloc(
sizeof (SETUPDLG));
12442
if (setupdlg == NULL) {
12443
return SQL_ERROR;
12444 }
12445 memset(setupdlg, 0,
sizeof (SETUPDLG));
12446 maybeprompt = drvcompl == SQL_DRIVER_COMPLETE ||
12447 drvcompl == SQL_DRIVER_COMPLETE_REQUIRED;
12448
if (connIn == NULL || !connInLen ||
12449 (connInLen == SQL_NTS && !connIn[0])) {
12450 prompt = TRUE;
12451 }
else {
12452 ParseAttributes(connIn, setupdlg);
12453
if (!setupdlg->attr[KEY_DSN].attr[0] &&
12454 drvcompl == SQL_DRIVER_COMPLETE_REQUIRED) {
12455 strcpy(setupdlg->attr[KEY_DSN].attr,
"DEFAULT");
12456 }
12457 GetAttributes(setupdlg);
12458
if (drvcompl == SQL_DRIVER_PROMPT ||
12459 (maybeprompt &&
12460 !setupdlg->attr[KEY_DSN].attr[0] ||
12461 !setupdlg->attr[KEY_DBNAME].attr[0])) {
12462 prompt = TRUE;
12463 }
12464 }
12465 retry:
12466
if (prompt) {
12467 ret = DialogBoxParam(hModule, MAKEINTRESOURCE(DRIVERCONNECT),
12468 hwnd, (DLGPROC) DriverConnectProc,
12469 (LONG) setupdlg);
12470
if (!ret || ret == -1) {
12471
xfree(setupdlg);
12472
return SQL_NO_DATA_FOUND;
12473 }
12474 }
12475
if (connOut || connOutLen) {
12476
char buf[1024];
12477
int len, count;
12478
char dsn_0 = setupdlg->attr[KEY_DSN].attr[0];
12479
char drv_0 = setupdlg->attr[KEY_DRIVER].attr[0];
12480
12481 buf[0] =
'\0';
12482 count = snprintf(buf,
sizeof (buf),
12483
"%s%s%s%s%s%sDatabase=%s;StepAPI=%s;"
12484
"Timeout=%s;NoWCHAR=%s",
12485 dsn_0 ?
"DSN=" :
"",
12486 dsn_0 ? setupdlg->attr[KEY_DSN].attr :
"",
12487 dsn_0 ?
";" :
"",
12488 drv_0 ?
"Driver=" :
"",
12489 drv_0 ? setupdlg->attr[KEY_DRIVER].attr :
"",
12490 drv_0 ?
";" :
"",
12491 setupdlg->attr[KEY_DBNAME].attr,
12492 setupdlg->attr[KEY_STEPAPI].attr,
12493 setupdlg->attr[KEY_BUSY].attr,
12494 setupdlg->attr[KEY_NOWCHAR].attr);
12495
if (count < 0) {
12496 buf[
sizeof (buf) - 1] =
'\0';
12497 }
12498 len =
min(connOutMax - 1, strlen(buf));
12499
if (connOut) {
12500 strncpy(connOut, buf, len);
12501 connOut[len] =
'\0';
12502 }
12503
if (connOutLen) {
12504 *connOutLen = len;
12505 }
12506 }
12507 d->
nowchar =
getbool(setupdlg->attr[KEY_NOWCHAR].attr);
12508 rc =
dbopen(d, setupdlg->attr[KEY_DBNAME].attr,
12509 setupdlg->attr[KEY_DSN].attr,
12510 setupdlg->attr[KEY_STEPAPI].attr,
12511 setupdlg->attr[KEY_BUSY].attr);
12512
if (rc != SQL_SUCCESS) {
12513
if (maybeprompt && !prompt) {
12514 prompt = TRUE;
12515
goto retry;
12516 }
12517
xfree(setupdlg);
12518
return rc;
12519 }
12520
xfree(setupdlg);
12521
return SQL_SUCCESS;
12522 }
12523
12524
#endif
12525
#endif
12526
12527
#ifndef WITHOUT_DRIVERMGR
12528
12529
#ifndef SQLITE_UTF8
12530
12543 SQLRETURN SQL_API
12544 SQLDriverConnect(SQLHDBC dbc, SQLHWND hwnd,
12545 SQLCHAR *connIn, SQLSMALLINT connInLen,
12546 SQLCHAR *connOut, SQLSMALLINT connOutMax,
12547 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
12548 {
12549
return drvdriverconnect(dbc, hwnd, connIn, connInLen,
12550 connOut, connOutMax, connOutLen, drvcompl);
12551 }
12552
#endif
12553
12554
#ifdef SQLITE_UTF8
12555
12568 SQLRETURN SQL_API
12569 SQLDriverConnectW(SQLHDBC dbc, SQLHWND hwnd,
12570 SQLWCHAR *connIn, SQLSMALLINT connInLen,
12571 SQLWCHAR *connOut, SQLSMALLINT connOutMax,
12572 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
12573 {
12574 SQLRETURN ret;
12575
char *ci = NULL;
12576 SQLSMALLINT len;
12577
12578
if (connIn) {
12579 ci = uc_to_utf_c(connIn, connInLen);
12580
if (!ci) {
12581
DBC *d = (
DBC *) dbc;
12582
12583
setstatd(d, -1,
"out of memory", (*d->
ov3) ?
"HY000" :
"S1000");
12584
return SQL_ERROR;
12585 }
12586 }
12587 ret =
drvdriverconnect(dbc, hwnd, ci, SQL_NTS,
12588 (
char *) connOut, connOutMax, &len, drvcompl);
12589 uc_free(ci);
12590
if (ret == SQL_SUCCESS) {
12591 SQLWCHAR *co = NULL;
12592
12593
if (connOut) {
12594
if (len > 0) {
12595 co = uc_from_utf((
char *) connOut, len);
12596
if (co) {
12597 uc_strncpy(connOut, co, connOutMax);
12598 len =
min(connOutMax, uc_strlen(co));
12599 uc_free(co);
12600 }
else {
12601 len = 0;
12602 }
12603 }
12604
if (len <= 0) {
12605 len = 0;
12606 connOut[0] = 0;
12607 }
12608 }
else {
12609 len = 0;
12610 }
12611
if (connOutLen) {
12612 *connOutLen = len;
12613 }
12614 }
12615
return ret;
12616 }
12617
#endif
12618
12619
#endif
12620
12621
#ifdef _WIN32
12622
12631 BOOL APIENTRY
12632 LibMain(HANDLE hinst, DWORD reason, LPVOID reserved)
12633 {
12634
static int initialized = 0;
12635
12636
switch (reason) {
12637
case DLL_PROCESS_ATTACH:
12638
if (!initialized++) {
12639 hModule = hinst;
12640 }
12641
break;
12642
case DLL_THREAD_ATTACH:
12643
break;
12644
case DLL_PROCESS_DETACH:
12645 --initialized;
12646
break;
12647
case DLL_THREAD_DETACH:
12648
break;
12649
default:
12650
break;
12651 }
12652
return TRUE;
12653 }
12654
12663
int __stdcall
12664 DllMain(HANDLE hinst, DWORD reason, LPVOID reserved)
12665 {
12666
return LibMain(hinst, reason, reserved);
12667 }
12668
12669
#endif
12670
12671
#if defined(HAVE_ODBCINSTEXT_H) && HAVE_ODBCINSTEXT_H
12672
12673
12674
12675
12676
12677
12678
#include <odbcinstext.h>
12679
12680
int
12681 ODBCINSTGetProperties(HODBCINSTPROPERTY prop)
12682 {
12683
static const char *instYN[] = {
"No",
"Yes", NULL };
12684
12685 prop->pNext = (HODBCINSTPROPERTY) malloc(
sizeof (ODBCINSTPROPERTY));
12686 prop = prop->pNext;
12687 memset(prop, 0,
sizeof (ODBCINSTPROPERTY));
12688 prop->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
12689 strncpy(prop->szName,
"Database", INI_MAX_PROPERTY_NAME);
12690 strncpy(prop->szValue,
"", INI_MAX_PROPERTY_VALUE);
12691 prop->pNext = (HODBCINSTPROPERTY) malloc(
sizeof (ODBCINSTPROPERTY));
12692 prop = prop->pNext;
12693 memset(prop, 0,
sizeof (ODBCINSTPROPERTY));
12694 prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
12695 strncpy(prop->szName,
"Timeout", INI_MAX_PROPERTY_NAME);
12696 strncpy(prop->szValue,
"1000", INI_MAX_PROPERTY_VALUE);
12697 prop->pNext = (HODBCINSTPROPERTY) malloc(
sizeof (ODBCINSTPROPERTY));
12698 prop = prop->pNext;
12699 memset(prop, 0,
sizeof (ODBCINSTPROPERTY));
12700 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
12701 prop->aPromptData = malloc (
sizeof (instYN));
12702 memcpy(prop->aPromptData, instYN, sizeof (instYN));
12703 strncpy(prop->szName,
"StepAPI", INI_MAX_PROPERTY_NAME);
12704 strncpy(prop->szValue,
"No", INI_MAX_PROPERTY_VALUE);
12705
#ifdef SQLITE_UTF8
12706
prop->pNext = (HODBCINSTPROPERTY) malloc(
sizeof (ODBCINSTPROPERTY));
12707 prop = prop->pNext;
12708 memset(prop, 0,
sizeof (ODBCINSTPROPERTY));
12709 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
12710 prop->aPromptData = malloc (
sizeof (instYN));
12711 memcpy(prop->aPromptData, instYN, sizeof (instYN));
12712 strncpy(prop->szName,
"NoWCHAR", INI_MAX_PROPERTY_NAME);
12713 strncpy(prop->szValue,
"No", INI_MAX_PROPERTY_VALUE);
12714
#endif
12715
return 1;
12716 }
12717
12718
#endif