00001
00014 #if defined(SQLITE_HAS_CODEC) && defined(SQLITE_API)
00015 #undef WITH_SQLITE_DLLS
00016 #undef SQLITE_DYNLOAD
00017 #include "sqlite3.c"
00018 #endif
00019
00020 #if defined(WITH_SQLITE_DLLS) && (WITH_SQLITE_DLLS > 1)
00021 #define SQLITE_DYNLOAD 1
00022 #undef HAVE_SQLITE3CLOSEV2
00023 #endif
00024
00025 #include "sqlite3odbc.h"
00026
00027 #ifdef SQLITE_DYNLOAD
00028
00029 #undef MEMORY_DEBUG
00030
00031 #if defined(_WIN32) || defined(_WIN64)
00032 static void dls_init(void);
00033 static void dls_fini(void);
00034 #else
00035 void dls_init(void);
00036 void dls_fini(void);
00037 #endif
00038
00039 static struct dl_sqlite3_funcs {
00040 void (*activate_see)(const char *p0);
00041 int (*bind_blob)(sqlite3_stmt *p0, int p1, const void *p2, int p3,
00042 void (*p4)(void *));
00043 int (*bind_double)(sqlite3_stmt *p0, int p1, double p2);
00044 int (*bind_int)(sqlite3_stmt *p0, int p1, int p2);
00045 int (*bind_int64)(sqlite3_stmt *p0, int p1, sqlite_int64 p2);
00046 int (*bind_null)(sqlite3_stmt *p0, int p1);
00047 int (*bind_parameter_count)(sqlite3_stmt *p0);
00048 int (*bind_text)(sqlite3_stmt *p0, int p1, const char *p2, int p3,
00049 void (*p4)(void *));
00050 int (*busy_handler)(sqlite3 *p0, int (*p2)(void *, int), void *p3);
00051 int (*changes)(sqlite3 *p0);
00052 int (*close)(sqlite3 *p0);
00053 const void * (*column_blob)(sqlite3_stmt *p0, int p1);
00054 int (*column_bytes)(sqlite3_stmt *p0, int p1);
00055 int (*column_count)(sqlite3_stmt *p0);
00056 const char * (*column_database_name)(sqlite3_stmt *p0, int p1);
00057 const char * (*column_decltype)(sqlite3_stmt *p0, int p1);
00058 double (*column_double)(sqlite3_stmt *p0, int p1);
00059 const char * (*column_name)(sqlite3_stmt *p0, int p1);
00060 const char * (*column_origin_name)(sqlite3_stmt *p0, int p1);
00061 const char * (*column_table_name)(sqlite3_stmt *p0, int p1);
00062 const unsigned char * (*column_text)(sqlite3_stmt *p0, int p1);
00063 int (*column_type)(sqlite3_stmt *p0, int p1);
00064 int (*create_function)(sqlite3 *p0, const char *p1, int p2, int p3,
00065 void *p4,
00066 void (*p5)(sqlite3_context *, int, sqlite3_value **),
00067 void (*p6)(sqlite3_context *, int, sqlite3_value **),
00068 void (*p7)(sqlite3_context *));
00069 int (*enable_load_extension)(sqlite3 *p0, int p1);
00070 int (*errcode)(sqlite3 *p0);
00071 const char * (*errmsg)(sqlite3 *p0);
00072 int (*exec)(sqlite3 *p0, const char *p1,
00073 int (*p2)(void *, int, char **, char **),
00074 void *p3, char **p4);
00075 int (*finalize)(sqlite3_stmt *p0);
00076 void (*free)(void *p0);
00077 void (*free_table)(char **p0);
00078 int (*get_table)(sqlite3 *p0, const char *p1, char ***p2,
00079 int *p3, int *p4, char **p5);
00080 void (*interrupt)(sqlite3 *p0);
00081 int (*key)(sqlite3 *p0, const void *p1, int p2);
00082 sqlite_int64 (*last_insert_rowid)(sqlite3 *p0);
00083 const char * (*libversion)(void);
00084 int (*load_extension)(sqlite3 *p0, const char *p1, const char *p2,
00085 char **p3);
00086 void * (*malloc)(int p0);
00087 char * (*mprintf)(const char *p0, ...);
00088 int (*open)(const char *p0, sqlite3 **p1);
00089 int (*open16)(const void *p0, sqlite3 **p1);
00090 int (*open_v2)(const char *p0, sqlite3 **p1, int p2, const char *p3);
00091 int (*prepare)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
00092 const char **p4);
00093 int (*prepare_v2)(sqlite3 *p0, const char *p1, int p2, sqlite3_stmt **p3,
00094 const char **p4);
00095 void * (*profile)(sqlite3 *p0,
00096 void (*p1)(void *, const char *, sqlite3_uint64),
00097 void *p2);
00098 void * (*realloc)(void *p0, int p1);
00099 int (*rekey)(sqlite3 *p0, const void *p1, int p2);
00100 int (*reset)(sqlite3_stmt *p0);
00101 void (*result_blob)(sqlite3_context *p0, const void *p1,
00102 int p2, void (*p3)(void *));
00103 void (*result_error)(sqlite3_context *p0, const char *p1, int p2);
00104 void (*result_int)(sqlite3_context *p0, int p1);
00105 void (*result_null)(sqlite3_context *p0);
00106 int (*step)(sqlite3_stmt *p0);
00107 int (*xstrnicmp)(const char *p0, const char *p1, int p2);
00108 int (*table_column_metadata)(sqlite3 *p0, const char *p1,
00109 const char *p2, const char *p3,
00110 char const **p4, char const **p5,
00111 int *p6, int *p7, int *p8);
00112 void * (*trace)(sqlite3 *p0, void (*p1)(void *, const char *), void *p2);
00113 void * (*user_data)(sqlite3_context *p0);
00114 const void * (*value_blob)(sqlite3_value *p0);
00115 int (*value_bytes)(sqlite3_value *p0);
00116 const unsigned char * (*value_text)(sqlite3_value *p0);
00117 int (*value_type)(sqlite3_value *p0);
00118 } dls_funcs;
00119
00120 #define sqlite3_activate_see dls_funcs.activate_see
00121 #define sqlite3_bind_blob dls_funcs.bind_blob
00122 #define sqlite3_bind_double dls_funcs.bind_double
00123 #define sqlite3_bind_int dls_funcs.bind_int
00124 #define sqlite3_bind_int64 dls_funcs.bind_int64
00125 #define sqlite3_bind_null dls_funcs.bind_null
00126 #define sqlite3_bind_parameter_count dls_funcs.bind_parameter_count
00127 #define sqlite3_bind_text dls_funcs.bind_text
00128 #define sqlite3_busy_handler dls_funcs.busy_handler
00129 #define sqlite3_changes dls_funcs.changes
00130 #define sqlite3_close dls_funcs.close
00131 #define sqlite3_column_blob dls_funcs.column_blob
00132 #define sqlite3_column_bytes dls_funcs.column_bytes
00133 #define sqlite3_column_count dls_funcs.column_count
00134 #define sqlite3_column_database_name dls_funcs.column_database_name
00135 #define sqlite3_column_decltype dls_funcs.column_decltype
00136 #define sqlite3_column_double dls_funcs.column_double
00137 #define sqlite3_column_name dls_funcs.column_name
00138 #define sqlite3_column_origin_name dls_funcs.column_origin_name
00139 #define sqlite3_column_table_name dls_funcs.column_table_name
00140 #define sqlite3_column_text dls_funcs.column_text
00141 #define sqlite3_column_type dls_funcs.column_type
00142 #define sqlite3_create_function dls_funcs.create_function
00143 #define sqlite3_enable_load_extension dls_funcs.enable_load_extension
00144 #define sqlite3_errcode dls_funcs.errcode
00145 #define sqlite3_errmsg dls_funcs.errmsg
00146 #define sqlite3_exec dls_funcs.exec
00147 #define sqlite3_finalize dls_funcs.finalize
00148 #define sqlite3_free dls_funcs.free
00149 #define sqlite3_free_table dls_funcs.free_table
00150 #define sqlite3_get_table dls_funcs.get_table
00151 #define sqlite3_interrupt dls_funcs.interrupt
00152 #define sqlite3_key dls_funcs.key
00153 #define sqlite3_last_insert_rowid dls_funcs.last_insert_rowid
00154 #define sqlite3_libversion dls_funcs.libversion
00155 #define sqlite3_load_extension dls_funcs.load_extension
00156 #define sqlite3_malloc dls_funcs.malloc
00157 #define sqlite3_mprintf dls_funcs.mprintf
00158 #define sqlite3_open dls_funcs.open
00159 #define sqlite3_open16 dls_funcs.open16
00160 #define sqlite3_open_v2 dls_funcs.open_v2
00161 #define sqlite3_prepare dls_funcs.prepare
00162 #define sqlite3_prepare_v2 dls_funcs.prepare_v2
00163 #define sqlite3_profile dls_funcs.profile
00164 #define sqlite3_realloc dls_funcs.realloc
00165 #define sqlite3_rekey dls_funcs.rekey
00166 #define sqlite3_reset dls_funcs.reset
00167 #define sqlite3_result_blob dls_funcs.result_blob
00168 #define sqlite3_result_error dls_funcs.result_error
00169 #define sqlite3_result_int dls_funcs.result_int
00170 #define sqlite3_result_null dls_funcs.result_null
00171 #define sqlite3_step dls_funcs.step
00172 #define sqlite3_strnicmp dls_funcs.xstrnicmp
00173 #define sqlite3_table_column_metadata dls_funcs.table_column_metadata
00174 #define sqlite3_trace dls_funcs.trace
00175 #define sqlite3_user_data dls_funcs.user_data
00176 #define sqlite3_value_blob dls_funcs.value_blob
00177 #define sqlite3_value_bytes dls_funcs.value_bytes
00178 #define sqlite3_value_text dls_funcs.value_text
00179 #define sqlite3_value_type dls_funcs.value_type
00180
00181 #endif
00182
00183 #ifndef WITHOUT_WINTERFACE
00184 #define WINTERFACE
00185 #define WCHARSUPPORT
00186 #endif
00187
00188 #if !defined(_WIN32) && !defined(_WIN64)
00189 #if !defined(WCHARSUPPORT) && defined(HAVE_SQLWCHAR) && (HAVE_SQLWCHAR)
00190 #define WCHARSUPPORT
00191 #endif
00192 #endif
00193
00194 #if defined(WINTERFACE)
00195 #include <sqlucode.h>
00196 #endif
00197
00198 #if defined(_WIN32) || defined(_WIN64)
00199 #include "resource3.h"
00200 #define ODBC_INI "ODBC.INI"
00201 #ifndef DRIVER_VER_INFO
00202 #define DRIVER_VER_INFO VERSION
00203 #endif
00204 #else
00205 #define ODBC_INI ".odbc.ini"
00206 #endif
00207
00208 #ifndef DRIVER_VER_INFO
00209 #define DRIVER_VER_INFO "0.0"
00210 #endif
00211
00212 #ifndef COLATTRIBUTE_LAST_ARG_TYPE
00213 #ifdef _WIN64
00214 #define COLATTRIBUTE_LAST_ARG_TYPE SQLLEN *
00215 #else
00216 #define COLATTRIBUTE_LAST_ARG_TYPE SQLPOINTER
00217 #endif
00218 #endif
00219
00220 #ifndef SETSTMTOPTION_LAST_ARG_TYPE
00221 #define SETSTMTOPTION_LAST_ARG_TYPE SQLROWCOUNT
00222 #endif
00223
00224 #undef min
00225 #define min(a, b) ((a) < (b) ? (a) : (b))
00226 #undef max
00227 #define max(a, b) ((a) < (b) ? (b) : (a))
00228
00229 #ifndef PTRDIFF_T
00230 #define PTRDIFF_T int
00231 #endif
00232
00233 #define array_size(x) (sizeof (x) / sizeof (x[0]))
00234
00235 #define stringify1(s) #s
00236 #define stringify(s) stringify1(s)
00237
00238 #define verinfo(maj, min, lev) ((maj) << 16 | (min) << 8 | (lev))
00239
00240
00241 #undef FULL_METADATA
00242 #if defined(HAVE_SQLITE3TABLECOLUMNMETADATA) && (HAVE_SQLITE3TABLECOLUMNMETADATA)
00243 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
00244 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
00245 #if defined(HAVE_SQLITE3COLUMNORIGINNAME) && (HAVE_SQLITE3COLUMNORIGINNAME)
00246 #define FULL_METADATA 1
00247 #endif
00248 #endif
00249 #endif
00250 #endif
00251
00252
00253
00254 #if defined(WINTERFACE) && !defined(_WIN32) && !defined(_WIN64)
00255 #define SCOL_VARCHAR SQL_WVARCHAR
00256 #define SCOL_CHAR SQL_WCHAR
00257 #else
00258 #define SCOL_VARCHAR SQL_VARCHAR
00259 #define SCOL_CHAR SQL_CHAR
00260 #endif
00261
00262 #define ENV_MAGIC 0x53544145
00263 #define DBC_MAGIC 0x53544144
00264 #define DEAD_MAGIC 0xdeadbeef
00265
00272 typedef struct dstr {
00273 int len;
00274 int max;
00275 int oom;
00276 char buffer[1];
00277 } dstr;
00278
00279 static const char *xdigits = "0123456789ABCDEFabcdef";
00280
00281 #ifdef MEMORY_DEBUG
00282
00283 static void *
00284 xmalloc_(int n, char *file, int line)
00285 {
00286 int nn = n + 4 * sizeof (long);
00287 long *p;
00288
00289 p = malloc(nn);
00290 if (!p) {
00291 #if (MEMORY_DEBUG > 1)
00292 fprintf(stderr, "malloc\t%d\tNULL\t%s:%d\n", n, file, line);
00293 #endif
00294 return NULL;
00295 }
00296 p[0] = 0xdead1234;
00297 nn = nn / sizeof (long) - 1;
00298 p[1] = n;
00299 p[nn] = 0xdead5678;
00300 #if (MEMORY_DEBUG > 1)
00301 fprintf(stderr, "malloc\t%d\t%p\t%s:%d\n", n, &p[2], file, line);
00302 #endif
00303 return (void *) &p[2];
00304 }
00305
00306 static void *
00307 xrealloc_(void *old, int n, char *file, int line)
00308 {
00309 int nn = n + 4 * sizeof (long), nnn;
00310 long *p, *pp;
00311
00312 if (n == 0 || !old) {
00313 return xmalloc_(n, file, line);
00314 }
00315 p = &((long *) old)[-2];
00316 if (p[0] != 0xdead1234) {
00317 fprintf(stderr, "*** low end corruption @ %p\n", old);
00318 abort();
00319 }
00320 nnn = p[1] + 4 * sizeof (long);
00321 nnn = nnn / sizeof (long) - 1;
00322 if (p[nnn] != 0xdead5678) {
00323 fprintf(stderr, "*** high end corruption @ %p\n", old);
00324 abort();
00325 }
00326 pp = realloc(p, nn);
00327 if (!pp) {
00328 #if (MEMORY_DEBUG > 1)
00329 fprintf(stderr, "realloc\t%p,%d\tNULL\t%s:%d\n", old, n, file, line);
00330 #endif
00331 return NULL;
00332 }
00333 #if (MEMORY_DEBUG > 1)
00334 fprintf(stderr, "realloc\t%p,%d\t%p\t%s:%d\n", old, n, &pp[2], file, line);
00335 #endif
00336 p = pp;
00337 p[1] = n;
00338 nn = nn / sizeof (long) - 1;
00339 p[nn] = 0xdead5678;
00340 return (void *) &p[2];
00341 }
00342
00343 static void
00344 xfree_(void *x, char *file, int line)
00345 {
00346 long *p;
00347 int n;
00348
00349 if (!x) {
00350 return;
00351 }
00352 p = &((long *) x)[-2];
00353 if (p[0] != 0xdead1234) {
00354 fprintf(stderr, "*** low end corruption @ %p\n", x);
00355 abort();
00356 }
00357 n = p[1] + 4 * sizeof (long);
00358 n = n / sizeof (long) - 1;
00359 if (p[n] != 0xdead5678) {
00360 fprintf(stderr, "*** high end corruption @ %p\n", x);
00361 abort();
00362 }
00363 #if (MEMORY_DEBUG > 1)
00364 fprintf(stderr, "free\t%p\t\t%s:%d\n", x, file, line);
00365 #endif
00366 free(p);
00367 }
00368
00369 static void
00370 xfree__(void *x)
00371 {
00372 xfree_(x, "unknown location", 0);
00373 }
00374
00375 static char *
00376 xstrdup_(const char *str, char *file, int line)
00377 {
00378 char *p;
00379
00380 if (!str) {
00381 #if (MEMORY_DEBUG > 1)
00382 fprintf(stderr, "strdup\tNULL\tNULL\t%s:%d\n", file, line);
00383 #endif
00384 return NULL;
00385 }
00386 p = xmalloc_(strlen(str) + 1, file, line);
00387 if (p) {
00388 strcpy(p, str);
00389 }
00390 #if (MEMORY_DEBUG > 1)
00391 fprintf(stderr, "strdup\t%p\t%p\t%s:%d\n", str, p, file, line);
00392 #endif
00393 return p;
00394 }
00395
00396 #define xmalloc(x) xmalloc_(x, __FILE__, __LINE__)
00397 #define xrealloc(x,y) xrealloc_(x, y, __FILE__, __LINE__)
00398 #define xfree(x) xfree_(x, __FILE__, __LINE__)
00399 #define xstrdup(x) xstrdup_(x, __FILE__, __LINE__)
00400
00401 #else
00402
00403 #define xmalloc(x) sqlite3_malloc(x)
00404 #define xrealloc(x,y) sqlite3_realloc(x, y)
00405 #define xfree(x) sqlite3_free(x)
00406 #define xstrdup(x) strdup_(x)
00407
00408 #endif
00409
00410 #if defined(_WIN32) || defined(_WIN64)
00411
00412 #define vsnprintf _vsnprintf
00413 #define snprintf _snprintf
00414 #define strcasecmp _stricmp
00415 #define strncasecmp _strnicmp
00416
00417 #ifdef _MSC_VER
00418 #define strtoll _strtoi64
00419 #define strtoull _strtoui64
00420 #endif
00421
00422 static HINSTANCE NEAR hModule;
00423
00424 #endif
00425
00426 #ifdef HAVE_SQLITE3STRNICMP
00427 #undef strncasecmp
00428 #define strncasecmp(A,B,C) sqlite3_strnicmp(A,B,C)
00429 #undef strcasecmp
00430 #define strcasecmp(A,B) strcasecmp_(A,B)
00431
00432 #if defined(__GNUC__) && (__GNUC__ >= 2)
00433 static int strcasecmp_(const char *a, const char *b)
00434 __attribute__((__unused__));
00435 #endif
00436
00437 static int strcasecmp_(const char *a, const char *b)
00438 {
00439 int c = strlen(a), d = strlen(b);
00440
00441 if (c > d) {
00442 return strncasecmp(a, b, c);
00443 }
00444 return strncasecmp(a, b, d);
00445 }
00446 #endif
00447
00448 #if defined(_WIN32) || defined(_WIN64)
00449
00450
00451
00452
00453
00454
00455
00456 #define HDBC_LOCK(hdbc) \
00457 { \
00458 DBC *d; \
00459 \
00460 if ((hdbc) == SQL_NULL_HDBC) { \
00461 return SQL_INVALID_HANDLE; \
00462 } \
00463 d = (DBC *) (hdbc); \
00464 if (d->magic != DBC_MAGIC) { \
00465 return SQL_INVALID_HANDLE; \
00466 } \
00467 EnterCriticalSection(&d->cs); \
00468 d->owner = GetCurrentThreadId(); \
00469 }
00470
00471 #define HDBC_UNLOCK(hdbc) \
00472 if ((hdbc) != SQL_NULL_HDBC) { \
00473 DBC *d; \
00474 \
00475 d = (DBC *) (hdbc); \
00476 if (d->magic == DBC_MAGIC) { \
00477 d->owner = 0; \
00478 LeaveCriticalSection(&d->cs); \
00479 } \
00480 }
00481
00482 #define HSTMT_LOCK(hstmt) \
00483 { \
00484 DBC *d; \
00485 \
00486 if ((hstmt) == SQL_NULL_HSTMT) { \
00487 return SQL_INVALID_HANDLE; \
00488 } \
00489 d = (DBC *) ((STMT *) (hstmt))->dbc; \
00490 if (d->magic != DBC_MAGIC) { \
00491 return SQL_INVALID_HANDLE; \
00492 } \
00493 EnterCriticalSection(&d->cs); \
00494 d->owner = GetCurrentThreadId(); \
00495 }
00496
00497 #define HSTMT_UNLOCK(hstmt) \
00498 if ((hstmt) != SQL_NULL_HSTMT) { \
00499 DBC *d; \
00500 \
00501 d = (DBC *) ((STMT *) (hstmt))->dbc; \
00502 if (d->magic == DBC_MAGIC) { \
00503 d->owner = 0; \
00504 LeaveCriticalSection(&d->cs); \
00505 } \
00506 }
00507
00508 #else
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 #define HDBC_LOCK(hdbc)
00531 #define HDBC_UNLOCK(hdbc)
00532 #define HSTMT_LOCK(hdbc)
00533 #define HSTMT_UNLOCK(hdbc)
00534
00535 #endif
00536
00537 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
00538 extern void nvfs_init(void);
00539 extern const char *nvfs_makevfs(const char *);
00540 #endif
00541
00542
00543
00544
00545
00546 static const char upper_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
00547 static const char lower_chars[] = "abcdefghijklmnopqrstuvwxyz";
00548
00549 static int
00550 TOLOWER(int c)
00551 {
00552 if (c) {
00553 char *p = strchr(upper_chars, c);
00554
00555 if (p) {
00556 c = lower_chars[p - upper_chars];
00557 }
00558 }
00559 return c;
00560 }
00561
00562
00563
00564
00565
00566 static const char digit_chars[] = "0123456789";
00567
00568 #define ISDIGIT(c) \
00569 ((c) && strchr(digit_chars, (c)) != NULL)
00570
00571
00572
00573
00574
00575 static const char space_chars[] = " \f\n\r\t\v";
00576
00577 #define ISSPACE(c) \
00578 ((c) && strchr(space_chars, (c)) != NULL)
00579
00580
00581
00582
00583
00584
00585 static void dbtraceapi(DBC *d, char *fn, const char *sql);
00586 static void freedyncols(STMT *s);
00587 static void freeresult(STMT *s, int clrcols);
00588 static void freerows(char **rowp);
00589 static void unbindcols(STMT *s);
00590 static void s3stmt_drop(STMT *s);
00591
00592 static SQLRETURN drvexecute(SQLHSTMT stmt, int initial);
00593 static SQLRETURN freestmt(HSTMT stmt);
00594 static SQLRETURN mkbindcols(STMT *s, int ncols);
00595 static SQLRETURN setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp);
00596 static SQLRETURN setupparbuf(STMT *s, BINDPARM *p);
00597 static SQLRETURN starttran(STMT *s);
00598 static SQLRETURN setupparam(STMT *s, char *sql, int pnum);
00599 static SQLRETURN getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
00600 SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp,
00601 int partial);
00602
00603 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
00604
00605 static COL *statSpec2P, *statSpec3P;
00606 #endif
00607
00608 #if (MEMORY_DEBUG < 1)
00609
00615 static char *
00616 strdup_(const char *str)
00617 {
00618 char *p = NULL;
00619
00620 if (str) {
00621 p = xmalloc(strlen(str) + 1);
00622 if (p) {
00623 strcpy(p, str);
00624 }
00625 }
00626 return p;
00627 }
00628 #endif
00629
00637 static dstr *
00638 dsappend(dstr *dsp, const char *str)
00639 {
00640 int len;
00641
00642 if (!str) {
00643 return dsp;
00644 }
00645 len = strlen(str);
00646 if (!dsp) {
00647 int max = 256;
00648
00649 if (max < len) {
00650 max += len;
00651 }
00652 dsp = xmalloc(max + sizeof (*dsp));
00653 if (dsp) {
00654 dsp->max = max;
00655 dsp->len = dsp->oom = 0;
00656 goto copy;
00657 }
00658 return dsp;
00659 }
00660 if (dsp->oom) {
00661 return dsp;
00662 }
00663 if (dsp->len + len > dsp->max) {
00664 int max = dsp->max + len + 256;
00665 dstr *ndsp = xrealloc(dsp, max + sizeof (*dsp));
00666
00667 if (!ndsp) {
00668 strcpy(dsp->buffer, "OUT OF MEMORY");
00669 dsp->max = dsp->len = 13;
00670 dsp->oom = 1;
00671 return dsp;
00672 }
00673 dsp = ndsp;
00674 dsp->max = max;
00675 }
00676 copy:
00677 strcpy(dsp->buffer + dsp->len, str);
00678 dsp->len += len;
00679 return dsp;
00680 }
00681
00689 static dstr *
00690 dsappendq(dstr *dsp, const char *str)
00691 {
00692 int len;
00693 const char *p;
00694 char *q;
00695
00696 if (!str) {
00697 return dsp;
00698 }
00699 len = strlen(str);
00700 for (p = str; *p; ++p) {
00701 if (p[0] == '"') {
00702 ++len;
00703 }
00704 }
00705 len += 2;
00706 if (!dsp) {
00707 int max = 256;
00708
00709 if (max < len) {
00710 max += len;
00711 }
00712 dsp = xmalloc(max + sizeof (*dsp));
00713 if (dsp) {
00714 dsp->max = max;
00715 dsp->len = dsp->oom = 0;
00716 goto copy;
00717 }
00718 return dsp;
00719 }
00720 if (dsp->oom) {
00721 return dsp;
00722 }
00723 if (dsp->len + len > dsp->max) {
00724 int max = dsp->max + len + 256;
00725 dstr *ndsp = xrealloc(dsp, max + sizeof (*dsp));
00726
00727 if (!ndsp) {
00728 strcpy(dsp->buffer, "OUT OF MEMORY");
00729 dsp->max = dsp->len = 13;
00730 dsp->oom = 1;
00731 return dsp;
00732 }
00733 dsp = ndsp;
00734 dsp->max = max;
00735 }
00736 copy:
00737 q = dsp->buffer + dsp->len;
00738 *q++ = '"';
00739 for (p = str; *p; ++p) {
00740 *q++ = *p;
00741 if (p[0] == '"') {
00742 *q++ = '"';
00743 }
00744 }
00745 *q++ = '"';
00746 *q = '\0';
00747 dsp->len += len;
00748 return dsp;
00749 }
00750
00757 static const char *
00758 dsval(dstr *dsp)
00759 {
00760 if (dsp) {
00761 return (const char *) dsp->buffer;
00762 }
00763 return "ERROR";
00764 }
00765
00772 static int
00773 dserr(dstr *dsp)
00774 {
00775 return !dsp || dsp->oom;
00776 }
00777
00783 static void
00784 dsfree(dstr *dsp)
00785 {
00786 if (dsp) {
00787 xfree(dsp);
00788 }
00789 }
00790
00791 #ifdef WCHARSUPPORT
00792
00799 static int
00800 uc_strlen(SQLWCHAR *str)
00801 {
00802 int len = 0;
00803
00804 if (str) {
00805 while (*str) {
00806 ++len;
00807 ++str;
00808 }
00809 }
00810 return len;
00811 }
00812
00821 static SQLWCHAR *
00822 uc_strncpy(SQLWCHAR *dest, SQLWCHAR *src, int len)
00823 {
00824 int i = 0;
00825
00826 while (i < len) {
00827 if (!src[i]) {
00828 break;
00829 }
00830 dest[i] = src[i];
00831 ++i;
00832 }
00833 if (i < len) {
00834 dest[i] = 0;
00835 }
00836 return dest;
00837 }
00838
00847 static void
00848 uc_from_utf_buf(unsigned char *str, int len, SQLWCHAR *uc, int ucLen)
00849 {
00850 ucLen = ucLen / sizeof (SQLWCHAR);
00851 if (!uc || ucLen < 0) {
00852 return;
00853 }
00854 if (len < 0) {
00855 len = ucLen * 5;
00856 }
00857 uc[0] = 0;
00858 if (str) {
00859 int i = 0;
00860
00861 while (i < len && *str && i < ucLen) {
00862 unsigned char c = str[0];
00863
00864 if (c < 0x80) {
00865 uc[i++] = c;
00866 ++str;
00867 } else if (c <= 0xc1 || c >= 0xf5) {
00868
00869 ++str;
00870 } else if (c < 0xe0) {
00871 if ((str[1] & 0xc0) == 0x80) {
00872 unsigned long t = ((c & 0x1f) << 6) | (str[1] & 0x3f);
00873
00874 uc[i++] = t;
00875 str += 2;
00876 } else {
00877 uc[i++] = c;
00878 ++str;
00879 }
00880 } else if (c < 0xf0) {
00881 if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80) {
00882 unsigned long t = ((c & 0x0f) << 12) |
00883 ((str[1] & 0x3f) << 6) | (str[2] & 0x3f);
00884
00885 uc[i++] = t;
00886 str += 3;
00887 } else {
00888 uc[i++] = c;
00889 ++str;
00890 }
00891 } else if (c < 0xf8) {
00892 if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
00893 (str[3] & 0xc0) == 0x80) {
00894 unsigned long t = ((c & 0x03) << 18) |
00895 ((str[1] & 0x3f) << 12) | ((str[2] & 0x3f) << 6) |
00896 (str[3] & 0x3f);
00897
00898 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
00899 t >= 0x10000) {
00900 t -= 0x10000;
00901 uc[i++] = 0xd800 | ((t >> 10) & 0x3ff);
00902 if (i >= ucLen) {
00903 break;
00904 }
00905 t = 0xdc00 | (t & 0x3ff);
00906 }
00907 uc[i++] = t;
00908 str += 4;
00909 } else {
00910 uc[i++] = c;
00911 ++str;
00912 }
00913 } else {
00914
00915 ++str;
00916 }
00917 }
00918 if (i < ucLen) {
00919 uc[i] = 0;
00920 }
00921 }
00922 }
00923
00931 static SQLWCHAR *
00932 uc_from_utf(unsigned char *str, int len)
00933 {
00934 SQLWCHAR *uc = NULL;
00935 int ucLen;
00936
00937 if (str) {
00938 if (len == SQL_NTS) {
00939 len = strlen((char *) str);
00940 }
00941 ucLen = sizeof (SQLWCHAR) * (len + 1);
00942 uc = xmalloc(ucLen);
00943 if (uc) {
00944 uc_from_utf_buf(str, len, uc, ucLen);
00945 }
00946 }
00947 return uc;
00948 }
00949
00957 static char *
00958 uc_to_utf(SQLWCHAR *str, int len)
00959 {
00960 int i;
00961 char *cp, *ret = NULL;
00962
00963 if (!str) {
00964 return ret;
00965 }
00966 if (len == SQL_NTS) {
00967 len = uc_strlen(str);
00968 } else {
00969 len = len / sizeof (SQLWCHAR);
00970 }
00971 cp = xmalloc(len * 6 + 1);
00972 if (!cp) {
00973 return ret;
00974 }
00975 ret = cp;
00976 for (i = 0; i < len; i++) {
00977 unsigned long c = str[i];
00978
00979 if (sizeof (SQLWCHAR) == 2 * sizeof (char)) {
00980 c &= 0xffff;
00981 }
00982 if (c < 0x80) {
00983 *cp++ = c;
00984 } else if (c < 0x800) {
00985 *cp++ = 0xc0 | ((c >> 6) & 0x1f);
00986 *cp++ = 0x80 | (c & 0x3f);
00987 } else if (c < 0x10000) {
00988 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
00989 c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
00990 unsigned long c2 = str[i + 1] & 0xffff;
00991
00992 if (c2 >= 0xdc00 && c2 <= 0xdfff) {
00993 c = (((c & 0x3ff) << 10) | (c2 & 0x3ff)) + 0x10000;
00994 *cp++ = 0xf0 | ((c >> 18) & 0x07);
00995 *cp++ = 0x80 | ((c >> 12) & 0x3f);
00996 *cp++ = 0x80 | ((c >> 6) & 0x3f);
00997 *cp++ = 0x80 | (c & 0x3f);
00998 ++i;
00999 continue;
01000 }
01001 }
01002 *cp++ = 0xe0 | ((c >> 12) & 0x0f);
01003 *cp++ = 0x80 | ((c >> 6) & 0x3f);
01004 *cp++ = 0x80 | (c & 0x3f);
01005 } else if (c <= 0x10ffff) {
01006 *cp++ = 0xf0 | ((c >> 18) & 0x07);
01007 *cp++ = 0x80 | ((c >> 12) & 0x3f);
01008 *cp++ = 0x80 | ((c >> 6) & 0x3f);
01009 *cp++ = 0x80 | (c & 0x3f);
01010 }
01011 }
01012 *cp = '\0';
01013 return ret;
01014 }
01015
01016 #endif
01017
01018 #ifdef WINTERFACE
01019
01027 static char *
01028 uc_to_utf_c(SQLWCHAR *str, int len)
01029 {
01030 if (len != SQL_NTS) {
01031 len = len * sizeof (SQLWCHAR);
01032 }
01033 return uc_to_utf(str, len);
01034 }
01035
01036 #endif
01037
01038 #if defined(WCHARSUPPORT) || defined(_WIN32) || defined(_WIN64)
01039
01045 static void
01046 uc_free(void *str)
01047 {
01048 if (str) {
01049 xfree(str);
01050 }
01051 }
01052
01053 #endif
01054
01055 #if defined(_WIN32) || defined(_WIN64)
01056
01064 static char *
01065 wmb_to_utf(char *str, int len)
01066 {
01067 WCHAR *wstr;
01068 OSVERSIONINFO ovi;
01069 int nchar, is2k, cp = CP_OEMCP;
01070
01071 ovi.dwOSVersionInfoSize = sizeof (ovi);
01072 GetVersionEx(&ovi);
01073 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01074 if (AreFileApisANSI()) {
01075 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01076 }
01077 nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
01078 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
01079 if (!wstr) {
01080 return NULL;
01081 }
01082 wstr[0] = 0;
01083 nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
01084 wstr[nchar] = 0;
01085 str = xmalloc((nchar + 1) * 7);
01086 if (!str) {
01087 xfree(wstr);
01088 return NULL;
01089 }
01090 str[0] = '\0';
01091 nchar = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, nchar * 7, 0, 0);
01092 str[nchar] = '\0';
01093 xfree(wstr);
01094 return str;
01095 }
01096
01097 #ifndef WINTERFACE
01098
01106 static char *
01107 wmb_to_utf_c(char *str, int len)
01108 {
01109 if (len == SQL_NTS) {
01110 len = strlen(str);
01111 }
01112 return wmb_to_utf(str, len);
01113 }
01114
01115 #endif
01116
01124 static char *
01125 utf_to_wmb(char *str, int len)
01126 {
01127 WCHAR *wstr;
01128 OSVERSIONINFO ovi;
01129 int nchar, is2k, cp = CP_OEMCP;
01130
01131 ovi.dwOSVersionInfoSize = sizeof (ovi);
01132 GetVersionEx(&ovi);
01133 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01134 if (AreFileApisANSI()) {
01135 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01136 }
01137 nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
01138 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
01139 if (!wstr) {
01140 return NULL;
01141 }
01142 wstr[0] = 0;
01143 nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, wstr, nchar);
01144 wstr[nchar] = 0;
01145 str = xmalloc((nchar + 1) * 7);
01146 if (!str) {
01147 xfree(wstr);
01148 return NULL;
01149 }
01150 str[0] = '\0';
01151 nchar = WideCharToMultiByte(cp, 0, wstr, -1, str, nchar * 7, 0, 0);
01152 str[nchar] = '\0';
01153 xfree(wstr);
01154 return str;
01155 }
01156
01157 #ifdef WINTERFACE
01158
01166 static WCHAR *
01167 wmb_to_uc(char *str, int len)
01168 {
01169 WCHAR *wstr;
01170 OSVERSIONINFO ovi;
01171 int nchar, is2k, cp = CP_OEMCP;
01172
01173 ovi.dwOSVersionInfoSize = sizeof (ovi);
01174 GetVersionEx(&ovi);
01175 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01176 if (AreFileApisANSI()) {
01177 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01178 }
01179 nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
01180 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
01181 if (!wstr) {
01182 return NULL;
01183 }
01184 wstr[0] = 0;
01185 nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
01186 wstr[nchar] = 0;
01187 return wstr;
01188 }
01189
01197 static char *
01198 uc_to_wmb(WCHAR *wstr, int len)
01199 {
01200 char *str;
01201 OSVERSIONINFO ovi;
01202 int nchar, is2k, cp = CP_OEMCP;
01203
01204 ovi.dwOSVersionInfoSize = sizeof (ovi);
01205 GetVersionEx(&ovi);
01206 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01207 if (AreFileApisANSI()) {
01208 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01209 }
01210 nchar = WideCharToMultiByte(cp, 0, wstr, len, NULL, 0, 0, 0);
01211 str = xmalloc((nchar + 1) * 2);
01212 if (!str) {
01213 return NULL;
01214 }
01215 str[0] = '\0';
01216 nchar = WideCharToMultiByte(cp, 0, wstr, len, str, nchar * 2, 0, 0);
01217 str[nchar] = '\0';
01218 return str;
01219 }
01220
01221 #endif
01222
01223 #endif
01224
01225
01226 #ifdef USE_DLOPEN_FOR_GPPS
01227
01228 #include <dlfcn.h>
01229
01230 #define SQLGetPrivateProfileString(A,B,C,D,E,F) drvgpps(d,A,B,C,D,E,F)
01231
01232
01233
01234
01235
01236
01237
01238
01239 static void
01240 drvgetgpps(DBC *d)
01241 {
01242 void *lib;
01243 int (*gpps)();
01244
01245 lib = dlopen("libodbcinst.so.2", RTLD_LAZY);
01246 if (!lib) {
01247 lib = dlopen("libodbcinst.so.1", RTLD_LAZY);
01248 }
01249 if (!lib) {
01250 lib = dlopen("libodbcinst.so", RTLD_LAZY);
01251 }
01252 if (!lib) {
01253 lib = dlopen("libiodbcinst.so.2", RTLD_LAZY);
01254 }
01255 if (!lib) {
01256 lib = dlopen("libiodbcinst.so", RTLD_LAZY);
01257 }
01258 if (lib) {
01259 gpps = (int (*)()) dlsym(lib, "SQLGetPrivateProfileString");
01260 if (!gpps) {
01261 dlclose(lib);
01262 return;
01263 }
01264 d->instlib = lib;
01265 d->gpps = gpps;
01266 }
01267 }
01268
01269 static void
01270 drvrelgpps(DBC *d)
01271 {
01272 if (d->instlib) {
01273 dlclose(d->instlib);
01274 d->instlib = 0;
01275 }
01276 }
01277
01278 static int
01279 drvgpps(DBC *d, char *sect, char *ent, char *def, char *buf,
01280 int bufsiz, char *fname)
01281 {
01282 if (d->gpps) {
01283 return d->gpps(sect, ent, def, buf, bufsiz, fname);
01284 }
01285 strncpy(buf, def, bufsiz);
01286 buf[bufsiz - 1] = '\0';
01287 return 1;
01288 }
01289 #else
01290 #include <odbcinst.h>
01291 #define drvgetgpps(d)
01292 #define drvrelgpps(d)
01293 #endif
01294
01295
01296
01297
01298
01299 static void
01300 s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
01301 {
01302 int i;
01303
01304 if (stmt && p && nparams > 0) {
01305 for (i = 0; i < nparams; i++, p++) {
01306 switch (p->s3type) {
01307 default:
01308 case SQLITE_NULL:
01309 sqlite3_bind_null(stmt, i + 1);
01310 if (d->trace) {
01311 fprintf(d->trace, "-- parameter %d: NULL\n", i + 1);
01312 fflush(d->trace);
01313 }
01314 break;
01315 case SQLITE_TEXT:
01316 sqlite3_bind_text(stmt, i + 1, p->s3val, p->s3size,
01317 SQLITE_STATIC);
01318 if (d->trace) {
01319 fprintf(d->trace, "-- parameter %d: '%*s'\n", i + 1,
01320 p->s3size, (char *) p->s3val);
01321 fflush(d->trace);
01322 }
01323 break;
01324 case SQLITE_BLOB:
01325 sqlite3_bind_blob(stmt, i + 1, p->s3val, p->s3size,
01326 SQLITE_STATIC);
01327 if (d->trace) {
01328 fprintf(d->trace, "-- parameter %d: [BLOB]'\n", i + 1);
01329 fflush(d->trace);
01330 }
01331 break;
01332 case SQLITE_FLOAT:
01333 sqlite3_bind_double(stmt, i + 1, p->s3dval);
01334 if (d->trace) {
01335 fprintf(d->trace, "-- parameter %d: %g\n",
01336 i + 1, p->s3dval);
01337 fflush(d->trace);
01338 }
01339 break;
01340 case SQLITE_INTEGER:
01341 if (p->s3size > sizeof (int)) {
01342 sqlite3_bind_int64(stmt, i + 1, p->s3lival);
01343 if (d->trace) {
01344 fprintf(d->trace,
01345 #ifdef _WIN32
01346 "-- parameter %d: %I64d\n",
01347 #else
01348 "-- parameter %d: %lld\n",
01349 #endif
01350 i + 1, p->s3lival);
01351 fflush(d->trace);
01352 }
01353 } else {
01354 sqlite3_bind_int(stmt, i + 1, p->s3ival);
01355 if (d->trace) {
01356 fprintf(d->trace, "-- parameter %d: %d\n",
01357 i + 1, p->s3ival);
01358 fflush(d->trace);
01359 }
01360 }
01361 break;
01362 }
01363 }
01364 }
01365 }
01366
01374 typedef struct tblres {
01375 char **resarr;
01376 char *errmsg;
01377 sqlite3_stmt *stmt;
01378 STMT *s;
01379 int nalloc;
01380 int nrow;
01381 int ncol;
01382 PTRDIFF_T ndata;
01383 int rc;
01384 } TBLRES;
01385
01386
01387
01388
01389
01390
01391 static int
01392 drvgettable_row(TBLRES *t, int ncol, int rc)
01393 {
01394 int need;
01395 int i;
01396 char *p;
01397
01398 if (t->nrow == 0 && rc == SQLITE_ROW) {
01399 need = ncol * 2;
01400 } else {
01401 need = ncol;
01402 }
01403 if (t->ndata + need >= t->nalloc) {
01404 char **resnew;
01405 int nalloc = t->nalloc * 2 + need + 1;
01406
01407 if (nalloc < t->nalloc) {
01408 goto nomem;
01409 }
01410 resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
01411 if (!resnew) {
01412 nomem:
01413 t->rc = SQLITE_NOMEM;
01414 return 1;
01415 }
01416 t->nalloc = nalloc;
01417 t->resarr = resnew;
01418 }
01419
01420 if (t->nrow == 0) {
01421 t->ncol = ncol;
01422 for (i = 0; i < ncol; i++) {
01423 p = (char *) sqlite3_column_name(t->stmt, i);
01424 if (p) {
01425 char *q = xmalloc(strlen(p) + 1);
01426
01427 if (!q) {
01428 goto nomem;
01429 }
01430 strcpy(q, p);
01431 p = q;
01432 }
01433 t->resarr[t->ndata++] = p;
01434 }
01435 if (t->s && t->s->guessed_types) {
01436 int ncol2 = ncol;
01437
01438 setupdyncols(t->s, t->stmt, &ncol2);
01439 t->s->guessed_types = 0;
01440 t->s->ncols = ncol;
01441 }
01442 } else if (t->ncol != ncol) {
01443 t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
01444 " more incompatible queries");
01445 t->rc = SQLITE_ERROR;
01446 return 1;
01447 }
01448
01449 if (rc == SQLITE_ROW) {
01450 for (i = 0; i < ncol; i++) {
01451 int coltype = sqlite3_column_type(t->stmt, i);
01452
01453 p = NULL;
01454 if (coltype == SQLITE_BLOB) {
01455 int k, nbytes = sqlite3_column_bytes(t->stmt, i);
01456 char *qp;
01457 unsigned const char *bp;
01458
01459 bp = sqlite3_column_blob(t->stmt, i);
01460 qp = xmalloc(nbytes * 2 + 4);
01461 if (!qp) {
01462 goto nomem;
01463 }
01464 p = qp;
01465 *qp++ = 'X';
01466 *qp++ = '\'';
01467 for (k = 0; k < nbytes; k++) {
01468 *qp++ = xdigits[(bp[k] >> 4)];
01469 *qp++ = xdigits[(bp[k] & 0xF)];
01470 }
01471 *qp++ = '\'';
01472 *qp = '\0';
01473 #ifdef _MSC_VER
01474 } else if (coltype == SQLITE_FLOAT) {
01475 struct lconv *lc = 0;
01476 double val = sqlite3_column_double(t->stmt, i);
01477 char buffer[128];
01478
01479
01480
01481
01482
01483
01484 snprintf(buffer, sizeof (buffer), "%.15g", val);
01485 lc = localeconv();
01486 if (lc && lc->decimal_point && lc->decimal_point[0] &&
01487 lc->decimal_point[0] != '.') {
01488 p = strchr(buffer, lc->decimal_point[0]);
01489 if (p) {
01490 *p = '.';
01491 }
01492 }
01493 p = xstrdup(buffer);
01494 if (!p) {
01495 goto nomem;
01496 }
01497 #endif
01498 } else if (coltype != SQLITE_NULL) {
01499 p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
01500 if (!p) {
01501 goto nomem;
01502 }
01503 }
01504 t->resarr[t->ndata++] = p;
01505 }
01506 t->nrow++;
01507 }
01508 return 0;
01509 }
01510
01511 static int
01512 drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
01513 int *ncolp, char **errp, int nparam, BINDPARM *p)
01514 {
01515 DBC *d = (DBC *) s->dbc;
01516 int rc = SQLITE_OK, keep = sql == NULL;
01517 TBLRES tres;
01518 const char *sqlleft = 0;
01519 int nretry = 0, haveerr = 0;
01520
01521 if (!resp) {
01522 return SQLITE_ERROR;
01523 }
01524 *resp = NULL;
01525 if (nrowp) {
01526 *nrowp = 0;
01527 }
01528 if (ncolp) {
01529 *ncolp = 0;
01530 }
01531 tres.errmsg = NULL;
01532 tres.nrow = 0;
01533 tres.ncol = 0;
01534 tres.ndata = 1;
01535 tres.nalloc = 20;
01536 tres.rc = SQLITE_OK;
01537 tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
01538 tres.stmt = NULL;
01539 tres.s = s;
01540 if (!tres.resarr) {
01541 return SQLITE_NOMEM;
01542 }
01543 tres.resarr[0] = 0;
01544 if (sql == NULL) {
01545 tres.stmt = s->s3stmt;
01546 if (tres.stmt == NULL) {
01547 return SQLITE_NOMEM;
01548 }
01549 goto retrieve;
01550 }
01551 while (sql && *sql && (rc == SQLITE_OK ||
01552 (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
01553 int ncol;
01554
01555 tres.stmt = NULL;
01556 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
01557 dbtraceapi(d, "sqlite3_prepare_v2", sql);
01558 rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
01559 #else
01560 dbtraceapi(d, "sqlite3_prepare", sql);
01561 rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
01562 #endif
01563 if (rc != SQLITE_OK) {
01564 if (tres.stmt) {
01565 dbtraceapi(d, "sqlite3_finalize", 0);
01566 sqlite3_finalize(tres.stmt);
01567 tres.stmt = NULL;
01568 }
01569 continue;
01570 }
01571 if (!tres.stmt) {
01572
01573 sql = sqlleft;
01574 continue;
01575 }
01576 retrieve:
01577 if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
01578 if (errp) {
01579 *errp =
01580 sqlite3_mprintf("%s", "parameter marker count incorrect");
01581 }
01582 haveerr = 1;
01583 rc = SQLITE_ERROR;
01584 goto tbldone;
01585 }
01586 s3bind(d, tres.stmt, nparam, p);
01587 ncol = sqlite3_column_count(tres.stmt);
01588 while (1) {
01589 if (s->max_rows && tres.nrow >= s->max_rows) {
01590 rc = SQLITE_OK;
01591 break;
01592 }
01593 rc = sqlite3_step(tres.stmt);
01594 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
01595 if (drvgettable_row(&tres, ncol, rc)) {
01596 rc = SQLITE_ABORT;
01597 goto tbldone;
01598 }
01599 }
01600 if (rc != SQLITE_ROW) {
01601 if (keep) {
01602 dbtraceapi(d, "sqlite3_reset", 0);
01603 rc = sqlite3_reset(tres.stmt);
01604 s->s3stmt_noreset = 1;
01605 } else {
01606 dbtraceapi(d, "sqlite3_finalize", 0);
01607 rc = sqlite3_finalize(tres.stmt);
01608 }
01609 tres.stmt = 0;
01610 if (rc != SQLITE_SCHEMA) {
01611 nretry = 0;
01612 sql = sqlleft;
01613 while (sql && ISSPACE(*sql)) {
01614 sql++;
01615 }
01616 }
01617 if (rc == SQLITE_DONE) {
01618 rc = SQLITE_OK;
01619 }
01620 break;
01621 }
01622 }
01623 }
01624 tbldone:
01625 if (tres.stmt) {
01626 if (keep) {
01627 if (!s->s3stmt_noreset) {
01628 dbtraceapi(d, "sqlite3_reset", 0);
01629 sqlite3_reset(tres.stmt);
01630 s->s3stmt_noreset = 1;
01631 }
01632 } else {
01633 dbtraceapi(d, "sqlite3_finalize", 0);
01634 sqlite3_finalize(tres.stmt);
01635 }
01636 }
01637 if (haveerr) {
01638
01639 } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
01640 *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
01641 } else if (errp) {
01642 *errp = NULL;
01643 }
01644 if (tres.resarr) {
01645 tres.resarr[0] = (char *) (tres.ndata - 1);
01646 }
01647 if (rc == SQLITE_ABORT) {
01648 freerows(&tres.resarr[1]);
01649 if (tres.errmsg) {
01650 if (errp) {
01651 if (*errp) {
01652 sqlite3_free(*errp);
01653 }
01654 *errp = tres.errmsg;
01655 } else {
01656 sqlite3_free(tres.errmsg);
01657 }
01658 }
01659 return tres.rc;
01660 }
01661 sqlite3_free(tres.errmsg);
01662 if (rc != SQLITE_OK) {
01663 freerows(&tres.resarr[1]);
01664 return rc;
01665 }
01666 *resp = &tres.resarr[1];
01667 if (ncolp) {
01668 *ncolp = tres.ncol;
01669 }
01670 if (nrowp) {
01671 *nrowp = tres.nrow;
01672 }
01673 return rc;
01674 }
01675
01684 #if defined(__GNUC__) && (__GNUC__ >= 2)
01685 static void setstatd(DBC *, int, char *, char *, ...)
01686 __attribute__((format (printf, 3, 5)));
01687 #endif
01688
01689 static void
01690 setstatd(DBC *d, int naterr, char *msg, char *st, ...)
01691 {
01692 va_list ap;
01693
01694 if (!d) {
01695 return;
01696 }
01697 d->naterr = naterr;
01698 d->logmsg[0] = '\0';
01699 if (msg) {
01700 int count;
01701
01702 va_start(ap, st);
01703 count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
01704 va_end(ap);
01705 if (count < 0) {
01706 d->logmsg[sizeof (d->logmsg) - 1] = '\0';
01707 }
01708 }
01709 if (!st) {
01710 st = "?????";
01711 }
01712 strncpy(d->sqlstate, st, 5);
01713 d->sqlstate[5] = '\0';
01714 }
01715
01724 #if defined(__GNUC__) && (__GNUC__ >= 2)
01725 static void setstat(STMT *, int, char *, char *, ...)
01726 __attribute__((format (printf, 3, 5)));
01727 #endif
01728
01729 static void
01730 setstat(STMT *s, int naterr, char *msg, char *st, ...)
01731 {
01732 va_list ap;
01733
01734 if (!s) {
01735 return;
01736 }
01737 s->naterr = naterr;
01738 s->logmsg[0] = '\0';
01739 if (msg) {
01740 int count;
01741
01742 va_start(ap, st);
01743 count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
01744 va_end(ap);
01745 if (count < 0) {
01746 s->logmsg[sizeof (s->logmsg) - 1] = '\0';
01747 }
01748 }
01749 if (!st) {
01750 st = "?????";
01751 }
01752 strncpy(s->sqlstate, st, 5);
01753 s->sqlstate[5] = '\0';
01754 }
01755
01762 static SQLRETURN
01763 drvunimpldbc(HDBC dbc)
01764 {
01765 DBC *d;
01766
01767 if (dbc == SQL_NULL_HDBC) {
01768 return SQL_INVALID_HANDLE;
01769 }
01770 d = (DBC *) dbc;
01771 setstatd(d, -1, "not supported", "IM001");
01772 return SQL_ERROR;
01773 }
01774
01781 static SQLRETURN
01782 drvunimplstmt(HSTMT stmt)
01783 {
01784 STMT *s;
01785
01786 if (stmt == SQL_NULL_HSTMT) {
01787 return SQL_INVALID_HANDLE;
01788 }
01789 s = (STMT *) stmt;
01790 setstat(s, -1, "not supported", "IM001");
01791 return SQL_ERROR;
01792 }
01793
01799 static void
01800 freep(void *x)
01801 {
01802 if (x && ((char **) x)[0]) {
01803 xfree(((char **) x)[0]);
01804 ((char **) x)[0] = NULL;
01805 }
01806 }
01807
01814 static SQLRETURN
01815 nomem(STMT *s)
01816 {
01817 setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
01818 return SQL_ERROR;
01819 }
01820
01827 static SQLRETURN
01828 noconn(STMT *s)
01829 {
01830 setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
01831 return SQL_ERROR;
01832 }
01833
01841 #if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
01842
01843 static double
01844 ln_strtod(const char *data, char **endp)
01845 {
01846 struct lconv *lc = 0;
01847 char buf[128], *p, *end;
01848 double value;
01849
01850 lc = localeconv();
01851 if (lc && lc->decimal_point && lc->decimal_point[0] &&
01852 lc->decimal_point[0] != '.') {
01853 strncpy(buf, data, sizeof (buf) - 1);
01854 buf[sizeof (buf) - 1] = '\0';
01855 p = strchr(buf, '.');
01856 if (p) {
01857 *p = lc->decimal_point[0];
01858 }
01859 p = buf;
01860 } else {
01861 p = (char *) data;
01862 }
01863 value = strtod(p, &end);
01864 end = (char *) data + (end - p);
01865 if (endp) {
01866 *endp = end;
01867 }
01868 return value;
01869 }
01870
01871 #else
01872
01873 #define ln_strtod(A,B) strtod(A,B)
01874
01875 #endif
01876
01882 static char *
01883 unquote(char *str)
01884 {
01885 if (str) {
01886 int len = strlen(str);
01887
01888 if (len > 1) {
01889 int end = len - 1;
01890
01891 if ((str[0] == '\'' && str[end] == '\'') ||
01892 (str[0] == '"' && str[end] == '"') ||
01893 (str[0] == '[' && str[end] == ']')) {
01894 memmove(str, str + 1, end - 1);
01895 str[end - 1] = '\0';
01896 }
01897 }
01898 }
01899 return str;
01900 }
01901
01909 static int
01910 unescpat(char *str)
01911 {
01912 char *p, *q;
01913 int count = 0;
01914
01915 p = str;
01916 while ((q = strchr(p, '_')) != NULL) {
01917 if (q == str || q[-1] != '\\') {
01918 count++;
01919 }
01920 p = q + 1;
01921 }
01922 p = str;
01923 while ((q = strchr(p, '%')) != NULL) {
01924 if (q == str || q[-1] != '\\') {
01925 count++;
01926 }
01927 p = q + 1;
01928 }
01929 p = str;
01930 while ((q = strchr(p, '\\')) != NULL) {
01931 if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
01932 memmove(q, q + 1, strlen(q));
01933 }
01934 p = q + 1;
01935 }
01936 return count;
01937 }
01938
01947 static int
01948 namematch(char *str, char *pat, int esc)
01949 {
01950 int cp, ch;
01951
01952 while (1) {
01953 cp = TOLOWER(*pat);
01954 if (cp == '\0') {
01955 if (*str != '\0') {
01956 goto nomatch;
01957 }
01958 break;
01959 }
01960 if (*str == '\0' && cp != '%') {
01961 goto nomatch;
01962 }
01963 if (cp == '%') {
01964 while (*pat == '%') {
01965 ++pat;
01966 }
01967 cp = TOLOWER(*pat);
01968 if (cp == '\0') {
01969 break;
01970 }
01971 while (1) {
01972 if (cp != '_' && cp != '\\') {
01973 while (*str) {
01974 ch = TOLOWER(*str);
01975 if (ch == cp) {
01976 break;
01977 }
01978 ++str;
01979 }
01980 }
01981 if (namematch(str, pat, esc)) {
01982 goto match;
01983 }
01984 if (*str == '\0') {
01985 goto nomatch;
01986 }
01987 ch = TOLOWER(*str);
01988 ++str;
01989 }
01990 }
01991 if (cp == '_') {
01992 pat++;
01993 str++;
01994 continue;
01995 }
01996 if (esc && cp == '\\' &&
01997 (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
01998 ++pat;
01999 cp = TOLOWER(*pat);
02000 }
02001 ch = TOLOWER(*str++);
02002 ++pat;
02003 if (ch != cp) {
02004 goto nomatch;
02005 }
02006 }
02007 match:
02008 return 1;
02009 nomatch:
02010 return 0;
02011 }
02012
02020 static int
02021 busy_handler(void *udata, int count)
02022 {
02023 DBC *d = (DBC *) udata;
02024 long t1;
02025 int ret = 0;
02026 #if !defined(_WIN32) && !defined(_WIN64)
02027 struct timeval tv;
02028 #ifdef HAVE_NANOSLEEP
02029 struct timespec ts;
02030 #endif
02031 #endif
02032
02033 if (d->busyint) {
02034 d->busyint = 0;
02035 return ret;
02036 }
02037 if (d->timeout <= 0) {
02038 return ret;
02039 }
02040 if (count <= 1) {
02041 #if defined(_WIN32) || defined(_WIN64)
02042 d->t0 = GetTickCount();
02043 #else
02044 gettimeofday(&tv, NULL);
02045 d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
02046 #endif
02047 }
02048 #if defined(_WIN32) || defined(_WIN64)
02049 t1 = GetTickCount();
02050 #else
02051 gettimeofday(&tv, NULL);
02052 t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
02053 #endif
02054 if (t1 - d->t0 > d->timeout) {
02055 goto done;
02056 }
02057 #if defined(_WIN32) || defined(_WIN64)
02058 Sleep(10);
02059 #else
02060 #ifdef HAVE_NANOSLEEP
02061 ts.tv_sec = 0;
02062 ts.tv_nsec = 10000000;
02063 do {
02064 ret = nanosleep(&ts, &ts);
02065 if (ret < 0 && errno != EINTR) {
02066 ret = 0;
02067 }
02068 } while (ret);
02069 #else
02070 #ifdef HAVE_USLEEP
02071 usleep(10000);
02072 #else
02073 tv.tv_sec = 0;
02074 tv.tv_usec = 10000;
02075 select(0, NULL, NULL, NULL, &tv);
02076 #endif
02077 #endif
02078 #endif
02079 ret = 1;
02080 done:
02081 return ret;
02082 }
02083
02095 static int
02096 setsqliteopts(sqlite3 *x, DBC *d)
02097 {
02098 int count = 0, step = 0, max, rc = SQLITE_ERROR;
02099
02100 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
02101 max = d->longnames ? 3 : 1;
02102 #else
02103 max = 3;
02104 #endif
02105 if (d->shortnames) {
02106 max = 3;
02107 }
02108 while (step < max) {
02109 if (step < 1) {
02110 rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
02111 NULL, NULL, NULL);
02112 if (rc == SQLITE_OK) {
02113 rc = sqlite3_exec(x, d->fksupport ?
02114 "PRAGMA foreign_keys = on;" :
02115 "PRAGMA foreign_keys = off;",
02116 NULL, NULL, NULL);
02117 }
02118 } else if (step < 2) {
02119 rc = sqlite3_exec(x, d->shortnames ?
02120 "PRAGMA full_column_names = off;" :
02121 "PRAGMA full_column_names = on;",
02122 NULL, NULL, NULL);
02123 } else if (step < 3) {
02124 rc = sqlite3_exec(x, d->shortnames ?
02125 "PRAGMA short_column_names = on;" :
02126 "PRAGMA short_column_names = off;",
02127 NULL, NULL, NULL);
02128 }
02129 if (rc != SQLITE_OK) {
02130 if (rc != SQLITE_BUSY ||
02131 !busy_handler((void *) d, ++count)) {
02132 return rc;
02133 }
02134 continue;
02135 }
02136 count = 0;
02137 ++step;
02138 }
02139 sqlite3_busy_handler(x, busy_handler, (void *) d);
02140 return SQLITE_OK;
02141 }
02142
02152 static void
02153 freerows(char **rowp)
02154 {
02155 PTRDIFF_T size, i;
02156
02157 if (!rowp) {
02158 return;
02159 }
02160 --rowp;
02161 size = (PTRDIFF_T) rowp[0];
02162 for (i = 1; i <= size; i++) {
02163 freep(&rowp[i]);
02164 }
02165 freep(&rowp);
02166 }
02167
02178 static int
02179 mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
02180 int dobigint)
02181 {
02182 char *p, *q;
02183 int testsign = 0, result;
02184
02185 #ifdef WINTERFACE
02186 result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
02187 #else
02188 result = SQL_VARCHAR;
02189 #endif
02190 if (!typename) {
02191 return result;
02192 }
02193 q = p = xmalloc(strlen(typename) + 1);
02194 if (!p) {
02195 return result;
02196 }
02197 strcpy(p, typename);
02198 while (*q) {
02199 *q = TOLOWER(*q);
02200 ++q;
02201 }
02202 if (strncmp(p, "inter", 5) == 0) {
02203 } else if (strncmp(p, "int", 3) == 0 ||
02204 strncmp(p, "mediumint", 9) == 0) {
02205 testsign = 1;
02206 result = SQL_INTEGER;
02207 } else if (strncmp(p, "numeric", 7) == 0) {
02208 result = SQL_DOUBLE;
02209 } else if (strncmp(p, "tinyint", 7) == 0) {
02210 testsign = 1;
02211 result = SQL_TINYINT;
02212 } else if (strncmp(p, "smallint", 8) == 0) {
02213 testsign = 1;
02214 result = SQL_SMALLINT;
02215 } else if (strncmp(p, "float", 5) == 0) {
02216 result = SQL_DOUBLE;
02217 } else if (strncmp(p, "double", 6) == 0 ||
02218 strncmp(p, "real", 4) == 0) {
02219 result = SQL_DOUBLE;
02220 } else if (strncmp(p, "timestamp", 9) == 0) {
02221 #ifdef SQL_TYPE_TIMESTAMP
02222 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
02223 #else
02224 result = SQL_TIMESTAMP;
02225 #endif
02226 } else if (strncmp(p, "datetime", 8) == 0) {
02227 #ifdef SQL_TYPE_TIMESTAMP
02228 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
02229 #else
02230 result = SQL_TIMESTAMP;
02231 #endif
02232 } else if (strncmp(p, "time", 4) == 0) {
02233 #ifdef SQL_TYPE_TIME
02234 result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
02235 #else
02236 result = SQL_TIME;
02237 #endif
02238 } else if (strncmp(p, "date", 4) == 0) {
02239 #ifdef SQL_TYPE_DATE
02240 result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
02241 #else
02242 result = SQL_DATE;
02243 #endif
02244 #ifdef SQL_LONGVARCHAR
02245 } else if (strncmp(p, "text", 4) == 0 ||
02246 strncmp(p, "memo", 4) == 0 ||
02247 strncmp(p, "longvarchar", 11) == 0) {
02248 #ifdef WINTERFACE
02249 result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
02250 #else
02251 result = SQL_LONGVARCHAR;
02252 #endif
02253 #ifdef WINTERFACE
02254 } else if (strncmp(p, "wtext", 5) == 0 ||
02255 strncmp(p, "wvarchar", 8) == 0 ||
02256 strncmp(p, "longwvarchar", 12) == 0) {
02257 result = SQL_WLONGVARCHAR;
02258 #endif
02259 #endif
02260 #ifdef SQL_BIT
02261 } else if (strncmp(p, "bool", 4) == 0 ||
02262 strncmp(p, "bit", 3) == 0) {
02263 result = SQL_BIT;
02264 #endif
02265 #ifdef SQL_BIGINT
02266 } else if (strncmp(p, "bigint", 6) == 0) {
02267 testsign = 1;
02268 result = SQL_BIGINT;
02269 #endif
02270 } else if (strncmp(p, "blob", 4) == 0) {
02271 result = SQL_BINARY;
02272 } else if (strncmp(p, "varbinary", 9) == 0) {
02273 result = SQL_VARBINARY;
02274 } else if (strncmp(p, "longvarbinary", 13) == 0) {
02275 result = SQL_LONGVARBINARY;
02276 }
02277 if (nosign) {
02278 if (testsign) {
02279 *nosign = strstr(p, "unsigned") != NULL;
02280 } else {
02281 *nosign = 1;
02282 }
02283 }
02284 #ifdef SQL_BIGINT
02285 if (dobigint && result == SQL_INTEGER) {
02286 result = SQL_BIGINT;
02287 }
02288 #endif
02289 xfree(p);
02290 return result;
02291 }
02292
02302 static void
02303 getmd(const char *typename, int sqltype, int *mp, int *dp)
02304 {
02305 int m = 0, d = 0;
02306
02307 switch (sqltype) {
02308 case SQL_INTEGER: m = 10; d = 9; break;
02309 case SQL_TINYINT: m = 4; d = 3; break;
02310 case SQL_SMALLINT: m = 6; d = 5; break;
02311 case SQL_FLOAT: m = 25; d = 24; break;
02312 case SQL_DOUBLE: m = 54; d = 53; break;
02313 case SQL_VARCHAR: m = 255; d = 0; break;
02314 #ifdef WINTERFACE
02315 #ifdef SQL_WVARCHAR
02316 case SQL_WVARCHAR: m = 255; d = 0; break;
02317 #endif
02318 #endif
02319 #ifdef SQL_TYPE_DATE
02320 case SQL_TYPE_DATE:
02321 #endif
02322 case SQL_DATE: m = 10; d = 0; break;
02323 #ifdef SQL_TYPE_TIME
02324 case SQL_TYPE_TIME:
02325 #endif
02326 case SQL_TIME: m = 8; d = 0; break;
02327 #ifdef SQL_TYPE_TIMESTAMP
02328 case SQL_TYPE_TIMESTAMP:
02329 #endif
02330 case SQL_TIMESTAMP: m = 32; d = 3; break;
02331 #ifdef SQL_LONGVARCHAR
02332 case SQL_LONGVARCHAR : m = 65536; d = 0; break;
02333 #endif
02334 #ifdef WINTERFACE
02335 #ifdef SQL_WLONGVARCHAR
02336 case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
02337 #endif
02338 #endif
02339 case SQL_BINARY:
02340 case SQL_VARBINARY: m = 255; d = 0; break;
02341 case SQL_LONGVARBINARY: m = 65536; d = 0; break;
02342 #ifdef SQL_BIGINT
02343 case SQL_BIGINT: m = 20; d = 19; break;
02344 #endif
02345 #ifdef SQL_BIT
02346 case SQL_BIT: m = 1; d = 1; break;
02347 #endif
02348 }
02349 if (m && typename) {
02350 int mm, dd;
02351 char clbr[4];
02352
02353 if (sscanf(typename, "%*[^(](%d,%d %1[)]", &mm, &dd, clbr) == 3) {
02354 m = mm;
02355 d = dd;
02356 } else if (sscanf(typename, "%*[^(](%d %1[)]", &mm, clbr) == 2) {
02357 if (sqltype == SQL_TIMESTAMP) {
02358 d = mm;
02359 }
02360 #ifdef SQL_TYPE_TIMESTAMP
02361 else if (sqltype == SQL_TYPE_TIMESTAMP) {
02362 d = mm;
02363 }
02364 #endif
02365 else {
02366 m = d = mm;
02367 }
02368 }
02369 }
02370 if (mp) {
02371 *mp = m;
02372 }
02373 if (dp) {
02374 *dp = d;
02375 }
02376 }
02377
02387 static int
02388 mapdeftype(int type, int stype, int nosign, int nowchar)
02389 {
02390 if (type == SQL_C_DEFAULT) {
02391 switch (stype) {
02392 case SQL_INTEGER:
02393 type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
02394 break;
02395 case SQL_TINYINT:
02396 type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
02397 break;
02398 case SQL_SMALLINT:
02399 type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
02400 break;
02401 case SQL_FLOAT:
02402 type = SQL_C_FLOAT;
02403 break;
02404 case SQL_DOUBLE:
02405 type = SQL_C_DOUBLE;
02406 break;
02407 case SQL_TIMESTAMP:
02408 type = SQL_C_TIMESTAMP;
02409 break;
02410 case SQL_TIME:
02411 type = SQL_C_TIME;
02412 break;
02413 case SQL_DATE:
02414 type = SQL_C_DATE;
02415 break;
02416 #ifdef SQL_C_TYPE_TIMESTAMP
02417 case SQL_TYPE_TIMESTAMP:
02418 type = SQL_C_TYPE_TIMESTAMP;
02419 break;
02420 #endif
02421 #ifdef SQL_C_TYPE_TIME
02422 case SQL_TYPE_TIME:
02423 type = SQL_C_TYPE_TIME;
02424 break;
02425 #endif
02426 #ifdef SQL_C_TYPE_DATE
02427 case SQL_TYPE_DATE:
02428 type = SQL_C_TYPE_DATE;
02429 break;
02430 #endif
02431 #ifdef WINTERFACE
02432 case SQL_WVARCHAR:
02433 case SQL_WCHAR:
02434 #ifdef SQL_WLONGVARCHAR
02435 case SQL_WLONGVARCHAR:
02436 #endif
02437 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
02438 break;
02439 #endif
02440 case SQL_BINARY:
02441 case SQL_VARBINARY:
02442 case SQL_LONGVARBINARY:
02443 type = SQL_C_BINARY;
02444 break;
02445 #ifdef SQL_BIT
02446 case SQL_BIT:
02447 type = SQL_C_BIT;
02448 break;
02449 #endif
02450 #ifdef SQL_BIGINT
02451 case SQL_BIGINT:
02452 type = SQL_C_CHAR;
02453 break;
02454 #endif
02455 default:
02456 #ifdef WINTERFACE
02457 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
02458 #else
02459 type = SQL_C_CHAR;
02460 #endif
02461 break;
02462 }
02463 }
02464 return type;
02465 }
02466
02473 static int
02474 checkddl(char *sql)
02475 {
02476 int isddl = 0;
02477
02478 while (*sql && ISSPACE(*sql)) {
02479 ++sql;
02480 }
02481 if (*sql && *sql != ';') {
02482 int i, size;
02483 static const struct {
02484 int len;
02485 const char *str;
02486 } ddlstr[] = {
02487 { 5, "alter" },
02488 { 7, "analyze" },
02489 { 6, "attach" },
02490 { 5, "begin" },
02491 { 6, "commit" },
02492 { 6, "create" },
02493 { 6, "detach" },
02494 { 4, "drop" },
02495 { 3, "end" },
02496 { 7, "reindex" },
02497 { 7, "release" },
02498 { 8, "rollback" },
02499 { 9, "savepoint" },
02500 { 6, "vacuum" }
02501 };
02502
02503 size = strlen(sql);
02504 for (i = 0; i < array_size(ddlstr); i++) {
02505 if (size >= ddlstr[i].len &&
02506 strncasecmp(sql, ddlstr[i].str, ddlstr[i].len) == 0) {
02507 isddl = 1;
02508 break;
02509 }
02510 }
02511 }
02512 return isddl;
02513 }
02514
02526 static char *
02527 fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect,
02528 char **errmsg)
02529 {
02530 char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
02531 int np = 0, isddl = -1, size;
02532
02533 if (errmsg) {
02534 *errmsg = NULL;
02535 }
02536 if (sqlLen != SQL_NTS) {
02537 qz = q = xmalloc(sqlLen + 1);
02538 if (!qz) {
02539 return NULL;
02540 }
02541 memcpy(q, sql, sqlLen);
02542 q[sqlLen] = '\0';
02543 size = sqlLen * 4;
02544 } else {
02545 size = strlen(sql) * 4;
02546 }
02547 size += sizeof (char *) - 1;
02548 size &= ~(sizeof (char *) - 1);
02549 p = xmalloc(size);
02550 if (!p) {
02551 errout:
02552 freep(&qz);
02553 return NULL;
02554 }
02555 memset(p, 0, size);
02556 out = p;
02557 while (*q) {
02558 switch (*q) {
02559 case '\'':
02560 case '\"':
02561 if (q == inq) {
02562 inq = NULL;
02563 } else if (!inq) {
02564 inq = q + 1;
02565
02566 while (*inq) {
02567 if (*inq == *q) {
02568 if (inq[1] == *q) {
02569 inq++;
02570 } else {
02571 break;
02572 }
02573 }
02574 inq++;
02575 }
02576 }
02577 *p++ = *q;
02578 break;
02579 case '-':
02580 *p++ = *q;
02581 if (!inq && q[1] == '-') {
02582 ++q;
02583 while (*q) {
02584 *p++ = *q++;
02585 if (*q == '\n') {
02586 break;
02587 }
02588 }
02589 }
02590 break;
02591 case '?':
02592 *p++ = *q;
02593 if (!inq) {
02594 np++;
02595 }
02596 break;
02597 case ';':
02598 if (!inq) {
02599 if (isddl < 0) {
02600 isddl = checkddl(out);
02601 }
02602 if (isddl == 0) {
02603 char *qq = q;
02604
02605 do {
02606 ++qq;
02607 } while (*qq && ISSPACE(*qq));
02608 if (*qq && *qq != ';') {
02609 freep(&out);
02610 if (errmsg) {
02611 *errmsg = "only one SQL statement allowed";
02612 }
02613 goto errout;
02614 }
02615 }
02616 }
02617 *p++ = *q;
02618 break;
02619 case '{':
02620
02621
02622
02623
02624
02625 if (!inq) {
02626 int ojfn = 0, brc = 0;
02627 char *inq2 = NULL, *end = q + 1, *start;
02628
02629 while (*end && ISSPACE(*end)) {
02630 ++end;
02631 }
02632 if (*end != 'd' && *end != 'D' &&
02633 *end != 't' && *end != 'T') {
02634 ojfn = 1;
02635 }
02636 start = end;
02637 while (*end) {
02638 if (inq2 && *end == *inq2) {
02639 inq2 = NULL;
02640 } else if (inq2 == NULL && *end == '{') {
02641 char *nerr = 0, *nsql;
02642
02643 nsql = fixupsql(end, SQL_NTS, cte, 0, 0, &nerr);
02644 if (nsql && !nerr) {
02645 strcpy(end, nsql);
02646 } else {
02647 brc++;
02648 }
02649 freep(&nsql);
02650 } else if (inq2 == NULL && *end == '}') {
02651 if (brc-- <= 0) {
02652 break;
02653 }
02654 } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
02655 inq2 = end;
02656 } else if (inq2 == NULL && *end == '?') {
02657 np++;
02658 }
02659 ++end;
02660 }
02661 if (*end == '}') {
02662 char *end2 = end - 1;
02663
02664 if (ojfn) {
02665 while (start < end) {
02666 if (ISSPACE(*start)) {
02667 break;
02668 }
02669 ++start;
02670 }
02671 while (start < end) {
02672 *p++ = *start;
02673 ++start;
02674 }
02675 q = end;
02676 break;
02677 } else {
02678 while (start < end2 && *start != '\'') {
02679 ++start;
02680 }
02681 while (end2 > start && *end2 != '\'') {
02682 --end2;
02683 }
02684 if (*start == '\'' && *end2 == '\'') {
02685 while (start <= end2) {
02686 *p++ = *start;
02687 ++start;
02688 }
02689 q = end;
02690 break;
02691 }
02692 }
02693 }
02694 }
02695
02696 default:
02697 *p++ = *q;
02698 }
02699 ++q;
02700 }
02701 freep(&qz);
02702 *p = '\0';
02703 if (nparam) {
02704 *nparam = np;
02705 }
02706 if (isselect) {
02707 if (isddl < 0) {
02708 isddl = checkddl(out);
02709 }
02710 if (isddl > 0) {
02711 *isselect = 2;
02712 } else {
02713 int incom = 0;
02714
02715 p = out;
02716 while (*p) {
02717 switch (*p) {
02718 case '-':
02719 if (!incom && p[1] == '-') {
02720 incom = -1;
02721 }
02722 break;
02723 case '\n':
02724 if (incom < 0) {
02725 incom = 0;
02726 }
02727 break;
02728 case '/':
02729 if (incom > 0 && p[-1] == '*') {
02730 incom = 0;
02731 p++;
02732 continue;
02733 } else if (!incom && p[1] == '*') {
02734 incom = 1;
02735 }
02736 break;
02737 }
02738 if (!incom && !ISSPACE(*p)) {
02739 break;
02740 }
02741 p++;
02742 }
02743 size = strlen(p);
02744 if (size >= 6 &&
02745 (strncasecmp(p, "select", 6) == 0 ||
02746 strncasecmp(p, "pragma", 6) == 0)) {
02747 *isselect = 1;
02748 } else if (cte && size >= 4 && strncasecmp(p, "with", 4) == 0) {
02749 *isselect = 1;
02750 } else if (size >= 7 && strncasecmp(p, "explain", 7) == 0) {
02751 *isselect = 1;
02752 } else {
02753 *isselect = 0;
02754 }
02755 }
02756 }
02757 return out;
02758 }
02759
02765 static void
02766 replilike(char *sql)
02767 {
02768 char *q = sql, *inq = NULL;
02769
02770 while (*q) {
02771 switch (*q) {
02772 case '\'':
02773 case '\"':
02774 if (q == inq) {
02775 inq = NULL;
02776 } else if (!inq) {
02777 inq = q + 1;
02778
02779 while (*inq) {
02780 if (*inq == *q) {
02781 if (inq[1] == *q) {
02782 inq++;
02783 } else {
02784 break;
02785 }
02786 }
02787 inq++;
02788 }
02789 }
02790 break;
02791 case '-':
02792 if (!inq && q[1] == '-') {
02793 ++q;
02794 while (*q) {
02795 if (*q == '\n') {
02796 break;
02797 }
02798 }
02799 }
02800 break;
02801 default:
02802 if (!inq && ISSPACE(*q) && q[1]) {
02803 if (strncasecmp(q + 1, "ilike", 5) == 0) {
02804 if ((q[2] != '\0') && (q[3] != '\0') &&
02805 (q[4] != '\0') && (q[5] != '\0') &&
02806 ((q[6] == '\0') || ISSPACE(q[6]))) {
02807 q++;
02808 memmove(q, q + 1, strlen(q));
02809 q += 3;
02810 }
02811 }
02812 }
02813 break;
02814 }
02815 ++q;
02816 }
02817 }
02818
02827 static int
02828 findcol(char **cols, int ncols, char *name)
02829 {
02830 int i;
02831
02832 if (cols) {
02833 for (i = 0; i < ncols; i++) {
02834 if (strcmp(cols[i], name) == 0) {
02835 return i;
02836 }
02837 }
02838 }
02839 return -1;
02840 }
02841
02858 static void
02859 fixupdyncols(STMT *s, DBC *d)
02860 {
02861 int i, k;
02862 #ifndef FULL_METADATA
02863 int pk, nn, t, r, nrows, ncols;
02864 char **rowp, *flagp, flags[128];
02865 #endif
02866
02867 if (!s->dyncols) {
02868 return;
02869 }
02870
02871 if (!s->longnames) {
02872 if (s->dcols > 1) {
02873 char *table = s->dyncols[0].table;
02874
02875 for (i = 1; table[0] && i < s->dcols; i++) {
02876 if (strcmp(s->dyncols[i].table, table)) {
02877 break;
02878 }
02879 }
02880 if (i >= s->dcols) {
02881 for (i = 0; i < s->dcols; i++) {
02882 s->dyncols[i].label = s->dyncols[i].column;
02883 }
02884 }
02885 } else if (s->dcols == 1) {
02886 s->dyncols[0].label = s->dyncols[0].column;
02887 }
02888 }
02889 for (i = 0; i < s->dcols; i++) {
02890 s->dyncols[i].type =
02891 mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
02892 s->nowchar[0] || s->nowchar[1], s->dobigint);
02893 getmd(s->dyncols[i].typename, s->dyncols[i].type,
02894 &s->dyncols[i].size, &s->dyncols[i].prec);
02895 #ifdef SQL_LONGVARCHAR
02896 if (s->dyncols[i].type == SQL_VARCHAR &&
02897 s->dyncols[i].size > 255) {
02898 s->dyncols[i].type = SQL_LONGVARCHAR;
02899 }
02900 #endif
02901 #ifdef WINTERFACE
02902 #ifdef SQL_WLONGVARCHAR
02903 if (s->dyncols[i].type == SQL_WVARCHAR &&
02904 s->dyncols[i].size > 255) {
02905 s->dyncols[i].type = SQL_WLONGVARCHAR;
02906 }
02907 #endif
02908 #endif
02909 if (s->dyncols[i].type == SQL_VARBINARY &&
02910 s->dyncols[i].size > 255) {
02911 s->dyncols[i].type = SQL_LONGVARBINARY;
02912 }
02913 }
02914 #ifndef FULL_METADATA
02915 if (s->dcols > array_size(flags)) {
02916 flagp = xmalloc(sizeof (flags[0]) * s->dcols);
02917 if (flagp == NULL) {
02918 return;
02919 }
02920 } else {
02921 flagp = flags;
02922 }
02923 memset(flagp, 0, sizeof (flags[0]) * s->dcols);
02924 for (i = 0; i < s->dcols; i++) {
02925 s->dyncols[i].autoinc = SQL_FALSE;
02926 s->dyncols[i].notnull = SQL_NULLABLE;
02927 }
02928 for (i = 0; i < s->dcols; i++) {
02929 int ret, lastpk = -1, autoinccount = 0;
02930 char *sql;
02931
02932 if (!s->dyncols[i].table[0]) {
02933 continue;
02934 }
02935 if (flagp[i]) {
02936 continue;
02937 }
02938 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
02939 if (!sql) {
02940 continue;
02941 }
02942 dbtraceapi(d, "sqlite3_get_table", sql);
02943 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
02944 sqlite3_free(sql);
02945 if (ret != SQLITE_OK) {
02946 continue;
02947 }
02948 k = findcol(rowp, ncols, "name");
02949 t = findcol(rowp, ncols, "type");
02950 pk = findcol(rowp, ncols, "pk");
02951 nn = findcol(rowp, ncols, "notnull");
02952 if (k < 0 || t < 0) {
02953 goto freet;
02954 }
02955 for (r = 1; r <= nrows; r++) {
02956 int m;
02957
02958 for (m = i; m < s->dcols; m++) {
02959 char *colname = s->dyncols[m].column;
02960
02961 if (s->longnames) {
02962 char *dotp = strchr(colname, '.');
02963
02964 if (dotp) {
02965 colname = dotp + 1;
02966 }
02967 }
02968 if (!flagp[m] &&
02969 strcmp(colname, rowp[r * ncols + k]) == 0 &&
02970 strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
02971 char *typename = rowp[r * ncols + t];
02972
02973 flagp[m] = i + 1;
02974 freep(&s->dyncols[m].typename);
02975 s->dyncols[m].typename = xstrdup(typename);
02976 s->dyncols[m].type =
02977 mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
02978 s->nowchar[0] || s->nowchar[1],
02979 s->dobigint);
02980 getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
02981 &s->dyncols[m].prec);
02982 #ifdef SQL_LONGVARCHAR
02983 if (s->dyncols[m].type == SQL_VARCHAR &&
02984 s->dyncols[m].size > 255) {
02985 s->dyncols[m].type = SQL_LONGVARCHAR;
02986 }
02987 #endif
02988 #ifdef WINTERFACE
02989 #ifdef SQL_WLONGVARCHAR
02990 if (s->dyncols[i].type == SQL_WVARCHAR &&
02991 s->dyncols[i].size > 255) {
02992 s->dyncols[i].type = SQL_WLONGVARCHAR;
02993 }
02994 #endif
02995 #endif
02996 if (s->dyncols[i].type == SQL_VARBINARY &&
02997 s->dyncols[i].size > 255) {
02998 s->dyncols[i].type = SQL_LONGVARBINARY;
02999 }
03000 if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
03001 s->dyncols[m].ispk = 1;
03002 if (++autoinccount > 1) {
03003 if (lastpk >= 0) {
03004 s->dyncols[lastpk].autoinc = SQL_FALSE;
03005 lastpk = -1;
03006 }
03007 } else {
03008 lastpk = m;
03009 if (strlen(typename) == 7 &&
03010 strncasecmp(typename, "integer", 7) == 0) {
03011 s->dyncols[m].autoinc = SQL_TRUE;
03012 }
03013 }
03014 } else {
03015 s->dyncols[m].ispk = 0;
03016 }
03017 if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
03018 s->dyncols[m].notnull = SQL_NO_NULLS;
03019 }
03020 }
03021 }
03022 }
03023 freet:
03024 sqlite3_free_table(rowp);
03025 }
03026 for (i = k = 0; i < s->dcols; i++) {
03027 if (flagp[i] == 0) {
03028 break;
03029 }
03030 if (k == 0) {
03031 k = flagp[i];
03032 } else if (flagp[i] != k) {
03033 k = 0;
03034 break;
03035 }
03036 }
03037 s->one_tbl = k ? 1 : 0;
03038 k = 0;
03039 if (s->one_tbl) {
03040 for (i = 0; i < s->dcols; i++) {
03041 if (s->dyncols[i].ispk > 0) {
03042 ++k;
03043 }
03044 }
03045 }
03046 s->has_pk = k;
03047 if (flagp != flags) {
03048 freep(&flagp);
03049 }
03050 #else
03051 for (i = 1, k = 0; i < s->dcols; i++) {
03052 if (strcmp(s->dyncols[i].table, s->dyncols[0].table) == 0) {
03053 k++;
03054 }
03055 }
03056 s->one_tbl = (k && k + 1 == s->dcols) ? 1 : 0;
03057 k = 0;
03058 if (s->one_tbl) {
03059 for (i = 0; i < s->dcols; i++) {
03060 if (s->dyncols[i].ispk > 0) {
03061 ++k;
03062 if (s->has_rowid < 0 && s->dyncols[i].isrowid > 0) {
03063 s->has_rowid = i;
03064 }
03065 }
03066 }
03067 }
03068 s->has_pk = k;
03069 #endif
03070 }
03071
03078 static void
03079 convJD2YMD(double jd, DATE_STRUCT *ds)
03080 {
03081 int z, a, b, c, d, e, x1;
03082 sqlite_int64 ijd;
03083
03084 ijd = jd * 86400000.0 + 0.5;
03085 z = (int) ((ijd + 43200000) / 86400000);
03086 a = (int) ((z - 1867216.25) / 36524.25);
03087 a = z + 1 + a - (a / 4);
03088 b = a + 1524;
03089 c = (int) ((b - 122.1) / 365.25);
03090 d = (36525 * c) / 100;
03091 e = (int) ((b - d) / 30.6001);
03092 x1 = (int) (30.6001 * e);
03093 ds->day = b - d - x1;
03094 ds->month = (e < 14) ? (e - 1) : (e - 13);
03095 ds->year = (ds->month > 2) ? (c - 4716) : (c - 4715);
03096 }
03097
03098
03106 static void
03107 convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
03108 {
03109 int s;
03110 double ds;
03111 sqlite_int64 ijd;
03112
03113 ijd = jd * 86400000.0 + 0.5;
03114 s = (int)((ijd + 43200000) % 86400000);
03115 ds = s / 1000.0;
03116 if (fp) {
03117 *fp = (s % 1000) * 1000000;
03118 }
03119 s = (int) ds;
03120 ds -= s;
03121 ts->hour = s / 3600;
03122 s -= ts->hour * 3600;
03123 ts->minute = s / 60;
03124 ds += s - ts->minute *60;
03125 ts->second = (int) ds;
03126 }
03127
03135 static int
03136 getmdays(int year, int month)
03137 {
03138 static const int mdays[] = {
03139 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
03140 };
03141 int mday;
03142
03143 if (month < 1) {
03144 return 0;
03145 }
03146 mday = mdays[(month - 1) % 12];
03147 if (mday == 28 && year % 4 == 0 &&
03148 (!(year % 100 == 0) || year % 400 == 0)) {
03149 mday++;
03150 }
03151 return mday;
03152 }
03153
03169 static int
03170 str2date(int jdconv, char *str, DATE_STRUCT *ds)
03171 {
03172 int i, err = 0;
03173 double jd;
03174 char *p, *q, sepc = '\0';
03175
03176 ds->year = ds->month = ds->day = 0;
03177 if (jdconv) {
03178 p = strchr(str, '.');
03179 if (p) {
03180
03181 p = 0;
03182 jd = ln_strtod(str, &p);
03183 if (p && p > str) {
03184 convJD2YMD(jd, ds);
03185 return 0;
03186 }
03187 }
03188 }
03189 p = str;
03190 while (*p && !ISDIGIT(*p)) {
03191 ++p;
03192 }
03193 q = p;
03194 i = 0;
03195 while (*q && !ISDIGIT(*q)) {
03196 ++i;
03197 ++q;
03198 }
03199 if (i >= 8) {
03200 char buf[8];
03201
03202 strncpy(buf, p + 0, 4); buf[4] = '\0';
03203 ds->year = strtol(buf, NULL, 10);
03204 strncpy(buf, p + 4, 2); buf[2] = '\0';
03205 ds->month = strtol(buf, NULL, 10);
03206 strncpy(buf, p + 6, 2); buf[2] = '\0';
03207 ds->day = strtol(buf, NULL, 10);
03208 goto done;
03209 }
03210 i = 0;
03211 while (i < 3) {
03212 int n;
03213
03214 q = NULL;
03215 n = strtol(p, &q, 10);
03216 if (!q || q == p) {
03217 if (*q == '\0') {
03218 if (i == 0) {
03219 err = 1;
03220 }
03221 goto done;
03222 }
03223 }
03224 if (!sepc) {
03225 sepc = *q;
03226 }
03227 if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
03228 switch (i) {
03229 case 0: ds->year = n; break;
03230 case 1: ds->month = n; break;
03231 case 2: ds->day = n; break;
03232 }
03233 ++i;
03234 if (*q) {
03235 ++q;
03236 }
03237 } else {
03238 i = 0;
03239 while (*q && !ISDIGIT(*q)) {
03240 ++q;
03241 }
03242 }
03243 p = q;
03244 }
03245 done:
03246
03247 if (err ||
03248 ds->month < 1 || ds->month > 12 ||
03249 ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
03250 if (sepc == '/') {
03251
03252 int t[3];
03253
03254 t[0] = ds->year;
03255 t[1] = ds->month;
03256 t[2] = ds->day;
03257 ds->year = t[2];
03258 ds->day = t[1];
03259 ds->month = t[0];
03260 if (ds->month >= 1 && ds->month <= 12 &&
03261 (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
03262 return 0;
03263 }
03264 }
03265 return -1;
03266 }
03267 return 0;
03268 }
03269
03284 static int
03285 str2time(int jdconv, char *str, TIME_STRUCT *ts)
03286 {
03287 int i, err = 0, ampm = -1;
03288 double jd;
03289 char *p, *q;
03290
03291 ts->hour = ts->minute = ts->second = 0;
03292 if (jdconv) {
03293 p = strchr(str, '.');
03294 if (p) {
03295
03296 p = 0;
03297 jd = ln_strtod(str, &p);
03298 if (p && p > str) {
03299 convJD2HMS(jd, ts, 0);
03300 return 0;
03301 }
03302 }
03303 }
03304 p = str;
03305 while (*p && !ISDIGIT(*p)) {
03306 ++p;
03307 }
03308 q = p;
03309 i = 0;
03310 while (*q && ISDIGIT(*q)) {
03311 ++i;
03312 ++q;
03313 }
03314 if (i >= 6) {
03315 char buf[4];
03316
03317 strncpy(buf, p + 0, 2); buf[2] = '\0';
03318 ts->hour = strtol(buf, NULL, 10);
03319 strncpy(buf, p + 2, 2); buf[2] = '\0';
03320 ts->minute = strtol(buf, NULL, 10);
03321 strncpy(buf, p + 4, 2); buf[2] = '\0';
03322 ts->second = strtol(buf, NULL, 10);
03323 goto done;
03324 }
03325 i = 0;
03326 while (i < 3) {
03327 int n;
03328
03329 q = NULL;
03330 n = strtol(p, &q, 10);
03331 if (!q || q == p) {
03332 if (*q == '\0') {
03333 if (i == 0) {
03334 err = 1;
03335 }
03336 goto done;
03337 }
03338 }
03339 if (*q == ':' || *q == '\0' || i == 2) {
03340 switch (i) {
03341 case 0: ts->hour = n; break;
03342 case 1: ts->minute = n; break;
03343 case 2: ts->second = n; break;
03344 }
03345 ++i;
03346 if (*q) {
03347 ++q;
03348 }
03349 } else {
03350 i = 0;
03351 while (*q && !ISDIGIT(*q)) {
03352 ++q;
03353 }
03354 }
03355 p = q;
03356 }
03357 if (!err) {
03358 while (*p) {
03359 if ((p[0] == 'p' || p[0] == 'P') &&
03360 (p[1] == 'm' || p[1] == 'M')) {
03361 ampm = 1;
03362 } else if ((p[0] == 'a' || p[0] == 'A') &&
03363 (p[1] == 'm' || p[1] == 'M')) {
03364 ampm = 0;
03365 }
03366 ++p;
03367 }
03368 if (ampm > 0) {
03369 if (ts->hour < 12) {
03370 ts->hour += 12;
03371 }
03372 } else if (ampm == 0) {
03373 if (ts->hour == 12) {
03374 ts->hour = 0;
03375 }
03376 }
03377 }
03378 done:
03379
03380 if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
03381 return -1;
03382 }
03383 return 0;
03384 }
03385
03405 static int
03406 str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
03407 {
03408 int i, m, n, err = 0, ampm = -1;
03409 double jd;
03410 char *p, *q, in = '\0', sepc = '\0';
03411
03412 tss->year = tss->month = tss->day = 0;
03413 tss->hour = tss->minute = tss->second = 0;
03414 tss->fraction = 0;
03415 if (jdconv) {
03416 p = strchr(str, '.');
03417 if (p) {
03418 q = strchr(str, '-');
03419 if (q == str) {
03420 q = 0;
03421 }
03422 if (!q) {
03423 q = strchr(str, '/');
03424 if (!q) {
03425 q = strchr(str, ':');
03426 }
03427 }
03428 if (!q || q > p) {
03429
03430 p = 0;
03431 jd = ln_strtod(str, &p);
03432 if (p && p > str) {
03433 DATE_STRUCT ds;
03434 TIME_STRUCT ts;
03435
03436 convJD2YMD(jd, &ds);
03437 convJD2HMS(jd, &ts, &n);
03438 tss->year = ds.year;
03439 tss->month = ds.month;
03440 tss->day = ds.day;
03441 tss->hour = ts.hour;
03442 tss->minute = ts.minute;
03443 tss->second = ts.second;
03444 tss->fraction = n;
03445 return 0;
03446 }
03447 }
03448 }
03449 }
03450 p = str;
03451 while (*p && !ISDIGIT(*p)) {
03452 ++p;
03453 }
03454 q = p;
03455 i = 0;
03456 while (*q && ISDIGIT(*q)) {
03457 ++i;
03458 ++q;
03459 }
03460 if (i >= 14) {
03461 char buf[16];
03462
03463 strncpy(buf, p + 0, 4); buf[4] = '\0';
03464 tss->year = strtol(buf, NULL, 10);
03465 strncpy(buf, p + 4, 2); buf[2] = '\0';
03466 tss->month = strtol(buf, NULL, 10);
03467 strncpy(buf, p + 6, 2); buf[2] = '\0';
03468 tss->day = strtol(buf, NULL, 10);
03469 strncpy(buf, p + 8, 2); buf[2] = '\0';
03470 tss->hour = strtol(buf, NULL, 10);
03471 strncpy(buf, p + 10, 2); buf[2] = '\0';
03472 tss->minute = strtol(buf, NULL, 10);
03473 strncpy(buf, p + 12, 2); buf[2] = '\0';
03474 tss->second = strtol(buf, NULL, 10);
03475 if (i > 14) {
03476 m = i - 14;
03477 strncpy(buf, p + 14, m);
03478 while (m < 9) {
03479 buf[m] = '0';
03480 ++m;
03481 }
03482 buf[m] = '\0';
03483 tss->fraction = strtol(buf, NULL, 10);
03484 }
03485 m = 7;
03486 goto done;
03487 }
03488 m = i = 0;
03489 while ((m & 7) != 7) {
03490 q = NULL;
03491 n = strtol(p, &q, 10);
03492 if (!q || q == p) {
03493 if (*q == '\0') {
03494 if (m < 1) {
03495 err = 1;
03496 }
03497 goto done;
03498 }
03499 }
03500 if (in == '\0') {
03501 switch (*q) {
03502 case '-':
03503 case '/':
03504 if ((m & 1) == 0) {
03505 in = *q;
03506 i = 0;
03507 }
03508 break;
03509 case ':':
03510 if ((m & 2) == 0) {
03511 in = *q;
03512 i = 0;
03513 }
03514 break;
03515 case ' ':
03516 case '.':
03517 break;
03518 default:
03519 in = '\0';
03520 i = 0;
03521 break;
03522 }
03523 }
03524 switch (in) {
03525 case '-':
03526 case '/':
03527 if (!sepc) {
03528 sepc = in;
03529 }
03530 switch (i) {
03531 case 0: tss->year = n; break;
03532 case 1: tss->month = n; break;
03533 case 2: tss->day = n; break;
03534 }
03535 if (++i >= 3) {
03536 i = 0;
03537 m |= 1;
03538 if (!(m & 2)) {
03539 m |= 8;
03540 }
03541 goto skip;
03542 } else {
03543 ++q;
03544 }
03545 break;
03546 case ':':
03547 switch (i) {
03548 case 0: tss->hour = n; break;
03549 case 1: tss->minute = n; break;
03550 case 2: tss->second = n; break;
03551 }
03552 if (++i >= 3) {
03553 i = 0;
03554 m |= 2;
03555 if (*q == '.') {
03556 in = '.';
03557 goto skip2;
03558 }
03559 if (*q == ' ') {
03560 if ((m & 1) == 0) {
03561 char *e = NULL;
03562
03563 (void) strtol(q + 1, &e, 10);
03564 if (e && *e == '-') {
03565 goto skip;
03566 }
03567 }
03568 in = '.';
03569 goto skip2;
03570 }
03571 goto skip;
03572 } else {
03573 ++q;
03574 }
03575 break;
03576 case '.':
03577 if (++i >= 1) {
03578 int ndig = q - p;
03579
03580 if (p[0] == '+' || p[0] == '-') {
03581 ndig--;
03582 }
03583 while (ndig < 9) {
03584 n = n * 10;
03585 ++ndig;
03586 }
03587 tss->fraction = n;
03588 m |= 4;
03589 i = 0;
03590 }
03591 default:
03592 skip:
03593 in = '\0';
03594 skip2:
03595 while (*q && !ISDIGIT(*q)) {
03596 if ((q[0] == 'a' || q[0] == 'A') &&
03597 (q[1] == 'm' || q[1] == 'M')) {
03598 ampm = 0;
03599 ++q;
03600 } else if ((q[0] == 'p' || q[0] == 'P') &&
03601 (q[1] == 'm' || q[1] == 'M')) {
03602 ampm = 1;
03603 ++q;
03604 }
03605 ++q;
03606 }
03607 }
03608 p = q;
03609 }
03610 if ((m & 7) > 1 && (m & 8)) {
03611
03612 if (p > str && ISDIGIT(*p)) {
03613 int nn, sign;
03614
03615 q = p - 1;
03616 if (*q != '+' && *q != '-') {
03617 goto done;
03618 }
03619 sign = (*q == '+') ? -1 : 1;
03620 q = NULL;
03621 n = strtol(p, &q, 10);
03622 if (!q || *q++ != ':' || !ISDIGIT(*q)) {
03623 goto done;
03624 }
03625 p = q;
03626 q = NULL;
03627 nn = strtol(p, &q, 10);
03628 tss->minute += nn * sign;
03629 if ((SQLSMALLINT) tss->minute < 0) {
03630 tss->hour -= 1;
03631 tss->minute += 60;
03632 } else if (tss->minute >= 60) {
03633 tss->hour += 1;
03634 tss->minute -= 60;
03635 }
03636 tss->hour += n * sign;
03637 if ((SQLSMALLINT) tss->hour < 0) {
03638 tss->day -= 1;
03639 tss->hour += 24;
03640 } else if (tss->hour >= 24) {
03641 tss->day += 1;
03642 tss->hour -= 24;
03643 }
03644 if ((short) tss->day < 1 || tss->day >= 28) {
03645 int mday, pday, pmon;
03646
03647 mday = getmdays(tss->year, tss->month);
03648 pmon = tss->month - 1;
03649 if (pmon < 1) {
03650 pmon = 12;
03651 }
03652 pday = getmdays(tss->year, pmon);
03653 if ((SQLSMALLINT) tss->day < 1) {
03654 tss->month -= 1;
03655 tss->day = pday;
03656 } else if (tss->day > mday) {
03657 tss->month += 1;
03658 tss->day = 1;
03659 }
03660 if ((SQLSMALLINT) tss->month < 1) {
03661 tss->year -= 1;
03662 tss->month = 12;
03663 } else if (tss->month > 12) {
03664 tss->year += 1;
03665 tss->month = 1;
03666 }
03667 }
03668 }
03669 }
03670 done:
03671 if ((m & 1) &&
03672 (tss->month < 1 || tss->month > 12 ||
03673 tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
03674 if (sepc == '/') {
03675
03676 int t[3];
03677
03678 t[0] = tss->year;
03679 t[1] = tss->month;
03680 t[2] = tss->day;
03681 tss->year = t[2];
03682 tss->day = t[1];
03683 tss->month = t[0];
03684 }
03685 }
03686
03687 if (!err && (m & 1) == 0) {
03688 #ifdef _WIN32
03689 SYSTEMTIME t;
03690
03691 GetLocalTime(&t);
03692 tss->year = t.wYear;
03693 tss->month = t.wMonth;
03694 tss->day = t.wDay;
03695 #else
03696 struct timeval tv;
03697 struct tm tm;
03698
03699 gettimeofday(&tv, NULL);
03700 tm = *localtime(&tv.tv_sec);
03701 tss->year = tm.tm_year + 1900;
03702 tss->month = tm.tm_mon + 1;
03703 tss->day = tm.tm_mday;
03704 #endif
03705 }
03706
03707 if (tss->fraction < 0) {
03708 tss->fraction = 0;
03709 }
03710
03711 if (err ||
03712 tss->month < 1 || tss->month > 12 ||
03713 tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
03714 tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
03715 return -1;
03716 }
03717 if ((m & 7) > 1) {
03718 if (ampm > 0) {
03719 if (tss->hour < 12) {
03720 tss->hour += 12;
03721 }
03722 } else if (ampm == 0) {
03723 if (tss->hour == 12) {
03724 tss->hour = 0;
03725 }
03726 }
03727 }
03728 return ((m & 7) < 1) ? -1 : 0;
03729 }
03730
03737 static int
03738 getbool(char *string)
03739 {
03740 if (string) {
03741 return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
03742 }
03743 return 0;
03744 }
03745
03753 static void
03754 blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
03755 {
03756 #if 0
03757 DBC *d = (DBC *) sqlite3_user_data(ctx);
03758 #endif
03759 char *filename = 0;
03760
03761 if (nargs > 0) {
03762 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
03763 filename = (char *) sqlite3_value_text(args[0]);
03764 }
03765 }
03766 if (filename) {
03767 #ifdef _WIN32
03768 char *wname = utf_to_wmb(filename, -1);
03769 FILE *f;
03770 #else
03771 FILE *f = fopen(filename, "r");
03772 #endif
03773 char *p;
03774 long n, nn;
03775
03776 #ifdef _WIN32
03777 if (wname) {
03778 f = fopen(wname, "rb");
03779 } else {
03780 sqlite3_result_error(ctx, "out of memory", -1);
03781 return;
03782 }
03783 uc_free(wname);
03784 #endif
03785 if (f) {
03786 if (fseek(f, 0, SEEK_END) == 0) {
03787 n = ftell(f);
03788 if (fseek(f, 0, SEEK_SET) == 0) {
03789 p = sqlite3_malloc(n);
03790 if (p) {
03791 nn = fread(p, 1, n, f);
03792 if (nn != n) {
03793 sqlite3_result_error(ctx, "read error", -1);
03794 sqlite3_free(p);
03795 } else {
03796 sqlite3_result_blob(ctx, p, n, sqlite3_free);
03797 }
03798 } else {
03799 sqlite3_result_error(ctx, "out of memory", -1);
03800 }
03801 } else {
03802 sqlite3_result_error(ctx, "seek error", -1);
03803 }
03804 } else {
03805 sqlite3_result_error(ctx, "seek error", -1);
03806 }
03807 fclose(f);
03808 } else {
03809 sqlite3_result_error(ctx, "cannot open file", -1);
03810 }
03811 } else {
03812 sqlite3_result_error(ctx, "no filename given", -1);
03813 }
03814 }
03815
03823 static void
03824 blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
03825 {
03826 #if 0
03827 DBC *d = (DBC *) sqlite3_user_data(ctx);
03828 #endif
03829 char *filename = 0;
03830 char *p = 0;
03831 int n = 0;
03832
03833 if (nargs > 0) {
03834 p = (char *) sqlite3_value_blob(args[0]);
03835 n = sqlite3_value_bytes(args[0]);
03836 }
03837 if (nargs > 1) {
03838 if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
03839 filename = (char *) sqlite3_value_text(args[1]);
03840 }
03841 }
03842 if (p) {
03843 if (filename) {
03844 #ifdef _WIN32
03845 char *wname = utf_to_wmb(filename, -1);
03846 FILE *f;
03847 #else
03848 FILE *f = fopen(filename, "w");
03849 #endif
03850 int nn;
03851
03852 #ifdef _WIN32
03853 if (wname) {
03854 f = fopen(wname, "wb");
03855 } else {
03856 sqlite3_result_error(ctx, "out of memory", -1);
03857 return;
03858 }
03859 uc_free(wname);
03860 #endif
03861 if (f) {
03862 nn = fwrite(p, 1, n, f);
03863 fclose(f);
03864 if (nn != n) {
03865 sqlite3_result_error(ctx, "write error", -1);
03866 } else {
03867 sqlite3_result_int(ctx, nn);
03868 }
03869 } else {
03870 sqlite3_result_error(ctx, "cannot open file", -1);
03871 }
03872 } else {
03873 sqlite3_result_error(ctx, "no filename given", -1);
03874 }
03875 } else {
03876 sqlite3_result_null(ctx);
03877 }
03878 }
03879
03887 static void
03888 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03889 dbtrace(void *arg, const char *msg, sqlite_uint64 et)
03890 #else
03891 dbtrace(void *arg, const char *msg)
03892 #endif
03893 {
03894 DBC *d = (DBC *) arg;
03895
03896 if (msg && d->trace) {
03897 int len = strlen(msg);
03898 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03899 unsigned long s, f;
03900 #endif
03901
03902 if (len > 0) {
03903 char *end = "\n";
03904
03905 if (msg[len - 1] != ';') {
03906 end = ";\n";
03907 }
03908 fprintf(d->trace, "%s%s", msg, end);
03909 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03910 s = et / 1000000000LL;
03911 f = et % 1000000000LL;
03912 fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
03913 #endif
03914 fflush(d->trace);
03915 }
03916 }
03917 }
03918
03926 static void
03927 dbtraceapi(DBC *d, char *fn, const char *sql)
03928 {
03929 if (fn && d->trace) {
03930 if (sql) {
03931 fprintf(d->trace, "-- %s: %s\n", fn, sql);
03932 } else {
03933 fprintf(d->trace, "-- %s\n", fn);
03934 }
03935 fflush(d->trace);
03936 }
03937 }
03938
03946 static void
03947 dbtracerc(DBC *d, int rc, char *err)
03948 {
03949 if (rc != SQLITE_OK && d->trace) {
03950 fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
03951 fprintf(d->trace, err ? ": %s\n" : "\n", err);
03952 fflush(d->trace);
03953 }
03954 }
03955
03970 static SQLRETURN
03971 dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
03972 char *spflag, char *ntflag, char *jmode, char *busy)
03973 {
03974 char *endp = NULL;
03975 int rc, tmp, busyto = 100000;
03976 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
03977 int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
03978 char *uname = name;
03979 const char *vfs_name = NULL;
03980 #endif
03981
03982 if (d->sqlite) {
03983 if (d->trace) {
03984 fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
03985 d->dbname);
03986 fflush(d->trace);
03987 }
03988 #if defined(HAVE_SQLITE3CLOSEV2) && (HAVE_SQLITE3CLOSEV2)
03989 sqlite3_close_v2(d->sqlite);
03990 #else
03991 sqlite3_close(d->sqlite);
03992 #endif
03993 d->sqlite = NULL;
03994 }
03995 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
03996 if (d->nocreat) {
03997 flags &= ~ SQLITE_OPEN_CREATE;
03998 }
03999 #if defined(_WIN32) || defined(_WIN64)
04000 if (!isu) {
04001 char expname[SQL_MAX_MESSAGE_LENGTH * 2];
04002
04003 expname[0] = '\0';
04004 rc = ExpandEnvironmentStrings(name, expname, sizeof (expname));
04005 if (rc <= sizeof (expname)) {
04006 uname = wmb_to_utf(expname, rc - 1);
04007 } else {
04008 uname = wmb_to_utf(name, -1);
04009 }
04010 if (!uname) {
04011 rc = SQLITE_NOMEM;
04012 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
04013 return SQL_ERROR;
04014 }
04015 }
04016 #endif
04017 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
04018 vfs_name = nvfs_makevfs(uname);
04019 #endif
04020 #ifdef SQLITE_OPEN_URI
04021 flags |= SQLITE_OPEN_URI;
04022 #endif
04023 rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
04024 #if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
04025 if (uname != name) {
04026 uc_free(uname);
04027 }
04028 #endif
04029 #else
04030 #if defined(_WIN32) || defined(_WIN64)
04031 if (d->nocreat) {
04032 char *cname = NULL;
04033
04034 if (isu) {
04035 cname = utf_to_wmb(name, -1);
04036 }
04037 if (GetFileAttributesA(cname ? cname : name) ==
04038 INVALID_FILE_ATTRIBUTES) {
04039 uc_free(cname);
04040 rc = SQLITE_CANTOPEN;
04041 setstatd(d, rc, "cannot open database",
04042 (*d->ov3) ? "HY000" : "S1000");
04043 return SQL_ERROR;
04044 }
04045 uc_free(cname);
04046 }
04047 #else
04048 if (d->nocreat && access(name, 004) < 0) {
04049 rc = SQLITE_CANTOPEN;
04050 setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
04051 return SQL_ERROR;
04052 }
04053 #endif
04054 #if defined(_WIN32) || defined(_WIN64)
04055 if (!isu) {
04056 WCHAR *wname = wmb_to_uc(name, -1);
04057
04058 if (!wname) {
04059 rc = SQLITE_NOMEM;
04060 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
04061 return SQL_ERROR;
04062 }
04063 rc = sqlite3_open16(wname, &d->sqlite);
04064 uc_free(wname);
04065 } else
04066 #endif
04067 rc = sqlite3_open(name, &d->sqlite);
04068 #endif
04069 if (rc != SQLITE_OK) {
04070 connfail:
04071 setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
04072 if (d->sqlite) {
04073 sqlite3_close(d->sqlite);
04074 d->sqlite = NULL;
04075 }
04076 return SQL_ERROR;
04077 }
04078 #if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
04079 if (d->pwd) {
04080 sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
04081 }
04082 #endif
04083 d->pwd = NULL;
04084 d->pwdLen = 0;
04085 if (d->trace) {
04086 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
04087 sqlite3_profile(d->sqlite, dbtrace, d);
04088 #else
04089 sqlite3_trace(d->sqlite, dbtrace, d);
04090 #endif
04091 }
04092 d->step_enable = getbool(sflag);
04093 d->trans_disable = getbool(ntflag);
04094 d->curtype = d->step_enable ?
04095 SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
04096 tmp = strtol(busy, &endp, 0);
04097 if (endp && *endp == '\0' && endp != busy) {
04098 busyto = tmp;
04099 }
04100 if (busyto < 1 || busyto > 1000000) {
04101 busyto = 1000000;
04102 }
04103 d->timeout = busyto;
04104 freep(&d->dbname);
04105 d->dbname = xstrdup(name);
04106 freep(&d->dsn);
04107 d->dsn = xstrdup(dsn);
04108 if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
04109 if (d->trace) {
04110 fprintf(d->trace, "-- sqlite3_close: '%s'\n",
04111 d->dbname);
04112 fflush(d->trace);
04113 }
04114 sqlite3_close(d->sqlite);
04115 d->sqlite = NULL;
04116 goto connfail;
04117 }
04118 if (!spflag || spflag[0] == '\0') {
04119 spflag = "NORMAL";
04120 }
04121 if (spflag[0] != '\0') {
04122 char syncp[128];
04123
04124 sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
04125 sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
04126 }
04127 if (jmode[0] != '\0') {
04128 char jourp[128];
04129
04130 sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
04131 sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
04132 }
04133 if (d->trace) {
04134 fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
04135 fflush(d->trace);
04136 }
04137 #if defined(_WIN32) || defined(_WIN64)
04138 {
04139 char pname[MAX_PATH];
04140 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
04141 FALSE, GetCurrentProcessId());
04142
04143 pname[0] = '\0';
04144 if (h) {
04145 HMODULE m = NULL, l = LoadLibrary("psapi.dll");
04146 DWORD need;
04147 typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
04148 typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
04149 epmfunc epm;
04150 gmbfunc gmb;
04151
04152 if (l) {
04153 epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
04154 gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
04155 if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
04156 gmb(h, m, pname, sizeof (pname));
04157 }
04158 FreeLibrary(l);
04159 }
04160 CloseHandle(h);
04161 }
04162 d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
04163 strncasecmp(pname, "MSQRY", 5) == 0;
04164 if (d->trace && d->xcelqrx) {
04165
04166 fprintf(d->trace, "-- enabled EXCEL quirks\n");
04167 fflush(d->trace);
04168 }
04169 }
04170 #endif
04171 sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
04172 d, blob_import, 0, 0);
04173 sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
04174 d, blob_export, 0, 0);
04175 return SQL_SUCCESS;
04176 }
04177
04184 static void
04185 dbloadext(DBC *d, char *exts)
04186 {
04187 #if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
04188 char *p;
04189 char path[SQL_MAX_MESSAGE_LENGTH];
04190 int plen = 0;
04191
04192 if (!d->sqlite) {
04193 return;
04194 }
04195 sqlite3_enable_load_extension(d->sqlite, 1);
04196 #if defined(_WIN32) || defined(_WIN64)
04197 GetModuleFileName(hModule, path, sizeof (path));
04198 p = strrchr(path, '\\');
04199 plen = p ? ((p + 1) - path) : 0;
04200 #endif
04201 do {
04202 p = strchr(exts, ',');
04203 if (p) {
04204 strncpy(path + plen, exts, p - exts);
04205 path[plen + (p - exts)] = '\0';
04206 } else {
04207 strcpy(path + plen, exts);
04208 }
04209 if (exts[0]) {
04210 char *errmsg = NULL;
04211 int rc;
04212 #if defined(_WIN32) || defined(_WIN64)
04213 int i;
04214 char *q;
04215
04216 q = path + plen;
04217 if (!(q[0] &&
04218 ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
04219 q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
04220 q = path;
04221 }
04222
04223 for (i = 0; q[i] != '\0'; i++) {
04224 if (q[i] == '\\') {
04225 q[i] = '/';
04226 }
04227 }
04228 rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
04229 #else
04230 rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
04231 #endif
04232 if (rc != SQLITE_OK) {
04233 #if defined(_WIN32) || defined(_WIN64)
04234 char buf[512], msg[512];
04235
04236 LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
04237 wsprintf(msg, buf, q, errmsg ?
04238 errmsg : "no error info available");
04239 LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
04240 MessageBox(NULL, msg, buf,
04241 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
04242 MB_SETFOREGROUND);
04243 #else
04244 fprintf(stderr, "extension '%s' did not load%s%s\n",
04245 path, errmsg ? ": " : "", errmsg ? errmsg : "");
04246 #endif
04247 }
04248 }
04249 if (p) {
04250 exts = p + 1;
04251 }
04252 } while (p);
04253 #endif
04254 }
04255
04262 static void
04263 dbattas(DBC *d, char *attas)
04264 {
04265 char *p;
04266 char as[SQL_MAX_MESSAGE_LENGTH];
04267
04268 if (!d->sqlite) {
04269 return;
04270 }
04271 do {
04272 p = strchr(attas, ',');
04273 if (p) {
04274 strncpy(as, attas, p - attas);
04275 as[p - attas] = '\0';
04276 } else {
04277 strcpy(as, attas);
04278 }
04279 if (attas[0]) {
04280 char *sql;
04281
04282 sql = sqlite3_mprintf("ATTACH %Q AS %s", d->dbname, as);
04283 if (sql != NULL) {
04284 sqlite3_exec(d->sqlite, sql, NULL, NULL, NULL);
04285 sqlite3_free(sql);
04286 }
04287 }
04288 if (p) {
04289 attas = p + 1;
04290 }
04291 } while (p);
04292 }
04293
04303 static char *
04304 s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
04305 {
04306 char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
04307 char guess[64];
04308
04309 guess[0] = '\0';
04310 if (!typename) {
04311 int coltype = sqlite3_column_type(s3stmt, col);
04312
04313 if (guessed_types) {
04314 guessed_types[0]++;
04315 }
04316 if (d->trace) {
04317 sprintf(guess, " (guessed from %d)", coltype);
04318 }
04319 switch (coltype) {
04320 case SQLITE_INTEGER: typename = "integer"; break;
04321 case SQLITE_FLOAT: typename = "double"; break;
04322 default:
04323 case SQLITE_TEXT: typename = "varchar"; break;
04324 case SQLITE_BLOB: typename = "blob"; break;
04325 #if 0
04326 case SQLITE_NULL: typename = "null"; break;
04327 #endif
04328 }
04329 }
04330 if (d->trace) {
04331 fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
04332 guess, typename);
04333 fflush(d->trace);
04334 }
04335 return typename;
04336 }
04337
04338 #ifdef FULL_METADATA
04339
04348 static void
04349 s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
04350 {
04351 int nn = 0, pk = 0, ai = 0;
04352 const char *dn = NULL, *tn = NULL, *cn = NULL, *dummy[4];
04353
04354 dn = sqlite3_column_database_name(s3stmt, col);
04355 tn = sqlite3_column_table_name(s3stmt, col);
04356 cn = sqlite3_column_origin_name(s3stmt, col);
04357 dummy[0] = dummy[1] = 0;
04358 if (tn && cn) {
04359 sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
04360 dummy, dummy + 1,
04361 &nn, &pk, &ai);
04362 }
04363 ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
04364 ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
04365 ci->ispk = pk ? 1 : 0;
04366 if (d->trace) {
04367 fprintf(d->trace, "-- column %d %s\n",
04368 col + 1, nn ? "notnull" : "nullable");
04369 if (ai) {
04370 fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
04371 }
04372 fflush(d->trace);
04373 }
04374 ci->isrowid = 0;
04375 if (ci->ispk && tn) {
04376 nn = pk = ai = 0;
04377 dummy[2] = dummy[3] = 0;
04378
04379 sqlite3_table_column_metadata(d->sqlite, dn, tn, "rowid",
04380 dummy + 2, dummy + 3,
04381 &nn, &pk, &ai);
04382 if (pk && dummy[0] && dummy[0] == dummy[2]) {
04383 ci->isrowid = 1;
04384 }
04385 }
04386 }
04387
04388 #endif
04389
04396 static int
04397 s3stmt_step(STMT *s)
04398 {
04399 DBC *d = (DBC *) s->dbc;
04400 char **rowd = NULL;
04401 const char *errp = NULL;
04402 int i, ncols, rc;
04403
04404 if (s != d->cur_s3stmt || !s->s3stmt) {
04405 setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
04406 return SQL_ERROR;
04407 }
04408 rc = sqlite3_step(s->s3stmt);
04409 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
04410 ++s->s3stmt_rownum;
04411 ncols = sqlite3_column_count(s->s3stmt);
04412 if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
04413 PTRDIFF_T size;
04414 char *p;
04415 COL *dyncols;
04416 const char *colname, *typename;
04417 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04418 char *tblname;
04419 #endif
04420 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
04421 char *dbname;
04422 #endif
04423
04424 for (i = size = 0; i < ncols; i++) {
04425 colname = sqlite3_column_name(s->s3stmt, i);
04426 size += 3 + 3 * strlen(colname);
04427 }
04428 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04429 tblname = (char *) size;
04430 for (i = 0; i < ncols; i++) {
04431 p = (char *) sqlite3_column_table_name(s->s3stmt, i);
04432 size += 2 + (p ? strlen(p) : 0);
04433 }
04434 #endif
04435 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
04436 dbname = (char *) size;
04437 for (i = 0; i < ncols; i++) {
04438 p = (char *) sqlite3_column_database_name(s->s3stmt, i);
04439 size += 2 + (p ? strlen(p) : 0);
04440 }
04441 #endif
04442 dyncols = xmalloc(ncols * sizeof (COL) + size);
04443 if (!dyncols) {
04444 freedyncols(s);
04445 s->ncols = 0;
04446 dbtraceapi(d, "sqlite3_finalize", 0);
04447 sqlite3_finalize(s->s3stmt);
04448 s->s3stmt = NULL;
04449 d->cur_s3stmt = NULL;
04450 return nomem(s);
04451 }
04452 p = (char *) (dyncols + ncols);
04453 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04454 tblname = p + (PTRDIFF_T) tblname;
04455 #endif
04456 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
04457 dbname = p + (PTRDIFF_T) dbname;
04458 #endif
04459 for (i = 0; i < ncols; i++) {
04460 char *q;
04461
04462 colname = sqlite3_column_name(s->s3stmt, i);
04463 if (d->trace) {
04464 fprintf(d->trace, "-- column %d name: '%s'\n",
04465 i + 1, colname);
04466 fflush(d->trace);
04467 }
04468 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04469 q = (char *) sqlite3_column_table_name(s->s3stmt, i);
04470 strcpy(tblname, q ? q : "");
04471 if (d->trace) {
04472 fprintf(d->trace, "-- table %d name: '%s'\n",
04473 i + 1, tblname);
04474 fflush(d->trace);
04475 }
04476 dyncols[i].table = tblname;
04477 tblname += strlen(tblname) + 1;
04478 #endif
04479 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
04480 q = (char *) sqlite3_column_database_name(s->s3stmt, i);
04481 strcpy(dbname, q ? q : "");
04482 if (d->trace) {
04483 fprintf(d->trace, "-- database %d name: '%s'\n",
04484 i + 1, dbname);
04485 fflush(d->trace);
04486 }
04487 dyncols[i].db = dbname;
04488 dbname += strlen(dbname) + 1;
04489 #else
04490 dyncols[i].db = ((DBC *) (s->dbc))->dbname;
04491 #endif
04492 typename = s3stmt_coltype(s->s3stmt, i, d, 0);
04493 strcpy(p, colname);
04494 dyncols[i].label = p;
04495 p += strlen(p) + 1;
04496 q = strchr(colname, '.');
04497 if (q) {
04498 char *q2 = strchr(q + 1, '.');
04499
04500
04501 if (q2) {
04502 q = q2;
04503 }
04504 }
04505 if (q) {
04506 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
04507 dyncols[i].table = p;
04508 #endif
04509 strncpy(p, colname, q - colname);
04510 p[q - colname] = '\0';
04511 p += strlen(p) + 1;
04512 strcpy(p, q + 1);
04513 dyncols[i].column = p;
04514 p += strlen(p) + 1;
04515 } else {
04516 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
04517 dyncols[i].table = "";
04518 #endif
04519 strcpy(p, colname);
04520 dyncols[i].column = p;
04521 p += strlen(p) + 1;
04522 }
04523 if (s->longnames) {
04524 dyncols[i].column = dyncols[i].label;
04525 }
04526 #ifdef SQL_LONGVARCHAR
04527 dyncols[i].type = SQL_LONGVARCHAR;
04528 dyncols[i].size = 65535;
04529 #else
04530 dyncols[i].type = SQL_VARCHAR;
04531 dyncols[i].size = 255;
04532 #endif
04533 dyncols[i].index = i;
04534 dyncols[i].scale = 0;
04535 dyncols[i].prec = 0;
04536 dyncols[i].nosign = 1;
04537 dyncols[i].autoinc = SQL_FALSE;
04538 dyncols[i].notnull = SQL_NULLABLE;
04539 dyncols[i].ispk = -1;
04540 dyncols[i].isrowid = -1;
04541 #ifdef FULL_METADATA
04542 s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
04543 #endif
04544 dyncols[i].typename = xstrdup(typename);
04545 }
04546 freedyncols(s);
04547 s->ncols = s->dcols = ncols;
04548 s->dyncols = s->cols = dyncols;
04549 fixupdyncols(s, d);
04550 mkbindcols(s, s->ncols);
04551 d->s3stmt_needmeta = 0;
04552 }
04553 if (ncols <= 0) {
04554 goto killstmt;
04555 }
04556 if (rc == SQLITE_DONE) {
04557 freeresult(s, 0);
04558 s->nrows = 0;
04559 dbtraceapi(d, "sqlite3_finalize", 0);
04560 sqlite3_finalize(s->s3stmt);
04561 s->s3stmt = NULL;
04562 d->cur_s3stmt = NULL;
04563 return SQL_SUCCESS;
04564 }
04565 rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
04566 if (rowd) {
04567 const unsigned char *value;
04568
04569 rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
04570 ++rowd;
04571 for (i = 0; i < ncols; i++) {
04572 int coltype = sqlite3_column_type(s->s3stmt, i);
04573
04574 rowd[i] = rowd[i + ncols] = NULL;
04575 if (coltype == SQLITE_BLOB) {
04576 int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
04577 char *qp;
04578 unsigned const char *bp;
04579
04580 bp = sqlite3_column_blob(s->s3stmt, i);
04581 qp = xmalloc(nbytes * 2 + 4);
04582 if (qp) {
04583 rowd[i + ncols] = qp;
04584 *qp++ = 'X';
04585 *qp++ = '\'';
04586 for (k = 0; k < nbytes; k++) {
04587 *qp++ = xdigits[(bp[k] >> 4)];
04588 *qp++ = xdigits[(bp[k] & 0xF)];
04589 }
04590 *qp++ = '\'';
04591 *qp = '\0';
04592 }
04593 #ifdef _MSC_VER
04594 } else if (coltype == SQLITE_FLOAT) {
04595 struct lconv *lc = 0;
04596 double d = sqlite3_column_double(s->s3stmt, i);
04597 char *p, buffer[128];
04598
04599
04600
04601
04602
04603
04604 snprintf(buffer, sizeof (buffer), "%.15g", d);
04605 lc = localeconv();
04606 if (lc && lc->decimal_point && lc->decimal_point[0] &&
04607 lc->decimal_point[0] != '.') {
04608 p = strchr(buffer, lc->decimal_point[0]);
04609 if (p) {
04610 *p = '.';
04611 }
04612 }
04613 rowd[i + ncols] = xstrdup(buffer);
04614 #endif
04615 } else if (coltype != SQLITE_NULL) {
04616 value = sqlite3_column_text(s->s3stmt, i);
04617 rowd[i + ncols] = xstrdup((char *) value);
04618 }
04619 }
04620 for (i = 0; i < ncols; i++) {
04621 int coltype = sqlite3_column_type(s->s3stmt, i);
04622
04623 value = NULL;
04624 if (coltype == SQLITE_BLOB) {
04625 value = sqlite3_column_blob(s->s3stmt, i);
04626 } else if (coltype != SQLITE_NULL) {
04627 value = sqlite3_column_text(s->s3stmt, i);
04628 }
04629 if (value && !rowd[i + ncols]) {
04630 freerows(rowd);
04631 rowd = 0;
04632 break;
04633 }
04634 }
04635 }
04636 if (rowd) {
04637 freeresult(s, 0);
04638 s->nrows = 1;
04639 s->rows = rowd;
04640 s->rowfree = freerows;
04641 if (rc == SQLITE_DONE) {
04642 dbtraceapi(d, "sqlite3_finalize", 0);
04643 sqlite3_finalize(s->s3stmt);
04644 s->s3stmt = NULL;
04645 d->cur_s3stmt = NULL;
04646 }
04647 return SQL_SUCCESS;
04648 }
04649 }
04650 killstmt:
04651 dbtraceapi(d, "sqlite3_reset", 0);
04652 rc = sqlite3_reset(s->s3stmt);
04653 s->s3stmt_noreset = 1;
04654 errp = sqlite3_errmsg(d->sqlite);
04655 if (d->cur_s3stmt == s) {
04656 d->cur_s3stmt = NULL;
04657 }
04658 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
04659 errp ? errp : "unknown error", rc);
04660 return SQL_ERROR;
04661 }
04662
04668 static void
04669 s3stmt_end(STMT *s)
04670 {
04671 DBC *d;
04672
04673 if (!s || !s->s3stmt) {
04674 return;
04675 }
04676 d = (DBC *) s->dbc;
04677 if (d) {
04678 d->busyint = 0;
04679 }
04680 if (!s->s3stmt_noreset) {
04681 dbtraceapi(d, "sqlite3_reset", 0);
04682 sqlite3_reset(s->s3stmt);
04683 s->s3stmt_noreset = 1;
04684 s->s3stmt_rownum = -1;
04685 }
04686 if (d->cur_s3stmt == s) {
04687 d->cur_s3stmt = NULL;
04688 }
04689 }
04690
04696 static void
04697 s3stmt_end_if(STMT *s)
04698 {
04699 DBC *d = (DBC *) s->dbc;
04700
04701 if (d) {
04702 d->busyint = 0;
04703 }
04704 if (d && d->cur_s3stmt == s) {
04705 s3stmt_end(s);
04706 }
04707 }
04708
04714 static void
04715 s3stmt_drop(STMT *s)
04716 {
04717 if (s->s3stmt) {
04718 DBC *d = (DBC *) s->dbc;
04719
04720 if (d) {
04721 dbtraceapi(d, "sqlite3_finalize", 0);
04722 }
04723 sqlite3_finalize(s->s3stmt);
04724 s->s3stmt = NULL;
04725 s->s3stmt_rownum = 0;
04726 }
04727 }
04728
04735 static SQLRETURN
04736 s3stmt_start(STMT *s)
04737 {
04738 DBC *d = (DBC *) s->dbc;
04739 const char *endp;
04740 sqlite3_stmt *s3stmt = NULL;
04741 int rc, nretry = 0;
04742
04743 d->s3stmt_needmeta = 0;
04744 if (!s->s3stmt) {
04745 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
04746 dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
04747 #else
04748 dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
04749 #endif
04750 do {
04751 s3stmt = NULL;
04752 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
04753 rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
04754 &s3stmt, &endp);
04755 #else
04756 rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
04757 &s3stmt, &endp);
04758 #endif
04759 if (rc != SQLITE_OK) {
04760 if (s3stmt) {
04761 sqlite3_finalize(s3stmt);
04762 s3stmt = NULL;
04763 }
04764 }
04765 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
04766 dbtracerc(d, rc, NULL);
04767 if (rc != SQLITE_OK) {
04768 if (s3stmt) {
04769 dbtraceapi(d, "sqlite3_finalize", NULL);
04770 sqlite3_finalize(s3stmt);
04771 }
04772 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
04773 sqlite3_errmsg(d->sqlite), rc);
04774 return SQL_ERROR;
04775 }
04776 if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
04777 dbtraceapi(d, "sqlite3_finalize", 0);
04778 sqlite3_finalize(s3stmt);
04779 setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
04780 (*s->ov3) ? "HY000" : "S1000");
04781 return SQL_ERROR;
04782 }
04783 s->s3stmt = s3stmt;
04784 s->s3stmt_noreset = 1;
04785 d->s3stmt_needmeta = 1;
04786 }
04787 d->cur_s3stmt = s;
04788 s->s3stmt_rownum = -1;
04789 s3bind(d, s->s3stmt, s->nparams, s->bindparms);
04790 return SQL_SUCCESS;
04791 }
04792
04793 #ifndef WINTERFACE
04794
04798 SQLRETURN SQL_API
04799 SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
04800 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
04801 SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
04802 {
04803 if (env == SQL_NULL_HENV) {
04804 return SQL_INVALID_HANDLE;
04805 }
04806 return SQL_ERROR;
04807 }
04808 #endif
04809
04810 #ifdef WINTERFACE
04811
04815 SQLRETURN SQL_API
04816 SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
04817 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
04818 SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
04819 {
04820 if (env == SQL_NULL_HENV) {
04821 return SQL_INVALID_HANDLE;
04822 }
04823 return SQL_ERROR;
04824 }
04825 #endif
04826
04827 #ifndef WINTERFACE
04828
04832 SQLRETURN SQL_API
04833 SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
04834 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
04835 SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
04836 {
04837 if (env == SQL_NULL_HENV) {
04838 return SQL_INVALID_HANDLE;
04839 }
04840 return SQL_ERROR;
04841 }
04842 #endif
04843
04844 #ifdef WINTERFACE
04845
04849 SQLRETURN SQL_API
04850 SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
04851 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
04852 SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
04853 {
04854 if (env == SQL_NULL_HENV) {
04855 return SQL_INVALID_HANDLE;
04856 }
04857 return SQL_ERROR;
04858 }
04859 #endif
04860
04861 #ifndef WINTERFACE
04862
04866 SQLRETURN SQL_API
04867 SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
04868 SQLCHAR *connout, SQLSMALLINT connoutMax,
04869 SQLSMALLINT *connoutLen)
04870 {
04871 SQLRETURN ret;
04872
04873 HDBC_LOCK(dbc);
04874 ret = drvunimpldbc(dbc);
04875 HDBC_UNLOCK(dbc);
04876 return ret;
04877 }
04878 #endif
04879
04880 #ifdef WINTERFACE
04881
04885 SQLRETURN SQL_API
04886 SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
04887 SQLWCHAR *connout, SQLSMALLINT connoutMax,
04888 SQLSMALLINT *connoutLen)
04889 {
04890 SQLRETURN ret;
04891
04892 HDBC_LOCK(dbc);
04893 ret = drvunimpldbc(dbc);
04894 HDBC_UNLOCK(dbc);
04895 return ret;
04896 }
04897 #endif
04898
04907 static SQLRETURN
04908 drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
04909 {
04910 STMT *s;
04911 int i, dlen, done = 0;
04912 BINDPARM *p;
04913
04914 if (stmt == SQL_NULL_HSTMT) {
04915 return SQL_INVALID_HANDLE;
04916 }
04917 s = (STMT *) stmt;
04918 if (!s->query || s->nparams <= 0) {
04919 seqerr:
04920 setstat(s, -1, "sequence error", "HY010");
04921 return SQL_ERROR;
04922 }
04923 for (i = (s->pdcount < 0) ? 0 : s->pdcount; i < s->nparams; i++) {
04924 p = &s->bindparms[i];
04925 if (p->need > 0) {
04926 int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
04927
04928 if (len == SQL_NULL_DATA) {
04929 freep(&p->parbuf);
04930 p->param = NULL;
04931 p->len = SQL_NULL_DATA;
04932 p->need = -1;
04933 } else if (type != SQL_C_CHAR
04934 #ifdef WCHARSUPPORT
04935 && type != SQL_C_WCHAR
04936 #endif
04937 && type != SQL_C_BINARY) {
04938 int size = 0;
04939
04940 switch (type) {
04941 case SQL_C_TINYINT:
04942 case SQL_C_UTINYINT:
04943 case SQL_C_STINYINT:
04944 #ifdef SQL_BIT
04945 case SQL_C_BIT:
04946 #endif
04947 size = sizeof (SQLCHAR);
04948 break;
04949 case SQL_C_SHORT:
04950 case SQL_C_USHORT:
04951 case SQL_C_SSHORT:
04952 size = sizeof (SQLSMALLINT);
04953 break;
04954 case SQL_C_LONG:
04955 case SQL_C_ULONG:
04956 case SQL_C_SLONG:
04957 size = sizeof (SQLINTEGER);
04958 break;
04959 #ifdef SQL_BIGINT
04960 case SQL_C_UBIGINT:
04961 case SQL_C_SBIGINT:
04962 size = sizeof (SQLBIGINT);
04963 break;
04964 #endif
04965 case SQL_C_FLOAT:
04966 size = sizeof (float);
04967 break;
04968 case SQL_C_DOUBLE:
04969 size = sizeof (double);
04970 break;
04971 #ifdef SQL_C_TYPE_DATE
04972 case SQL_C_TYPE_DATE:
04973 #endif
04974 case SQL_C_DATE:
04975 size = sizeof (DATE_STRUCT);
04976 break;
04977 #ifdef SQL_C_TYPE_DATE
04978 case SQL_C_TYPE_TIME:
04979 #endif
04980 case SQL_C_TIME:
04981 size = sizeof (TIME_STRUCT);
04982 break;
04983 #ifdef SQL_C_TYPE_DATE
04984 case SQL_C_TYPE_TIMESTAMP:
04985 #endif
04986 case SQL_C_TIMESTAMP:
04987 size = sizeof (TIMESTAMP_STRUCT);
04988 break;
04989 }
04990 freep(&p->parbuf);
04991 p->parbuf = xmalloc(size);
04992 if (!p->parbuf) {
04993 return nomem(s);
04994 }
04995 p->param = p->parbuf;
04996 memcpy(p->param, data, size);
04997 p->len = size;
04998 p->need = -1;
04999 } else if (len == SQL_NTS && (
05000 type == SQL_C_CHAR
05001 #ifdef WCHARSUPPORT
05002 || type == SQL_C_WCHAR
05003 #endif
05004 )) {
05005 char *dp = data;
05006
05007 #ifdef WCHARSUPPORT
05008 if (type == SQL_C_WCHAR) {
05009 dp = uc_to_utf(data, len);
05010 if (!dp) {
05011 return nomem(s);
05012 }
05013 }
05014 #endif
05015 #if defined(_WIN32) || defined(_WIN64)
05016 if (*s->oemcp) {
05017 dp = wmb_to_utf(data, strlen (data));
05018 if (!dp) {
05019 return nomem(s);
05020 }
05021 }
05022 #endif
05023 dlen = strlen(dp);
05024 freep(&p->parbuf);
05025 p->parbuf = xmalloc(dlen + 1);
05026 if (!p->parbuf) {
05027 if (dp != data) {
05028 uc_free(dp);
05029 }
05030 return nomem(s);
05031 }
05032 p->param = p->parbuf;
05033 strcpy(p->param, dp);
05034 if (dp != data) {
05035 uc_free(dp);
05036 }
05037 p->len = dlen;
05038 p->need = -1;
05039 } else if (len < 0) {
05040 setstat(s, -1, "invalid length", "HY090");
05041 return SQL_ERROR;
05042 } else {
05043 dlen = min(p->len - p->offs, len);
05044 if (!p->param) {
05045 setstat(s, -1, "no memory for parameter", "HY013");
05046 return SQL_ERROR;
05047 }
05048 memcpy((char *) p->param + p->offs, data, dlen);
05049 p->offs += dlen;
05050 if (p->offs >= p->len) {
05051 #ifdef WCHARSUPPORT
05052 if (type == SQL_C_WCHAR) {
05053 char *dp = uc_to_utf(p->param, p->len);
05054 char *np;
05055 int nlen;
05056
05057 if (!dp) {
05058 return nomem(s);
05059 }
05060 nlen = strlen(dp);
05061 np = xmalloc(nlen + 1);
05062 if (!np) {
05063 uc_free(dp);
05064 return nomem(s);
05065 }
05066 strcpy(np, dp);
05067 uc_free(dp);
05068 if (p->param == p->parbuf) {
05069 freep(&p->parbuf);
05070 }
05071 p->parbuf = p->param = np;
05072 p->len = nlen;
05073 } else {
05074 *((char *) p->param + p->len) = '\0';
05075 }
05076 p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
05077 ? -1 : 0;
05078 #else
05079 *((char *) p->param + p->len) = '\0';
05080 p->need = (type == SQL_C_CHAR) ? -1 : 0;
05081 #endif
05082 #if defined(_WIN32) || defined(_WIN64)
05083 if (type == SQL_C_CHAR && *s->oemcp &&
05084 !(p->stype == SQL_BINARY ||
05085 p->stype == SQL_VARBINARY ||
05086 p->stype == SQL_LONGVARBINARY)) {
05087 char *dp = wmb_to_utf(p->param, p->len);
05088
05089 if (!dp) {
05090 return nomem(s);
05091 }
05092 if (p->param == p->parbuf) {
05093 freep(&p->parbuf);
05094 }
05095 p->parbuf = p->param = dp;
05096 p->len = strlen(dp);
05097 }
05098 if (p->type == SQL_C_WCHAR &&
05099 (p->stype == SQL_VARCHAR ||
05100 p->stype == SQL_LONGVARCHAR) &&
05101 p->len == p->coldef * sizeof (SQLWCHAR)) {
05102
05103 p->len = p->coldef;
05104 }
05105 #endif
05106 }
05107 }
05108 done = 1;
05109 break;
05110 }
05111 }
05112 if (!done) {
05113 goto seqerr;
05114 }
05115 return SQL_SUCCESS;
05116 }
05117
05126 SQLRETURN SQL_API
05127 SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
05128 {
05129 SQLRETURN ret;
05130
05131 HSTMT_LOCK(stmt);
05132 ret = drvputdata(stmt, data, len);
05133 HSTMT_UNLOCK(stmt);
05134 return ret;
05135 }
05136
05142 static SQLRETURN
05143 freeparams(STMT *s)
05144 {
05145 if (s->bindparms) {
05146 int n;
05147
05148 for (n = 0; n < s->nbindparms; n++) {
05149 freep(&s->bindparms[n].parbuf);
05150 memset(&s->bindparms[n], 0, sizeof (BINDPARM));
05151 }
05152 }
05153 return SQL_SUCCESS;
05154 }
05155
05167 static SQLRETURN
05168 setupparam(STMT *s, char *sql, int pnum)
05169 {
05170 int type, len = 0, needalloc = 0;
05171 BINDPARM *p;
05172
05173 if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
05174 goto error;
05175 }
05176 p = &s->bindparms[pnum];
05177 type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
05178 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
05179
05180 if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
05181 type = SQL_C_CHAR;
05182 }
05183 #endif
05184 if (p->need > 0) {
05185 return setupparbuf(s, p);
05186 }
05187 p->strbuf[0] = '\0';
05188 if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
05189 p->s3type = SQLITE_NULL;
05190 p->s3size = 0;
05191 return SQL_SUCCESS;
05192 }
05193 if (type == SQL_C_CHAR &&
05194 (p->stype == SQL_BINARY ||
05195 p->stype == SQL_VARBINARY ||
05196 p->stype == SQL_LONGVARBINARY)) {
05197 type = SQL_C_BINARY;
05198 }
05199 switch (type) {
05200 case SQL_C_BINARY:
05201 p->s3type = SQLITE_BLOB;
05202 p->s3val = p->param;
05203 if (!p->lenp) {
05204 len = p->len;
05205 } else if (*p->lenp == SQL_DATA_AT_EXEC) {
05206 len = p->len;
05207 } else {
05208 len = *p->lenp;
05209 if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
05210 len = SQL_LEN_DATA_AT_EXEC(len);
05211 }
05212 }
05213 if (len < 0) {
05214 setstat(s, -1, "invalid length", "HY009");
05215 return SQL_ERROR;
05216 }
05217 p->len = len;
05218 p->max = p->len;
05219 p->s3size = len;
05220 break;
05221 #ifdef WCHARSUPPORT
05222 case SQL_C_WCHAR:
05223 #endif
05224 case SQL_C_CHAR:
05225 p->s3type = SQLITE_TEXT;
05226 p->s3size = -1;
05227 p->s3val = p->param;
05228 if (!p->parbuf) {
05229 #ifdef WCHARSUPPORT
05230 if (type == SQL_C_WCHAR) {
05231 if (!p->lenp || *p->lenp == SQL_NTS) {
05232 p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
05233 } else if (*p->lenp >= 0) {
05234 p->max = *p->lenp;
05235 }
05236 } else
05237 #endif
05238 if (type == SQL_C_CHAR) {
05239 if (!p->lenp || *p->lenp == SQL_NTS) {
05240 p->len = p->max = strlen(p->param);
05241 #if defined(_WIN32) || defined(_WIN64)
05242 needalloc = 1;
05243 #endif
05244 } else if (*p->lenp >= 0) {
05245 p->len = p->max = *p->lenp;
05246 needalloc = 1;
05247 }
05248 }
05249 }
05250 if (p->need < 0 && p->parbuf == p->param) {
05251 break;
05252 }
05253 #ifdef WCHARSUPPORT
05254 if (type == SQL_C_WCHAR) {
05255 char *dp = uc_to_utf(p->param, p->max);
05256
05257 if (!dp) {
05258 return nomem(s);
05259 }
05260 if (p->param == p->parbuf) {
05261 freep(&p->parbuf);
05262 }
05263 p->parbuf = p->param = dp;
05264 p->need = -1;
05265 p->len = strlen(p->param);
05266 p->s3val = p->param;
05267 p->s3size = p->len;
05268 } else
05269 #endif
05270 if (type == SQL_C_CHAR) {
05271 p->s3val = p->param;
05272 if (needalloc) {
05273 char *dp;
05274
05275 #if defined(_WIN32) || defined(_WIN64)
05276 if (*s->oemcp) {
05277 dp = wmb_to_utf(p->param, p->len);
05278 } else {
05279 dp = xmalloc(p->len + 1);
05280 }
05281 #else
05282 dp = xmalloc(p->len + 1);
05283 #endif
05284 if (!dp) {
05285 return nomem(s);
05286 }
05287 #if defined(_WIN32) || defined(_WIN64)
05288 if (*s->oemcp) {
05289 p->len = strlen(dp);
05290 } else {
05291 memcpy(dp, p->param, p->len);
05292 dp[p->len] = '\0';
05293 }
05294 #else
05295 memcpy(dp, p->param, p->len);
05296 dp[p->len] = '\0';
05297 #endif
05298 if (p->param == p->parbuf) {
05299 freep(&p->parbuf);
05300 }
05301 p->parbuf = p->param = dp;
05302 p->need = -1;
05303 p->s3val = p->param;
05304 p->s3size = p->len;
05305 }
05306 }
05307 break;
05308 case SQL_C_UTINYINT:
05309 case SQL_C_TINYINT:
05310 case SQL_C_STINYINT:
05311 p->s3type = SQLITE_INTEGER;
05312 p->s3size = sizeof (int);
05313 p->s3ival = *((SQLCHAR *) p->param);
05314 break;
05315 case SQL_C_USHORT:
05316 p->s3type = SQLITE_INTEGER;
05317 p->s3size = sizeof (int);
05318 p->s3ival = *((SQLUSMALLINT *) p->param);
05319 break;
05320 case SQL_C_SHORT:
05321 case SQL_C_SSHORT:
05322 p->s3type = SQLITE_INTEGER;
05323 p->s3size = sizeof (int);
05324 p->s3ival = *((SQLSMALLINT *) p->param);
05325 break;
05326 case SQL_C_ULONG:
05327 p->s3type = SQLITE_INTEGER;
05328 p->s3size = sizeof (int);
05329 p->s3ival = *((SQLUINTEGER *) p->param);
05330 break;
05331 case SQL_C_LONG:
05332 case SQL_C_SLONG:
05333 p->s3type = SQLITE_INTEGER;
05334 p->s3size = sizeof (int);
05335 p->s3ival = *((SQLINTEGER *) p->param);
05336 break;
05337 #ifdef SQL_BIT
05338 case SQL_C_BIT:
05339 p->s3type = SQLITE_INTEGER;
05340 p->s3size = sizeof (int);
05341 p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
05342 break;
05343 #endif
05344 #ifdef SQL_BIGINT
05345 case SQL_C_SBIGINT:
05346 p->s3type = SQLITE_INTEGER;
05347 p->s3size = sizeof (sqlite_int64);
05348 p->s3lival = *((sqlite_int64 *) p->param);
05349 break;
05350 case SQL_C_UBIGINT:
05351 p->s3type = SQLITE_INTEGER;
05352 p->s3size = sizeof (sqlite_int64);
05353 p->s3lival = *((sqlite_uint64 *) p->param);
05354 break;
05355 #endif
05356 case SQL_C_FLOAT:
05357 p->s3type = SQLITE_FLOAT;
05358 p->s3size = sizeof (double);
05359 p->s3dval = *((float *) p->param);
05360 break;
05361 case SQL_C_DOUBLE:
05362 p->s3type = SQLITE_FLOAT;
05363 p->s3size = sizeof (double);
05364 p->s3dval = *((double *) p->param);
05365 break;
05366 #ifdef SQL_C_TYPE_DATE
05367 case SQL_C_TYPE_DATE:
05368 #endif
05369 case SQL_C_DATE:
05370 if (*s->jdconv) {
05371 int a, b, x1, x2, y, m, d;
05372
05373 p->s3type = SQLITE_FLOAT;
05374 p->s3size = sizeof (double);
05375 y = ((DATE_STRUCT *) p->param)->year;
05376 m = ((DATE_STRUCT *) p->param)->month;
05377 d = ((DATE_STRUCT *) p->param)->day;
05378 if (m <= 2) {
05379 y--;
05380 m += 12;
05381 }
05382 a = y / 100;
05383 b = 2 - a + (a / 4);
05384 x1 = 36525 * (y + 4716) / 100;
05385 x2 = 306001 * (m + 1) / 10000;
05386 p->s3dval = x1 + x2 + d + b - 1524.5;
05387 break;
05388 }
05389 sprintf(p->strbuf, "%04d-%02d-%02d",
05390 ((DATE_STRUCT *) p->param)->year,
05391 ((DATE_STRUCT *) p->param)->month,
05392 ((DATE_STRUCT *) p->param)->day);
05393 p->s3type = SQLITE_TEXT;
05394 p->s3size = -1;
05395 p->s3val = p->strbuf;
05396 break;
05397 #ifdef SQL_C_TYPE_TIME
05398 case SQL_C_TYPE_TIME:
05399 #endif
05400 case SQL_C_TIME:
05401 if (*s->jdconv) {
05402 p->s3type = SQLITE_FLOAT;
05403 p->s3size = sizeof (double);
05404 p->s3dval = 2451544.5 +
05405 (((TIME_STRUCT *) p->param)->hour * 3600000.0 +
05406 ((TIME_STRUCT *) p->param)->minute * 60000.0 +
05407 ((TIME_STRUCT *) p->param)->second * 1000.0) / 86400000.0;
05408 break;
05409 }
05410 sprintf(p->strbuf, "%02d:%02d:%02d",
05411 ((TIME_STRUCT *) p->param)->hour,
05412 ((TIME_STRUCT *) p->param)->minute,
05413 ((TIME_STRUCT *) p->param)->second);
05414 p->s3type = SQLITE_TEXT;
05415 p->s3size = -1;
05416 p->s3val = p->strbuf;
05417 break;
05418 #ifdef SQL_C_TYPE_TIMESTAMP
05419 case SQL_C_TYPE_TIMESTAMP:
05420 #endif
05421 case SQL_C_TIMESTAMP:
05422 if (*s->jdconv) {
05423 int a, b, x1, x2, y, m, d;
05424
05425 p->s3type = SQLITE_FLOAT;
05426 p->s3size = sizeof (double);
05427 y = ((TIMESTAMP_STRUCT *) p->param)->year;
05428 m = ((TIMESTAMP_STRUCT *) p->param)->month;
05429 d = ((TIMESTAMP_STRUCT *) p->param)->day;
05430 if (m <= 2) {
05431 y--;
05432 m += 12;
05433 }
05434 a = y / 100;
05435 b = 2 - a + (a / 4);
05436 x1 = 36525 * (y + 4716) / 100;
05437 x2 = 306001 * (m + 1) / 10000;
05438 p->s3dval = x1 + x2 + d + b - 1524.5 +
05439 (((TIMESTAMP_STRUCT *) p->param)->hour * 3600000.0 +
05440 ((TIMESTAMP_STRUCT *) p->param)->minute * 60000.0 +
05441 ((TIMESTAMP_STRUCT *) p->param)->second * 1000.0 +
05442 ((TIMESTAMP_STRUCT *) p->param)->fraction / 1.0E6)
05443 / 86400000.0;
05444 break;
05445 }
05446 len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
05447 len /= 1000000;
05448 len = len % 1000;
05449 if (len < 0) {
05450 len = 0;
05451 }
05452 if (p->coldef && p->coldef <= 16) {
05453 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
05454 ((TIMESTAMP_STRUCT *) p->param)->year,
05455 ((TIMESTAMP_STRUCT *) p->param)->month,
05456 ((TIMESTAMP_STRUCT *) p->param)->day,
05457 ((TIMESTAMP_STRUCT *) p->param)->hour,
05458 ((TIMESTAMP_STRUCT *) p->param)->minute);
05459 } else if (p->coldef && p->coldef <= 19) {
05460 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
05461 ((TIMESTAMP_STRUCT *) p->param)->year,
05462 ((TIMESTAMP_STRUCT *) p->param)->month,
05463 ((TIMESTAMP_STRUCT *) p->param)->day,
05464 ((TIMESTAMP_STRUCT *) p->param)->hour,
05465 ((TIMESTAMP_STRUCT *) p->param)->minute,
05466 ((TIMESTAMP_STRUCT *) p->param)->second);
05467 } else {
05468 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
05469 ((TIMESTAMP_STRUCT *) p->param)->year,
05470 ((TIMESTAMP_STRUCT *) p->param)->month,
05471 ((TIMESTAMP_STRUCT *) p->param)->day,
05472 ((TIMESTAMP_STRUCT *) p->param)->hour,
05473 ((TIMESTAMP_STRUCT *) p->param)->minute,
05474 ((TIMESTAMP_STRUCT *) p->param)->second,
05475 len);
05476 }
05477 p->s3type = SQLITE_TEXT;
05478 p->s3size = -1;
05479 p->s3val = p->strbuf;
05480 break;
05481 default:
05482 error:
05483 setstat(s, -1, "unsupported parameter type",
05484 (*s->ov3) ? "07009" : "S1093");
05485 return SQL_ERROR;
05486 }
05487 return SQL_SUCCESS;
05488 }
05489
05505 static SQLRETURN
05506 drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
05507 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
05508 SQLSMALLINT scale,
05509 SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
05510 {
05511 STMT *s;
05512 BINDPARM *p;
05513
05514 if (stmt == SQL_NULL_HSTMT) {
05515 return SQL_INVALID_HANDLE;
05516 }
05517 s = (STMT *) stmt;
05518 if (pnum == 0) {
05519 setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
05520 return SQL_ERROR;
05521 }
05522 if (!data && !len) {
05523 setstat(s, -1, "invalid buffer", "HY003");
05524 return SQL_ERROR;
05525 }
05526 --pnum;
05527 if (s->bindparms) {
05528 if (pnum >= s->nbindparms) {
05529 BINDPARM *newparms;
05530
05531 newparms = xrealloc(s->bindparms,
05532 (pnum + 1) * sizeof (BINDPARM));
05533 if (!newparms) {
05534 outofmem:
05535 return nomem(s);
05536 }
05537 s->bindparms = newparms;
05538 memset(&s->bindparms[s->nbindparms], 0,
05539 (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
05540 s->nbindparms = pnum + 1;
05541 }
05542 } else {
05543 int npar = max(10, pnum + 1);
05544
05545 s->bindparms = xmalloc(npar * sizeof (BINDPARM));
05546 if (!s->bindparms) {
05547 goto outofmem;
05548 }
05549 memset(s->bindparms, 0, npar * sizeof (BINDPARM));
05550 s->nbindparms = npar;
05551 }
05552 switch (buftype) {
05553 case SQL_C_STINYINT:
05554 case SQL_C_UTINYINT:
05555 case SQL_C_TINYINT:
05556 #ifdef SQL_C_BIT
05557 case SQL_C_BIT:
05558 #endif
05559 buflen = sizeof (SQLCHAR);
05560 break;
05561 case SQL_C_SHORT:
05562 case SQL_C_USHORT:
05563 case SQL_C_SSHORT:
05564 buflen = sizeof (SQLSMALLINT);
05565 break;
05566 case SQL_C_SLONG:
05567 case SQL_C_ULONG:
05568 case SQL_C_LONG:
05569 buflen = sizeof (SQLINTEGER);
05570 break;
05571 case SQL_C_FLOAT:
05572 buflen = sizeof (float);
05573 break;
05574 case SQL_C_DOUBLE:
05575 buflen = sizeof (double);
05576 break;
05577 case SQL_C_TIMESTAMP:
05578 #ifdef SQL_C_TYPE_TIMESTAMP
05579 case SQL_C_TYPE_TIMESTAMP:
05580 #endif
05581 buflen = sizeof (TIMESTAMP_STRUCT);
05582 break;
05583 case SQL_C_TIME:
05584 #ifdef SQL_C_TYPE_TIME
05585 case SQL_C_TYPE_TIME:
05586 #endif
05587 buflen = sizeof (TIME_STRUCT);
05588 break;
05589 case SQL_C_DATE:
05590 #ifdef SQL_C_TYPE_DATE
05591 case SQL_C_TYPE_DATE:
05592 #endif
05593 buflen = sizeof (DATE_STRUCT);
05594 break;
05595 #ifdef SQL_C_UBIGINT
05596 case SQL_C_UBIGINT:
05597 buflen = sizeof (SQLBIGINT);
05598 break;
05599 #endif
05600 #ifdef SQL_C_SBIGINT
05601 case SQL_C_SBIGINT:
05602 buflen = sizeof (SQLBIGINT);
05603 break;
05604 #endif
05605 #ifdef SQL_C_BIGINT
05606 case SQL_C_BIGINT:
05607 buflen = sizeof (SQLBIGINT);
05608 break;
05609 #endif
05610 }
05611 p = &s->bindparms[pnum];
05612 p->type = buftype;
05613 p->stype = ptype;
05614 p->coldef = coldef;
05615 p->scale = scale;
05616 p->max = buflen;
05617 p->inc = buflen;
05618 p->lenp = p->lenp0 = len;
05619 p->offs = 0;
05620 p->len = 0;
05621 p->param0 = data;
05622 freep(&p->parbuf);
05623 p->param = p->param0;
05624 p->bound = 1;
05625 p->need = 0;
05626 return SQL_SUCCESS;
05627 }
05628
05644 SQLRETURN SQL_API
05645 SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
05646 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
05647 SQLSMALLINT scale,
05648 SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
05649 {
05650 SQLRETURN ret;
05651
05652 HSTMT_LOCK(stmt);
05653 ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
05654 scale, data, buflen, len);
05655 HSTMT_UNLOCK(stmt);
05656 return ret;
05657 }
05658
05659 #ifndef HAVE_IODBC
05660
05673 SQLRETURN SQL_API
05674 SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
05675 SQLSMALLINT ptype, SQLULEN lenprec,
05676 SQLSMALLINT scale, SQLPOINTER val,
05677 SQLLEN *lenp)
05678 {
05679 SQLRETURN ret;
05680
05681 HSTMT_LOCK(stmt);
05682 ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
05683 lenprec, scale, val, 0, lenp);
05684 HSTMT_UNLOCK(stmt);
05685 return ret;
05686 }
05687 #endif
05688
05696 SQLRETURN SQL_API
05697 SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
05698 {
05699 STMT *s;
05700 SQLSMALLINT dummy;
05701
05702 HSTMT_LOCK(stmt);
05703 if (stmt == SQL_NULL_HSTMT) {
05704 return SQL_INVALID_HANDLE;
05705 }
05706 s = (STMT *) stmt;
05707 if (!nparam) {
05708 nparam = &dummy;
05709 }
05710 *nparam = s->nparams;
05711 HSTMT_UNLOCK(stmt);
05712 return SQL_SUCCESS;
05713 }
05714
05722 static SQLRETURN
05723 setupparbuf(STMT *s, BINDPARM *p)
05724 {
05725 if (!p->parbuf) {
05726 if (*p->lenp == SQL_DATA_AT_EXEC) {
05727 p->len = p->max;
05728 } else {
05729 p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
05730 }
05731 if (p->len < 0 && p->len != SQL_NTS &&
05732 p->len != SQL_NULL_DATA) {
05733 setstat(s, -1, "invalid length", "HY009");
05734 return SQL_ERROR;
05735 }
05736 if (p->len >= 0) {
05737 p->parbuf = xmalloc(p->len + 2);
05738 if (!p->parbuf) {
05739 return nomem(s);
05740 }
05741 p->param = p->parbuf;
05742 } else {
05743 p->param = NULL;
05744 }
05745 }
05746 return SQL_NEED_DATA;
05747 }
05748
05756 SQLRETURN SQL_API
05757 SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
05758 {
05759 STMT *s;
05760 int i;
05761 SQLPOINTER dummy;
05762 SQLRETURN ret;
05763 BINDPARM *p;
05764
05765 HSTMT_LOCK(stmt);
05766 if (stmt == SQL_NULL_HSTMT) {
05767 return SQL_INVALID_HANDLE;
05768 }
05769 s = (STMT *) stmt;
05770 if (!pind) {
05771 pind = &dummy;
05772 }
05773 if (s->pdcount < s->nparams) {
05774 s->pdcount++;
05775 }
05776 for (i = 0; i < s->pdcount; i++) {
05777 p = &s->bindparms[i];
05778 if (p->need > 0) {
05779 int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
05780
05781 p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? -1 : 0;
05782 }
05783 }
05784 for (; i < s->nparams; i++) {
05785 p = &s->bindparms[i];
05786 if (p->need > 0) {
05787 *pind = (SQLPOINTER) p->param0;
05788 ret = setupparbuf(s, p);
05789 s->pdcount = i;
05790 goto done;
05791 }
05792 }
05793 ret = drvexecute(stmt, 0);
05794 done:
05795 HSTMT_UNLOCK(stmt);
05796 return ret;
05797 }
05798
05810 SQLRETURN SQL_API
05811 SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
05812 SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
05813 {
05814 STMT *s;
05815 SQLRETURN ret = SQL_ERROR;
05816
05817 HSTMT_LOCK(stmt);
05818 if (stmt == SQL_NULL_HSTMT) {
05819 return SQL_INVALID_HANDLE;
05820 }
05821 s = (STMT *) stmt;
05822 --pnum;
05823 if (pnum >= s->nparams) {
05824 setstat(s, -1, "invalid parameter index",
05825 (*s->ov3) ? "HY000" : "S1000");
05826 goto done;
05827 }
05828 if (dtype) {
05829 #ifdef SQL_LONGVARCHAR
05830 #ifdef WINTERFACE
05831 *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
05832 #else
05833 *dtype = SQL_LONGVARCHAR;
05834 #endif
05835 #else
05836 #ifdef WINTERFACE
05837 *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
05838 #else
05839 *dtype = SQL_VARCHAR;
05840 #endif
05841 #endif
05842 }
05843 if (size) {
05844 #ifdef SQL_LONGVARCHAR
05845 *size = 65536;
05846 #else
05847 *size = 255;
05848 #endif
05849 }
05850 if (decdigits) {
05851 *decdigits = 0;
05852 }
05853 if (nullable) {
05854 *nullable = SQL_NULLABLE;
05855 }
05856 ret = SQL_SUCCESS;
05857 done:
05858 HSTMT_UNLOCK(stmt);
05859 return ret;
05860 }
05861
05875 SQLRETURN SQL_API
05876 SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
05877 SQLSMALLINT sqltype, SQLULEN coldef,
05878 SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
05879 {
05880 SQLRETURN ret;
05881
05882 HSTMT_LOCK(stmt);
05883 ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
05884 type, sqltype, coldef, scale, val,
05885 SQL_SETPARAM_VALUE_MAX, nval);
05886 HSTMT_UNLOCK(stmt);
05887 return ret;
05888 }
05889
05894 SQLRETURN SQL_API
05895 SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
05896 {
05897 SQLRETURN ret;
05898
05899 HSTMT_LOCK(stmt);
05900 ret = drvunimplstmt(stmt);
05901 HSTMT_UNLOCK(stmt);
05902 return ret;
05903 }
05904
05905 #ifndef WINTERFACE
05906
05910 SQLRETURN SQL_API
05911 SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
05912 SQLSMALLINT fieldid, SQLPOINTER value,
05913 SQLINTEGER buflen, SQLINTEGER *strlen)
05914 {
05915 return SQL_ERROR;
05916 }
05917 #endif
05918
05919 #ifdef WINTERFACE
05920
05924 SQLRETURN SQL_API
05925 SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
05926 SQLSMALLINT fieldid, SQLPOINTER value,
05927 SQLINTEGER buflen, SQLINTEGER *strlen)
05928 {
05929 return SQL_ERROR;
05930 }
05931 #endif
05932
05933 #ifndef WINTERFACE
05934
05938 SQLRETURN SQL_API
05939 SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
05940 SQLSMALLINT fieldid, SQLPOINTER value,
05941 SQLINTEGER buflen)
05942 {
05943 return SQL_ERROR;
05944 }
05945 #endif
05946
05947 #ifdef WINTERFACE
05948
05952 SQLRETURN SQL_API
05953 SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
05954 SQLSMALLINT fieldid, SQLPOINTER value,
05955 SQLINTEGER buflen)
05956 {
05957 return SQL_ERROR;
05958 }
05959 #endif
05960
05961 #ifndef WINTERFACE
05962
05966 SQLRETURN SQL_API
05967 SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
05968 SQLCHAR *name, SQLSMALLINT buflen,
05969 SQLSMALLINT *strlen, SQLSMALLINT *type,
05970 SQLSMALLINT *subtype, SQLLEN *len,
05971 SQLSMALLINT *prec, SQLSMALLINT *scale,
05972 SQLSMALLINT *nullable)
05973 {
05974 return SQL_ERROR;
05975 }
05976 #endif
05977
05978 #ifdef WINTERFACE
05979
05983 SQLRETURN SQL_API
05984 SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
05985 SQLWCHAR *name, SQLSMALLINT buflen,
05986 SQLSMALLINT *strlen, SQLSMALLINT *type,
05987 SQLSMALLINT *subtype, SQLLEN *len,
05988 SQLSMALLINT *prec, SQLSMALLINT *scale,
05989 SQLSMALLINT *nullable)
05990 {
05991 return SQL_ERROR;
05992 }
05993 #endif
05994
05999 SQLRETURN SQL_API
06000 SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
06001 SQLSMALLINT type, SQLSMALLINT subtype,
06002 SQLLEN len, SQLSMALLINT prec,
06003 SQLSMALLINT scale, SQLPOINTER data,
06004 SQLLEN *strlen, SQLLEN *indicator)
06005 {
06006 return SQL_ERROR;
06007 }
06008
06020 static SQLRETURN
06021 mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
06022 int ncols3, int *nret)
06023 {
06024 STMT *s;
06025 DBC *d;
06026
06027 if (stmt == SQL_NULL_HSTMT) {
06028 return SQL_INVALID_HANDLE;
06029 }
06030 s = (STMT *) stmt;
06031 if (s->dbc == SQL_NULL_HDBC) {
06032 noconn:
06033 return noconn(s);
06034 }
06035 d = (DBC *) s->dbc;
06036 if (!d->sqlite) {
06037 goto noconn;
06038 }
06039 s3stmt_end_if(s);
06040 freeresult(s, 0);
06041 if (colspec3 && *s->ov3) {
06042 s->ncols = ncols3;
06043 s->cols = colspec3;
06044 } else {
06045 s->ncols = ncols;
06046 s->cols = colspec;
06047 }
06048 mkbindcols(s, s->ncols);
06049 s->nowchar[1] = 1;
06050 s->nrows = 0;
06051 s->rowp = s->rowprs = -1;
06052 s->isselect = -1;
06053 if (nret) {
06054 *nret = s->ncols;
06055 }
06056 return SQL_SUCCESS;
06057 }
06058
06063 static COL tablePrivSpec2[] = {
06064 { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
06065 { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
06066 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
06067 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
06068 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
06069 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
06070 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
06071 };
06072
06073 static COL tablePrivSpec3[] = {
06074 { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
06075 { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
06076 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
06077 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
06078 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
06079 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
06080 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
06081 };
06082
06095 static SQLRETURN
06096 drvtableprivileges(SQLHSTMT stmt,
06097 SQLCHAR *cat, SQLSMALLINT catLen,
06098 SQLCHAR *schema, SQLSMALLINT schemaLen,
06099 SQLCHAR *table, SQLSMALLINT tableLen)
06100 {
06101 SQLRETURN ret;
06102 STMT *s;
06103 DBC *d;
06104 int ncols, rc, size, npatt;
06105 char *errp = NULL, *sql, tname[512];
06106
06107 ret = mkresultset(stmt, tablePrivSpec2, array_size(tablePrivSpec2),
06108 tablePrivSpec3, array_size(tablePrivSpec3), NULL);
06109 if (ret != SQL_SUCCESS) {
06110 return ret;
06111 }
06112 s = (STMT *) stmt;
06113 d = (DBC *) s->dbc;
06114 if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
06115 table = NULL;
06116 goto doit;
06117 }
06118 if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
06119 schema[0] == '%') {
06120 if ((!cat || catLen == 0 || !cat[0]) &&
06121 (!table || tableLen == 0 || !table[0])) {
06122 table = NULL;
06123 goto doit;
06124 }
06125 }
06126 doit:
06127 if (!table) {
06128 size = 1;
06129 tname[0] = '%';
06130 } else {
06131 if (tableLen == SQL_NTS) {
06132 size = sizeof (tname) - 1;
06133 } else {
06134 size = min(sizeof (tname) - 1, tableLen);
06135 }
06136 strncpy(tname, (char *) table, size);
06137 }
06138 tname[size] = '\0';
06139 npatt = unescpat(tname);
06140 #if defined(_WIN32) || defined(_WIN64)
06141 if (npatt) {
06142 sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
06143 "%s as 'TABLE_OWNER', "
06144 "tbl_name as 'TABLE_NAME', "
06145 "'' as 'GRANTOR', "
06146 "'' as 'GRANTEE', "
06147 "'SELECT' AS 'PRIVILEGE', "
06148 "NULL as 'IS_GRANTABLE' "
06149 "from sqlite_master where "
06150 "(type = 'table' or type = 'view') "
06151 "and tbl_name like %Q "
06152 "UNION "
06153 "select %s as 'TABLE_QUALIFIER', "
06154 "%s as 'TABLE_OWNER', "
06155 "tbl_name as 'TABLE_NAME', "
06156 "'' as 'GRANTOR', "
06157 "'' as 'GRANTEE', "
06158 "'UPDATE' AS 'PRIVILEGE', "
06159 "NULL as 'IS_GRANTABLE' "
06160 "from sqlite_master where "
06161 "(type = 'table' or type = 'view') "
06162 "and tbl_name like %Q "
06163 "UNION "
06164 "select %s as 'TABLE_QUALIFIER', "
06165 "%s as 'TABLE_OWNER', "
06166 "tbl_name as 'TABLE_NAME', "
06167 "'' as 'GRANTOR', "
06168 "'' as 'GRANTEE', "
06169 "'DELETE' AS 'PRIVILEGE', "
06170 "NULL as 'IS_GRANTABLE' "
06171 "from sqlite_master where "
06172 "(type = 'table' or type = 'view') "
06173 "and tbl_name like %Q "
06174 "UNION "
06175 "select %s as 'TABLE_QUALIFIER', "
06176 "%s as 'TABLE_OWNER', "
06177 "tbl_name as 'TABLE_NAME', "
06178 "'' as 'GRANTOR', "
06179 "'' as 'GRANTEE', "
06180 "'INSERT' AS 'PRIVILEGE', "
06181 "NULL as 'IS_GRANTABLE' "
06182 "from sqlite_master where "
06183 "(type = 'table' or type = 'view') "
06184 "and tbl_name like %Q "
06185 "UNION "
06186 "select %s as 'TABLE_QUALIFIER', "
06187 "%s as 'TABLE_OWNER', "
06188 "tbl_name as 'TABLE_NAME', "
06189 "'' as 'GRANTOR', "
06190 "'' as 'GRANTEE', "
06191 "'REFERENCES' AS 'PRIVILEGE', "
06192 "NULL as 'IS_GRANTABLE' "
06193 "from sqlite_master where "
06194 "(type = 'table' or type = 'view') "
06195 "and tbl_name like %Q",
06196 d->xcelqrx ? "'main'" : "NULL",
06197 d->xcelqrx ? "''" : "NULL",
06198 tname,
06199 d->xcelqrx ? "'main'" : "NULL",
06200 d->xcelqrx ? "''" : "NULL",
06201 tname,
06202 d->xcelqrx ? "'main'" : "NULL",
06203 d->xcelqrx ? "''" : "NULL",
06204 tname,
06205 d->xcelqrx ? "'main'" : "NULL",
06206 d->xcelqrx ? "''" : "NULL",
06207 tname,
06208 d->xcelqrx ? "'main'" : "NULL",
06209 d->xcelqrx ? "''" : "NULL",
06210 tname);
06211 } else {
06212 sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
06213 "%s as 'TABLE_OWNER', "
06214 "tbl_name as 'TABLE_NAME', "
06215 "'' as 'GRANTOR', "
06216 "'' as 'GRANTEE', "
06217 "'SELECT' AS 'PRIVILEGE', "
06218 "NULL as 'IS_GRANTABLE' "
06219 "from sqlite_master where "
06220 "(type = 'table' or type = 'view') "
06221 "and lower(tbl_name) = lower(%Q) "
06222 "UNION "
06223 "select %s as 'TABLE_QUALIFIER', "
06224 "%s as 'TABLE_OWNER', "
06225 "tbl_name as 'TABLE_NAME', "
06226 "'' as 'GRANTOR', "
06227 "'' as 'GRANTEE', "
06228 "'UPDATE' AS 'PRIVILEGE', "
06229 "NULL as 'IS_GRANTABLE' "
06230 "from sqlite_master where "
06231 "(type = 'table' or type = 'view') "
06232 "and lower(tbl_name) = lower(%Q) "
06233 "UNION "
06234 "select %s as 'TABLE_QUALIFIER', "
06235 "%s as 'TABLE_OWNER', "
06236 "tbl_name as 'TABLE_NAME', "
06237 "'' as 'GRANTOR', "
06238 "'' as 'GRANTEE', "
06239 "'DELETE' AS 'PRIVILEGE', "
06240 "NULL as 'IS_GRANTABLE' "
06241 "from sqlite_master where "
06242 "(type = 'table' or type = 'view') "
06243 "and lower(tbl_name) = lower(%Q) "
06244 "UNION "
06245 "select %s as 'TABLE_QUALIFIER', "
06246 "%s as 'TABLE_OWNER', "
06247 "tbl_name as 'TABLE_NAME', "
06248 "'' as 'GRANTOR', "
06249 "'' as 'GRANTEE', "
06250 "'INSERT' AS 'PRIVILEGE', "
06251 "NULL as 'IS_GRANTABLE' "
06252 "from sqlite_master where "
06253 "(type = 'table' or type = 'view') "
06254 "and lower(tbl_name) = lower(%Q) "
06255 "UNION "
06256 "select %s as 'TABLE_QUALIFIER', "
06257 "%s as 'TABLE_OWNER', "
06258 "tbl_name as 'TABLE_NAME', "
06259 "'' as 'GRANTOR', "
06260 "'' as 'GRANTEE', "
06261 "'REFERENCES' AS 'PRIVILEGE', "
06262 "NULL as 'IS_GRANTABLE' "
06263 "from sqlite_master where "
06264 "(type = 'table' or type = 'view') "
06265 "and lower(tbl_name) = lower(%Q)",
06266 d->xcelqrx ? "'main'" : "NULL",
06267 d->xcelqrx ? "''" : "NULL",
06268 tname,
06269 d->xcelqrx ? "'main'" : "NULL",
06270 d->xcelqrx ? "''" : "NULL",
06271 tname,
06272 d->xcelqrx ? "'main'" : "NULL",
06273 d->xcelqrx ? "''" : "NULL",
06274 tname,
06275 d->xcelqrx ? "'main'" : "NULL",
06276 d->xcelqrx ? "''" : "NULL",
06277 tname,
06278 d->xcelqrx ? "'main'" : "NULL",
06279 d->xcelqrx ? "''" : "NULL",
06280 tname);
06281 }
06282 #else
06283 if (npatt) {
06284 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
06285 "NULL as 'TABLE_OWNER', "
06286 "tbl_name as 'TABLE_NAME', "
06287 "'' as 'GRANTOR', "
06288 "'' as 'GRANTEE', "
06289 "'SELECT' AS 'PRIVILEGE', "
06290 "NULL as 'IS_GRANTABLE' "
06291 "from sqlite_master where "
06292 "(type = 'table' or type = 'view') "
06293 "and tbl_name like %Q "
06294 "UNION "
06295 "select NULL as 'TABLE_QUALIFIER', "
06296 "NULL as 'TABLE_OWNER', "
06297 "tbl_name as 'TABLE_NAME', "
06298 "'' as 'GRANTOR', "
06299 "'' as 'GRANTEE', "
06300 "'UPDATE' AS 'PRIVILEGE', "
06301 "NULL as 'IS_GRANTABLE' "
06302 "from sqlite_master where "
06303 "(type = 'table' or type = 'view') "
06304 "and tbl_name like %Q "
06305 "UNION "
06306 "select NULL as 'TABLE_QUALIFIER', "
06307 "NULL as 'TABLE_OWNER', "
06308 "tbl_name as 'TABLE_NAME', "
06309 "'' as 'GRANTOR', "
06310 "'' as 'GRANTEE', "
06311 "'DELETE' AS 'PRIVILEGE', "
06312 "NULL as 'IS_GRANTABLE' "
06313 "from sqlite_master where "
06314 "(type = 'table' or type = 'view') "
06315 "and tbl_name like %Q "
06316 "UNION "
06317 "select NULL as 'TABLE_QUALIFIER', "
06318 "NULL as 'TABLE_OWNER', "
06319 "tbl_name as 'TABLE_NAME', "
06320 "'' as 'GRANTOR', "
06321 "'' as 'GRANTEE', "
06322 "'INSERT' AS 'PRIVILEGE', "
06323 "NULL as 'IS_GRANTABLE' "
06324 "from sqlite_master where "
06325 "(type = 'table' or type = 'view') "
06326 "and tbl_name like %Q "
06327 "UNION "
06328 "select NULL as 'TABLE_QUALIFIER', "
06329 "NULL as 'TABLE_OWNER', "
06330 "tbl_name as 'TABLE_NAME', "
06331 "'' as 'GRANTOR', "
06332 "'' as 'GRANTEE', "
06333 "'REFERENCES' AS 'PRIVILEGE', "
06334 "NULL as 'IS_GRANTABLE' "
06335 "from sqlite_master where "
06336 "(type = 'table' or type = 'view') "
06337 "and tbl_name like %Q",
06338 tname, tname, tname, tname, tname);
06339 } else {
06340 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
06341 "NULL as 'TABLE_OWNER', "
06342 "tbl_name as 'TABLE_NAME', "
06343 "'' as 'GRANTOR', "
06344 "'' as 'GRANTEE', "
06345 "'SELECT' AS 'PRIVILEGE', "
06346 "NULL as 'IS_GRANTABLE' "
06347 "from sqlite_master where "
06348 "(type = 'table' or type = 'view') "
06349 "and lower(tbl_name) = lower(%Q) "
06350 "UNION "
06351 "select NULL as 'TABLE_QUALIFIER', "
06352 "NULL as 'TABLE_OWNER', "
06353 "tbl_name as 'TABLE_NAME', "
06354 "'' as 'GRANTOR', "
06355 "'' as 'GRANTEE', "
06356 "'UPDATE' AS 'PRIVILEGE', "
06357 "NULL as 'IS_GRANTABLE' "
06358 "from sqlite_master where "
06359 "(type = 'table' or type = 'view') "
06360 "and lower(tbl_name) = lower(%Q) "
06361 "UNION "
06362 "select NULL as 'TABLE_QUALIFIER', "
06363 "NULL as 'TABLE_OWNER', "
06364 "tbl_name as 'TABLE_NAME', "
06365 "'' as 'GRANTOR', "
06366 "'' as 'GRANTEE', "
06367 "'DELETE' AS 'PRIVILEGE', "
06368 "NULL as 'IS_GRANTABLE' "
06369 "from sqlite_master where "
06370 "(type = 'table' or type = 'view') "
06371 "and lower(tbl_name) = lower(%Q) "
06372 "UNION "
06373 "select NULL as 'TABLE_QUALIFIER', "
06374 "NULL as 'TABLE_OWNER', "
06375 "tbl_name as 'TABLE_NAME', "
06376 "'' as 'GRANTOR', "
06377 "'' as 'GRANTEE', "
06378 "'INSERT' AS 'PRIVILEGE', "
06379 "NULL as 'IS_GRANTABLE' "
06380 "from sqlite_master where "
06381 "(type = 'table' or type = 'view') "
06382 "and lower(tbl_name) = lower(%Q) "
06383 "UNION "
06384 "select NULL as 'TABLE_QUALIFIER', "
06385 "NULL as 'TABLE_OWNER', "
06386 "tbl_name as 'TABLE_NAME', "
06387 "'' as 'GRANTOR', "
06388 "'' as 'GRANTEE', "
06389 "'REFERENCES' AS 'PRIVILEGE', "
06390 "NULL as 'IS_GRANTABLE' "
06391 "from sqlite_master where "
06392 "(type = 'table' or type = 'view') "
06393 "and lower(tbl_name) = lower(%Q)",
06394 tname, tname, tname, tname, tname);
06395 }
06396 #endif
06397 if (!sql) {
06398 return nomem(s);
06399 }
06400 ret = starttran(s);
06401 if (ret != SQL_SUCCESS) {
06402 sqlite3_free(sql);
06403 return ret;
06404 }
06405 dbtraceapi(d, "sqlite3_get_table", sql);
06406 rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
06407 sqlite3_free(sql);
06408 if (rc == SQLITE_OK) {
06409 if (ncols != s->ncols) {
06410 freeresult(s, 0);
06411 s->nrows = 0;
06412 } else {
06413 s->rowfree = sqlite3_free_table;
06414 }
06415 } else {
06416 s->nrows = 0;
06417 s->rows = NULL;
06418 s->rowfree = NULL;
06419 }
06420 if (errp) {
06421 sqlite3_free(errp);
06422 errp = NULL;
06423 }
06424 s->rowp = s->rowprs = -1;
06425 return SQL_SUCCESS;
06426 }
06427
06428
06429 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
06430
06442 SQLRETURN SQL_API
06443 SQLTablePrivileges(SQLHSTMT stmt,
06444 SQLCHAR *catalog, SQLSMALLINT catalogLen,
06445 SQLCHAR *schema, SQLSMALLINT schemaLen,
06446 SQLCHAR *table, SQLSMALLINT tableLen)
06447 {
06448 #if defined(_WIN32) || defined(_WIN64)
06449 char *c = NULL, *s = NULL, *t = NULL;
06450 #endif
06451 SQLRETURN ret;
06452
06453 HSTMT_LOCK(stmt);
06454 #if defined(_WIN32) || defined(_WIN64)
06455 if (!((STMT *) stmt)->oemcp[0]) {
06456 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
06457 table, tableLen);
06458 goto done2;
06459 }
06460 if (catalog) {
06461 c = wmb_to_utf_c((char *) catalog, catalogLen);
06462 if (!c) {
06463 ret = nomem((STMT *) stmt);
06464 goto done;
06465 }
06466 }
06467 if (schema) {
06468 s = wmb_to_utf_c((char *) schema, schemaLen);
06469 if (!s) {
06470 ret = nomem((STMT *) stmt);
06471 goto done;
06472 }
06473 }
06474 if (table) {
06475 t = wmb_to_utf_c((char *) table, tableLen);
06476 if (!t) {
06477 ret = nomem((STMT *) stmt);
06478 goto done;
06479 }
06480 }
06481 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
06482 (SQLCHAR *) s, SQL_NTS,
06483 (SQLCHAR *) t, SQL_NTS);
06484 #else
06485 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
06486 table, tableLen);
06487 #endif
06488 #if defined(_WIN32) || defined(_WIN64)
06489 done:
06490 uc_free(t);
06491 uc_free(s);
06492 uc_free(c);
06493 done2:
06494 ;
06495 #endif
06496 HSTMT_UNLOCK(stmt);
06497 return ret;
06498 }
06499 #endif
06500
06501 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
06502 #ifdef WINTERFACE
06503
06515 SQLRETURN SQL_API
06516 SQLTablePrivilegesW(SQLHSTMT stmt,
06517 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
06518 SQLWCHAR *schema, SQLSMALLINT schemaLen,
06519 SQLWCHAR *table, SQLSMALLINT tableLen)
06520 {
06521 char *c = NULL, *s = NULL, *t = NULL;
06522 SQLRETURN ret;
06523
06524 HSTMT_LOCK(stmt);
06525 if (catalog) {
06526 c = uc_to_utf_c(catalog, catalogLen);
06527 if (!c) {
06528 ret = nomem((STMT *) stmt);
06529 goto done;
06530 }
06531 }
06532 if (schema) {
06533 s = uc_to_utf_c(schema, schemaLen);
06534 if (!s) {
06535 ret = nomem((STMT *) stmt);
06536 goto done;
06537 }
06538 }
06539 if (table) {
06540 t = uc_to_utf_c(table, tableLen);
06541 if (!t) {
06542 ret = nomem((STMT *) stmt);
06543 goto done;
06544 }
06545 }
06546 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
06547 (SQLCHAR *) s, SQL_NTS,
06548 (SQLCHAR *) t, SQL_NTS);
06549 done:
06550 uc_free(t);
06551 uc_free(s);
06552 uc_free(c);
06553 HSTMT_UNLOCK(stmt);
06554 return ret;
06555 }
06556 #endif
06557 #endif
06558
06563 static COL colPrivSpec2[] = {
06564 { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
06565 { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
06566 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
06567 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06568 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
06569 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
06570 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
06571 };
06572
06573 static COL colPrivSpec3[] = {
06574 { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
06575 { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
06576 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
06577 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06578 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
06579 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
06580 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
06581 };
06582
06583 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
06584
06598 SQLRETURN SQL_API
06599 SQLColumnPrivileges(SQLHSTMT stmt,
06600 SQLCHAR *catalog, SQLSMALLINT catalogLen,
06601 SQLCHAR *schema, SQLSMALLINT schemaLen,
06602 SQLCHAR *table, SQLSMALLINT tableLen,
06603 SQLCHAR *column, SQLSMALLINT columnLen)
06604 {
06605 SQLRETURN ret;
06606
06607 HSTMT_LOCK(stmt);
06608 ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
06609 colPrivSpec3, array_size(colPrivSpec3), NULL);
06610 HSTMT_UNLOCK(stmt);
06611 return ret;
06612 }
06613 #endif
06614
06615 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
06616 #ifdef WINTERFACE
06617
06631 SQLRETURN SQL_API
06632 SQLColumnPrivilegesW(SQLHSTMT stmt,
06633 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
06634 SQLWCHAR *schema, SQLSMALLINT schemaLen,
06635 SQLWCHAR *table, SQLSMALLINT tableLen,
06636 SQLWCHAR *column, SQLSMALLINT columnLen)
06637 {
06638 SQLRETURN ret;
06639
06640 HSTMT_LOCK(stmt);
06641 ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
06642 colPrivSpec3, array_size(colPrivSpec3), NULL);
06643 HSTMT_UNLOCK(stmt);
06644 return ret;
06645 }
06646 #endif
06647 #endif
06648
06653 static COL pkeySpec2[] = {
06654 { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
06655 { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
06656 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
06657 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06658 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
06659 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
06660 };
06661
06662 static COL pkeySpec3[] = {
06663 { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
06664 { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
06665 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
06666 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06667 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
06668 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
06669 };
06670
06683 static SQLRETURN
06684 drvprimarykeys(SQLHSTMT stmt,
06685 SQLCHAR *cat, SQLSMALLINT catLen,
06686 SQLCHAR *schema, SQLSMALLINT schemaLen,
06687 SQLCHAR *table, SQLSMALLINT tableLen)
06688 {
06689 STMT *s;
06690 DBC *d;
06691 SQLRETURN sret;
06692 int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
06693 int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
06694 PTRDIFF_T size;
06695 char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
06696
06697 sret = mkresultset(stmt, pkeySpec2, array_size(pkeySpec2),
06698 pkeySpec3, array_size(pkeySpec3), &asize);
06699 if (sret != SQL_SUCCESS) {
06700 return sret;
06701 }
06702 s = (STMT *) stmt;
06703 d = (DBC *) s->dbc;
06704 if (!table || table[0] == '\0' || table[0] == '%') {
06705 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
06706 return SQL_ERROR;
06707 }
06708 if (tableLen == SQL_NTS) {
06709 size = sizeof (tname) - 1;
06710 } else {
06711 size = min(sizeof (tname) - 1, tableLen);
06712 }
06713 strncpy(tname, (char *) table, size);
06714 tname[size] = '\0';
06715 unescpat(tname);
06716 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
06717 if (!sql) {
06718 return nomem(s);
06719 }
06720 sret = starttran(s);
06721 if (sret != SQL_SUCCESS) {
06722 sqlite3_free(sql);
06723 return sret;
06724 }
06725 dbtraceapi(d, "sqlite3_get_table", sql);
06726 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
06727 sqlite3_free(sql);
06728 if (ret != SQLITE_OK) {
06729 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
06730 errp ? errp : "unknown error", ret);
06731 if (errp) {
06732 sqlite3_free(errp);
06733 errp = NULL;
06734 }
06735 return SQL_ERROR;
06736 }
06737 if (errp) {
06738 sqlite3_free(errp);
06739 errp = NULL;
06740 }
06741 size = 0;
06742 if (ncols * nrows > 0) {
06743 int typec;
06744
06745 namec = findcol(rowp, ncols, "name");
06746 uniquec = findcol(rowp, ncols, "pk");
06747 typec = findcol(rowp, ncols, "type");
06748 if (namec >= 0 && uniquec >= 0 && typec >= 0) {
06749 for (i = 1; i <= nrows; i++) {
06750 if (*rowp[i * ncols + uniquec] != '0') {
06751 size++;
06752 }
06753 }
06754 }
06755 }
06756 if (size == 0) {
06757 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
06758 if (!sql) {
06759 sqlite3_free_table(rowp);
06760 return nomem(s);
06761 }
06762 dbtraceapi(d, "sqlite3_get_table", sql);
06763 ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
06764 &errp);
06765 sqlite3_free(sql);
06766 if (ret != SQLITE_OK) {
06767 sqlite3_free_table(rowp);
06768 sqlite3_free_table(rowp2);
06769 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
06770 errp ? errp : "unknown error", ret);
06771 if (errp) {
06772 sqlite3_free(errp);
06773 errp = NULL;
06774 }
06775 return SQL_ERROR;
06776 }
06777 if (errp) {
06778 sqlite3_free(errp);
06779 errp = NULL;
06780 }
06781 }
06782 if (ncols2 * nrows2 > 0) {
06783 namec2 = findcol(rowp2, ncols2, "name");
06784 uniquec2 = findcol(rowp2, ncols2, "unique");
06785 if (namec2 >= 0 && uniquec2 >= 0) {
06786 for (i = 1; i <= nrows2; i++) {
06787 int nnrows, nncols, nlen = 0;
06788 char **rowpp;
06789
06790 if (rowp2[i * ncols2 + namec2]) {
06791 nlen = strlen(rowp2[i * ncols2 + namec2]);
06792 }
06793 if (nlen < 17 ||
06794 strncmp(rowp2[i * ncols2 + namec2],
06795 "sqlite_autoindex_", 17)) {
06796 continue;
06797 }
06798 if (*rowp2[i * ncols2 + uniquec2] != '0') {
06799 ret = SQLITE_ERROR;
06800 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06801 rowp2[i * ncols2 + namec2]);
06802 if (sql) {
06803 dbtraceapi(d, "sqlite3_get_table", sql);
06804 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06805 &nnrows, &nncols, NULL);
06806 sqlite3_free(sql);
06807 }
06808 if (ret == SQLITE_OK) {
06809 size += nnrows;
06810 sqlite3_free_table(rowpp);
06811 }
06812 }
06813 }
06814 }
06815 }
06816 if (size == 0) {
06817 sqlite3_free_table(rowp);
06818 sqlite3_free_table(rowp2);
06819 return SQL_SUCCESS;
06820 }
06821 s->nrows = size;
06822 size = (size + 1) * asize;
06823 s->rows = xmalloc((size + 1) * sizeof (char *));
06824 if (!s->rows) {
06825 s->nrows = 0;
06826 sqlite3_free_table(rowp);
06827 sqlite3_free_table(rowp2);
06828 return nomem(s);
06829 }
06830 s->rows[0] = (char *) size;
06831 s->rows += 1;
06832 memset(s->rows, 0, sizeof (char *) * size);
06833 s->rowfree = freerows;
06834 offs = s->ncols;
06835 if (rowp) {
06836 for (i = 1; i <= nrows; i++) {
06837 if (*rowp[i * ncols + uniquec] != '0') {
06838 char buf[32];
06839
06840 #if defined(_WIN32) || defined(_WIN64)
06841 s->rows[offs + 0] = xstrdup(d->xcelqrx ? "main" : "");
06842 s->rows[offs + 1] = xstrdup("");
06843 #else
06844 s->rows[offs + 0] = xstrdup("");
06845 s->rows[offs + 1] = xstrdup("");
06846 #endif
06847 s->rows[offs + 2] = xstrdup(tname);
06848 s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
06849 sprintf(buf, "%d", seq++);
06850 s->rows[offs + 4] = xstrdup(buf);
06851 offs += s->ncols;
06852 }
06853 }
06854 }
06855 if (rowp2) {
06856 for (i = 1; i <= nrows2; i++) {
06857 int nnrows, nncols, nlen = 0;
06858 char **rowpp;
06859
06860 if (rowp2[i * ncols2 + namec2]) {
06861 nlen = strlen(rowp2[i * ncols2 + namec2]);
06862 }
06863 if (nlen < 17 ||
06864 strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
06865 continue;
06866 }
06867 if (*rowp2[i * ncols2 + uniquec2] != '0') {
06868 int k;
06869
06870 ret = SQLITE_ERROR;
06871 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06872 rowp2[i * ncols2 + namec2]);
06873 if (sql) {
06874 dbtraceapi(d, "sqlite3_get_table", sql);
06875 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06876 &nnrows, &nncols, NULL);
06877 sqlite3_free(sql);
06878 }
06879 if (ret != SQLITE_OK) {
06880 continue;
06881 }
06882 for (k = 0; nnrows && k < nncols; k++) {
06883 if (strcmp(rowpp[k], "name") == 0) {
06884 int m;
06885
06886 for (m = 1; m <= nnrows; m++) {
06887 int roffs = offs + (m - 1) * s->ncols;
06888
06889 #if defined(_WIN32) || defined(_WIN64)
06890 s->rows[roffs + 0] =
06891 xstrdup(d->xcelqrx ? "main" : "");
06892 s->rows[roffs + 1] = xstrdup("");
06893 #else
06894 s->rows[roffs + 0] = xstrdup("");
06895 s->rows[roffs + 1] = xstrdup("");
06896 #endif
06897 s->rows[roffs + 2] = xstrdup(tname);
06898 s->rows[roffs + 3] =
06899 xstrdup(rowpp[m * nncols + k]);
06900 s->rows[roffs + 5] =
06901 xstrdup(rowp2[i * ncols2 + namec2]);
06902 }
06903 } else if (strcmp(rowpp[k], "seqno") == 0) {
06904 int m;
06905
06906 for (m = 1; m <= nnrows; m++) {
06907 int roffs = offs + (m - 1) * s->ncols;
06908 int pos = m - 1;
06909 char buf[32];
06910
06911 sscanf(rowpp[m * nncols + k], "%d", &pos);
06912 sprintf(buf, "%d", pos + 1);
06913 s->rows[roffs + 4] = xstrdup(buf);
06914 }
06915 }
06916 }
06917 offs += nnrows * s->ncols;
06918 sqlite3_free_table(rowpp);
06919 }
06920 }
06921 }
06922 sqlite3_free_table(rowp);
06923 sqlite3_free_table(rowp2);
06924 return SQL_SUCCESS;
06925 }
06926
06927 #ifndef WINTERFACE
06928
06940 SQLRETURN SQL_API
06941 SQLPrimaryKeys(SQLHSTMT stmt,
06942 SQLCHAR *cat, SQLSMALLINT catLen,
06943 SQLCHAR *schema, SQLSMALLINT schemaLen,
06944 SQLCHAR *table, SQLSMALLINT tableLen)
06945 {
06946 #if defined(_WIN32) || defined(_WIN64)
06947 char *c = NULL, *s = NULL, *t = NULL;
06948 #endif
06949 SQLRETURN ret;
06950
06951 HSTMT_LOCK(stmt);
06952 #if defined(_WIN32) || defined(_WIN64)
06953 if (!((STMT *) stmt)->oemcp[0]) {
06954 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
06955 table, tableLen);
06956 goto done2;
06957 }
06958 if (cat) {
06959 c = wmb_to_utf_c((char *) cat, catLen);
06960 if (!c) {
06961 ret = nomem((STMT *) stmt);
06962 goto done;
06963 }
06964 }
06965 if (schema) {
06966 s = wmb_to_utf_c((char *) schema, schemaLen);
06967 if (!s) {
06968 ret = nomem((STMT *) stmt);
06969 goto done;
06970 }
06971 }
06972 if (table) {
06973 t = wmb_to_utf_c((char *) table, tableLen);
06974 if (!t) {
06975 ret = nomem((STMT *) stmt);
06976 goto done;
06977 }
06978 }
06979 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
06980 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
06981 #else
06982 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
06983 table, tableLen);
06984 #endif
06985 #if defined(_WIN32) || defined(_WIN64)
06986 done:
06987 uc_free(t);
06988 uc_free(s);
06989 uc_free(c);
06990 done2:
06991 ;
06992 #endif
06993 HSTMT_UNLOCK(stmt);
06994 return ret;
06995 }
06996 #endif
06997
06998 #ifdef WINTERFACE
06999
07011 SQLRETURN SQL_API
07012 SQLPrimaryKeysW(SQLHSTMT stmt,
07013 SQLWCHAR *cat, SQLSMALLINT catLen,
07014 SQLWCHAR *schema, SQLSMALLINT schemaLen,
07015 SQLWCHAR *table, SQLSMALLINT tableLen)
07016 {
07017 char *c = NULL, *s = NULL, *t = NULL;
07018 SQLRETURN ret;
07019
07020 HSTMT_LOCK(stmt);
07021 if (cat) {
07022 c = uc_to_utf_c(cat, catLen);
07023 if (!c) {
07024 ret = nomem((STMT *) stmt);
07025 goto done;
07026 }
07027 }
07028 if (schema) {
07029 s = uc_to_utf_c(schema, schemaLen);
07030 if (!s) {
07031 ret = nomem((STMT *) stmt);
07032 goto done;
07033 }
07034 }
07035 if (table) {
07036 t = uc_to_utf_c(table, tableLen);
07037 if (!t) {
07038 ret = nomem((STMT *) stmt);
07039 goto done;
07040 }
07041 }
07042 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
07043 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
07044 done:
07045 uc_free(t);
07046 uc_free(s);
07047 uc_free(c);
07048 HSTMT_UNLOCK(stmt);
07049 return ret;
07050 }
07051 #endif
07052
07057 static COL scolSpec2[] = {
07058 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
07059 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
07060 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
07061 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
07062 { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
07063 { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
07064 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
07065 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
07066 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
07067 };
07068
07069 static COL scolSpec3[] = {
07070 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
07071 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
07072 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
07073 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
07074 { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
07075 { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
07076 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
07077 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
07078 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
07079 };
07080
07096 static SQLRETURN
07097 drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
07098 SQLCHAR *cat, SQLSMALLINT catLen,
07099 SQLCHAR *schema, SQLSMALLINT schemaLen,
07100 SQLCHAR *table, SQLSMALLINT tableLen,
07101 SQLUSMALLINT scope, SQLUSMALLINT nullable)
07102 {
07103 STMT *s;
07104 DBC *d;
07105 SQLRETURN sret;
07106 int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
07107 PTRDIFF_T size;
07108 int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
07109 int notnullcc = -1, mkrowid = 0;
07110 char *errp = NULL, *sql, tname[512];
07111 char **rowp = NULL, **rowppp = NULL;
07112
07113 sret = mkresultset(stmt, scolSpec2, array_size(scolSpec2),
07114 scolSpec3, array_size(scolSpec3), &asize);
07115 if (sret != SQL_SUCCESS) {
07116 return sret;
07117 }
07118 s = (STMT *) stmt;
07119 d = (DBC *) s->dbc;
07120 if (!table || table[0] == '\0' || table[0] == '%') {
07121 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
07122 return SQL_ERROR;
07123 }
07124 if (tableLen == SQL_NTS) {
07125 size = sizeof (tname) - 1;
07126 } else {
07127 size = min(sizeof (tname) - 1, tableLen);
07128 }
07129 strncpy(tname, (char *) table, size);
07130 tname[size] = '\0';
07131 unescpat(tname);
07132 if (id != SQL_BEST_ROWID) {
07133 return SQL_SUCCESS;
07134 }
07135 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
07136 if (!sql) {
07137 return nomem(s);
07138 }
07139 sret = starttran(s);
07140 if (sret != SQL_SUCCESS) {
07141 sqlite3_free(sql);
07142 return sret;
07143 }
07144 dbtraceapi(d, "sqlite3_get_table", sql);
07145 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
07146 sqlite3_free(sql);
07147 if (ret != SQLITE_OK) {
07148 doerr:
07149 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
07150 errp ? errp : "unknown error", ret);
07151 if (errp) {
07152 sqlite3_free(errp);
07153 errp = NULL;
07154 }
07155 return SQL_ERROR;
07156 }
07157 if (errp) {
07158 sqlite3_free(errp);
07159 errp = NULL;
07160 }
07161 size = 0;
07162 if (ncols * nrows <= 0) {
07163 goto nodata_but_rowid;
07164 }
07165 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
07166 if (!sql) {
07167 return nomem(s);
07168 }
07169 dbtraceapi(d, "sqlite3_get_table", sql);
07170 ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
07171 &errp);
07172 sqlite3_free(sql);
07173 if (ret != SQLITE_OK) {
07174 sqlite3_free_table(rowp);
07175 goto doerr;
07176 }
07177 if (errp) {
07178 sqlite3_free(errp);
07179 errp = NULL;
07180 }
07181 namec = findcol(rowp, ncols, "name");
07182 uniquec = findcol(rowp, ncols, "unique");
07183 if (namec < 0 || uniquec < 0) {
07184 goto nodata_but_rowid;
07185 }
07186 namecc = findcol(rowppp, nnncols, "name");
07187 typecc = findcol(rowppp, nnncols, "type");
07188 notnullcc = findcol(rowppp, nnncols, "notnull");
07189 for (i = 1; i <= nrows; i++) {
07190 int nnrows, nncols;
07191 char **rowpp = NULL;
07192
07193 if (*rowp[i * ncols + uniquec] != '0') {
07194 ret = SQLITE_ERROR;
07195 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
07196 rowp[i * ncols + namec]);
07197 if (sql) {
07198 dbtraceapi(d, "sqlite3_get_table", sql);
07199 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
07200 &nnrows, &nncols, NULL);
07201 sqlite3_free(sql);
07202 }
07203 if (ret == SQLITE_OK) {
07204 size += nnrows;
07205 sqlite3_free_table(rowpp);
07206 }
07207 }
07208 }
07209 nodata_but_rowid:
07210 if (size == 0) {
07211 size = 1;
07212 mkrowid = 1;
07213 }
07214 s->nrows = size;
07215 size = (size + 1) * asize;
07216 s->rows = xmalloc((size + 1) * sizeof (char *));
07217 if (!s->rows) {
07218 s->nrows = 0;
07219 sqlite3_free_table(rowp);
07220 sqlite3_free_table(rowppp);
07221 return nomem(s);
07222 }
07223 s->rows[0] = (char *) size;
07224 s->rows += 1;
07225 memset(s->rows, 0, sizeof (char *) * size);
07226 s->rowfree = freerows;
07227 if (mkrowid) {
07228 s->nrows = 0;
07229 goto mkrowid;
07230 }
07231 offs = 0;
07232 for (i = 1; i <= nrows; i++) {
07233 int nnrows, nncols;
07234 char **rowpp = NULL;
07235
07236 if (*rowp[i * ncols + uniquec] != '0') {
07237 int k;
07238
07239 ret = SQLITE_ERROR;
07240 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
07241 rowp[i * ncols + namec]);
07242 if (sql) {
07243 dbtraceapi(d, "sqlite3_get_table", sql);
07244 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
07245 &nnrows, &nncols, NULL);
07246 sqlite3_free(sql);
07247 }
07248 if (ret != SQLITE_OK) {
07249 continue;
07250 }
07251 for (k = 0; nnrows && k < nncols; k++) {
07252 if (strcmp(rowpp[k], "name") == 0) {
07253 int m;
07254
07255 for (m = 1; m <= nnrows; m++) {
07256 int roffs = (offs + m) * s->ncols;
07257
07258 s->rows[roffs + 0] =
07259 xstrdup(stringify(SQL_SCOPE_SESSION));
07260 s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
07261 s->rows[roffs + 4] = xstrdup("0");
07262 s->rows[roffs + 7] =
07263 xstrdup(stringify(SQL_PC_NOT_PSEUDO));
07264 if (namecc >= 0 && typecc >= 0) {
07265 int ii;
07266
07267 for (ii = 1; ii <= nnnrows; ii++) {
07268 if (strcmp(rowppp[ii * nnncols + namecc],
07269 rowpp[m * nncols + k]) == 0) {
07270 char *typen = rowppp[ii * nnncols + typecc];
07271 int sqltype, mm, dd, isnullable = 0;
07272 char buf[32];
07273
07274 s->rows[roffs + 3] = xstrdup(typen);
07275 sqltype = mapsqltype(typen, NULL, *s->ov3,
07276 s->nowchar[0],
07277 s->dobigint);
07278 getmd(typen, sqltype, &mm, &dd);
07279 #ifdef SQL_LONGVARCHAR
07280 if (sqltype == SQL_VARCHAR && mm > 255) {
07281 sqltype = SQL_LONGVARCHAR;
07282 }
07283 #endif
07284 #ifdef WINTERFACE
07285 #ifdef SQL_WLONGVARCHAR
07286 if (sqltype == SQL_WVARCHAR && mm > 255) {
07287 sqltype = SQL_WLONGVARCHAR;
07288 }
07289 #endif
07290 #endif
07291 if (sqltype == SQL_VARBINARY && mm > 255) {
07292 sqltype = SQL_LONGVARBINARY;
07293 }
07294 sprintf(buf, "%d", sqltype);
07295 s->rows[roffs + 2] = xstrdup(buf);
07296 sprintf(buf, "%d", mm);
07297 s->rows[roffs + 5] = xstrdup(buf);
07298 sprintf(buf, "%d", dd);
07299 s->rows[roffs + 6] = xstrdup(buf);
07300 if (notnullcc >= 0) {
07301 char *inp =
07302 rowppp[ii * nnncols + notnullcc];
07303
07304 isnullable = inp[0] != '0';
07305 }
07306 sprintf(buf, "%d", isnullable);
07307 s->rows[roffs + 8] = xstrdup(buf);
07308 }
07309 }
07310 }
07311 }
07312 }
07313 }
07314 offs += nnrows;
07315 sqlite3_free_table(rowpp);
07316 }
07317 }
07318 if (nullable == SQL_NO_NULLS) {
07319 for (i = 1; i < s->nrows; i++) {
07320 if (s->rows[i * s->ncols + 8][0] == '0') {
07321 int m, i1 = i + 1;
07322
07323 for (m = 0; m < s->ncols; m++) {
07324 freep(&s->rows[i * s->ncols + m]);
07325 }
07326 size = s->ncols * sizeof (char *) * (s->nrows - i1);
07327 if (size > 0) {
07328 memmove(s->rows + i * s->ncols,
07329 s->rows + i1 * s->ncols,
07330 size);
07331 memset(s->rows + s->nrows * s->ncols, 0,
07332 s->ncols * sizeof (char *));
07333 }
07334 s->nrows--;
07335 --i;
07336 }
07337 }
07338 }
07339 mkrowid:
07340 sqlite3_free_table(rowp);
07341 sqlite3_free_table(rowppp);
07342 if (s->nrows == 0) {
07343 s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
07344 s->rows[s->ncols + 1] = xstrdup("_ROWID_");
07345 s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
07346 s->rows[s->ncols + 3] = xstrdup("integer");
07347 s->rows[s->ncols + 4] = xstrdup("0");
07348 s->rows[s->ncols + 5] = xstrdup("10");
07349 s->rows[s->ncols + 6] = xstrdup("9");
07350 s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
07351 s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
07352 s->nrows = 1;
07353 }
07354 return SQL_SUCCESS;
07355 }
07356
07357 #ifndef WINTERFACE
07358
07373 SQLRETURN SQL_API
07374 SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
07375 SQLCHAR *cat, SQLSMALLINT catLen,
07376 SQLCHAR *schema, SQLSMALLINT schemaLen,
07377 SQLCHAR *table, SQLSMALLINT tableLen,
07378 SQLUSMALLINT scope, SQLUSMALLINT nullable)
07379 {
07380 #if defined(_WIN32) || defined(_WIN64)
07381 char *c = NULL, *s = NULL, *t = NULL;
07382 #endif
07383 SQLRETURN ret;
07384
07385 HSTMT_LOCK(stmt);
07386 #if defined(_WIN32) || defined(_WIN64)
07387 if (!((STMT *) stmt)->oemcp[0]) {
07388 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
07389 table, tableLen, scope, nullable);
07390 goto done2;
07391 }
07392 if (cat) {
07393 c = wmb_to_utf_c((char *) cat, catLen);
07394 if (!c) {
07395 ret = nomem((STMT *) stmt);
07396 goto done;
07397 }
07398 }
07399 if (schema) {
07400 s = wmb_to_utf_c((char *) schema, schemaLen);
07401 if (!s) {
07402 ret = nomem((STMT *) stmt);
07403 goto done;
07404 }
07405 }
07406 if (table) {
07407 t = wmb_to_utf_c((char *) table, tableLen);
07408 if (!t) {
07409 ret = nomem((STMT *) stmt);
07410 goto done;
07411 }
07412 }
07413 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
07414 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
07415 scope, nullable);
07416 #else
07417 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
07418 table, tableLen, scope, nullable);
07419 #endif
07420 #if defined(_WIN32) || defined(_WIN64)
07421 done:
07422 uc_free(t);
07423 uc_free(s);
07424 uc_free(c);
07425 done2:
07426 ;
07427 #endif
07428 HSTMT_UNLOCK(stmt);
07429 return ret;
07430 }
07431 #endif
07432
07433 #ifdef WINTERFACE
07434
07449 SQLRETURN SQL_API
07450 SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
07451 SQLWCHAR *cat, SQLSMALLINT catLen,
07452 SQLWCHAR *schema, SQLSMALLINT schemaLen,
07453 SQLWCHAR *table, SQLSMALLINT tableLen,
07454 SQLUSMALLINT scope, SQLUSMALLINT nullable)
07455 {
07456 char *c = NULL, *s = NULL, *t = NULL;
07457 SQLRETURN ret;
07458
07459 HSTMT_LOCK(stmt);
07460 if (cat) {
07461 c = uc_to_utf_c(cat, catLen);
07462 if (!c) {
07463 ret = nomem((STMT *) stmt);
07464 goto done;
07465 }
07466 }
07467 if (schema) {
07468 s = uc_to_utf_c(schema, schemaLen);
07469 if (!s) {
07470 ret = nomem((STMT *) stmt);
07471 goto done;
07472 }
07473 }
07474 if (table) {
07475 t = uc_to_utf_c(table, tableLen);
07476 if (!t) {
07477 ret = nomem((STMT *) stmt);
07478 goto done;
07479 }
07480 }
07481 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
07482 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
07483 scope, nullable);
07484 done:
07485 uc_free(t);
07486 uc_free(s);
07487 uc_free(c);
07488 HSTMT_UNLOCK(stmt);
07489 return ret;
07490 }
07491 #endif
07492
07497 static COL fkeySpec2[] = {
07498 { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
07499 { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
07500 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
07501 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
07502 { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
07503 { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
07504 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
07505 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
07506 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
07507 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
07508 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
07509 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
07510 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
07511 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
07512 };
07513
07514 static COL fkeySpec3[] = {
07515 { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
07516 { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
07517 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
07518 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
07519 { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
07520 { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
07521 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
07522 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
07523 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
07524 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
07525 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
07526 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
07527 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
07528 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
07529 };
07530
07549 static SQLRETURN SQL_API
07550 drvforeignkeys(SQLHSTMT stmt,
07551 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
07552 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
07553 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
07554 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
07555 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
07556 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
07557 {
07558 STMT *s;
07559 DBC *d;
07560 SQLRETURN sret;
07561 int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
07562 int onu, ond;
07563 PTRDIFF_T size;
07564 char **rowp, *errp = NULL, *sql, pname[512], fname[512];
07565
07566 sret = mkresultset(stmt, fkeySpec2, array_size(fkeySpec2),
07567 fkeySpec3, array_size(fkeySpec3), &asize);
07568 if (sret != SQL_SUCCESS) {
07569 return sret;
07570 }
07571 s = (STMT *) stmt;
07572 sret = starttran(s);
07573 if (sret != SQL_SUCCESS) {
07574 return sret;
07575 }
07576 d = (DBC *) s->dbc;
07577 if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
07578 (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
07579 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
07580 return SQL_ERROR;
07581 }
07582 size = 0;
07583 if (PKtable) {
07584 if (PKtableLen == SQL_NTS) {
07585 size = sizeof (pname) - 1;
07586 } else {
07587 size = min(sizeof (pname) - 1, PKtableLen);
07588 }
07589 strncpy(pname, (char *) PKtable, size);
07590 }
07591 pname[size] = '\0';
07592 size = 0;
07593 if (FKtable) {
07594
07595 if (FKtableLen == SQL_NTS) {
07596 size = sizeof (fname) - 1;
07597 } else {
07598 size = min(sizeof (fname) - 1, FKtableLen);
07599 }
07600 strncpy(fname, (char *) FKtable, size);
07601 }
07602 fname[size] = '\0';
07603 if (fname[0] != '\0') {
07604 int plen;
07605
07606 ret = SQLITE_ERROR;
07607 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
07608 if (sql) {
07609 dbtraceapi(d, "sqlite3_get_table", sql);
07610 ret = sqlite3_get_table(d->sqlite, sql, &rowp,
07611 &nrows, &ncols, &errp);
07612 sqlite3_free(sql);
07613 }
07614 if (ret != SQLITE_OK) {
07615 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
07616 errp ? errp : "unknown error", ret);
07617 if (errp) {
07618 sqlite3_free(errp);
07619 errp = NULL;
07620 }
07621 return SQL_ERROR;
07622 }
07623 if (errp) {
07624 sqlite3_free(errp);
07625 errp = NULL;
07626 }
07627 if (ncols * nrows <= 0) {
07628 nodata:
07629 sqlite3_free_table(rowp);
07630 return SQL_SUCCESS;
07631 }
07632 size = 0;
07633 namec = findcol(rowp, ncols, "table");
07634 seqc = findcol(rowp, ncols, "seq");
07635 fromc = findcol(rowp, ncols, "from");
07636 toc = findcol(rowp, ncols, "to");
07637 onu = findcol(rowp, ncols, "on_update");
07638 ond = findcol(rowp, ncols, "on_delete");
07639 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
07640 goto nodata;
07641 }
07642 plen = strlen(pname);
07643 for (i = 1; i <= nrows; i++) {
07644 char *ptab = unquote(rowp[i * ncols + namec]);
07645
07646 if (plen && ptab) {
07647 int len = strlen(ptab);
07648
07649 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
07650 continue;
07651 }
07652 }
07653 size++;
07654 }
07655 if (size == 0) {
07656 goto nodata;
07657 }
07658 s->nrows = size;
07659 size = (size + 1) * asize;
07660 s->rows = xmalloc((size + 1) * sizeof (char *));
07661 if (!s->rows) {
07662 s->nrows = 0;
07663 return nomem(s);
07664 }
07665 s->rows[0] = (char *) size;
07666 s->rows += 1;
07667 memset(s->rows, 0, sizeof (char *) * size);
07668 s->rowfree = freerows;
07669 offs = 0;
07670 for (i = 1; i <= nrows; i++) {
07671 int pos = 0, roffs = (offs + 1) * s->ncols;
07672 char *ptab = rowp[i * ncols + namec];
07673 char buf[32];
07674
07675 if (plen && ptab) {
07676 int len = strlen(ptab);
07677
07678 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
07679 continue;
07680 }
07681 }
07682 #if defined(_WIN32) || defined(_WIN64)
07683 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
07684 s->rows[roffs + 1] = xstrdup("");
07685 #else
07686 s->rows[roffs + 0] = xstrdup("");
07687 s->rows[roffs + 1] = xstrdup("");
07688 #endif
07689 s->rows[roffs + 2] = xstrdup(ptab);
07690 s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
07691 s->rows[roffs + 4] = xstrdup("");
07692 s->rows[roffs + 5] = xstrdup("");
07693 s->rows[roffs + 6] = xstrdup(fname);
07694 s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
07695 sscanf(rowp[i * ncols + seqc], "%d", &pos);
07696 sprintf(buf, "%d", pos + 1);
07697 s->rows[roffs + 8] = xstrdup(buf);
07698 if (onu < 0) {
07699 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
07700 } else {
07701 if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
07702 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
07703 } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
07704 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
07705 } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
07706 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
07707 } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
07708 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
07709 } else {
07710 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
07711 }
07712 }
07713 if (ond < 0) {
07714 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
07715 } else {
07716 if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
07717 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
07718 } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
07719 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
07720 } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
07721 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
07722 } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
07723 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
07724 } else {
07725 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
07726 }
07727 }
07728 s->rows[roffs + 11] = NULL;
07729 s->rows[roffs + 12] = NULL;
07730 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
07731 offs++;
07732 }
07733 sqlite3_free_table(rowp);
07734 } else {
07735 int nnrows, nncols, plen = strlen(pname);
07736 char **rowpp;
07737
07738 sql = "select name from sqlite_master where type='table'";
07739 dbtraceapi(d, "sqlite3_get_table", sql);
07740 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
07741 if (ret != SQLITE_OK) {
07742 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
07743 errp ? errp : "unknown error", ret);
07744 if (errp) {
07745 sqlite3_free(errp);
07746 errp = NULL;
07747 }
07748 return SQL_ERROR;
07749 }
07750 if (errp) {
07751 sqlite3_free(errp);
07752 errp = NULL;
07753 }
07754 if (ncols * nrows <= 0) {
07755 goto nodata;
07756 }
07757 size = 0;
07758 for (i = 1; i <= nrows; i++) {
07759 int k;
07760
07761 if (!rowp[i]) {
07762 continue;
07763 }
07764 rowpp = NULL;
07765 ret = SQLITE_ERROR;
07766 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
07767 if (sql) {
07768 dbtraceapi(d, "sqlite3_get_table", sql);
07769 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
07770 &nnrows, &nncols, NULL);
07771 sqlite3_free(sql);
07772 }
07773 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
07774 sqlite3_free_table(rowpp);
07775 continue;
07776 }
07777 namec = findcol(rowpp, nncols, "table");
07778 seqc = findcol(rowpp, nncols, "seq");
07779 fromc = findcol(rowpp, nncols, "from");
07780 toc = findcol(rowpp, nncols, "to");
07781 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
07782 sqlite3_free_table(rowpp);
07783 continue;
07784 }
07785 for (k = 1; k <= nnrows; k++) {
07786 char *ptab = unquote(rowpp[k * nncols + namec]);
07787
07788 if (plen && ptab) {
07789 int len = strlen(ptab);
07790
07791 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
07792 continue;
07793 }
07794 }
07795 size++;
07796 }
07797 sqlite3_free_table(rowpp);
07798 }
07799 if (size == 0) {
07800 goto nodata;
07801 }
07802 s->nrows = size;
07803 size = (size + 1) * asize;
07804 s->rows = xmalloc((size + 1) * sizeof (char *));
07805 if (!s->rows) {
07806 s->nrows = 0;
07807 return nomem(s);
07808 }
07809 s->rows[0] = (char *) size;
07810 s->rows += 1;
07811 memset(s->rows, 0, sizeof (char *) * size);
07812 s->rowfree = freerows;
07813 offs = 0;
07814 for (i = 1; i <= nrows; i++) {
07815 int k;
07816
07817 if (!rowp[i]) {
07818 continue;
07819 }
07820 rowpp = NULL;
07821 ret = SQLITE_ERROR;
07822 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
07823 if (sql) {
07824 dbtraceapi(d, "sqlite3_get_table", sql);
07825 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
07826 &nnrows, &nncols, NULL);
07827 sqlite3_free(sql);
07828 }
07829 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
07830 sqlite3_free_table(rowpp);
07831 continue;
07832 }
07833 namec = findcol(rowpp, nncols, "table");
07834 seqc = findcol(rowpp, nncols, "seq");
07835 fromc = findcol(rowpp, nncols, "from");
07836 toc = findcol(rowpp, nncols, "to");
07837 onu = findcol(rowpp, nncols, "on_update");
07838 ond = findcol(rowpp, nncols, "on_delete");
07839 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
07840 sqlite3_free_table(rowpp);
07841 continue;
07842 }
07843 for (k = 1; k <= nnrows; k++) {
07844 int pos = 0, roffs = (offs + 1) * s->ncols;
07845 char *ptab = unquote(rowpp[k * nncols + namec]);
07846 char buf[32];
07847
07848 if (plen && ptab) {
07849 int len = strlen(ptab);
07850
07851 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
07852 continue;
07853 }
07854 }
07855 #if defined(_WIN32) || defined(_WIN64)
07856 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
07857 s->rows[roffs + 1] = xstrdup("");
07858 #else
07859 s->rows[roffs + 0] = xstrdup("");
07860 s->rows[roffs + 1] = xstrdup("");
07861 #endif
07862 s->rows[roffs + 2] = xstrdup(ptab);
07863 s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
07864 s->rows[roffs + 4] = xstrdup("");
07865 s->rows[roffs + 5] = xstrdup("");
07866 s->rows[roffs + 6] = xstrdup(rowp[i]);
07867 s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
07868 sscanf(rowpp[k * nncols + seqc], "%d", &pos);
07869 sprintf(buf, "%d", pos + 1);
07870 s->rows[roffs + 8] = xstrdup(buf);
07871 if (onu < 0) {
07872 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
07873 } else {
07874 if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
07875 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
07876 } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
07877 == 0) {
07878 s->rows[roffs + 9] =
07879 xstrdup(stringify(SQL_SET_DEFAULT));
07880 } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
07881 == 0) {
07882 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
07883 } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
07884 == 0) {
07885 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
07886 } else {
07887 s->rows[roffs + 9] =
07888 xstrdup(stringify(SQL_NO_ACTION));
07889 }
07890 }
07891 if (ond < 0) {
07892 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
07893 } else {
07894 if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
07895 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
07896 } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
07897 == 0) {
07898 s->rows[roffs + 10] =
07899 xstrdup(stringify(SQL_SET_DEFAULT));
07900 } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
07901 == 0) {
07902 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
07903 } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
07904 == 0) {
07905 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
07906 } else {
07907 s->rows[roffs + 10] =
07908 xstrdup(stringify(SQL_NO_ACTION));
07909 }
07910 }
07911 s->rows[roffs + 11] = NULL;
07912 s->rows[roffs + 12] = NULL;
07913 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
07914 offs++;
07915 }
07916 sqlite3_free_table(rowpp);
07917 }
07918 sqlite3_free_table(rowp);
07919 }
07920 return SQL_SUCCESS;
07921 }
07922
07923 #ifndef WINTERFACE
07924
07942 SQLRETURN SQL_API
07943 SQLForeignKeys(SQLHSTMT stmt,
07944 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
07945 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
07946 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
07947 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
07948 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
07949 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
07950 {
07951 #if defined(_WIN32) || defined(_WIN64)
07952 char *pc = NULL, *ps = NULL, *pt = NULL;
07953 char *fc = NULL, *fs = NULL, *ft = NULL;
07954 #endif
07955 SQLRETURN ret;
07956
07957 HSTMT_LOCK(stmt);
07958 #if defined(_WIN32) || defined(_WIN64)
07959 if (!((STMT *) stmt)->oemcp[0]) {
07960 ret = drvforeignkeys(stmt,
07961 PKcatalog, PKcatalogLen,
07962 PKschema, PKschemaLen, PKtable, PKtableLen,
07963 FKcatalog, FKcatalogLen,
07964 FKschema, FKschemaLen,
07965 FKtable, FKtableLen);
07966 goto done2;
07967 }
07968 if (PKcatalog) {
07969 pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
07970 if (!pc) {
07971 ret = nomem((STMT *) stmt);
07972 goto done;
07973 }
07974 }
07975 if (PKschema) {
07976 ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
07977 if (!ps) {
07978 ret = nomem((STMT *) stmt);
07979 goto done;
07980 }
07981 }
07982 if (PKtable) {
07983 pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
07984 if (!pt) {
07985 ret = nomem((STMT *) stmt);
07986 goto done;
07987 }
07988 }
07989 if (FKcatalog) {
07990 fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
07991 if (!fc) {
07992 ret = nomem((STMT *) stmt);
07993 goto done;
07994 }
07995 }
07996 if (FKschema) {
07997 fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
07998 if (!fs) {
07999 ret = nomem((STMT *) stmt);
08000 goto done;
08001 }
08002 }
08003 if (FKtable) {
08004 ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
08005 if (!ft) {
08006 ret = nomem((STMT *) stmt);
08007 goto done;
08008 }
08009 }
08010 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
08011 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
08012 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
08013 (SQLCHAR *) ft, SQL_NTS);
08014 #else
08015 ret = drvforeignkeys(stmt,
08016 PKcatalog, PKcatalogLen,
08017 PKschema, PKschemaLen, PKtable, PKtableLen,
08018 FKcatalog, FKcatalogLen,
08019 FKschema, FKschemaLen,
08020 FKtable, FKtableLen);
08021 #endif
08022 #if defined(_WIN32) || defined(_WIN64)
08023 done:
08024 uc_free(ft);
08025 uc_free(fs);
08026 uc_free(fc);
08027 uc_free(pt);
08028 uc_free(ps);
08029 uc_free(pc);
08030 done2:
08031 ;
08032 #endif
08033 HSTMT_UNLOCK(stmt);
08034 return ret;
08035 }
08036 #endif
08037
08038 #ifdef WINTERFACE
08039
08057 SQLRETURN SQL_API
08058 SQLForeignKeysW(SQLHSTMT stmt,
08059 SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
08060 SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
08061 SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
08062 SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
08063 SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
08064 SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
08065 {
08066 char *pc = NULL, *ps = NULL, *pt = NULL;
08067 char *fc = NULL, *fs = NULL, *ft = NULL;
08068 SQLRETURN ret;
08069
08070 HSTMT_LOCK(stmt);
08071 if (PKcatalog) {
08072 pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
08073 if (!pc) {
08074 ret = nomem((STMT *) stmt);
08075 goto done;
08076 }
08077 }
08078 if (PKschema) {
08079 ps = uc_to_utf_c(PKschema, PKschemaLen);
08080 if (!ps) {
08081 ret = nomem((STMT *) stmt);
08082 goto done;
08083 }
08084 }
08085 if (PKtable) {
08086 pt = uc_to_utf_c(PKtable, PKtableLen);
08087 if (!pt) {
08088 ret = nomem((STMT *) stmt);
08089 goto done;
08090 }
08091 }
08092 if (FKcatalog) {
08093 fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
08094 if (!fc) {
08095 ret = nomem((STMT *) stmt);
08096 goto done;
08097 }
08098 }
08099 if (FKschema) {
08100 fs = uc_to_utf_c(FKschema, FKschemaLen);
08101 if (!fs) {
08102 ret = nomem((STMT *) stmt);
08103 goto done;
08104 }
08105 }
08106 if (FKtable) {
08107 ft = uc_to_utf_c(FKtable, FKtableLen);
08108 if (!ft) {
08109 ret = nomem((STMT *) stmt);
08110 goto done;
08111 }
08112 }
08113 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
08114 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
08115 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
08116 (SQLCHAR *) ft, SQL_NTS);
08117 done:
08118 uc_free(ft);
08119 uc_free(fs);
08120 uc_free(fc);
08121 uc_free(pt);
08122 uc_free(ps);
08123 uc_free(pc);
08124 HSTMT_UNLOCK(stmt);
08125 return ret;
08126 }
08127 #endif
08128
08135 static SQLRETURN
08136 starttran(STMT *s)
08137 {
08138 int ret = SQL_SUCCESS, rc, busy_count = 0;
08139 char *errp = NULL;
08140 DBC *d = (DBC *) s->dbc;
08141
08142 if (!d->autocommit && !d->intrans && !d->trans_disable) {
08143 begin_again:
08144 rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
08145 if (rc == SQLITE_BUSY) {
08146 if (busy_handler((void *) d, ++busy_count)) {
08147 if (errp) {
08148 sqlite3_free(errp);
08149 errp = NULL;
08150 }
08151 goto begin_again;
08152 }
08153 }
08154 dbtracerc(d, rc, errp);
08155 if (rc != SQLITE_OK) {
08156 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
08157 errp ? errp : "unknown error", rc);
08158 ret = SQL_ERROR;
08159 } else {
08160 d->intrans = 1;
08161 }
08162 if (errp) {
08163 sqlite3_free(errp);
08164 errp = NULL;
08165 }
08166 }
08167 return ret;
08168 }
08169
08178 static SQLRETURN
08179 endtran(DBC *d, SQLSMALLINT comptype, int force)
08180 {
08181 int ret, busy_count = 0;
08182 char *sql, *errp = NULL;
08183
08184 if (!d->sqlite) {
08185 setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
08186 return SQL_ERROR;
08187 }
08188 if ((!force && d->autocommit) || !d->intrans) {
08189 return SQL_SUCCESS;
08190 }
08191 switch (comptype) {
08192 case SQL_COMMIT:
08193 sql = "COMMIT TRANSACTION";
08194 goto doit;
08195 case SQL_ROLLBACK:
08196 sql = "ROLLBACK TRANSACTION";
08197 doit:
08198 ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
08199 dbtracerc(d, ret, errp);
08200 if (ret == SQLITE_BUSY && busy_count < 10) {
08201 if (busy_handler((void *) d, ++busy_count)) {
08202 if (errp) {
08203 sqlite3_free(errp);
08204 errp = NULL;
08205 }
08206 goto doit;
08207 }
08208 }
08209 if (ret != SQLITE_OK) {
08210 setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
08211 errp ? errp : "transaction failed");
08212 if (errp) {
08213 sqlite3_free(errp);
08214 errp = NULL;
08215 }
08216 return SQL_ERROR;
08217 }
08218 if (errp) {
08219 sqlite3_free(errp);
08220 errp = NULL;
08221 }
08222 d->intrans = 0;
08223 return SQL_SUCCESS;
08224 }
08225 setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
08226 return SQL_ERROR;
08227 }
08228
08237 static SQLRETURN
08238 drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
08239 {
08240 DBC *dbc = NULL;
08241 int fail = 0;
08242 SQLRETURN ret;
08243 #if defined(_WIN32) || defined(_WIN64)
08244 ENV *env;
08245 #endif
08246
08247 switch (type) {
08248 case SQL_HANDLE_DBC:
08249 HDBC_LOCK((SQLHDBC) handle);
08250 if (handle == SQL_NULL_HDBC) {
08251 return SQL_INVALID_HANDLE;
08252 }
08253 dbc = (DBC *) handle;
08254 ret = endtran(dbc, comptype, 0);
08255 HDBC_UNLOCK((SQLHDBC) handle);
08256 return ret;
08257 case SQL_HANDLE_ENV:
08258 if (handle == SQL_NULL_HENV) {
08259 return SQL_INVALID_HANDLE;
08260 }
08261 #if defined(_WIN32) || defined(_WIN64)
08262 env = (ENV *) handle;
08263 if (env->magic != ENV_MAGIC) {
08264 return SQL_INVALID_HANDLE;
08265 }
08266 EnterCriticalSection(&env->cs);
08267 #endif
08268 dbc = ((ENV *) handle)->dbcs;
08269 while (dbc) {
08270 HDBC_LOCK((SQLHDBC) dbc);
08271 ret = endtran(dbc, comptype, 0);
08272 HDBC_UNLOCK((SQLHDBC) dbc);
08273 if (ret != SQL_SUCCESS) {
08274 fail++;
08275 }
08276 dbc = dbc->next;
08277 }
08278 #if defined(_WIN32) || defined(_WIN64)
08279 LeaveCriticalSection(&env->cs);
08280 #endif
08281 return fail ? SQL_ERROR : SQL_SUCCESS;
08282 }
08283 return SQL_INVALID_HANDLE;
08284 }
08285
08294 SQLRETURN SQL_API
08295 SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
08296 {
08297 return drvendtran(type, handle, comptype);
08298 }
08299
08308 SQLRETURN SQL_API
08309 SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
08310 {
08311 if (dbc != SQL_NULL_HDBC) {
08312 return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
08313 }
08314 return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
08315 }
08316
08321 SQLRETURN SQL_API
08322 SQLCopyDesc(SQLHDESC source, SQLHDESC target)
08323 {
08324 return SQL_ERROR;
08325 }
08326
08327 #ifndef WINTERFACE
08328
08339 SQLRETURN SQL_API
08340 SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
08341 SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
08342 {
08343 int outLen = 0;
08344 SQLRETURN ret = SQL_SUCCESS;
08345
08346 HSTMT_LOCK(stmt);
08347 if (sqlinLen == SQL_NTS) {
08348 sqlinLen = strlen((char *) sqlin);
08349 }
08350 if (sql) {
08351 if (sqlMax > 0) {
08352 strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
08353 sqlin[sqlMax - 1] = '\0';
08354 outLen = min(sqlMax - 1, sqlinLen);
08355 }
08356 } else {
08357 outLen = sqlinLen;
08358 }
08359 if (sqlLen) {
08360 *sqlLen = outLen;
08361 }
08362 if (sql && outLen < sqlinLen) {
08363 setstat((STMT *) stmt, -1, "data right truncated", "01004");
08364 ret = SQL_SUCCESS_WITH_INFO;
08365 }
08366 HSTMT_UNLOCK(stmt);
08367 return ret;
08368 }
08369 #endif
08370
08371 #ifdef WINTERFACE
08372
08383 SQLRETURN SQL_API
08384 SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
08385 SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
08386 {
08387 int outLen = 0;
08388 SQLRETURN ret = SQL_SUCCESS;
08389
08390 HSTMT_LOCK(stmt);
08391 if (sqlinLen == SQL_NTS) {
08392 sqlinLen = uc_strlen(sqlin);
08393 }
08394 if (sql) {
08395 if (sqlMax > 0) {
08396 uc_strncpy(sql, sqlin, sqlMax - 1);
08397 sqlin[sqlMax - 1] = 0;
08398 outLen = min(sqlMax - 1, sqlinLen);
08399 }
08400 } else {
08401 outLen = sqlinLen;
08402 }
08403 if (sqlLen) {
08404 *sqlLen = outLen;
08405 }
08406 if (sql && outLen < sqlinLen) {
08407 setstat((STMT *) stmt, -1, "data right truncated", "01004");
08408 ret = SQL_SUCCESS_WITH_INFO;
08409 }
08410 HSTMT_UNLOCK(stmt);
08411 return ret;
08412 }
08413 #endif
08414
08419 static COL procSpec2[] = {
08420 { "SYSTEM", "PROCEDURE", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
08421 { "SYSTEM", "PROCEDURE", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
08422 { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
08423 { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
08424 { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
08425 { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
08426 { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
08427 { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
08428 };
08429
08430 static COL procSpec3[] = {
08431 { "SYSTEM", "PROCEDURE", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
08432 { "SYSTEM", "PROCEDURE", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
08433 { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
08434 { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
08435 { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
08436 { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
08437 { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
08438 { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
08439 };
08440
08441 #ifndef WINTERFACE
08442
08454 SQLRETURN SQL_API
08455 SQLProcedures(SQLHSTMT stmt,
08456 SQLCHAR *catalog, SQLSMALLINT catalogLen,
08457 SQLCHAR *schema, SQLSMALLINT schemaLen,
08458 SQLCHAR *proc, SQLSMALLINT procLen)
08459 {
08460 SQLRETURN ret;
08461
08462 HSTMT_LOCK(stmt);
08463 ret = mkresultset(stmt, procSpec2, array_size(procSpec2),
08464 procSpec3, array_size(procSpec3), NULL);
08465 HSTMT_UNLOCK(stmt);
08466 return ret;
08467 }
08468 #endif
08469
08470 #ifdef WINTERFACE
08471
08483 SQLRETURN SQL_API
08484 SQLProceduresW(SQLHSTMT stmt,
08485 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
08486 SQLWCHAR *schema, SQLSMALLINT schemaLen,
08487 SQLWCHAR *proc, SQLSMALLINT procLen)
08488 {
08489 SQLRETURN ret;
08490
08491 HSTMT_LOCK(stmt);
08492 ret = mkresultset(stmt, procSpec2, array_size(procSpec2),
08493 procSpec3, array_size(procSpec3), NULL);
08494 HSTMT_UNLOCK(stmt);
08495 return ret;
08496 }
08497 #endif
08498
08503 static COL procColSpec2[] = {
08504 { "SYSTEM", "PROCCOL", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
08505 { "SYSTEM", "PROCCOL", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
08506 { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
08507 { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
08508 { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
08509 { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
08510 { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
08511 { "SYSTEM", "PROCCOL", "PRECISION", SQL_INTEGER, 10 },
08512 { "SYSTEM", "PROCCOL", "LENGTH", SQL_INTEGER, 10 },
08513 { "SYSTEM", "PROCCOL", "SCALE", SQL_SMALLINT, 5 },
08514 { "SYSTEM", "PROCCOL", "RADIX", SQL_SMALLINT, 5 },
08515 { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
08516 { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
08517 { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
08518 { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
08519 { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
08520 { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
08521 { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
08522 { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
08523 };
08524
08525 static COL procColSpec3[] = {
08526 { "SYSTEM", "PROCCOL", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
08527 { "SYSTEM", "PROCCOL", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
08528 { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
08529 { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
08530 { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
08531 { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
08532 { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
08533 { "SYSTEM", "PROCCOL", "COLUMN_SIZE", SQL_INTEGER, 10 },
08534 { "SYSTEM", "PROCCOL", "BUFFER_LENGTH", SQL_INTEGER, 10 },
08535 { "SYSTEM", "PROCCOL", "DECIMAL_DIGITS", SQL_SMALLINT, 5 },
08536 { "SYSTEM", "PROCCOL", "NUM_PREC_RADIX", SQL_SMALLINT, 5 },
08537 { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
08538 { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
08539 { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
08540 { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
08541 { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
08542 { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
08543 { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
08544 { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
08545 };
08546
08547 #ifndef WINTERFACE
08548
08562 SQLRETURN SQL_API
08563 SQLProcedureColumns(SQLHSTMT stmt,
08564 SQLCHAR *catalog, SQLSMALLINT catalogLen,
08565 SQLCHAR *schema, SQLSMALLINT schemaLen,
08566 SQLCHAR *proc, SQLSMALLINT procLen,
08567 SQLCHAR *column, SQLSMALLINT columnLen)
08568 {
08569 SQLRETURN ret;
08570
08571 HSTMT_LOCK(stmt);
08572 ret = mkresultset(stmt, procColSpec2, array_size(procColSpec2),
08573 procColSpec3, array_size(procColSpec3), NULL);
08574 HSTMT_UNLOCK(stmt);
08575 return ret;
08576 }
08577 #endif
08578
08579 #ifdef WINTERFACE
08580
08595 SQLRETURN SQL_API
08596 SQLProcedureColumnsW(SQLHSTMT stmt,
08597 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
08598 SQLWCHAR *schema, SQLSMALLINT schemaLen,
08599 SQLWCHAR *proc, SQLSMALLINT procLen,
08600 SQLWCHAR *column, SQLSMALLINT columnLen)
08601 {
08602 SQLRETURN ret;
08603
08604 HSTMT_LOCK(stmt);
08605 ret = mkresultset(stmt, procColSpec2, array_size(procColSpec2),
08606 procColSpec3, array_size(procColSpec3), NULL);
08607 HSTMT_UNLOCK(stmt);
08608 return ret;
08609 }
08610 #endif
08611
08622 SQLRETURN SQL_API
08623 SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
08624 SQLINTEGER len, SQLINTEGER *lenp)
08625 {
08626 ENV *e;
08627 SQLRETURN ret = SQL_ERROR;
08628
08629 if (env == SQL_NULL_HENV) {
08630 return SQL_INVALID_HANDLE;
08631 }
08632 e = (ENV *) env;
08633 if (!e || e->magic != ENV_MAGIC) {
08634 return SQL_INVALID_HANDLE;
08635 }
08636 #if defined(_WIN32) || defined(_WIN64)
08637 EnterCriticalSection(&e->cs);
08638 #endif
08639 switch (attr) {
08640 case SQL_ATTR_CONNECTION_POOLING:
08641 if (val) {
08642 *((SQLINTEGER *) val) = e->pool ?
08643 SQL_CP_ONE_PER_DRIVER : SQL_CP_OFF;
08644 }
08645 if (lenp) {
08646 *lenp = sizeof (SQLINTEGER);
08647 }
08648 ret = SQL_SUCCESS;
08649 break;
08650 case SQL_ATTR_CP_MATCH:
08651 *((SQLINTEGER *) val) = SQL_CP_RELAXED_MATCH;
08652 if (lenp) {
08653 *lenp = sizeof (SQLINTEGER);
08654 }
08655 ret = SQL_SUCCESS;
08656 break;
08657 case SQL_ATTR_OUTPUT_NTS:
08658 if (val) {
08659 *((SQLINTEGER *) val) = SQL_TRUE;
08660 }
08661 if (lenp) {
08662 *lenp = sizeof (SQLINTEGER);
08663 }
08664 ret = SQL_SUCCESS;
08665 break;
08666 case SQL_ATTR_ODBC_VERSION:
08667 if (val) {
08668 *((SQLINTEGER *) val) = e->ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
08669 }
08670 if (lenp) {
08671 *lenp = sizeof (SQLINTEGER);
08672 }
08673 ret = SQL_SUCCESS;
08674 break;
08675 }
08676 #if defined(_WIN32) || defined(_WIN64)
08677 LeaveCriticalSection(&e->cs);
08678 #endif
08679 return ret;
08680 }
08681
08691 SQLRETURN SQL_API
08692 SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
08693 {
08694 ENV *e;
08695 SQLRETURN ret = SQL_ERROR;
08696
08697 if (env == SQL_NULL_HENV) {
08698 return SQL_INVALID_HANDLE;
08699 }
08700 e = (ENV *) env;
08701 if (!e || e->magic != ENV_MAGIC) {
08702 return SQL_INVALID_HANDLE;
08703 }
08704 #if defined(_WIN32) || defined(_WIN64)
08705 EnterCriticalSection(&e->cs);
08706 #endif
08707 switch (attr) {
08708 case SQL_ATTR_CONNECTION_POOLING:
08709 if (val == (SQLPOINTER) SQL_CP_ONE_PER_DRIVER) {
08710 e->pool = 1;
08711 ret = SQL_SUCCESS;
08712 } else if (val == (SQLPOINTER) SQL_CP_OFF) {
08713 e->pool = 0;
08714 ret = SQL_SUCCESS;
08715 }
08716 break;
08717 case SQL_ATTR_CP_MATCH:
08718 ret = SQL_SUCCESS;
08719 break;
08720 case SQL_ATTR_OUTPUT_NTS:
08721 if (val == (SQLPOINTER) SQL_TRUE) {
08722 ret = SQL_SUCCESS;
08723 }
08724 break;
08725 case SQL_ATTR_ODBC_VERSION:
08726 if (!val) {
08727 break;
08728 }
08729 if (val == (SQLPOINTER) SQL_OV_ODBC2) {
08730 e->ov3 = 0;
08731 ret = SQL_SUCCESS;
08732 } else if (val == (SQLPOINTER) SQL_OV_ODBC3) {
08733 e->ov3 = 1;
08734 ret = SQL_SUCCESS;
08735 }
08736 break;
08737 }
08738 #if defined(_WIN32) || defined(_WIN64)
08739 LeaveCriticalSection(&e->cs);
08740 #endif
08741 return ret;
08742 }
08743
08757 static SQLRETURN
08758 drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08759 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
08760 SQLSMALLINT buflen, SQLSMALLINT *msglen)
08761 {
08762 DBC *d = NULL;
08763 STMT *s = NULL;
08764 int len, naterr;
08765 char *logmsg, *sqlst;
08766 SQLRETURN ret = SQL_ERROR;
08767
08768 if (handle == SQL_NULL_HANDLE) {
08769 return SQL_INVALID_HANDLE;
08770 }
08771 if (sqlstate) {
08772 sqlstate[0] = '\0';
08773 }
08774 if (msg && buflen > 0) {
08775 msg[0] = '\0';
08776 }
08777 if (msglen) {
08778 *msglen = 0;
08779 }
08780 if (nativeerr) {
08781 *nativeerr = 0;
08782 }
08783 switch (htype) {
08784 case SQL_HANDLE_ENV:
08785 case SQL_HANDLE_DESC:
08786 return SQL_NO_DATA;
08787 case SQL_HANDLE_DBC:
08788 HDBC_LOCK((SQLHDBC) handle);
08789 d = (DBC *) handle;
08790 logmsg = (char *) d->logmsg;
08791 sqlst = d->sqlstate;
08792 naterr = d->naterr;
08793 break;
08794 case SQL_HANDLE_STMT:
08795 HSTMT_LOCK((SQLHSTMT) handle);
08796 s = (STMT *) handle;
08797 logmsg = (char *) s->logmsg;
08798 sqlst = s->sqlstate;
08799 naterr = s->naterr;
08800 break;
08801 default:
08802 return SQL_INVALID_HANDLE;
08803 }
08804 if (buflen < 0) {
08805 goto done;
08806 }
08807 if (recno > 1) {
08808 ret = SQL_NO_DATA;
08809 goto done;
08810 }
08811 len = strlen(logmsg);
08812 if (len == 0) {
08813 ret = SQL_NO_DATA;
08814 goto done;
08815 }
08816 if (nativeerr) {
08817 *nativeerr = naterr;
08818 }
08819 if (sqlstate) {
08820 strcpy((char *) sqlstate, sqlst);
08821 }
08822 if (msglen) {
08823 *msglen = len;
08824 }
08825 if (len >= buflen) {
08826 if (msg && buflen > 0) {
08827 strncpy((char *) msg, logmsg, buflen);
08828 msg[buflen - 1] = '\0';
08829 logmsg[0] = '\0';
08830 }
08831 } else if (msg) {
08832 strcpy((char *) msg, logmsg);
08833 logmsg[0] = '\0';
08834 }
08835 ret = SQL_SUCCESS;
08836 done:
08837 switch (htype) {
08838 case SQL_HANDLE_DBC:
08839 HDBC_UNLOCK((SQLHDBC) handle);
08840 break;
08841 case SQL_HANDLE_STMT:
08842 HSTMT_UNLOCK((SQLHSTMT) handle);
08843 break;
08844 }
08845 return ret;
08846 }
08847
08848 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
08849
08862 SQLRETURN SQL_API
08863 SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08864 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
08865 SQLSMALLINT buflen, SQLSMALLINT *msglen)
08866 {
08867 return drvgetdiagrec(htype, handle, recno, sqlstate,
08868 nativeerr, msg, buflen, msglen);
08869 }
08870 #endif
08871
08872 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
08873 #ifdef WINTERFACE
08874
08888 SQLRETURN SQL_API
08889 SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08890 SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
08891 SQLSMALLINT buflen, SQLSMALLINT *msglen)
08892 {
08893 char state[16];
08894 SQLSMALLINT len;
08895 SQLRETURN ret;
08896
08897 ret = drvgetdiagrec(htype, handle, recno, (SQLCHAR *) state,
08898 nativeerr, (SQLCHAR *) msg, buflen, &len);
08899 if (ret == SQL_SUCCESS) {
08900 if (sqlstate) {
08901 uc_from_utf_buf((SQLCHAR *) state, -1, sqlstate,
08902 6 * sizeof (SQLWCHAR));
08903 }
08904 if (msg) {
08905 if (len > 0) {
08906 SQLWCHAR *m = NULL;
08907
08908 m = uc_from_utf((unsigned char *) msg, len);
08909 if (m) {
08910 if (buflen) {
08911 buflen /= sizeof (SQLWCHAR);
08912 uc_strncpy(msg, m, buflen);
08913 m[len] = 0;
08914 len = min(buflen, uc_strlen(m));
08915 } else {
08916 len = uc_strlen(m);
08917 }
08918 uc_free(m);
08919 } else {
08920 len = 0;
08921 }
08922 }
08923 if (len <= 0) {
08924 len = 0;
08925 if (buflen > 0) {
08926 msg[0] = 0;
08927 }
08928 }
08929 } else {
08930
08931 len *= sizeof (SQLWCHAR);
08932 }
08933 if (msglen) {
08934 *msglen = len;
08935 }
08936 } else if (ret == SQL_NO_DATA) {
08937 if (sqlstate) {
08938 sqlstate[0] = 0;
08939 }
08940 if (msg) {
08941 if (buflen > 0) {
08942 msg[0] = 0;
08943 }
08944 }
08945 if (msglen) {
08946 *msglen = 0;
08947 }
08948 }
08949 return ret;
08950 }
08951 #endif
08952 #endif
08953
08966 static SQLRETURN
08967 drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08968 SQLSMALLINT id, SQLPOINTER info,
08969 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
08970 {
08971 DBC *d = NULL;
08972 STMT *s = NULL;
08973 int len, naterr, strbuf = 1;
08974 char *logmsg, *sqlst, *clrmsg = NULL;
08975 SQLRETURN ret = SQL_ERROR;
08976
08977 if (handle == SQL_NULL_HANDLE) {
08978 return SQL_INVALID_HANDLE;
08979 }
08980 if (stringlen) {
08981 *stringlen = 0;
08982 }
08983 switch (htype) {
08984 case SQL_HANDLE_ENV:
08985 case SQL_HANDLE_DESC:
08986 return SQL_NO_DATA;
08987 case SQL_HANDLE_DBC:
08988 HDBC_LOCK((SQLHDBC) handle);
08989 d = (DBC *) handle;
08990 logmsg = (char *) d->logmsg;
08991 sqlst = d->sqlstate;
08992 naterr = d->naterr;
08993 break;
08994 case SQL_HANDLE_STMT:
08995 HSTMT_LOCK((SQLHSTMT) handle);
08996 s = (STMT *) handle;
08997 d = (DBC *) s->dbc;
08998 logmsg = (char *) s->logmsg;
08999 sqlst = s->sqlstate;
09000 naterr = s->naterr;
09001 break;
09002 default:
09003 return SQL_INVALID_HANDLE;
09004 }
09005 if (buflen < 0) {
09006 switch (buflen) {
09007 case SQL_IS_POINTER:
09008 case SQL_IS_UINTEGER:
09009 case SQL_IS_INTEGER:
09010 case SQL_IS_USMALLINT:
09011 case SQL_IS_SMALLINT:
09012 strbuf = 0;
09013 break;
09014 default:
09015 ret = SQL_ERROR;
09016 goto done;
09017 }
09018 }
09019 if (recno > 1) {
09020 ret = SQL_NO_DATA;
09021 goto done;
09022 }
09023 switch (id) {
09024 case SQL_DIAG_CLASS_ORIGIN:
09025 logmsg = "ISO 9075";
09026 if (sqlst[0] == 'I' && sqlst[1] == 'M') {
09027 logmsg = "ODBC 3.0";
09028 }
09029 break;
09030 case SQL_DIAG_SUBCLASS_ORIGIN:
09031 logmsg = "ISO 9075";
09032 if (sqlst[0] == 'I' && sqlst[1] == 'M') {
09033 logmsg = "ODBC 3.0";
09034 } else if (sqlst[0] == 'H' && sqlst[1] == 'Y') {
09035 logmsg = "ODBC 3.0";
09036 } else if (sqlst[0] == '2' || sqlst[0] == '0' || sqlst[0] == '4') {
09037 logmsg = "ODBC 3.0";
09038 }
09039 break;
09040 case SQL_DIAG_CONNECTION_NAME:
09041 case SQL_DIAG_SERVER_NAME:
09042 logmsg = d->dsn ? d->dsn : "No DSN";
09043 break;
09044 case SQL_DIAG_SQLSTATE:
09045 logmsg = sqlst;
09046 break;
09047 case SQL_DIAG_MESSAGE_TEXT:
09048 if (info) {
09049 clrmsg = logmsg;
09050 }
09051 break;
09052 case SQL_DIAG_NUMBER:
09053 naterr = 1;
09054
09055 case SQL_DIAG_NATIVE:
09056 len = strlen(logmsg);
09057 if (len == 0) {
09058 ret = SQL_NO_DATA;
09059 goto done;
09060 }
09061 if (info) {
09062 *((SQLINTEGER *) info) = naterr;
09063 }
09064 ret = SQL_SUCCESS;
09065 goto done;
09066 case SQL_DIAG_DYNAMIC_FUNCTION:
09067 logmsg = "";
09068 break;
09069 case SQL_DIAG_CURSOR_ROW_COUNT:
09070 if (htype == SQL_HANDLE_STMT) {
09071 SQLULEN count;
09072
09073 count = (s->isselect == 1 || s->isselect == -1) ? s->nrows : 0;
09074 *((SQLULEN *) info) = count;
09075 ret = SQL_SUCCESS;
09076 }
09077 goto done;
09078 case SQL_DIAG_ROW_COUNT:
09079 if (htype == SQL_HANDLE_STMT) {
09080 SQLULEN count;
09081
09082 count = s->isselect ? 0 : s->nrows;
09083 *((SQLULEN *) info) = count;
09084 ret = SQL_SUCCESS;
09085 }
09086 goto done;
09087 default:
09088 goto done;
09089 }
09090 if (info && buflen > 0) {
09091 ((char *) info)[0] = '\0';
09092 }
09093 len = strlen(logmsg);
09094 if (len == 0) {
09095 ret = SQL_NO_DATA;
09096 goto done;
09097 }
09098 if (stringlen) {
09099 *stringlen = len;
09100 }
09101 if (strbuf) {
09102 if (len >= buflen) {
09103 if (info && buflen > 0) {
09104 if (stringlen) {
09105 *stringlen = buflen - 1;
09106 }
09107 strncpy((char *) info, logmsg, buflen);
09108 ((char *) info)[buflen - 1] = '\0';
09109 }
09110 } else if (info) {
09111 strcpy((char *) info, logmsg);
09112 }
09113 }
09114 if (clrmsg) {
09115 *clrmsg = '\0';
09116 }
09117 ret = SQL_SUCCESS;
09118 done:
09119 switch (htype) {
09120 case SQL_HANDLE_DBC:
09121 HDBC_UNLOCK((SQLHDBC) handle);
09122 break;
09123 case SQL_HANDLE_STMT:
09124 HSTMT_UNLOCK((SQLHSTMT) handle);
09125 break;
09126 }
09127 return ret;
09128 }
09129
09130 #ifndef WINTERFACE
09131
09143 SQLRETURN SQL_API
09144 SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
09145 SQLSMALLINT id, SQLPOINTER info,
09146 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
09147 {
09148 return drvgetdiagfield(htype, handle, recno, id, info, buflen, stringlen);
09149 }
09150 #endif
09151
09152 #ifdef WINTERFACE
09153
09165 SQLRETURN SQL_API
09166 SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
09167 SQLSMALLINT id, SQLPOINTER info,
09168 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
09169 {
09170 SQLSMALLINT len;
09171 SQLRETURN ret;
09172
09173 ret = drvgetdiagfield(htype, handle, recno, id, info, buflen, &len);
09174 if (ret == SQL_SUCCESS) {
09175 if (info) {
09176 switch (id) {
09177 case SQL_DIAG_CLASS_ORIGIN:
09178 case SQL_DIAG_SUBCLASS_ORIGIN:
09179 case SQL_DIAG_CONNECTION_NAME:
09180 case SQL_DIAG_SERVER_NAME:
09181 case SQL_DIAG_SQLSTATE:
09182 case SQL_DIAG_MESSAGE_TEXT:
09183 case SQL_DIAG_DYNAMIC_FUNCTION:
09184 if (len > 0) {
09185 SQLWCHAR *m = NULL;
09186
09187 m = uc_from_utf((unsigned char *) info, len);
09188 if (m) {
09189 if (buflen) {
09190 buflen /= sizeof (SQLWCHAR);
09191 uc_strncpy(info, m, buflen);
09192 m[len] = 0;
09193 len = min(buflen, uc_strlen(m));
09194 } else {
09195 len = uc_strlen(m);
09196 }
09197 uc_free(m);
09198 len *= sizeof (SQLWCHAR);
09199 } else {
09200 len = 0;
09201 }
09202 }
09203 if (len <= 0) {
09204 len = 0;
09205 if (buflen > 0) {
09206 ((SQLWCHAR *) info)[0] = 0;
09207 }
09208 }
09209 }
09210 } else {
09211 switch (id) {
09212 case SQL_DIAG_CLASS_ORIGIN:
09213 case SQL_DIAG_SUBCLASS_ORIGIN:
09214 case SQL_DIAG_CONNECTION_NAME:
09215 case SQL_DIAG_SERVER_NAME:
09216 case SQL_DIAG_SQLSTATE:
09217 case SQL_DIAG_MESSAGE_TEXT:
09218 case SQL_DIAG_DYNAMIC_FUNCTION:
09219 len *= sizeof (SQLWCHAR);
09220 break;
09221 }
09222 }
09223 if (stringlen) {
09224 *stringlen = len;
09225 }
09226 }
09227 return ret;
09228 }
09229 #endif
09230
09241 static SQLRETURN
09242 drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09243 SQLINTEGER bufmax, SQLINTEGER *buflen)
09244 {
09245 STMT *s = (STMT *) stmt;
09246 SQLULEN *uval = (SQLULEN *) val;
09247 SQLINTEGER dummy;
09248 char dummybuf[16];
09249
09250 if (!buflen) {
09251 buflen = &dummy;
09252 }
09253 if (!uval) {
09254 uval = (SQLPOINTER) dummybuf;
09255 }
09256 switch (attr) {
09257 case SQL_QUERY_TIMEOUT:
09258 *uval = 0;
09259 *buflen = sizeof (SQLULEN);
09260 return SQL_SUCCESS;
09261 case SQL_ATTR_CURSOR_TYPE:
09262 *uval = s->curtype;
09263 *buflen = sizeof (SQLULEN);
09264 return SQL_SUCCESS;
09265 case SQL_ATTR_CURSOR_SCROLLABLE:
09266 *uval = (s->curtype != SQL_CURSOR_FORWARD_ONLY) ?
09267 SQL_SCROLLABLE : SQL_NONSCROLLABLE;
09268 *buflen = sizeof (SQLULEN);
09269 return SQL_SUCCESS;
09270 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
09271 case SQL_ATTR_CURSOR_SENSITIVITY:
09272 *uval = SQL_UNSPECIFIED;
09273 *buflen = sizeof (SQLULEN);
09274 return SQL_SUCCESS;
09275 #endif
09276 case SQL_ATTR_ROW_NUMBER:
09277 if (s->s3stmt) {
09278 *uval = (s->s3stmt_rownum < 0) ?
09279 SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
09280 } else {
09281 *uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
09282 }
09283 *buflen = sizeof (SQLULEN);
09284 return SQL_SUCCESS;
09285 case SQL_ATTR_ASYNC_ENABLE:
09286 *uval = SQL_ASYNC_ENABLE_OFF;
09287 *buflen = sizeof (SQLULEN);
09288 return SQL_SUCCESS;
09289 case SQL_CONCURRENCY:
09290 *uval = SQL_CONCUR_LOCK;
09291 *buflen = sizeof (SQLULEN);
09292 return SQL_SUCCESS;
09293 case SQL_ATTR_RETRIEVE_DATA:
09294 *uval = s->retr_data;
09295 *buflen = sizeof (SQLULEN);
09296 return SQL_SUCCESS;
09297 case SQL_ROWSET_SIZE:
09298 case SQL_ATTR_ROW_ARRAY_SIZE:
09299 *uval = s->rowset_size;
09300 *buflen = sizeof (SQLULEN);
09301 return SQL_SUCCESS;
09302
09303 case SQL_ATTR_IMP_ROW_DESC:
09304 case SQL_ATTR_APP_ROW_DESC:
09305 case SQL_ATTR_IMP_PARAM_DESC:
09306 case SQL_ATTR_APP_PARAM_DESC:
09307 *((SQLHDESC *) uval) = (SQLHDESC) DEAD_MAGIC;
09308 *buflen = sizeof (SQLHDESC);
09309 return SQL_SUCCESS;
09310 case SQL_ATTR_ROW_STATUS_PTR:
09311 *((SQLUSMALLINT **) uval) = s->row_status;
09312 *buflen = sizeof (SQLUSMALLINT *);
09313 return SQL_SUCCESS;
09314 case SQL_ATTR_ROWS_FETCHED_PTR:
09315 *((SQLULEN **) uval) = s->row_count;
09316 *buflen = sizeof (SQLULEN *);
09317 return SQL_SUCCESS;
09318 case SQL_ATTR_USE_BOOKMARKS: {
09319 STMT *s = (STMT *) stmt;
09320
09321 *(SQLUINTEGER *) uval = s->bkmrk;
09322 *buflen = sizeof (SQLUINTEGER);
09323 return SQL_SUCCESS;
09324 }
09325 case SQL_ATTR_FETCH_BOOKMARK_PTR:
09326 *(SQLPOINTER *) uval = s->bkmrkptr;
09327 *buflen = sizeof (SQLPOINTER);
09328 return SQL_SUCCESS;
09329 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
09330 *((SQLULEN **) uval) = s->parm_bind_offs;
09331 *buflen = sizeof (SQLULEN *);
09332 return SQL_SUCCESS;
09333 case SQL_ATTR_PARAM_BIND_TYPE:
09334 *((SQLULEN *) uval) = s->parm_bind_type;
09335 *buflen = sizeof (SQLULEN);
09336 return SQL_SUCCESS;
09337 case SQL_ATTR_PARAM_OPERATION_PTR:
09338 *((SQLUSMALLINT **) uval) = s->parm_oper;
09339 *buflen = sizeof (SQLUSMALLINT *);
09340 return SQL_SUCCESS;
09341 case SQL_ATTR_PARAM_STATUS_PTR:
09342 *((SQLUSMALLINT **) uval) = s->parm_status;
09343 *buflen = sizeof (SQLUSMALLINT *);
09344 return SQL_SUCCESS;
09345 case SQL_ATTR_PARAMS_PROCESSED_PTR:
09346 *((SQLULEN **) uval) = s->parm_proc;
09347 *buflen = sizeof (SQLULEN *);
09348 return SQL_SUCCESS;
09349 case SQL_ATTR_PARAMSET_SIZE:
09350 *((SQLULEN *) uval) = s->paramset_size;
09351 *buflen = sizeof (SQLULEN);
09352 return SQL_SUCCESS;
09353 case SQL_ATTR_ROW_BIND_TYPE:
09354 *(SQLULEN *) uval = s->bind_type;
09355 *buflen = sizeof (SQLULEN);
09356 return SQL_SUCCESS;
09357 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
09358 *((SQLULEN **) uval) = s->bind_offs;
09359 *buflen = sizeof (SQLULEN *);
09360 return SQL_SUCCESS;
09361 case SQL_ATTR_MAX_ROWS:
09362 *((SQLULEN *) uval) = s->max_rows;
09363 *buflen = sizeof (SQLULEN);
09364 return SQL_SUCCESS;
09365 case SQL_ATTR_MAX_LENGTH:
09366 *((SQLULEN *) uval) = 1000000000;
09367 *buflen = sizeof (SQLULEN);
09368 return SQL_SUCCESS;
09369 #ifdef SQL_ATTR_METADATA_ID
09370 case SQL_ATTR_METADATA_ID:
09371 *((SQLULEN *) uval) = SQL_FALSE;
09372 *buflen = sizeof (SQLULEN);
09373 return SQL_SUCCESS;
09374 #endif
09375 }
09376 return drvunimplstmt(stmt);
09377 }
09378
09379 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
09380
09390 SQLRETURN SQL_API
09391 SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09392 SQLINTEGER bufmax, SQLINTEGER *buflen)
09393 {
09394 SQLRETURN ret;
09395
09396 HSTMT_LOCK(stmt);
09397 ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
09398 HSTMT_UNLOCK(stmt);
09399 return ret;
09400 }
09401 #endif
09402
09403 #ifdef WINTERFACE
09404
09414 SQLRETURN SQL_API
09415 SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09416 SQLINTEGER bufmax, SQLINTEGER *buflen)
09417 {
09418 SQLRETURN ret;
09419
09420 HSTMT_LOCK(stmt);
09421 ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
09422 HSTMT_UNLOCK(stmt);
09423 return ret;
09424 }
09425 #endif
09426
09436 static SQLRETURN
09437 drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09438 SQLINTEGER buflen)
09439 {
09440 STMT *s = (STMT *) stmt;
09441 #if defined(SQL_BIGINT) && defined(__WORDSIZE) && (__WORDSIZE == 64)
09442 SQLBIGINT uval;
09443
09444 uval = (SQLBIGINT) val;
09445 #else
09446 SQLULEN uval;
09447
09448 uval = (SQLULEN) val;
09449 #endif
09450 switch (attr) {
09451 case SQL_ATTR_CURSOR_TYPE:
09452 if (val == (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY) {
09453 s->curtype = SQL_CURSOR_FORWARD_ONLY;
09454 } else {
09455 s->curtype = SQL_CURSOR_STATIC;
09456 }
09457 if (val != (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY &&
09458 val != (SQLPOINTER) SQL_CURSOR_STATIC) {
09459 goto e01s02;
09460 }
09461 return SQL_SUCCESS;
09462 case SQL_ATTR_CURSOR_SCROLLABLE:
09463 if (val == (SQLPOINTER) SQL_NONSCROLLABLE) {
09464 s->curtype = SQL_CURSOR_FORWARD_ONLY;
09465 } else {
09466 s->curtype = SQL_CURSOR_STATIC;
09467 }
09468 return SQL_SUCCESS;
09469 case SQL_ATTR_ASYNC_ENABLE:
09470 if (val != (SQLPOINTER) SQL_ASYNC_ENABLE_OFF) {
09471 e01s02:
09472 setstat(s, -1, "option value changed", "01S02");
09473 return SQL_SUCCESS_WITH_INFO;
09474 }
09475 return SQL_SUCCESS;
09476 case SQL_CONCURRENCY:
09477 if (val != (SQLPOINTER) SQL_CONCUR_LOCK) {
09478 goto e01s02;
09479 }
09480 return SQL_SUCCESS;
09481 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
09482 case SQL_ATTR_CURSOR_SENSITIVITY:
09483 if (val != (SQLPOINTER) SQL_UNSPECIFIED) {
09484 goto e01s02;
09485 }
09486 return SQL_SUCCESS;
09487 #endif
09488 case SQL_ATTR_QUERY_TIMEOUT:
09489 return SQL_SUCCESS;
09490 case SQL_ATTR_RETRIEVE_DATA:
09491 if (val != (SQLPOINTER) SQL_RD_ON &&
09492 val != (SQLPOINTER) SQL_RD_OFF) {
09493 goto e01s02;
09494 }
09495 s->retr_data = uval;
09496 return SQL_SUCCESS;
09497 case SQL_ROWSET_SIZE:
09498 case SQL_ATTR_ROW_ARRAY_SIZE:
09499 if (uval < 1) {
09500 setstat(s, -1, "invalid rowset size", "HY000");
09501 return SQL_ERROR;
09502 } else {
09503 SQLUSMALLINT *rst = &s->row_status1;
09504
09505 if (uval > 1) {
09506 rst = xmalloc(sizeof (SQLUSMALLINT) * uval);
09507 if (!rst) {
09508 return nomem(s);
09509 }
09510 }
09511 if (s->row_status0 != &s->row_status1) {
09512 freep(&s->row_status0);
09513 }
09514 s->row_status0 = rst;
09515 s->rowset_size = uval;
09516 }
09517 return SQL_SUCCESS;
09518 case SQL_ATTR_ROW_STATUS_PTR:
09519 s->row_status = (SQLUSMALLINT *) val;
09520 return SQL_SUCCESS;
09521 case SQL_ATTR_ROWS_FETCHED_PTR:
09522 s->row_count = (SQLULEN *) val;
09523 return SQL_SUCCESS;
09524 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
09525 s->parm_bind_offs = (SQLULEN *) val;
09526 return SQL_SUCCESS;
09527 case SQL_ATTR_PARAM_BIND_TYPE:
09528 s->parm_bind_type = uval;
09529 return SQL_SUCCESS;
09530 case SQL_ATTR_PARAM_OPERATION_PTR:
09531 s->parm_oper = (SQLUSMALLINT *) val;
09532 return SQL_SUCCESS;
09533 case SQL_ATTR_PARAM_STATUS_PTR:
09534 s->parm_status = (SQLUSMALLINT *) val;
09535 return SQL_SUCCESS;
09536 case SQL_ATTR_PARAMS_PROCESSED_PTR:
09537 s->parm_proc = (SQLULEN *) val;
09538 return SQL_SUCCESS;
09539 case SQL_ATTR_PARAMSET_SIZE:
09540 if (uval < 1) {
09541 goto e01s02;
09542 }
09543 s->paramset_size = uval;
09544 s->paramset_count = 0;
09545 return SQL_SUCCESS;
09546 case SQL_ATTR_ROW_BIND_TYPE:
09547 s->bind_type = uval;
09548 return SQL_SUCCESS;
09549 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
09550 s->bind_offs = (SQLULEN *) val;
09551 return SQL_SUCCESS;
09552 case SQL_ATTR_USE_BOOKMARKS:
09553 if (val != (SQLPOINTER) SQL_UB_OFF &&
09554 val != (SQLPOINTER) SQL_UB_ON &&
09555 val != (SQLPOINTER) SQL_UB_VARIABLE) {
09556 goto e01s02;
09557 }
09558 if (*s->ov3 && val == (SQLPOINTER) SQL_UB_VARIABLE) {
09559 s->bkmrk = SQL_UB_VARIABLE;
09560 return SQL_SUCCESS;
09561 }
09562 if (val == (SQLPOINTER) SQL_UB_VARIABLE) {
09563 s->bkmrk = SQL_UB_ON;
09564 goto e01s02;
09565 }
09566 s->bkmrk = (val == (SQLPOINTER) SQL_UB_ON) ? SQL_UB_ON : SQL_UB_OFF;
09567 return SQL_SUCCESS;
09568 case SQL_ATTR_FETCH_BOOKMARK_PTR:
09569 s->bkmrkptr = (SQLINTEGER *) val;
09570 return SQL_SUCCESS;
09571 case SQL_ATTR_MAX_ROWS:
09572 s->max_rows = uval;
09573 return SQL_SUCCESS;
09574 case SQL_ATTR_MAX_LENGTH:
09575 if (val != (SQLPOINTER) 1000000000) {
09576 goto e01s02;
09577 }
09578 return SQL_SUCCESS;
09579 #ifdef SQL_ATTR_METADATA_ID
09580 case SQL_ATTR_METADATA_ID:
09581 if (val != (SQLPOINTER) SQL_FALSE) {
09582 goto e01s02;
09583 }
09584 return SQL_SUCCESS;
09585 #endif
09586 }
09587 return drvunimplstmt(stmt);
09588 }
09589
09590 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
09591
09600 SQLRETURN SQL_API
09601 SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09602 SQLINTEGER buflen)
09603 {
09604 SQLRETURN ret;
09605
09606 HSTMT_LOCK(stmt);
09607 ret = drvsetstmtattr(stmt, attr, val, buflen);
09608 HSTMT_UNLOCK(stmt);
09609 return ret;
09610 }
09611 #endif
09612
09613 #ifdef WINTERFACE
09614
09623 SQLRETURN SQL_API
09624 SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09625 SQLINTEGER buflen)
09626 {
09627 SQLRETURN ret;
09628
09629 HSTMT_LOCK(stmt);
09630 ret = drvsetstmtattr(stmt, attr, val, buflen);
09631 HSTMT_UNLOCK(stmt);
09632 return ret;
09633 }
09634 #endif
09635
09644 static SQLRETURN
09645 drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
09646 {
09647 STMT *s = (STMT *) stmt;
09648 SQLUINTEGER *ret = (SQLUINTEGER *) param;
09649
09650 switch (opt) {
09651 case SQL_QUERY_TIMEOUT:
09652 *ret = 0;
09653 return SQL_SUCCESS;
09654 case SQL_CURSOR_TYPE:
09655 *ret = s->curtype;
09656 return SQL_SUCCESS;
09657 case SQL_ROW_NUMBER:
09658 if (s->s3stmt) {
09659 *ret = (s->s3stmt_rownum < 0) ?
09660 SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
09661 } else {
09662 *ret = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
09663 }
09664 return SQL_SUCCESS;
09665 case SQL_ASYNC_ENABLE:
09666 *ret = SQL_ASYNC_ENABLE_OFF;
09667 return SQL_SUCCESS;
09668 case SQL_CONCURRENCY:
09669 *ret = SQL_CONCUR_LOCK;
09670 return SQL_SUCCESS;
09671 case SQL_ATTR_RETRIEVE_DATA:
09672 *ret = s->retr_data;
09673 return SQL_SUCCESS;
09674 case SQL_ROWSET_SIZE:
09675 case SQL_ATTR_ROW_ARRAY_SIZE:
09676 *ret = s->rowset_size;
09677 return SQL_SUCCESS;
09678 case SQL_ATTR_MAX_ROWS:
09679 *ret = s->max_rows;
09680 return SQL_SUCCESS;
09681 case SQL_ATTR_MAX_LENGTH:
09682 *ret = 1000000000;
09683 return SQL_SUCCESS;
09684 }
09685 return drvunimplstmt(stmt);
09686 }
09687
09696 SQLRETURN SQL_API
09697 SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
09698 {
09699 SQLRETURN ret;
09700
09701 HSTMT_LOCK(stmt);
09702 ret = drvgetstmtoption(stmt, opt, param);
09703 HSTMT_UNLOCK(stmt);
09704 return ret;
09705 }
09706
09707 #ifdef WINTERFACE
09708
09716 SQLRETURN SQL_API
09717 SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
09718 {
09719 SQLRETURN ret;
09720
09721 HSTMT_LOCK(stmt);
09722 ret = drvgetstmtoption(stmt, opt, param);
09723 HSTMT_UNLOCK(stmt);
09724 return ret;
09725 }
09726 #endif
09727
09736 static SQLRETURN
09737 drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
09738 {
09739 STMT *s = (STMT *) stmt;
09740
09741 switch (opt) {
09742 case SQL_CURSOR_TYPE:
09743 if (param == SQL_CURSOR_FORWARD_ONLY) {
09744 s->curtype = param;
09745 } else {
09746 s->curtype = SQL_CURSOR_STATIC;
09747 }
09748 if (param != SQL_CURSOR_FORWARD_ONLY &&
09749 param != SQL_CURSOR_STATIC) {
09750 goto e01s02;
09751 }
09752 return SQL_SUCCESS;
09753 case SQL_ASYNC_ENABLE:
09754 if (param != SQL_ASYNC_ENABLE_OFF) {
09755 goto e01s02;
09756 }
09757 return SQL_SUCCESS;
09758 case SQL_CONCURRENCY:
09759 if (param != SQL_CONCUR_LOCK) {
09760 goto e01s02;
09761 }
09762 return SQL_SUCCESS;
09763 case SQL_QUERY_TIMEOUT:
09764 return SQL_SUCCESS;
09765 case SQL_RETRIEVE_DATA:
09766 if (param != SQL_RD_ON && param != SQL_RD_OFF) {
09767 e01s02:
09768 setstat(s, -1, "option value changed", "01S02");
09769 return SQL_SUCCESS_WITH_INFO;
09770 }
09771 s->retr_data = (int) param;
09772 return SQL_SUCCESS;
09773 case SQL_ROWSET_SIZE:
09774 case SQL_ATTR_ROW_ARRAY_SIZE:
09775 if (param < 1) {
09776 setstat(s, -1, "invalid rowset size", "HY000");
09777 return SQL_ERROR;
09778 } else {
09779 SQLUSMALLINT *rst = &s->row_status1;
09780
09781 if (param > 1) {
09782 rst = xmalloc(sizeof (SQLUSMALLINT) * param);
09783 if (!rst) {
09784 return nomem(s);
09785 }
09786 }
09787 if (s->row_status0 != &s->row_status1) {
09788 freep(&s->row_status0);
09789 }
09790 s->row_status0 = rst;
09791 s->rowset_size = param;
09792 }
09793 return SQL_SUCCESS;
09794 case SQL_ATTR_MAX_ROWS:
09795 s->max_rows = param;
09796 return SQL_SUCCESS;
09797 case SQL_ATTR_MAX_LENGTH:
09798 if (param != 1000000000) {
09799 goto e01s02;
09800 }
09801 return SQL_SUCCESS;
09802 }
09803 return drvunimplstmt(stmt);
09804 }
09805
09814 SQLRETURN SQL_API
09815 SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt,
09816 SETSTMTOPTION_LAST_ARG_TYPE param)
09817 {
09818 SQLRETURN ret;
09819
09820 HSTMT_LOCK(stmt);
09821 ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
09822 HSTMT_UNLOCK(stmt);
09823 return ret;
09824 }
09825
09826 #ifdef WINTERFACE
09827
09835 SQLRETURN SQL_API
09836 SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt,
09837 SETSTMTOPTION_LAST_ARG_TYPE param)
09838 {
09839 SQLRETURN ret;
09840
09841 HSTMT_LOCK(stmt);
09842 ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
09843 HSTMT_UNLOCK(stmt);
09844 return ret;
09845 }
09846 #endif
09847
09854 static SQLRETURN
09855 chkunbound(STMT *s)
09856 {
09857 int i;
09858
09859 if (!s->bindcols || s->nbindcols < s->ncols) {
09860 unbound:
09861 setstat(s, -1, "unbound columns", (*s->ov3) ? "HY000" : "S1000");
09862 return SQL_ERROR;
09863 }
09864 for (i = 0; i < s->ncols; i++) {
09865 BINDCOL *b = &s->bindcols[i];
09866
09867 if (b->type == SQL_UNKNOWN_TYPE || !b->valp) {
09868 goto unbound;
09869 }
09870 }
09871 return SQL_SUCCESS;
09872 }
09873
09885 static SQLRETURN
09886 setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
09887 {
09888 DBC *d = (DBC *) s->dbc;
09889 SQLPOINTER dp = 0;
09890 SQLLEN *lp = 0;
09891 BINDCOL *b = &s->bindcols[i];
09892 COL *c = &s->cols[i];
09893 char strbuf[128], *cp;
09894
09895 if (b->valp) {
09896 if (s->bind_type != SQL_BIND_BY_COLUMN) {
09897 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
09898 } else {
09899 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
09900 }
09901 if (s->bind_offs) {
09902 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
09903 }
09904 }
09905 if (b->lenp) {
09906 if (s->bind_type != SQL_BIND_BY_COLUMN) {
09907 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
09908 } else {
09909 lp = b->lenp + rsi;
09910 }
09911 if (s->bind_offs) {
09912 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
09913 }
09914 }
09915 if (!dp || !lp) {
09916 setstat(s, -1, "unbound column in positional update",
09917 (*s->ov3) ? "HY000" : "S1000");
09918 return SQL_ERROR;
09919 }
09920 if (*lp == SQL_NULL_DATA) {
09921 sqlite3_bind_null(stmt, si);
09922 if (d->trace) {
09923 fprintf(d->trace, "-- parameter %d: NULL\n", si);
09924 fflush(d->trace);
09925 }
09926 return SQL_SUCCESS;
09927 }
09928 switch (b->type) {
09929 case SQL_C_UTINYINT:
09930 case SQL_C_TINYINT:
09931 case SQL_C_STINYINT:
09932 sqlite3_bind_int(stmt, si, *(SQLCHAR *) dp);
09933 if (d->trace) {
09934 fprintf(d->trace, "-- parameter %d: %d\n", si, *(SQLCHAR *) dp);
09935 fflush(d->trace);
09936 }
09937 break;
09938 #ifdef SQL_BIT
09939 case SQL_C_BIT:
09940 sqlite3_bind_int(stmt, si, (*(SQLCHAR *) dp) ? 1 : 0);
09941 if (d->trace) {
09942 fprintf(d->trace, "-- parameter %d: %d\n", si,
09943 (*(SQLCHAR *) dp) ? 1 : 0);
09944 fflush(d->trace);
09945 }
09946 break;
09947 #endif
09948 case SQL_C_USHORT:
09949 sqlite3_bind_int(stmt, si, *(SQLUSMALLINT *) dp);
09950 if (d->trace) {
09951 fprintf(d->trace, "-- parameter %d: %d\n", si,
09952 *(SQLUSMALLINT *) dp);
09953 fflush(d->trace);
09954 }
09955 break;
09956 case SQL_C_SHORT:
09957 case SQL_C_SSHORT:
09958 sqlite3_bind_int(stmt, si, *(SQLSMALLINT *) dp);
09959 if (d->trace) {
09960 fprintf(d->trace, "-- parameter %d: %d\n", si,
09961 *(SQLSMALLINT *) dp);
09962 fflush(d->trace);
09963 }
09964 break;
09965 case SQL_C_ULONG:
09966 sqlite3_bind_int(stmt, si, *(SQLUINTEGER *) dp);
09967 if (d->trace) {
09968 fprintf(d->trace, "-- parameter %d: %ld\n", si,
09969 (long) *(SQLUINTEGER *) dp);
09970 fflush(d->trace);
09971 }
09972 break;
09973 case SQL_C_LONG:
09974 case SQL_C_SLONG:
09975 sqlite3_bind_int(stmt, si, *(SQLINTEGER *) dp);
09976 if (d->trace) {
09977 fprintf(d->trace, "-- parameter %d: %ld\n", si,
09978 (long) *(SQLINTEGER *) dp);
09979 fflush(d->trace);
09980 }
09981 break;
09982 #ifdef SQL_BIGINT
09983 case SQL_C_UBIGINT:
09984 case SQL_C_SBIGINT:
09985 sqlite3_bind_int64(stmt, si, *(SQLBIGINT *) dp);
09986 if (d->trace) {
09987 fprintf(d->trace,
09988 #ifdef _WIN32
09989 "-- parameter %d: %I64d\n",
09990 #else
09991 "-- parameter %d: %lld\n",
09992 #endif
09993 si, (sqlite_int64) *(SQLBIGINT *) dp);
09994 fflush(d->trace);
09995 }
09996 break;
09997 #endif
09998 case SQL_C_FLOAT:
09999 sqlite3_bind_double(stmt, si, *(float *) dp);
10000 if (d->trace) {
10001 fprintf(d->trace, "-- parameter %d: %g\n", si,
10002 *(float *) dp);
10003 fflush(d->trace);
10004 }
10005 break;
10006 case SQL_C_DOUBLE:
10007 sqlite3_bind_double(stmt, si, *(double *) dp);
10008 if (d->trace) {
10009 fprintf(d->trace, "-- parameter %d: %g\n", si,
10010 *(double *) dp);
10011 fflush(d->trace);
10012 }
10013 break;
10014 case SQL_C_BINARY:
10015 sqlite3_bind_blob(stmt, si, (char *) dp, *lp, SQLITE_STATIC);
10016 if (d->trace) {
10017 fprintf(d->trace, "-- parameter %d: [BLOB]\n", si);
10018 fflush(d->trace);
10019 }
10020 break;
10021 #ifdef WCHARSUPPORT
10022 case SQL_C_WCHAR:
10023 cp = uc_to_utf((SQLWCHAR *) dp, *lp);
10024 if (!cp) {
10025 return nomem(s);
10026 }
10027 sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
10028 if (d->trace) {
10029 fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
10030 fflush(d->trace);
10031 }
10032 uc_free(cp);
10033 break;
10034 #endif
10035 case SQL_C_CHAR:
10036 #if defined(_WIN32) || defined(_WIN64)
10037 if (*s->oemcp) {
10038 cp = wmb_to_utf((char *) dp, *lp);
10039 if (!cp) {
10040 return nomem(s);
10041 }
10042 sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
10043 if (d->trace) {
10044 fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
10045 fflush(d->trace);
10046 }
10047 uc_free(cp);
10048 } else
10049 #endif
10050 {
10051 if (*lp == SQL_NTS) {
10052 sqlite3_bind_text(stmt, si, (char *) dp, -1,
10053 SQLITE_STATIC);
10054 if (d->trace) {
10055 fprintf(d->trace, "-- parameter %d: '%s'\n", si,
10056 (char *) dp);
10057 fflush(d->trace);
10058 }
10059 } else {
10060 sqlite3_bind_text(stmt, si, (char *) dp, *lp,
10061 SQLITE_STATIC);
10062 if (d->trace) {
10063 fprintf(d->trace, "-- parameter %d: '%*s'\n", si,
10064 (int) *lp, (char *) dp);
10065 fflush(d->trace);
10066 }
10067 }
10068 }
10069 break;
10070 #ifdef SQL_C_TYPE_DATE
10071 case SQL_C_TYPE_DATE:
10072 #endif
10073 case SQL_C_DATE:
10074 if (*s->jdconv) {
10075 int a, b, x1, x2, y, m, dd;
10076 double v;
10077
10078 y = ((DATE_STRUCT *) dp)->year;
10079 m = ((DATE_STRUCT *) dp)->month;
10080 dd = ((DATE_STRUCT *) dp)->day;
10081 if (m <= 2) {
10082 y--;
10083 m += 12;
10084 }
10085 a = y / 100;
10086 b = 2 - a + (a / 4);
10087 x1 = 36525 * (y + 4716) / 100;
10088 x2 = 306001 * (m + 1) / 10000;
10089 v = x1 + x2 + dd + b - 1524.5;
10090 sqlite3_bind_double(stmt, si, v);
10091 if (d->trace) {
10092 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10093 fflush(d->trace);
10094 }
10095 } else {
10096 sprintf(strbuf, "%04d-%02d-%02d",
10097 ((DATE_STRUCT *) dp)->year,
10098 ((DATE_STRUCT *) dp)->month,
10099 ((DATE_STRUCT *) dp)->day);
10100 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10101 if (d->trace) {
10102 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10103 fflush(d->trace);
10104 }
10105 }
10106 break;
10107 #ifdef SQL_C_TYPE_TIME
10108 case SQL_C_TYPE_TIME:
10109 #endif
10110 case SQL_C_TIME:
10111 if (*s->jdconv) {
10112 double v;
10113
10114 v = 2451544.5 +
10115 (((TIME_STRUCT *) dp)->hour * 3600000.0 +
10116 ((TIME_STRUCT *) dp)->minute * 60000.0 +
10117 ((TIME_STRUCT *) dp)->second * 1000.0) / 86400000.0;
10118 sqlite3_bind_double(stmt, si, v);
10119 if (d->trace) {
10120 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10121 fflush(d->trace);
10122 }
10123 } else {
10124 sprintf(strbuf, "%02d:%02d:%02d",
10125 ((TIME_STRUCT *) dp)->hour,
10126 ((TIME_STRUCT *) dp)->minute,
10127 ((TIME_STRUCT *) dp)->second);
10128 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10129 if (d->trace) {
10130 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10131 fflush(d->trace);
10132 }
10133 }
10134 break;
10135 #ifdef SQL_C_TYPE_TIMESTAMP
10136 case SQL_C_TYPE_TIMESTAMP:
10137 #endif
10138 case SQL_C_TIMESTAMP:
10139 if (*s->jdconv) {
10140 int a, b, x1, x2, y, m, dd;
10141 double v;
10142
10143 y = ((TIMESTAMP_STRUCT *) dp)->year;
10144 m = ((TIMESTAMP_STRUCT *) dp)->month;
10145 dd = ((TIMESTAMP_STRUCT *) dp)->day;
10146 if (m <= 2) {
10147 y--;
10148 m += 12;
10149 }
10150 a = y / 100;
10151 b = 2 - a + (a / 4);
10152 x1 = 36525 * (y + 4716) / 100;
10153 x2 = 306001 * (m + 1) / 10000;
10154 v = x1 + x2 + dd + b - 1524.5 +
10155 (((TIMESTAMP_STRUCT *) dp)->hour * 3600000.0 +
10156 ((TIMESTAMP_STRUCT *) dp)->minute * 60000.0 +
10157 ((TIMESTAMP_STRUCT *) dp)->second * 1000.0 +
10158 ((TIMESTAMP_STRUCT *) dp)->fraction / 1.0E6)
10159 / 86400000.0;
10160 sqlite3_bind_double(stmt, si, v);
10161 if (d->trace) {
10162 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
10163 fflush(d->trace);
10164 }
10165 } else {
10166 int frac;
10167
10168 frac = (int) ((TIMESTAMP_STRUCT *) dp)->fraction;
10169 frac /= 1000000;
10170 frac = frac % 1000;
10171 if (frac < 0) {
10172 frac = 0;
10173 }
10174 if (c->prec && c->prec <= 16) {
10175 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
10176 ((TIMESTAMP_STRUCT *) dp)->year,
10177 ((TIMESTAMP_STRUCT *) dp)->month,
10178 ((TIMESTAMP_STRUCT *) dp)->day,
10179 ((TIMESTAMP_STRUCT *) dp)->hour,
10180 ((TIMESTAMP_STRUCT *) dp)->minute);
10181 } else if (c->prec && c->prec <= 19) {
10182 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
10183 ((TIMESTAMP_STRUCT *) dp)->year,
10184 ((TIMESTAMP_STRUCT *) dp)->month,
10185 ((TIMESTAMP_STRUCT *) dp)->day,
10186 ((TIMESTAMP_STRUCT *) dp)->hour,
10187 ((TIMESTAMP_STRUCT *) dp)->minute,
10188 ((TIMESTAMP_STRUCT *) dp)->second);
10189 } else {
10190 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
10191 ((TIMESTAMP_STRUCT *) dp)->year,
10192 ((TIMESTAMP_STRUCT *) dp)->month,
10193 ((TIMESTAMP_STRUCT *) dp)->day,
10194 ((TIMESTAMP_STRUCT *) dp)->hour,
10195 ((TIMESTAMP_STRUCT *) dp)->minute,
10196 ((TIMESTAMP_STRUCT *) dp)->second,
10197 frac);
10198 }
10199 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
10200 if (d->trace) {
10201 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
10202 fflush(d->trace);
10203 }
10204 }
10205 break;
10206 default:
10207 setstat(s, -1, "unsupported column type in positional update",
10208 (*s->ov3) ? "HY000" : "S1000");
10209 return SQL_ERROR;
10210 }
10211 return SQL_SUCCESS;
10212 }
10213
10225 static SQLRETURN
10226 setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
10227 {
10228 DBC *d = (DBC *) s->dbc;
10229 char **data;
10230 int pos;
10231
10232 pos = s->rowprs;
10233 if (pos < 0) {
10234 setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10235 return SQL_ERROR;
10236 }
10237 pos += rsi;
10238 data = s->rows + s->ncols + (pos * s->ncols) + i;
10239 if (*data == NULL) {
10240 sqlite3_bind_null(stmt, si);
10241 if (d->trace) {
10242 fprintf(d->trace, "-- parameter %d: NULL\n", si);
10243 fflush(d->trace);
10244 }
10245 } else {
10246 sqlite3_bind_text(stmt, si, *data, -1, SQLITE_STATIC);
10247 if (d->trace) {
10248 fprintf(d->trace, "-- parameter %d: '%s'\n", si, *data);
10249 fflush(d->trace);
10250 }
10251 }
10252 return SQL_SUCCESS;
10253 }
10254
10262 static SQLRETURN
10263 setposrefr(STMT *s, int rsi)
10264 {
10265 int i, withinfo = 0;
10266 SQLRETURN ret = SQL_SUCCESS;
10267
10268 for (i = 0; s->bindcols && i < s->ncols; i++) {
10269 BINDCOL *b = &s->bindcols[i];
10270 SQLPOINTER dp = 0;
10271 SQLLEN *lp = 0;
10272
10273 b->offs = 0;
10274 if (b->valp) {
10275 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10276 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
10277 } else {
10278 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
10279 }
10280 if (s->bind_offs) {
10281 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
10282 }
10283 }
10284 if (b->lenp) {
10285 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10286 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
10287 } else {
10288 lp = b->lenp + rsi;
10289 }
10290 if (s->bind_offs) {
10291 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
10292 }
10293 }
10294 if (dp || lp) {
10295 int rowp = s->rowp;
10296
10297 s->rowp = s->rowprs + rsi;
10298 ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp,
10299 b->max, lp, 0);
10300 s->rowp = rowp;
10301 if (!SQL_SUCCEEDED(ret)) {
10302 s->row_status0[rsi] = SQL_ROW_ERROR;
10303 break;
10304 }
10305 if (ret != SQL_SUCCESS) {
10306 withinfo = 1;
10307 #ifdef SQL_ROW_SUCCESS_WITH_INFO
10308 s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
10309 #endif
10310 }
10311 }
10312 }
10313 if (SQL_SUCCEEDED(ret)) {
10314 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10315 }
10316 return ret;
10317 }
10318
10328 static SQLRETURN
10329 drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10330 {
10331 STMT *s = (STMT *) stmt;
10332 DBC *d = (DBC *) s->dbc;
10333 int rowp, i, k, rc, nretry = 0;
10334 dstr *sql = 0;
10335 const char *endp;
10336 sqlite3_stmt *s3stmt = NULL;
10337 SQLRETURN ret;
10338
10339 if (lock != SQL_LOCK_NO_CHANGE) {
10340 setstat(s, -1, "unsupported locking mode",
10341 (*s->ov3) ? "HY000" : "S1000");
10342 return SQL_ERROR;
10343 }
10344 if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10345 setstat(s, -1, "incompatible statement",
10346 (*s->ov3) ? "HY000" : "S1000");
10347 return SQL_ERROR;
10348 }
10349 if (op == SQL_ADD) {
10350 if (s->one_tbl <= 0) {
10351 setstat(s, -1, "incompatible rowset",
10352 (*s->ov3) ? "HY000" : "S1000");
10353 return SQL_ERROR;
10354 }
10355 if (row == 0 || row > s->rowset_size + 1) {
10356 goto rowoor;
10357 }
10358 ret = chkunbound(s);
10359 if (ret != SQL_SUCCESS) {
10360 return ret;
10361 }
10362 sql = dsappend(sql, "INSERT INTO ");
10363 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10364 sql = dsappendq(sql, s->dyncols[0].db);
10365 sql = dsappend(sql, ".");
10366 }
10367 sql = dsappendq(sql, s->dyncols[0].table);
10368 for (i = 0; i < s->ncols; i++) {
10369 sql = dsappend(sql, (i > 0) ? "," : "(");
10370 sql = dsappendq(sql, s->dyncols[i].column);
10371 }
10372 sql = dsappend(sql, ") VALUES ");
10373 for (i = 0; i < s->ncols; i++) {
10374 sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10375 }
10376 sql = dsappend(sql, ")");
10377 if (dserr(sql)) {
10378 dsfree(sql);
10379 return nomem(s);
10380 }
10381 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10382 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10383 #else
10384 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10385 #endif
10386 do {
10387 s3stmt = NULL;
10388 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10389 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10390 &s3stmt, &endp);
10391 #else
10392 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10393 &s3stmt, &endp);
10394 #endif
10395 if (rc != SQLITE_OK) {
10396 if (s3stmt) {
10397 sqlite3_finalize(s3stmt);
10398 s3stmt = NULL;
10399 }
10400 }
10401 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10402 dbtracerc(d, rc, NULL);
10403 dsfree(sql);
10404 if (rc != SQLITE_OK) {
10405 istmterr:
10406 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10407 sqlite3_errmsg(d->sqlite), rc);
10408 if (s3stmt) {
10409 dbtraceapi(d, "sqlite3_finalize", NULL);
10410 sqlite3_finalize(s3stmt);
10411 }
10412 return SQL_ERROR;
10413 }
10414 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10415 ret = setposbind(s, s3stmt, i, k, row - 1);
10416 if (ret != SQL_SUCCESS) {
10417 dbtraceapi(d, "sqlite3_finalize", NULL);
10418 sqlite3_finalize(s3stmt);
10419 return ret;
10420 }
10421 k++;
10422 }
10423 rc = sqlite3_step(s3stmt);
10424 if (rc != SQLITE_DONE) {
10425 goto istmterr;
10426 }
10427 sqlite3_finalize(s3stmt);
10428 if (sqlite3_changes(d->sqlite) > 0 && row <= s->rowset_size) {
10429 if (s->row_status0) {
10430 s->row_status0[row - 1] = SQL_ROW_ADDED;
10431 }
10432 if (s->row_status) {
10433 s->row_status[row - 1] = SQL_ROW_ADDED;
10434 }
10435 }
10436 return SQL_SUCCESS;
10437 } else if (op == SQL_UPDATE || op == SQL_DELETE) {
10438 if (s->one_tbl <= 0 || s->has_pk <= 0) {
10439 setstat(s, -1, "incompatible rowset",
10440 (*s->ov3) ? "HY000" : "S1000");
10441 return SQL_ERROR;
10442 }
10443 if (row == 0) {
10444 ret = SQL_SUCCESS;
10445 for (i = 1; i <= s->rowset_size; i++) {
10446 ret = drvsetpos(stmt, i, op, lock);
10447 if (!SQL_SUCCEEDED(ret)) {
10448 break;
10449 }
10450 }
10451 return ret;
10452 }
10453 if (row > s->rowset_size) {
10454 goto rowoor;
10455 }
10456 }
10457 if (op != SQL_POSITION && op != SQL_REFRESH &&
10458 op != SQL_DELETE && op != SQL_UPDATE) {
10459 return drvunimplstmt(stmt);
10460 }
10461 if (op == SQL_POSITION) {
10462 rowp = s->rowp + row - 1;
10463 if (!s->rows || row == 0 || rowp < -1 || rowp >= s->nrows) {
10464 rowoor:
10465 setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10466 return SQL_ERROR;
10467 }
10468 s->rowp = rowp;
10469 } else if (op == SQL_REFRESH) {
10470 if (row > s->rowset_size) {
10471 goto rowoor;
10472 }
10473 if (row == 0) {
10474 ret = SQL_SUCCESS;
10475 for (i = 0; i < s->rowset_size; i++) {
10476 ret = setposrefr(s, i);
10477 if (!SQL_SUCCEEDED(ret)) {
10478 break;
10479 }
10480 }
10481 return ret;
10482 }
10483 return setposrefr(s, row - 1);
10484 } else if (op == SQL_DELETE) {
10485 sql = dsappend(sql, "DELETE FROM ");
10486 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10487 sql = dsappendq(sql, s->dyncols[0].db);
10488 sql = dsappend(sql, ".");
10489 }
10490 sql = dsappendq(sql, s->dyncols[0].table);
10491 for (i = k = 0; i < s->ncols; i++) {
10492 if (s->dyncols[i].ispk <= 0) {
10493 continue;
10494 }
10495 sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10496 sql = dsappendq(sql, s->dyncols[i].column);
10497 sql = dsappend(sql, " = ?");
10498 k++;
10499 }
10500 if (dserr(sql)) {
10501 dsfree(sql);
10502 return nomem(s);
10503 }
10504 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10505 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10506 #else
10507 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10508 #endif
10509 do {
10510 s3stmt = NULL;
10511 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10512 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10513 &s3stmt, &endp);
10514 #else
10515 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10516 &s3stmt, &endp);
10517 #endif
10518 if (rc != SQLITE_OK) {
10519 if (s3stmt) {
10520 sqlite3_finalize(s3stmt);
10521 s3stmt = NULL;
10522 }
10523 }
10524 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10525 dbtracerc(d, rc, NULL);
10526 dsfree(sql);
10527 if (rc != SQLITE_OK) {
10528 dstmterr:
10529 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10530 sqlite3_errmsg(d->sqlite), rc);
10531 if (s3stmt) {
10532 dbtraceapi(d, "sqlite3_finalize", NULL);
10533 sqlite3_finalize(s3stmt);
10534 }
10535 return SQL_ERROR;
10536 }
10537 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10538 if (s->dyncols[i].ispk <= 0) {
10539 continue;
10540 }
10541 ret = setposibind(s, s3stmt, i, k, row - 1);
10542 if (ret != SQL_SUCCESS) {
10543 dbtraceapi(d, "sqlite3_finalize", NULL);
10544 sqlite3_finalize(s3stmt);
10545 return ret;
10546 }
10547 k++;
10548 }
10549 rc = sqlite3_step(s3stmt);
10550 if (rc != SQLITE_DONE) {
10551 goto dstmterr;
10552 }
10553 sqlite3_finalize(s3stmt);
10554 if (sqlite3_changes(d->sqlite) > 0) {
10555 if (s->row_status0) {
10556 s->row_status0[row - 1] = SQL_ROW_DELETED;
10557 }
10558 if (s->row_status) {
10559 s->row_status[row - 1] = SQL_ROW_DELETED;
10560 }
10561 }
10562 return SQL_SUCCESS;
10563 } else if (op == SQL_UPDATE) {
10564 ret = chkunbound(s);
10565 if (ret != SQL_SUCCESS) {
10566 return ret;
10567 }
10568 sql = dsappend(sql, "UPDATE ");
10569 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10570 sql = dsappendq(sql, s->dyncols[0].db);
10571 sql = dsappend(sql, ".");
10572 }
10573 sql = dsappendq(sql, s->dyncols[0].table);
10574 for (i = 0; i < s->ncols; i++) {
10575 sql = dsappend(sql, (i > 0) ? ", " : " SET ");
10576 sql = dsappendq(sql, s->dyncols[i].column);
10577 sql = dsappend(sql, " = ?");
10578 }
10579 for (i = k = 0; i < s->ncols; i++) {
10580 if (s->dyncols[i].ispk <= 0) {
10581 continue;
10582 }
10583 sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10584 sql = dsappendq(sql, s->dyncols[i].column);
10585 sql = dsappend(sql, " = ?");
10586 k++;
10587 }
10588 if (dserr(sql)) {
10589 dsfree(sql);
10590 return nomem(s);
10591 }
10592 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10593 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10594 #else
10595 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10596 #endif
10597 do {
10598 s3stmt = NULL;
10599 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10600 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10601 &s3stmt, &endp);
10602 #else
10603 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10604 &s3stmt, &endp);
10605 #endif
10606 if (rc != SQLITE_OK) {
10607 if (s3stmt) {
10608 sqlite3_finalize(s3stmt);
10609 s3stmt = NULL;
10610 }
10611 }
10612 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10613 dbtracerc(d, rc, NULL);
10614 dsfree(sql);
10615 if (rc != SQLITE_OK) {
10616 ustmterr:
10617 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10618 sqlite3_errmsg(d->sqlite), rc);
10619 if (s3stmt) {
10620 dbtraceapi(d, "sqlite3_finalize", NULL);
10621 sqlite3_finalize(s3stmt);
10622 }
10623 return SQL_ERROR;
10624 }
10625 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10626 ret = setposbind(s, s3stmt, i, k, row - 1);
10627 if (ret != SQL_SUCCESS) {
10628 dbtraceapi(d, "sqlite3_finalize", NULL);
10629 sqlite3_finalize(s3stmt);
10630 return ret;
10631 }
10632 k++;
10633 }
10634 for (i = 0; s->bindcols && i < s->ncols; i++) {
10635 if (s->dyncols[i].ispk <= 0) {
10636 continue;
10637 }
10638 ret = setposibind(s, s3stmt, i, k, row - 1);
10639 if (ret != SQL_SUCCESS) {
10640 dbtraceapi(d, "sqlite3_finalize", NULL);
10641 sqlite3_finalize(s3stmt);
10642 return ret;
10643 }
10644 k++;
10645 }
10646 rc = sqlite3_step(s3stmt);
10647 if (rc != SQLITE_DONE) {
10648 goto ustmterr;
10649 }
10650 sqlite3_finalize(s3stmt);
10651 if (sqlite3_changes(d->sqlite) > 0) {
10652 if (s->row_status0) {
10653 s->row_status0[row - 1] = SQL_ROW_UPDATED;
10654 }
10655 if (s->row_status) {
10656 s->row_status[row - 1] = SQL_ROW_UPDATED;
10657 }
10658 }
10659 return SQL_SUCCESS;
10660 }
10661 return SQL_SUCCESS;
10662 }
10663
10673 SQLRETURN SQL_API
10674 SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10675 {
10676 SQLRETURN ret;
10677
10678 HSTMT_LOCK(stmt);
10679 ret = drvsetpos(stmt, row, op, lock);
10680 HSTMT_UNLOCK(stmt);
10681 return ret;
10682 }
10683
10691 static SQLRETURN
10692 drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
10693 {
10694 STMT *s = (STMT *) stmt;
10695 DBC *d = (DBC *) s->dbc;
10696 int row, i, k, rc, nretry = 0;
10697 dstr *sql = 0;
10698 const char *endp;
10699 sqlite3_stmt *s3stmt = NULL;
10700 SQLRETURN ret;
10701
10702 if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10703 setstat(s, -1, "incompatible statement",
10704 (*s->ov3) ? "HY000" : "S1000");
10705 return SQL_ERROR;
10706 }
10707 if (op == SQL_ADD) {
10708 if (s->one_tbl <= 0) {
10709 setstat(s, -1, "incompatible rowset",
10710 (*s->ov3) ? "HY000" : "S1000");
10711 return SQL_ERROR;
10712 }
10713 ret = chkunbound(s);
10714 if (ret != SQL_SUCCESS) {
10715 return ret;
10716 }
10717 sql = dsappend(sql, "INSERT INTO ");
10718 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10719 sql = dsappendq(sql, s->dyncols[0].db);
10720 sql = dsappend(sql, ".");
10721 }
10722 sql = dsappendq(sql, s->dyncols[0].table);
10723 for (i = 0; i < s->ncols; i++) {
10724 sql = dsappend(sql, (i > 0) ? "," : "(");
10725 sql = dsappendq(sql, s->dyncols[i].column);
10726 }
10727 sql = dsappend(sql, ") VALUES ");
10728 for (i = 0; i < s->ncols; i++) {
10729 sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10730 }
10731 sql = dsappend(sql, ")");
10732 if (dserr(sql)) {
10733 dsfree(sql);
10734 return nomem(s);
10735 }
10736 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10737 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10738 #else
10739 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10740 #endif
10741 do {
10742 s3stmt = NULL;
10743 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10744 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10745 &s3stmt, &endp);
10746 #else
10747 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10748 &s3stmt, &endp);
10749 #endif
10750 if (rc != SQLITE_OK) {
10751 if (s3stmt) {
10752 sqlite3_finalize(s3stmt);
10753 s3stmt = NULL;
10754 }
10755 }
10756 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10757 dbtracerc(d, rc, NULL);
10758 dsfree(sql);
10759 if (rc != SQLITE_OK) {
10760 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10761 sqlite3_errmsg(d->sqlite), rc);
10762 if (s3stmt) {
10763 dbtraceapi(d, "sqlite3_finalize", NULL);
10764 sqlite3_finalize(s3stmt);
10765 }
10766 return SQL_ERROR;
10767 }
10768 for (row = 0; row < s->rowset_size; row++) {
10769 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10770 ret = setposbind(s, s3stmt, i, k, row);
10771 if (ret != SQL_SUCCESS) {
10772 istmterr:
10773 if (s->row_status0) {
10774 s->row_status0[row] = SQL_ROW_ERROR;
10775 }
10776 if (s->row_status) {
10777 s->row_status[row] = SQL_ROW_ERROR;
10778 }
10779 dbtraceapi(d, "sqlite3_finalize", NULL);
10780 sqlite3_finalize(s3stmt);
10781 return ret;
10782 }
10783 k++;
10784 }
10785 rc = sqlite3_step(s3stmt);
10786 if (rc != SQLITE_DONE) {
10787 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10788 sqlite3_errmsg(d->sqlite), rc);
10789 ret = SQL_ERROR;
10790 goto istmterr;
10791 }
10792 if (sqlite3_changes(d->sqlite) > 0) {
10793 if (s->row_status0) {
10794 s->row_status0[row] = SQL_ROW_ADDED;
10795 }
10796 if (s->row_status) {
10797 s->row_status[row] = SQL_ROW_ADDED;
10798 }
10799 }
10800 if (s->bkmrk == SQL_UB_VARIABLE &&
10801 s->bkmrkcol.type == SQL_C_VARBOOKMARK &&
10802 s->bkmrkcol.valp) {
10803 SQLPOINTER *val;
10804
10805 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10806 val = (SQLPOINTER)
10807 ((char *) s->bkmrkcol.valp + s->bind_type * row);
10808 } else {
10809 val = (SQLPOINTER)
10810 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10811 }
10812 if (s->bind_offs) {
10813 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10814 }
10815 *(sqlite_int64 *) val = sqlite3_last_insert_rowid(d->sqlite);
10816 if (s->bkmrkcol.lenp) {
10817 SQLLEN *ival;
10818
10819 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10820 ival = (SQLLEN *)
10821 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10822 } else {
10823 ival = &s->bkmrkcol.lenp[row];
10824 }
10825 if (s->bind_offs) {
10826 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10827 }
10828 *ival = sizeof (sqlite_int64);
10829 }
10830 }
10831 dbtraceapi(d, "sqlite3_reset", NULL);
10832 sqlite3_reset(s3stmt);
10833 }
10834 dbtraceapi(d, "sqlite3_finalize", NULL);
10835 sqlite3_finalize(s3stmt);
10836 return SQL_SUCCESS;
10837 } else if (op == SQL_DELETE_BY_BOOKMARK) {
10838 if (s->has_rowid < 0 ||
10839 s->bkmrk != SQL_UB_VARIABLE ||
10840 s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10841 !s->bkmrkcol.valp) {
10842 setstat(s, -1, "incompatible rowset",
10843 (*s->ov3) ? "HY000" : "S1000");
10844 return SQL_ERROR;
10845 }
10846 sql = dsappend(sql, "DELETE FROM ");
10847 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10848 sql = dsappendq(sql, s->dyncols[0].db);
10849 sql = dsappend(sql, ".");
10850 }
10851 sql = dsappendq(sql, s->dyncols[0].table);
10852 sql = dsappend(sql, " WHERE ");
10853 sql = dsappendq(sql, s->dyncols[0].column);
10854 sql = dsappend(sql, " = ?");
10855 if (dserr(sql)) {
10856 dsfree(sql);
10857 return nomem(s);
10858 }
10859 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10860 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10861 #else
10862 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10863 #endif
10864 do {
10865 s3stmt = NULL;
10866 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10867 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10868 &s3stmt, &endp);
10869 #else
10870 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10871 &s3stmt, &endp);
10872 #endif
10873 if (rc != SQLITE_OK) {
10874 if (s3stmt) {
10875 sqlite3_finalize(s3stmt);
10876 s3stmt = NULL;
10877 }
10878 }
10879 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10880 dbtracerc(d, rc, NULL);
10881 dsfree(sql);
10882 if (rc != SQLITE_OK) {
10883 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10884 sqlite3_errmsg(d->sqlite), rc);
10885 if (s3stmt) {
10886 dbtraceapi(d, "sqlite3_finalize", NULL);
10887 sqlite3_finalize(s3stmt);
10888 }
10889 return SQL_ERROR;
10890 }
10891 for (row = 0; row < s->rowset_size; row++) {
10892 SQLPOINTER *val;
10893 sqlite_int64 rowid;
10894
10895 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10896 val = (SQLPOINTER)
10897 ((char *) s->bkmrkcol.valp + s->bind_type * row);
10898 } else {
10899 val = (SQLPOINTER)
10900 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10901 }
10902 if (s->bind_offs) {
10903 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10904 }
10905 if (s->bkmrkcol.lenp) {
10906 SQLLEN *ival;
10907
10908 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10909 ival = (SQLLEN *)
10910 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10911 } else {
10912 ival = &s->bkmrkcol.lenp[row];
10913 }
10914 if (s->bind_offs) {
10915 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10916 }
10917 if (*ival != sizeof (sqlite_int64)) {
10918 continue;
10919 }
10920 }
10921 rowid = *(sqlite_int64 *) val;
10922 sqlite3_bind_int64(s3stmt, 1, rowid);
10923 if (d->trace) {
10924 fprintf(d->trace,
10925 #ifdef _WIN32
10926 "-- parameter 1: %I64d\n",
10927 #else
10928 "-- parameter 1: %lld\n",
10929 #endif
10930 rowid);
10931 fflush(d->trace);
10932 }
10933 rc = sqlite3_step(s3stmt);
10934 if (rc != SQLITE_DONE) {
10935 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10936 sqlite3_errmsg(d->sqlite), rc);
10937 if (s->row_status0) {
10938 s->row_status0[row] = SQL_ROW_ERROR;
10939 }
10940 if (s->row_status) {
10941 s->row_status[row] = SQL_ROW_ERROR;
10942 }
10943 dbtraceapi(d, "sqlite3_finalize", NULL);
10944 sqlite3_finalize(s3stmt);
10945 return SQL_ERROR;
10946 }
10947 if (sqlite3_changes(d->sqlite) > 0) {
10948 if (s->row_status0) {
10949 s->row_status0[row] = SQL_ROW_DELETED;
10950 }
10951 if (s->row_status) {
10952 s->row_status[row] = SQL_ROW_DELETED;
10953 }
10954 }
10955 dbtraceapi(d, "sqlite3_reset", NULL);
10956 sqlite3_reset(s3stmt);
10957 }
10958 dbtraceapi(d, "sqlite3_finalize", NULL);
10959 sqlite3_finalize(s3stmt);
10960 return SQL_SUCCESS;
10961 } else if (op == SQL_UPDATE_BY_BOOKMARK) {
10962 if (s->has_rowid < 0 ||
10963 s->bkmrk != SQL_UB_VARIABLE ||
10964 s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10965 !s->bkmrkcol.valp) {
10966 setstat(s, -1, "incompatible rowset",
10967 (*s->ov3) ? "HY000" : "S1000");
10968 return SQL_ERROR;
10969 }
10970 ret = chkunbound(s);
10971 if (ret != SQL_SUCCESS) {
10972 return ret;
10973 }
10974 sql = dsappend(sql, "UPDATE ");
10975 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10976 sql = dsappendq(sql, s->dyncols[0].db);
10977 sql = dsappend(sql, ".");
10978 }
10979 sql = dsappendq(sql, s->dyncols[0].table);
10980 for (i = 0, k = 0; i < s->ncols; i++) {
10981 sql = dsappend(sql, (k > 0) ? ", " : " SET ");
10982 sql = dsappendq(sql, s->dyncols[i].column);
10983 sql = dsappend(sql, " = ?");
10984 k++;
10985 }
10986 sql = dsappend(sql, " WHERE ");
10987 sql = dsappendq(sql, s->dyncols[s->has_rowid].column);
10988 sql = dsappend(sql, " = ?");
10989 if (dserr(sql)) {
10990 dsfree(sql);
10991 return nomem(s);
10992 }
10993 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10994 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10995 #else
10996 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10997 #endif
10998 do {
10999 s3stmt = NULL;
11000 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
11001 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
11002 &s3stmt, &endp);
11003 #else
11004 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
11005 &s3stmt, &endp);
11006 #endif
11007 if (rc != SQLITE_OK) {
11008 if (s3stmt) {
11009 sqlite3_finalize(s3stmt);
11010 s3stmt = NULL;
11011 }
11012 }
11013 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
11014 dbtracerc(d, rc, NULL);
11015 dsfree(sql);
11016 if (rc != SQLITE_OK) {
11017 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
11018 sqlite3_errmsg(d->sqlite), rc);
11019 if (s3stmt) {
11020 dbtraceapi(d, "sqlite3_finalize", NULL);
11021 sqlite3_finalize(s3stmt);
11022 }
11023 return SQL_ERROR;
11024 }
11025 for (row = 0; row < s->rowset_size; row++) {
11026 SQLPOINTER *val;
11027 sqlite_int64 rowid;
11028
11029 if (s->bind_type != SQL_BIND_BY_COLUMN) {
11030 val = (SQLPOINTER)
11031 ((char *) s->bkmrkcol.valp + s->bind_type * row);
11032 } else {
11033 val = (SQLPOINTER)
11034 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
11035 }
11036 if (s->bind_offs) {
11037 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
11038 }
11039 if (s->bkmrkcol.lenp) {
11040 SQLLEN *ival;
11041
11042 if (s->bind_type != SQL_BIND_BY_COLUMN) {
11043 ival = (SQLLEN *)
11044 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
11045 } else {
11046 ival = &s->bkmrkcol.lenp[row];
11047 }
11048 if (s->bind_offs) {
11049 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
11050 }
11051 if (*ival != sizeof (sqlite_int64)) {
11052 continue;
11053 }
11054 }
11055 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
11056 ret = setposbind(s, s3stmt, i, k, row);
11057 if (ret != SQL_SUCCESS) {
11058 ustmterr:
11059 if (s->row_status0) {
11060 s->row_status0[row] = SQL_ROW_ERROR;
11061 }
11062 if (s->row_status) {
11063 s->row_status[row] = SQL_ROW_ERROR;
11064 }
11065 dbtraceapi(d, "sqlite3_finalize", NULL);
11066 sqlite3_finalize(s3stmt);
11067 return ret;
11068 }
11069 k++;
11070 }
11071 rowid = *(sqlite_int64 *) val;
11072 sqlite3_bind_int64(s3stmt, k, rowid);
11073 if (d->trace) {
11074 fprintf(d->trace,
11075 #ifdef _WIN32
11076 "-- parameter %d: %I64d\n",
11077 #else
11078 "-- parameter %d: %lld\n",
11079 #endif
11080 k, rowid);
11081 fflush(d->trace);
11082 }
11083 rc = sqlite3_step(s3stmt);
11084 if (rc != SQLITE_DONE) {
11085 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
11086 sqlite3_errmsg(d->sqlite), rc);
11087 ret = SQL_ERROR;
11088 goto ustmterr;
11089 }
11090 if (sqlite3_changes(d->sqlite) > 0) {
11091 if (s->row_status0) {
11092 s->row_status0[row] = SQL_ROW_UPDATED;
11093 }
11094 if (s->row_status) {
11095 s->row_status[row] = SQL_ROW_UPDATED;
11096 }
11097 }
11098 dbtraceapi(d, "sqlite3_reset", NULL);
11099 sqlite3_reset(s3stmt);
11100 }
11101 dbtraceapi(d, "sqlite3_finalize", NULL);
11102 sqlite3_finalize(s3stmt);
11103 return SQL_SUCCESS;
11104 }
11105 setstat(s, -1, "unsupported operation", (*s->ov3) ? "HY000" : "S1000");
11106 return SQL_ERROR;
11107 }
11108
11116 SQLRETURN SQL_API
11117 SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
11118 {
11119 SQLRETURN ret;
11120
11121 HSTMT_LOCK(stmt);
11122 ret = drvbulkoperations(stmt, oper);
11123 HSTMT_UNLOCK(stmt);
11124 return ret;
11125 }
11126
11127
11132 SQLRETURN SQL_API
11133 SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset,
11134 SQLUSMALLINT rowset)
11135 {
11136 SQLRETURN ret;
11137
11138 HSTMT_LOCK(stmt);
11139 ret = drvunimplstmt(stmt);
11140 HSTMT_UNLOCK(stmt);
11141 return ret;
11142 }
11143
11144 #define strmak(dst, src, max, lenp) { \
11145 int len = strlen(src); \
11146 int cnt = min(len + 1, max); \
11147 strncpy(dst, src, cnt); \
11148 *lenp = (cnt > len) ? len : cnt; \
11149 }
11150
11161 static SQLRETURN
11162 drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11163 SQLSMALLINT *valLen)
11164 {
11165 DBC *d;
11166 char dummyc[301];
11167 SQLSMALLINT dummy;
11168 #if defined(_WIN32) || defined(_WIN64)
11169 char pathbuf[301], *drvname;
11170 #else
11171 static char drvname[] = "sqlite3odbc.so";
11172 #endif
11173
11174 if (dbc == SQL_NULL_HDBC) {
11175 return SQL_INVALID_HANDLE;
11176 }
11177 d = (DBC *) dbc;
11178 if (valMax) {
11179 valMax--;
11180 }
11181 if (!valLen) {
11182 valLen = &dummy;
11183 }
11184 if (!val) {
11185 val = dummyc;
11186 valMax = sizeof (dummyc) - 1;
11187 }
11188 switch (type) {
11189 case SQL_MAX_USER_NAME_LEN:
11190 *((SQLSMALLINT *) val) = 16;
11191 *valLen = sizeof (SQLSMALLINT);
11192 break;
11193 case SQL_USER_NAME:
11194 strmak(val, "", valMax, valLen);
11195 break;
11196 case SQL_DRIVER_ODBC_VER:
11197 #if 0
11198 strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11199 #else
11200 strmak(val, "03.00", valMax, valLen);
11201 #endif
11202 break;
11203 case SQL_ACTIVE_CONNECTIONS:
11204 case SQL_ACTIVE_STATEMENTS:
11205 *((SQLSMALLINT *) val) = 0;
11206 *valLen = sizeof (SQLSMALLINT);
11207 break;
11208 #ifdef SQL_ASYNC_MODE
11209 case SQL_ASYNC_MODE:
11210 *((SQLUINTEGER *) val) = SQL_AM_NONE;
11211 *valLen = sizeof (SQLUINTEGER);
11212 break;
11213 #endif
11214 #ifdef SQL_CREATE_TABLE
11215 case SQL_CREATE_TABLE:
11216 *((SQLUINTEGER *) val) = SQL_CT_CREATE_TABLE |
11217 SQL_CT_COLUMN_DEFAULT |
11218 SQL_CT_COLUMN_CONSTRAINT |
11219 SQL_CT_CONSTRAINT_NON_DEFERRABLE;
11220 *valLen = sizeof (SQLUINTEGER);
11221 break;
11222 #endif
11223 #ifdef SQL_CREATE_VIEW
11224 case SQL_CREATE_VIEW:
11225 *((SQLUINTEGER *) val) = SQL_CV_CREATE_VIEW;
11226 *valLen = sizeof (SQLUINTEGER);
11227 break;
11228 #endif
11229 #ifdef SQL_DDL_INDEX
11230 case SQL_DDL_INDEX:
11231 *((SQLUINTEGER *) val) = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
11232 *valLen = sizeof (SQLUINTEGER);
11233 break;
11234 #endif
11235 #ifdef SQL_DROP_TABLE
11236 case SQL_DROP_TABLE:
11237 *((SQLUINTEGER *) val) = SQL_DT_DROP_TABLE;
11238 *valLen = sizeof (SQLUINTEGER);
11239 break;
11240 #endif
11241 #ifdef SQL_DROP_VIEW
11242 case SQL_DROP_VIEW:
11243 *((SQLUINTEGER *) val) = SQL_DV_DROP_VIEW;
11244 *valLen = sizeof (SQLUINTEGER);
11245 break;
11246 #endif
11247 #ifdef SQL_INDEX_KEYWORDS
11248 case SQL_INDEX_KEYWORDS:
11249 *((SQLUINTEGER *) val) = SQL_IK_ALL;
11250 *valLen = sizeof (SQLUINTEGER);
11251 break;
11252 #endif
11253 case SQL_DATA_SOURCE_NAME:
11254 strmak(val, d->dsn ? d->dsn : "", valMax, valLen);
11255 break;
11256 case SQL_DRIVER_NAME:
11257 #if defined(_WIN32) || defined(_WIN64)
11258 GetModuleFileName(hModule, pathbuf, sizeof (pathbuf));
11259 drvname = strrchr(pathbuf, '\\');
11260 if (drvname == NULL) {
11261 drvname = strrchr(pathbuf, '/');
11262 }
11263 if (drvname == NULL) {
11264 drvname = pathbuf;
11265 } else {
11266 drvname++;
11267 }
11268 #endif
11269 strmak(val, drvname, valMax, valLen);
11270 break;
11271 case SQL_DRIVER_VER:
11272 strmak(val, DRIVER_VER_INFO, valMax, valLen);
11273 break;
11274 case SQL_FETCH_DIRECTION:
11275 *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
11276 SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
11277 *valLen = sizeof (SQLUINTEGER);
11278 break;
11279 case SQL_ODBC_VER:
11280 strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11281 break;
11282 case SQL_ODBC_SAG_CLI_CONFORMANCE:
11283 *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
11284 *valLen = sizeof (SQLSMALLINT);
11285 break;
11286 case SQL_STANDARD_CLI_CONFORMANCE:
11287 *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
11288 *valLen = sizeof (SQLUINTEGER);
11289 break;
11290 case SQL_SQL_CONFORMANCE:
11291 *((SQLUINTEGER *) val) = SQL_SC_SQL92_ENTRY;
11292 *valLen = sizeof (SQLUINTEGER);
11293 break;
11294 case SQL_SERVER_NAME:
11295 case SQL_DATABASE_NAME:
11296 strmak(val, d->dbname ? d->dbname : "", valMax, valLen);
11297 break;
11298 case SQL_SEARCH_PATTERN_ESCAPE:
11299 strmak(val, "\\", valMax, valLen);
11300 break;
11301 case SQL_ODBC_SQL_CONFORMANCE:
11302 *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
11303 *valLen = sizeof (SQLSMALLINT);
11304 break;
11305 case SQL_ODBC_API_CONFORMANCE:
11306 *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
11307 *valLen = sizeof (SQLSMALLINT);
11308 break;
11309 case SQL_DBMS_NAME:
11310 strmak(val, "SQLite", valMax, valLen);
11311 break;
11312 case SQL_DBMS_VER:
11313 strmak(val, SQLITE_VERSION, valMax, valLen);
11314 break;
11315 case SQL_COLUMN_ALIAS:
11316 case SQL_NEED_LONG_DATA_LEN:
11317 case SQL_OUTER_JOINS:
11318 strmak(val, "Y", valMax, valLen);
11319 break;
11320 case SQL_ROW_UPDATES:
11321 case SQL_ACCESSIBLE_PROCEDURES:
11322 case SQL_PROCEDURES:
11323 case SQL_EXPRESSIONS_IN_ORDERBY:
11324 case SQL_ODBC_SQL_OPT_IEF:
11325 case SQL_LIKE_ESCAPE_CLAUSE:
11326 case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11327 case SQL_ACCESSIBLE_TABLES:
11328 case SQL_MULT_RESULT_SETS:
11329 case SQL_MULTIPLE_ACTIVE_TXN:
11330 case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11331 strmak(val, "N", valMax, valLen);
11332 break;
11333 #ifdef SQL_CATALOG_NAME
11334 case SQL_CATALOG_NAME:
11335 #if defined(_WIN32) || defined(_WIN64)
11336 strmak(val, d->xcelqrx ? "Y" : "N", valMax, valLen);
11337 #else
11338 strmak(val, "N", valMax, valLen);
11339 #endif
11340 break;
11341 #endif
11342 case SQL_DATA_SOURCE_READ_ONLY:
11343 strmak(val, "N", valMax, valLen);
11344 break;
11345 #ifdef SQL_OJ_CAPABILITIES
11346 case SQL_OJ_CAPABILITIES:
11347 *((SQLUINTEGER *) val) = SQL_OJ_LEFT;
11348 *valLen = sizeof (SQLUINTEGER);
11349 break;
11350 #endif
11351 #ifdef SQL_MAX_IDENTIFIER_LEN
11352 case SQL_MAX_IDENTIFIER_LEN:
11353 *((SQLUSMALLINT *) val) = 255;
11354 *valLen = sizeof (SQLUSMALLINT);
11355 break;
11356 #endif
11357 case SQL_CONCAT_NULL_BEHAVIOR:
11358 *((SQLSMALLINT *) val) = SQL_CB_NULL;
11359 *valLen = sizeof (SQLSMALLINT);
11360 break;
11361 case SQL_CURSOR_COMMIT_BEHAVIOR:
11362 case SQL_CURSOR_ROLLBACK_BEHAVIOR:
11363 *((SQLSMALLINT *) val) = SQL_CB_PRESERVE;
11364 *valLen = sizeof (SQLSMALLINT);
11365 break;
11366 #ifdef SQL_CURSOR_SENSITIVITY
11367 case SQL_CURSOR_SENSITIVITY:
11368 *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
11369 *valLen = sizeof (SQLUINTEGER);
11370 break;
11371 #endif
11372 case SQL_DEFAULT_TXN_ISOLATION:
11373 *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11374 *valLen = sizeof (SQLUINTEGER);
11375 break;
11376 #ifdef SQL_DESCRIBE_PARAMETER
11377 case SQL_DESCRIBE_PARAMETER:
11378 strmak(val, "Y", valMax, valLen);
11379 break;
11380 #endif
11381 case SQL_TXN_ISOLATION_OPTION:
11382 *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11383 *valLen = sizeof (SQLUINTEGER);
11384 break;
11385 case SQL_IDENTIFIER_CASE:
11386 *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
11387 *valLen = sizeof (SQLSMALLINT);
11388 break;
11389 case SQL_IDENTIFIER_QUOTE_CHAR:
11390 strmak(val, "\"", valMax, valLen);
11391 break;
11392 case SQL_MAX_TABLE_NAME_LEN:
11393 case SQL_MAX_COLUMN_NAME_LEN:
11394 *((SQLSMALLINT *) val) = 255;
11395 *valLen = sizeof (SQLSMALLINT);
11396 break;
11397 case SQL_MAX_CURSOR_NAME_LEN:
11398 *((SQLSMALLINT *) val) = 255;
11399 *valLen = sizeof (SQLSMALLINT);
11400 break;
11401 case SQL_MAX_PROCEDURE_NAME_LEN:
11402 *((SQLSMALLINT *) val) = 0;
11403 break;
11404 case SQL_MAX_QUALIFIER_NAME_LEN:
11405 case SQL_MAX_OWNER_NAME_LEN:
11406 *((SQLSMALLINT *) val) = 255;
11407 break;
11408 case SQL_OWNER_TERM:
11409 strmak(val, "", valMax, valLen);
11410 break;
11411 case SQL_PROCEDURE_TERM:
11412 strmak(val, "PROCEDURE", valMax, valLen);
11413 break;
11414 case SQL_QUALIFIER_NAME_SEPARATOR:
11415 strmak(val, ".", valMax, valLen);
11416 break;
11417 case SQL_QUALIFIER_TERM:
11418 #if defined(_WIN32) || defined(_WIN64)
11419 strmak(val, d->xcelqrx ? "catalog" : "", valMax, valLen);
11420 #else
11421 strmak(val, "", valMax, valLen);
11422 #endif
11423 break;
11424 case SQL_QUALIFIER_USAGE:
11425 #if defined(_WIN32) || defined(_WIN64)
11426 *((SQLUINTEGER *) val) = d->xcelqrx ?
11427 (SQL_CU_DML_STATEMENTS | SQL_CU_INDEX_DEFINITION |
11428 SQL_CU_TABLE_DEFINITION) : 0;
11429 #else
11430 *((SQLUINTEGER *) val) = 0;
11431 #endif
11432 *valLen = sizeof (SQLUINTEGER);
11433 break;
11434 case SQL_SCROLL_CONCURRENCY:
11435 *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
11436 *valLen = sizeof (SQLUINTEGER);
11437 break;
11438 case SQL_SCROLL_OPTIONS:
11439 *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
11440 *valLen = sizeof (SQLUINTEGER);
11441 break;
11442 case SQL_TABLE_TERM:
11443 strmak(val, "TABLE", valMax, valLen);
11444 break;
11445 case SQL_TXN_CAPABLE:
11446 *((SQLSMALLINT *) val) = SQL_TC_ALL;
11447 *valLen = sizeof (SQLSMALLINT);
11448 break;
11449 case SQL_CONVERT_FUNCTIONS:
11450 *((SQLUINTEGER *) val) = 0;
11451 *valLen = sizeof (SQLUINTEGER);
11452 break;
11453 case SQL_SYSTEM_FUNCTIONS:
11454 case SQL_NUMERIC_FUNCTIONS:
11455 case SQL_STRING_FUNCTIONS:
11456 case SQL_TIMEDATE_FUNCTIONS:
11457 *((SQLUINTEGER *) val) = 0;
11458 *valLen = sizeof (SQLUINTEGER);
11459 break;
11460 case SQL_CONVERT_BIGINT:
11461 case SQL_CONVERT_BIT:
11462 case SQL_CONVERT_CHAR:
11463 case SQL_CONVERT_DATE:
11464 case SQL_CONVERT_DECIMAL:
11465 case SQL_CONVERT_DOUBLE:
11466 case SQL_CONVERT_FLOAT:
11467 case SQL_CONVERT_INTEGER:
11468 case SQL_CONVERT_LONGVARCHAR:
11469 case SQL_CONVERT_NUMERIC:
11470 case SQL_CONVERT_REAL:
11471 case SQL_CONVERT_SMALLINT:
11472 case SQL_CONVERT_TIME:
11473 case SQL_CONVERT_TIMESTAMP:
11474 case SQL_CONVERT_TINYINT:
11475 case SQL_CONVERT_VARCHAR:
11476 *((SQLUINTEGER *) val) =
11477 SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
11478 SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
11479 SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
11480 SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
11481 SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
11482 *valLen = sizeof (SQLUINTEGER);
11483 break;
11484 case SQL_CONVERT_BINARY:
11485 case SQL_CONVERT_VARBINARY:
11486 case SQL_CONVERT_LONGVARBINARY:
11487 *((SQLUINTEGER *) val) = 0;
11488 *valLen = sizeof (SQLUINTEGER);
11489 break;
11490 case SQL_POSITIONED_STATEMENTS:
11491 *((SQLUINTEGER *) val) = 0;
11492 *valLen = sizeof (SQLUINTEGER);
11493 break;
11494 case SQL_LOCK_TYPES:
11495 *((SQLUINTEGER *) val) = SQL_LCK_NO_CHANGE;
11496 *valLen = sizeof (SQLUINTEGER);
11497 break;
11498 case SQL_BOOKMARK_PERSISTENCE:
11499 *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
11500 *valLen = sizeof (SQLUINTEGER);
11501 break;
11502 case SQL_UNION:
11503 *((SQLUINTEGER *) val) = SQL_U_UNION | SQL_U_UNION_ALL;
11504 *valLen = sizeof (SQLUINTEGER);
11505 break;
11506 case SQL_OWNER_USAGE:
11507 case SQL_SUBQUERIES:
11508 case SQL_TIMEDATE_ADD_INTERVALS:
11509 case SQL_TIMEDATE_DIFF_INTERVALS:
11510 *((SQLUINTEGER *) val) = 0;
11511 *valLen = sizeof (SQLUINTEGER);
11512 break;
11513 case SQL_QUOTED_IDENTIFIER_CASE:
11514 *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
11515 *valLen = sizeof (SQLUSMALLINT);
11516 break;
11517 case SQL_POS_OPERATIONS:
11518 *((SQLUINTEGER *) val) = SQL_POS_POSITION | SQL_POS_UPDATE |
11519 SQL_POS_DELETE | SQL_POS_ADD | SQL_POS_REFRESH;
11520 *valLen = sizeof (SQLUINTEGER);
11521 break;
11522 case SQL_ALTER_TABLE:
11523 *((SQLUINTEGER *) val) = 0;
11524 *valLen = sizeof (SQLUINTEGER);
11525 break;
11526 case SQL_CORRELATION_NAME:
11527 *((SQLSMALLINT *) val) = SQL_CN_ANY;
11528 *valLen = sizeof (SQLSMALLINT);
11529 break;
11530 case SQL_NON_NULLABLE_COLUMNS:
11531 *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
11532 *valLen = sizeof (SQLSMALLINT);
11533 break;
11534 case SQL_NULL_COLLATION:
11535 *((SQLSMALLINT *) val) = SQL_NC_START;
11536 *valLen = sizeof (SQLSMALLINT);
11537 break;
11538 case SQL_MAX_COLUMNS_IN_GROUP_BY:
11539 case SQL_MAX_COLUMNS_IN_ORDER_BY:
11540 case SQL_MAX_COLUMNS_IN_SELECT:
11541 case SQL_MAX_COLUMNS_IN_TABLE:
11542 case SQL_MAX_ROW_SIZE:
11543 case SQL_MAX_TABLES_IN_SELECT:
11544 *((SQLSMALLINT *) val) = 0;
11545 *valLen = sizeof (SQLSMALLINT);
11546 break;
11547 case SQL_MAX_BINARY_LITERAL_LEN:
11548 case SQL_MAX_CHAR_LITERAL_LEN:
11549 *((SQLUINTEGER *) val) = 0;
11550 *valLen = sizeof (SQLUINTEGER);
11551 break;
11552 case SQL_MAX_COLUMNS_IN_INDEX:
11553 *((SQLSMALLINT *) val) = 0;
11554 *valLen = sizeof (SQLSMALLINT);
11555 break;
11556 case SQL_MAX_INDEX_SIZE:
11557 *((SQLUINTEGER *) val) = 0;
11558 *valLen = sizeof (SQLUINTEGER);
11559 break;
11560 #ifdef SQL_MAX_IDENTIFIER_LENGTH
11561 case SQL_MAX_IDENTIFIER_LENGTH:
11562 *((SQLUINTEGER *) val) = 255;
11563 *valLen = sizeof (SQLUINTEGER);
11564 break;
11565 #endif
11566 case SQL_MAX_STATEMENT_LEN:
11567 *((SQLUINTEGER *) val) = 16384;
11568 *valLen = sizeof (SQLUINTEGER);
11569 break;
11570 case SQL_QUALIFIER_LOCATION:
11571 *((SQLSMALLINT *) val) = SQL_QL_START;
11572 *valLen = sizeof (SQLSMALLINT);
11573 break;
11574 case SQL_GETDATA_EXTENSIONS:
11575 *((SQLUINTEGER *) val) =
11576 SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
11577 *valLen = sizeof (SQLUINTEGER);
11578 break;
11579 case SQL_STATIC_SENSITIVITY:
11580 *((SQLUINTEGER *) val) = 0;
11581 *valLen = sizeof (SQLUINTEGER);
11582 break;
11583 case SQL_FILE_USAGE:
11584 #if defined(_WIN32) || defined(_WIN64)
11585 *((SQLSMALLINT *) val) =
11586 d->xcelqrx ? SQL_FILE_CATALOG : SQL_FILE_NOT_SUPPORTED;
11587 #else
11588 *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
11589 #endif
11590 *valLen = sizeof (SQLSMALLINT);
11591 break;
11592 case SQL_GROUP_BY:
11593 *((SQLSMALLINT *) val) = SQL_GB_GROUP_BY_EQUALS_SELECT;
11594 *valLen = sizeof (SQLSMALLINT);
11595 break;
11596 case SQL_KEYWORDS:
11597 strmak(val, "CREATE,SELECT,DROP,DELETE,UPDATE,INSERT,"
11598 "INTO,VALUES,TABLE,INDEX,FROM,SET,WHERE,AND,CURRENT,OF",
11599 valMax, valLen);
11600 break;
11601 case SQL_SPECIAL_CHARACTERS:
11602 #ifdef SQL_COLLATION_SEQ
11603 case SQL_COLLATION_SEQ:
11604 #endif
11605 strmak(val, "", valMax, valLen);
11606 break;
11607 case SQL_BATCH_SUPPORT:
11608 case SQL_BATCH_ROW_COUNT:
11609 case SQL_PARAM_ARRAY_ROW_COUNTS:
11610 *((SQLUINTEGER *) val) = 0;
11611 *valLen = sizeof (SQLUINTEGER);
11612 break;
11613 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
11614 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
11615 *valLen = sizeof (SQLUINTEGER);
11616 break;
11617 case SQL_STATIC_CURSOR_ATTRIBUTES1:
11618 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
11619 SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_POS_POSITION |
11620 SQL_CA1_POS_DELETE | SQL_CA1_POS_UPDATE | SQL_CA1_POS_REFRESH |
11621 SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_BULK_ADD |
11622 SQL_CA1_BULK_UPDATE_BY_BOOKMARK | SQL_CA1_BULK_DELETE_BY_BOOKMARK;
11623 *valLen = sizeof (SQLUINTEGER);
11624 break;
11625 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
11626 case SQL_STATIC_CURSOR_ATTRIBUTES2:
11627 *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
11628 SQL_CA2_LOCK_CONCURRENCY;
11629 *valLen = sizeof (SQLUINTEGER);
11630 break;
11631 case SQL_KEYSET_CURSOR_ATTRIBUTES1:
11632 case SQL_KEYSET_CURSOR_ATTRIBUTES2:
11633 case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
11634 case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
11635 *((SQLUINTEGER *) val) = 0;
11636 *valLen = sizeof (SQLUINTEGER);
11637 break;
11638 case SQL_ODBC_INTERFACE_CONFORMANCE:
11639 *((SQLUINTEGER *) val) = SQL_OIC_CORE;
11640 *valLen = sizeof (SQLUINTEGER);
11641 break;
11642 default:
11643 setstatd(d, -1, "unsupported info option %d",
11644 (*d->ov3) ? "HYC00" : "S1C00", type);
11645 return SQL_ERROR;
11646 }
11647 return SQL_SUCCESS;
11648 }
11649
11650 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
11651
11661 SQLRETURN SQL_API
11662 SQLGetInfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11663 SQLSMALLINT *valLen)
11664 {
11665 SQLRETURN ret;
11666
11667 HDBC_LOCK(dbc);
11668 ret = drvgetinfo(dbc, type, val, valMax, valLen);
11669 HDBC_UNLOCK(dbc);
11670 return ret;
11671 }
11672 #endif
11673
11674 #ifdef WINTERFACE
11675
11685 SQLRETURN SQL_API
11686 SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11687 SQLSMALLINT *valLen)
11688 {
11689 SQLRETURN ret;
11690 SQLSMALLINT len = 0;
11691
11692 HDBC_LOCK(dbc);
11693 ret = drvgetinfo(dbc, type, val, valMax, &len);
11694 HDBC_UNLOCK(dbc);
11695 if (ret == SQL_SUCCESS) {
11696 SQLWCHAR *v = NULL;
11697
11698 switch (type) {
11699 case SQL_USER_NAME:
11700 case SQL_DRIVER_ODBC_VER:
11701 case SQL_DATA_SOURCE_NAME:
11702 case SQL_DRIVER_NAME:
11703 case SQL_DRIVER_VER:
11704 case SQL_ODBC_VER:
11705 case SQL_SERVER_NAME:
11706 case SQL_DATABASE_NAME:
11707 case SQL_SEARCH_PATTERN_ESCAPE:
11708 case SQL_DBMS_NAME:
11709 case SQL_DBMS_VER:
11710 case SQL_NEED_LONG_DATA_LEN:
11711 case SQL_ROW_UPDATES:
11712 case SQL_ACCESSIBLE_PROCEDURES:
11713 case SQL_PROCEDURES:
11714 case SQL_EXPRESSIONS_IN_ORDERBY:
11715 case SQL_ODBC_SQL_OPT_IEF:
11716 case SQL_LIKE_ESCAPE_CLAUSE:
11717 case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11718 case SQL_OUTER_JOINS:
11719 case SQL_COLUMN_ALIAS:
11720 case SQL_ACCESSIBLE_TABLES:
11721 case SQL_MULT_RESULT_SETS:
11722 case SQL_MULTIPLE_ACTIVE_TXN:
11723 case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11724 case SQL_DATA_SOURCE_READ_ONLY:
11725 #ifdef SQL_DESCRIBE_PARAMETER
11726 case SQL_DESCRIBE_PARAMETER:
11727 #endif
11728 case SQL_IDENTIFIER_QUOTE_CHAR:
11729 case SQL_OWNER_TERM:
11730 case SQL_PROCEDURE_TERM:
11731 case SQL_QUALIFIER_NAME_SEPARATOR:
11732 case SQL_QUALIFIER_TERM:
11733 case SQL_TABLE_TERM:
11734 case SQL_KEYWORDS:
11735 case SQL_SPECIAL_CHARACTERS:
11736 #ifdef SQL_CATALOG_NAME
11737 case SQL_CATALOG_NAME:
11738 #endif
11739 #ifdef SQL_COLLATION_SEQ
11740 case SQL_COLLATION_SEQ:
11741 #endif
11742 if (val) {
11743 if (len > 0) {
11744 v = uc_from_utf((SQLCHAR *) val, len);
11745 if (v) {
11746 int vmax = valMax / sizeof (SQLWCHAR);
11747
11748 uc_strncpy(val, v, vmax);
11749 if (len < vmax) {
11750 len = min(vmax, uc_strlen(v));
11751 v[len] = 0;
11752 } else {
11753 len = vmax;
11754 }
11755 uc_free(v);
11756 len *= sizeof (SQLWCHAR);
11757 } else {
11758 len = 0;
11759 }
11760 }
11761 if (len <= 0) {
11762 len = 0;
11763 if (valMax >= sizeof (SQLWCHAR)) {
11764 *((SQLWCHAR *)val) = 0;
11765 }
11766 }
11767 } else {
11768 len *= sizeof (SQLWCHAR);
11769 }
11770 break;
11771 }
11772 if (valLen) {
11773 *valLen = len;
11774 }
11775 }
11776 return ret;
11777 }
11778 #endif
11779
11788 SQLRETURN SQL_API
11789 SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
11790 SQLUSMALLINT *flags)
11791 {
11792 int i;
11793 SQLUSMALLINT exists[100];
11794
11795 if (dbc == SQL_NULL_HDBC) {
11796 return SQL_INVALID_HANDLE;
11797 }
11798 for (i = 0; i < array_size(exists); i++) {
11799 exists[i] = SQL_FALSE;
11800 }
11801 exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
11802 exists[SQL_API_SQLFETCH] = SQL_TRUE;
11803 exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
11804 exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
11805 exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
11806 exists[SQL_API_SQLFREEENV] = SQL_TRUE;
11807 exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
11808 exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
11809 exists[SQL_API_SQLCANCEL] = SQL_TRUE;
11810 exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
11811 exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
11812 exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
11813 exists[SQL_API_SQLCONNECT] = SQL_TRUE;
11814 exists[SQL_API_SQLPREPARE] = SQL_TRUE;
11815 exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
11816 exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
11817 exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
11818 exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
11819 exists[SQL_API_SQLERROR] = SQL_TRUE;
11820 exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
11821 exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
11822 exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
11823 exists[SQL_API_SQLBULKOPERATIONS] = SQL_TRUE;
11824 exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
11825 exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
11826 exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
11827 exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
11828 exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
11829 exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
11830 exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
11831 exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
11832 exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
11833 exists[SQL_API_SQLGETDATA] = SQL_TRUE;
11834 exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
11835 exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
11836 exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
11837 exists[SQL_API_SQLGETINFO] = SQL_TRUE;
11838 exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
11839 exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
11840 exists[SQL_API_SQLTABLES] = SQL_TRUE;
11841 exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
11842 exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
11843 exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
11844 exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
11845 exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
11846 exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
11847 exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
11848 exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
11849 exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
11850 exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
11851 exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
11852 exists[SQL_API_SQLSETPOS] = SQL_TRUE;
11853 exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
11854 exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
11855 exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
11856 exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_TRUE;
11857 exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
11858 if (func == SQL_API_ALL_FUNCTIONS) {
11859 memcpy(flags, exists, sizeof (exists));
11860 } else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
11861 int i;
11862 #define SET_EXISTS(x) \
11863 flags[(x) >> 4] |= (1 << ((x) & 0xF))
11864 #define CLR_EXISTS(x) \
11865 flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
11866
11867 memset(flags, 0,
11868 sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
11869 for (i = 0; i < array_size(exists); i++) {
11870 if (exists[i]) {
11871 flags[i >> 4] |= (1 << (i & 0xF));
11872 }
11873 }
11874 SET_EXISTS(SQL_API_SQLALLOCHANDLE);
11875 SET_EXISTS(SQL_API_SQLFREEHANDLE);
11876 SET_EXISTS(SQL_API_SQLGETSTMTATTR);
11877 SET_EXISTS(SQL_API_SQLSETSTMTATTR);
11878 SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
11879 SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
11880 SET_EXISTS(SQL_API_SQLGETENVATTR);
11881 SET_EXISTS(SQL_API_SQLSETENVATTR);
11882 SET_EXISTS(SQL_API_SQLCLOSECURSOR);
11883 SET_EXISTS(SQL_API_SQLBINDPARAM);
11884 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11885
11886
11887
11888
11889
11890 SET_EXISTS(SQL_API_SQLGETDIAGREC);
11891 #endif
11892 SET_EXISTS(SQL_API_SQLGETDIAGFIELD);
11893 SET_EXISTS(SQL_API_SQLFETCHSCROLL);
11894 SET_EXISTS(SQL_API_SQLENDTRAN);
11895 } else {
11896 if (func < array_size(exists)) {
11897 *flags = exists[func];
11898 } else {
11899 switch (func) {
11900 case SQL_API_SQLALLOCHANDLE:
11901 case SQL_API_SQLFREEHANDLE:
11902 case SQL_API_SQLGETSTMTATTR:
11903 case SQL_API_SQLSETSTMTATTR:
11904 case SQL_API_SQLGETCONNECTATTR:
11905 case SQL_API_SQLSETCONNECTATTR:
11906 case SQL_API_SQLGETENVATTR:
11907 case SQL_API_SQLSETENVATTR:
11908 case SQL_API_SQLCLOSECURSOR:
11909 case SQL_API_SQLBINDPARAM:
11910 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11911
11912
11913
11914
11915
11916 case SQL_API_SQLGETDIAGREC:
11917 #endif
11918 case SQL_API_SQLGETDIAGFIELD:
11919 case SQL_API_SQLFETCHSCROLL:
11920 case SQL_API_SQLENDTRAN:
11921 *flags = SQL_TRUE;
11922 break;
11923 default:
11924 *flags = SQL_FALSE;
11925 }
11926 }
11927 }
11928 return SQL_SUCCESS;
11929 }
11930
11937 static SQLRETURN
11938 drvallocenv(SQLHENV *env)
11939 {
11940 ENV *e;
11941
11942 if (env == NULL) {
11943 return SQL_INVALID_HANDLE;
11944 }
11945 e = (ENV *) xmalloc(sizeof (ENV));
11946 if (e == NULL) {
11947 *env = SQL_NULL_HENV;
11948 return SQL_ERROR;
11949 }
11950 e->magic = ENV_MAGIC;
11951 e->ov3 = 0;
11952 e->pool = 0;
11953 #if defined(_WIN32) || defined(_WIN64)
11954 InitializeCriticalSection(&e->cs);
11955 #else
11956 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
11957 nvfs_init();
11958 #endif
11959 #endif
11960 e->dbcs = NULL;
11961 *env = (SQLHENV) e;
11962 return SQL_SUCCESS;
11963 }
11964
11971 SQLRETURN SQL_API
11972 SQLAllocEnv(SQLHENV *env)
11973 {
11974 return drvallocenv(env);
11975 }
11976
11983 static SQLRETURN
11984 drvfreeenv(SQLHENV env)
11985 {
11986 ENV *e;
11987
11988 if (env == SQL_NULL_HENV) {
11989 return SQL_INVALID_HANDLE;
11990 }
11991 e = (ENV *) env;
11992 if (e->magic != ENV_MAGIC) {
11993 return SQL_SUCCESS;
11994 }
11995 #if defined(_WIN32) || defined(_WIN64)
11996 EnterCriticalSection(&e->cs);
11997 #endif
11998 if (e->dbcs) {
11999 #if defined(_WIN32) || defined(_WIN64)
12000 LeaveCriticalSection(&e->cs);
12001 #endif
12002 return SQL_ERROR;
12003 }
12004 e->magic = DEAD_MAGIC;
12005 #if defined(_WIN32) || defined(_WIN64)
12006 LeaveCriticalSection(&e->cs);
12007 DeleteCriticalSection(&e->cs);
12008 #endif
12009 xfree(e);
12010 return SQL_SUCCESS;
12011 }
12012
12019 SQLRETURN SQL_API
12020 SQLFreeEnv(SQLHENV env)
12021 {
12022 return drvfreeenv(env);
12023 }
12024
12032 static SQLRETURN
12033 drvallocconnect(SQLHENV env, SQLHDBC *dbc)
12034 {
12035 DBC *d;
12036 ENV *e;
12037 const char *verstr;
12038 int maj = 0, min = 0, lev = 0;
12039
12040 if (dbc == NULL) {
12041 return SQL_ERROR;
12042 }
12043 d = (DBC *) xmalloc(sizeof (DBC));
12044 if (d == NULL) {
12045 *dbc = SQL_NULL_HDBC;
12046 return SQL_ERROR;
12047 }
12048 memset(d, 0, sizeof (DBC));
12049 d->curtype = SQL_CURSOR_STATIC;
12050 d->ov3 = &d->ov3val;
12051 verstr = sqlite3_libversion();
12052 sscanf(verstr, "%d.%d.%d", &maj, &min, &lev);
12053 d->version = verinfo(maj & 0xFF, min & 0xFF, lev & 0xFF);
12054 e = (ENV *) env;
12055 #if defined(_WIN32) || defined(_WIN64)
12056 if (e->magic == ENV_MAGIC) {
12057 EnterCriticalSection(&e->cs);
12058 }
12059 #endif
12060 if (e->magic == ENV_MAGIC) {
12061 DBC *n, *p;
12062
12063 d->env = e;
12064 d->ov3 = &e->ov3;
12065 p = NULL;
12066 n = e->dbcs;
12067 while (n) {
12068 p = n;
12069 n = n->next;
12070 }
12071 if (p) {
12072 p->next = d;
12073 } else {
12074 e->dbcs = d;
12075 }
12076 }
12077 #if defined(_WIN32) || defined(_WIN64)
12078 InitializeCriticalSection(&d->cs);
12079 d->owner = 0;
12080 if (e->magic == ENV_MAGIC) {
12081 LeaveCriticalSection(&e->cs);
12082 }
12083 d->oemcp = 1;
12084 #endif
12085 d->autocommit = 1;
12086 d->magic = DBC_MAGIC;
12087 *dbc = (SQLHDBC) d;
12088 drvgetgpps(d);
12089 return SQL_SUCCESS;
12090 }
12091
12099 SQLRETURN SQL_API
12100 SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
12101 {
12102 return drvallocconnect(env, dbc);
12103 }
12104
12111 static SQLRETURN
12112 drvfreeconnect(SQLHDBC dbc)
12113 {
12114 DBC *d;
12115 ENV *e;
12116 SQLRETURN ret = SQL_ERROR;
12117
12118 if (dbc == SQL_NULL_HDBC) {
12119 return SQL_INVALID_HANDLE;
12120 }
12121 d = (DBC *) dbc;
12122 if (d->magic != DBC_MAGIC) {
12123 return SQL_INVALID_HANDLE;
12124 }
12125 e = d->env;
12126 if (e && e->magic == ENV_MAGIC) {
12127 #if defined(_WIN32) || defined(_WIN64)
12128 EnterCriticalSection(&e->cs);
12129 #endif
12130 } else {
12131 e = NULL;
12132 }
12133 HDBC_LOCK(dbc);
12134 if (d->sqlite) {
12135 setstatd(d, -1, "not disconnected", (*d->ov3) ? "HY000" : "S1000");
12136 HDBC_UNLOCK(dbc);
12137 goto done;
12138 }
12139 while (d->stmt) {
12140 freestmt((HSTMT) d->stmt);
12141 }
12142 if (e && e->magic == ENV_MAGIC) {
12143 DBC *n, *p;
12144
12145 p = NULL;
12146 n = e->dbcs;
12147 while (n) {
12148 if (n == d) {
12149 break;
12150 }
12151 p = n;
12152 n = n->next;
12153 }
12154 if (n) {
12155 if (p) {
12156 p->next = d->next;
12157 } else {
12158 e->dbcs = d->next;
12159 }
12160 }
12161 }
12162 drvrelgpps(d);
12163 d->magic = DEAD_MAGIC;
12164 if (d->trace) {
12165 fclose(d->trace);
12166 }
12167 #if defined(_WIN32) || defined(_WIN64)
12168 d->owner = 0;
12169 LeaveCriticalSection(&d->cs);
12170 DeleteCriticalSection(&d->cs);
12171 #endif
12172 xfree(d);
12173 ret = SQL_SUCCESS;
12174 done:
12175 #if defined(_WIN32) || defined(_WIN64)
12176 if (e) {
12177 LeaveCriticalSection(&e->cs);
12178 }
12179 #endif
12180 return ret;
12181 }
12182
12189 SQLRETURN SQL_API
12190 SQLFreeConnect(SQLHDBC dbc)
12191 {
12192 return drvfreeconnect(dbc);
12193 }
12194
12205 static SQLRETURN
12206 drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12207 SQLINTEGER bufmax, SQLINTEGER *buflen)
12208 {
12209 DBC *d;
12210 SQLINTEGER dummy;
12211
12212 if (dbc == SQL_NULL_HDBC) {
12213 return SQL_INVALID_HANDLE;
12214 }
12215 d = (DBC *) dbc;
12216 if (!val) {
12217 val = (SQLPOINTER) &dummy;
12218 }
12219 if (!buflen) {
12220 buflen = &dummy;
12221 }
12222 switch (attr) {
12223 case SQL_ATTR_CONNECTION_DEAD:
12224 *((SQLINTEGER *) val) = d->sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
12225 *buflen = sizeof (SQLINTEGER);
12226 break;
12227 case SQL_ATTR_ACCESS_MODE:
12228 *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
12229 *buflen = sizeof (SQLINTEGER);
12230 break;
12231 case SQL_ATTR_AUTOCOMMIT:
12232 *((SQLINTEGER *) val) =
12233 d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12234 *buflen = sizeof (SQLINTEGER);
12235 break;
12236 case SQL_ATTR_LOGIN_TIMEOUT:
12237 *((SQLINTEGER *) val) = 100;
12238 *buflen = sizeof (SQLINTEGER);
12239 break;
12240 case SQL_ATTR_ODBC_CURSORS:
12241 *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
12242 *buflen = sizeof (SQLINTEGER);
12243 break;
12244 case SQL_ATTR_PACKET_SIZE:
12245 *((SQLINTEGER *) val) = 16384;
12246 *buflen = sizeof (SQLINTEGER);
12247 break;
12248 case SQL_ATTR_TXN_ISOLATION:
12249 *((SQLINTEGER *) val) = SQL_TXN_SERIALIZABLE;
12250 *buflen = sizeof (SQLINTEGER);
12251 break;
12252 case SQL_ATTR_TRACEFILE:
12253 case SQL_ATTR_TRANSLATE_LIB:
12254 *((SQLCHAR *) val) = 0;
12255 *buflen = 0;
12256 break;
12257 case SQL_ATTR_CURRENT_CATALOG:
12258 #if defined(_WIN32) || defined(_WIN64)
12259 if (d->xcelqrx) {
12260 if ((bufmax > 4) && (val != (SQLPOINTER) &dummy)) {
12261 strcpy((char *) val, "main");
12262 *buflen = 4;
12263 break;
12264 }
12265 }
12266 #endif
12267 *((SQLCHAR *) val) = 0;
12268 *buflen = 0;
12269 break;
12270 case SQL_ATTR_TRACE:
12271 case SQL_ATTR_QUIET_MODE:
12272 case SQL_ATTR_TRANSLATE_OPTION:
12273 case SQL_ATTR_KEYSET_SIZE:
12274 case SQL_ATTR_QUERY_TIMEOUT:
12275 *((SQLINTEGER *) val) = 0;
12276 *buflen = sizeof (SQLINTEGER);
12277 break;
12278 case SQL_ATTR_PARAM_BIND_TYPE:
12279 *((SQLULEN *) val) = SQL_PARAM_BIND_BY_COLUMN;
12280 *buflen = sizeof (SQLUINTEGER);
12281 break;
12282 case SQL_ATTR_ROW_BIND_TYPE:
12283 *((SQLULEN *) val) = SQL_BIND_BY_COLUMN;
12284 *buflen = sizeof (SQLULEN);
12285 break;
12286 case SQL_ATTR_USE_BOOKMARKS:
12287 *((SQLINTEGER *) val) = SQL_UB_OFF;
12288 *buflen = sizeof (SQLINTEGER);
12289 break;
12290 case SQL_ATTR_ASYNC_ENABLE:
12291 *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
12292 *buflen = sizeof (SQLINTEGER);
12293 break;
12294 case SQL_ATTR_NOSCAN:
12295 *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
12296 *buflen = sizeof (SQLINTEGER);
12297 break;
12298 case SQL_ATTR_CONCURRENCY:
12299 *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
12300 *buflen = sizeof (SQLINTEGER);
12301 break;
12302 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
12303 case SQL_ATTR_CURSOR_SENSITIVITY:
12304 *((SQLINTEGER *) val) = SQL_UNSPECIFIED;
12305 *buflen = sizeof (SQLINTEGER);
12306 break;
12307 #endif
12308 case SQL_ATTR_SIMULATE_CURSOR:
12309 *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
12310 *buflen = sizeof (SQLINTEGER);
12311 break;
12312 case SQL_ATTR_MAX_ROWS:
12313 *((SQLINTEGER *) val) = 0;
12314 *buflen = sizeof (SQLINTEGER);
12315 case SQL_ATTR_MAX_LENGTH:
12316 *((SQLINTEGER *) val) = 1000000000;
12317 *buflen = sizeof (SQLINTEGER);
12318 break;
12319 case SQL_ATTR_CURSOR_TYPE:
12320 *((SQLINTEGER *) val) = d->curtype;
12321 *buflen = sizeof (SQLINTEGER);
12322 break;
12323 case SQL_ATTR_RETRIEVE_DATA:
12324 *((SQLINTEGER *) val) = SQL_RD_ON;
12325 *buflen = sizeof (SQLINTEGER);
12326 break;
12327 #ifdef SQL_ATTR_METADATA_ID
12328 case SQL_ATTR_METADATA_ID:
12329 *((SQLULEN *) val) = SQL_FALSE;
12330 return SQL_SUCCESS;
12331 #endif
12332 default:
12333 *((SQLINTEGER *) val) = 0;
12334 *buflen = sizeof (SQLINTEGER);
12335 setstatd(d, -1, "unsupported connect attribute %d",
12336 (*d->ov3) ? "HYC00" : "S1C00", (int) attr);
12337 return SQL_ERROR;
12338 }
12339 return SQL_SUCCESS;
12340 }
12341
12342 #ifndef WINTERFACE
12343
12353 SQLRETURN SQL_API
12354 SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12355 SQLINTEGER bufmax, SQLINTEGER *buflen)
12356 {
12357 SQLRETURN ret;
12358
12359 HDBC_LOCK(dbc);
12360 ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
12361 HDBC_UNLOCK(dbc);
12362 return ret;
12363 }
12364 #endif
12365
12366 #ifdef WINTERFACE
12367
12377 SQLRETURN SQL_API
12378 SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12379 SQLINTEGER bufmax, SQLINTEGER *buflen)
12380 {
12381 SQLRETURN ret;
12382 SQLINTEGER len = 0;
12383
12384 HDBC_LOCK(dbc);
12385 ret = drvgetconnectattr(dbc, attr, val, bufmax, &len);
12386 if (ret == SQL_SUCCESS) {
12387 SQLWCHAR *v = NULL;
12388
12389 switch (attr) {
12390 case SQL_ATTR_TRACEFILE:
12391 case SQL_ATTR_CURRENT_CATALOG:
12392 case SQL_ATTR_TRANSLATE_LIB:
12393 if (val) {
12394 if (len > 0) {
12395 v = uc_from_utf((SQLCHAR *) val, len);
12396 if (v) {
12397 int vmax = bufmax / sizeof (SQLWCHAR);
12398
12399 uc_strncpy(val, v, vmax);
12400 if (len < vmax) {
12401 len = min(vmax, uc_strlen(v));
12402 v[len] = 0;
12403 } else {
12404 len = vmax;
12405 }
12406 uc_free(v);
12407 len *= sizeof (SQLWCHAR);
12408 } else {
12409 len = 0;
12410 }
12411 }
12412 if (len <= 0) {
12413 len = 0;
12414 if (bufmax >= sizeof (SQLWCHAR)) {
12415 *((SQLWCHAR *)val) = 0;
12416 }
12417 }
12418 } else {
12419 len *= sizeof (SQLWCHAR);
12420 }
12421 break;
12422 }
12423 if (buflen) {
12424 *buflen = len;
12425 }
12426 }
12427 HDBC_UNLOCK(dbc);
12428 return ret;
12429 }
12430 #endif
12431
12441 static SQLRETURN
12442 drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12443 SQLINTEGER len)
12444 {
12445 DBC *d;
12446
12447 if (dbc == SQL_NULL_HDBC) {
12448 return SQL_INVALID_HANDLE;
12449 }
12450 d = (DBC *) dbc;
12451 switch (attr) {
12452 case SQL_AUTOCOMMIT:
12453 d->autocommit = val == (SQLPOINTER) SQL_AUTOCOMMIT_ON;
12454 if (d->autocommit && d->intrans) {
12455 return endtran(d, SQL_COMMIT, 1);
12456 } else if (!d->autocommit) {
12457 s3stmt_end(d->cur_s3stmt);
12458 }
12459 break;
12460 #ifdef SQL_ATTR_METADATA_ID
12461 case SQL_ATTR_METADATA_ID:
12462 if (val == (SQLPOINTER) SQL_FALSE) {
12463 break;
12464 }
12465
12466 #endif
12467 default:
12468 setstatd(d, -1, "option value changed", "01S02");
12469 return SQL_SUCCESS_WITH_INFO;
12470 }
12471 return SQL_SUCCESS;
12472 }
12473
12474 #ifndef WINTERFACE
12475
12484 SQLRETURN SQL_API
12485 SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12486 SQLINTEGER len)
12487 {
12488 SQLRETURN ret;
12489
12490 HDBC_LOCK(dbc);
12491 ret = drvsetconnectattr(dbc, attr, val, len);
12492 HDBC_UNLOCK(dbc);
12493 return ret;
12494 }
12495 #endif
12496
12497 #ifdef WINTERFACE
12498
12507 SQLRETURN SQL_API
12508 SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12509 SQLINTEGER len)
12510 {
12511 SQLRETURN ret;
12512
12513 HDBC_LOCK(dbc);
12514 ret = drvsetconnectattr(dbc, attr, val, len);
12515 HDBC_UNLOCK(dbc);
12516 return ret;
12517 }
12518 #endif
12519
12528 static SQLRETURN
12529 drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12530 {
12531 DBC *d;
12532 SQLINTEGER dummy;
12533
12534 if (dbc == SQL_NULL_HDBC) {
12535 return SQL_INVALID_HANDLE;
12536 }
12537 d = (DBC *) dbc;
12538 if (!param) {
12539 param = (SQLPOINTER) &dummy;
12540 }
12541 switch (opt) {
12542 case SQL_ACCESS_MODE:
12543 *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
12544 break;
12545 case SQL_AUTOCOMMIT:
12546 *((SQLINTEGER *) param) =
12547 d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12548 break;
12549 case SQL_LOGIN_TIMEOUT:
12550 *((SQLINTEGER *) param) = 100;
12551 break;
12552 case SQL_ODBC_CURSORS:
12553 *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
12554 break;
12555 case SQL_PACKET_SIZE:
12556 *((SQLINTEGER *) param) = 16384;
12557 break;
12558 case SQL_TXN_ISOLATION:
12559 *((SQLINTEGER *) param) = SQL_TXN_SERIALIZABLE;
12560 break;
12561 case SQL_OPT_TRACE:
12562 case SQL_OPT_TRACEFILE:
12563 case SQL_QUIET_MODE:
12564 case SQL_TRANSLATE_DLL:
12565 case SQL_TRANSLATE_OPTION:
12566 case SQL_KEYSET_SIZE:
12567 case SQL_QUERY_TIMEOUT:
12568 case SQL_BIND_TYPE:
12569 case SQL_CURRENT_QUALIFIER:
12570 *((SQLINTEGER *) param) = 0;
12571 break;
12572 case SQL_USE_BOOKMARKS:
12573 *((SQLINTEGER *) param) = SQL_UB_OFF;
12574 break;
12575 case SQL_ASYNC_ENABLE:
12576 *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
12577 break;
12578 case SQL_NOSCAN:
12579 *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
12580 break;
12581 case SQL_CONCURRENCY:
12582 *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
12583 break;
12584 case SQL_SIMULATE_CURSOR:
12585 *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
12586 break;
12587 case SQL_MAX_ROWS:
12588 *((SQLINTEGER *) param) = 0;
12589 break;
12590 case SQL_ROWSET_SIZE:
12591 case SQL_MAX_LENGTH:
12592 *((SQLINTEGER *) param) = 1000000000;
12593 break;
12594 case SQL_CURSOR_TYPE:
12595 *((SQLINTEGER *) param) = d->curtype;
12596 break;
12597 case SQL_RETRIEVE_DATA:
12598 *((SQLINTEGER *) param) = SQL_RD_ON;
12599 break;
12600 default:
12601 *((SQLINTEGER *) param) = 0;
12602 setstatd(d, -1, "unsupported connect option %d",
12603 (*d->ov3) ? "HYC00" : "S1C00", opt);
12604 return SQL_ERROR;
12605 }
12606 return SQL_SUCCESS;
12607 }
12608
12609 #ifndef WINTERFACE
12610
12618 SQLRETURN SQL_API
12619 SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12620 {
12621 SQLRETURN ret;
12622
12623 HDBC_LOCK(dbc);
12624 ret = drvgetconnectoption(dbc, opt, param);
12625 HDBC_UNLOCK(dbc);
12626 return ret;
12627 }
12628 #endif
12629
12630 #ifdef WINTERFACE
12631
12639 SQLRETURN SQL_API
12640 SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12641 {
12642 SQLRETURN ret;
12643
12644 HDBC_LOCK(dbc);
12645 ret = drvgetconnectoption(dbc, opt, param);
12646 if (SQL_SUCCEEDED(ret)) {
12647 switch (opt) {
12648 case SQL_OPT_TRACEFILE:
12649 case SQL_CURRENT_QUALIFIER:
12650 case SQL_TRANSLATE_DLL:
12651 if (param) {
12652 *(SQLWCHAR *) param = 0;
12653 }
12654 break;
12655 }
12656 }
12657 HDBC_UNLOCK(dbc);
12658 return ret;
12659 }
12660 #endif
12661
12670 static SQLRETURN
12671 drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
12672 {
12673 DBC *d;
12674
12675 if (dbc == SQL_NULL_HDBC) {
12676 return SQL_INVALID_HANDLE;
12677 }
12678 d = (DBC *) dbc;
12679 switch (opt) {
12680 case SQL_AUTOCOMMIT:
12681 d->autocommit = param == SQL_AUTOCOMMIT_ON;
12682 if (d->autocommit && d->intrans) {
12683 return endtran(d, SQL_COMMIT, 1);
12684 } else if (!d->autocommit) {
12685 s3stmt_end(d->cur_s3stmt);
12686 }
12687 break;
12688 default:
12689 setstatd(d, -1, "option value changed", "01S02");
12690 return SQL_SUCCESS_WITH_INFO;
12691 }
12692 return SQL_SUCCESS;
12693 }
12694
12695 #ifndef WINTERFACE
12696
12704 SQLRETURN SQL_API
12705 SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12706 {
12707 SQLRETURN ret;
12708
12709 HDBC_LOCK(dbc);
12710 ret = drvsetconnectoption(dbc, opt, param);
12711 HDBC_UNLOCK(dbc);
12712 return ret;
12713 }
12714 #endif
12715
12716 #ifdef WINTERFACE
12717
12725 SQLRETURN SQL_API
12726 SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12727 {
12728 SQLRETURN ret;
12729
12730 HDBC_LOCK(dbc);
12731 ret = drvsetconnectoption(dbc, opt, param);
12732 HDBC_UNLOCK(dbc);
12733 return ret;
12734 }
12735 #endif
12736
12737 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12738
12749 static int
12750 getdsnattr(char *dsn, char *attr, char *out, int outLen)
12751 {
12752 char *str = dsn, *start;
12753 int len = strlen(attr);
12754
12755 while (*str) {
12756 while (*str && *str == ';') {
12757 ++str;
12758 }
12759 start = str;
12760 if ((str = strchr(str, '=')) == NULL) {
12761 return 0;
12762 }
12763 if (str - start == len && strncasecmp(start, attr, len) == 0) {
12764 start = ++str;
12765 while (*str && *str != ';') {
12766 ++str;
12767 }
12768 len = min(outLen - 1, str - start);
12769 strncpy(out, start, len);
12770 out[len] = '\0';
12771 return 1;
12772 }
12773 while (*str && *str != ';') {
12774 ++str;
12775 }
12776 }
12777 return 0;
12778 }
12779 #endif
12780
12792 static SQLRETURN
12793 drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd,
12794 int pwdLen, int isu)
12795 {
12796 DBC *d;
12797 int len;
12798 SQLRETURN ret;
12799 char buf[SQL_MAX_MESSAGE_LENGTH * 6], dbname[SQL_MAX_MESSAGE_LENGTH];
12800 char busy[SQL_MAX_MESSAGE_LENGTH / 4], tracef[SQL_MAX_MESSAGE_LENGTH];
12801 char loadext[SQL_MAX_MESSAGE_LENGTH], attas[SQL_MAX_MESSAGE_LENGTH];
12802 char sflag[32], spflag[32], ntflag[32], nwflag[32], biflag[32];
12803 char snflag[32], lnflag[32], ncflag[32], fkflag[32], jmode[32];
12804 char jdflag[32], ilflag[32];
12805 #if defined(_WIN32) || defined(_WIN64)
12806 char oemcp[32];
12807 #endif
12808
12809 if (dbc == SQL_NULL_HDBC) {
12810 return SQL_INVALID_HANDLE;
12811 }
12812 d = (DBC *) dbc;
12813 if (d->magic != DBC_MAGIC) {
12814 return SQL_INVALID_HANDLE;
12815 }
12816 if (d->sqlite != NULL) {
12817 setstatd(d, -1, "connection already established", "08002");
12818 return SQL_ERROR;
12819 }
12820 buf[0] = '\0';
12821 if (dsnLen == SQL_NTS) {
12822 len = sizeof (buf) - 1;
12823 } else {
12824 len = min(sizeof (buf) - 1, dsnLen);
12825 }
12826 if (dsn != NULL) {
12827 strncpy(buf, (char *) dsn, len);
12828 }
12829 buf[len] = '\0';
12830 if (buf[0] == '\0') {
12831 setstatd(d, -1, "invalid DSN", (*d->ov3) ? "HY090" : "S1090");
12832 return SQL_ERROR;
12833 }
12834 #if defined(_WIN32) || defined(_WIN64)
12835
12836
12837
12838
12839 if (isu) {
12840 char *cdsn = utf_to_wmb(buf, len);
12841
12842 if (!cdsn) {
12843 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12844 return SQL_ERROR;
12845 }
12846 strcpy(buf, cdsn);
12847 uc_free(cdsn);
12848 }
12849 #endif
12850 busy[0] = '\0';
12851 dbname[0] = '\0';
12852 #ifdef WITHOUT_DRIVERMGR
12853 getdsnattr(buf, "database", dbname, sizeof (dbname));
12854 if (dbname[0] == '\0') {
12855 strncpy(dbname, buf, sizeof (dbname));
12856 dbname[sizeof (dbname) - 1] = '\0';
12857 }
12858 getdsnattr(buf, "timeout", busy, sizeof (busy));
12859 sflag[0] = '\0';
12860 getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12861 spflag[0] = '\0';
12862 getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12863 ntflag[0] = '\0';
12864 getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12865 nwflag[0] = '\0';
12866 getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12867 snflag[0] = '\0';
12868 getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12869 lnflag[0] = '\0';
12870 getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12871 ncflag[0] = '\0';
12872 getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12873 fkflag[0] = '\0';
12874 getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12875 loadext[0] = '\0';
12876 getdsnattr(buf, "loadext", loadext, sizeof (loadext));
12877 jmode[0] = '\0';
12878 getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
12879 jdflag[0] = '\0';
12880 getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
12881 #if defined(_WIN32) || defined(_WIN64)
12882 oemcp[0] = '\0';
12883 getdsnattr(buf, "oemcp", oemcp, sizeof (oemcp));
12884 #endif
12885 biflag[0] = '\0';
12886 getdsnattr(buf, "bigint", biflag, sizeof (biflag));
12887 attas[0] = '\0';
12888 getdsnattr(buf, "attachas", attas, sizeof (attas));
12889 ilflag[0] = '\0';
12890 getdsnattr(buf, "ilike", ilflag, sizeof (ilflag));
12891 #else
12892 SQLGetPrivateProfileString(buf, "timeout", "100000",
12893 busy, sizeof (busy), ODBC_INI);
12894 SQLGetPrivateProfileString(buf, "database", "",
12895 dbname, sizeof (dbname), ODBC_INI);
12896 #if defined(_WIN32) || defined(_WIN64)
12897
12898 isu = 0;
12899 #endif
12900 SQLGetPrivateProfileString(buf, "stepapi", "",
12901 sflag, sizeof (sflag), ODBC_INI);
12902 SQLGetPrivateProfileString(buf, "syncpragma", "NORMAL",
12903 spflag, sizeof (spflag), ODBC_INI);
12904 SQLGetPrivateProfileString(buf, "notxn", "",
12905 ntflag, sizeof (ntflag), ODBC_INI);
12906 SQLGetPrivateProfileString(buf, "nowchar", "",
12907 nwflag, sizeof (nwflag), ODBC_INI);
12908 SQLGetPrivateProfileString(buf, "shortnames", "",
12909 snflag, sizeof (snflag), ODBC_INI);
12910 SQLGetPrivateProfileString(buf, "longnames", "",
12911 lnflag, sizeof (lnflag), ODBC_INI);
12912 SQLGetPrivateProfileString(buf, "nocreat", "",
12913 ncflag, sizeof (ncflag), ODBC_INI);
12914 SQLGetPrivateProfileString(buf, "fksupport", "",
12915 fkflag, sizeof (fkflag), ODBC_INI);
12916 SQLGetPrivateProfileString(buf, "loadext", "",
12917 loadext, sizeof (loadext), ODBC_INI);
12918 SQLGetPrivateProfileString(buf, "journalmode", "",
12919 jmode, sizeof (jmode), ODBC_INI);
12920 SQLGetPrivateProfileString(buf, "jdconv", "",
12921 jdflag, sizeof (jdflag), ODBC_INI);
12922 #if defined(_WIN32) || defined(_WIN64)
12923 SQLGetPrivateProfileString(buf, "oemcp", "1",
12924 oemcp, sizeof (oemcp), ODBC_INI);
12925 #endif
12926 SQLGetPrivateProfileString(buf, "bigint", "",
12927 biflag, sizeof (biflag), ODBC_INI);
12928 SQLGetPrivateProfileString(buf, "attachas", "",
12929 attas, sizeof (attas), ODBC_INI);
12930 SQLGetPrivateProfileString(buf, "ilike", "",
12931 ilflag, sizeof (ilflag), ODBC_INI);
12932 #endif
12933 tracef[0] = '\0';
12934 #ifdef WITHOUT_DRIVERMGR
12935 getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
12936 #else
12937 SQLGetPrivateProfileString(buf, "tracefile", "",
12938 tracef, sizeof (tracef), ODBC_INI);
12939 #endif
12940 if (tracef[0] != '\0') {
12941 d->trace = fopen(tracef, "a");
12942 }
12943 d->nowchar = getbool(nwflag);
12944 d->shortnames = getbool(snflag);
12945 d->longnames = getbool(lnflag);
12946 d->nocreat = getbool(ncflag);
12947 d->fksupport = getbool(fkflag);
12948 d->jdconv = getbool(jdflag);
12949 d->ilike = getbool(ilflag);
12950 #if defined(_WIN32) || defined(_WIN64)
12951 d->oemcp = getbool(oemcp);
12952 #else
12953 d->oemcp = 0;
12954 #endif
12955 d->dobigint = getbool(biflag);
12956 d->pwd = pwd;
12957 d->pwdLen = 0;
12958 if (d->pwd) {
12959 d->pwdLen = (pwdLen == SQL_NTS) ? strlen(d->pwd) : pwdLen;
12960 }
12961 ret = dbopen(d, dbname, isu, (char *) dsn, sflag, spflag, ntflag,
12962 jmode, busy);
12963 if (ret == SQL_SUCCESS) {
12964 dbloadext(d, loadext);
12965 dbattas(d, attas);
12966 }
12967 return ret;
12968 }
12969
12970 #ifndef WINTERFACE
12971
12983 SQLRETURN SQL_API
12984 SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
12985 SQLCHAR *uid, SQLSMALLINT uidLen,
12986 SQLCHAR *pwd, SQLSMALLINT pwdLen)
12987 {
12988 SQLRETURN ret;
12989
12990 HDBC_LOCK(dbc);
12991 ret = drvconnect(dbc, dsn, dsnLen, (char *) pwd, pwdLen, 0);
12992 HDBC_UNLOCK(dbc);
12993 return ret;
12994 }
12995 #endif
12996
12997 #ifdef WINTERFACE
12998
13010 SQLRETURN SQL_API
13011 SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
13012 SQLWCHAR *uid, SQLSMALLINT uidLen,
13013 SQLWCHAR *pwd, SQLSMALLINT pwdLen)
13014 {
13015 char *dsna = NULL;
13016 char *pwda = NULL;
13017 SQLRETURN ret;
13018
13019 HDBC_LOCK(dbc);
13020 if (dsn) {
13021 dsna = uc_to_utf_c(dsn, dsnLen);
13022 if (!dsna) {
13023 DBC *d = (DBC *) dbc;
13024
13025 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
13026 ret = SQL_ERROR;
13027 goto done;
13028 }
13029 }
13030 if (pwd) {
13031 pwda = uc_to_utf_c(pwd, pwdLen);
13032 if (!pwda) {
13033 DBC *d = (DBC *) dbc;
13034
13035 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
13036 ret = SQL_ERROR;
13037 goto done;
13038 }
13039 }
13040 ret = drvconnect(dbc, (SQLCHAR *) dsna, SQL_NTS, pwda, SQL_NTS, 1);
13041 done:
13042 HDBC_UNLOCK(dbc);
13043 uc_free(dsna);
13044 uc_free(pwda);
13045 return ret;
13046 }
13047 #endif
13048
13055 static SQLRETURN
13056 drvdisconnect(SQLHDBC dbc)
13057 {
13058 DBC *d;
13059 int rc;
13060
13061 if (dbc == SQL_NULL_HDBC) {
13062 return SQL_INVALID_HANDLE;
13063 }
13064 d = (DBC *) dbc;
13065 if (d->magic != DBC_MAGIC) {
13066 return SQL_INVALID_HANDLE;
13067 }
13068 if (d->intrans) {
13069 setstatd(d, -1, "incomplete transaction", "25000");
13070 return SQL_ERROR;
13071 }
13072 if (d->cur_s3stmt) {
13073 s3stmt_end(d->cur_s3stmt);
13074 }
13075 if (d->sqlite) {
13076 if (d->trace) {
13077 fprintf(d->trace, "-- sqlite3_close: '%s'\n",
13078 d->dbname);
13079 fflush(d->trace);
13080 }
13081 rc = sqlite3_close(d->sqlite);
13082 if (rc == SQLITE_BUSY) {
13083 setstatd(d, -1, "unfinished statements", "25000");
13084 return SQL_ERROR;
13085 }
13086 d->sqlite = NULL;
13087 }
13088 freep(&d->dbname);
13089 freep(&d->dsn);
13090 return SQL_SUCCESS;
13091 }
13092
13099 SQLRETURN SQL_API
13100 SQLDisconnect(SQLHDBC dbc)
13101 {
13102 SQLRETURN ret;
13103
13104 HDBC_LOCK(dbc);
13105 ret = drvdisconnect(dbc);
13106 HDBC_UNLOCK(dbc);
13107 return ret;
13108 }
13109
13110 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
13111
13125 static SQLRETURN
13126 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
13127 SQLCHAR *connIn, SQLSMALLINT connInLen,
13128 SQLCHAR *connOut, SQLSMALLINT connOutMax,
13129 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
13130 {
13131 DBC *d;
13132 int len;
13133 SQLRETURN ret;
13134 char buf[SQL_MAX_MESSAGE_LENGTH * 8], dbname[SQL_MAX_MESSAGE_LENGTH];
13135 char dsn[SQL_MAX_MESSAGE_LENGTH], busy[SQL_MAX_MESSAGE_LENGTH / 4];
13136 char tracef[SQL_MAX_MESSAGE_LENGTH], loadext[SQL_MAX_MESSAGE_LENGTH];
13137 char pwd[SQL_MAX_MESSAGE_LENGTH], attas[SQL_MAX_MESSAGE_LENGTH];
13138 char sflag[32], spflag[32], ntflag[32], snflag[32], lnflag[32];
13139 char ncflag[32], nwflag[32], fkflag[32], jmode[32], biflag[32];
13140 char jdflag[32], ilflag[32];
13141
13142 if (dbc == SQL_NULL_HDBC) {
13143 return SQL_INVALID_HANDLE;
13144 }
13145 if (drvcompl != SQL_DRIVER_COMPLETE &&
13146 drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
13147 drvcompl != SQL_DRIVER_PROMPT &&
13148 drvcompl != SQL_DRIVER_NOPROMPT) {
13149 return SQL_NO_DATA;
13150 }
13151 d = (DBC *) dbc;
13152 if (d->sqlite) {
13153 setstatd(d, -1, "connection already established", "08002");
13154 return SQL_ERROR;
13155 }
13156 buf[0] = '\0';
13157 if (connInLen == SQL_NTS) {
13158 len = sizeof (buf) - 1;
13159 } else {
13160 len = min(connInLen, sizeof (buf) - 1);
13161 }
13162 if (connIn != NULL) {
13163 strncpy(buf, (char *) connIn, len);
13164 }
13165 buf[len] = '\0';
13166 if (!buf[0]) {
13167 setstatd(d, -1, "invalid connect attributes",
13168 (*d->ov3) ? "HY090" : "S1090");
13169 return SQL_ERROR;
13170 }
13171 dsn[0] = '\0';
13172 getdsnattr(buf, "DSN", dsn, sizeof (dsn));
13173
13174
13175 if (!dsn[0] && !strchr(buf, ';') && !strchr(buf, '=')) {
13176 strncpy(dsn, buf, sizeof (dsn) - 1);
13177 dsn[sizeof (dsn) - 1] = '\0';
13178 }
13179
13180 busy[0] = '\0';
13181 getdsnattr(buf, "timeout", busy, sizeof (busy));
13182 #ifndef WITHOUT_DRIVERMGR
13183 if (dsn[0] && !busy[0]) {
13184 SQLGetPrivateProfileString(dsn, "timeout", "100000",
13185 busy, sizeof (busy), ODBC_INI);
13186 }
13187 #endif
13188 dbname[0] = '\0';
13189 getdsnattr(buf, "database", dbname, sizeof (dbname));
13190 #ifndef WITHOUT_DRIVERMGR
13191 if (dsn[0] && !dbname[0]) {
13192 SQLGetPrivateProfileString(dsn, "database", "",
13193 dbname, sizeof (dbname), ODBC_INI);
13194 }
13195 #endif
13196 sflag[0] = '\0';
13197 getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
13198 #ifndef WITHOUT_DRIVERMGR
13199 if (dsn[0] && !sflag[0]) {
13200 SQLGetPrivateProfileString(dsn, "stepapi", "",
13201 sflag, sizeof (sflag), ODBC_INI);
13202 }
13203 #endif
13204 spflag[0] = '\0';
13205 getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
13206 #ifndef WITHOUT_DRIVERMGR
13207 if (dsn[0] && !spflag[0]) {
13208 SQLGetPrivateProfileString(dsn, "syncpragma", "NORMAL",
13209 spflag, sizeof (spflag), ODBC_INI);
13210 }
13211 #endif
13212 ntflag[0] = '\0';
13213 getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
13214 #ifndef WITHOUT_DRIVERMGR
13215 if (dsn[0] && !ntflag[0]) {
13216 SQLGetPrivateProfileString(dsn, "notxn", "",
13217 ntflag, sizeof (ntflag), ODBC_INI);
13218 }
13219 #endif
13220 snflag[0] = '\0';
13221 getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
13222 #ifndef WITHOUT_DRIVERMGR
13223 if (dsn[0] && !snflag[0]) {
13224 SQLGetPrivateProfileString(dsn, "shortnames", "",
13225 snflag, sizeof (snflag), ODBC_INI);
13226 }
13227 #endif
13228 lnflag[0] = '\0';
13229 getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
13230 #ifndef WITHOUT_DRIVERMGR
13231 if (dsn[0] && !lnflag[0]) {
13232 SQLGetPrivateProfileString(dsn, "longnames", "",
13233 lnflag, sizeof (lnflag), ODBC_INI);
13234 }
13235 #endif
13236 ncflag[0] = '\0';
13237 getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
13238 #ifndef WITHOUT_DRIVERMGR
13239 if (dsn[0] && !ncflag[0]) {
13240 SQLGetPrivateProfileString(dsn, "nocreat", "",
13241 ncflag, sizeof (ncflag), ODBC_INI);
13242 }
13243 #endif
13244 nwflag[0] = '\0';
13245 getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
13246 #ifndef WITHOUT_DRIVERMGR
13247 if (dsn[0] && !nwflag[0]) {
13248 SQLGetPrivateProfileString(dsn, "nowchar", "",
13249 nwflag, sizeof (nwflag), ODBC_INI);
13250 }
13251 #endif
13252 fkflag[0] = '\0';
13253 getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
13254 #ifndef WITHOUT_DRIVERMGR
13255 if (dsn[0] && !fkflag[0]) {
13256 SQLGetPrivateProfileString(dsn, "fksupport", "",
13257 fkflag, sizeof (fkflag), ODBC_INI);
13258 }
13259 #endif
13260 loadext[0] = '\0';
13261 getdsnattr(buf, "loadext", loadext, sizeof (loadext));
13262 #ifndef WITHOUT_DRIVERMGR
13263 if (dsn[0] && !loadext[0]) {
13264 SQLGetPrivateProfileString(dsn, "loadext", "",
13265 loadext, sizeof (loadext), ODBC_INI);
13266 }
13267 #endif
13268 jmode[0] = '\0';
13269 getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
13270 #ifndef WITHOUT_DRIVERMGR
13271 if (dsn[0] && !jmode[0]) {
13272 SQLGetPrivateProfileString(dsn, "journalmode", "",
13273 jmode, sizeof (jmode), ODBC_INI);
13274 }
13275 #endif
13276 biflag[0] = '\0';
13277 getdsnattr(buf, "bigint", biflag, sizeof (biflag));
13278 #ifndef WITHOUT_DRIVERMGR
13279 if (dsn[0] && !biflag[0]) {
13280 SQLGetPrivateProfileString(dsn, "bigint", "",
13281 biflag, sizeof (biflag), ODBC_INI);
13282 }
13283 #endif
13284 jdflag[0] = '\0';
13285 getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
13286 #ifndef WITHOUT_DRIVERMGR
13287 if (dsn[0] && !jdflag[0]) {
13288 SQLGetPrivateProfileString(dsn, "jdconv", "",
13289 jdflag, sizeof (jdflag), ODBC_INI);
13290 }
13291 #endif
13292 pwd[0] = '\0';
13293 getdsnattr(buf, "pwd", pwd, sizeof (pwd));
13294 #ifndef WITHOUT_DRIVERMGR
13295 if (dsn[0] && !pwd[0]) {
13296 SQLGetPrivateProfileString(dsn, "pwd", "",
13297 pwd, sizeof (pwd), ODBC_INI);
13298 }
13299 #endif
13300 attas[0] = '\0';
13301 getdsnattr(buf, "attachas", attas, sizeof (attas));
13302 #ifndef WITHOUT_DRIVERMGR
13303 if (dsn[0] && !attas[0]) {
13304 SQLGetPrivateProfileString(dsn, "attachas", "",
13305 attas, sizeof (attas), ODBC_INI);
13306 }
13307 #endif
13308 ilflag[0] = '\0';
13309 getdsnattr(buf, "ilike", ilflag, sizeof (ilflag));
13310 #ifndef WITHOUT_DRIVERMGR
13311 if (dsn[0] && !ilflag[0]) {
13312 SQLGetPrivateProfileString(dsn, "ilike", "",
13313 ilflag, sizeof (ilflag), ODBC_INI);
13314 }
13315 #endif
13316
13317 if (!dbname[0] && !dsn[0]) {
13318 strcpy(dsn, "SQLite");
13319 strncpy(dbname, buf, sizeof (dbname));
13320 dbname[sizeof (dbname) - 1] = '\0';
13321 }
13322 tracef[0] = '\0';
13323 getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
13324 #ifndef WITHOUT_DRIVERMGR
13325 if (dsn[0] && !tracef[0]) {
13326 SQLGetPrivateProfileString(dsn, "tracefile", "",
13327 tracef, sizeof (tracef), ODBC_INI);
13328 }
13329 #endif
13330 if (connOut || connOutLen) {
13331 int count;
13332
13333 buf[0] = '\0';
13334 count = snprintf(buf, sizeof (buf),
13335 "DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
13336 "SyncPragma=%s;NoTXN=%s;ShortNames=%s;LongNames=%s;"
13337 "NoCreat=%s;NoWCHAR=%s;FKSupport=%s;Tracefile=%s;"
13338 "JournalMode=%s;LoadExt=%s;BigInt=%s;JDConv=%s;"
13339 "PWD=%s;AttachAs=%s;ILike=%s",
13340 dsn, dbname, sflag, busy, spflag, ntflag,
13341 snflag, lnflag, ncflag, nwflag, fkflag, tracef,
13342 jmode, loadext, biflag, jdflag, pwd, attas, ilflag);
13343 if (count < 0) {
13344 buf[sizeof (buf) - 1] = '\0';
13345 }
13346 len = min(connOutMax - 1, strlen(buf));
13347 if (connOut) {
13348 strncpy((char *) connOut, buf, len);
13349 connOut[len] = '\0';
13350 }
13351 if (connOutLen) {
13352 *connOutLen = len;
13353 }
13354 }
13355 if (tracef[0] != '\0') {
13356 d->trace = fopen(tracef, "a");
13357 }
13358 d->shortnames = getbool(snflag);
13359 d->longnames = getbool(lnflag);
13360 d->nocreat = getbool(ncflag);
13361 d->nowchar = getbool(nwflag);
13362 d->fksupport = getbool(fkflag);
13363 d->dobigint = getbool(biflag);
13364 d->jdconv = getbool(jdflag);
13365 d->ilike = getbool(ilflag);
13366 d->oemcp = 0;
13367 d->pwdLen = strlen(pwd);
13368 d->pwd = (d->pwdLen > 0) ? pwd : NULL;
13369 ret = dbopen(d, dbname, 0, dsn, sflag, spflag, ntflag, jmode, busy);
13370 memset(pwd, 0, sizeof (pwd));
13371 if (ret == SQL_SUCCESS) {
13372 dbloadext(d, loadext);
13373 dbattas(d, attas);
13374 }
13375 return ret;
13376 }
13377 #endif
13378
13385 static SQLRETURN
13386 freestmt(SQLHSTMT stmt)
13387 {
13388 STMT *s;
13389 DBC *d;
13390
13391 if (stmt == SQL_NULL_HSTMT) {
13392 return SQL_INVALID_HANDLE;
13393 }
13394 s = (STMT *) stmt;
13395 s3stmt_drop(s);
13396 freeresult(s, 1);
13397 freep(&s->query);
13398 d = (DBC *) s->dbc;
13399 if (d && d->magic == DBC_MAGIC) {
13400 STMT *p, *n;
13401
13402 p = NULL;
13403 n = d->stmt;
13404 while (n) {
13405 if (n == s) {
13406 break;
13407 }
13408 p = n;
13409 n = n->next;
13410 }
13411 if (n) {
13412 if (p) {
13413 p->next = s->next;
13414 } else {
13415 d->stmt = s->next;
13416 }
13417 }
13418 }
13419 freeparams(s);
13420 freep(&s->bindparms);
13421 if (s->row_status0 != &s->row_status1) {
13422 freep(&s->row_status0);
13423 s->rowset_size = 1;
13424 s->row_status0 = &s->row_status1;
13425 }
13426 xfree(s);
13427 return SQL_SUCCESS;
13428 }
13429
13437 static SQLRETURN
13438 drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
13439 {
13440 DBC *d;
13441 STMT *s, *sl, *pl;
13442
13443 if (dbc == SQL_NULL_HDBC) {
13444 return SQL_INVALID_HANDLE;
13445 }
13446 d = (DBC *) dbc;
13447 if (d->magic != DBC_MAGIC || stmt == NULL) {
13448 return SQL_INVALID_HANDLE;
13449 }
13450 s = (STMT *) xmalloc(sizeof (STMT));
13451 if (s == NULL) {
13452 *stmt = SQL_NULL_HSTMT;
13453 return SQL_ERROR;
13454 }
13455 *stmt = (SQLHSTMT) s;
13456 memset(s, 0, sizeof (STMT));
13457 s->dbc = dbc;
13458 s->ov3 = d->ov3;
13459 s->bkmrk = SQL_UB_OFF;
13460 s->bkmrkptr = 0;
13461 s->oemcp = &d->oemcp;
13462 s->jdconv = &d->jdconv;
13463 s->ilike = &d->ilike;
13464 s->nowchar[0] = d->nowchar;
13465 s->nowchar[1] = 0;
13466 s->dobigint = d->dobigint;
13467 s->curtype = d->curtype;
13468 s->row_status0 = &s->row_status1;
13469 s->rowset_size = 1;
13470 s->longnames = d->longnames;
13471 s->retr_data = SQL_RD_ON;
13472 s->max_rows = 0;
13473 s->bind_type = SQL_BIND_BY_COLUMN;
13474 s->bind_offs = NULL;
13475 s->paramset_size = 1;
13476 s->parm_bind_type = SQL_PARAM_BIND_BY_COLUMN;
13477 s->one_tbl = -1;
13478 s->has_pk = -1;
13479 s->has_rowid = -1;
13480 #ifdef _WIN64
13481 sprintf((char *) s->cursorname, "CUR_%I64X", (SQLUBIGINT) *stmt);
13482 #else
13483 sprintf((char *) s->cursorname, "CUR_%016lX", (long) *stmt);
13484 #endif
13485 sl = d->stmt;
13486 pl = NULL;
13487 while (sl) {
13488 pl = sl;
13489 sl = sl->next;
13490 }
13491 if (pl) {
13492 pl->next = s;
13493 } else {
13494 d->stmt = s;
13495 }
13496 return SQL_SUCCESS;
13497 }
13498
13506 SQLRETURN SQL_API
13507 SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
13508 {
13509 SQLRETURN ret;
13510
13511 HDBC_LOCK(dbc);
13512 ret = drvallocstmt(dbc, stmt);
13513 HDBC_UNLOCK(dbc);
13514 return ret;
13515 }
13516
13524 static SQLRETURN
13525 drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13526 {
13527 STMT *s;
13528 SQLRETURN ret = SQL_SUCCESS;
13529 SQLHDBC dbc;
13530
13531 if (stmt == SQL_NULL_HSTMT) {
13532 return SQL_INVALID_HANDLE;
13533 }
13534 HSTMT_LOCK(stmt);
13535 s = (STMT *) stmt;
13536 dbc = s->dbc;
13537 switch (opt) {
13538 case SQL_RESET_PARAMS:
13539 freeparams(s);
13540 break;
13541 case SQL_UNBIND:
13542 unbindcols(s);
13543 break;
13544 case SQL_CLOSE:
13545 s3stmt_end_if(s);
13546 freeresult(s, 0);
13547 break;
13548 case SQL_DROP:
13549 s3stmt_end_if(s);
13550 ret = freestmt(stmt);
13551 break;
13552 default:
13553 setstat(s, -1, "unsupported option", (*s->ov3) ? "HYC00" : "S1C00");
13554 ret = SQL_ERROR;
13555 break;
13556 }
13557 HDBC_UNLOCK(dbc);
13558 return ret;
13559 }
13560
13568 SQLRETURN SQL_API
13569 SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13570 {
13571 return drvfreestmt(stmt, opt);
13572 }
13573
13580 SQLRETURN SQL_API
13581 SQLCancel(SQLHSTMT stmt)
13582 {
13583 if (stmt != SQL_NULL_HSTMT) {
13584 DBC *d = (DBC *) ((STMT *) stmt)->dbc;
13585 #if defined(_WIN32) || defined(_WIN64)
13586
13587 if (d->magic == DBC_MAGIC && d->owner != GetCurrentThreadId() &&
13588 d->owner != 0) {
13589 d->busyint = 1;
13590 sqlite3_interrupt(d->sqlite);
13591 return SQL_SUCCESS;
13592 }
13593 #else
13594 if (d->magic == DBC_MAGIC) {
13595 d->busyint = 1;
13596 sqlite3_interrupt(d->sqlite);
13597 }
13598 #endif
13599 }
13600 return drvfreestmt(stmt, SQL_CLOSE);
13601 }
13602
13612 static SQLRETURN
13613 drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13614 SQLSMALLINT *lenp)
13615 {
13616 STMT *s;
13617
13618 if (stmt == SQL_NULL_HSTMT) {
13619 return SQL_INVALID_HANDLE;
13620 }
13621 s = (STMT *) stmt;
13622 if (lenp && !cursor) {
13623 *lenp = strlen((char *) s->cursorname);
13624 return SQL_SUCCESS;
13625 }
13626 if (cursor) {
13627 if (buflen > 0) {
13628 strncpy((char *) cursor, (char *) s->cursorname, buflen - 1);
13629 cursor[buflen - 1] = '\0';
13630 }
13631 if (lenp) {
13632 *lenp = min(strlen((char *) s->cursorname), buflen - 1);
13633 }
13634 }
13635 return SQL_SUCCESS;
13636 }
13637
13638 #ifndef WINTERFACE
13639
13648 SQLRETURN SQL_API
13649 SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13650 SQLSMALLINT *lenp)
13651 {
13652 SQLRETURN ret;
13653 #if defined(_WIN32) || defined(_WIN64)
13654 SQLSMALLINT len = 0;
13655 #endif
13656
13657 HSTMT_LOCK(stmt);
13658 #if defined(_WIN32) || defined(_WIN64)
13659 if (!((STMT *) stmt)->oemcp[0]) {
13660 ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13661 goto done;
13662 }
13663 ret = drvgetcursorname(stmt, cursor, buflen, &len);
13664 if (ret == SQL_SUCCESS) {
13665 char *c = NULL;
13666
13667 if (cursor) {
13668 c = utf_to_wmb((char *) cursor, len);
13669 if (!c) {
13670 ret = nomem((STMT *) stmt);
13671 goto done;
13672 }
13673 c[len] = 0;
13674 len = strlen(c);
13675 if (buflen > 0) {
13676 strncpy((char *) cursor, c, buflen - 1);
13677 cursor[buflen - 1] = 0;
13678 }
13679 uc_free(c);
13680 }
13681 if (lenp) {
13682 *lenp = min(len, buflen - 1);
13683 }
13684 }
13685 done:
13686 ;
13687 #else
13688 ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13689 #endif
13690 HSTMT_UNLOCK(stmt);
13691 return ret;
13692 }
13693 #endif
13694
13695 #ifdef WINTERFACE
13696
13705 SQLRETURN SQL_API
13706 SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
13707 SQLSMALLINT *lenp)
13708 {
13709 SQLRETURN ret;
13710 SQLSMALLINT len = 0;
13711
13712 HSTMT_LOCK(stmt);
13713 ret = drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
13714 if (ret == SQL_SUCCESS) {
13715 SQLWCHAR *c = NULL;
13716
13717 if (cursor) {
13718 c = uc_from_utf((SQLCHAR *) cursor, len);
13719 if (!c) {
13720 ret = nomem((STMT *) stmt);
13721 goto done;
13722 }
13723 c[len] = 0;
13724 len = uc_strlen(c);
13725 if (buflen > 0) {
13726 uc_strncpy(cursor, c, buflen - 1);
13727 cursor[buflen - 1] = 0;
13728 }
13729 uc_free(c);
13730 }
13731 if (lenp) {
13732 *lenp = min(len, buflen - 1);
13733 }
13734 }
13735 done:
13736 HSTMT_UNLOCK(stmt);
13737 return ret;
13738 }
13739 #endif
13740
13749 static SQLRETURN
13750 drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13751 {
13752 STMT *s;
13753
13754 if (stmt == SQL_NULL_HSTMT) {
13755 return SQL_INVALID_HANDLE;
13756 }
13757 s = (STMT *) stmt;
13758 if (!cursor ||
13759 !((cursor[0] >= 'A' && cursor[0] <= 'Z') ||
13760 (cursor[0] >= 'a' && cursor[0] <= 'z'))) {
13761 setstat(s, -1, "invalid cursor name", (*s->ov3) ? "HYC00" : "S1C00");
13762 return SQL_ERROR;
13763 }
13764 if (len == SQL_NTS) {
13765 len = sizeof (s->cursorname) - 1;
13766 } else {
13767 len = min(sizeof (s->cursorname) - 1, len);
13768 }
13769 strncpy((char *) s->cursorname, (char *) cursor, len);
13770 s->cursorname[len] = '\0';
13771 return SQL_SUCCESS;
13772 }
13773
13774 #ifndef WINTERFACE
13775
13783 SQLRETURN SQL_API
13784 SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13785 {
13786 #if defined(_WIN32) || defined(_WIN64)
13787 char *c = NULL;
13788 #endif
13789 SQLRETURN ret;
13790
13791 HSTMT_LOCK(stmt);
13792 #if defined(_WIN32) || defined(_WIN64)
13793 if (!((STMT *) stmt)->oemcp[0]) {
13794 ret = drvsetcursorname(stmt, cursor, len);
13795 goto done2;
13796 }
13797 if (cursor) {
13798 c = wmb_to_utf_c((char *) cursor, len);
13799 if (!c) {
13800 ret = nomem((STMT *) stmt);
13801 goto done;
13802 }
13803 }
13804 ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13805 #else
13806 ret = drvsetcursorname(stmt, cursor, len);
13807 #endif
13808 #if defined(_WIN32) || defined(_WIN64)
13809 done:
13810 uc_free(c);
13811 done2:
13812 ;
13813 #endif
13814 HSTMT_UNLOCK(stmt);
13815 return ret;
13816 }
13817 #endif
13818
13819 #ifdef WINTERFACE
13820
13828 SQLRETURN SQL_API
13829 SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
13830 {
13831 char *c = NULL;
13832 SQLRETURN ret;
13833
13834 HSTMT_LOCK(stmt);
13835 if (cursor) {
13836 c = uc_to_utf_c(cursor, len);
13837 if (!c) {
13838 ret = nomem((STMT *) stmt);
13839 goto done;
13840 }
13841 }
13842 ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13843 done:
13844 uc_free(c);
13845 HSTMT_UNLOCK(stmt);
13846 return ret;
13847 }
13848 #endif
13849
13856 SQLRETURN SQL_API
13857 SQLCloseCursor(SQLHSTMT stmt)
13858 {
13859 return drvfreestmt(stmt, SQL_CLOSE);
13860 }
13861
13870 SQLRETURN SQL_API
13871 SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
13872 {
13873 SQLRETURN ret;
13874
13875 switch (type) {
13876 case SQL_HANDLE_ENV:
13877 ret = drvallocenv((SQLHENV *) output);
13878 if (ret == SQL_SUCCESS) {
13879 ENV *e = (ENV *) *output;
13880
13881 if (e && e->magic == ENV_MAGIC) {
13882 e->ov3 = 1;
13883 }
13884 }
13885 return ret;
13886 case SQL_HANDLE_DBC:
13887 return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
13888 case SQL_HANDLE_STMT:
13889 HDBC_LOCK((SQLHDBC) input);
13890 ret = drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
13891 HDBC_UNLOCK((SQLHDBC) input);
13892 return ret;
13893 }
13894 return SQL_ERROR;
13895 }
13896
13904 SQLRETURN SQL_API
13905 SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
13906 {
13907 switch (type) {
13908 case SQL_HANDLE_ENV:
13909 return drvfreeenv((SQLHENV) h);
13910 case SQL_HANDLE_DBC:
13911 return drvfreeconnect((SQLHDBC) h);
13912 case SQL_HANDLE_STMT:
13913 return drvfreestmt((SQLHSTMT) h, SQL_DROP);
13914 }
13915 return SQL_ERROR;
13916 }
13917
13923 static void
13924 freedyncols(STMT *s)
13925 {
13926 if (s->dyncols) {
13927 int i;
13928
13929 for (i = 0; i < s->dcols; i++) {
13930 freep(&s->dyncols[i].typename);
13931 }
13932 if (s->cols == s->dyncols) {
13933 s->cols = NULL;
13934 s->ncols = 0;
13935 }
13936 freep(&s->dyncols);
13937 }
13938 s->dcols = 0;
13939 }
13940
13952 static void
13953 freeresult(STMT *s, int clrcols)
13954 {
13955 freep(&s->bincache);
13956 s->bincell = NULL;
13957 s->binlen = 0;
13958 if (s->rows) {
13959 if (s->rowfree) {
13960 s->rowfree(s->rows);
13961 s->rowfree = NULL;
13962 }
13963 s->rows = NULL;
13964 }
13965 s->nrows = -1;
13966 if (clrcols > 0) {
13967 freep(&s->bindcols);
13968 s->nbindcols = 0;
13969 }
13970 if (clrcols) {
13971 freedyncols(s);
13972 s->cols = NULL;
13973 s->ncols = 0;
13974 s->nowchar[1] = 0;
13975 s->one_tbl = -1;
13976 s->has_pk = -1;
13977 s->has_rowid = -1;
13978 }
13979 }
13980
13986 static void
13987 unbindcols(STMT *s)
13988 {
13989 int i;
13990
13991 for (i = 0; s->bindcols && i < s->nbindcols; i++) {
13992 s->bindcols[i].type = SQL_UNKNOWN_TYPE;
13993 s->bindcols[i].max = 0;
13994 s->bindcols[i].lenp = NULL;
13995 s->bindcols[i].valp = NULL;
13996 s->bindcols[i].index = i;
13997 s->bindcols[i].offs = 0;
13998 }
13999 }
14000
14008 static SQLRETURN
14009 mkbindcols(STMT *s, int ncols)
14010 {
14011 if (s->bindcols) {
14012 if (s->nbindcols < ncols) {
14013 int i;
14014 BINDCOL *bindcols =
14015 xrealloc(s->bindcols, ncols * sizeof (BINDCOL));
14016
14017 if (!bindcols) {
14018 return nomem(s);
14019 }
14020 for (i = s->nbindcols; i < ncols; i++) {
14021 bindcols[i].type = SQL_UNKNOWN_TYPE;
14022 bindcols[i].max = 0;
14023 bindcols[i].lenp = NULL;
14024 bindcols[i].valp = NULL;
14025 bindcols[i].index = i;
14026 bindcols[i].offs = 0;
14027 }
14028 s->bindcols = bindcols;
14029 s->nbindcols = ncols;
14030 }
14031 } else if (ncols > 0) {
14032 s->bindcols = (BINDCOL *) xmalloc(ncols * sizeof (BINDCOL));
14033 if (!s->bindcols) {
14034 return nomem(s);
14035 }
14036 s->nbindcols = ncols;
14037 unbindcols(s);
14038 }
14039 return SQL_SUCCESS;
14040 }
14041
14055 static SQLRETURN
14056 getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
14057 SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
14058 {
14059 char **data, valdummy[16];
14060 SQLLEN dummy;
14061 SQLINTEGER *ilenp = NULL;
14062 int valnull = 0;
14063 int type = otype;
14064 SQLRETURN sret = SQL_NO_DATA;
14065
14066 if (!lenp) {
14067 lenp = &dummy;
14068 }
14069
14070 if (((SQLINTEGER *) lenp) + 1 == (SQLINTEGER *) val) {
14071 ilenp = (SQLINTEGER *) lenp;
14072 lenp = &dummy;
14073 }
14074 if (col >= s->ncols) {
14075 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14076 return SQL_ERROR;
14077 }
14078 if (s->retr_data != SQL_RD_ON) {
14079 return SQL_SUCCESS;
14080 }
14081 if (!s->rows) {
14082 *lenp = SQL_NULL_DATA;
14083 goto done;
14084 }
14085 if (s->rowp < 0 || s->rowp >= s->nrows) {
14086 *lenp = SQL_NULL_DATA;
14087 goto done;
14088 }
14089 type = mapdeftype(type, s->cols[col].type, s->cols[col].nosign ? 1 : 0,
14090 s->nowchar[0]);
14091 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14092
14093 if (type == SQL_C_WCHAR && otype == SQL_C_DEFAULT) {
14094 type = SQL_C_CHAR;
14095 }
14096 #endif
14097 data = s->rows + s->ncols + (s->rowp * s->ncols) + col;
14098 if (!val) {
14099 valnull = 1;
14100 val = (SQLPOINTER) valdummy;
14101 }
14102 if (*data == NULL) {
14103 *lenp = SQL_NULL_DATA;
14104 switch (type) {
14105 case SQL_C_UTINYINT:
14106 case SQL_C_TINYINT:
14107 case SQL_C_STINYINT:
14108 #ifdef SQL_BIT
14109 case SQL_C_BIT:
14110 #endif
14111 *((SQLCHAR *) val) = 0;
14112 break;
14113 case SQL_C_USHORT:
14114 case SQL_C_SHORT:
14115 case SQL_C_SSHORT:
14116 *((SQLSMALLINT *) val) = 0;
14117 break;
14118 case SQL_C_ULONG:
14119 case SQL_C_LONG:
14120 case SQL_C_SLONG:
14121 *((SQLINTEGER *) val) = 0;
14122 break;
14123 #ifdef SQL_BIGINT
14124 case SQL_C_SBIGINT:
14125 case SQL_C_UBIGINT:
14126 *((SQLBIGINT *) val) = 0;
14127 break;
14128 #endif
14129 case SQL_C_FLOAT:
14130 *((float *) val) = 0;
14131 break;
14132 case SQL_C_DOUBLE:
14133 *((double *) val) = 0;
14134 break;
14135 case SQL_C_BINARY:
14136 case SQL_C_CHAR:
14137 if (len > 0) {
14138 *((SQLCHAR *) val) = '\0';
14139 }
14140 break;
14141 #ifdef WCHARSUPPORT
14142 case SQL_C_WCHAR:
14143 if (len > 0) {
14144 *((SQLWCHAR *) val) = '\0';
14145 }
14146 break;
14147 #endif
14148 #ifdef SQL_C_TYPE_DATE
14149 case SQL_C_TYPE_DATE:
14150 #endif
14151 case SQL_C_DATE:
14152 memset((DATE_STRUCT *) val, 0, sizeof (DATE_STRUCT));
14153 break;
14154 #ifdef SQL_C_TYPE_TIME
14155 case SQL_C_TYPE_TIME:
14156 #endif
14157 case SQL_C_TIME:
14158 memset((TIME_STRUCT *) val, 0, sizeof (TIME_STRUCT));
14159 break;
14160 #ifdef SQL_C_TYPE_TIMESTAMP
14161 case SQL_C_TYPE_TIMESTAMP:
14162 #endif
14163 case SQL_C_TIMESTAMP:
14164 memset((TIMESTAMP_STRUCT *) val, 0, sizeof (TIMESTAMP_STRUCT));
14165 break;
14166 default:
14167 return SQL_ERROR;
14168 }
14169 } else {
14170 char *endp = NULL;
14171 #if defined(_WIN32) || defined(_WIN64)
14172 #ifdef SQL_BIGINT
14173 char endc;
14174 #endif
14175 #endif
14176
14177 switch (type) {
14178 case SQL_C_UTINYINT:
14179 case SQL_C_TINYINT:
14180 case SQL_C_STINYINT:
14181 *((SQLCHAR *) val) = strtol(*data, &endp, 0);
14182 if (endp && endp == *data) {
14183 *lenp = SQL_NULL_DATA;
14184 } else {
14185 *lenp = sizeof (SQLCHAR);
14186 }
14187 break;
14188 #ifdef SQL_BIT
14189 case SQL_C_BIT:
14190 *((SQLCHAR *) val) = getbool(*data);
14191 *lenp = sizeof (SQLCHAR);
14192 break;
14193 #endif
14194 case SQL_C_USHORT:
14195 case SQL_C_SHORT:
14196 case SQL_C_SSHORT:
14197 *((SQLSMALLINT *) val) = strtol(*data, &endp, 0);
14198 if (endp && endp == *data) {
14199 *lenp = SQL_NULL_DATA;
14200 } else {
14201 *lenp = sizeof (SQLSMALLINT);
14202 }
14203 break;
14204 case SQL_C_ULONG:
14205 case SQL_C_LONG:
14206 case SQL_C_SLONG:
14207 *((SQLINTEGER *) val) = strtol(*data, &endp, 0);
14208 if (endp && endp == *data) {
14209 *lenp = SQL_NULL_DATA;
14210 } else {
14211 *lenp = sizeof (SQLINTEGER);
14212 }
14213 break;
14214 #ifdef SQL_BIGINT
14215 case SQL_C_UBIGINT:
14216 #if defined(_WIN32) || defined(_WIN64)
14217 if (sscanf(*data, "%I64u%c", (SQLUBIGINT *) val, &endc) != 1) {
14218 *lenp = SQL_NULL_DATA;
14219 } else {
14220 *lenp = sizeof (SQLUBIGINT);
14221 }
14222 #else
14223 #ifdef __osf__
14224 *((SQLUBIGINT *) val) = strtoul(*data, &endp, 0);
14225 #else
14226 *((SQLUBIGINT *) val) = strtoull(*data, &endp, 0);
14227 #endif
14228 if (endp && endp == *data) {
14229 *lenp = SQL_NULL_DATA;
14230 } else {
14231 *lenp = sizeof (SQLUBIGINT);
14232 }
14233 #endif
14234 break;
14235 case SQL_C_SBIGINT:
14236 #if defined(_WIN32) || defined(_WIN64)
14237 if (sscanf(*data, "%I64d%c", (SQLBIGINT *) val, &endc) != 1) {
14238 *lenp = SQL_NULL_DATA;
14239 } else {
14240 *lenp = sizeof (SQLBIGINT);
14241 }
14242 #else
14243 #ifdef __osf__
14244 *((SQLBIGINT *) val) = strtol(*data, &endp, 0);
14245 #else
14246 *((SQLBIGINT *) val) = strtoll(*data, &endp, 0);
14247 #endif
14248 if (endp && endp == *data) {
14249 *lenp = SQL_NULL_DATA;
14250 } else {
14251 *lenp = sizeof (SQLBIGINT);
14252 }
14253 #endif
14254 break;
14255 #endif
14256 case SQL_C_FLOAT:
14257 *((float *) val) = ln_strtod(*data, &endp);
14258 if (endp && endp == *data) {
14259 *lenp = SQL_NULL_DATA;
14260 } else {
14261 *lenp = sizeof (float);
14262 }
14263 break;
14264 case SQL_C_DOUBLE:
14265 *((double *) val) = ln_strtod(*data, &endp);
14266 if (endp && endp == *data) {
14267 *lenp = SQL_NULL_DATA;
14268 } else {
14269 *lenp = sizeof (double);
14270 }
14271 break;
14272 case SQL_C_BINARY: {
14273 int dlen, offs = 0;
14274 char *bin;
14275
14276 if (valnull) {
14277 freep(&s->bincache);
14278 s->binlen = 0;
14279 goto doCHAR;
14280 }
14281 if (*data == s->bincell) {
14282 if (s->bincache) {
14283 bin = s->bincache;
14284 dlen = s->binlen;
14285 } else {
14286 goto doCHAR;
14287 }
14288 } else {
14289 char *dp;
14290 int i;
14291
14292 freep(&s->bincache);
14293 dp = *data;
14294 dlen = strlen(dp);
14295 s->bincell = dp;
14296 s->binlen = 0;
14297 if (!(dp[0] == 'x' || dp[0] == 'X') || dp[1] != '\'' ||
14298 dp[dlen - 1] != '\'') {
14299 goto doCHAR;
14300 }
14301 dlen -= 2;
14302 dp += 2;
14303 dlen = dlen / 2;
14304 s->bincache = bin = xmalloc(dlen + 1);
14305 if (!bin) {
14306 return nomem(s);
14307 }
14308 s->binlen = dlen;
14309 memset(bin, 0, dlen);
14310 bin[dlen] = '\0';
14311 for (i = 0; i < dlen; i++) {
14312 char *x;
14313 int v;
14314
14315 if (!*dp || !(x = strchr(xdigits, *dp))) {
14316 goto converr;
14317 }
14318 v = x - xdigits;
14319 bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
14320 ++dp;
14321 if (!*dp || !(x = strchr(xdigits, *dp))) {
14322 converr:
14323 freep(&s->bincache);
14324 s->binlen = 0;
14325 setstat(s, -1, "conversion error",
14326 (*s->ov3) ? "HY000" : "S1000");
14327 return SQL_ERROR;
14328 }
14329 v = x - xdigits;
14330 bin[i] |= (v >= 16) ? (v - 6) : v;
14331 ++dp;
14332 }
14333 bin = s->bincache;
14334 }
14335 if (partial && len && s->bindcols) {
14336 if (s->bindcols[col].offs >= dlen) {
14337 *lenp = 0;
14338 if (!dlen && s->bindcols[col].offs == dlen) {
14339 s->bindcols[col].offs = 1;
14340 sret = SQL_SUCCESS;
14341 goto done;
14342 }
14343 s->bindcols[col].offs = 0;
14344 sret = SQL_NO_DATA;
14345 goto done;
14346 }
14347 offs = s->bindcols[col].offs;
14348 dlen -= offs;
14349 }
14350 if (val && len) {
14351 memcpy(val, bin + offs, min(len, dlen));
14352 }
14353 if (len < 1) {
14354 *lenp = dlen;
14355 } else {
14356 *lenp = min(len, dlen);
14357 if (*lenp == len && *lenp != dlen) {
14358 *lenp = SQL_NO_TOTAL;
14359 }
14360 }
14361 if (partial && len && s->bindcols) {
14362 if (*lenp == SQL_NO_TOTAL) {
14363 *lenp = dlen;
14364 s->bindcols[col].offs += len;
14365 setstat(s, -1, "data right truncated", "01004");
14366 if (s->bindcols[col].lenp) {
14367 *s->bindcols[col].lenp = dlen;
14368 }
14369 sret = SQL_SUCCESS_WITH_INFO;
14370 goto done;
14371 }
14372 s->bindcols[col].offs += *lenp;
14373 }
14374 if (*lenp == SQL_NO_TOTAL) {
14375 *lenp = dlen;
14376 setstat(s, -1, "data right truncated", "01004");
14377 sret = SQL_SUCCESS_WITH_INFO;
14378 goto done;
14379 }
14380 break;
14381 }
14382 doCHAR:
14383 #ifdef WCHARSUPPORT
14384 case SQL_C_WCHAR:
14385 #endif
14386 case SQL_C_CHAR: {
14387 int doz, zlen = len - 1;
14388 int dlen = strlen(*data);
14389 int offs = 0;
14390 #ifdef WCHARSUPPORT
14391 SQLWCHAR *ucdata = NULL;
14392 SQLCHAR *cdata = (SQLCHAR *) *data;
14393 #endif
14394
14395 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14396
14397 if (!valnull &&
14398 (s->cols == statSpec2P || s->cols == statSpec3P) &&
14399 type == SQL_C_WCHAR) {
14400 if (len > 0 && len <= sizeof (SQLWCHAR)) {
14401 ((char *) val)[0] = data[0][0];
14402 memset((char *) val + 1, 0, len - 1);
14403 *lenp = 1;
14404 sret = SQL_SUCCESS;
14405 goto done;
14406 }
14407 }
14408 #endif
14409
14410 #ifdef WCHARSUPPORT
14411 switch (type) {
14412 case SQL_C_CHAR:
14413 doz = 1;
14414 break;
14415 case SQL_C_WCHAR:
14416 doz = sizeof (SQLWCHAR);
14417 break;
14418 default:
14419 doz = 0;
14420 break;
14421 }
14422 if (type == SQL_C_WCHAR) {
14423 ucdata = uc_from_utf(cdata, dlen);
14424 if (!ucdata) {
14425 return nomem(s);
14426 }
14427 dlen = uc_strlen(ucdata) * sizeof (SQLWCHAR);
14428 }
14429 #if defined(_WIN32) || defined(_WIN64)
14430 else if (*s->oemcp && type == SQL_C_CHAR) {
14431 ucdata = (SQLWCHAR *) utf_to_wmb((char *) cdata, dlen);
14432 if (!ucdata) {
14433 return nomem(s);
14434 }
14435 cdata = (SQLCHAR *) ucdata;
14436 dlen = strlen((char *) cdata);
14437 }
14438 #endif
14439 #else
14440 doz = (type == SQL_C_CHAR) ? 1 : 0;
14441 #endif
14442 if (partial && len && s->bindcols) {
14443 if (s->bindcols[col].offs >= dlen) {
14444 #ifdef WCHARSUPPORT
14445 uc_free(ucdata);
14446 #endif
14447 *lenp = 0;
14448 if (doz && val) {
14449 #ifdef WCHARSUPPORT
14450 if (type == SQL_C_WCHAR) {
14451 ((SQLWCHAR *) val)[0] = 0;
14452 } else {
14453 ((char *) val)[0] = '\0';
14454 }
14455 #else
14456 ((char *) val)[0] = '\0';
14457 #endif
14458 }
14459 if (!dlen && s->bindcols[col].offs == dlen) {
14460 s->bindcols[col].offs = 1;
14461 sret = SQL_SUCCESS;
14462 goto done;
14463 }
14464 s->bindcols[col].offs = 0;
14465 sret = SQL_NO_DATA;
14466 goto done;
14467 }
14468 offs = s->bindcols[col].offs;
14469 dlen -= offs;
14470 }
14471 if (val && !valnull && len) {
14472 #ifdef WCHARSUPPORT
14473 if (type == SQL_C_WCHAR) {
14474 uc_strncpy(val, ucdata + offs / sizeof (SQLWCHAR),
14475 (len - doz) / sizeof (SQLWCHAR));
14476 } else {
14477 strncpy(val, (char *) cdata + offs, len - doz);
14478 }
14479 #else
14480 strncpy(val, *data + offs, len - doz);
14481 #endif
14482 }
14483 if (valnull || len < 1) {
14484 *lenp = dlen;
14485 } else {
14486 *lenp = min(len - doz, dlen);
14487 if (*lenp == len - doz && *lenp != dlen) {
14488 *lenp = SQL_NO_TOTAL;
14489 } else if (*lenp < zlen) {
14490 zlen = *lenp;
14491 }
14492 }
14493 if (len && !valnull && doz) {
14494 #ifdef WCHARSUPPORT
14495 if (type == SQL_C_WCHAR) {
14496 ((SQLWCHAR *) val)[zlen / sizeof (SQLWCHAR)] = 0;
14497 } else {
14498 ((char *) val)[zlen] = '\0';
14499 }
14500 #else
14501 ((char *) val)[zlen] = '\0';
14502 #endif
14503 }
14504 #ifdef WCHARSUPPORT
14505 uc_free(ucdata);
14506 #endif
14507 if (partial && len && s->bindcols) {
14508 if (*lenp == SQL_NO_TOTAL) {
14509 *lenp = dlen;
14510 s->bindcols[col].offs += len - doz;
14511 setstat(s, -1, "data right truncated", "01004");
14512 if (s->bindcols[col].lenp) {
14513 *s->bindcols[col].lenp = dlen;
14514 }
14515 sret = SQL_SUCCESS_WITH_INFO;
14516 goto done;
14517 }
14518 s->bindcols[col].offs += *lenp;
14519 }
14520 if (*lenp == SQL_NO_TOTAL) {
14521 *lenp = dlen;
14522 setstat(s, -1, "data right truncated", "01004");
14523 sret = SQL_SUCCESS_WITH_INFO;
14524 goto done;
14525 }
14526 break;
14527 }
14528 #ifdef SQL_C_TYPE_DATE
14529 case SQL_C_TYPE_DATE:
14530 #endif
14531 case SQL_C_DATE:
14532 if (str2date(*s->jdconv, *data, (DATE_STRUCT *) val) < 0) {
14533 *lenp = SQL_NULL_DATA;
14534 } else {
14535 *lenp = sizeof (DATE_STRUCT);
14536 }
14537 break;
14538 #ifdef SQL_C_TYPE_TIME
14539 case SQL_C_TYPE_TIME:
14540 #endif
14541 case SQL_C_TIME:
14542 if (str2time(*s->jdconv, *data, (TIME_STRUCT *) val) < 0) {
14543 *lenp = SQL_NULL_DATA;
14544 } else {
14545 *lenp = sizeof (TIME_STRUCT);
14546 }
14547 break;
14548 #ifdef SQL_C_TYPE_TIMESTAMP
14549 case SQL_C_TYPE_TIMESTAMP:
14550 #endif
14551 case SQL_C_TIMESTAMP:
14552 if (str2timestamp(*s->jdconv, *data,
14553 (TIMESTAMP_STRUCT *) val) < 0) {
14554 *lenp = SQL_NULL_DATA;
14555 } else {
14556 *lenp = sizeof (TIMESTAMP_STRUCT);
14557 }
14558 switch (s->cols[col].prec) {
14559 case 0:
14560 ((TIMESTAMP_STRUCT *) val)->fraction = 0;
14561 break;
14562 case 1:
14563 ((TIMESTAMP_STRUCT *) val)->fraction /= 100000000;
14564 ((TIMESTAMP_STRUCT *) val)->fraction *= 100000000;
14565 break;
14566 case 2:
14567 ((TIMESTAMP_STRUCT *) val)->fraction /= 10000000;
14568 ((TIMESTAMP_STRUCT *) val)->fraction *= 10000000;
14569 break;
14570 }
14571 break;
14572 default:
14573 return SQL_ERROR;
14574 }
14575 }
14576 sret = SQL_SUCCESS;
14577 done:
14578 if (ilenp) {
14579 *ilenp = *lenp;
14580 }
14581 return sret;
14582 }
14583
14595 static SQLRETURN
14596 drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14597 SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14598 {
14599 STMT *s;
14600 int sz = 0;
14601
14602 if (stmt == SQL_NULL_HSTMT) {
14603 return SQL_INVALID_HANDLE;
14604 }
14605 s = (STMT *) stmt;
14606 if (col < 1) {
14607 if (col == 0 && s->bkmrk == SQL_UB_ON &&
14608 type == SQL_C_BOOKMARK) {
14609 s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14610 s->bkmrkcol.max = val ? sizeof (SQLINTEGER) : 0;
14611 s->bkmrkcol.lenp = val ? lenp : 0;
14612 s->bkmrkcol.valp = val;
14613 s->bkmrkcol.offs = 0;
14614 if (val && lenp) {
14615 *lenp = 0;
14616 }
14617 return SQL_SUCCESS;
14618 } else if (col == 0 && s->bkmrk == SQL_UB_VARIABLE &&
14619 type == SQL_C_VARBOOKMARK &&
14620 max >= sizeof (sqlite_int64)) {
14621 s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14622 s->bkmrkcol.max = val ? max : 0;
14623 s->bkmrkcol.lenp = val ? lenp : 0;
14624 s->bkmrkcol.valp = val;
14625 s->bkmrkcol.offs = 0;
14626 if (val && lenp) {
14627 *lenp = 0;
14628 }
14629 return SQL_SUCCESS;
14630 }
14631 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14632 return SQL_ERROR;
14633 }
14634 if (mkbindcols(s, col) != SQL_SUCCESS) {
14635 return SQL_ERROR;
14636 }
14637 --col;
14638 if (type == SQL_C_DEFAULT) {
14639 type = mapdeftype(type, s->cols[col].type, 0,
14640 s->nowchar[0] || s->nowchar[1]);
14641 }
14642 switch (type) {
14643 case SQL_C_LONG:
14644 case SQL_C_ULONG:
14645 case SQL_C_SLONG:
14646 sz = sizeof (SQLINTEGER);
14647 break;
14648 case SQL_C_TINYINT:
14649 case SQL_C_UTINYINT:
14650 case SQL_C_STINYINT:
14651 sz = sizeof (SQLCHAR);
14652 break;
14653 case SQL_C_SHORT:
14654 case SQL_C_USHORT:
14655 case SQL_C_SSHORT:
14656 sz = sizeof (SQLSMALLINT);
14657 break;
14658 case SQL_C_FLOAT:
14659 sz = sizeof (SQLFLOAT);
14660 break;
14661 case SQL_C_DOUBLE:
14662 sz = sizeof (SQLDOUBLE);
14663 break;
14664 case SQL_C_TIMESTAMP:
14665 sz = sizeof (SQL_TIMESTAMP_STRUCT);
14666 break;
14667 case SQL_C_TIME:
14668 sz = sizeof (SQL_TIME_STRUCT);
14669 break;
14670 case SQL_C_DATE:
14671 sz = sizeof (SQL_DATE_STRUCT);
14672 break;
14673 case SQL_C_CHAR:
14674 break;
14675 #ifdef WCHARSUPPORT
14676 case SQL_C_WCHAR:
14677 break;
14678 #endif
14679 #ifdef SQL_C_TYPE_DATE
14680 case SQL_C_TYPE_DATE:
14681 sz = sizeof (SQL_DATE_STRUCT);
14682 break;
14683 #endif
14684 #ifdef SQL_C_TYPE_TIME
14685 case SQL_C_TYPE_TIME:
14686 sz = sizeof (SQL_TIME_STRUCT);
14687 break;
14688 #endif
14689 #ifdef SQL_C_TYPE_TIMESTAMP
14690 case SQL_C_TYPE_TIMESTAMP:
14691 sz = sizeof (SQL_TIMESTAMP_STRUCT);
14692 break;
14693 #endif
14694 #ifdef SQL_BIT
14695 case SQL_C_BIT:
14696 sz = sizeof (SQLCHAR);
14697 break;
14698 #endif
14699 case SQL_C_BINARY:
14700 break;
14701 #ifdef SQL_BIGINT
14702 case SQL_C_SBIGINT:
14703 case SQL_C_UBIGINT:
14704 sz = sizeof (SQLBIGINT);
14705 break;
14706 #endif
14707 default:
14708 if (val == NULL) {
14709
14710 break;
14711 }
14712 setstat(s, -1, "invalid type %d", "HY003", type);
14713 return SQL_ERROR;
14714 }
14715 if (val == NULL) {
14716
14717 s->bindcols[col].type = SQL_UNKNOWN_TYPE;
14718 s->bindcols[col].max = 0;
14719 s->bindcols[col].lenp = NULL;
14720 s->bindcols[col].valp = NULL;
14721 s->bindcols[col].offs = 0;
14722 } else {
14723 if (sz == 0 && max < 0) {
14724 setstat(s, -1, "invalid length", "HY090");
14725 return SQL_ERROR;
14726 }
14727 s->bindcols[col].type = type;
14728 s->bindcols[col].max = (sz == 0) ? max : sz;
14729 s->bindcols[col].lenp = lenp;
14730 s->bindcols[col].valp = val;
14731 s->bindcols[col].offs = 0;
14732 if (lenp) {
14733 *lenp = 0;
14734 }
14735 }
14736 return SQL_SUCCESS;
14737 }
14738
14750 SQLRETURN SQL_API
14751 SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14752 SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14753 {
14754 SQLRETURN ret;
14755
14756 HSTMT_LOCK(stmt);
14757 ret = drvbindcol(stmt, col, type, val, max, lenp);
14758 HSTMT_UNLOCK(stmt);
14759 return ret;
14760 }
14761
14766 static COL tableSpec2[] = {
14767 { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14768 { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14769 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14770 { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14771 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14772 };
14773
14774 static COL tableSpec3[] = {
14775 { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14776 { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14777 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14778 { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14779 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14780 };
14781
14796 static SQLRETURN
14797 drvtables(SQLHSTMT stmt,
14798 SQLCHAR *cat, SQLSMALLINT catLen,
14799 SQLCHAR *schema, SQLSMALLINT schemaLen,
14800 SQLCHAR *table, SQLSMALLINT tableLen,
14801 SQLCHAR *type, SQLSMALLINT typeLen)
14802 {
14803 SQLRETURN ret;
14804 STMT *s;
14805 DBC *d;
14806 int ncols, asize, rc, size, npatt;
14807 char *errp = NULL, *sql, tname[512];
14808 char *where = "(type = 'table' or type = 'view')";
14809
14810 ret = mkresultset(stmt, tableSpec2, array_size(tableSpec2),
14811 tableSpec3, array_size(tableSpec3), &asize);
14812 if (ret != SQL_SUCCESS) {
14813 return ret;
14814 }
14815 s = (STMT *) stmt;
14816 d = (DBC *) s->dbc;
14817 if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] == '%') {
14818 int size = 3 * asize;
14819
14820 s->rows = xmalloc(size * sizeof (char *));
14821 if (!s->rows) {
14822 s->nrows = 0;
14823 return nomem(s);
14824 }
14825 memset(s->rows, 0, sizeof (char *) * size);
14826 s->ncols = asize;
14827 s->rows[s->ncols + 0] = "";
14828 s->rows[s->ncols + 1] = "";
14829 s->rows[s->ncols + 2] = "";
14830 s->rows[s->ncols + 3] = "TABLE";
14831 s->rows[s->ncols + 5] = "";
14832 s->rows[s->ncols + 6] = "";
14833 s->rows[s->ncols + 7] = "";
14834 s->rows[s->ncols + 8] = "VIEW";
14835 #ifdef MEMORY_DEBUG
14836 s->rowfree = xfree__;
14837 #else
14838 s->rowfree = sqlite3_free;
14839 #endif
14840 s->nrows = 2;
14841 s->rowp = s->rowprs = -1;
14842 return SQL_SUCCESS;
14843 }
14844 if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
14845 table = NULL;
14846 goto doit;
14847 }
14848 if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
14849 schema[0] == '%') {
14850 if ((!cat || catLen == 0 || !cat[0]) &&
14851 (!table || tableLen == 0 || !table[0])) {
14852 table = NULL;
14853 goto doit;
14854 }
14855 }
14856 if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] != '\0') {
14857 char tmp[256], *t;
14858 int with_view = 0, with_table = 0;
14859
14860 if (typeLen == SQL_NTS) {
14861 strncpy(tmp, (char *) type, sizeof (tmp));
14862 tmp[sizeof (tmp) - 1] = '\0';
14863 } else {
14864 int len = min(sizeof (tmp) - 1, typeLen);
14865
14866 strncpy(tmp, (char *) type, len);
14867 tmp[len] = '\0';
14868 }
14869 t = tmp;
14870 while (*t) {
14871 *t = TOLOWER(*t);
14872 t++;
14873 }
14874 t = tmp;
14875 unescpat(t);
14876 while (t) {
14877 if (t[0] == '\'') {
14878 ++t;
14879 }
14880 if (strncmp(t, "table", 5) == 0) {
14881 with_table++;
14882 } else if (strncmp(t, "view", 4) == 0) {
14883 with_view++;
14884 }
14885 t = strchr(t, ',');
14886 if (t) {
14887 ++t;
14888 }
14889 }
14890 if (with_view && with_table) {
14891
14892 } else if (with_view && !with_table) {
14893 where = "type = 'view'";
14894 } else if (!with_view && with_table) {
14895 where = "type = 'table'";
14896 } else {
14897 return SQL_SUCCESS;
14898 }
14899 }
14900 doit:
14901 if (!table) {
14902 size = 1;
14903 tname[0] = '%';
14904 } else {
14905 if (tableLen == SQL_NTS) {
14906 size = sizeof (tname) - 1;
14907 } else {
14908 size = min(sizeof (tname) - 1, tableLen);
14909 }
14910 strncpy(tname, (char *) table, size);
14911 }
14912 tname[size] = '\0';
14913 npatt = unescpat(tname);
14914 #if defined(_WIN32) || defined(_WIN64)
14915 if (npatt) {
14916 sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14917 "%s as 'TABLE_SCHEM', "
14918 "tbl_name as 'TABLE_NAME', "
14919 "upper(type) as 'TABLE_TYPE', "
14920 "NULL as 'REMARKS' "
14921 "from sqlite_master where %s "
14922 "and tbl_name like %Q",
14923 d->xcelqrx ? "'main'" : "NULL",
14924 d->xcelqrx ? "''" : "NULL",
14925 where, tname);
14926 } else {
14927 sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14928 "%s as 'TABLE_SCHEM', "
14929 "tbl_name as 'TABLE_NAME', "
14930 "upper(type) as 'TABLE_TYPE', "
14931 "NULL as 'REMARKS' "
14932 "from sqlite_master where %s "
14933 "and lower(tbl_name) = lower(%Q)",
14934 d->xcelqrx ? "'main'" : "NULL",
14935 d->xcelqrx ? "''" : "NULL",
14936 where, tname);
14937 }
14938 #else
14939 if (npatt) {
14940 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14941 "NULL as 'TABLE_OWNER', "
14942 "tbl_name as 'TABLE_NAME', "
14943 "upper(type) as 'TABLE_TYPE', "
14944 "NULL as 'REMARKS' "
14945 "from sqlite_master where %s "
14946 "and tbl_name like %Q",
14947 where, tname);
14948 } else {
14949 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14950 "NULL as 'TABLE_OWNER', "
14951 "tbl_name as 'TABLE_NAME', "
14952 "upper(type) as 'TABLE_TYPE', "
14953 "NULL as 'REMARKS' "
14954 "from sqlite_master where %s "
14955 "and lower(tbl_name) = lower(%Q)",
14956 where, tname);
14957 }
14958 #endif
14959 if (!sql) {
14960 return nomem(s);
14961 }
14962 ret = starttran(s);
14963 if (ret != SQL_SUCCESS) {
14964 sqlite3_free(sql);
14965 return ret;
14966 }
14967 dbtraceapi(d, "sqlite3_get_table", sql);
14968 rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
14969 sqlite3_free(sql);
14970 if (rc == SQLITE_OK) {
14971 if (ncols != s->ncols) {
14972 freeresult(s, 0);
14973 s->nrows = 0;
14974 } else {
14975 s->rowfree = sqlite3_free_table;
14976 }
14977 } else {
14978 s->nrows = 0;
14979 s->rows = NULL;
14980 s->rowfree = NULL;
14981 }
14982 if (errp) {
14983 sqlite3_free(errp);
14984 errp = NULL;
14985 }
14986 s->rowp = s->rowprs = -1;
14987 return SQL_SUCCESS;
14988 }
14989
14990 #ifndef WINTERFACE
14991
15005 SQLRETURN SQL_API
15006 SQLTables(SQLHSTMT stmt,
15007 SQLCHAR *cat, SQLSMALLINT catLen,
15008 SQLCHAR *schema, SQLSMALLINT schemaLen,
15009 SQLCHAR *table, SQLSMALLINT tableLen,
15010 SQLCHAR *type, SQLSMALLINT typeLen)
15011 {
15012 #if defined(_WIN32) || defined(_WIN64)
15013 char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
15014 #endif
15015 SQLRETURN ret;
15016
15017 HSTMT_LOCK(stmt);
15018 #if defined(_WIN32) || defined(_WIN64)
15019 if (!((STMT *) stmt)->oemcp[0]) {
15020 ret = drvtables(stmt, cat, catLen, schema, schemaLen,
15021 table, tableLen, type, typeLen);
15022 goto done2;
15023 }
15024 if (cat) {
15025 c = wmb_to_utf_c((char *) cat, catLen);
15026 if (!c) {
15027 ret = nomem((STMT *) stmt);
15028 goto done;
15029 }
15030 }
15031 if (schema) {
15032 s = wmb_to_utf_c((char *) schema, schemaLen);
15033 if (!s) {
15034 ret = nomem((STMT *) stmt);
15035 goto done;
15036 }
15037 }
15038 if (table) {
15039 t = wmb_to_utf_c((char *) table, tableLen);
15040 if (!t) {
15041 ret = nomem((STMT *) stmt);
15042 goto done;
15043 }
15044 }
15045 if (type) {
15046 y = wmb_to_utf_c((char *) type, typeLen);
15047 if (!y) {
15048 ret = nomem((STMT *) stmt);
15049 goto done;
15050 }
15051 }
15052 ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15053 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
15054 #else
15055 ret = drvtables(stmt, cat, catLen, schema, schemaLen,
15056 table, tableLen, type, typeLen);
15057 #endif
15058 #if defined(_WIN32) || defined(_WIN64)
15059 done:
15060 uc_free(y);
15061 uc_free(t);
15062 uc_free(s);
15063 uc_free(c);
15064 done2:
15065 ;
15066 #endif
15067 HSTMT_UNLOCK(stmt);
15068 return ret;
15069 }
15070 #endif
15071
15072 #ifdef WINTERFACE
15073
15087 SQLRETURN SQL_API
15088 SQLTablesW(SQLHSTMT stmt,
15089 SQLWCHAR *cat, SQLSMALLINT catLen,
15090 SQLWCHAR *schema, SQLSMALLINT schemaLen,
15091 SQLWCHAR *table, SQLSMALLINT tableLen,
15092 SQLWCHAR *type, SQLSMALLINT typeLen)
15093 {
15094 char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
15095 SQLRETURN ret;
15096
15097 HSTMT_LOCK(stmt);
15098 if (cat) {
15099 c = uc_to_utf_c(cat, catLen);
15100 if (!c) {
15101 ret = nomem((STMT *) stmt);
15102 goto done;
15103 }
15104 }
15105 if (schema) {
15106 s = uc_to_utf_c(schema, schemaLen);
15107 if (!s) {
15108 ret = nomem((STMT *) stmt);
15109 goto done;
15110 }
15111 }
15112 if (table) {
15113 t = uc_to_utf_c(table, tableLen);
15114 if (!t) {
15115 ret = nomem((STMT *) stmt);
15116 goto done;
15117 }
15118 }
15119 if (type) {
15120 y = uc_to_utf_c(type, typeLen);
15121 if (!y) {
15122 ret = nomem((STMT *) stmt);
15123 goto done;
15124 }
15125 }
15126 ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15127 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
15128 done:
15129 uc_free(y);
15130 uc_free(t);
15131 uc_free(s);
15132 uc_free(c);
15133 HSTMT_UNLOCK(stmt);
15134 return ret;
15135 }
15136 #endif
15137
15142 static COL colSpec2[] = {
15143 { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15144 { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
15145 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
15146 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15147 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
15148 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
15149 { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
15150 { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
15151 { "SYSTEM", "COLUMN", "SCALE", SQL_SMALLINT, 50 },
15152 { "SYSTEM", "COLUMN", "RADIX", SQL_SMALLINT, 50 },
15153 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
15154 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
15155 { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
15156 { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
15157 { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
15158 { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
15159 { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15160 { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
15161 };
15162
15163 static COL colSpec3[] = {
15164 { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
15165 { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15166 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
15167 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15168 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
15169 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
15170 { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
15171 { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
15172 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_SMALLINT, 50 },
15173 { "SYSTEM", "COLUMN", "NUM_PREC_RADIX", SQL_SMALLINT, 50 },
15174 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
15175 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
15176 { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
15177 { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
15178 { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
15179 { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
15180 { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15181 { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
15182 };
15183
15198 static SQLRETURN
15199 drvcolumns(SQLHSTMT stmt,
15200 SQLCHAR *cat, SQLSMALLINT catLen,
15201 SQLCHAR *schema, SQLSMALLINT schemaLen,
15202 SQLCHAR *table, SQLSMALLINT tableLen,
15203 SQLCHAR *col, SQLSMALLINT colLen)
15204 {
15205 SQLRETURN sret;
15206 STMT *s;
15207 DBC *d;
15208 int ret, nrows, ncols, asize, i, k, roffs, namec;
15209 int tnrows, tncols, npatt;
15210 PTRDIFF_T size;
15211 char *errp = NULL, *sql, tname[512], cname[512], **rowp, **trows;
15212
15213 sret = mkresultset(stmt, colSpec2, array_size(colSpec2),
15214 colSpec3, array_size(colSpec3), &asize);
15215 if (sret != SQL_SUCCESS) {
15216 return sret;
15217 }
15218 s = (STMT *) stmt;
15219 d = (DBC *) s->dbc;
15220 if (!table) {
15221 size = 1;
15222 tname[0] = '%';
15223 } else {
15224 if (tableLen == SQL_NTS) {
15225 size = sizeof (tname) - 1;
15226 } else {
15227 size = min(sizeof (tname) - 1, tableLen);
15228 }
15229 strncpy(tname, (char *) table, size);
15230 }
15231 tname[size] = '\0';
15232 npatt = unescpat(tname);
15233 size = 0;
15234 if (col) {
15235 if (colLen == SQL_NTS) {
15236 size = sizeof (cname) - 1;
15237 } else {
15238 size = min(sizeof (cname) - 1, colLen);
15239 }
15240 strncpy(cname, (char *) col, size);
15241 }
15242 cname[size] = '\0';
15243 if (!strcmp(cname, "%")) {
15244 cname[0] = '\0';
15245 }
15246 if (npatt) {
15247 sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
15248 "(type = 'table' or type = 'view') "
15249 "and tbl_name like %Q", tname);
15250 } else {
15251 sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
15252 "(type = 'table' or type = 'view') "
15253 "and lower(tbl_name) = lower(%Q)", tname);
15254 }
15255 if (!sql) {
15256 return nomem(s);
15257 }
15258 sret = starttran(s);
15259 if (sret != SQL_SUCCESS) {
15260 sqlite3_free(sql);
15261 return sret;
15262 }
15263 dbtraceapi(d, "sqlite3_get_table", sql);
15264 ret = sqlite3_get_table(d->sqlite, sql, &trows, &tnrows, &tncols, &errp);
15265 sqlite3_free(sql);
15266 if (ret != SQLITE_OK) {
15267 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15268 errp ? errp : "unknown error", ret);
15269 if (errp) {
15270 sqlite3_free(errp);
15271 errp = NULL;
15272 }
15273 return SQL_ERROR;
15274 }
15275 if (errp) {
15276 sqlite3_free(errp);
15277 errp = NULL;
15278 }
15279
15280 if (tncols * tnrows <= 0) {
15281 sqlite3_free_table(trows);
15282 return SQL_SUCCESS;
15283 }
15284 size = 0;
15285 for (i = 1; i <= tnrows; i++) {
15286 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15287 if (!sql) {
15288 sqlite3_free_table(trows);
15289 return nomem(s);
15290 }
15291 dbtraceapi(d, "sqlite3_get_table", sql);
15292 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15293 sqlite3_free(sql);
15294 if (ret != SQLITE_OK) {
15295 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15296 errp ? errp : "unknown error", ret);
15297 if (errp) {
15298 sqlite3_free(errp);
15299 errp = NULL;
15300 }
15301 sqlite3_free_table(trows);
15302 return SQL_ERROR;
15303 }
15304 if (errp) {
15305 sqlite3_free(errp);
15306 errp = NULL;
15307 }
15308 if (ncols * nrows > 0) {
15309 namec = -1;
15310 for (k = 0; k < ncols; k++) {
15311 if (strcmp(rowp[k], "name") == 0) {
15312 namec = k;
15313 break;
15314 }
15315 }
15316 if (cname[0]) {
15317 if (namec >= 0) {
15318 for (k = 1; k <= nrows; k++) {
15319 if (namematch(rowp[k * ncols + namec], cname, 1)) {
15320 size++;
15321 }
15322 }
15323 }
15324 } else {
15325 size += nrows;
15326 }
15327 }
15328 sqlite3_free_table(rowp);
15329 }
15330
15331 if (size <= 0) {
15332 sqlite3_free_table(trows);
15333 return SQL_SUCCESS;
15334 }
15335 s->nrows = size;
15336 size = (size + 1) * asize;
15337 s->rows = xmalloc((size + 1) * sizeof (char *));
15338 if (!s->rows) {
15339 s->nrows = 0;
15340 sqlite3_free_table(trows);
15341 return nomem(s);
15342 }
15343 s->rows[0] = (char *) size;
15344 s->rows += 1;
15345 memset(s->rows, 0, sizeof (char *) * size);
15346 s->rowfree = freerows;
15347 roffs = 1;
15348 for (i = 1; i <= tnrows; i++) {
15349 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15350 if (!sql) {
15351 sqlite3_free_table(trows);
15352 return nomem(s);
15353 }
15354 dbtraceapi(d, "sqlite3_get_table", sql);
15355 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15356 sqlite3_free(sql);
15357 if (ret != SQLITE_OK) {
15358 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15359 errp ? errp : "unknown error", ret);
15360 if (errp) {
15361 sqlite3_free(errp);
15362 errp = NULL;
15363 }
15364 sqlite3_free_table(trows);
15365 return SQL_ERROR;
15366 }
15367 if (errp) {
15368 sqlite3_free(errp);
15369 errp = NULL;
15370 }
15371 if (ncols * nrows > 0) {
15372 int m, mr, nr = nrows;
15373
15374 namec = -1;
15375 for (k = 0; k < ncols; k++) {
15376 if (strcmp(rowp[k], "name") == 0) {
15377 namec = k;
15378 break;
15379 }
15380 }
15381 if (cname[0]) {
15382 nr = 0;
15383 if (namec >= 0) {
15384 for (k = 1; k <= nrows; k++) {
15385 if (namematch(rowp[k * ncols + namec], cname, 1)) {
15386 nr++;
15387 }
15388 }
15389 }
15390 }
15391 for (k = 0; k < nr; k++) {
15392 m = asize * (roffs + k);
15393 #if defined(_WIN32) || defined(_WIN64)
15394 s->rows[m + 0] = xstrdup(d->xcelqrx ? "main" : "");
15395 s->rows[m + 1] = xstrdup("");
15396 #else
15397 s->rows[m + 0] = xstrdup("");
15398 s->rows[m + 1] = xstrdup("");
15399 #endif
15400 s->rows[m + 2] = xstrdup(trows[i]);
15401 s->rows[m + 8] = xstrdup("10");
15402 s->rows[m + 9] = xstrdup("0");
15403 s->rows[m + 15] = xstrdup("16384");
15404 }
15405 for (k = 0; nr && k < ncols; k++) {
15406 if (strcmp(rowp[k], "cid") == 0) {
15407 for (mr = 0, m = 1; m <= nrows; m++) {
15408 char buf[256];
15409 int ir, coln = k;
15410
15411 if (cname[0] &&
15412 !namematch(rowp[m * ncols + namec], cname, 1)) {
15413 continue;
15414 }
15415 ir = asize * (roffs + mr);
15416 sscanf(rowp[m * ncols + k], "%d", &coln);
15417 sprintf(buf, "%d", coln + 1);
15418 s->rows[ir + 16] = xstrdup(buf);
15419 ++mr;
15420 }
15421 } else if (k == namec) {
15422 for (mr = 0, m = 1; m <= nrows; m++) {
15423 int ir;
15424
15425 if (cname[0] &&
15426 !namematch(rowp[m * ncols + namec], cname, 1)) {
15427 continue;
15428 }
15429 ir = asize * (roffs + mr);
15430 s->rows[ir + 3] = xstrdup(rowp[m * ncols + k]);
15431 ++mr;
15432 }
15433 } else if (strcmp(rowp[k], "notnull") == 0) {
15434 for (mr = 0, m = 1; m <= nrows; m++) {
15435 int ir;
15436
15437 if (cname[0] &&
15438 !namematch(rowp[m * ncols + namec], cname, 1)) {
15439 continue;
15440 }
15441 ir = asize * (roffs + mr);
15442 if (*rowp[m * ncols + k] != '0') {
15443 s->rows[ir + 10] = xstrdup(stringify(SQL_FALSE));
15444 } else {
15445 s->rows[ir + 10] = xstrdup(stringify(SQL_TRUE));
15446 }
15447 s->rows[ir + 17] =
15448 xstrdup((*rowp[m * ncols + k] != '0') ?
15449 "NO" : "YES");
15450 ++mr;
15451 }
15452 } else if (strcmp(rowp[k], "dflt_value") == 0) {
15453 for (mr = 0, m = 1; m <= nrows; m++) {
15454 char *dflt = unquote(rowp[m * ncols + k]);
15455 int ir;
15456
15457 if (cname[0] &&
15458 !namematch(rowp[m * ncols + namec], cname, 1)) {
15459 continue;
15460 }
15461 ir = asize * (roffs + mr);
15462 s->rows[ir + 12] = xstrdup(dflt ? dflt : "NULL");
15463 ++mr;
15464 }
15465 } else if (strcmp(rowp[k], "type") == 0) {
15466 for (mr = 0, m = 1; m <= nrows; m++) {
15467 char *typename = rowp[m * ncols + k];
15468 int sqltype, mm, dd, ir;
15469 char buf[256];
15470
15471 if (cname[0] &&
15472 !namematch(rowp[m * ncols + namec], cname, 1)) {
15473 continue;
15474 }
15475 ir = asize * (roffs + mr);
15476 s->rows[ir + 5] = xstrdup(typename);
15477 sqltype = mapsqltype(typename, NULL, *s->ov3,
15478 s->nowchar[0], s->dobigint);
15479 getmd(typename, sqltype, &mm, &dd);
15480 #ifdef SQL_LONGVARCHAR
15481 if (sqltype == SQL_VARCHAR && mm > 255) {
15482 sqltype = SQL_LONGVARCHAR;
15483 }
15484 #endif
15485 #ifdef WINTERFACE
15486 #ifdef SQL_WLONGVARCHAR
15487 if (sqltype == SQL_WVARCHAR && mm > 255) {
15488 sqltype = SQL_WLONGVARCHAR;
15489 }
15490 #endif
15491 #endif
15492 if (sqltype == SQL_VARBINARY && mm > 255) {
15493 sqltype = SQL_LONGVARBINARY;
15494 }
15495 sprintf(buf, "%d", sqltype);
15496 s->rows[ir + 4] = xstrdup(buf);
15497 s->rows[ir + 13] = xstrdup(buf);
15498 sprintf(buf, "%d", mm);
15499 s->rows[ir + 7] = xstrdup(buf);
15500 sprintf(buf, "%d", dd);
15501 s->rows[ir + 6] = xstrdup(buf);
15502 ++mr;
15503 }
15504 }
15505 }
15506 roffs += nr;
15507 }
15508 sqlite3_free_table(rowp);
15509 }
15510 sqlite3_free_table(trows);
15511 return SQL_SUCCESS;
15512 }
15513
15514 #ifndef WINTERFACE
15515
15529 SQLRETURN SQL_API
15530 SQLColumns(SQLHSTMT stmt,
15531 SQLCHAR *cat, SQLSMALLINT catLen,
15532 SQLCHAR *schema, SQLSMALLINT schemaLen,
15533 SQLCHAR *table, SQLSMALLINT tableLen,
15534 SQLCHAR *col, SQLSMALLINT colLen)
15535 {
15536 #if defined(_WIN32) || defined(_WIN64)
15537 char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15538 #endif
15539 SQLRETURN ret;
15540
15541 HSTMT_LOCK(stmt);
15542 #if defined(_WIN32) || defined(_WIN64)
15543 if (!((STMT *) stmt)->oemcp[0]) {
15544 ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15545 table, tableLen, col, colLen);
15546 goto done2;
15547 }
15548 if (cat) {
15549 c = wmb_to_utf_c((char *) cat, catLen);
15550 if (!c) {
15551 ret = nomem((STMT *) stmt);
15552 goto done;
15553 }
15554 }
15555 if (schema) {
15556 s = wmb_to_utf_c((char *) schema, schemaLen);
15557 if (!s) {
15558 ret = nomem((STMT *) stmt);
15559 goto done;
15560 }
15561 }
15562 if (table) {
15563 t = wmb_to_utf_c((char *) table, tableLen);
15564 if (!t) {
15565 ret = nomem((STMT *) stmt);
15566 goto done;
15567 }
15568 }
15569 if (col) {
15570 k = wmb_to_utf_c((char *) col, colLen);
15571 if (!k) {
15572 ret = nomem((STMT *) stmt);
15573 goto done;
15574 }
15575 }
15576 ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15577 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15578 #else
15579 ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15580 table, tableLen, col, colLen);
15581 #endif
15582 #if defined(_WIN32) || defined(_WIN64)
15583 done:
15584 uc_free(k);
15585 uc_free(t);
15586 uc_free(s);
15587 uc_free(c);
15588 done2:
15589 ;
15590 #endif
15591 HSTMT_UNLOCK(stmt);
15592 return ret;
15593 }
15594 #endif
15595
15596 #ifdef WINTERFACE
15597
15611 SQLRETURN SQL_API
15612 SQLColumnsW(SQLHSTMT stmt,
15613 SQLWCHAR *cat, SQLSMALLINT catLen,
15614 SQLWCHAR *schema, SQLSMALLINT schemaLen,
15615 SQLWCHAR *table, SQLSMALLINT tableLen,
15616 SQLWCHAR *col, SQLSMALLINT colLen)
15617 {
15618 char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15619 SQLRETURN ret;
15620
15621 HSTMT_LOCK(stmt);
15622 if (cat) {
15623 c = uc_to_utf_c(cat, catLen);
15624 if (!c) {
15625 ret = nomem((STMT *) stmt);
15626 goto done;
15627 }
15628 }
15629 if (schema) {
15630 s = uc_to_utf_c(schema, schemaLen);
15631 if (!s) {
15632 ret = nomem((STMT *) stmt);
15633 goto done;
15634 }
15635 }
15636 if (table) {
15637 t = uc_to_utf_c(table, tableLen);
15638 if (!t) {
15639 ret = nomem((STMT *) stmt);
15640 goto done;
15641 }
15642 }
15643 if (col) {
15644 k = uc_to_utf_c(col, colLen);
15645 if (!k) {
15646 ret = nomem((STMT *) stmt);
15647 goto done;
15648 }
15649 }
15650 ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15651 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15652 done:
15653 uc_free(k);
15654 uc_free(t);
15655 uc_free(s);
15656 uc_free(c);
15657 HSTMT_UNLOCK(stmt);
15658 return ret;
15659
15660 }
15661 #endif
15662
15667 static COL typeSpec2[] = {
15668 { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15669 { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15670 { "SYSTEM", "TYPE", "PRECISION", SQL_INTEGER, 9 },
15671 { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15672 { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15673 { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15674 { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15675 { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15676 { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15677 { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15678 { "SYSTEM", "TYPE", "MONEY", SQL_SMALLINT, 2 },
15679 { "SYSTEM", "TYPE", "AUTO_INCREMENT", SQL_SMALLINT, 2 },
15680 { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15681 { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15682 { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 }
15683 };
15684
15685 static COL typeSpec3[] = {
15686 { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15687 { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15688 { "SYSTEM", "TYPE", "COLUMN_SIZE", SQL_INTEGER, 9 },
15689 { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15690 { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15691 { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15692 { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15693 { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15694 { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15695 { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15696 { "SYSTEM", "TYPE", "FIXED_PREC_SCALE", SQL_SMALLINT, 2 },
15697 { "SYSTEM", "TYPE", "AUTO_UNIQUE_VALUE", SQL_SMALLINT, 2 },
15698 { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15699 { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15700 { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 },
15701 { "SYSTEM", "TYPE", "SQL_DATA_TYPE", SQL_SMALLINT, 2 },
15702 { "SYSTEM", "TYPE", "SQL_DATETIME_SUB", SQL_SMALLINT, 2 },
15703 { "SYSTEM", "TYPE", "NUM_PREC_RADIX", SQL_INTEGER, 4 },
15704 { "SYSTEM", "TYPE", "INTERVAL_PRECISION", SQL_SMALLINT, 2 }
15705 };
15706
15717 static void
15718 mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
15719 {
15720 int offs = row * asize;
15721 char *tcode, *crpar = NULL, *sign = stringify(SQL_FALSE);
15722 char *quote[2] = { NULL, NULL };
15723 static char tcodes[32 * 32];
15724
15725 if (tind <= 0) {
15726 tind = row;
15727 }
15728 tcode = tcodes + tind * 32;
15729 sprintf(tcode, "%d", type);
15730 s->rows[offs + 0] = typename;
15731 s->rows[offs + 1] = tcode;
15732 if (asize >= 17) {
15733 s->rows[offs + 15] = tcode;
15734 s->rows[offs + 16] = "0";
15735 }
15736 switch (type) {
15737 default:
15738 #ifdef SQL_LONGVARCHAR
15739 case SQL_LONGVARCHAR:
15740 #ifdef WINTERFACE
15741 case SQL_WLONGVARCHAR:
15742 #endif
15743 crpar = "length";
15744 quote[0] = quote[1] = "'";
15745 sign = NULL;
15746 s->rows[offs + 2] = "65536";
15747 break;
15748 #endif
15749 #ifdef SQL_BIT
15750 case SQL_BIT:
15751 sign = NULL;
15752 s->rows[offs + 2] = "1";
15753 break;
15754 #endif
15755 case SQL_CHAR:
15756 case SQL_VARCHAR:
15757 #ifdef WINTERFACE
15758 case SQL_WCHAR:
15759 case SQL_WVARCHAR:
15760 #endif
15761 s->rows[offs + 2] = "255";
15762 crpar = "length";
15763 quote[0] = quote[1] = "'";
15764 sign = NULL;
15765 break;
15766 case SQL_TINYINT:
15767 s->rows[offs + 2] = "3";
15768 break;
15769 case SQL_SMALLINT:
15770 s->rows[offs + 2] = "5";
15771 break;
15772 case SQL_INTEGER:
15773 s->rows[offs + 2] = "9";
15774 break;
15775 #ifdef SQL_BIGINT
15776 case SQL_BIGINT:
15777 s->rows[offs + 2] = "19";
15778 break;
15779 #endif
15780 case SQL_FLOAT:
15781 s->rows[offs + 2] = "7";
15782 break;
15783 case SQL_DOUBLE:
15784 s->rows[offs + 2] = "15";
15785 break;
15786 #ifdef SQL_TYPE_DATE
15787 case SQL_TYPE_DATE:
15788 #endif
15789 case SQL_DATE:
15790 s->rows[offs + 2] = "10";
15791 quote[0] = quote[1] = "'";
15792 sign = NULL;
15793 break;
15794 #ifdef SQL_TYPE_TIME
15795 case SQL_TYPE_TIME:
15796 #endif
15797 case SQL_TIME:
15798 s->rows[offs + 2] = "8";
15799 quote[0] = quote[1] = "'";
15800 sign = NULL;
15801 break;
15802 #ifdef SQL_TYPE_TIMESTAMP
15803 case SQL_TYPE_TIMESTAMP:
15804 #endif
15805 case SQL_TIMESTAMP:
15806 s->rows[offs + 2] = "32";
15807 quote[0] = quote[1] = "'";
15808 sign = NULL;
15809 break;
15810 case SQL_VARBINARY:
15811 quote[0] = "0x";
15812 sign = NULL;
15813 s->rows[offs + 2] = "255";
15814 break;
15815 case SQL_LONGVARBINARY:
15816 quote[0] = "0x";
15817 sign = NULL;
15818 s->rows[offs + 2] = "65536";
15819 break;
15820 }
15821 s->rows[offs + 3] = quote[0];
15822 s->rows[offs + 4] = quote[1];
15823 s->rows[offs + 5] = crpar;
15824 s->rows[offs + 6] = stringify(SQL_NULLABLE);
15825 s->rows[offs + 7] = stringify(SQL_FALSE);
15826 s->rows[offs + 8] = stringify(SQL_SEARCHABLE);
15827 s->rows[offs + 9] = sign;
15828 s->rows[offs + 10] = stringify(SQL_FALSE);
15829 s->rows[offs + 11] = stringify(SQL_FALSE);
15830 s->rows[offs + 12] = typename;
15831 switch (type) {
15832 case SQL_DATE:
15833 case SQL_TIME:
15834 s->rows[offs + 13] = "0";
15835 s->rows[offs + 14] = "0";
15836 break;
15837 #ifdef SQL_TYPE_TIMESTAMP
15838 case SQL_TYPE_TIMESTAMP:
15839 #endif
15840 case SQL_TIMESTAMP:
15841 s->rows[offs + 13] = "0";
15842 s->rows[offs + 14] = "3";
15843 break;
15844 default:
15845 s->rows[offs + 13] = NULL;
15846 s->rows[offs + 14] = NULL;
15847 break;
15848 }
15849 }
15850
15859 static int
15860 typeinfosort(const void *a, const void *b)
15861 {
15862 char **pa = (char **) a;
15863 char **pb = (char **) b;
15864 int na, nb;
15865
15866 na = strtol(pa[1], NULL, 0);
15867 nb = strtol(pb[1], NULL, 0);
15868 return na - nb;
15869 }
15870
15878 static SQLRETURN
15879 drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15880 {
15881 SQLRETURN ret;
15882 STMT *s;
15883 int asize;
15884
15885 ret = mkresultset(stmt, typeSpec2, array_size(typeSpec2),
15886 typeSpec3, array_size(typeSpec3), &asize);
15887 if (ret != SQL_SUCCESS) {
15888 return ret;
15889 }
15890 s = (STMT *) stmt;
15891 #ifdef SQL_LONGVARCHAR
15892 s->nrows = (sqltype == SQL_ALL_TYPES) ? 13 : 1;
15893 #else
15894 s->nrows = (sqltype == SQL_ALL_TYPES) ? 12 : 1;
15895 #endif
15896 if (sqltype == SQL_ALL_TYPES) {
15897 #ifdef WINTERFACE
15898 s->nrows += 2;
15899 #ifdef SQL_WLONGVARCHAR
15900 s->nrows += 2;
15901 #endif
15902 #endif
15903 }
15904 if (sqltype == SQL_ALL_TYPES) {
15905 s->nrows += 2;
15906 #ifdef SQL_BIT
15907 s->nrows += 1;
15908 #endif
15909 #ifdef SQL_BIGINT
15910 s->nrows += 1;
15911 #endif
15912 }
15913 s->rows = (char **) xmalloc(sizeof (char *) * (s->nrows + 1) * asize);
15914 if (!s->rows) {
15915 s->nrows = 0;
15916 return nomem(s);
15917 }
15918 #ifdef MEMORY_DEBUG
15919 s->rowfree = xfree__;
15920 #else
15921 s->rowfree = sqlite3_free;
15922 #endif
15923 memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
15924 if (sqltype == SQL_ALL_TYPES) {
15925 int cc = 1;
15926
15927 mktypeinfo(s, cc++, asize, "varchar", SQL_VARCHAR, 0);
15928 mktypeinfo(s, cc++, asize, "tinyint", SQL_TINYINT, 0);
15929 mktypeinfo(s, cc++, asize, "smallint", SQL_SMALLINT, 0);
15930 mktypeinfo(s, cc++, asize, "integer", SQL_INTEGER, 0);
15931 mktypeinfo(s, cc++, asize, "float", SQL_FLOAT, 0);
15932 mktypeinfo(s, cc++, asize, "double", SQL_DOUBLE, 0);
15933 #ifdef SQL_TYPE_DATE
15934 mktypeinfo(s, cc++, asize, "date",
15935 (*s->ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
15936 #else
15937 mktypeinfo(s, cc++, asize, "date", SQL_DATE, 0);
15938 #endif
15939 #ifdef SQL_TYPE_TIME
15940 mktypeinfo(s, cc++, asize, "time",
15941 (*s->ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
15942 #else
15943 mktypeinfo(s, cc++, asize, "time", SQL_TIME, 0);
15944 #endif
15945 #ifdef SQL_TYPE_TIMESTAMP
15946 mktypeinfo(s, cc++, asize, "timestamp",
15947 (*s->ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
15948 #else
15949 mktypeinfo(s, cc++, asize, "timestamp", SQL_TIMESTAMP, 0);
15950 #endif
15951 mktypeinfo(s, cc++, asize, "char", SQL_CHAR, 0);
15952 mktypeinfo(s, cc++, asize, "numeric", SQL_DOUBLE, 0);
15953 #ifdef SQL_LONGVARCHAR
15954 mktypeinfo(s, cc++, asize, "text", SQL_LONGVARCHAR, 0);
15955 mktypeinfo(s, cc++, asize, "longvarchar", SQL_LONGVARCHAR, 0);
15956 #else
15957 mktypeinfo(s, cc++, asize, "text", SQL_VARCHAR, 0);
15958 #endif
15959 mktypeinfo(s, cc++, asize, "varbinary", SQL_VARBINARY, 0);
15960 mktypeinfo(s, cc++, asize, "longvarbinary", SQL_LONGVARBINARY, 0);
15961 #ifdef SQL_BIT
15962 mktypeinfo(s, cc++, asize, "bit", SQL_BIT, 0);
15963 #endif
15964 #ifdef SQL_BIGINT
15965 mktypeinfo(s, cc++, asize, "bigint", SQL_BIGINT, 0);
15966 #endif
15967 #ifdef WINTERFACE
15968 mktypeinfo(s, cc++, asize, "wvarchar", SQL_WVARCHAR, 0);
15969 mktypeinfo(s, cc++, asize, "wchar", SQL_WCHAR, 0);
15970 #ifdef SQL_WLONGVARCHAR
15971 mktypeinfo(s, cc++, asize, "wtext", SQL_WLONGVARCHAR, 0);
15972 mktypeinfo(s, cc++, asize, "longwvarchar", SQL_WLONGVARCHAR, 0);
15973 #endif
15974 #endif
15975 qsort(s->rows + asize, s->nrows, sizeof (char *) * asize,
15976 typeinfosort);
15977 } else {
15978 switch (sqltype) {
15979 case SQL_CHAR:
15980 mktypeinfo(s, 1, asize, "char", SQL_CHAR, 10);
15981 break;
15982 case SQL_VARCHAR:
15983 mktypeinfo(s, 1, asize, "varchar", SQL_VARCHAR, 1);
15984 break;
15985 case SQL_TINYINT:
15986 mktypeinfo(s, 1, asize, "tinyint", SQL_TINYINT, 2);
15987 break;
15988 case SQL_SMALLINT:
15989 mktypeinfo(s, 1, asize, "smallint", SQL_SMALLINT, 3);
15990 break;
15991 case SQL_INTEGER:
15992 mktypeinfo(s, 1, asize, "integer", SQL_INTEGER, 4);
15993 break;
15994 case SQL_FLOAT:
15995 mktypeinfo(s, 1, asize, "float", SQL_FLOAT, 5);
15996 break;
15997 case SQL_DOUBLE:
15998 mktypeinfo(s, 1, asize, "double", SQL_DOUBLE, 6);
15999 break;
16000 #ifdef SQL_TYPE_DATE
16001 case SQL_TYPE_DATE:
16002 mktypeinfo(s, 1, asize, "date", SQL_TYPE_DATE, 25);
16003 break;
16004 #endif
16005 case SQL_DATE:
16006 mktypeinfo(s, 1, asize, "date", SQL_DATE, 7);
16007 break;
16008 #ifdef SQL_TYPE_TIME
16009 case SQL_TYPE_TIME:
16010 mktypeinfo(s, 1, asize, "time", SQL_TYPE_TIME, 26);
16011 break;
16012 #endif
16013 case SQL_TIME:
16014 mktypeinfo(s, 1, asize, "time", SQL_TIME, 8);
16015 break;
16016 #ifdef SQL_TYPE_TIMESTAMP
16017 case SQL_TYPE_TIMESTAMP:
16018 mktypeinfo(s, 1, asize, "timestamp", SQL_TYPE_TIMESTAMP, 27);
16019 break;
16020 #endif
16021 case SQL_TIMESTAMP:
16022 mktypeinfo(s, 1, asize, "timestamp", SQL_TIMESTAMP, 9);
16023 break;
16024 #ifdef SQL_LONGVARCHAR
16025 case SQL_LONGVARCHAR:
16026 mktypeinfo(s, 1, asize, "longvarchar", SQL_LONGVARCHAR, 12);
16027 break;
16028 #endif
16029 case SQL_VARBINARY:
16030 mktypeinfo(s, 1, asize, "varbinary", SQL_VARBINARY, 30);
16031 break;
16032 case SQL_LONGVARBINARY:
16033 mktypeinfo(s, 1, asize, "longvarbinary", SQL_LONGVARBINARY, 31);
16034 break;
16035 #ifdef SQL_BIT
16036 case SQL_BIT:
16037 mktypeinfo(s, 1, asize, "bit", SQL_BIT, 29);
16038 break;
16039 #endif
16040 #ifdef SQL_BIGINT
16041 case SQL_BIGINT:
16042 mktypeinfo(s, 1, asize, "bigint", SQL_BIGINT, 28);
16043 break;
16044 #endif
16045 #ifdef WINTERFACE
16046 #ifdef SQL_WCHAR
16047 case SQL_WCHAR:
16048 mktypeinfo(s, 1, asize, "wchar", SQL_WCHAR, 18);
16049 break;
16050 #endif
16051 #ifdef SQL_WVARCHAR
16052 case SQL_WVARCHAR:
16053 mktypeinfo(s, 1, asize, "wvarchar", SQL_WVARCHAR, 19);
16054 break;
16055 #endif
16056 #ifdef SQL_WLONGVARCHAR
16057 case SQL_WLONGVARCHAR:
16058 mktypeinfo(s, 1, asize, "longwvarchar", SQL_WLONGVARCHAR, 20);
16059 break;
16060 #endif
16061 #endif
16062 default:
16063 s->nrows = 0;
16064 }
16065 }
16066 return SQL_SUCCESS;
16067 }
16068
16069 #ifndef WINTERFACE
16070
16077 SQLRETURN SQL_API
16078 SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
16079 {
16080 SQLRETURN ret;
16081
16082 HSTMT_LOCK(stmt);
16083 ret = drvgettypeinfo(stmt, sqltype);
16084 HSTMT_UNLOCK(stmt);
16085 return ret;
16086 }
16087 #endif
16088
16089 #ifdef WINTERFACE
16090
16097 SQLRETURN SQL_API
16098 SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
16099 {
16100 SQLRETURN ret;
16101
16102 HSTMT_LOCK(stmt);
16103 ret = drvgettypeinfo(stmt, sqltype);
16104 HSTMT_UNLOCK(stmt);
16105 return ret;
16106 }
16107 #endif
16108
16113 static COL statSpec2[] = {
16114 { "SYSTEM", "STATISTICS", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
16115 { "SYSTEM", "STATISTICS", "TABLE_OWNER", SCOL_VARCHAR, 50 },
16116 { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
16117 { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
16118 { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
16119 { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
16120 { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
16121 { "SYSTEM", "STATISTICS", "SEQ_IN_INDEX", SQL_SMALLINT, 50 },
16122 { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
16123 { "SYSTEM", "STATISTICS", "COLLATION", SCOL_CHAR, 1 },
16124 { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
16125 { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
16126 { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
16127 };
16128
16129 static COL statSpec3[] = {
16130 { "SYSTEM", "STATISTICS", "TABLE_CAT", SCOL_VARCHAR, 50 },
16131 { "SYSTEM", "STATISTICS", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
16132 { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
16133 { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
16134 { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
16135 { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
16136 { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
16137 { "SYSTEM", "STATISTICS", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
16138 { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
16139 { "SYSTEM", "STATISTICS", "ASC_OR_DESC", SCOL_CHAR, 1 },
16140 { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
16141 { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
16142 { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
16143 };
16144
16159 static SQLRETURN
16160 drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16161 SQLCHAR *schema, SQLSMALLINT schemaLen,
16162 SQLCHAR *table, SQLSMALLINT tableLen,
16163 SQLUSMALLINT itype, SQLUSMALLINT resv)
16164 {
16165 SQLRETURN sret;
16166 STMT *s;
16167 DBC *d;
16168 int i, asize, ret, nrows, ncols, offs, namec, uniquec, addipk = 0;
16169 PTRDIFF_T size;
16170 char **rowp, *errp = NULL, *sql, tname[512];
16171
16172 sret = mkresultset(stmt, statSpec2, array_size(statSpec2),
16173 statSpec3, array_size(statSpec3), &asize);
16174 if (sret != SQL_SUCCESS) {
16175 return sret;
16176 }
16177 s = (STMT *) stmt;
16178 d = (DBC *) s->dbc;
16179 if (!table || table[0] == '\0' || table[0] == '%') {
16180 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
16181 return SQL_ERROR;
16182 }
16183 if (tableLen == SQL_NTS) {
16184 size = sizeof (tname) - 1;
16185 } else {
16186 size = min(sizeof (tname) - 1, tableLen);
16187 }
16188 strncpy(tname, (char *) table, size);
16189 tname[size] = '\0';
16190 unescpat(tname);
16191 sret = starttran(s);
16192 if (sret != SQL_SUCCESS) {
16193 return sret;
16194 }
16195
16196
16197
16198 if (itype == SQL_INDEX_UNIQUE || itype == SQL_INDEX_ALL) {
16199 rowp = 0;
16200 ret = SQLITE_ERROR;
16201 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16202 if (sql) {
16203 dbtraceapi(d, "sqlite3_get_table", sql);
16204 ret = sqlite3_get_table(d->sqlite, sql, &rowp,
16205 &nrows, &ncols, NULL);
16206 sqlite3_free(sql);
16207 }
16208 if (ret == SQLITE_OK) {
16209 int colid, typec, npk = 0, npkint = 0;
16210
16211 namec = findcol(rowp, ncols, "name");
16212 uniquec = findcol(rowp, ncols, "pk");
16213 typec = findcol(rowp, ncols, "type");
16214 colid = findcol(rowp, ncols, "cid");
16215 if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
16216 goto noipk;
16217 }
16218 for (i = 1; i <= nrows; i++) {
16219 if (*rowp[i * ncols + uniquec] != '0') {
16220 npk++;
16221 if (strlen(rowp[i * ncols + typec]) == 7 &&
16222 strncasecmp(rowp[i * ncols + typec], "integer", 7)
16223 == 0) {
16224 npkint++;
16225 }
16226 }
16227 }
16228 if (npkint == 1 && npk == npkint) {
16229 addipk = 1;
16230 }
16231 }
16232 noipk:
16233 sqlite3_free_table(rowp);
16234 }
16235 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
16236 if (!sql) {
16237 return nomem(s);
16238 }
16239 dbtraceapi(d, "sqlite3_get_table", sql);
16240 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
16241 sqlite3_free(sql);
16242 if (ret != SQLITE_OK) {
16243 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
16244 errp ? errp : "unknown error", ret);
16245 if (errp) {
16246 sqlite3_free(errp);
16247 errp = NULL;
16248 }
16249 return SQL_ERROR;
16250 }
16251 if (errp) {
16252 sqlite3_free(errp);
16253 errp = NULL;
16254 }
16255 size = 0;
16256 namec = findcol(rowp, ncols, "name");
16257 uniquec = findcol(rowp, ncols, "unique");
16258 if (namec < 0 || uniquec < 0) {
16259 goto nodata;
16260 }
16261 for (i = 1; i <= nrows; i++) {
16262 int nnrows, nncols;
16263 char **rowpp;
16264 int isuniq;
16265
16266 isuniq = *rowp[i * ncols + uniquec] != '0';
16267 if (isuniq || itype == SQL_INDEX_ALL) {
16268 ret = SQLITE_ERROR;
16269 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16270 rowp[i * ncols + namec]);
16271 if (sql) {
16272 dbtraceapi(d, "sqlite3_get_table", sql);
16273 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16274 &nnrows, &nncols, NULL);
16275 sqlite3_free(sql);
16276 }
16277 if (ret == SQLITE_OK) {
16278 size += nnrows;
16279 sqlite3_free_table(rowpp);
16280 }
16281 }
16282 }
16283 nodata:
16284 if (addipk) {
16285 size++;
16286 }
16287 if (size == 0) {
16288 sqlite3_free_table(rowp);
16289 return SQL_SUCCESS;
16290 }
16291 s->nrows = size;
16292 size = (size + 1) * asize;
16293 s->rows = xmalloc((size + 1) * sizeof (char *));
16294 if (!s->rows) {
16295 s->nrows = 0;
16296 return nomem(s);
16297 }
16298 s->rows[0] = (char *) size;
16299 s->rows += 1;
16300 memset(s->rows, 0, sizeof (char *) * size);
16301 s->rowfree = freerows;
16302 offs = 0;
16303 if (addipk) {
16304 char **rowpp = 0;
16305 int nrows2, ncols2;
16306
16307 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16308 if (sql) {
16309 dbtraceapi(d, "sqlite3_get_table", sql);
16310 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16311 &nrows2, &ncols2, NULL);
16312 sqlite3_free(sql);
16313 }
16314 if (ret == SQLITE_OK) {
16315 int colid, typec, roffs, namecc, uniquecc;
16316
16317 namecc = findcol(rowpp, ncols2, "name");
16318 uniquecc = findcol(rowpp, ncols2, "pk");
16319 typec = findcol(rowpp, ncols2, "type");
16320 colid = findcol(rowpp, ncols2, "cid");
16321 if (namecc < 0 || uniquecc < 0 || typec < 0 || colid < 0) {
16322 addipk = 0;
16323 s->nrows--;
16324 goto nodata2;
16325 }
16326 for (i = 1; i <= nrows2; i++) {
16327 if (*rowpp[i * ncols2 + uniquecc] != '0' &&
16328 strlen(rowpp[i * ncols2 + typec]) == 7 &&
16329 strncasecmp(rowpp[i * ncols2 + typec], "integer", 7)
16330 == 0) {
16331 break;
16332 }
16333 }
16334 if (i > nrows2) {
16335 addipk = 0;
16336 s->nrows--;
16337 goto nodata2;
16338 }
16339 roffs = s->ncols;
16340 #if defined(_WIN32) || defined(_WIN64)
16341 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
16342 s->rows[roffs + 1] = xstrdup("");
16343 #else
16344 s->rows[roffs + 0] = xstrdup("");
16345 s->rows[roffs + 1] = xstrdup("");
16346 #endif
16347 s->rows[roffs + 2] = xstrdup(tname);
16348 s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16349 s->rows[roffs + 5] = xstrdup("sqlite_autoindex_0");
16350 s->rows[roffs + 6] = xstrdup(stringify(SQL_INDEX_OTHER));
16351 s->rows[roffs + 7] = xstrdup("1");
16352 s->rows[roffs + 8] = xstrdup(rowpp[i * ncols2 + namecc]);
16353 s->rows[roffs + 9] = xstrdup("A");
16354 }
16355 nodata2:
16356 sqlite3_free_table(rowpp);
16357 }
16358 for (i = 1; i <= nrows; i++) {
16359 int nnrows, nncols;
16360 char **rowpp = 0;
16361
16362 if (*rowp[i * ncols + uniquec] != '0' || itype == SQL_INDEX_ALL) {
16363 int k;
16364
16365 ret = SQLITE_ERROR;
16366 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16367 rowp[i * ncols + namec]);
16368 if (sql) {
16369 dbtraceapi(d, "sqlite3_get_table", sql);
16370 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16371 &nnrows, &nncols, NULL);
16372 sqlite3_free(sql);
16373 }
16374 if (ret != SQLITE_OK) {
16375 continue;
16376 }
16377 for (k = 0; nnrows && k < nncols; k++) {
16378 if (strcmp(rowpp[k], "name") == 0) {
16379 int m;
16380
16381 for (m = 1; m <= nnrows; m++) {
16382 int roffs = (offs + addipk + m) * s->ncols;
16383 int isuniq;
16384
16385 isuniq = *rowp[i * ncols + uniquec] != '0';
16386 s->rows[roffs + 0] = xstrdup("");
16387 s->rows[roffs + 1] = xstrdup("");
16388 s->rows[roffs + 2] = xstrdup(tname);
16389 if (isuniq) {
16390 s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16391 } else {
16392 s->rows[roffs + 3] = xstrdup(stringify(SQL_TRUE));
16393 }
16394 s->rows[roffs + 5] = xstrdup(rowp[i * ncols + namec]);
16395 s->rows[roffs + 6] =
16396 xstrdup(stringify(SQL_INDEX_OTHER));
16397 s->rows[roffs + 8] = xstrdup(rowpp[m * nncols + k]);
16398 s->rows[roffs + 9] = xstrdup("A");
16399 }
16400 } else if (strcmp(rowpp[k], "seqno") == 0) {
16401 int m;
16402
16403 for (m = 1; m <= nnrows; m++) {
16404 int roffs = (offs + addipk + m) * s->ncols;
16405 int pos = m - 1;
16406 char buf[32];
16407
16408 sscanf(rowpp[m * nncols + k], "%d", &pos);
16409 sprintf(buf, "%d", pos + 1);
16410 s->rows[roffs + 7] = xstrdup(buf);
16411 }
16412 }
16413 }
16414 offs += nnrows;
16415 sqlite3_free_table(rowpp);
16416 }
16417 }
16418 sqlite3_free_table(rowp);
16419 return SQL_SUCCESS;
16420 }
16421
16422 #ifndef WINTERFACE
16423
16437 SQLRETURN SQL_API
16438 SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16439 SQLCHAR *schema, SQLSMALLINT schemaLen,
16440 SQLCHAR *table, SQLSMALLINT tableLen,
16441 SQLUSMALLINT itype, SQLUSMALLINT resv)
16442 {
16443 #if defined(_WIN32) || defined(_WIN64)
16444 char *c = NULL, *s = NULL, *t = NULL;
16445 #endif
16446 SQLRETURN ret;
16447
16448 HSTMT_LOCK(stmt);
16449 #if defined(_WIN32) || defined(_WIN64)
16450 if (!((STMT *) stmt)->oemcp[0]) {
16451 ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16452 table, tableLen, itype, resv);
16453 goto done2;
16454 }
16455 if (cat) {
16456 c = wmb_to_utf_c((char *) cat, catLen);
16457 if (!c) {
16458 ret = nomem((STMT *) stmt);
16459 goto done;
16460 }
16461 }
16462 if (schema) {
16463 s = wmb_to_utf_c((char *) schema, schemaLen);
16464 if (!s) {
16465 ret = nomem((STMT *) stmt);
16466 goto done;
16467 }
16468 }
16469 if (table) {
16470 t = wmb_to_utf_c((char *) table, tableLen);
16471 if (!t) {
16472 ret = nomem((STMT *) stmt);
16473 goto done;
16474 }
16475 }
16476 ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16477 (SQLCHAR *) t, SQL_NTS, itype, resv);
16478 #else
16479 ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16480 table, tableLen, itype, resv);
16481 #endif
16482 #if defined(_WIN32) || defined(_WIN64)
16483 done:
16484 uc_free(t);
16485 uc_free(s);
16486 uc_free(c);
16487 done2:
16488 ;
16489 #endif
16490 HSTMT_UNLOCK(stmt);
16491 return ret;
16492 }
16493 #endif
16494
16495 #ifdef WINTERFACE
16496
16510 SQLRETURN SQL_API
16511 SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
16512 SQLWCHAR *schema, SQLSMALLINT schemaLen,
16513 SQLWCHAR *table, SQLSMALLINT tableLen,
16514 SQLUSMALLINT itype, SQLUSMALLINT resv)
16515 {
16516 char *c = NULL, *s = NULL, *t = NULL;
16517 SQLRETURN ret;
16518
16519 HSTMT_LOCK(stmt);
16520 if (cat) {
16521 c = uc_to_utf_c(cat, catLen);
16522 if (!c) {
16523 ret = nomem((STMT *) stmt);
16524 goto done;
16525 }
16526 }
16527 if (schema) {
16528 s = uc_to_utf_c(schema, schemaLen);
16529 if (!s) {
16530 ret = nomem((STMT *) stmt);
16531 goto done;
16532 }
16533 }
16534 if (table) {
16535 t = uc_to_utf_c(table, tableLen);
16536 if (!t) {
16537 ret = nomem((STMT *) stmt);
16538 goto done;
16539 }
16540 }
16541 ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16542 (SQLCHAR *) t, SQL_NTS, itype, resv);
16543 done:
16544 uc_free(t);
16545 uc_free(s);
16546 uc_free(c);
16547 HSTMT_UNLOCK(stmt);
16548 return ret;
16549 }
16550 #endif
16551
16563 SQLRETURN SQL_API
16564 SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
16565 SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
16566 {
16567 STMT *s;
16568 SQLRETURN ret = SQL_ERROR;
16569
16570 HSTMT_LOCK(stmt);
16571 if (stmt == SQL_NULL_HSTMT) {
16572 return SQL_INVALID_HANDLE;
16573 }
16574 s = (STMT *) stmt;
16575 if (col == 0 && s->bkmrk != SQL_UB_OFF) {
16576 if (s->bkmrk == SQL_UB_ON && type == SQL_C_BOOKMARK) {
16577 *((SQLINTEGER *) val) = s->rowp;
16578 if (lenp) {
16579 *lenp = sizeof (SQLINTEGER);
16580 }
16581 ret = SQL_SUCCESS;
16582 goto done;
16583 } else if (s->bkmrk == SQL_UB_VARIABLE && type == SQL_C_VARBOOKMARK) {
16584 if (s->has_rowid >= 0) {
16585 char **data, *endp = 0;
16586
16587 data = s->rows + s->ncols + (s->rowp * s->ncols)
16588 + s->has_rowid;
16589 #ifdef __osf__
16590 *((sqlite_int64 *) val) = strtol(*data, &endp, 0);
16591 #else
16592 *((sqlite_int64 *) val) = strtoll(*data, &endp, 0);
16593 #endif
16594 } else {
16595 *((sqlite_int64 *) val) = s->rowp;
16596 }
16597 if (lenp) {
16598 *lenp = sizeof (sqlite_int64);
16599 }
16600 ret = SQL_SUCCESS;
16601 goto done;
16602 }
16603 }
16604 if (col < 1 || col > s->ncols) {
16605 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16606 goto done;
16607 }
16608 --col;
16609 ret = getrowdata(s, col, type, val, len, lenp, 1);
16610 done:
16611 HSTMT_UNLOCK(stmt);
16612 return ret;
16613 }
16614
16622 static SQLRETURN
16623 dofetchbind(STMT *s, int rsi)
16624 {
16625 int ret, i, withinfo = 0;
16626
16627 s->row_status0[rsi] = SQL_ROW_SUCCESS;
16628 if (s->bkmrk != SQL_UB_OFF && s->bkmrkcol.valp) {
16629 int bsize = sizeof (SQLINTEGER);
16630
16631 if (s->bkmrkcol.type == SQL_C_VARBOOKMARK) {
16632 SQLPOINTER *val;
16633
16634 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16635 val = (SQLPOINTER)
16636 ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16637 } else {
16638 val = (SQLPOINTER)
16639 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * rsi);
16640 }
16641 if (s->bind_offs) {
16642 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
16643 }
16644 if (s->has_rowid >= 0) {
16645 char **data, *endp = 0;
16646
16647 data = s->rows + s->ncols + (s->rowp * s->ncols)
16648 + s->has_rowid;
16649 #ifdef __osf__
16650 *(sqlite_int64 *) val = strtol(*data, &endp, 0);
16651 #else
16652 *(sqlite_int64 *) val = strtoll(*data, &endp, 0);
16653 #endif
16654 } else {
16655 *(sqlite_int64 *) val = s->rowp;
16656 }
16657 bsize = sizeof (sqlite_int64);
16658 } else {
16659 SQLINTEGER *val;
16660
16661 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16662 val = (SQLINTEGER *)
16663 ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16664 } else {
16665 val = (SQLINTEGER *) s->bkmrkcol.valp + rsi;
16666 }
16667 if (s->bind_offs) {
16668 val = (SQLINTEGER *) ((char *) val + *s->bind_offs);
16669 }
16670 *val = s->rowp;
16671 }
16672 if (s->bkmrkcol.lenp) {
16673 SQLLEN *ival;
16674
16675 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16676 ival = (SQLLEN *)
16677 ((char *) s->bkmrkcol.lenp + s->bind_type * rsi);
16678 } else {
16679 ival = &s->bkmrkcol.lenp[rsi];
16680 }
16681 if (s->bind_offs) {
16682 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
16683 }
16684 *ival = bsize;
16685 }
16686 }
16687 ret = SQL_SUCCESS;
16688 for (i = 0; s->bindcols && i < s->ncols; i++) {
16689 BINDCOL *b = &s->bindcols[i];
16690 SQLPOINTER dp = 0;
16691 SQLLEN *lp = 0;
16692
16693 b->offs = 0;
16694 if (b->valp) {
16695 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16696 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
16697 } else {
16698 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
16699 }
16700 if (s->bind_offs) {
16701 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
16702 }
16703 }
16704 if (b->lenp) {
16705 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16706 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
16707 } else {
16708 lp = b->lenp + rsi;
16709 }
16710 if (s->bind_offs) {
16711 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
16712 }
16713 }
16714 if (dp || lp) {
16715 ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp, b->max, lp, 0);
16716 if (!SQL_SUCCEEDED(ret)) {
16717 s->row_status0[rsi] = SQL_ROW_ERROR;
16718 break;
16719 }
16720 if (ret != SQL_SUCCESS) {
16721 withinfo = 1;
16722 #ifdef SQL_ROW_SUCCESS_WITH_INFO
16723 s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
16724 #endif
16725 }
16726 }
16727 }
16728 if (SQL_SUCCEEDED(ret)) {
16729 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16730 }
16731 return ret;
16732 }
16733
16742 static SQLRETURN
16743 drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
16744 {
16745 STMT *s;
16746 int i, withinfo = 0;
16747 SQLRETURN ret;
16748
16749 if (stmt == SQL_NULL_HSTMT) {
16750 return SQL_INVALID_HANDLE;
16751 }
16752 s = (STMT *) stmt;
16753 for (i = 0; i < s->rowset_size; i++) {
16754 s->row_status0[i] = SQL_ROW_NOROW;
16755 }
16756 if (s->row_status) {
16757 memcpy(s->row_status, s->row_status0,
16758 sizeof (SQLUSMALLINT) * s->rowset_size);
16759 }
16760 s->row_count0 = 0;
16761 if (s->row_count) {
16762 *s->row_count = s->row_count0;
16763 }
16764 if (!s->bindcols) {
16765 for (i = 0; i < s->rowset_size; i++) {
16766 s->row_status0[i] = SQL_ROW_ERROR;
16767 }
16768 ret = SQL_ERROR;
16769 i = 0;
16770 goto done2;
16771 }
16772 if (s->isselect != 1 && s->isselect != -1) {
16773 if (s->isselect != 0 || s->ncols <= 0) {
16774 setstat(s, -1, "no result set available", "24000");
16775 ret = SQL_ERROR;
16776 i = s->nrows;
16777 goto done2;
16778 } else {
16779
16780 }
16781 }
16782 if (s->curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
16783 setstat(s, -1, "wrong fetch direction", "01000");
16784 ret = SQL_ERROR;
16785 i = 0;
16786 goto done2;
16787 }
16788 ret = SQL_SUCCESS;
16789 i = 0;
16790 if (((DBC *) (s->dbc))->cur_s3stmt == s && s->s3stmt) {
16791 s->rowp = s->rowprs = 0;
16792 for (; i < s->rowset_size; i++) {
16793 if (s->max_rows && s->s3stmt_rownum + 1 >= s->max_rows) {
16794 ret = (i == 0) ? SQL_NO_DATA : SQL_SUCCESS;
16795 break;
16796 }
16797 ret = s3stmt_step(s);
16798 if (ret != SQL_SUCCESS) {
16799 s->row_status0[i] = SQL_ROW_ERROR;
16800 break;
16801 }
16802 if (s->nrows < 1) {
16803 break;
16804 }
16805 ret = dofetchbind(s, i);
16806 if (!SQL_SUCCEEDED(ret)) {
16807 break;
16808 } else if (ret == SQL_SUCCESS_WITH_INFO) {
16809 withinfo = 1;
16810 }
16811 }
16812 } else if (s->rows) {
16813 switch (orient) {
16814 case SQL_FETCH_NEXT:
16815 if (s->nrows < 1) {
16816 return SQL_NO_DATA;
16817 }
16818 if (s->rowp < 0) {
16819 s->rowp = -1;
16820 }
16821 if (s->rowp >= s->nrows) {
16822 s->rowp = s->rowprs = s->nrows;
16823 return SQL_NO_DATA;
16824 }
16825 break;
16826 case SQL_FETCH_PRIOR:
16827 if (s->nrows < 1 || s->rowp <= 0) {
16828 s->rowp = s->rowprs = -1;
16829 return SQL_NO_DATA;
16830 }
16831 s->rowp -= s->rowset_size + 1;
16832 if (s->rowp < -1) {
16833 s->rowp = s->rowprs = -1;
16834 return SQL_NO_DATA;
16835 }
16836 break;
16837 case SQL_FETCH_FIRST:
16838 if (s->nrows < 1) {
16839 return SQL_NO_DATA;
16840 }
16841 s->rowp = -1;
16842 break;
16843 case SQL_FETCH_LAST:
16844 if (s->nrows < 1) {
16845 return SQL_NO_DATA;
16846 }
16847 s->rowp = s->nrows - s->rowset_size;
16848 if (--s->rowp < -1) {
16849 s->rowp = -1;
16850 }
16851 break;
16852 case SQL_FETCH_ABSOLUTE:
16853 if (offset == 0) {
16854 s->rowp = s->rowprs = -1;
16855 return SQL_NO_DATA;
16856 } else if (offset < 0) {
16857 if (0 - offset <= s->nrows) {
16858 s->rowp = s->nrows + offset - 1;
16859 break;
16860 }
16861 s->rowp = s->rowprs = -1;
16862 return SQL_NO_DATA;
16863 } else if (offset > s->nrows) {
16864 s->rowp = s->rowprs = s->nrows;
16865 return SQL_NO_DATA;
16866 }
16867 s->rowp = offset - 1 - 1;
16868 break;
16869 case SQL_FETCH_RELATIVE:
16870 if (offset >= 0) {
16871 s->rowp += offset * s->rowset_size - 1;
16872 if (s->rowp >= s->nrows) {
16873 s->rowp = s->rowprs = s->nrows;
16874 return SQL_NO_DATA;
16875 }
16876 } else {
16877 s->rowp += offset * s->rowset_size - 1;
16878 if (s->rowp < -1) {
16879 s->rowp = s->rowprs = -1;
16880 return SQL_NO_DATA;
16881 }
16882 }
16883 break;
16884 case SQL_FETCH_BOOKMARK:
16885 if (s->bkmrk == SQL_UB_ON && !s->bkmrkptr) {
16886 if (offset < 0 || offset >= s->nrows) {
16887 return SQL_NO_DATA;
16888 }
16889 s->rowp = offset - 1;
16890 break;
16891 }
16892 if (s->bkmrk != SQL_UB_OFF && s->bkmrkptr) {
16893 int rowp;
16894
16895 if (s->bkmrk == SQL_UB_VARIABLE) {
16896 if (s->has_rowid >= 0) {
16897 sqlite_int64 bkmrk, rowid;
16898
16899 bkmrk = *(sqlite_int64 *) s->bkmrkptr;
16900 for (rowp = 0; rowp < s->nrows; rowp++) {
16901 char **data, *endp = 0;
16902
16903 data = s->rows + s->ncols + (rowp * s->ncols)
16904 + s->has_rowid;
16905 #ifdef __osf__
16906 rowid = strtol(*data, &endp, 0);
16907 #else
16908 rowid = strtoll(*data, &endp, 0);
16909 #endif
16910 if (rowid == bkmrk) {
16911 break;
16912 }
16913 }
16914 } else {
16915 rowp = *(sqlite_int64 *) s->bkmrkptr;
16916 }
16917 } else {
16918 rowp = *(int *) s->bkmrkptr;
16919 }
16920 if (rowp + offset < 0 || rowp + offset >= s->nrows) {
16921 return SQL_NO_DATA;
16922 }
16923 s->rowp = rowp + offset - 1;
16924 break;
16925 }
16926
16927 default:
16928 s->row_status0[0] = SQL_ROW_ERROR;
16929 ret = SQL_ERROR;
16930 goto done;
16931 }
16932 s->rowprs = s->rowp + 1;
16933 for (; i < s->rowset_size; i++) {
16934 ++s->rowp;
16935 if (s->rowp < 0 || s->rowp >= s->nrows) {
16936 break;
16937 }
16938 ret = dofetchbind(s, i);
16939 if (!SQL_SUCCEEDED(ret)) {
16940 break;
16941 } else if (ret == SQL_SUCCESS_WITH_INFO) {
16942 withinfo = 1;
16943 }
16944 }
16945 }
16946 done:
16947 if (i == 0) {
16948 if (SQL_SUCCEEDED(ret)) {
16949 return SQL_NO_DATA;
16950 }
16951 return ret;
16952 }
16953 if (SQL_SUCCEEDED(ret)) {
16954 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16955 }
16956 done2:
16957 if (s->row_status) {
16958 memcpy(s->row_status, s->row_status0,
16959 sizeof (SQLUSMALLINT) * s->rowset_size);
16960 }
16961 s->row_count0 = i;
16962 if (s->row_count) {
16963 *s->row_count = s->row_count0;
16964 }
16965 return ret;
16966 }
16967
16974 SQLRETURN SQL_API
16975 SQLFetch(SQLHSTMT stmt)
16976 {
16977 SQLRETURN ret;
16978
16979 HSTMT_LOCK(stmt);
16980 ret = drvfetchscroll(stmt, SQL_FETCH_NEXT, 0);
16981 HSTMT_UNLOCK(stmt);
16982 return ret;
16983 }
16984
16993 SQLRETURN SQL_API
16994 SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
16995 {
16996 SQLRETURN ret;
16997
16998 HSTMT_LOCK(stmt);
16999 ret = drvfetchscroll(stmt, orient, offset);
17000 HSTMT_UNLOCK(stmt);
17001 return ret;
17002 }
17003
17014 SQLRETURN SQL_API
17015 SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset,
17016 SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
17017 {
17018 STMT *s;
17019 SQLRETURN ret;
17020 SQLUSMALLINT *rst;
17021 SQLINTEGER *bkmrkptr;
17022
17023 HSTMT_LOCK(stmt);
17024 if (stmt == SQL_NULL_HSTMT) {
17025 return SQL_INVALID_HANDLE;
17026 }
17027 s = (STMT *) stmt;
17028
17029 rst = s->row_status;
17030 s->row_status = 0;
17031 bkmrkptr = s->bkmrkptr;
17032 s->bkmrkptr = 0;
17033 ret = drvfetchscroll(stmt, orient, offset);
17034 s->row_status = rst;
17035 s->bkmrkptr = bkmrkptr;
17036 if (rowstatus) {
17037 memcpy(rowstatus, s->row_status0,
17038 sizeof (SQLUSMALLINT) * s->rowset_size);
17039 }
17040 if (rowcount) {
17041 *rowcount = s->row_count0;
17042 }
17043 HSTMT_UNLOCK(stmt);
17044 return ret;
17045 }
17046
17054 SQLRETURN SQL_API
17055 SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
17056 {
17057 STMT *s;
17058
17059 HSTMT_LOCK(stmt);
17060 if (stmt == SQL_NULL_HSTMT) {
17061 return SQL_INVALID_HANDLE;
17062 }
17063 s = (STMT *) stmt;
17064 if (nrows) {
17065 *nrows = s->isselect ? 0 : s->nrows;
17066 }
17067 HSTMT_UNLOCK(stmt);
17068 return SQL_SUCCESS;
17069 }
17070
17078 SQLRETURN SQL_API
17079 SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
17080 {
17081 STMT *s;
17082
17083 HSTMT_LOCK(stmt);
17084 if (stmt == SQL_NULL_HSTMT) {
17085 return SQL_INVALID_HANDLE;
17086 }
17087 s = (STMT *) stmt;
17088 if (ncols) {
17089 *ncols = s->ncols;
17090 }
17091 HSTMT_UNLOCK(stmt);
17092 return SQL_SUCCESS;
17093 }
17094
17109 static SQLRETURN
17110 drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
17111 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17112 SQLSMALLINT *type, SQLULEN *size,
17113 SQLSMALLINT *digits, SQLSMALLINT *nullable)
17114 {
17115 STMT *s;
17116 COL *c;
17117 int didname = 0;
17118
17119 if (stmt == SQL_NULL_HSTMT) {
17120 return SQL_INVALID_HANDLE;
17121 }
17122 s = (STMT *) stmt;
17123 if (!s->cols) {
17124 setstat(s, -1, "no columns", (*s->ov3) ? "07009" : "S1002");
17125 return SQL_ERROR;
17126 }
17127 if (col < 1 || col > s->ncols) {
17128 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17129 return SQL_ERROR;
17130 }
17131 c = s->cols + col - 1;
17132 if (name && nameMax > 0) {
17133 strncpy((char *) name, c->column, nameMax);
17134 name[nameMax - 1] = '\0';
17135 didname = 1;
17136 }
17137 if (nameLen) {
17138 if (didname) {
17139 *nameLen = strlen((char *) name);
17140 } else {
17141 *nameLen = strlen(c->column);
17142 }
17143 }
17144 if (type) {
17145 *type = c->type;
17146 #ifdef WINTERFACE
17147 if (s->nowchar[0] || s->nowchar[1]) {
17148 switch (c->type) {
17149 case SQL_WCHAR:
17150 *type = SQL_CHAR;
17151 break;
17152 case SQL_WVARCHAR:
17153 *type = SQL_VARCHAR;
17154 break;
17155 #ifdef SQL_LONGVARCHAR
17156 case SQL_WLONGVARCHAR:
17157 *type = SQL_LONGVARCHAR;
17158 break;
17159 #endif
17160 }
17161 }
17162 #endif
17163 }
17164 if (size) {
17165 *size = c->size;
17166 }
17167 if (digits) {
17168 *digits = 0;
17169 }
17170 if (nullable) {
17171 *nullable = 1;
17172 }
17173 return SQL_SUCCESS;
17174 }
17175
17176 #ifndef WINTERFACE
17177
17191 SQLRETURN SQL_API
17192 SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
17193 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17194 SQLSMALLINT *type, SQLULEN *size,
17195 SQLSMALLINT *digits, SQLSMALLINT *nullable)
17196 {
17197 #if defined(_WIN32) || defined(_WIN64)
17198 SQLSMALLINT len = 0;
17199 #endif
17200 SQLRETURN ret;
17201
17202 HSTMT_LOCK(stmt);
17203 #if defined(_WIN32) || defined(_WIN64)
17204 if (!((STMT *) stmt)->oemcp[0]) {
17205 ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
17206 type, size, digits, nullable);
17207 goto done;
17208 }
17209 ret = drvdescribecol(stmt, col, name, nameMax,
17210 &len, type, size, digits, nullable);
17211 if (ret == SQL_SUCCESS) {
17212 if (name) {
17213 if (len > 0) {
17214 SQLCHAR *n = NULL;
17215
17216 n = (SQLCHAR *) utf_to_wmb((char *) name, len);
17217 if (n) {
17218 strncpy((char *) name, (char *) n, nameMax);
17219 n[len] = 0;
17220 len = min(nameMax, strlen((char *) n));
17221 uc_free(n);
17222 } else {
17223 len = 0;
17224 }
17225 }
17226 if (len <= 0) {
17227 len = 0;
17228 if (nameMax > 0) {
17229 name[0] = 0;
17230 }
17231 }
17232 } else {
17233 STMT *s = (STMT *) stmt;
17234 COL *c = s->cols + col - 1;
17235
17236 len = 0;
17237 if (c->column) {
17238 len = strlen(c->column);
17239 }
17240 }
17241 if (nameLen) {
17242 *nameLen = len;
17243 }
17244 }
17245 done:
17246 ;
17247 #else
17248 ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
17249 type, size, digits, nullable);
17250 #endif
17251 HSTMT_UNLOCK(stmt);
17252 return ret;
17253 }
17254 #endif
17255
17256 #ifdef WINTERFACE
17257
17271 SQLRETURN SQL_API
17272 SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
17273 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
17274 SQLSMALLINT *type, SQLULEN *size,
17275 SQLSMALLINT *digits, SQLSMALLINT *nullable)
17276 {
17277 SQLRETURN ret;
17278 SQLSMALLINT len = 0;
17279
17280 HSTMT_LOCK(stmt);
17281 ret = drvdescribecol(stmt, col, (SQLCHAR *) name,
17282 (SQLSMALLINT) (nameMax * sizeof (SQLWCHAR)),
17283 &len, type, size, digits, nullable);
17284 if (ret == SQL_SUCCESS) {
17285 if (name) {
17286 if (len > 0) {
17287 SQLWCHAR *n = NULL;
17288
17289 n = uc_from_utf((SQLCHAR *) name, len);
17290 if (n) {
17291 uc_strncpy(name, n, nameMax);
17292 n[len] = 0;
17293 len = min(nameMax, uc_strlen(n));
17294 uc_free(n);
17295 } else {
17296 len = 0;
17297 }
17298 }
17299 if (len <= 0) {
17300 len = 0;
17301 if (nameMax > 0) {
17302 name[0] = 0;
17303 }
17304 }
17305 } else {
17306 STMT *s = (STMT *) stmt;
17307 COL *c = s->cols + col - 1;
17308
17309 len = 0;
17310 if (c->column) {
17311 len = strlen(c->column);
17312 }
17313 }
17314 if (nameLen) {
17315 *nameLen = len;
17316 }
17317 }
17318 HSTMT_UNLOCK(stmt);
17319 return ret;
17320 }
17321 #endif
17322
17335 static SQLRETURN
17336 drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17337 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17338 SQLLEN *val2)
17339 {
17340 STMT *s;
17341 COL *c;
17342 SQLSMALLINT dummy;
17343 char *valc = (char *) val;
17344
17345 if (stmt == SQL_NULL_HSTMT) {
17346 return SQL_INVALID_HANDLE;
17347 }
17348 s = (STMT *) stmt;
17349 if (!s->cols) {
17350 return SQL_ERROR;
17351 }
17352 if (!valLen) {
17353 valLen = &dummy;
17354 }
17355 if (id == SQL_COLUMN_COUNT) {
17356 if (val2) {
17357 *val2 = s->ncols;
17358 }
17359 *valLen = sizeof (int);
17360 return SQL_SUCCESS;
17361 }
17362 if (id == SQL_COLUMN_TYPE && col == 0) {
17363 if (val2) {
17364 *val2 = SQL_INTEGER;
17365 }
17366 *valLen = sizeof (int);
17367 return SQL_SUCCESS;
17368 }
17369 #ifdef SQL_DESC_OCTET_LENGTH
17370 if (id == SQL_DESC_OCTET_LENGTH && col == 0) {
17371 if (val2) {
17372 *val2 = 4;
17373 }
17374 *valLen = sizeof (int);
17375 return SQL_SUCCESS;
17376 }
17377 #endif
17378 if (col < 1 || col > s->ncols) {
17379 setstat(s, -1, "invalid column", (*s->ov3) ? "07009": "S1002");
17380 return SQL_ERROR;
17381 }
17382 c = s->cols + col - 1;
17383
17384 switch (id) {
17385 case SQL_COLUMN_LABEL:
17386 if (c->label) {
17387 if (valc && valMax > 0) {
17388 strncpy(valc, c->label, valMax);
17389 valc[valMax - 1] = '\0';
17390 }
17391 *valLen = strlen(c->label);
17392 goto checkLen;
17393 }
17394
17395 case SQL_COLUMN_NAME:
17396 case SQL_DESC_NAME:
17397 if (valc && valMax > 0) {
17398 strncpy(valc, c->column, valMax);
17399 valc[valMax - 1] = '\0';
17400 }
17401 *valLen = strlen(c->column);
17402 checkLen:
17403 if (*valLen >= valMax) {
17404 setstat(s, -1, "data right truncated", "01004");
17405 return SQL_SUCCESS_WITH_INFO;
17406 }
17407 return SQL_SUCCESS;
17408 #ifdef SQL_DESC_BASE_COLUMN_NAME
17409 case SQL_DESC_BASE_COLUMN_NAME:
17410 if (strchr(c->column, '(') || strchr(c->column, ')')) {
17411 if (valc && valMax > 0) {
17412 valc[0] = '\0';
17413 }
17414 *valLen = 0;
17415 } else if (valc && valMax > 0) {
17416 strncpy(valc, c->column, valMax);
17417 valc[valMax - 1] = '\0';
17418 *valLen = strlen(c->column);
17419 }
17420 goto checkLen;
17421 #endif
17422 case SQL_COLUMN_TYPE:
17423 case SQL_DESC_TYPE:
17424 #ifdef WINTERFACE
17425 {
17426 int type = c->type;
17427
17428 if (s->nowchar[0] || s->nowchar[1]) {
17429 switch (type) {
17430 case SQL_WCHAR:
17431 type = SQL_CHAR;
17432 break;
17433 case SQL_WVARCHAR:
17434 type = SQL_VARCHAR;
17435 break;
17436 #ifdef SQL_LONGVARCHAR
17437 case SQL_WLONGVARCHAR:
17438 type = SQL_LONGVARCHAR;
17439 break;
17440 }
17441 }
17442 if (val2) {
17443 *val2 = type;
17444 }
17445 #endif
17446 }
17447 #else
17448 if (val2) {
17449 *val2 = c->type;
17450 }
17451 #endif
17452 *valLen = sizeof (int);
17453 return SQL_SUCCESS;
17454 case SQL_COLUMN_DISPLAY_SIZE:
17455 if (val2) {
17456 *val2 = c->size;
17457 }
17458 *valLen = sizeof (int);
17459 return SQL_SUCCESS;
17460 case SQL_COLUMN_UNSIGNED:
17461 if (val2) {
17462 *val2 = c->nosign ? SQL_TRUE : SQL_FALSE;
17463 }
17464 *valLen = sizeof (int);
17465 return SQL_SUCCESS;
17466 case SQL_COLUMN_SCALE:
17467 case SQL_DESC_SCALE:
17468 if (val2) {
17469 *val2 = c->scale;
17470 }
17471 *valLen = sizeof (int);
17472 return SQL_SUCCESS;
17473 case SQL_COLUMN_PRECISION:
17474 case SQL_DESC_PRECISION:
17475 if (val2) {
17476 switch (c->type) {
17477 case SQL_SMALLINT:
17478 *val2 = 5;
17479 break;
17480 case SQL_INTEGER:
17481 *val2 = 10;
17482 break;
17483 case SQL_FLOAT:
17484 case SQL_REAL:
17485 case SQL_DOUBLE:
17486 *val2 = 15;
17487 break;
17488 case SQL_DATE:
17489 *val2 = 0;
17490 break;
17491 case SQL_TIME:
17492 *val2 = 0;
17493 break;
17494 #ifdef SQL_TYPE_TIMESTAMP
17495 case SQL_TYPE_TIMESTAMP:
17496 #endif
17497 case SQL_TIMESTAMP:
17498 *val2 = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17499 break;
17500 default:
17501 *val2 = c->prec;
17502 break;
17503 }
17504 }
17505 *valLen = sizeof (int);
17506 return SQL_SUCCESS;
17507 case SQL_COLUMN_MONEY:
17508 if (val2) {
17509 *val2 = SQL_FALSE;
17510 }
17511 *valLen = sizeof (int);
17512 return SQL_SUCCESS;
17513 case SQL_COLUMN_AUTO_INCREMENT:
17514 if (val2) {
17515 *val2 = c->autoinc;
17516 }
17517 *valLen = sizeof (int);
17518 return SQL_SUCCESS;
17519 case SQL_COLUMN_LENGTH:
17520 case SQL_DESC_LENGTH:
17521 if (val2) {
17522 *val2 = c->size;
17523 }
17524 *valLen = sizeof (int);
17525 return SQL_SUCCESS;
17526 case SQL_COLUMN_NULLABLE:
17527 case SQL_DESC_NULLABLE:
17528 if (val2) {
17529 *val2 = c->notnull;
17530 }
17531 *valLen = sizeof (int);
17532 return SQL_SUCCESS;
17533 case SQL_COLUMN_SEARCHABLE:
17534 if (val2) {
17535 *val2 = SQL_SEARCHABLE;
17536 }
17537 *valLen = sizeof (int);
17538 return SQL_SUCCESS;
17539 case SQL_COLUMN_CASE_SENSITIVE:
17540 if (val2) {
17541 *val2 = SQL_TRUE;
17542 }
17543 *valLen = sizeof (int);
17544 return SQL_SUCCESS;
17545 case SQL_COLUMN_UPDATABLE:
17546 if (val2) {
17547 *val2 = SQL_TRUE;
17548 }
17549 *valLen = sizeof (int);
17550 return SQL_SUCCESS;
17551 case SQL_DESC_COUNT:
17552 if (val2) {
17553 *val2 = s->ncols;
17554 }
17555 *valLen = sizeof (int);
17556 return SQL_SUCCESS;
17557 case SQL_COLUMN_TYPE_NAME: {
17558 char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17559
17560 #ifdef WINTERFACE
17561 if (c->type == SQL_WCHAR ||
17562 c->type == SQL_WVARCHAR ||
17563 c->type == SQL_WLONGVARCHAR) {
17564 if (!(s->nowchar[0] || s->nowchar[1])) {
17565 if (strcasecmp(tn, "varchar") == 0) {
17566 tn = "wvarchar";
17567 }
17568 }
17569 }
17570 #endif
17571 if (valc && valMax > 0) {
17572 strncpy(valc, tn, valMax);
17573 valc[valMax - 1] = '\0';
17574 p = strchr(valc, '(');
17575 if (p) {
17576 *p = '\0';
17577 while (p > valc && ISSPACE(p[-1])) {
17578 --p;
17579 *p = '\0';
17580 }
17581 }
17582 *valLen = strlen(valc);
17583 } else {
17584 *valLen = strlen(tn);
17585 p = strchr(tn, '(');
17586 if (p) {
17587 *valLen = p - tn;
17588 while (p > tn && ISSPACE(p[-1])) {
17589 --p;
17590 *valLen -= 1;
17591 }
17592 }
17593 }
17594 goto checkLen;
17595 }
17596 case SQL_COLUMN_OWNER_NAME:
17597 case SQL_COLUMN_QUALIFIER_NAME: {
17598 char *z = "";
17599
17600 if (valc && valMax > 0) {
17601 strncpy(valc, z, valMax);
17602 valc[valMax - 1] = '\0';
17603 }
17604 *valLen = strlen(z);
17605 goto checkLen;
17606 }
17607 case SQL_COLUMN_TABLE_NAME:
17608 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17609 case SQL_DESC_TABLE_NAME:
17610 #endif
17611 #ifdef SQL_DESC_BASE_TABLE_NAME
17612 case SQL_DESC_BASE_TABLE_NAME:
17613 #endif
17614 if (valc && valMax > 0) {
17615 strncpy(valc, c->table, valMax);
17616 valc[valMax - 1] = '\0';
17617 }
17618 *valLen = strlen(c->table);
17619 goto checkLen;
17620 #ifdef SQL_DESC_NUM_PREC_RADIX
17621 case SQL_DESC_NUM_PREC_RADIX:
17622 if (val2) {
17623 switch (c->type) {
17624 #ifdef WINTERFACE
17625 case SQL_WCHAR:
17626 case SQL_WVARCHAR:
17627 #ifdef SQL_LONGVARCHAR
17628 case SQL_WLONGVARCHAR:
17629 #endif
17630 #endif
17631 case SQL_CHAR:
17632 case SQL_VARCHAR:
17633 #ifdef SQL_LONGVARCHAR
17634 case SQL_LONGVARCHAR:
17635 #endif
17636 case SQL_BINARY:
17637 case SQL_VARBINARY:
17638 case SQL_LONGVARBINARY:
17639 *val2 = 0;
17640 break;
17641 default:
17642 *val2 = 2;
17643 }
17644 }
17645 *valLen = sizeof (int);
17646 return SQL_SUCCESS;
17647 #endif
17648 }
17649 setstat(s, -1, "unsupported column attributes %d", "HY091", id);
17650 return SQL_ERROR;
17651 }
17652
17653 #ifndef WINTERFACE
17654
17666 SQLRETURN SQL_API
17667 SQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17668 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17669 SQLLEN *val2)
17670 {
17671 #if defined(_WIN32) || defined(_WIN64)
17672 SQLSMALLINT len = 0;
17673 #endif
17674 SQLRETURN ret;
17675
17676 HSTMT_LOCK(stmt);
17677 #if defined(_WIN32) || defined(_WIN64)
17678 if (!((STMT *) stmt)->oemcp[0]) {
17679 ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17680 goto done;
17681 }
17682 ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17683 if (SQL_SUCCEEDED(ret)) {
17684 char *v = NULL;
17685
17686 switch (id) {
17687 case SQL_COLUMN_LABEL:
17688 case SQL_COLUMN_NAME:
17689 case SQL_DESC_NAME:
17690 case SQL_COLUMN_TYPE_NAME:
17691 case SQL_COLUMN_OWNER_NAME:
17692 case SQL_COLUMN_QUALIFIER_NAME:
17693 case SQL_COLUMN_TABLE_NAME:
17694 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17695 case SQL_DESC_TABLE_NAME:
17696 #endif
17697 #ifdef SQL_DESC_BASE_COLUMN_NAME
17698 case SQL_DESC_BASE_COLUMN_NAME:
17699 #endif
17700 #ifdef SQL_DESC_BASE_TABLE_NAME
17701 case SQL_DESC_BASE_TABLE_NAME:
17702 #endif
17703 if (val && valMax > 0) {
17704 int vmax = valMax;
17705
17706 v = utf_to_wmb((char *) val, SQL_NTS);
17707 if (v) {
17708 strncpy(val, v, vmax);
17709 len = min(vmax, strlen(v));
17710 uc_free(v);
17711 }
17712 if (vmax > 0) {
17713 v = (char *) val;
17714 v[vmax - 1] = '\0';
17715 }
17716 }
17717 if (len <= 0) {
17718 len = 0;
17719 }
17720 break;
17721 }
17722 if (valLen) {
17723 *valLen = len;
17724 }
17725 }
17726 done:
17727 ;
17728 #else
17729 ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17730 #endif
17731 HSTMT_UNLOCK(stmt);
17732 return ret;
17733 }
17734 #endif
17735
17736 #ifdef WINTERFACE
17737
17749 SQLRETURN SQL_API
17750 SQLColAttributesW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17751 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17752 SQLLEN *val2)
17753 {
17754 SQLRETURN ret;
17755 SQLSMALLINT len = 0;
17756
17757 HSTMT_LOCK(stmt);
17758 ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17759 if (SQL_SUCCEEDED(ret)) {
17760 SQLWCHAR *v = NULL;
17761
17762 switch (id) {
17763 case SQL_COLUMN_LABEL:
17764 case SQL_COLUMN_NAME:
17765 case SQL_DESC_NAME:
17766 case SQL_COLUMN_TYPE_NAME:
17767 case SQL_COLUMN_OWNER_NAME:
17768 case SQL_COLUMN_QUALIFIER_NAME:
17769 case SQL_COLUMN_TABLE_NAME:
17770 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17771 case SQL_DESC_TABLE_NAME:
17772 #endif
17773 #ifdef SQL_DESC_BASE_COLUMN_NAME
17774 case SQL_DESC_BASE_COLUMN_NAME:
17775 #endif
17776 #ifdef SQL_DESC_BASE_TABLE_NAME
17777 case SQL_DESC_BASE_TABLE_NAME:
17778 #endif
17779 if (val && valMax > 0) {
17780 int vmax = valMax / sizeof (SQLWCHAR);
17781
17782 v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17783 if (v) {
17784 uc_strncpy(val, v, vmax);
17785 len = min(vmax, uc_strlen(v));
17786 uc_free(v);
17787 len *= sizeof (SQLWCHAR);
17788 }
17789 if (vmax > 0) {
17790 v = (SQLWCHAR *) val;
17791 v[vmax - 1] = '\0';
17792 }
17793 }
17794 if (len <= 0) {
17795 len = 0;
17796 }
17797 break;
17798 }
17799 if (valLen) {
17800 *valLen = len;
17801 }
17802 }
17803 HSTMT_UNLOCK(stmt);
17804 return ret;
17805 }
17806 #endif
17807
17820 static SQLRETURN
17821 drvcolattribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17822 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17823 SQLPOINTER val2)
17824 {
17825 STMT *s;
17826 COL *c;
17827 int v = 0;
17828 char *valc = (char *) val;
17829 SQLSMALLINT dummy;
17830
17831 if (stmt == SQL_NULL_HSTMT) {
17832 return SQL_INVALID_HANDLE;
17833 }
17834 s = (STMT *) stmt;
17835 if (!s->cols) {
17836 return SQL_ERROR;
17837 }
17838 if (col < 1 || col > s->ncols) {
17839 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17840 return SQL_ERROR;
17841 }
17842 if (!valLen) {
17843 valLen = &dummy;
17844 }
17845 c = s->cols + col - 1;
17846 switch (id) {
17847 case SQL_DESC_COUNT:
17848 v = s->ncols;
17849 break;
17850 case SQL_DESC_CATALOG_NAME:
17851 if (valc && valMax > 0) {
17852 strncpy(valc, c->db, valMax);
17853 valc[valMax - 1] = '\0';
17854 }
17855 *valLen = strlen(c->db);
17856 checkLen:
17857 if (*valLen >= valMax) {
17858 setstat(s, -1, "data right truncated", "01004");
17859 return SQL_SUCCESS_WITH_INFO;
17860 }
17861 break;
17862 case SQL_COLUMN_LENGTH:
17863 case SQL_DESC_LENGTH:
17864 v = c->size;
17865 break;
17866 case SQL_COLUMN_LABEL:
17867 if (c->label) {
17868 if (valc && valMax > 0) {
17869 strncpy(valc, c->label, valMax);
17870 valc[valMax - 1] = '\0';
17871 }
17872 *valLen = strlen(c->label);
17873 goto checkLen;
17874 }
17875
17876 case SQL_COLUMN_NAME:
17877 case SQL_DESC_NAME:
17878 if (valc && valMax > 0) {
17879 strncpy(valc, c->column, valMax);
17880 valc[valMax - 1] = '\0';
17881 }
17882 *valLen = strlen(c->column);
17883 goto checkLen;
17884 case SQL_DESC_SCHEMA_NAME: {
17885 char *z = "";
17886
17887 if (valc && valMax > 0) {
17888 strncpy(valc, z, valMax);
17889 valc[valMax - 1] = '\0';
17890 }
17891 *valLen = strlen(z);
17892 goto checkLen;
17893 }
17894 #ifdef SQL_DESC_BASE_COLUMN_NAME
17895 case SQL_DESC_BASE_COLUMN_NAME:
17896 if (strchr(c->column, '(') || strchr(c->column, ')')) {
17897 valc[0] = '\0';
17898 *valLen = 0;
17899 } else if (valc && valMax > 0) {
17900 strncpy(valc, c->column, valMax);
17901 valc[valMax - 1] = '\0';
17902 *valLen = strlen(c->column);
17903 }
17904 goto checkLen;
17905 #endif
17906 case SQL_DESC_TYPE_NAME: {
17907 char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17908
17909 #ifdef WINTERFACE
17910 if (c->type == SQL_WCHAR ||
17911 c->type == SQL_WVARCHAR ||
17912 c->type == SQL_WLONGVARCHAR) {
17913 if (!(s->nowchar[0] || s->nowchar[1])) {
17914 if (strcasecmp(tn, "varchar") == 0) {
17915 tn = "wvarchar";
17916 }
17917 }
17918 }
17919 #endif
17920 if (valc && valMax > 0) {
17921 strncpy(valc, tn, valMax);
17922 valc[valMax - 1] = '\0';
17923 p = strchr(valc, '(');
17924 if (p) {
17925 *p = '\0';
17926 while (p > valc && ISSPACE(p[-1])) {
17927 --p;
17928 *p = '\0';
17929 }
17930 }
17931 *valLen = strlen(valc);
17932 } else {
17933 *valLen = strlen(tn);
17934 p = strchr(tn, '(');
17935 if (p) {
17936 *valLen = p - tn;
17937 while (p > tn && ISSPACE(p[-1])) {
17938 --p;
17939 *valLen -= 1;
17940 }
17941 }
17942 }
17943 goto checkLen;
17944 }
17945 case SQL_DESC_OCTET_LENGTH:
17946 v = c->size;
17947 #ifdef WINTERFACE
17948 if (c->type == SQL_WCHAR ||
17949 c->type == SQL_WVARCHAR ||
17950 c->type == SQL_WLONGVARCHAR) {
17951 if (!(s->nowchar[0] || s->nowchar[1])) {
17952 v *= sizeof (SQLWCHAR);
17953 }
17954 }
17955 #endif
17956 break;
17957 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17958 case SQL_COLUMN_TABLE_NAME:
17959 #endif
17960 #ifdef SQL_DESC_BASE_TABLE_NAME
17961 case SQL_DESC_BASE_TABLE_NAME:
17962 #endif
17963 case SQL_DESC_TABLE_NAME:
17964 if (valc && valMax > 0) {
17965 strncpy(valc, c->table, valMax);
17966 valc[valMax - 1] = '\0';
17967 }
17968 *valLen = strlen(c->table);
17969 goto checkLen;
17970 case SQL_DESC_TYPE:
17971 v = c->type;
17972 #ifdef WINTERFACE
17973 if (s->nowchar[0] || s->nowchar[1]) {
17974 switch (v) {
17975 case SQL_WCHAR:
17976 v = SQL_CHAR;
17977 break;
17978 case SQL_WVARCHAR:
17979 v = SQL_VARCHAR;
17980 break;
17981 #ifdef SQL_LONGVARCHAR
17982 case SQL_WLONGVARCHAR:
17983 v = SQL_LONGVARCHAR;
17984 break;
17985 #endif
17986 }
17987 }
17988 #endif
17989 break;
17990 case SQL_DESC_CONCISE_TYPE:
17991 switch (c->type) {
17992 case SQL_INTEGER:
17993 v = SQL_C_LONG;
17994 break;
17995 case SQL_TINYINT:
17996 v = SQL_C_TINYINT;
17997 break;
17998 case SQL_SMALLINT:
17999 v = SQL_C_SHORT;
18000 break;
18001 case SQL_FLOAT:
18002 v = SQL_C_FLOAT;
18003 break;
18004 case SQL_DOUBLE:
18005 v = SQL_C_DOUBLE;
18006 break;
18007 case SQL_TIMESTAMP:
18008 v = SQL_C_TIMESTAMP;
18009 break;
18010 case SQL_TIME:
18011 v = SQL_C_TIME;
18012 break;
18013 case SQL_DATE:
18014 v = SQL_C_DATE;
18015 break;
18016 #ifdef SQL_C_TYPE_TIMESTAMP
18017 case SQL_TYPE_TIMESTAMP:
18018 v = SQL_C_TYPE_TIMESTAMP;
18019 break;
18020 #endif
18021 #ifdef SQL_C_TYPE_TIME
18022 case SQL_TYPE_TIME:
18023 v = SQL_C_TYPE_TIME;
18024 break;
18025 #endif
18026 #ifdef SQL_C_TYPE_DATE
18027 case SQL_TYPE_DATE:
18028 v = SQL_C_TYPE_DATE;
18029 break;
18030 #endif
18031 #ifdef SQL_BIT
18032 case SQL_BIT:
18033 v = SQL_C_BIT;
18034 break;
18035 #endif
18036 #ifdef SQL_BIGINT
18037 case SQL_BIGINT:
18038 v = SQL_C_SBIGINT;
18039 break;
18040 #endif
18041 default:
18042 #ifdef WINTERFACE
18043 v = (s->nowchar[0] || s->nowchar[1]) ? SQL_C_CHAR : SQL_C_WCHAR;
18044 #else
18045 v = SQL_C_CHAR;
18046 #endif
18047 break;
18048 }
18049 break;
18050 case SQL_DESC_UPDATABLE:
18051 v = SQL_TRUE;
18052 break;
18053 case SQL_COLUMN_DISPLAY_SIZE:
18054 v = c->size;
18055 break;
18056 case SQL_COLUMN_UNSIGNED:
18057 v = c->nosign ? SQL_TRUE : SQL_FALSE;
18058 break;
18059 case SQL_COLUMN_SEARCHABLE:
18060 v = SQL_SEARCHABLE;
18061 break;
18062 case SQL_COLUMN_SCALE:
18063 case SQL_DESC_SCALE:
18064 v = c->scale;
18065 break;
18066 case SQL_COLUMN_PRECISION:
18067 case SQL_DESC_PRECISION:
18068 switch (c->type) {
18069 case SQL_SMALLINT:
18070 v = 5;
18071 break;
18072 case SQL_INTEGER:
18073 v = 10;
18074 break;
18075 case SQL_FLOAT:
18076 case SQL_REAL:
18077 case SQL_DOUBLE:
18078 v = 15;
18079 break;
18080 case SQL_DATE:
18081 v = 0;
18082 break;
18083 case SQL_TIME:
18084 v = 0;
18085 break;
18086 #ifdef SQL_TYPE_TIMESTAMP
18087 case SQL_TYPE_TIMESTAMP:
18088 #endif
18089 case SQL_TIMESTAMP:
18090 v = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
18091 break;
18092 default:
18093 v = c->prec;
18094 break;
18095 }
18096 break;
18097 case SQL_COLUMN_MONEY:
18098 v = SQL_FALSE;
18099 break;
18100 case SQL_COLUMN_AUTO_INCREMENT:
18101 v = c->autoinc;
18102 break;
18103 case SQL_DESC_NULLABLE:
18104 v = c->notnull;
18105 break;
18106 #ifdef SQL_DESC_NUM_PREC_RADIX
18107 case SQL_DESC_NUM_PREC_RADIX:
18108 switch (c->type) {
18109 #ifdef WINTERFACE
18110 case SQL_WCHAR:
18111 case SQL_WVARCHAR:
18112 #ifdef SQL_LONGVARCHAR
18113 case SQL_WLONGVARCHAR:
18114 #endif
18115 #endif
18116 case SQL_CHAR:
18117 case SQL_VARCHAR:
18118 #ifdef SQL_LONGVARCHAR
18119 case SQL_LONGVARCHAR:
18120 #endif
18121 case SQL_BINARY:
18122 case SQL_VARBINARY:
18123 case SQL_LONGVARBINARY:
18124 v = 0;
18125 break;
18126 default:
18127 v = 2;
18128 }
18129 break;
18130 #endif
18131 default:
18132 setstat(s, -1, "unsupported column attribute %d", "HY091", id);
18133 return SQL_ERROR;
18134 }
18135 if (val2) {
18136 *(SQLLEN *) val2 = v;
18137 }
18138 return SQL_SUCCESS;
18139 }
18140
18141 #ifndef WINTERFACE
18142
18154 SQLRETURN SQL_API
18155 SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
18156 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
18157 COLATTRIBUTE_LAST_ARG_TYPE val2)
18158 {
18159 #if defined(_WIN32) || defined(_WIN64)
18160 SQLSMALLINT len = 0;
18161 #endif
18162 SQLRETURN ret;
18163
18164 HSTMT_LOCK(stmt);
18165 #if defined(_WIN32) || defined(_WIN64)
18166 if (!((STMT *) stmt)->oemcp[0]) {
18167 ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
18168 (SQLPOINTER) val2);
18169 goto done;
18170 }
18171 ret = drvcolattribute(stmt, col, id, val, valMax, &len,
18172 (SQLPOINTER) val2);
18173 if (SQL_SUCCEEDED(ret)) {
18174 char *v = NULL;
18175
18176 switch (id) {
18177 case SQL_DESC_SCHEMA_NAME:
18178 case SQL_DESC_CATALOG_NAME:
18179 case SQL_COLUMN_LABEL:
18180 case SQL_DESC_NAME:
18181 case SQL_DESC_TABLE_NAME:
18182 #ifdef SQL_DESC_BASE_TABLE_NAME
18183 case SQL_DESC_BASE_TABLE_NAME:
18184 #endif
18185 #ifdef SQL_DESC_BASE_COLUMN_NAME
18186 case SQL_DESC_BASE_COLUMN_NAME:
18187 #endif
18188 case SQL_DESC_TYPE_NAME:
18189 if (val && valMax > 0) {
18190 int vmax = valMax;
18191
18192 v = utf_to_wmb((char *) val, SQL_NTS);
18193 if (v) {
18194 strncpy(val, v, vmax);
18195 len = min(vmax, strlen(v));
18196 uc_free(v);
18197 }
18198 if (vmax > 0) {
18199 v = (char *) val;
18200 v[vmax - 1] = '\0';
18201 }
18202 }
18203 if (len <= 0) {
18204 len = 0;
18205 }
18206 break;
18207 }
18208 if (valLen) {
18209 *valLen = len;
18210 }
18211 }
18212 done:
18213 ;
18214 #else
18215 ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
18216 (SQLPOINTER) val2);
18217 #endif
18218 HSTMT_UNLOCK(stmt);
18219 return ret;
18220 }
18221 #endif
18222
18223 #ifdef WINTERFACE
18224
18236 SQLRETURN SQL_API
18237 SQLColAttributeW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
18238 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
18239 COLATTRIBUTE_LAST_ARG_TYPE val2)
18240 {
18241 SQLRETURN ret;
18242 SQLSMALLINT len = 0;
18243
18244 HSTMT_LOCK(stmt);
18245 ret = drvcolattribute(stmt, col, id, val, valMax, &len,
18246 (SQLPOINTER) val2);
18247 if (SQL_SUCCEEDED(ret)) {
18248 SQLWCHAR *v = NULL;
18249
18250 switch (id) {
18251 case SQL_DESC_SCHEMA_NAME:
18252 case SQL_DESC_CATALOG_NAME:
18253 case SQL_COLUMN_LABEL:
18254 case SQL_DESC_NAME:
18255 case SQL_DESC_TABLE_NAME:
18256 #ifdef SQL_DESC_BASE_TABLE_NAME
18257 case SQL_DESC_BASE_TABLE_NAME:
18258 #endif
18259 #ifdef SQL_DESC_BASE_COLUMN_NAME
18260 case SQL_DESC_BASE_COLUMN_NAME:
18261 #endif
18262 case SQL_DESC_TYPE_NAME:
18263 if (val && valMax > 0) {
18264 int vmax = valMax / sizeof (SQLWCHAR);
18265
18266 v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
18267 if (v) {
18268 uc_strncpy(val, v, vmax);
18269 len = min(vmax, uc_strlen(v));
18270 uc_free(v);
18271 len *= sizeof (SQLWCHAR);
18272 }
18273 if (vmax > 0) {
18274 v = (SQLWCHAR *) val;
18275 v[vmax - 1] = '\0';
18276 }
18277 }
18278 if (len <= 0) {
18279 len = 0;
18280 }
18281 break;
18282 }
18283 if (valLen) {
18284 *valLen = len;
18285 }
18286 }
18287 HSTMT_UNLOCK(stmt);
18288 return ret;
18289 }
18290 #endif
18291
18305 static SQLRETURN
18306 drverror(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18307 SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18308 SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18309 {
18310 SQLCHAR dummy0[6];
18311 SQLINTEGER dummy1;
18312 SQLSMALLINT dummy2;
18313
18314 if (env == SQL_NULL_HENV &&
18315 dbc == SQL_NULL_HDBC &&
18316 stmt == SQL_NULL_HSTMT) {
18317 return SQL_INVALID_HANDLE;
18318 }
18319 if (sqlState) {
18320 sqlState[0] = '\0';
18321 } else {
18322 sqlState = dummy0;
18323 }
18324 if (!nativeErr) {
18325 nativeErr = &dummy1;
18326 }
18327 *nativeErr = 0;
18328 if (!errlen) {
18329 errlen = &dummy2;
18330 }
18331 *errlen = 0;
18332 if (errmsg) {
18333 if (errmax > 0) {
18334 errmsg[0] = '\0';
18335 }
18336 } else {
18337 errmsg = dummy0;
18338 errmax = 0;
18339 }
18340 if (stmt) {
18341 STMT *s = (STMT *) stmt;
18342
18343 HSTMT_LOCK(stmt);
18344 if (s->logmsg[0] == '\0') {
18345 HSTMT_UNLOCK(stmt);
18346 goto noerr;
18347 }
18348 *nativeErr = s->naterr;
18349 strcpy((char *) sqlState, s->sqlstate);
18350 if (errmax == SQL_NTS) {
18351 strcpy((char *) errmsg, "[SQLite]");
18352 strcat((char *) errmsg, (char *) s->logmsg);
18353 *errlen = strlen((char *) errmsg);
18354 } else {
18355 strncpy((char *) errmsg, "[SQLite]", errmax);
18356 if (errmax - 8 > 0) {
18357 strncpy((char *) errmsg + 8, (char *) s->logmsg, errmax - 8);
18358 }
18359 *errlen = min(strlen((char *) s->logmsg) + 8, errmax);
18360 }
18361 s->logmsg[0] = '\0';
18362 HSTMT_UNLOCK(stmt);
18363 return SQL_SUCCESS;
18364 }
18365 if (dbc) {
18366 DBC *d = (DBC *) dbc;
18367
18368 HDBC_LOCK(dbc);
18369 if (d->magic != DBC_MAGIC || d->logmsg[0] == '\0') {
18370 HDBC_UNLOCK(dbc);
18371 goto noerr;
18372 }
18373 *nativeErr = d->naterr;
18374 strcpy((char *) sqlState, d->sqlstate);
18375 if (errmax == SQL_NTS) {
18376 strcpy((char *) errmsg, "[SQLite]");
18377 strcat((char *) errmsg, (char *) d->logmsg);
18378 *errlen = strlen((char *) errmsg);
18379 } else {
18380 strncpy((char *) errmsg, "[SQLite]", errmax);
18381 if (errmax - 8 > 0) {
18382 strncpy((char *) errmsg + 8, (char *) d->logmsg, errmax - 8);
18383 }
18384 *errlen = min(strlen((char *) d->logmsg) + 8, errmax);
18385 }
18386 d->logmsg[0] = '\0';
18387 HDBC_UNLOCK(dbc);
18388 return SQL_SUCCESS;
18389 }
18390 noerr:
18391 sqlState[0] = '\0';
18392 errmsg[0] = '\0';
18393 *nativeErr = 0;
18394 *errlen = 0;
18395 return SQL_NO_DATA;
18396 }
18397
18398 #ifndef WINTERFACE
18399
18412 SQLRETURN SQL_API
18413 SQLError(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18414 SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18415 SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18416 {
18417 return drverror(env, dbc, stmt, sqlState, nativeErr,
18418 errmsg, errmax, errlen);
18419 }
18420 #endif
18421
18422 #ifdef WINTERFACE
18423
18436 SQLRETURN SQL_API
18437 SQLErrorW(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18438 SQLWCHAR *sqlState, SQLINTEGER *nativeErr,
18439 SQLWCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18440 {
18441 char state[16];
18442 SQLSMALLINT len = 0;
18443 SQLRETURN ret;
18444
18445 ret = drverror(env, dbc, stmt, (SQLCHAR *) state, nativeErr,
18446 (SQLCHAR *) errmsg, errmax, &len);
18447 if (ret == SQL_SUCCESS) {
18448 if (sqlState) {
18449 uc_from_utf_buf((SQLCHAR *) state, -1, sqlState,
18450 6 * sizeof (SQLWCHAR));
18451 }
18452 if (errmsg) {
18453 if (len > 0) {
18454 SQLWCHAR *e = NULL;
18455
18456 e = uc_from_utf((SQLCHAR *) errmsg, len);
18457 if (e) {
18458 if (errmax > 0) {
18459 uc_strncpy(errmsg, e, errmax);
18460 e[len] = 0;
18461 len = min(errmax, uc_strlen(e));
18462 } else {
18463 len = uc_strlen(e);
18464 }
18465 uc_free(e);
18466 } else {
18467 len = 0;
18468 }
18469 }
18470 if (len <= 0) {
18471 len = 0;
18472 if (errmax > 0) {
18473 errmsg[0] = 0;
18474 }
18475 }
18476 } else {
18477 len = 0;
18478 }
18479 if (errlen) {
18480 *errlen = len;
18481 }
18482 } else if (ret == SQL_NO_DATA) {
18483 if (sqlState) {
18484 sqlState[0] = 0;
18485 }
18486 if (errmsg) {
18487 if (errmax > 0) {
18488 errmsg[0] = 0;
18489 }
18490 }
18491 if (errlen) {
18492 *errlen = 0;
18493 }
18494 }
18495 return ret;
18496 }
18497 #endif
18498
18505 SQLRETURN SQL_API
18506 SQLMoreResults(SQLHSTMT stmt)
18507 {
18508 HSTMT_LOCK(stmt);
18509 if (stmt == SQL_NULL_HSTMT) {
18510 return SQL_INVALID_HANDLE;
18511 }
18512 HSTMT_UNLOCK(stmt);
18513 return SQL_NO_DATA;
18514 }
18515
18524 static SQLRETURN
18525 setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
18526 {
18527 int ncols = *ncolsp, guessed_types = 0;
18528 SQLRETURN ret = SQL_SUCCESS;
18529
18530 if (ncols > 0) {
18531 int i;
18532 PTRDIFF_T size;
18533 char *p;
18534 COL *dyncols;
18535 DBC *d = (DBC *) s->dbc;
18536 const char *colname, *typename;
18537 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18538 char *tblname;
18539 #endif
18540 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18541 char *dbname;
18542 #endif
18543
18544 for (i = size = 0; i < ncols; i++) {
18545 colname = sqlite3_column_name(s3stmt, i);
18546 size += 3 + 3 * strlen(colname);
18547 }
18548 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18549 tblname = (char *) size;
18550 for (i = 0; i < ncols; i++) {
18551 p = (char *) sqlite3_column_table_name(s3stmt, i);
18552 size += 2 + (p ? strlen(p) : 0);
18553 }
18554 #endif
18555 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18556 dbname = (char *) size;
18557 for (i = 0; i < ncols; i++) {
18558 p = (char *) sqlite3_column_database_name(s3stmt, i);
18559 size += 2 + (p ? strlen(p) : 0);
18560 }
18561 #endif
18562 dyncols = xmalloc(ncols * sizeof (COL) + size);
18563 if (!dyncols) {
18564 freedyncols(s);
18565 *ncolsp = 0;
18566 ret = SQL_ERROR;
18567 } else {
18568 p = (char *) (dyncols + ncols);
18569 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18570 tblname = p + (PTRDIFF_T) tblname;
18571 #endif
18572 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18573 dbname = p + (PTRDIFF_T) dbname;
18574 #endif
18575 for (i = 0; i < ncols; i++) {
18576 char *q;
18577
18578 colname = sqlite3_column_name(s3stmt, i);
18579 if (d->trace) {
18580 fprintf(d->trace, "-- column %d name: '%s'\n",
18581 i + 1, colname);
18582 fflush(d->trace);
18583 }
18584 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18585 q = (char *) sqlite3_column_table_name(s3stmt, i);
18586 strcpy(tblname, q ? q : "");
18587 if (d->trace) {
18588 fprintf(d->trace, "-- table %d name: '%s'\n",
18589 i + 1, tblname);
18590 fflush(d->trace);
18591 }
18592 dyncols[i].table = tblname;
18593 tblname += strlen(tblname) + 1;
18594 #endif
18595 #if defined(HAVE_SQLITE3COLUMNDATABASENAME) && (HAVE_SQLITE3COLUMNDATABASENAME)
18596 q = (char *) sqlite3_column_database_name(s3stmt, i);
18597 strcpy(dbname, q ? q : "");
18598 if (d->trace) {
18599 fprintf(d->trace, "-- database %d name: '%s'\n",
18600 i + 1, dbname);
18601 fflush(d->trace);
18602 }
18603 dyncols[i].db = dbname;
18604 dbname += strlen(dbname) + 1;
18605 #else
18606 dyncols[i].db = ((DBC *) (s->dbc))->dbname;
18607 #endif
18608 typename = s3stmt_coltype(s3stmt, i, d, &guessed_types);
18609 strcpy(p, colname);
18610 dyncols[i].label = p;
18611 p += strlen(p) + 1;
18612 q = strchr(colname, '.');
18613 if (q) {
18614 char *q2 = strchr(q + 1, '.');
18615
18616
18617 if (q2) {
18618 q = q2;
18619 }
18620 }
18621 if (q) {
18622 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18623 dyncols[i].table = p;
18624 #endif
18625 strncpy(p, colname, q - colname);
18626 p[q - colname] = '\0';
18627 p += strlen(p) + 1;
18628 strcpy(p, q + 1);
18629 dyncols[i].column = p;
18630 p += strlen(p) + 1;
18631 } else {
18632 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18633 dyncols[i].table = "";
18634 #endif
18635 strcpy(p, colname);
18636 dyncols[i].column = p;
18637 p += strlen(p) + 1;
18638 }
18639 if (s->longnames) {
18640 dyncols[i].column = dyncols[i].label;
18641 }
18642 #ifdef SQL_LONGVARCHAR
18643 dyncols[i].type = SQL_LONGVARCHAR;
18644 dyncols[i].size = 65535;
18645 #else
18646 dyncols[i].type = SQL_VARCHAR;
18647 dyncols[i].size = 255;
18648 #endif
18649 dyncols[i].index = i;
18650 dyncols[i].scale = 0;
18651 dyncols[i].prec = 0;
18652 dyncols[i].nosign = 1;
18653 dyncols[i].autoinc = SQL_FALSE;
18654 dyncols[i].notnull = SQL_NULLABLE;
18655 dyncols[i].ispk = -1;
18656 dyncols[i].isrowid = -1;
18657 #ifdef FULL_METADATA
18658 s3stmt_addmeta(s3stmt, i, d, &dyncols[i]);
18659 #endif
18660 dyncols[i].typename = xstrdup(typename);
18661 }
18662 freedyncols(s);
18663 s->dyncols = s->cols = dyncols;
18664 s->dcols = ncols;
18665 fixupdyncols(s, d);
18666 s->guessed_types = guessed_types;
18667 }
18668 }
18669 return ret;
18670 }
18671
18680 static SQLRETURN
18681 drvprepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18682 {
18683 STMT *s;
18684 DBC *d;
18685 char *errp = NULL;
18686 SQLRETURN sret;
18687
18688 if (stmt == SQL_NULL_HSTMT) {
18689 return SQL_INVALID_HANDLE;
18690 }
18691 s = (STMT *) stmt;
18692 if (s->dbc == SQL_NULL_HDBC) {
18693 noconn:
18694 return noconn(s);
18695 }
18696 d = s->dbc;
18697 if (!d->sqlite) {
18698 goto noconn;
18699 }
18700 s3stmt_end(s);
18701 s3stmt_drop(s);
18702 sret = starttran(s);
18703 if (sret != SQL_SUCCESS) {
18704 return sret;
18705 }
18706 freep(&s->query);
18707 s->query = (SQLCHAR *) fixupsql((char *) query, queryLen,
18708 (d->version >= 0x030805),
18709 &s->nparams, &s->isselect, &errp);
18710 if (!s->query) {
18711 if (errp) {
18712 setstat(s, -1, "%s", (*s->ov3) ? "HY000" : "S1000", errp);
18713 return SQL_ERROR;
18714 }
18715 return nomem(s);
18716 }
18717 if (*s->ilike) {
18718 replilike((char *) s->query);
18719 }
18720 errp = NULL;
18721 freeresult(s, -1);
18722 if (s->isselect == 1) {
18723 int ret, ncols, nretry = 0;
18724 const char *rest;
18725 sqlite3_stmt *s3stmt = NULL;
18726
18727 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18728 dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
18729 #else
18730 dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
18731 #endif
18732 do {
18733 s3stmt = NULL;
18734 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18735 ret = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
18736 &s3stmt, &rest);
18737 #else
18738 ret = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
18739 &s3stmt, &rest);
18740 #endif
18741 if (ret != SQLITE_OK) {
18742 if (s3stmt) {
18743 sqlite3_finalize(s3stmt);
18744 s3stmt = NULL;
18745 }
18746 }
18747 } while (ret == SQLITE_SCHEMA && (++nretry) < 2);
18748 dbtracerc(d, ret, NULL);
18749 if (ret != SQLITE_OK) {
18750 if (s3stmt) {
18751 dbtraceapi(d, "sqlite3_finalize", 0);
18752 sqlite3_finalize(s3stmt);
18753 }
18754 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18755 sqlite3_errmsg(d->sqlite), ret);
18756 return SQL_ERROR;
18757 }
18758 if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
18759 dbtraceapi(d, "sqlite3_finalize", 0);
18760 sqlite3_finalize(s3stmt);
18761 setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
18762 (*s->ov3) ? "HY000" : "S1000");
18763 return SQL_ERROR;
18764 }
18765 ncols = sqlite3_column_count(s3stmt);
18766 s->guessed_types = 0;
18767 setupdyncols(s, s3stmt, &ncols);
18768 s->ncols = ncols;
18769 s->s3stmt = s3stmt;
18770 } else {
18771 s->guessed_types = 1;
18772 }
18773 mkbindcols(s, s->ncols);
18774 s->paramset_count = 0;
18775 return SQL_SUCCESS;
18776 }
18777
18785 static SQLRETURN
18786 drvexecute(SQLHSTMT stmt, int initial)
18787 {
18788 STMT *s;
18789 DBC *d;
18790 char *errp = NULL;
18791 int rc, i, ncols = 0, nrows = 0, busy_count;
18792 SQLRETURN ret;
18793
18794 if (stmt == SQL_NULL_HSTMT) {
18795 return SQL_INVALID_HANDLE;
18796 }
18797 s = (STMT *) stmt;
18798 if (s->dbc == SQL_NULL_HDBC) {
18799 noconn:
18800 return noconn(s);
18801 }
18802 d = (DBC *) s->dbc;
18803 if (!d->sqlite) {
18804 goto noconn;
18805 }
18806 if (!s->query) {
18807 setstat(s, -1, "no query prepared", (*s->ov3) ? "HY000" : "S1000");
18808 return SQL_ERROR;
18809 }
18810 if (s->nbindparms < s->nparams) {
18811 unbound:
18812 setstat(s, -1, "unbound parameters in query",
18813 (*s->ov3) ? "HY000" : "S1000");
18814 return SQL_ERROR;
18815 }
18816 for (i = 0; i < s->nparams; i++) {
18817 BINDPARM *p = &s->bindparms[i];
18818
18819 if (!p->bound) {
18820 goto unbound;
18821 }
18822 if (initial) {
18823 SQLLEN *lenp = p->lenp;
18824
18825 if (lenp && *lenp < 0 && *lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18826 *lenp != SQL_NTS && *lenp != SQL_NULL_DATA &&
18827 *lenp != SQL_DATA_AT_EXEC) {
18828 setstat(s, -1, "invalid length reference", "HY009");
18829 return SQL_ERROR;
18830 }
18831 if (lenp && (*lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18832 *lenp == SQL_DATA_AT_EXEC)) {
18833 p->need = 1;
18834 p->offs = 0;
18835 p->len = 0;
18836 }
18837 }
18838 }
18839 ret = starttran(s);
18840 if (ret != SQL_SUCCESS) {
18841 goto cleanup;
18842 }
18843 busy_count = 0;
18844 again:
18845 s3stmt_end(s);
18846 if (initial) {
18847
18848 s->pdcount = -1;
18849 for (i = 0; i < s->nparams; i++) {
18850 BINDPARM *p = &s->bindparms[i];
18851
18852 if (p->param == p->parbuf) {
18853 p->param = NULL;
18854 }
18855 freep(&p->parbuf);
18856 if (p->need <= 0 &&
18857 p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18858 *p->lenp == SQL_DATA_AT_EXEC)) {
18859 p->need = 1;
18860 p->offs = 0;
18861 p->len = 0;
18862 }
18863 }
18864 }
18865 if (s->nparams) {
18866 for (i = 0; i < s->nparams; i++) {
18867 ret = setupparam(s, (char *) s->query, i);
18868 if (ret != SQL_SUCCESS) {
18869 goto cleanup;
18870 }
18871 }
18872 }
18873 freeresult(s, 0);
18874 if (s->isselect == 1 && !d->intrans &&
18875 s->curtype == SQL_CURSOR_FORWARD_ONLY &&
18876 d->step_enable && s->nparams == 0 && d->cur_s3stmt == NULL) {
18877 s->nrows = -1;
18878 ret = s3stmt_start(s);
18879 if (ret == SQL_SUCCESS) {
18880 goto done2;
18881 }
18882 }
18883 rc = drvgettable(s, s->s3stmt ? NULL : (char *) s->query, &s->rows,
18884 &s->nrows, &ncols, &errp, s->nparams, s->bindparms);
18885 dbtracerc(d, rc, errp);
18886 if (rc == SQLITE_BUSY) {
18887 if (busy_handler((void *) d, ++busy_count)) {
18888 if (errp) {
18889 sqlite3_free(errp);
18890 errp = NULL;
18891 }
18892 for (i = 0; i < s->nparams; i++) {
18893 BINDPARM *p = &s->bindparms[i];
18894
18895 if (p->param == p->parbuf) {
18896 p->param = NULL;
18897 }
18898 freep(&p->parbuf);
18899 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18900 *p->lenp != SQL_DATA_AT_EXEC)) {
18901 p->param = p->param0;
18902 }
18903 p->lenp = p->lenp0;
18904 }
18905 s->nrows = 0;
18906 goto again;
18907 }
18908 }
18909 if (rc != SQLITE_OK) {
18910 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18911 errp ? errp : "unknown error", rc);
18912 if (errp) {
18913 sqlite3_free(errp);
18914 errp = NULL;
18915 }
18916 ret = SQL_ERROR;
18917 goto cleanup;
18918 }
18919 if (errp) {
18920 sqlite3_free(errp);
18921 errp = NULL;
18922 }
18923 s->rowfree = freerows;
18924 if (s->isselect <= 0 || s->isselect > 1) {
18925
18926
18927
18928
18929
18930 if (s->isselect != 0 || ncols == 0) {
18931 freeresult(s, -1);
18932 nrows += sqlite3_changes(d->sqlite);
18933 s->nrows = nrows;
18934 } else {
18935 s->ncols = ncols;
18936 }
18937 goto done;
18938 }
18939 if (s->ncols != ncols) {
18940
18941
18942
18943 setstat(s, -1, "broken result set %d/%d",
18944 (*s->ov3) ? "HY000" : "S1000", s->ncols, ncols);
18945 ret = SQL_ERROR;
18946 goto cleanup;
18947 }
18948 done:
18949 mkbindcols(s, s->ncols);
18950 done2:
18951 ret = SQL_SUCCESS;
18952 s->rowp = s->rowprs = -1;
18953 s->paramset_count++;
18954 s->paramset_nrows = s->nrows;
18955 if (s->paramset_count < s->paramset_size) {
18956 for (i = 0; i < s->nparams; i++) {
18957 BINDPARM *p = &s->bindparms[i];
18958
18959 if (p->param == p->parbuf) {
18960 p->param = NULL;
18961 }
18962 freep(&p->parbuf);
18963 if (p->lenp0 &&
18964 s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18965 p->lenp = (SQLLEN *) ((char *) p->lenp0 +
18966 s->paramset_count * s->parm_bind_type);
18967 } else if (p->lenp0 && p->inc > 0) {
18968 p->lenp = p->lenp0 + s->paramset_count;
18969 }
18970 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18971 *p->lenp != SQL_DATA_AT_EXEC)) {
18972 if (p->param0 &&
18973 s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18974 p->param = (char *) p->param0 +
18975 s->paramset_count * s->parm_bind_type;
18976 } else if (p->param0 && p->inc > 0) {
18977 p->param = (char *) p->param0 +
18978 s->paramset_count * p->inc;
18979 }
18980 } else if (p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18981 *p->lenp == SQL_DATA_AT_EXEC)) {
18982 p->need = 1;
18983 p->offs = 0;
18984 p->len = 0;
18985 }
18986 }
18987 goto again;
18988 }
18989 cleanup:
18990 if (ret != SQL_NEED_DATA) {
18991 for (i = 0; i < s->nparams; i++) {
18992 BINDPARM *p = &s->bindparms[i];
18993
18994 if (p->param == p->parbuf) {
18995 p->param = NULL;
18996 }
18997 freep(&p->parbuf);
18998 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18999 *p->lenp != SQL_DATA_AT_EXEC)) {
19000 p->param = p->param0;
19001 }
19002 p->lenp = p->lenp0;
19003 }
19004 s->nrows = s->paramset_nrows;
19005 if (s->parm_proc) {
19006 *s->parm_proc = s->paramset_count;
19007 }
19008 s->paramset_count = 0;
19009 s->paramset_nrows = 0;
19010 }
19011
19012
19013
19014
19015 if (*s->ov3 && s->isselect == 0 &&
19016 ret == SQL_SUCCESS && nrows == 0) {
19017 ret = SQL_NO_DATA;
19018 }
19019 return ret;
19020 }
19021
19022 #ifndef WINTERFACE
19023
19031 SQLRETURN SQL_API
19032 SQLPrepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
19033 {
19034 SQLRETURN ret;
19035 #if defined(_WIN32) || defined(_WIN64)
19036 char *q;
19037 #endif
19038
19039 HSTMT_LOCK(stmt);
19040 #if defined(_WIN32) || defined(_WIN64)
19041 if (!((STMT *) stmt)->oemcp[0]) {
19042 ret = drvprepare(stmt, query, queryLen);
19043 goto done;
19044 }
19045 q = wmb_to_utf_c((char *) query, queryLen);
19046 if (!q) {
19047 ret = nomem((STMT *) stmt);
19048 goto done;
19049 }
19050 query = (SQLCHAR *) q;
19051 queryLen = SQL_NTS;
19052 #endif
19053 ret = drvprepare(stmt, query, queryLen);
19054 #if defined(_WIN32) || defined(_WIN64)
19055 uc_free(q);
19056 done:
19057 ;
19058 #endif
19059 HSTMT_UNLOCK(stmt);
19060 return ret;
19061 }
19062 #endif
19063
19064 #ifdef WINTERFACE
19065
19073 SQLRETURN SQL_API
19074 SQLPrepareW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
19075 {
19076 SQLRETURN ret;
19077 char *q = uc_to_utf_c(query, queryLen);
19078
19079 HSTMT_LOCK(stmt);
19080 if (!q) {
19081 ret = nomem((STMT *) stmt);
19082 goto done;
19083 }
19084 ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
19085 uc_free(q);
19086 done:
19087 HSTMT_UNLOCK(stmt);
19088 return ret;
19089 }
19090 #endif
19091
19098 SQLRETURN SQL_API
19099 SQLExecute(SQLHSTMT stmt)
19100 {
19101 SQLRETURN ret;
19102
19103 HSTMT_LOCK(stmt);
19104 ret = drvexecute(stmt, 1);
19105 HSTMT_UNLOCK(stmt);
19106 return ret;
19107 }
19108
19109 #ifndef WINTERFACE
19110
19118 SQLRETURN SQL_API
19119 SQLExecDirect(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
19120 {
19121 SQLRETURN ret;
19122 #if defined(_WIN32) || defined(_WIN64)
19123 char *q;
19124 #endif
19125
19126 HSTMT_LOCK(stmt);
19127 #if defined(_WIN32) || defined(_WIN64)
19128 if (!((STMT *) stmt)->oemcp[0]) {
19129 ret = drvprepare(stmt, query, queryLen);
19130 if (ret == SQL_SUCCESS) {
19131 ret = drvexecute(stmt, 1);
19132 }
19133 goto done;
19134 }
19135 q = wmb_to_utf_c((char *) query, queryLen);
19136 if (!q) {
19137 ret = nomem((STMT *) stmt);
19138 goto done;
19139 }
19140 query = (SQLCHAR *) q;
19141 queryLen = SQL_NTS;
19142 #endif
19143 ret = drvprepare(stmt, query, queryLen);
19144 if (ret == SQL_SUCCESS) {
19145 ret = drvexecute(stmt, 1);
19146 }
19147 #if defined(_WIN32) || defined(_WIN64)
19148 uc_free(q);
19149 done:
19150 ;
19151 #endif
19152 HSTMT_UNLOCK(stmt);
19153 return ret;
19154 }
19155 #endif
19156
19157 #ifdef WINTERFACE
19158
19166 SQLRETURN SQL_API
19167 SQLExecDirectW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
19168 {
19169 SQLRETURN ret;
19170 char *q = uc_to_utf_c(query, queryLen);
19171
19172 HSTMT_LOCK(stmt);
19173 if (!q) {
19174 ret = nomem((STMT *) stmt);
19175 goto done;
19176 }
19177 ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
19178 uc_free(q);
19179 if (ret == SQL_SUCCESS) {
19180 ret = drvexecute(stmt, 1);
19181 }
19182 done:
19183 HSTMT_UNLOCK(stmt);
19184 return ret;
19185 }
19186 #endif
19187
19188
19189 #if defined(_WIN32) || defined(_WIN64)
19190 #ifndef WITHOUT_DRIVERMGR
19191
19192
19193
19194
19195
19196 #include <windowsx.h>
19197 #include <winuser.h>
19198
19199 #define MAXPATHLEN (259+1)
19200 #define MAXKEYLEN (15+1)
19201 #define MAXDESC (255+1)
19202 #define MAXDSNAME (255+1)
19203 #define MAXTONAME (32+1)
19204 #define MAXDBNAME MAXPATHLEN
19205
19206
19207
19208 #define KEY_DSN 0
19209 #define KEY_DESC 1
19210 #define KEY_DBNAME 2
19211 #define KEY_BUSY 3
19212 #define KEY_DRIVER 4
19213 #define KEY_STEPAPI 5
19214 #define KEY_SYNCP 6
19215 #define KEY_NOTXN 7
19216 #define KEY_SHORTNAM 8
19217 #define KEY_LONGNAM 9
19218 #define KEY_NOCREAT 10
19219 #define KEY_NOWCHAR 11
19220 #define KEY_LOADEXT 12
19221 #define KEY_JMODE 13
19222 #define KEY_FKSUPPORT 14
19223 #define KEY_OEMCP 15
19224 #define KEY_BIGINT 16
19225 #define KEY_PASSWD 17
19226 #define KEY_JDCONV 18
19227 #define KEY_ATTAS 19
19228 #define KEY_ILIKE 20
19229 #define NUMOFKEYS 21
19230
19231 typedef struct {
19232 BOOL supplied;
19233 char attr[MAXPATHLEN*4];
19234 } ATTR;
19235
19236 typedef struct {
19237 SQLHWND parent;
19238 LPCSTR driver;
19239 ATTR attr[NUMOFKEYS];
19240 char DSN[MAXDSNAME];
19241 BOOL newDSN;
19242 BOOL defDSN;
19243 } SETUPDLG;
19244
19245 static struct {
19246 char *key;
19247 int ikey;
19248 } attrLookup[] = {
19249 { "DSN", KEY_DSN },
19250 { "DESC", KEY_DESC },
19251 { "Description", KEY_DESC},
19252 { "Database", KEY_DBNAME },
19253 { "Timeout", KEY_BUSY },
19254 { "Driver", KEY_DRIVER },
19255 { "StepAPI", KEY_STEPAPI },
19256 { "SyncPragma", KEY_SYNCP },
19257 { "NoTXN", KEY_NOTXN },
19258 { "ShortNames", KEY_SHORTNAM },
19259 { "LongNames", KEY_LONGNAM },
19260 { "NoCreat", KEY_NOCREAT },
19261 { "NoWCHAR", KEY_NOWCHAR },
19262 { "LoadExt", KEY_LOADEXT },
19263 { "JournalMode", KEY_JMODE },
19264 { "FKSupport", KEY_FKSUPPORT },
19265 { "OEMCP", KEY_OEMCP },
19266 { "BigInt", KEY_BIGINT },
19267 { "PWD", KEY_PASSWD },
19268 { "JDConv", KEY_JDCONV },
19269 { "AttachAs", KEY_ATTAS },
19270 { "ILike", KEY_ILIKE },
19271 { NULL, 0 }
19272 };
19273
19280 static void
19281 ParseAttributes(LPCSTR attribs, SETUPDLG *setupdlg)
19282 {
19283 char *str = (char *) attribs, *start, key[MAXKEYLEN];
19284 int elem, nkey;
19285
19286 while (*str) {
19287 start = str;
19288 if ((str = strchr(str, '=')) == NULL) {
19289 return;
19290 }
19291 elem = -1;
19292 nkey = str - start;
19293 if (nkey < sizeof (key)) {
19294 int i;
19295
19296 memcpy(key, start, nkey);
19297 key[nkey] = '\0';
19298 for (i = 0; attrLookup[i].key; i++) {
19299 if (strcasecmp(attrLookup[i].key, key) == 0) {
19300 elem = attrLookup[i].ikey;
19301 break;
19302 }
19303 }
19304 }
19305 start = ++str;
19306 while (*str && *str != ';') {
19307 ++str;
19308 }
19309 if (elem >= 0) {
19310 int end = min(str - start, sizeof (setupdlg->attr[elem].attr) - 1);
19311
19312 setupdlg->attr[elem].supplied = TRUE;
19313 memcpy(setupdlg->attr[elem].attr, start, end);
19314 setupdlg->attr[elem].attr[end] = '\0';
19315 }
19316 ++str;
19317 }
19318 }
19319
19327 static BOOL
19328 SetDSNAttributes(HWND parent, SETUPDLG *setupdlg)
19329 {
19330 char *dsn = setupdlg->attr[KEY_DSN].attr;
19331
19332 if (setupdlg->newDSN && strlen(dsn) == 0) {
19333 return FALSE;
19334 }
19335 if (!SQLWriteDSNToIni(dsn, setupdlg->driver)) {
19336 if (parent) {
19337 char buf[MAXPATHLEN], msg[MAXPATHLEN];
19338
19339 LoadString(hModule, IDS_BADDSN, buf, sizeof (buf));
19340 wsprintf(msg, buf, dsn);
19341 LoadString(hModule, IDS_MSGTITLE, buf, sizeof (buf));
19342 MessageBox(parent, msg, buf,
19343 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
19344 MB_SETFOREGROUND);
19345 }
19346 return FALSE;
19347 }
19348 if (parent || setupdlg->attr[KEY_DESC].supplied) {
19349 SQLWritePrivateProfileString(dsn, "Description",
19350 setupdlg->attr[KEY_DESC].attr,
19351 ODBC_INI);
19352 }
19353 if (parent || setupdlg->attr[KEY_DBNAME].supplied) {
19354 SQLWritePrivateProfileString(dsn, "Database",
19355 setupdlg->attr[KEY_DBNAME].attr,
19356 ODBC_INI);
19357 }
19358 if (parent || setupdlg->attr[KEY_BUSY].supplied) {
19359 SQLWritePrivateProfileString(dsn, "Timeout",
19360 setupdlg->attr[KEY_BUSY].attr,
19361 ODBC_INI);
19362 }
19363 if (parent || setupdlg->attr[KEY_STEPAPI].supplied) {
19364 SQLWritePrivateProfileString(dsn, "StepAPI",
19365 setupdlg->attr[KEY_STEPAPI].attr,
19366 ODBC_INI);
19367 }
19368 if (parent || setupdlg->attr[KEY_SYNCP].supplied) {
19369 SQLWritePrivateProfileString(dsn, "SyncPragma",
19370 setupdlg->attr[KEY_SYNCP].attr,
19371 ODBC_INI);
19372 }
19373 if (parent || setupdlg->attr[KEY_NOTXN].supplied) {
19374 SQLWritePrivateProfileString(dsn, "NoTXN",
19375 setupdlg->attr[KEY_NOTXN].attr,
19376 ODBC_INI);
19377 }
19378 if (parent || setupdlg->attr[KEY_SHORTNAM].supplied) {
19379 SQLWritePrivateProfileString(dsn, "ShortNames",
19380 setupdlg->attr[KEY_SHORTNAM].attr,
19381 ODBC_INI);
19382 }
19383 if (parent || setupdlg->attr[KEY_LONGNAM].supplied) {
19384 SQLWritePrivateProfileString(dsn, "LongNames",
19385 setupdlg->attr[KEY_LONGNAM].attr,
19386 ODBC_INI);
19387 }
19388 if (parent || setupdlg->attr[KEY_NOCREAT].supplied) {
19389 SQLWritePrivateProfileString(dsn, "NoCreat",
19390 setupdlg->attr[KEY_NOCREAT].attr,
19391 ODBC_INI);
19392 }
19393 if (parent || setupdlg->attr[KEY_NOWCHAR].supplied) {
19394 SQLWritePrivateProfileString(dsn, "NoWCHAR",
19395 setupdlg->attr[KEY_NOWCHAR].attr,
19396 ODBC_INI);
19397 }
19398 if (parent || setupdlg->attr[KEY_FKSUPPORT].supplied) {
19399 SQLWritePrivateProfileString(dsn, "FKSupport",
19400 setupdlg->attr[KEY_FKSUPPORT].attr,
19401 ODBC_INI);
19402 }
19403 if (parent || setupdlg->attr[KEY_OEMCP].supplied) {
19404 SQLWritePrivateProfileString(dsn, "OEMCP",
19405 setupdlg->attr[KEY_OEMCP].attr,
19406 ODBC_INI);
19407 }
19408 if (parent || setupdlg->attr[KEY_LOADEXT].supplied) {
19409 SQLWritePrivateProfileString(dsn, "LoadExt",
19410 setupdlg->attr[KEY_LOADEXT].attr,
19411 ODBC_INI);
19412 }
19413 if (parent || setupdlg->attr[KEY_BIGINT].supplied) {
19414 SQLWritePrivateProfileString(dsn, "BigInt",
19415 setupdlg->attr[KEY_BIGINT].attr,
19416 ODBC_INI);
19417 }
19418 if (parent || setupdlg->attr[KEY_JDCONV].supplied) {
19419 SQLWritePrivateProfileString(dsn, "JDConv",
19420 setupdlg->attr[KEY_JDCONV].attr,
19421 ODBC_INI);
19422 }
19423 if (parent || setupdlg->attr[KEY_ATTAS].supplied) {
19424 SQLWritePrivateProfileString(dsn, "AttachAs",
19425 setupdlg->attr[KEY_ATTAS].attr,
19426 ODBC_INI);
19427 }
19428 if (parent || setupdlg->attr[KEY_ILIKE].supplied) {
19429 SQLWritePrivateProfileString(dsn, "ILike",
19430 setupdlg->attr[KEY_ILIKE].attr,
19431 ODBC_INI);
19432 }
19433 if (parent || setupdlg->attr[KEY_PASSWD].supplied) {
19434 SQLWritePrivateProfileString(dsn, "PWD",
19435 setupdlg->attr[KEY_PASSWD].attr,
19436 ODBC_INI);
19437 }
19438 if (setupdlg->attr[KEY_DSN].supplied &&
19439 strcasecmp(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr)) {
19440 SQLRemoveDSNFromIni(setupdlg->DSN);
19441 }
19442 return TRUE;
19443 }
19444
19450 static void
19451 GetAttributes(SETUPDLG *setupdlg)
19452 {
19453 char *dsn = setupdlg->attr[KEY_DSN].attr;
19454
19455 if (!setupdlg->attr[KEY_DESC].supplied) {
19456 SQLGetPrivateProfileString(dsn, "Description", "",
19457 setupdlg->attr[KEY_DESC].attr,
19458 sizeof (setupdlg->attr[KEY_DESC].attr),
19459 ODBC_INI);
19460 }
19461 if (!setupdlg->attr[KEY_DBNAME].supplied) {
19462 SQLGetPrivateProfileString(dsn, "Database", "",
19463 setupdlg->attr[KEY_DBNAME].attr,
19464 sizeof (setupdlg->attr[KEY_DBNAME].attr),
19465 ODBC_INI);
19466 }
19467 if (!setupdlg->attr[KEY_BUSY].supplied) {
19468 SQLGetPrivateProfileString(dsn, "Timeout", "100000",
19469 setupdlg->attr[KEY_BUSY].attr,
19470 sizeof (setupdlg->attr[KEY_BUSY].attr),
19471 ODBC_INI);
19472 }
19473 if (!setupdlg->attr[KEY_STEPAPI].supplied) {
19474 SQLGetPrivateProfileString(dsn, "StepAPI", "0",
19475 setupdlg->attr[KEY_STEPAPI].attr,
19476 sizeof (setupdlg->attr[KEY_STEPAPI].attr),
19477 ODBC_INI);
19478 }
19479 if (!setupdlg->attr[KEY_SYNCP].supplied) {
19480 SQLGetPrivateProfileString(dsn, "SyncPragma", "NORMAL",
19481 setupdlg->attr[KEY_SYNCP].attr,
19482 sizeof (setupdlg->attr[KEY_SYNCP].attr),
19483 ODBC_INI);
19484 }
19485 if (!setupdlg->attr[KEY_NOTXN].supplied) {
19486 SQLGetPrivateProfileString(dsn, "NoTXN", "",
19487 setupdlg->attr[KEY_NOTXN].attr,
19488 sizeof (setupdlg->attr[KEY_NOTXN].attr),
19489 ODBC_INI);
19490 }
19491 if (!setupdlg->attr[KEY_SHORTNAM].supplied) {
19492 SQLGetPrivateProfileString(dsn, "ShortNames", "",
19493 setupdlg->attr[KEY_SHORTNAM].attr,
19494 sizeof (setupdlg->attr[KEY_SHORTNAM].attr),
19495 ODBC_INI);
19496 }
19497 if (!setupdlg->attr[KEY_LONGNAM].supplied) {
19498 SQLGetPrivateProfileString(dsn, "LongNames", "",
19499 setupdlg->attr[KEY_LONGNAM].attr,
19500 sizeof (setupdlg->attr[KEY_LONGNAM].attr),
19501 ODBC_INI);
19502 }
19503 if (!setupdlg->attr[KEY_NOCREAT].supplied) {
19504 SQLGetPrivateProfileString(dsn, "NoCreat", "",
19505 setupdlg->attr[KEY_NOCREAT].attr,
19506 sizeof (setupdlg->attr[KEY_NOCREAT].attr),
19507 ODBC_INI);
19508 }
19509 if (!setupdlg->attr[KEY_NOWCHAR].supplied) {
19510 SQLGetPrivateProfileString(dsn, "NoWCHAR", "",
19511 setupdlg->attr[KEY_NOWCHAR].attr,
19512 sizeof (setupdlg->attr[KEY_NOWCHAR].attr),
19513 ODBC_INI);
19514 }
19515 if (!setupdlg->attr[KEY_FKSUPPORT].supplied) {
19516 SQLGetPrivateProfileString(dsn, "FKSupport", "",
19517 setupdlg->attr[KEY_FKSUPPORT].attr,
19518 sizeof (setupdlg->attr[KEY_FKSUPPORT].attr),
19519 ODBC_INI);
19520 }
19521 if (!setupdlg->attr[KEY_OEMCP].supplied) {
19522 SQLGetPrivateProfileString(dsn, "OEMCP", "",
19523 setupdlg->attr[KEY_OEMCP].attr,
19524 sizeof (setupdlg->attr[KEY_OEMCP].attr),
19525 ODBC_INI);
19526 }
19527 if (!setupdlg->attr[KEY_LOADEXT].supplied) {
19528 SQLGetPrivateProfileString(dsn, "LoadExt", "",
19529 setupdlg->attr[KEY_LOADEXT].attr,
19530 sizeof (setupdlg->attr[KEY_LOADEXT].attr),
19531 ODBC_INI);
19532 }
19533 if (!setupdlg->attr[KEY_JMODE].supplied) {
19534 SQLGetPrivateProfileString(dsn, "JournalMode", "",
19535 setupdlg->attr[KEY_JMODE].attr,
19536 sizeof (setupdlg->attr[KEY_JMODE].attr),
19537 ODBC_INI);
19538 }
19539 if (!setupdlg->attr[KEY_BIGINT].supplied) {
19540 SQLGetPrivateProfileString(dsn, "BigInt", "",
19541 setupdlg->attr[KEY_BIGINT].attr,
19542 sizeof (setupdlg->attr[KEY_BIGINT].attr),
19543 ODBC_INI);
19544 }
19545 if (!setupdlg->attr[KEY_PASSWD].supplied) {
19546 SQLGetPrivateProfileString(dsn, "PWD", "",
19547 setupdlg->attr[KEY_PASSWD].attr,
19548 sizeof (setupdlg->attr[KEY_PASSWD].attr),
19549 ODBC_INI);
19550 }
19551 if (!setupdlg->attr[KEY_JDCONV].supplied) {
19552 SQLGetPrivateProfileString(dsn, "JDConv", "",
19553 setupdlg->attr[KEY_JDCONV].attr,
19554 sizeof (setupdlg->attr[KEY_JDCONV].attr),
19555 ODBC_INI);
19556 }
19557 if (!setupdlg->attr[KEY_ATTAS].supplied) {
19558 SQLGetPrivateProfileString(dsn, "AttachAs", "",
19559 setupdlg->attr[KEY_ATTAS].attr,
19560 sizeof (setupdlg->attr[KEY_ATTAS].attr),
19561 ODBC_INI);
19562 }
19563 if (!setupdlg->attr[KEY_ILIKE].supplied) {
19564 SQLGetPrivateProfileString(dsn, "ILike", "",
19565 setupdlg->attr[KEY_ILIKE].attr,
19566 sizeof (setupdlg->attr[KEY_ILIKE].attr),
19567 ODBC_INI);
19568 }
19569 }
19570
19576 static void
19577 GetDBFile(HWND hdlg)
19578 {
19579 #ifdef _WIN64
19580 SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19581 #else
19582 SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19583 #endif
19584 OPENFILENAME ofn;
19585
19586 memset(&ofn, 0, sizeof (ofn));
19587 ofn.lStructSize = sizeof (ofn);
19588 ofn.hwndOwner = hdlg;
19589 #ifdef _WIN64
19590 ofn.hInstance = (HINSTANCE) GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
19591 #else
19592 ofn.hInstance = (HINSTANCE) GetWindowLong(hdlg, GWL_HINSTANCE);
19593 #endif
19594 ofn.lpstrFile = (LPTSTR) setupdlg->attr[KEY_DBNAME].attr;
19595 ofn.nMaxFile = MAXPATHLEN;
19596 ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST |
19597 OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST;
19598 if (GetOpenFileName(&ofn)) {
19599 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19600 setupdlg->attr[KEY_DBNAME].supplied = TRUE;
19601 }
19602 }
19603
19613 static BOOL CALLBACK
19614 ConfigDlgProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19615 {
19616 SETUPDLG *setupdlg = NULL;
19617 WORD index;
19618
19619 switch (wmsg) {
19620 case WM_INITDIALOG:
19621 #ifdef _WIN64
19622 SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19623 #else
19624 SetWindowLong(hdlg, DWL_USER, lparam);
19625 #endif
19626 setupdlg = (SETUPDLG *) lparam;
19627 GetAttributes(setupdlg);
19628 SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19629 SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19630 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19631 SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19632 SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19633 SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19634 (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19635 SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19636 (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19637 SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19638 (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19639 SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19640 (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19641 SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19642 (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19643 CheckDlgButton(hdlg, IDC_STEPAPI,
19644 getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19645 BST_CHECKED : BST_UNCHECKED);
19646 CheckDlgButton(hdlg, IDC_NOTXN,
19647 getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19648 BST_CHECKED : BST_UNCHECKED);
19649 CheckDlgButton(hdlg, IDC_SHORTNAM,
19650 getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19651 BST_CHECKED : BST_UNCHECKED);
19652 CheckDlgButton(hdlg, IDC_LONGNAM,
19653 getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19654 BST_CHECKED : BST_UNCHECKED);
19655 CheckDlgButton(hdlg, IDC_NOCREAT,
19656 getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19657 BST_CHECKED : BST_UNCHECKED);
19658 CheckDlgButton(hdlg, IDC_NOWCHAR,
19659 getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19660 BST_CHECKED : BST_UNCHECKED);
19661 CheckDlgButton(hdlg, IDC_FKSUPPORT,
19662 getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19663 BST_CHECKED : BST_UNCHECKED);
19664 CheckDlgButton(hdlg, IDC_OEMCP,
19665 getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19666 BST_CHECKED : BST_UNCHECKED);
19667 CheckDlgButton(hdlg, IDC_BIGINT,
19668 getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19669 BST_CHECKED : BST_UNCHECKED);
19670 CheckDlgButton(hdlg, IDC_JDCONV,
19671 getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19672 BST_CHECKED : BST_UNCHECKED);
19673 SetDlgItemText(hdlg, IDC_ATTAS, setupdlg->attr[KEY_ATTAS].attr);
19674 CheckDlgButton(hdlg, IDC_ILIKE,
19675 getbool(setupdlg->attr[KEY_ILIKE].attr) ?
19676 BST_CHECKED : BST_UNCHECKED);
19677 SendDlgItemMessage(hdlg, IDC_SYNCP,
19678 CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19679 SendDlgItemMessage(hdlg, IDC_SYNCP,
19680 CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19681 SendDlgItemMessage(hdlg, IDC_SYNCP,
19682 CB_ADDSTRING, 0, (LPARAM) "OFF");
19683 SendDlgItemMessage(hdlg, IDC_SYNCP,
19684 CB_ADDSTRING, 0, (LPARAM) "FULL");
19685 SendDlgItemMessage(hdlg, IDC_SYNCP,
19686 CB_SELECTSTRING, (WPARAM) -1,
19687 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19688 if (setupdlg->defDSN) {
19689 EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19690 EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19691 }
19692 return TRUE;
19693 case WM_COMMAND:
19694 switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19695 case IDC_DSNAME:
19696 if (GET_WM_COMMAND_CMD(wparam, lparam) == EN_CHANGE) {
19697 char item[MAXDSNAME];
19698
19699 EnableWindow(GetDlgItem(hdlg, IDOK),
19700 GetDlgItemText(hdlg, IDC_DSNAME,
19701 item, sizeof (item)));
19702 return TRUE;
19703 }
19704 break;
19705 case IDC_BROWSE:
19706 GetDBFile(hdlg);
19707 break;
19708 case IDOK:
19709 #ifdef _WIN64
19710 setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19711 #else
19712 setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19713 #endif
19714 if (!setupdlg->defDSN) {
19715 GetDlgItemText(hdlg, IDC_DSNAME,
19716 setupdlg->attr[KEY_DSN].attr,
19717 sizeof (setupdlg->attr[KEY_DSN].attr));
19718 }
19719 GetDlgItemText(hdlg, IDC_DESC,
19720 setupdlg->attr[KEY_DESC].attr,
19721 sizeof (setupdlg->attr[KEY_DESC].attr));
19722 GetDlgItemText(hdlg, IDC_DBNAME,
19723 setupdlg->attr[KEY_DBNAME].attr,
19724 sizeof (setupdlg->attr[KEY_DBNAME].attr));
19725 GetDlgItemText(hdlg, IDC_TONAME,
19726 setupdlg->attr[KEY_BUSY].attr,
19727 sizeof (setupdlg->attr[KEY_BUSY].attr));
19728 GetDlgItemText(hdlg, IDC_LOADEXT,
19729 setupdlg->attr[KEY_LOADEXT].attr,
19730 sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19731 index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19732 CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19733 if (index != (WORD) CB_ERR) {
19734 SendDlgItemMessage(hdlg, IDC_SYNCP,
19735 CB_GETLBTEXT, index,
19736 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19737 }
19738 strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19739 (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19740 "1" : "0");
19741 strcpy(setupdlg->attr[KEY_NOTXN].attr,
19742 (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19743 "1" : "0");
19744 strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19745 (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19746 "1" : "0");
19747 strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19748 (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19749 "1" : "0");
19750 strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19751 (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19752 "1" : "0");
19753 strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19754 (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19755 "1" : "0");
19756 strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19757 (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19758 "1" : "0");
19759 strcpy(setupdlg->attr[KEY_OEMCP].attr,
19760 (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19761 "1" : "0");
19762 strcpy(setupdlg->attr[KEY_BIGINT].attr,
19763 (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19764 "1" : "0");
19765 strcpy(setupdlg->attr[KEY_JDCONV].attr,
19766 (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19767 "1" : "0");
19768 GetDlgItemText(hdlg, IDC_ATTAS,
19769 setupdlg->attr[KEY_ATTAS].attr,
19770 sizeof (setupdlg->attr[KEY_ATTAS].attr));
19771 strcpy(setupdlg->attr[KEY_ILIKE].attr,
19772 (IsDlgButtonChecked(hdlg, IDC_ILIKE) == BST_CHECKED) ?
19773 "1" : "0");
19774 SetDSNAttributes(hdlg, setupdlg);
19775
19776 case IDCANCEL:
19777 EndDialog(hdlg, wparam);
19778 return TRUE;
19779 }
19780 break;
19781 }
19782 return FALSE;
19783 }
19784
19794 BOOL INSTAPI
19795 ConfigDSN(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attribs)
19796 {
19797 BOOL success;
19798 SETUPDLG *setupdlg;
19799
19800 setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19801 if (setupdlg == NULL) {
19802 return FALSE;
19803 }
19804 memset(setupdlg, 0, sizeof (SETUPDLG));
19805 if (attribs) {
19806 ParseAttributes(attribs, setupdlg);
19807 }
19808 if (setupdlg->attr[KEY_DSN].supplied) {
19809 strcpy(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr);
19810 } else {
19811 setupdlg->DSN[0] = '\0';
19812 }
19813 if (request == ODBC_REMOVE_DSN) {
19814 if (!setupdlg->attr[KEY_DSN].supplied) {
19815 success = FALSE;
19816 } else {
19817 success = SQLRemoveDSNFromIni(setupdlg->attr[KEY_DSN].attr);
19818 }
19819 } else {
19820 setupdlg->parent = hwnd;
19821 setupdlg->driver = driver;
19822 setupdlg->newDSN = request == ODBC_ADD_DSN;
19823 setupdlg->defDSN = strcasecmp(setupdlg->attr[KEY_DSN].attr,
19824 "Default") == 0;
19825 if (hwnd) {
19826 success = DialogBoxParam(hModule, MAKEINTRESOURCE(CONFIGDSN),
19827 hwnd, (DLGPROC) ConfigDlgProc,
19828 (LPARAM) setupdlg) == IDOK;
19829 } else if (setupdlg->attr[KEY_DSN].supplied) {
19830 success = SetDSNAttributes(hwnd, setupdlg);
19831 } else {
19832 success = FALSE;
19833 }
19834 }
19835 xfree(setupdlg);
19836 return success;
19837 }
19838
19848 static BOOL CALLBACK
19849 DriverConnectProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19850 {
19851 SETUPDLG *setupdlg;
19852 WORD index;
19853
19854 switch (wmsg) {
19855 case WM_INITDIALOG:
19856 #ifdef _WIN64
19857 SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19858 #else
19859 SetWindowLong(hdlg, DWL_USER, lparam);
19860 #endif
19861 setupdlg = (SETUPDLG *) lparam;
19862 SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19863 SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19864 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19865 SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19866 SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19867 SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19868 (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19869 SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19870 (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19871 SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19872 (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19873 SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19874 (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19875 SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19876 (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19877 CheckDlgButton(hdlg, IDC_STEPAPI,
19878 getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19879 BST_CHECKED : BST_UNCHECKED);
19880 CheckDlgButton(hdlg, IDC_NOTXN,
19881 getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19882 BST_CHECKED : BST_UNCHECKED);
19883 CheckDlgButton(hdlg, IDC_SHORTNAM,
19884 getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19885 BST_CHECKED : BST_UNCHECKED);
19886 CheckDlgButton(hdlg, IDC_LONGNAM,
19887 getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19888 BST_CHECKED : BST_UNCHECKED);
19889 CheckDlgButton(hdlg, IDC_NOCREAT,
19890 getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19891 BST_CHECKED : BST_UNCHECKED);
19892 CheckDlgButton(hdlg, IDC_NOWCHAR,
19893 getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19894 BST_CHECKED : BST_UNCHECKED);
19895 CheckDlgButton(hdlg, IDC_FKSUPPORT,
19896 getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19897 BST_CHECKED : BST_UNCHECKED);
19898 CheckDlgButton(hdlg, IDC_OEMCP,
19899 getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19900 BST_CHECKED : BST_UNCHECKED);
19901 CheckDlgButton(hdlg, IDC_BIGINT,
19902 getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19903 BST_CHECKED : BST_UNCHECKED);
19904 CheckDlgButton(hdlg, IDC_JDCONV,
19905 getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19906 BST_CHECKED : BST_UNCHECKED);
19907 SendDlgItemMessage(hdlg, IDC_SYNCP,
19908 CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19909 SendDlgItemMessage(hdlg, IDC_SYNCP,
19910 CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19911 SendDlgItemMessage(hdlg, IDC_SYNCP,
19912 CB_ADDSTRING, 0, (LPARAM) "OFF");
19913 SendDlgItemMessage(hdlg, IDC_SYNCP,
19914 CB_ADDSTRING, 0, (LPARAM) "FULL");
19915 SendDlgItemMessage(hdlg, IDC_SYNCP,
19916 CB_SELECTSTRING, (WORD) -1,
19917 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19918 if (setupdlg->defDSN) {
19919 EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19920 EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19921 }
19922 SetDlgItemText(hdlg, IDC_ATTAS, setupdlg->attr[KEY_ATTAS].attr);
19923 CheckDlgButton(hdlg, IDC_ILIKE,
19924 getbool(setupdlg->attr[KEY_ILIKE].attr) ?
19925 BST_CHECKED : BST_UNCHECKED);
19926 return TRUE;
19927 case WM_COMMAND:
19928 switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19929 case IDC_BROWSE:
19930 GetDBFile(hdlg);
19931 break;
19932 case IDOK:
19933 #ifdef _WIN64
19934 setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19935 #else
19936 setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19937 #endif
19938 GetDlgItemText(hdlg, IDC_DSNAME,
19939 setupdlg->attr[KEY_DSN].attr,
19940 sizeof (setupdlg->attr[KEY_DSN].attr));
19941 GetDlgItemText(hdlg, IDC_DBNAME,
19942 setupdlg->attr[KEY_DBNAME].attr,
19943 sizeof (setupdlg->attr[KEY_DBNAME].attr));
19944 GetDlgItemText(hdlg, IDC_TONAME,
19945 setupdlg->attr[KEY_BUSY].attr,
19946 sizeof (setupdlg->attr[KEY_BUSY].attr));
19947 GetDlgItemText(hdlg, IDC_LOADEXT,
19948 setupdlg->attr[KEY_LOADEXT].attr,
19949 sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19950 index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19951 CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19952 if (index != (WORD) CB_ERR) {
19953 SendDlgItemMessage(hdlg, IDC_SYNCP,
19954 CB_GETLBTEXT, index,
19955 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19956 }
19957 strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19958 (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19959 "1" : "0");
19960 strcpy(setupdlg->attr[KEY_NOTXN].attr,
19961 (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19962 "1" : "0");
19963 strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19964 (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19965 "1" : "0");
19966 strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19967 (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19968 "1" : "0");
19969 strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19970 (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19971 "1" : "0");
19972 strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19973 (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19974 "1" : "0");
19975 strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19976 (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19977 "1" : "0");
19978 strcpy(setupdlg->attr[KEY_OEMCP].attr,
19979 (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19980 "1" : "0");
19981 strcpy(setupdlg->attr[KEY_BIGINT].attr,
19982 (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19983 "1" : "0");
19984 strcpy(setupdlg->attr[KEY_JDCONV].attr,
19985 (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19986 "1" : "0");
19987 GetDlgItemText(hdlg, IDC_ATTAS,
19988 setupdlg->attr[KEY_ATTAS].attr,
19989 sizeof (setupdlg->attr[KEY_ATTAS].attr));
19990 strcpy(setupdlg->attr[KEY_ILIKE].attr,
19991 (IsDlgButtonChecked(hdlg, IDC_ILIKE) == BST_CHECKED) ?
19992 "1" : "0");
19993
19994 case IDCANCEL:
19995 EndDialog(hdlg, GET_WM_COMMAND_ID(wparam, lparam) == IDOK);
19996 return TRUE;
19997 }
19998 }
19999 return FALSE;
20000 }
20001
20015 static SQLRETURN
20016 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
20017 SQLCHAR *connIn, SQLSMALLINT connInLen,
20018 SQLCHAR *connOut, SQLSMALLINT connOutMax,
20019 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
20020 {
20021 BOOL maybeprompt, prompt = FALSE, defaultdsn = FALSE;
20022 DBC *d;
20023 SETUPDLG *setupdlg;
20024 SQLRETURN ret;
20025 char *dsn = NULL, *driver = NULL, *dbname = NULL;
20026
20027 if (dbc == SQL_NULL_HDBC) {
20028 return SQL_INVALID_HANDLE;
20029 }
20030 d = (DBC *) dbc;
20031 if (d->sqlite) {
20032 setstatd(d, -1, "connection already established", "08002");
20033 return SQL_ERROR;
20034 }
20035 setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
20036 if (setupdlg == NULL) {
20037 return SQL_ERROR;
20038 }
20039 memset(setupdlg, 0, sizeof (SETUPDLG));
20040 maybeprompt = drvcompl == SQL_DRIVER_COMPLETE ||
20041 drvcompl == SQL_DRIVER_COMPLETE_REQUIRED;
20042 if (connIn == NULL || !connInLen ||
20043 (connInLen == SQL_NTS && !connIn[0])) {
20044 prompt = TRUE;
20045 } else {
20046 ParseAttributes((LPCSTR) connIn, setupdlg);
20047 if (!setupdlg->attr[KEY_DSN].attr[0] &&
20048 drvcompl == SQL_DRIVER_COMPLETE_REQUIRED) {
20049 strcpy(setupdlg->attr[KEY_DSN].attr, "DEFAULT");
20050 defaultdsn = TRUE;
20051 }
20052 GetAttributes(setupdlg);
20053 if (drvcompl == SQL_DRIVER_PROMPT ||
20054 (maybeprompt &&
20055 !setupdlg->attr[KEY_DBNAME].attr[0])) {
20056 prompt = TRUE;
20057 }
20058 }
20059 retry:
20060 if (prompt) {
20061 short dlgret;
20062
20063 setupdlg->defDSN = setupdlg->attr[KEY_DRIVER].attr[0] != '\0';
20064 dlgret = DialogBoxParam(hModule, MAKEINTRESOURCE(DRIVERCONNECT),
20065 hwnd, (DLGPROC) DriverConnectProc,
20066 (LPARAM) setupdlg);
20067
20068 if (!dlgret || dlgret == -1) {
20069 xfree(setupdlg);
20070 return SQL_NO_DATA;
20071 }
20072 }
20073 dsn = setupdlg->attr[KEY_DSN].attr;
20074 driver = setupdlg->attr[KEY_DRIVER].attr;
20075 dbname = setupdlg->attr[KEY_DBNAME].attr;
20076 if (connOut || connOutLen) {
20077 char buf[SQL_MAX_MESSAGE_LENGTH * 8];
20078 int len, count;
20079 char dsn_0 = (dsn && !defaultdsn) ? dsn[0] : '\0';
20080 char drv_0 = driver ? driver[0] : '\0';
20081
20082 buf[0] = '\0';
20083 count = snprintf(buf, sizeof (buf),
20084 "%s%s%s%s%s%sDatabase=%s;StepAPI=%s;"
20085 "SyncPragma=%s;NoTXN=%s;Timeout=%s;"
20086 "ShortNames=%s;LongNames=%s;"
20087 "NoCreat=%s;NoWCHAR=%s;"
20088 "FKSupport=%s;JournalMode=%s;OEMCP=%s;LoadExt=%s;"
20089 "BigInt=%s;JDConv=%s;PWD=%s;AttachAs=%s;ILike=%s",
20090 dsn_0 ? "DSN=" : "",
20091 dsn_0 ? dsn : "",
20092 dsn_0 ? ";" : "",
20093 drv_0 ? "Driver=" : "",
20094 drv_0 ? driver : "",
20095 drv_0 ? ";" : "",
20096 dbname ? dbname : "",
20097 setupdlg->attr[KEY_STEPAPI].attr,
20098 setupdlg->attr[KEY_SYNCP].attr,
20099 setupdlg->attr[KEY_NOTXN].attr,
20100 setupdlg->attr[KEY_BUSY].attr,
20101 setupdlg->attr[KEY_SHORTNAM].attr,
20102 setupdlg->attr[KEY_LONGNAM].attr,
20103 setupdlg->attr[KEY_NOCREAT].attr,
20104 setupdlg->attr[KEY_NOWCHAR].attr,
20105 setupdlg->attr[KEY_FKSUPPORT].attr,
20106 setupdlg->attr[KEY_JMODE].attr,
20107 setupdlg->attr[KEY_OEMCP].attr,
20108 setupdlg->attr[KEY_LOADEXT].attr,
20109 setupdlg->attr[KEY_BIGINT].attr,
20110 setupdlg->attr[KEY_JDCONV].attr,
20111 setupdlg->attr[KEY_PASSWD].attr,
20112 setupdlg->attr[KEY_ATTAS].attr,
20113 setupdlg->attr[KEY_ILIKE].attr);
20114 if (count < 0) {
20115 buf[sizeof (buf) - 1] = '\0';
20116 }
20117 len = min(connOutMax - 1, strlen(buf));
20118 if (connOut) {
20119 strncpy((char *) connOut, buf, len);
20120 connOut[len] = '\0';
20121 }
20122 if (connOutLen) {
20123 *connOutLen = len;
20124 }
20125 }
20126 if (dsn[0]) {
20127 char tracef[SQL_MAX_MESSAGE_LENGTH];
20128
20129 tracef[0] = '\0';
20130 SQLGetPrivateProfileString(setupdlg->attr[KEY_DSN].attr,
20131 "tracefile", "", tracef,
20132 sizeof (tracef), ODBC_INI);
20133 if (tracef[0] != '\0') {
20134 d->trace = fopen(tracef, "a");
20135 }
20136 }
20137 d->nowchar = getbool(setupdlg->attr[KEY_NOWCHAR].attr);
20138 d->shortnames = getbool(setupdlg->attr[KEY_SHORTNAM].attr);
20139 d->longnames = getbool(setupdlg->attr[KEY_LONGNAM].attr);
20140 d->nocreat = getbool(setupdlg->attr[KEY_NOCREAT].attr);
20141 d->fksupport = getbool(setupdlg->attr[KEY_FKSUPPORT].attr);
20142 d->oemcp = getbool(setupdlg->attr[KEY_OEMCP].attr);
20143 d->dobigint = getbool(setupdlg->attr[KEY_BIGINT].attr);
20144 d->jdconv = getbool(setupdlg->attr[KEY_JDCONV].attr);
20145 d->ilike = getbool(setupdlg->attr[KEY_ILIKE].attr);
20146 d->pwdLen = strlen(setupdlg->attr[KEY_PASSWD].attr);
20147 d->pwd = (d->pwdLen > 0) ? setupdlg->attr[KEY_PASSWD].attr : NULL;
20148 ret = dbopen(d, dbname ? dbname : "", 0,
20149 dsn ? dsn : "",
20150 setupdlg->attr[KEY_STEPAPI].attr,
20151 setupdlg->attr[KEY_SYNCP].attr,
20152 setupdlg->attr[KEY_NOTXN].attr,
20153 setupdlg->attr[KEY_JMODE].attr,
20154 setupdlg->attr[KEY_BUSY].attr);
20155 if (ret != SQL_SUCCESS) {
20156 if (maybeprompt && !prompt) {
20157 prompt = TRUE;
20158 goto retry;
20159 }
20160 }
20161 memset(setupdlg->attr[KEY_PASSWD].attr, 0,
20162 sizeof (setupdlg->attr[KEY_PASSWD].attr));
20163 if (ret == SQL_SUCCESS) {
20164 dbloadext(d, setupdlg->attr[KEY_LOADEXT].attr);
20165 dbattas(d, setupdlg->attr[KEY_ATTAS].attr);
20166 }
20167 xfree(setupdlg);
20168 return ret;
20169 }
20170
20171 #endif
20172 #endif
20173
20174 #ifndef WINTERFACE
20175
20188 SQLRETURN SQL_API
20189 SQLDriverConnect(SQLHDBC dbc, SQLHWND hwnd,
20190 SQLCHAR *connIn, SQLSMALLINT connInLen,
20191 SQLCHAR *connOut, SQLSMALLINT connOutMax,
20192 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
20193 {
20194 SQLRETURN ret;
20195
20196 HDBC_LOCK(dbc);
20197 ret = drvdriverconnect(dbc, hwnd, connIn, connInLen,
20198 connOut, connOutMax, connOutLen, drvcompl);
20199 HDBC_UNLOCK(dbc);
20200 return ret;
20201 }
20202 #endif
20203
20204 #ifdef WINTERFACE
20205
20218 SQLRETURN SQL_API
20219 SQLDriverConnectW(SQLHDBC dbc, SQLHWND hwnd,
20220 SQLWCHAR *connIn, SQLSMALLINT connInLen,
20221 SQLWCHAR *connOut, SQLSMALLINT connOutMax,
20222 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
20223 {
20224 SQLRETURN ret;
20225 char *ci = NULL;
20226 SQLSMALLINT len = 0;
20227
20228 HDBC_LOCK(dbc);
20229 if (connIn) {
20230 #if defined(_WIN32) || defined(_WIN64)
20231 if (connInLen == SQL_NTS) {
20232 connInLen = -1;
20233 }
20234 ci = uc_to_wmb(connIn, connInLen);
20235 #else
20236 ci = uc_to_utf(connIn, connInLen);
20237 #endif
20238 if (!ci) {
20239 DBC *d = (DBC *) dbc;
20240
20241 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
20242 HDBC_UNLOCK(dbc);
20243 return SQL_ERROR;
20244 }
20245 }
20246 ret = drvdriverconnect(dbc, hwnd, (SQLCHAR *) ci, SQL_NTS,
20247 (SQLCHAR *) connOut, connOutMax, &len, drvcompl);
20248 HDBC_UNLOCK(dbc);
20249 uc_free(ci);
20250 if (ret == SQL_SUCCESS) {
20251 SQLWCHAR *co = NULL;
20252
20253 if (connOut) {
20254 if (len > 0) {
20255 #if defined(_WIN32) || defined(_WIN64)
20256 co = wmb_to_uc((char *) connOut, len);
20257 #else
20258 co = uc_from_utf((SQLCHAR *) connOut, len);
20259 #endif
20260 if (co) {
20261 uc_strncpy(connOut, co, connOutMax / sizeof (SQLWCHAR));
20262 len = min(connOutMax / sizeof (SQLWCHAR), uc_strlen(co));
20263 uc_free(co);
20264 } else {
20265 len = 0;
20266 }
20267 }
20268 if (len <= 0) {
20269 len = 0;
20270 connOut[0] = 0;
20271 }
20272 } else {
20273 len = 0;
20274 }
20275 if (connOutLen) {
20276 *connOutLen = len;
20277 }
20278 }
20279 return ret;
20280 }
20281 #endif
20282
20283 #if defined(_WIN32) || defined(_WIN64)
20284
20293 BOOL APIENTRY
20294 LibMain(HANDLE hinst, DWORD reason, LPVOID reserved)
20295 {
20296 static int initialized = 0;
20297
20298 switch (reason) {
20299 case DLL_PROCESS_ATTACH:
20300 if (!initialized++) {
20301 hModule = hinst;
20302 #ifdef WINTERFACE
20303
20304 statSpec2P = statSpec2;
20305 statSpec3P = statSpec3;
20306 #endif
20307 #ifdef SQLITE_DYNLOAD
20308 dls_init();
20309 #endif
20310 #ifdef SQLITE_HAS_CODEC
20311 sqlite3_activate_see(SQLITE_ACTIVATION_KEY);
20312 #endif
20313 }
20314 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20315 nvfs_init();
20316 #endif
20317 break;
20318 case DLL_THREAD_ATTACH:
20319 break;
20320 case DLL_PROCESS_DETACH:
20321 if (--initialized <= 0) {
20322 #ifdef SQLITE_DYNLOAD
20323 dls_fini();
20324 #endif
20325 }
20326 break;
20327 case DLL_THREAD_DETACH:
20328 break;
20329 default:
20330 break;
20331 }
20332 return TRUE;
20333 }
20334
20343 int __stdcall
20344 DllMain(HANDLE hinst, DWORD reason, LPVOID reserved)
20345 {
20346 return LibMain(hinst, reason, reserved);
20347 }
20348
20349 #ifndef WITHOUT_INSTALLER
20350
20357 static BOOL
20358 InUnError(char *name)
20359 {
20360 WORD err = 1;
20361 DWORD code;
20362 char errmsg[301];
20363 WORD errlen, errmax = sizeof (errmsg) - 1;
20364 int sqlret;
20365 BOOL ret = FALSE;
20366
20367 do {
20368 errmsg[0] = '\0';
20369 sqlret = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
20370 if (SQL_SUCCEEDED(sqlret)) {
20371 MessageBox(NULL, errmsg, name,
20372 MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20373 ret = TRUE;
20374 }
20375 err++;
20376 } while (sqlret != SQL_NO_DATA);
20377 return ret;
20378 }
20379
20386 static BOOL
20387 InUn(int remove, char *cmdline)
20388 {
20389 #ifdef SQLITE_HAS_CODEC
20390 static char *drivername = "SQLite3 ODBC Driver (SEE)";
20391 static char *dsname = "SQLite3 SEE Datasource";
20392 #else
20393 static char *drivername = "SQLite3 ODBC Driver";
20394 static char *dsname = "SQLite3 Datasource";
20395 #endif
20396 char *dllname, *p;
20397 char dllbuf[301], path[301], driver[300], attr[300], inst[400];
20398 WORD pathmax = sizeof (path) - 1, pathlen;
20399 DWORD usecnt, mincnt;
20400 int quiet = 0;
20401
20402 dllbuf[0] = '\0';
20403 GetModuleFileName(hModule, dllbuf, sizeof (dllbuf));
20404 p = strrchr(dllbuf, '\\');
20405 dllname = p ? (p + 1) : dllbuf;
20406 quiet = cmdline && strstr(cmdline, "quiet");
20407 if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
20408 sprintf(driver, "%s;Driver=%s;Setup=%s;",
20409 drivername, dllname, dllname);
20410 p = driver;
20411 while (*p) {
20412 if (*p == ';') {
20413 *p = '\0';
20414 }
20415 ++p;
20416 }
20417 usecnt = 0;
20418 path[0] = '\0';
20419 SQLInstallDriverEx(driver, NULL, path, pathmax, NULL,
20420 ODBC_INSTALL_INQUIRY, &usecnt);
20421 pathlen = strlen(path);
20422 while (pathlen > 0 && path[pathlen - 1] == '\\') {
20423 --pathlen;
20424 path[pathlen] = '\0';
20425 }
20426 sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
20427 drivername, path, dllname, path, dllname);
20428 p = driver;
20429 while (*p) {
20430 if (*p == ';') {
20431 *p = '\0';
20432 }
20433 ++p;
20434 }
20435 sprintf(inst, "%s\\%s", path, dllname);
20436 if (!remove && usecnt > 0) {
20437
20438 if (GetFileAttributesA(dllbuf) != INVALID_FILE_ATTRIBUTES &&
20439 CopyFile(dllbuf, inst, 0)) {
20440 if (!quiet) {
20441 char buf[512];
20442
20443 sprintf(buf, "%s replaced.", drivername);
20444 MessageBox(NULL, buf, "Info",
20445 MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20446 MB_SETFOREGROUND);
20447 }
20448 return TRUE;
20449 }
20450 }
20451 mincnt = remove ? 1 : 0;
20452 while (usecnt != mincnt) {
20453 if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
20454 break;
20455 }
20456 }
20457 if (remove) {
20458 if (usecnt && !SQLRemoveDriver(driver, TRUE, &usecnt)) {
20459 InUnError("SQLRemoveDriver");
20460 return FALSE;
20461 }
20462 if (!usecnt) {
20463 char buf[512];
20464
20465 DeleteFile(inst);
20466 if (!quiet) {
20467 sprintf(buf, "%s uninstalled.", drivername);
20468 MessageBox(NULL, buf, "Info",
20469 MB_ICONINFORMATION |MB_OK | MB_TASKMODAL |
20470 MB_SETFOREGROUND);
20471 }
20472 }
20473 sprintf(attr, "DSN=%s;Database=;", dsname);
20474 p = attr;
20475 while (*p) {
20476 if (*p == ';') {
20477 *p = '\0';
20478 }
20479 ++p;
20480 }
20481 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20482 return TRUE;
20483 }
20484 if (GetFileAttributesA(dllbuf) == INVALID_FILE_ATTRIBUTES) {
20485 return FALSE;
20486 }
20487 if (strcasecmp(dllbuf, inst) != 0 && !CopyFile(dllbuf, inst, 0)) {
20488 char buf[512];
20489
20490 sprintf(buf, "Copy %s to %s failed.", dllbuf, inst);
20491 MessageBox(NULL, buf, "CopyFile",
20492 MB_ICONSTOP |MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20493 return FALSE;
20494 }
20495 if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
20496 ODBC_INSTALL_COMPLETE, &usecnt)) {
20497 InUnError("SQLInstallDriverEx");
20498 return FALSE;
20499 }
20500 sprintf(attr, "DSN=%s;Database=;", dsname);
20501 p = attr;
20502 while (*p) {
20503 if (*p == ';') {
20504 *p = '\0';
20505 }
20506 ++p;
20507 }
20508 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20509 if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
20510 InUnError("SQLConfigDataSource");
20511 return FALSE;
20512 }
20513 if (!quiet) {
20514 char buf[512];
20515
20516 sprintf(buf, "%s installed.", drivername);
20517 MessageBox(NULL, buf, "Info",
20518 MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20519 MB_SETFOREGROUND);
20520 }
20521 } else {
20522 InUnError("SQLInstallDriverManager");
20523 return FALSE;
20524 }
20525 return TRUE;
20526 }
20527
20536 void CALLBACK
20537 install(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20538 {
20539 InUn(0, lpszCmdLine);
20540 }
20541
20550 void CALLBACK
20551 uninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20552 {
20553 InUn(1, lpszCmdLine);
20554 }
20555
20556 #endif
20557
20558 #ifndef WITHOUT_SHELL
20559
20568 static void
20569 setargv(int *argcp, char ***argvp, char *cmdline, char *argv0)
20570 {
20571 char *p, *arg, *argspace, **argv;
20572 int argc, size, inquote, copy, slashes;
20573
20574 size = 2 + (argv0 ? 1 : 0);
20575 for (p = cmdline; *p != '\0'; p++) {
20576 if (ISSPACE(*p)) {
20577 size++;
20578 while (ISSPACE(*p)) {
20579 p++;
20580 }
20581 if (*p == '\0') {
20582 break;
20583 }
20584 }
20585 }
20586 argspace = malloc(size * sizeof (char *) + strlen(cmdline) + 1);
20587 argv = (char **) argspace;
20588 argspace += size * sizeof (char *);
20589 size--;
20590 argc = 0;
20591 if (argv0) {
20592 argv[argc++] = argv0;
20593 }
20594 p = cmdline;
20595 for (; argc < size; argc++) {
20596 argv[argc] = arg = argspace;
20597 while (ISSPACE(*p)) {
20598 p++;
20599 }
20600 if (*p == '\0') {
20601 break;
20602 }
20603 inquote = 0;
20604 slashes = 0;
20605 while (1) {
20606 copy = 1;
20607 while (*p == '\\') {
20608 slashes++;
20609 p++;
20610 }
20611 if (*p == '"') {
20612 if ((slashes & 1) == 0) {
20613 copy = 0;
20614 if (inquote && p[1] == '"') {
20615 p++;
20616 copy = 1;
20617 } else {
20618 inquote = !inquote;
20619 }
20620 }
20621 slashes >>= 1;
20622 }
20623 while (slashes) {
20624 *arg = '\\';
20625 arg++;
20626 slashes--;
20627 }
20628 if (*p == '\0' || (!inquote && ISSPACE(*p))) {
20629 break;
20630 }
20631 if (copy != 0) {
20632 *arg = *p;
20633 arg++;
20634 }
20635 p++;
20636 }
20637 *arg = '\0';
20638 argspace = arg + 1;
20639 }
20640 argv[argc] = 0;
20641 *argcp = argc;
20642 *argvp = argv;
20643 }
20644
20653 void CALLBACK
20654 shell(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20655 {
20656 int argc, needcon = 0;
20657 char **argv;
20658 extern int sqlite3_main(int, char **);
20659 static const char *name = "SQLite3 Shell";
20660 DWORD ftype0, ftype1, ftype2;
20661
20662 ftype0 = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
20663 ftype1 = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
20664 ftype2 = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
20665 if (ftype0 != FILE_TYPE_DISK && ftype0 != FILE_TYPE_CHAR &&
20666 ftype0 != FILE_TYPE_PIPE) {
20667 fclose(stdin);
20668 ++needcon;
20669 ftype0 = FILE_TYPE_UNKNOWN;
20670 }
20671 if (ftype1 != FILE_TYPE_DISK && ftype1 != FILE_TYPE_CHAR &&
20672 ftype1 != FILE_TYPE_PIPE) {
20673 fclose(stdout);
20674 ++needcon;
20675 ftype1 = FILE_TYPE_UNKNOWN;
20676 }
20677 if (ftype2 != FILE_TYPE_DISK && ftype2 != FILE_TYPE_CHAR &&
20678 ftype2 != FILE_TYPE_PIPE) {
20679 fclose(stderr);
20680 ++needcon;
20681 ftype2 = FILE_TYPE_UNKNOWN;
20682 }
20683 if (needcon > 0) {
20684 AllocConsole();
20685 SetConsoleTitle(name);
20686 }
20687 if (ftype0 == FILE_TYPE_UNKNOWN) {
20688 freopen("CONIN$", "r", stdin);
20689 }
20690 if (ftype1 == FILE_TYPE_UNKNOWN) {
20691 freopen("CONOUT$", "w", stdout);
20692 }
20693 if (ftype2 == FILE_TYPE_UNKNOWN) {
20694 freopen("CONOUT$", "w", stderr);
20695 }
20696 setargv(&argc, &argv, lpszCmdLine, (char *) name);
20697 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20698 nvfs_init();
20699 #endif
20700 sqlite3_main(argc, argv);
20701 }
20702
20703 #endif
20704
20705 #endif
20706
20707 #if defined(HAVE_ODBCINSTEXT_H) && (HAVE_ODBCINSTEXT_H)
20708
20709
20710
20711
20712
20713
20714 #include <odbcinstext.h>
20715
20716 int
20717 ODBCINSTGetProperties(HODBCINSTPROPERTY prop)
20718 {
20719 static const char *instYN[] = { "No", "Yes", NULL };
20720 static const char *syncPragma[] = { "NORMAL", "OFF", "FULL", NULL };
20721 static const char *jmPragma[] = {
20722 "DELETE", "PERSIST", "OFF", "TRUNCATE", "MEMORY", "WAL", NULL
20723 };
20724
20725 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20726 prop = prop->pNext;
20727 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20728 prop->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
20729 strncpy(prop->szName, "Database", INI_MAX_PROPERTY_NAME);
20730 strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20731 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20732 prop = prop->pNext;
20733 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20734 prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20735 strncpy(prop->szName, "Timeout", INI_MAX_PROPERTY_NAME);
20736 strncpy(prop->szValue, "100000", INI_MAX_PROPERTY_VALUE);
20737 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20738 prop = prop->pNext;
20739 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20740 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20741 prop->aPromptData = malloc(sizeof (instYN));
20742 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20743 strncpy(prop->szName, "StepAPI", INI_MAX_PROPERTY_NAME);
20744 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20745 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20746 prop = prop->pNext;
20747 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20748 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20749 prop->aPromptData = malloc(sizeof (instYN));
20750 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20751 strncpy(prop->szName, "ShortNames", INI_MAX_PROPERTY_NAME);
20752 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20753 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20754 prop = prop->pNext;
20755 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20756 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20757 prop->aPromptData = malloc(sizeof (instYN));
20758 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20759 strncpy(prop->szName, "LongNames", INI_MAX_PROPERTY_NAME);
20760 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20761 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20762 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20763 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20764 prop->aPromptData = malloc(sizeof (instYN));
20765 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20766 strncpy(prop->szName, "NoCreat", INI_MAX_PROPERTY_NAME);
20767 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20768 #ifdef WINTERFACE
20769 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20770 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20771 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20772 prop->aPromptData = malloc(sizeof (instYN));
20773 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20774 strncpy(prop->szName, "NoWCHAR", INI_MAX_PROPERTY_NAME);
20775 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20776 #endif
20777 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20778 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20779 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20780 prop->aPromptData = malloc(sizeof (instYN));
20781 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20782 strncpy(prop->szName, "FKSupport", INI_MAX_PROPERTY_NAME);
20783 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20784 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20785 prop = prop->pNext;
20786 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20787 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20788 prop->aPromptData = malloc(sizeof (syncPragma));
20789 memcpy(prop->aPromptData, syncPragma, sizeof (syncPragma));
20790 strncpy(prop->szName, "SyncPragma", INI_MAX_PROPERTY_NAME);
20791 strncpy(prop->szValue, "NORMAL", INI_MAX_PROPERTY_VALUE);
20792 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20793 prop = prop->pNext;
20794 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20795 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20796 prop->aPromptData = malloc(sizeof (jmPragma));
20797 memcpy(prop->aPromptData, jmPragma, sizeof (jmPragma));
20798 strncpy(prop->szName, "JournalMode", INI_MAX_PROPERTY_NAME);
20799 strncpy(prop->szValue, "DELETE", INI_MAX_PROPERTY_VALUE);
20800 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20801 prop = prop->pNext;
20802 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20803 prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20804 strncpy(prop->szName, "LoadExt", INI_MAX_PROPERTY_NAME);
20805 strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20806 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20807 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20808 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20809 prop->aPromptData = malloc(sizeof (instYN));
20810 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20811 strncpy(prop->szName, "BigInt", INI_MAX_PROPERTY_NAME);
20812 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20813 return 1;
20814 }
20815
20816 #endif
20817
20818 #ifdef SQLITE_DYNLOAD
20819
20820
20821
20822
20823
20824 static void
20825 dls_void(void)
20826 {
20827 }
20828
20829 static int
20830 dls_error(void)
20831 {
20832 return SQLITE_ERROR;
20833 }
20834
20835 static int
20836 dls_0(void)
20837 {
20838 return 0;
20839 }
20840
20841 static sqlite_int64
20842 dls_0LL(void)
20843 {
20844 return 0;
20845 }
20846
20847 static double
20848 dls_00(void)
20849 {
20850 return 0;
20851 }
20852
20853 static void *
20854 dls_null(void)
20855 {
20856 return NULL;
20857 }
20858
20859 static const char *
20860 dls_empty(void)
20861 {
20862 return "";
20863 }
20864
20865 static int
20866 dls_snull(void)
20867 {
20868 return SQLITE_NULL;
20869 }
20870
20871 #define DLS_ENT(name, func) \
20872 { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, name), \
20873 (void *) func }
20874
20875 #define DLS_ENT3(name, off, func) \
20876 { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, off), \
20877 (void *) func }
20878
20879 #define DLS_END { NULL, 0, NULL }
20880
20881 static struct {
20882 const char *name;
20883 int offset;
20884 void *func;
20885 } dls_nametab[] = {
20886 DLS_ENT(activate_see, dls_void),
20887 DLS_ENT(bind_blob, dls_error),
20888 DLS_ENT(bind_double, dls_error),
20889 DLS_ENT(bind_int, dls_error),
20890 DLS_ENT(bind_int64, dls_error),
20891 DLS_ENT(bind_null, dls_error),
20892 DLS_ENT(bind_parameter_count, dls_0),
20893 DLS_ENT(bind_text, dls_error),
20894 DLS_ENT(busy_handler, dls_error),
20895 DLS_ENT(changes, dls_0),
20896 DLS_ENT(close, dls_error),
20897 DLS_ENT(column_blob, dls_null),
20898 DLS_ENT(column_bytes, dls_0),
20899 DLS_ENT(column_count, dls_0),
20900 DLS_ENT(column_database_name, dls_empty),
20901 DLS_ENT(column_decltype, dls_empty),
20902 DLS_ENT(column_double, dls_00),
20903 DLS_ENT(column_name, dls_empty),
20904 DLS_ENT(column_origin_name, dls_null),
20905 DLS_ENT(column_table_name, dls_null),
20906 DLS_ENT(column_text, dls_null),
20907 DLS_ENT(column_type, dls_snull),
20908 DLS_ENT(create_function, dls_error),
20909 DLS_ENT(enable_load_extension, dls_error),
20910 DLS_ENT(errcode, dls_error),
20911 DLS_ENT(errmsg, dls_empty),
20912 DLS_ENT(exec, dls_error),
20913 DLS_ENT(finalize, dls_error),
20914 DLS_ENT(free, free),
20915 DLS_ENT(free_table, dls_void),
20916 DLS_ENT(get_table, dls_error),
20917 DLS_ENT(interrupt, dls_void),
20918 DLS_ENT(key, dls_error),
20919 DLS_ENT(last_insert_rowid, dls_0LL),
20920 DLS_ENT(libversion, dls_empty),
20921 DLS_ENT(load_extension, dls_error),
20922 DLS_ENT(malloc, malloc),
20923 DLS_ENT(mprintf, dls_null),
20924 DLS_ENT(open, dls_error),
20925 DLS_ENT(open16, dls_error),
20926 DLS_ENT(open_v2, dls_error),
20927 DLS_ENT(prepare, dls_error),
20928 DLS_ENT(prepare_v2, dls_error),
20929 DLS_ENT(profile, dls_null),
20930 DLS_ENT(realloc, realloc),
20931 DLS_ENT(rekey, dls_error),
20932 DLS_ENT(reset, dls_error),
20933 DLS_ENT(result_blob, dls_void),
20934 DLS_ENT(result_error, dls_void),
20935 DLS_ENT(result_int, dls_void),
20936 DLS_ENT(result_null, dls_void),
20937 DLS_ENT(step, dls_error),
20938 #if defined(_WIN32) || defined(_WIN64)
20939 DLS_ENT3(strnicmp, xstrnicmp, _strnicmp),
20940 #else
20941 DLS_ENT3(strnicmp, xstrnicmp, strncasecmp),
20942 #endif
20943 DLS_ENT(table_column_metadata, dls_error),
20944 DLS_ENT(trace, dls_null),
20945 DLS_ENT(user_data, dls_null),
20946 DLS_ENT(value_blob, dls_null),
20947 DLS_ENT(value_bytes, dls_0),
20948 DLS_ENT(value_text, dls_empty),
20949 DLS_ENT(value_type, dls_snull),
20950 DLS_END
20951 };
20952
20953 #if defined(_WIN32) || defined(_WIN64)
20954
20955 static HMODULE sqlite3_dll = 0;
20956
20957 static void
20958 dls_init(void)
20959 {
20960 int i;
20961 static const char *dll_names[] = {
20962 "System.Data.SQLite.dll",
20963 "sqlite3.dll",
20964 NULL,
20965 };
20966
20967 i = 0;
20968 while (dll_names[i]) {
20969 sqlite3_dll = LoadLibrary(dll_names[i]);
20970 if (sqlite3_dll) {
20971 break;
20972 }
20973 ++i;
20974 }
20975 i = 0;
20976 while (dls_nametab[i].name) {
20977 void *func = 0, **loc;
20978
20979 if (sqlite3_dll) {
20980 func = (void *) GetProcAddress(sqlite3_dll, dls_nametab[i].name);
20981 }
20982 if (!func) {
20983 func = dls_nametab[i].func;
20984 }
20985 loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20986 *loc = func;
20987 ++i;
20988 }
20989 if (!sqlite3_dll) {
20990 char buf[MAXPATHLEN], msg[MAXPATHLEN];
20991
20992 LoadString(hModule, IDS_DRVTITLE, buf, sizeof (buf));
20993 LoadString(hModule, IDS_DLLERR, msg, sizeof (msg));
20994 MessageBox(NULL, msg, buf,
20995 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
20996 MB_SETFOREGROUND);
20997 }
20998 }
20999
21000 static void
21001 dls_fini(void)
21002 {
21003 if (sqlite3_dll) {
21004 FreeLibrary(sqlite3_dll);
21005 sqlite3_dll = 0;
21006 }
21007 }
21008
21009 #else
21010
21011 #include <dlfcn.h>
21012
21013 static void *libsqlite3_so = 0;
21014
21015 void
21016 dls_init(void)
21017 {
21018 int i;
21019
21020 libsqlite3_so = dlopen("libsqlite3.so.0", RTLD_NOW | RTLD_GLOBAL);
21021 i = 0;
21022 while (dls_nametab[i].name) {
21023 void *func = 0, **loc;
21024
21025 if (libsqlite3_so) {
21026 func = dlsym(libsqlite3_so, dls_nametab[i].name);
21027 }
21028 if (!func) {
21029 func = dls_nametab[i].func;
21030 }
21031 loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
21032 *loc = func;
21033 ++i;
21034 }
21035 if (!libsqlite3_so) {
21036 const char errmsg[] = "SQLite3 shared library not found.\n";
21037
21038 write(2, errmsg, sizeof (errmsg) - 1);
21039 }
21040 }
21041
21042 void
21043 dls_fini(void)
21044 {
21045 if (libsqlite3_so) {
21046 dlclose(libsqlite3_so);
21047 libsqlite3_so = 0;
21048 }
21049 }
21050
21051 #endif
21052
21053 #endif
21054
21055
21056
21057
21058
21059
21060
21061
21062