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);
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);
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);
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);
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 if (c < 0xfc) {
00914 if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 &&
00915 (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) {
00916 unsigned long t = ((c & 0x01) << 24) |
00917 ((str[1] & 0x3f) << 18) | ((str[2] & 0x3f) << 12) |
00918 ((str[3] & 0x3f) << 6) | (str[4] & 0x3f);
00919
00920 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
00921 t >= 0x10000) {
00922 t -= 0x10000;
00923 uc[i++] = 0xd800 | ((t >> 10) & 0x3ff);
00924 if (i >= ucLen) {
00925 break;
00926 }
00927 t = 0xdc00 | (t & 0x3ff);
00928 }
00929 uc[i++] = t;
00930 str += 5;
00931 } else {
00932 uc[i++] = c;
00933 ++str;
00934 }
00935 } else {
00936
00937 ++str;
00938 }
00939 }
00940 if (i < ucLen) {
00941 uc[i] = 0;
00942 }
00943 }
00944 }
00945
00953 static SQLWCHAR *
00954 uc_from_utf(unsigned char *str, int len)
00955 {
00956 SQLWCHAR *uc = NULL;
00957 int ucLen;
00958
00959 if (str) {
00960 if (len == SQL_NTS) {
00961 len = strlen((char *) str);
00962 }
00963 ucLen = sizeof (SQLWCHAR) * (len + 1);
00964 uc = xmalloc(ucLen);
00965 if (uc) {
00966 uc_from_utf_buf(str, len, uc, ucLen);
00967 }
00968 }
00969 return uc;
00970 }
00971
00979 static char *
00980 uc_to_utf(SQLWCHAR *str, int len)
00981 {
00982 int i;
00983 char *cp, *ret = NULL;
00984
00985 if (!str) {
00986 return ret;
00987 }
00988 if (len == SQL_NTS) {
00989 len = uc_strlen(str);
00990 } else {
00991 len = len / sizeof (SQLWCHAR);
00992 }
00993 cp = xmalloc(len * 6 + 1);
00994 if (!cp) {
00995 return ret;
00996 }
00997 ret = cp;
00998 for (i = 0; i < len; i++) {
00999 unsigned long c = str[i];
01000
01001 if (sizeof (SQLWCHAR) == 2 * sizeof (char)) {
01002 c &= 0xffff;
01003 }
01004 if (c < 0x80) {
01005 *cp++ = c;
01006 } else if (c < 0x800) {
01007 *cp++ = 0xc0 | ((c >> 6) & 0x1f);
01008 *cp++ = 0x80 | (c & 0x3f);
01009 } else if (c < 0x10000) {
01010 if (sizeof (SQLWCHAR) == 2 * sizeof (char) &&
01011 c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
01012 unsigned long c2 = str[i + 1] & 0xffff;
01013
01014 if (c2 >= 0xdc00 && c2 <= 0xdfff) {
01015 c = (((c & 0x3ff) << 10) | (c2 & 0x3ff)) + 0x10000;
01016 *cp++ = 0xf0 | ((c >> 18) & 0x07);
01017 *cp++ = 0x80 | ((c >> 12) & 0x3f);
01018 *cp++ = 0x80 | ((c >> 6) & 0x3f);
01019 *cp++ = 0x80 | (c & 0x3f);
01020 ++i;
01021 continue;
01022 }
01023 }
01024 *cp++ = 0xe0 | ((c >> 12) & 0x0f);
01025 *cp++ = 0x80 | ((c >> 6) & 0x3f);
01026 *cp++ = 0x80 | (c & 0x3f);
01027 } else if (c < 0x200000) {
01028 *cp++ = 0xf0 | ((c >> 18) & 0x07);
01029 *cp++ = 0x80 | ((c >> 12) & 0x3f);
01030 *cp++ = 0x80 | ((c >> 6) & 0x3f);
01031 *cp++ = 0x80 | (c & 0x3f);
01032 } else if (c < 0x4000000) {
01033 *cp++ = 0xf8 | ((c >> 24) & 0x03);
01034 *cp++ = 0x80 | ((c >> 18) & 0x3f);
01035 *cp++ = 0x80 | ((c >> 12) & 0x3f);
01036 *cp++ = 0x80 | ((c >> 6) & 0x3f);
01037 *cp++ = 0x80 | (c & 0x3f);
01038 } else if (c < 0x80000000) {
01039 *cp++ = 0xfc | ((c >> 31) & 0x01);
01040 *cp++ = 0x80 | ((c >> 24) & 0x3f);
01041 *cp++ = 0x80 | ((c >> 18) & 0x3f);
01042 *cp++ = 0x80 | ((c >> 12) & 0x3f);
01043 *cp++ = 0x80 | ((c >> 6) & 0x3f);
01044 *cp++ = 0x80 | (c & 0x3f);
01045 }
01046 }
01047 *cp = '\0';
01048 return ret;
01049 }
01050
01051 #endif
01052
01053 #ifdef WINTERFACE
01054
01062 static char *
01063 uc_to_utf_c(SQLWCHAR *str, int len)
01064 {
01065 if (len != SQL_NTS) {
01066 len = len * sizeof (SQLWCHAR);
01067 }
01068 return uc_to_utf(str, len);
01069 }
01070
01071 #endif
01072
01073 #if defined(WCHARSUPPORT) || defined(_WIN32) || defined(_WIN64)
01074
01080 static void
01081 uc_free(void *str)
01082 {
01083 if (str) {
01084 xfree(str);
01085 }
01086 }
01087
01088 #endif
01089
01090 #if defined(_WIN32) || defined(_WIN64)
01091
01099 static char *
01100 wmb_to_utf(char *str, int len)
01101 {
01102 WCHAR *wstr;
01103 OSVERSIONINFO ovi;
01104 int nchar, is2k, cp = CP_OEMCP;
01105
01106 ovi.dwOSVersionInfoSize = sizeof (ovi);
01107 GetVersionEx(&ovi);
01108 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01109 if (AreFileApisANSI()) {
01110 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01111 }
01112 nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
01113 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
01114 if (!wstr) {
01115 return NULL;
01116 }
01117 wstr[0] = 0;
01118 nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
01119 wstr[nchar] = 0;
01120 str = xmalloc((nchar + 1) * 7);
01121 if (!str) {
01122 xfree(wstr);
01123 return NULL;
01124 }
01125 str[0] = '\0';
01126 nchar = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, nchar * 7, 0, 0);
01127 str[nchar] = '\0';
01128 xfree(wstr);
01129 return str;
01130 }
01131
01132 #ifndef WINTERFACE
01133
01141 static char *
01142 wmb_to_utf_c(char *str, int len)
01143 {
01144 if (len == SQL_NTS) {
01145 len = strlen(str);
01146 }
01147 return wmb_to_utf(str, len);
01148 }
01149
01150 #endif
01151
01159 static char *
01160 utf_to_wmb(char *str, int len)
01161 {
01162 WCHAR *wstr;
01163 OSVERSIONINFO ovi;
01164 int nchar, is2k, cp = CP_OEMCP;
01165
01166 ovi.dwOSVersionInfoSize = sizeof (ovi);
01167 GetVersionEx(&ovi);
01168 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01169 if (AreFileApisANSI()) {
01170 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01171 }
01172 nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
01173 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
01174 if (!wstr) {
01175 return NULL;
01176 }
01177 wstr[0] = 0;
01178 nchar = MultiByteToWideChar(CP_UTF8, 0, str, len, wstr, nchar);
01179 wstr[nchar] = 0;
01180 str = xmalloc((nchar + 1) * 7);
01181 if (!str) {
01182 xfree(wstr);
01183 return NULL;
01184 }
01185 str[0] = '\0';
01186 nchar = WideCharToMultiByte(cp, 0, wstr, -1, str, nchar * 7, 0, 0);
01187 str[nchar] = '\0';
01188 xfree(wstr);
01189 return str;
01190 }
01191
01192 #ifdef WINTERFACE
01193
01201 static WCHAR *
01202 wmb_to_uc(char *str, int len)
01203 {
01204 WCHAR *wstr;
01205 OSVERSIONINFO ovi;
01206 int nchar, is2k, cp = CP_OEMCP;
01207
01208 ovi.dwOSVersionInfoSize = sizeof (ovi);
01209 GetVersionEx(&ovi);
01210 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01211 if (AreFileApisANSI()) {
01212 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01213 }
01214 nchar = MultiByteToWideChar(cp, 0, str, len, NULL, 0);
01215 wstr = xmalloc((nchar + 1) * sizeof (WCHAR));
01216 if (!wstr) {
01217 return NULL;
01218 }
01219 wstr[0] = 0;
01220 nchar = MultiByteToWideChar(cp, 0, str, len, wstr, nchar);
01221 wstr[nchar] = 0;
01222 return wstr;
01223 }
01224
01232 static char *
01233 uc_to_wmb(WCHAR *wstr, int len)
01234 {
01235 char *str;
01236 OSVERSIONINFO ovi;
01237 int nchar, is2k, cp = CP_OEMCP;
01238
01239 ovi.dwOSVersionInfoSize = sizeof (ovi);
01240 GetVersionEx(&ovi);
01241 is2k = ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4;
01242 if (AreFileApisANSI()) {
01243 cp = is2k ? CP_THREAD_ACP : CP_ACP;
01244 }
01245 nchar = WideCharToMultiByte(cp, 0, wstr, len, NULL, 0, 0, 0);
01246 str = xmalloc((nchar + 1) * 2);
01247 if (!str) {
01248 return NULL;
01249 }
01250 str[0] = '\0';
01251 nchar = WideCharToMultiByte(cp, 0, wstr, len, str, nchar * 2, 0, 0);
01252 str[nchar] = '\0';
01253 return str;
01254 }
01255
01256 #endif
01257
01258 #endif
01259
01260
01261 #ifdef USE_DLOPEN_FOR_GPPS
01262
01263 #include <dlfcn.h>
01264
01265 #define SQLGetPrivateProfileString(A,B,C,D,E,F) drvgpps(d,A,B,C,D,E,F)
01266
01267
01268
01269
01270
01271
01272
01273
01274 static void
01275 drvgetgpps(DBC *d)
01276 {
01277 void *lib;
01278 int (*gpps)();
01279
01280 lib = dlopen("libodbcinst.so.2", RTLD_LAZY);
01281 if (!lib) {
01282 lib = dlopen("libodbcinst.so.1", RTLD_LAZY);
01283 }
01284 if (!lib) {
01285 lib = dlopen("libodbcinst.so", RTLD_LAZY);
01286 }
01287 if (!lib) {
01288 lib = dlopen("libiodbcinst.so.2", RTLD_LAZY);
01289 }
01290 if (!lib) {
01291 lib = dlopen("libiodbcinst.so", RTLD_LAZY);
01292 }
01293 if (lib) {
01294 gpps = (int (*)()) dlsym(lib, "SQLGetPrivateProfileString");
01295 if (!gpps) {
01296 dlclose(lib);
01297 return;
01298 }
01299 d->instlib = lib;
01300 d->gpps = gpps;
01301 }
01302 }
01303
01304 static void
01305 drvrelgpps(DBC *d)
01306 {
01307 if (d->instlib) {
01308 dlclose(d->instlib);
01309 d->instlib = 0;
01310 }
01311 }
01312
01313 static int
01314 drvgpps(DBC *d, char *sect, char *ent, char *def, char *buf,
01315 int bufsiz, char *fname)
01316 {
01317 if (d->gpps) {
01318 return d->gpps(sect, ent, def, buf, bufsiz, fname);
01319 }
01320 strncpy(buf, def, bufsiz);
01321 buf[bufsiz - 1] = '\0';
01322 return 1;
01323 }
01324 #else
01325 #include <odbcinst.h>
01326 #define drvgetgpps(d)
01327 #define drvrelgpps(d)
01328 #endif
01329
01330
01331
01332
01333
01334 static void
01335 s3bind(DBC *d, sqlite3_stmt *stmt, int nparams, BINDPARM *p)
01336 {
01337 int i;
01338
01339 if (stmt && p && nparams > 0) {
01340 for (i = 0; i < nparams; i++, p++) {
01341 switch (p->s3type) {
01342 default:
01343 case SQLITE_NULL:
01344 sqlite3_bind_null(stmt, i + 1);
01345 if (d->trace) {
01346 fprintf(d->trace, "-- parameter %d: NULL\n", i + 1);
01347 fflush(d->trace);
01348 }
01349 break;
01350 case SQLITE_TEXT:
01351 sqlite3_bind_text(stmt, i + 1, p->s3val, p->s3size,
01352 SQLITE_STATIC);
01353 if (d->trace) {
01354 fprintf(d->trace, "-- parameter %d: '%*s'\n", i + 1,
01355 p->s3size, (char *) p->s3val);
01356 fflush(d->trace);
01357 }
01358 break;
01359 case SQLITE_BLOB:
01360 sqlite3_bind_blob(stmt, i + 1, p->s3val, p->s3size,
01361 SQLITE_STATIC);
01362 if (d->trace) {
01363 fprintf(d->trace, "-- parameter %d: [BLOB]'\n", i + 1);
01364 fflush(d->trace);
01365 }
01366 break;
01367 case SQLITE_FLOAT:
01368 sqlite3_bind_double(stmt, i + 1, p->s3dval);
01369 if (d->trace) {
01370 fprintf(d->trace, "-- parameter %d: %g\n",
01371 i + 1, p->s3dval);
01372 fflush(d->trace);
01373 }
01374 break;
01375 case SQLITE_INTEGER:
01376 if (p->s3size > sizeof (int)) {
01377 sqlite3_bind_int64(stmt, i + 1, p->s3lival);
01378 if (d->trace) {
01379 fprintf(d->trace,
01380 #ifdef _WIN32
01381 "-- parameter %d: %I64d\n",
01382 #else
01383 "-- parameter %d: %lld\n",
01384 #endif
01385 i + 1, p->s3lival);
01386 fflush(d->trace);
01387 }
01388 } else {
01389 sqlite3_bind_int(stmt, i + 1, p->s3ival);
01390 if (d->trace) {
01391 fprintf(d->trace, "-- parameter %d: %d\n",
01392 i + 1, p->s3ival);
01393 fflush(d->trace);
01394 }
01395 }
01396 break;
01397 }
01398 }
01399 }
01400 }
01401
01409 typedef struct tblres {
01410 char **resarr;
01411 char *errmsg;
01412 sqlite3_stmt *stmt;
01413 STMT *s;
01414 int nalloc;
01415 int nrow;
01416 int ncol;
01417 PTRDIFF_T ndata;
01418 int rc;
01419 } TBLRES;
01420
01421
01422
01423
01424
01425
01426 static int
01427 drvgettable_row(TBLRES *t, int ncol, int rc)
01428 {
01429 int need;
01430 int i;
01431 char *p;
01432
01433 if (t->nrow == 0 && rc == SQLITE_ROW) {
01434 need = ncol * 2;
01435 } else {
01436 need = ncol;
01437 }
01438 if (t->ndata + need >= t->nalloc) {
01439 char **resnew;
01440 int nalloc = t->nalloc * 2 + need + 1;
01441
01442 resnew = xrealloc(t->resarr, sizeof (char *) * nalloc);
01443 if (!resnew) {
01444 nomem:
01445 t->rc = SQLITE_NOMEM;
01446 return 1;
01447 }
01448 t->nalloc = nalloc;
01449 t->resarr = resnew;
01450 }
01451
01452 if (t->nrow == 0) {
01453 t->ncol = ncol;
01454 for (i = 0; i < ncol; i++) {
01455 p = (char *) sqlite3_column_name(t->stmt, i);
01456 if (p) {
01457 char *q = xmalloc(strlen(p) + 1);
01458
01459 if (!q) {
01460 goto nomem;
01461 }
01462 strcpy(q, p);
01463 p = q;
01464 }
01465 t->resarr[t->ndata++] = p;
01466 }
01467 if (t->s && t->s->guessed_types) {
01468 int ncol2 = ncol;
01469
01470 setupdyncols(t->s, t->stmt, &ncol2);
01471 t->s->guessed_types = 0;
01472 t->s->ncols = ncol;
01473 }
01474 } else if (t->ncol != ncol) {
01475 t->errmsg = sqlite3_mprintf("drvgettable() called with two or"
01476 " more incompatible queries");
01477 t->rc = SQLITE_ERROR;
01478 return 1;
01479 }
01480
01481 if (rc == SQLITE_ROW) {
01482 for (i = 0; i < ncol; i++) {
01483 int coltype = sqlite3_column_type(t->stmt, i);
01484
01485 p = NULL;
01486 if (coltype == SQLITE_BLOB) {
01487 int k, nbytes = sqlite3_column_bytes(t->stmt, i);
01488 char *qp;
01489 unsigned const char *bp;
01490
01491 bp = sqlite3_column_blob(t->stmt, i);
01492 qp = xmalloc(nbytes * 2 + 4);
01493 if (!qp) {
01494 goto nomem;
01495 }
01496 p = qp;
01497 *qp++ = 'X';
01498 *qp++ = '\'';
01499 for (k = 0; k < nbytes; k++) {
01500 *qp++ = xdigits[(bp[k] >> 4)];
01501 *qp++ = xdigits[(bp[k] & 0xF)];
01502 }
01503 *qp++ = '\'';
01504 *qp = '\0';
01505 #ifdef _MSC_VER
01506 } else if (coltype == SQLITE_FLOAT) {
01507 struct lconv *lc = 0;
01508 double val = sqlite3_column_double(t->stmt, i);
01509 char buffer[128];
01510
01511
01512
01513
01514
01515
01516 snprintf(buffer, sizeof (buffer), "%.15g", val);
01517 lc = localeconv();
01518 if (lc && lc->decimal_point && lc->decimal_point[0] &&
01519 lc->decimal_point[0] != '.') {
01520 p = strchr(buffer, lc->decimal_point[0]);
01521 if (p) {
01522 *p = '.';
01523 }
01524 }
01525 p = xstrdup(buffer);
01526 if (!p) {
01527 goto nomem;
01528 }
01529 #endif
01530 } else if (coltype != SQLITE_NULL) {
01531 p = xstrdup((char *) sqlite3_column_text(t->stmt, i));
01532 if (!p) {
01533 goto nomem;
01534 }
01535 }
01536 t->resarr[t->ndata++] = p;
01537 }
01538 t->nrow++;
01539 }
01540 return 0;
01541 }
01542
01543 static int
01544 drvgettable(STMT *s, const char *sql, char ***resp, int *nrowp,
01545 int *ncolp, char **errp, int nparam, BINDPARM *p)
01546 {
01547 DBC *d = (DBC *) s->dbc;
01548 int rc = SQLITE_OK, keep = sql == NULL;
01549 TBLRES tres;
01550 const char *sqlleft = 0;
01551 int nretry = 0, haveerr = 0;
01552
01553 if (!resp) {
01554 return SQLITE_ERROR;
01555 }
01556 *resp = NULL;
01557 if (nrowp) {
01558 *nrowp = 0;
01559 }
01560 if (ncolp) {
01561 *ncolp = 0;
01562 }
01563 tres.errmsg = NULL;
01564 tres.nrow = 0;
01565 tres.ncol = 0;
01566 tres.ndata = 1;
01567 tres.nalloc = 20;
01568 tres.rc = SQLITE_OK;
01569 tres.resarr = xmalloc(sizeof (char *) * tres.nalloc);
01570 tres.stmt = NULL;
01571 tres.s = s;
01572 if (!tres.resarr) {
01573 return SQLITE_NOMEM;
01574 }
01575 tres.resarr[0] = 0;
01576 if (sql == NULL) {
01577 tres.stmt = s->s3stmt;
01578 if (tres.stmt == NULL) {
01579 return SQLITE_NOMEM;
01580 }
01581 goto retrieve;
01582 }
01583 while (sql && *sql && (rc == SQLITE_OK ||
01584 (rc == SQLITE_SCHEMA && (++nretry) < 2))) {
01585 int ncol;
01586
01587 tres.stmt = NULL;
01588 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
01589 dbtraceapi(d, "sqlite3_prepare_v2", sql);
01590 rc = sqlite3_prepare_v2(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
01591 #else
01592 dbtraceapi(d, "sqlite3_prepare", sql);
01593 rc = sqlite3_prepare(d->sqlite, sql, -1, &tres.stmt, &sqlleft);
01594 #endif
01595 if (rc != SQLITE_OK) {
01596 if (tres.stmt) {
01597 dbtraceapi(d, "sqlite3_finalize", 0);
01598 sqlite3_finalize(tres.stmt);
01599 tres.stmt = NULL;
01600 }
01601 continue;
01602 }
01603 if (!tres.stmt) {
01604
01605 sql = sqlleft;
01606 continue;
01607 }
01608 retrieve:
01609 if (sqlite3_bind_parameter_count(tres.stmt) != nparam) {
01610 if (errp) {
01611 *errp =
01612 sqlite3_mprintf("%s", "parameter marker count incorrect");
01613 }
01614 haveerr = 1;
01615 rc = SQLITE_ERROR;
01616 goto tbldone;
01617 }
01618 s3bind(d, tres.stmt, nparam, p);
01619 ncol = sqlite3_column_count(tres.stmt);
01620 while (1) {
01621 if (s->max_rows && tres.nrow >= s->max_rows) {
01622 rc = SQLITE_OK;
01623 break;
01624 }
01625 rc = sqlite3_step(tres.stmt);
01626 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
01627 if (drvgettable_row(&tres, ncol, rc)) {
01628 rc = SQLITE_ABORT;
01629 goto tbldone;
01630 }
01631 }
01632 if (rc != SQLITE_ROW) {
01633 if (keep) {
01634 dbtraceapi(d, "sqlite3_reset", 0);
01635 rc = sqlite3_reset(tres.stmt);
01636 s->s3stmt_noreset = 1;
01637 } else {
01638 dbtraceapi(d, "sqlite3_finalize", 0);
01639 rc = sqlite3_finalize(tres.stmt);
01640 }
01641 tres.stmt = 0;
01642 if (rc != SQLITE_SCHEMA) {
01643 nretry = 0;
01644 sql = sqlleft;
01645 while (sql && ISSPACE(*sql)) {
01646 sql++;
01647 }
01648 }
01649 if (rc == SQLITE_DONE) {
01650 rc = SQLITE_OK;
01651 }
01652 break;
01653 }
01654 }
01655 }
01656 tbldone:
01657 if (tres.stmt) {
01658 if (keep) {
01659 if (!s->s3stmt_noreset) {
01660 dbtraceapi(d, "sqlite3_reset", 0);
01661 sqlite3_reset(tres.stmt);
01662 s->s3stmt_noreset = 1;
01663 }
01664 } else {
01665 dbtraceapi(d, "sqlite3_finalize", 0);
01666 sqlite3_finalize(tres.stmt);
01667 }
01668 }
01669 if (haveerr) {
01670
01671 } else if (rc != SQLITE_OK && rc == sqlite3_errcode(d->sqlite) && errp) {
01672 *errp = sqlite3_mprintf("%s", sqlite3_errmsg(d->sqlite));
01673 } else if (errp) {
01674 *errp = NULL;
01675 }
01676 if (tres.resarr) {
01677 tres.resarr[0] = (char *) (tres.ndata - 1);
01678 }
01679 if (rc == SQLITE_ABORT) {
01680 freerows(&tres.resarr[1]);
01681 if (tres.errmsg) {
01682 if (errp) {
01683 if (*errp) {
01684 sqlite3_free(*errp);
01685 }
01686 *errp = tres.errmsg;
01687 } else {
01688 sqlite3_free(tres.errmsg);
01689 }
01690 }
01691 return tres.rc;
01692 }
01693 sqlite3_free(tres.errmsg);
01694 if (rc != SQLITE_OK) {
01695 freerows(&tres.resarr[1]);
01696 return rc;
01697 }
01698 *resp = &tres.resarr[1];
01699 if (ncolp) {
01700 *ncolp = tres.ncol;
01701 }
01702 if (nrowp) {
01703 *nrowp = tres.nrow;
01704 }
01705 return rc;
01706 }
01707
01716 #if defined(__GNUC__) && (__GNUC__ >= 2)
01717 static void setstatd(DBC *, int, char *, char *, ...)
01718 __attribute__((format (printf, 3, 5)));
01719 #endif
01720
01721 static void
01722 setstatd(DBC *d, int naterr, char *msg, char *st, ...)
01723 {
01724 va_list ap;
01725
01726 if (!d) {
01727 return;
01728 }
01729 d->naterr = naterr;
01730 d->logmsg[0] = '\0';
01731 if (msg) {
01732 int count;
01733
01734 va_start(ap, st);
01735 count = vsnprintf((char *) d->logmsg, sizeof (d->logmsg), msg, ap);
01736 va_end(ap);
01737 if (count < 0) {
01738 d->logmsg[sizeof (d->logmsg) - 1] = '\0';
01739 }
01740 }
01741 if (!st) {
01742 st = "?????";
01743 }
01744 strncpy(d->sqlstate, st, 5);
01745 d->sqlstate[5] = '\0';
01746 }
01747
01756 #if defined(__GNUC__) && (__GNUC__ >= 2)
01757 static void setstat(STMT *, int, char *, char *, ...)
01758 __attribute__((format (printf, 3, 5)));
01759 #endif
01760
01761 static void
01762 setstat(STMT *s, int naterr, char *msg, char *st, ...)
01763 {
01764 va_list ap;
01765
01766 if (!s) {
01767 return;
01768 }
01769 s->naterr = naterr;
01770 s->logmsg[0] = '\0';
01771 if (msg) {
01772 int count;
01773
01774 va_start(ap, st);
01775 count = vsnprintf((char *) s->logmsg, sizeof (s->logmsg), msg, ap);
01776 va_end(ap);
01777 if (count < 0) {
01778 s->logmsg[sizeof (s->logmsg) - 1] = '\0';
01779 }
01780 }
01781 if (!st) {
01782 st = "?????";
01783 }
01784 strncpy(s->sqlstate, st, 5);
01785 s->sqlstate[5] = '\0';
01786 }
01787
01794 static SQLRETURN
01795 drvunimpldbc(HDBC dbc)
01796 {
01797 DBC *d;
01798
01799 if (dbc == SQL_NULL_HDBC) {
01800 return SQL_INVALID_HANDLE;
01801 }
01802 d = (DBC *) dbc;
01803 setstatd(d, -1, "not supported", "IM001");
01804 return SQL_ERROR;
01805 }
01806
01813 static SQLRETURN
01814 drvunimplstmt(HSTMT stmt)
01815 {
01816 STMT *s;
01817
01818 if (stmt == SQL_NULL_HSTMT) {
01819 return SQL_INVALID_HANDLE;
01820 }
01821 s = (STMT *) stmt;
01822 setstat(s, -1, "not supported", "IM001");
01823 return SQL_ERROR;
01824 }
01825
01831 static void
01832 freep(void *x)
01833 {
01834 if (x && ((char **) x)[0]) {
01835 xfree(((char **) x)[0]);
01836 ((char **) x)[0] = NULL;
01837 }
01838 }
01839
01846 static SQLRETURN
01847 nomem(STMT *s)
01848 {
01849 setstat(s, -1, "out of memory", (*s->ov3) ? "HY000" : "S1000");
01850 return SQL_ERROR;
01851 }
01852
01859 static SQLRETURN
01860 noconn(STMT *s)
01861 {
01862 setstat(s, -1, "not connected", (*s->ov3) ? "HY000" : "S1000");
01863 return SQL_ERROR;
01864 }
01865
01873 #if defined(HAVE_LOCALECONV) || defined(_WIN32) || defined(_WIN64)
01874
01875 static double
01876 ln_strtod(const char *data, char **endp)
01877 {
01878 struct lconv *lc = 0;
01879 char buf[128], *p, *end;
01880 double value;
01881
01882 lc = localeconv();
01883 if (lc && lc->decimal_point && lc->decimal_point[0] &&
01884 lc->decimal_point[0] != '.') {
01885 strncpy(buf, data, sizeof (buf) - 1);
01886 buf[sizeof (buf) - 1] = '\0';
01887 p = strchr(buf, '.');
01888 if (p) {
01889 *p = lc->decimal_point[0];
01890 }
01891 p = buf;
01892 } else {
01893 p = (char *) data;
01894 }
01895 value = strtod(p, &end);
01896 end = (char *) data + (end - p);
01897 if (endp) {
01898 *endp = end;
01899 }
01900 return value;
01901 }
01902
01903 #else
01904
01905 #define ln_strtod(A,B) strtod(A,B)
01906
01907 #endif
01908
01914 static char *
01915 unquote(char *str)
01916 {
01917 if (str) {
01918 int len = strlen(str);
01919
01920 if (len > 1) {
01921 int end = len - 1;
01922
01923 if ((str[0] == '\'' && str[end] == '\'') ||
01924 (str[0] == '"' && str[end] == '"') ||
01925 (str[0] == '[' && str[end] == ']')) {
01926 memmove(str, str + 1, end - 1);
01927 str[end - 1] = '\0';
01928 }
01929 }
01930 }
01931 return str;
01932 }
01933
01941 static int
01942 unescpat(char *str)
01943 {
01944 char *p, *q;
01945 int count = 0;
01946
01947 p = str;
01948 while ((q = strchr(p, '_')) != NULL) {
01949 if (q == str || q[-1] != '\\') {
01950 count++;
01951 }
01952 p = q + 1;
01953 }
01954 p = str;
01955 while ((q = strchr(p, '%')) != NULL) {
01956 if (q == str || q[-1] != '\\') {
01957 count++;
01958 }
01959 p = q + 1;
01960 }
01961 p = str;
01962 while ((q = strchr(p, '\\')) != NULL) {
01963 if (q[1] == '\\' || q[1] == '_' || q[1] == '%') {
01964 memmove(q, q + 1, strlen(q));
01965 }
01966 p = q + 1;
01967 }
01968 return count;
01969 }
01970
01979 static int
01980 namematch(char *str, char *pat, int esc)
01981 {
01982 int cp, ch;
01983
01984 while (1) {
01985 cp = TOLOWER(*pat);
01986 if (cp == '\0') {
01987 if (*str != '\0') {
01988 goto nomatch;
01989 }
01990 break;
01991 }
01992 if (*str == '\0' && cp != '%') {
01993 goto nomatch;
01994 }
01995 if (cp == '%') {
01996 while (*pat == '%') {
01997 ++pat;
01998 }
01999 cp = TOLOWER(*pat);
02000 if (cp == '\0') {
02001 break;
02002 }
02003 while (1) {
02004 if (cp != '_' && cp != '\\') {
02005 while (*str) {
02006 ch = TOLOWER(*str);
02007 if (ch == cp) {
02008 break;
02009 }
02010 ++str;
02011 }
02012 }
02013 if (namematch(str, pat, esc)) {
02014 goto match;
02015 }
02016 if (*str == '\0') {
02017 goto nomatch;
02018 }
02019 ch = TOLOWER(*str);
02020 ++str;
02021 }
02022 }
02023 if (cp == '_') {
02024 pat++;
02025 str++;
02026 continue;
02027 }
02028 if (esc && cp == '\\' &&
02029 (pat[1] == '\\' || pat[1] == '%' || pat[1] == '_')) {
02030 ++pat;
02031 cp = TOLOWER(*pat);
02032 }
02033 ch = TOLOWER(*str++);
02034 ++pat;
02035 if (ch != cp) {
02036 goto nomatch;
02037 }
02038 }
02039 match:
02040 return 1;
02041 nomatch:
02042 return 0;
02043 }
02044
02052 static int
02053 busy_handler(void *udata, int count)
02054 {
02055 DBC *d = (DBC *) udata;
02056 long t1;
02057 int ret = 0;
02058 #if !defined(_WIN32) && !defined(_WIN64)
02059 struct timeval tv;
02060 #ifdef HAVE_NANOSLEEP
02061 struct timespec ts;
02062 #endif
02063 #endif
02064
02065 if (d->busyint) {
02066 d->busyint = 0;
02067 return ret;
02068 }
02069 if (d->timeout <= 0) {
02070 return ret;
02071 }
02072 if (count <= 1) {
02073 #if defined(_WIN32) || defined(_WIN64)
02074 d->t0 = GetTickCount();
02075 #else
02076 gettimeofday(&tv, NULL);
02077 d->t0 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
02078 #endif
02079 }
02080 #if defined(_WIN32) || defined(_WIN64)
02081 t1 = GetTickCount();
02082 #else
02083 gettimeofday(&tv, NULL);
02084 t1 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
02085 #endif
02086 if (t1 - d->t0 > d->timeout) {
02087 goto done;
02088 }
02089 #if defined(_WIN32) || defined(_WIN64)
02090 Sleep(10);
02091 #else
02092 #ifdef HAVE_NANOSLEEP
02093 ts.tv_sec = 0;
02094 ts.tv_nsec = 10000000;
02095 do {
02096 ret = nanosleep(&ts, &ts);
02097 if (ret < 0 && errno != EINTR) {
02098 ret = 0;
02099 }
02100 } while (ret);
02101 #else
02102 #ifdef HAVE_USLEEP
02103 usleep(10000);
02104 #else
02105 tv.tv_sec = 0;
02106 tv.tv_usec = 10000;
02107 select(0, NULL, NULL, NULL, &tv);
02108 #endif
02109 #endif
02110 #endif
02111 ret = 1;
02112 done:
02113 return ret;
02114 }
02115
02127 static int
02128 setsqliteopts(sqlite3 *x, DBC *d)
02129 {
02130 int count = 0, step = 0, max, rc = SQLITE_ERROR;
02131
02132 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
02133 max = d->longnames ? 3 : 1;
02134 #else
02135 max = 3;
02136 #endif
02137 if (d->shortnames) {
02138 max = 3;
02139 }
02140 while (step < max) {
02141 if (step < 1) {
02142 rc = sqlite3_exec(x, "PRAGMA empty_result_callbacks = on;",
02143 NULL, NULL, NULL);
02144 if (rc == SQLITE_OK) {
02145 rc = sqlite3_exec(x, d->fksupport ?
02146 "PRAGMA foreign_keys = on;" :
02147 "PRAGMA foreign_keys = off;",
02148 NULL, NULL, NULL);
02149 }
02150 } else if (step < 2) {
02151 rc = sqlite3_exec(x, d->shortnames ?
02152 "PRAGMA full_column_names = off;" :
02153 "PRAGMA full_column_names = on;",
02154 NULL, NULL, NULL);
02155 } else if (step < 3) {
02156 rc = sqlite3_exec(x, d->shortnames ?
02157 "PRAGMA short_column_names = on;" :
02158 "PRAGMA short_column_names = off;",
02159 NULL, NULL, NULL);
02160 }
02161 if (rc != SQLITE_OK) {
02162 if (rc != SQLITE_BUSY ||
02163 !busy_handler((void *) d, ++count)) {
02164 return rc;
02165 }
02166 continue;
02167 }
02168 count = 0;
02169 ++step;
02170 }
02171 sqlite3_busy_handler(x, busy_handler, (void *) d);
02172 return SQLITE_OK;
02173 }
02174
02184 static void
02185 freerows(char **rowp)
02186 {
02187 PTRDIFF_T size, i;
02188
02189 if (!rowp) {
02190 return;
02191 }
02192 --rowp;
02193 size = (PTRDIFF_T) rowp[0];
02194 for (i = 1; i <= size; i++) {
02195 freep(&rowp[i]);
02196 }
02197 freep(&rowp);
02198 }
02199
02210 static int
02211 mapsqltype(const char *typename, int *nosign, int ov3, int nowchar,
02212 int dobigint)
02213 {
02214 char *p, *q;
02215 int testsign = 0, result;
02216
02217 #ifdef WINTERFACE
02218 result = nowchar ? SQL_VARCHAR : SQL_WVARCHAR;
02219 #else
02220 result = SQL_VARCHAR;
02221 #endif
02222 if (!typename) {
02223 return result;
02224 }
02225 q = p = xmalloc(strlen(typename) + 1);
02226 if (!p) {
02227 return result;
02228 }
02229 strcpy(p, typename);
02230 while (*q) {
02231 *q = TOLOWER(*q);
02232 ++q;
02233 }
02234 if (strncmp(p, "inter", 5) == 0) {
02235 } else if (strncmp(p, "int", 3) == 0 ||
02236 strncmp(p, "mediumint", 9) == 0) {
02237 testsign = 1;
02238 result = SQL_INTEGER;
02239 } else if (strncmp(p, "numeric", 7) == 0) {
02240 result = SQL_DOUBLE;
02241 } else if (strncmp(p, "tinyint", 7) == 0) {
02242 testsign = 1;
02243 result = SQL_TINYINT;
02244 } else if (strncmp(p, "smallint", 8) == 0) {
02245 testsign = 1;
02246 result = SQL_SMALLINT;
02247 } else if (strncmp(p, "float", 5) == 0) {
02248 result = SQL_DOUBLE;
02249 } else if (strncmp(p, "double", 6) == 0 ||
02250 strncmp(p, "real", 4) == 0) {
02251 result = SQL_DOUBLE;
02252 } else if (strncmp(p, "timestamp", 9) == 0) {
02253 #ifdef SQL_TYPE_TIMESTAMP
02254 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
02255 #else
02256 result = SQL_TIMESTAMP;
02257 #endif
02258 } else if (strncmp(p, "datetime", 8) == 0) {
02259 #ifdef SQL_TYPE_TIMESTAMP
02260 result = ov3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
02261 #else
02262 result = SQL_TIMESTAMP;
02263 #endif
02264 } else if (strncmp(p, "time", 4) == 0) {
02265 #ifdef SQL_TYPE_TIME
02266 result = ov3 ? SQL_TYPE_TIME : SQL_TIME;
02267 #else
02268 result = SQL_TIME;
02269 #endif
02270 } else if (strncmp(p, "date", 4) == 0) {
02271 #ifdef SQL_TYPE_DATE
02272 result = ov3 ? SQL_TYPE_DATE : SQL_DATE;
02273 #else
02274 result = SQL_DATE;
02275 #endif
02276 #ifdef SQL_LONGVARCHAR
02277 } else if (strncmp(p, "text", 4) == 0 ||
02278 strncmp(p, "memo", 4) == 0 ||
02279 strncmp(p, "longvarchar", 11) == 0) {
02280 #ifdef WINTERFACE
02281 result = nowchar ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
02282 #else
02283 result = SQL_LONGVARCHAR;
02284 #endif
02285 #ifdef WINTERFACE
02286 } else if (strncmp(p, "wtext", 5) == 0 ||
02287 strncmp(p, "wvarchar", 8) == 0 ||
02288 strncmp(p, "longwvarchar", 12) == 0) {
02289 result = SQL_WLONGVARCHAR;
02290 #endif
02291 #endif
02292 #ifdef SQL_BIT
02293 } else if (strncmp(p, "bool", 4) == 0 ||
02294 strncmp(p, "bit", 3) == 0) {
02295 result = SQL_BIT;
02296 #endif
02297 #ifdef SQL_BIGINT
02298 } else if (strncmp(p, "bigint", 6) == 0) {
02299 testsign = 1;
02300 result = SQL_BIGINT;
02301 #endif
02302 } else if (strncmp(p, "blob", 4) == 0) {
02303 result = SQL_BINARY;
02304 } else if (strncmp(p, "varbinary", 9) == 0) {
02305 result = SQL_VARBINARY;
02306 } else if (strncmp(p, "longvarbinary", 13) == 0) {
02307 result = SQL_LONGVARBINARY;
02308 }
02309 if (nosign) {
02310 if (testsign) {
02311 *nosign = strstr(p, "unsigned") != NULL;
02312 } else {
02313 *nosign = 1;
02314 }
02315 }
02316 #ifdef SQL_BIGINT
02317 if (dobigint && result == SQL_INTEGER) {
02318 result = SQL_BIGINT;
02319 }
02320 #endif
02321 xfree(p);
02322 return result;
02323 }
02324
02334 static void
02335 getmd(const char *typename, int sqltype, int *mp, int *dp)
02336 {
02337 int m = 0, d = 0;
02338
02339 switch (sqltype) {
02340 case SQL_INTEGER: m = 10; d = 9; break;
02341 case SQL_TINYINT: m = 4; d = 3; break;
02342 case SQL_SMALLINT: m = 6; d = 5; break;
02343 case SQL_FLOAT: m = 25; d = 24; break;
02344 case SQL_DOUBLE: m = 54; d = 53; break;
02345 case SQL_VARCHAR: m = 255; d = 0; break;
02346 #ifdef WINTERFACE
02347 #ifdef SQL_WVARCHAR
02348 case SQL_WVARCHAR: m = 255; d = 0; break;
02349 #endif
02350 #endif
02351 #ifdef SQL_TYPE_DATE
02352 case SQL_TYPE_DATE:
02353 #endif
02354 case SQL_DATE: m = 10; d = 0; break;
02355 #ifdef SQL_TYPE_TIME
02356 case SQL_TYPE_TIME:
02357 #endif
02358 case SQL_TIME: m = 8; d = 0; break;
02359 #ifdef SQL_TYPE_TIMESTAMP
02360 case SQL_TYPE_TIMESTAMP:
02361 #endif
02362 case SQL_TIMESTAMP: m = 32; d = 3; break;
02363 #ifdef SQL_LONGVARCHAR
02364 case SQL_LONGVARCHAR : m = 65536; d = 0; break;
02365 #endif
02366 #ifdef WINTERFACE
02367 #ifdef SQL_WLONGVARCHAR
02368 case SQL_WLONGVARCHAR: m = 65536; d = 0; break;
02369 #endif
02370 #endif
02371 case SQL_BINARY:
02372 case SQL_VARBINARY: m = 255; d = 0; break;
02373 case SQL_LONGVARBINARY: m = 65536; d = 0; break;
02374 #ifdef SQL_BIGINT
02375 case SQL_BIGINT: m = 20; d = 19; break;
02376 #endif
02377 #ifdef SQL_BIT
02378 case SQL_BIT: m = 1; d = 1; break;
02379 #endif
02380 }
02381 if (m && typename) {
02382 int mm, dd;
02383 char clbr[4];
02384
02385 if (sscanf(typename, "%*[^(](%d,%d %1[)]", &mm, &dd, clbr) == 3) {
02386 m = mm;
02387 d = dd;
02388 } else if (sscanf(typename, "%*[^(](%d %1[)]", &mm, clbr) == 2) {
02389 if (sqltype == SQL_TIMESTAMP) {
02390 d = mm;
02391 }
02392 #ifdef SQL_TYPE_TIMESTAMP
02393 else if (sqltype == SQL_TYPE_TIMESTAMP) {
02394 d = mm;
02395 }
02396 #endif
02397 else {
02398 m = d = mm;
02399 }
02400 }
02401 }
02402 if (mp) {
02403 *mp = m;
02404 }
02405 if (dp) {
02406 *dp = d;
02407 }
02408 }
02409
02419 static int
02420 mapdeftype(int type, int stype, int nosign, int nowchar)
02421 {
02422 if (type == SQL_C_DEFAULT) {
02423 switch (stype) {
02424 case SQL_INTEGER:
02425 type = (nosign > 0) ? SQL_C_ULONG : SQL_C_LONG;
02426 break;
02427 case SQL_TINYINT:
02428 type = (nosign > 0) ? SQL_C_UTINYINT : SQL_C_TINYINT;
02429 break;
02430 case SQL_SMALLINT:
02431 type = (nosign > 0) ? SQL_C_USHORT : SQL_C_SHORT;
02432 break;
02433 case SQL_FLOAT:
02434 type = SQL_C_FLOAT;
02435 break;
02436 case SQL_DOUBLE:
02437 type = SQL_C_DOUBLE;
02438 break;
02439 case SQL_TIMESTAMP:
02440 type = SQL_C_TIMESTAMP;
02441 break;
02442 case SQL_TIME:
02443 type = SQL_C_TIME;
02444 break;
02445 case SQL_DATE:
02446 type = SQL_C_DATE;
02447 break;
02448 #ifdef SQL_C_TYPE_TIMESTAMP
02449 case SQL_TYPE_TIMESTAMP:
02450 type = SQL_C_TYPE_TIMESTAMP;
02451 break;
02452 #endif
02453 #ifdef SQL_C_TYPE_TIME
02454 case SQL_TYPE_TIME:
02455 type = SQL_C_TYPE_TIME;
02456 break;
02457 #endif
02458 #ifdef SQL_C_TYPE_DATE
02459 case SQL_TYPE_DATE:
02460 type = SQL_C_TYPE_DATE;
02461 break;
02462 #endif
02463 #ifdef WINTERFACE
02464 case SQL_WVARCHAR:
02465 case SQL_WCHAR:
02466 #ifdef SQL_WLONGVARCHAR
02467 case SQL_WLONGVARCHAR:
02468 #endif
02469 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
02470 break;
02471 #endif
02472 case SQL_BINARY:
02473 case SQL_VARBINARY:
02474 case SQL_LONGVARBINARY:
02475 type = SQL_C_BINARY;
02476 break;
02477 #ifdef SQL_BIT
02478 case SQL_BIT:
02479 type = SQL_C_BIT;
02480 break;
02481 #endif
02482 #ifdef SQL_BIGINT
02483 case SQL_BIGINT:
02484 type = SQL_C_CHAR;
02485 break;
02486 #endif
02487 default:
02488 #ifdef WINTERFACE
02489 type = nowchar ? SQL_C_CHAR : SQL_C_WCHAR;
02490 #else
02491 type = SQL_C_CHAR;
02492 #endif
02493 break;
02494 }
02495 }
02496 return type;
02497 }
02498
02510 static char *
02511 fixupsql(char *sql, int sqlLen, int cte, int *nparam, int *isselect,
02512 char **errmsg)
02513 {
02514 char *q = sql, *qz = NULL, *p, *inq = NULL, *out;
02515 int np = 0, isddl = -1, size;
02516
02517 if (errmsg) {
02518 *errmsg = NULL;
02519 }
02520 if (sqlLen != SQL_NTS) {
02521 qz = q = xmalloc(sqlLen + 1);
02522 if (!qz) {
02523 return NULL;
02524 }
02525 memcpy(q, sql, sqlLen);
02526 q[sqlLen] = '\0';
02527 size = sqlLen * 4;
02528 } else {
02529 size = strlen(sql) * 4;
02530 }
02531 size += sizeof (char *) - 1;
02532 size &= ~(sizeof (char *) - 1);
02533 p = xmalloc(size);
02534 if (!p) {
02535 errout:
02536 freep(&qz);
02537 return NULL;
02538 }
02539 memset(p, 0, size);
02540 out = p;
02541 while (*q) {
02542 switch (*q) {
02543 case '\'':
02544 case '\"':
02545 if (q == inq) {
02546 inq = NULL;
02547 } else if (!inq) {
02548 inq = q + 1;
02549
02550 while (*inq) {
02551 if (*inq == *q) {
02552 if (inq[1] == *q) {
02553 inq++;
02554 } else {
02555 break;
02556 }
02557 }
02558 inq++;
02559 }
02560 }
02561 *p++ = *q;
02562 break;
02563 case '?':
02564 *p++ = *q;
02565 if (!inq) {
02566 np++;
02567 }
02568 break;
02569 case ';':
02570 if (!inq) {
02571 if (isddl < 0) {
02572 char *qq = out;
02573
02574 while (*qq && ISSPACE(*qq)) {
02575 ++qq;
02576 }
02577 if (*qq && *qq != ';') {
02578 int i;
02579 static const struct {
02580 int len;
02581 const char *str;
02582 } ddlstr[] = {
02583 { 5, "alter" },
02584 { 7, "analyze" },
02585 { 6, "attach" },
02586 { 5, "begin" },
02587 { 6, "commit" },
02588 { 6, "create" },
02589 { 6, "detach" },
02590 { 4, "drop" },
02591 { 3, "end" },
02592 { 7, "reindex" },
02593 { 7, "release" },
02594 { 8, "rollback" },
02595 { 9, "savepoint" },
02596 { 6, "vacuum" }
02597 };
02598
02599 size = strlen(qq);
02600 for (i = 0; i < array_size(ddlstr); i++) {
02601 if (size >= ddlstr[i].len &&
02602 strncasecmp(qq, ddlstr[i].str, ddlstr[i].len)
02603 == 0) {
02604 isddl = 1;
02605 break;
02606 }
02607 }
02608 if (isddl != 1) {
02609 isddl = 0;
02610 }
02611 }
02612 }
02613 if (isddl == 0) {
02614 char *qq = q;
02615
02616 do {
02617 ++qq;
02618 } while (*qq && ISSPACE(*qq));
02619 if (*qq && *qq != ';') {
02620 freep(&out);
02621 if (errmsg) {
02622 *errmsg = "only one SQL statement allowed";
02623 }
02624 goto errout;
02625 }
02626 }
02627 }
02628 *p++ = *q;
02629 break;
02630 case '{':
02631
02632
02633
02634
02635
02636 if (!inq) {
02637 int ojfn = 0, brc = 0;
02638 char *inq2 = NULL, *end = q + 1, *start;
02639
02640 while (*end && ISSPACE(*end)) {
02641 ++end;
02642 }
02643 if (*end != 'd' && *end != 'D' &&
02644 *end != 't' && *end != 'T') {
02645 ojfn = 1;
02646 }
02647 start = end;
02648 while (*end) {
02649 if (inq2 && *end == *inq2) {
02650 inq2 = NULL;
02651 } else if (inq2 == NULL && *end == '{') {
02652 char *nerr = 0, *nsql;
02653
02654 nsql = fixupsql(end, SQL_NTS, cte, 0, 0, &nerr);
02655 if (nsql && !nerr) {
02656 strcpy(end, nsql);
02657 } else {
02658 brc++;
02659 }
02660 freep(&nsql);
02661 } else if (inq2 == NULL && *end == '}') {
02662 if (brc-- <= 0) {
02663 break;
02664 }
02665 } else if (inq2 == NULL && (*end == '\'' || *end == '"')) {
02666 inq2 = end;
02667 } else if (inq2 == NULL && *end == '?') {
02668 np++;
02669 }
02670 ++end;
02671 }
02672 if (*end == '}') {
02673 char *end2 = end - 1;
02674
02675 if (ojfn) {
02676 while (start < end) {
02677 if (ISSPACE(*start)) {
02678 break;
02679 }
02680 ++start;
02681 }
02682 while (start < end) {
02683 *p++ = *start;
02684 ++start;
02685 }
02686 q = end;
02687 break;
02688 } else {
02689 while (start < end2 && *start != '\'') {
02690 ++start;
02691 }
02692 while (end2 > start && *end2 != '\'') {
02693 --end2;
02694 }
02695 if (*start == '\'' && *end2 == '\'') {
02696 while (start <= end2) {
02697 *p++ = *start;
02698 ++start;
02699 }
02700 q = end;
02701 break;
02702 }
02703 }
02704 }
02705 }
02706
02707 default:
02708 *p++ = *q;
02709 }
02710 ++q;
02711 }
02712 freep(&qz);
02713 *p = '\0';
02714 if (nparam) {
02715 *nparam = np;
02716 }
02717 if (isselect) {
02718 if (isddl > 0) {
02719 *isselect = 2;
02720 } else {
02721 int incom = 0;
02722
02723 p = out;
02724 while (*p) {
02725 switch (*p) {
02726 case '-':
02727 if (!incom && p[1] == '-') {
02728 incom = -1;
02729 }
02730 break;
02731 case '\n':
02732 if (incom < 0) {
02733 incom = 0;
02734 }
02735 break;
02736 case '/':
02737 if (incom > 0 && p[-1] == '*') {
02738 incom = 0;
02739 p++;
02740 continue;
02741 } else if (!incom && p[1] == '*') {
02742 incom = 1;
02743 }
02744 break;
02745 }
02746 if (!incom && !ISSPACE(*p)) {
02747 break;
02748 }
02749 p++;
02750 }
02751 size = strlen(p);
02752 if (size >= 6 &&
02753 (strncasecmp(p, "select", 6) == 0 ||
02754 strncasecmp(p, "pragma", 6) == 0)) {
02755 *isselect = 1;
02756 } else if (cte && size >= 4 && strncasecmp(p, "with", 4) == 0) {
02757 *isselect = 1;
02758 } else if (size >= 7 && strncasecmp(p, "explain", 7) == 0) {
02759 *isselect = 1;
02760 } else {
02761 *isselect = 0;
02762 }
02763 }
02764 }
02765 return out;
02766 }
02767
02776 static int
02777 findcol(char **cols, int ncols, char *name)
02778 {
02779 int i;
02780
02781 if (cols) {
02782 for (i = 0; i < ncols; i++) {
02783 if (strcmp(cols[i], name) == 0) {
02784 return i;
02785 }
02786 }
02787 }
02788 return -1;
02789 }
02790
02807 static void
02808 fixupdyncols(STMT *s, DBC *d)
02809 {
02810 int i, k;
02811 #ifndef FULL_METADATA
02812 int pk, nn, t, r, nrows, ncols;
02813 char **rowp, *flagp, flags[128];
02814 #endif
02815
02816 if (!s->dyncols) {
02817 return;
02818 }
02819
02820 if (!s->longnames) {
02821 if (s->dcols > 1) {
02822 char *table = s->dyncols[0].table;
02823
02824 for (i = 1; table[0] && i < s->dcols; i++) {
02825 if (strcmp(s->dyncols[i].table, table)) {
02826 break;
02827 }
02828 }
02829 if (i >= s->dcols) {
02830 for (i = 0; i < s->dcols; i++) {
02831 s->dyncols[i].label = s->dyncols[i].column;
02832 }
02833 }
02834 } else if (s->dcols == 1) {
02835 s->dyncols[0].label = s->dyncols[0].column;
02836 }
02837 }
02838 for (i = 0; i < s->dcols; i++) {
02839 s->dyncols[i].type =
02840 mapsqltype(s->dyncols[i].typename, &s->dyncols[i].nosign, *s->ov3,
02841 s->nowchar[0] || s->nowchar[1], s->dobigint);
02842 getmd(s->dyncols[i].typename, s->dyncols[i].type,
02843 &s->dyncols[i].size, &s->dyncols[i].prec);
02844 #ifdef SQL_LONGVARCHAR
02845 if (s->dyncols[i].type == SQL_VARCHAR &&
02846 s->dyncols[i].size > 255) {
02847 s->dyncols[i].type = SQL_LONGVARCHAR;
02848 }
02849 #endif
02850 #ifdef WINTERFACE
02851 #ifdef SQL_WLONGVARCHAR
02852 if (s->dyncols[i].type == SQL_WVARCHAR &&
02853 s->dyncols[i].size > 255) {
02854 s->dyncols[i].type = SQL_WLONGVARCHAR;
02855 }
02856 #endif
02857 #endif
02858 if (s->dyncols[i].type == SQL_VARBINARY &&
02859 s->dyncols[i].size > 255) {
02860 s->dyncols[i].type = SQL_LONGVARBINARY;
02861 }
02862 }
02863 #ifndef FULL_METADATA
02864 if (s->dcols > array_size(flags)) {
02865 flagp = xmalloc(sizeof (flags[0]) * s->dcols);
02866 if (flagp == NULL) {
02867 return;
02868 }
02869 } else {
02870 flagp = flags;
02871 }
02872 memset(flagp, 0, sizeof (flags[0]) * s->dcols);
02873 for (i = 0; i < s->dcols; i++) {
02874 s->dyncols[i].autoinc = SQL_FALSE;
02875 s->dyncols[i].notnull = SQL_NULLABLE;
02876 }
02877 for (i = 0; i < s->dcols; i++) {
02878 int ret, lastpk = -1, autoinccount = 0;
02879 char *sql;
02880
02881 if (!s->dyncols[i].table[0]) {
02882 continue;
02883 }
02884 if (flagp[i]) {
02885 continue;
02886 }
02887 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", s->dyncols[i].table);
02888 if (!sql) {
02889 continue;
02890 }
02891 dbtraceapi(d, "sqlite3_get_table", sql);
02892 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, NULL);
02893 sqlite3_free(sql);
02894 if (ret != SQLITE_OK) {
02895 continue;
02896 }
02897 k = findcol(rowp, ncols, "name");
02898 t = findcol(rowp, ncols, "type");
02899 pk = findcol(rowp, ncols, "pk");
02900 nn = findcol(rowp, ncols, "notnull");
02901 if (k < 0 || t < 0) {
02902 goto freet;
02903 }
02904 for (r = 1; r <= nrows; r++) {
02905 int m;
02906
02907 for (m = i; m < s->dcols; m++) {
02908 char *colname = s->dyncols[m].column;
02909
02910 if (s->longnames) {
02911 char *dotp = strchr(colname, '.');
02912
02913 if (dotp) {
02914 colname = dotp + 1;
02915 }
02916 }
02917 if (!flagp[m] &&
02918 strcmp(colname, rowp[r * ncols + k]) == 0 &&
02919 strcmp(s->dyncols[m].table, s->dyncols[i].table) == 0) {
02920 char *typename = rowp[r * ncols + t];
02921
02922 flagp[m] = i + 1;
02923 freep(&s->dyncols[m].typename);
02924 s->dyncols[m].typename = xstrdup(typename);
02925 s->dyncols[m].type =
02926 mapsqltype(typename, &s->dyncols[m].nosign, *s->ov3,
02927 s->nowchar[0] || s->nowchar[1],
02928 s->dobigint);
02929 getmd(typename, s->dyncols[m].type, &s->dyncols[m].size,
02930 &s->dyncols[m].prec);
02931 #ifdef SQL_LONGVARCHAR
02932 if (s->dyncols[m].type == SQL_VARCHAR &&
02933 s->dyncols[m].size > 255) {
02934 s->dyncols[m].type = SQL_LONGVARCHAR;
02935 }
02936 #endif
02937 #ifdef WINTERFACE
02938 #ifdef SQL_WLONGVARCHAR
02939 if (s->dyncols[i].type == SQL_WVARCHAR &&
02940 s->dyncols[i].size > 255) {
02941 s->dyncols[i].type = SQL_WLONGVARCHAR;
02942 }
02943 #endif
02944 #endif
02945 if (s->dyncols[i].type == SQL_VARBINARY &&
02946 s->dyncols[i].size > 255) {
02947 s->dyncols[i].type = SQL_LONGVARBINARY;
02948 }
02949 if (pk >= 0 && strcmp(rowp[r * ncols + pk], "1") == 0) {
02950 s->dyncols[m].ispk = 1;
02951 if (++autoinccount > 1) {
02952 if (lastpk >= 0) {
02953 s->dyncols[lastpk].autoinc = SQL_FALSE;
02954 lastpk = -1;
02955 }
02956 } else {
02957 lastpk = m;
02958 if (strlen(typename) == 7 &&
02959 strncasecmp(typename, "integer", 7) == 0) {
02960 s->dyncols[m].autoinc = SQL_TRUE;
02961 }
02962 }
02963 } else {
02964 s->dyncols[m].ispk = 0;
02965 }
02966 if (nn >= 0 && rowp[r * ncols + nn][0] != '0') {
02967 s->dyncols[m].notnull = SQL_NO_NULLS;
02968 }
02969 }
02970 }
02971 }
02972 freet:
02973 sqlite3_free_table(rowp);
02974 }
02975 for (i = k = 0; i < s->dcols; i++) {
02976 if (flagp[i] == 0) {
02977 break;
02978 }
02979 if (k == 0) {
02980 k = flagp[i];
02981 } else if (flagp[i] != k) {
02982 k = 0;
02983 break;
02984 }
02985 }
02986 s->one_tbl = k ? 1 : 0;
02987 k = 0;
02988 if (s->one_tbl) {
02989 for (i = 0; i < s->dcols; i++) {
02990 if (s->dyncols[i].ispk > 0) {
02991 ++k;
02992 }
02993 }
02994 }
02995 s->has_pk = k;
02996 if (flagp != flags) {
02997 freep(&flagp);
02998 }
02999 #else
03000 for (i = 1, k = 0; i < s->dcols; i++) {
03001 if (strcmp(s->dyncols[i].table, s->dyncols[0].table) == 0) {
03002 k++;
03003 }
03004 }
03005 s->one_tbl = (k && k + 1 == s->dcols) ? 1 : 0;
03006 k = 0;
03007 if (s->one_tbl) {
03008 for (i = 0; i < s->dcols; i++) {
03009 if (s->dyncols[i].ispk > 0) {
03010 ++k;
03011 if (s->has_rowid < 0 && s->dyncols[i].isrowid > 0) {
03012 s->has_rowid = i;
03013 }
03014 }
03015 }
03016 }
03017 s->has_pk = k;
03018 #endif
03019 }
03020
03027 static void
03028 convJD2YMD(double jd, DATE_STRUCT *ds)
03029 {
03030 int z, a, b, c, d, e, x1;
03031 sqlite_int64 ijd;
03032
03033 ijd = jd * 86400000.0 + 0.5;
03034 z = (int) ((ijd + 43200000) / 86400000);
03035 a = (int) ((z - 1867216.25) / 36524.25);
03036 a = z + 1 + a - (a / 4);
03037 b = a + 1524;
03038 c = (int) ((b - 122.1) / 365.25);
03039 d = (36525 * c) / 100;
03040 e = (int) ((b - d) / 30.6001);
03041 x1 = (int) (30.6001 * e);
03042 ds->day = b - d - x1;
03043 ds->month = (e < 14) ? (e - 1) : (e - 13);
03044 ds->year = (ds->month > 2) ? (c - 4716) : (c - 4715);
03045 }
03046
03047
03055 static void
03056 convJD2HMS(double jd, TIME_STRUCT *ts, int *fp)
03057 {
03058 int s;
03059 double ds;
03060 sqlite_int64 ijd;
03061
03062 ijd = jd * 86400000.0 + 0.5;
03063 s = (int)((ijd + 43200000) % 86400000);
03064 ds = s / 1000.0;
03065 if (fp) {
03066 *fp = (s % 1000) * 1000000;
03067 }
03068 s = (int) ds;
03069 ds -= s;
03070 ts->hour = s / 3600;
03071 s -= ts->hour * 3600;
03072 ts->minute = s / 60;
03073 ds += s - ts->minute *60;
03074 ts->second = (int) ds;
03075 }
03076
03084 static int
03085 getmdays(int year, int month)
03086 {
03087 static const int mdays[] = {
03088 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
03089 };
03090 int mday;
03091
03092 if (month < 1) {
03093 return 0;
03094 }
03095 mday = mdays[(month - 1) % 12];
03096 if (mday == 28 && year % 4 == 0 &&
03097 (!(year % 100 == 0) || year % 400 == 0)) {
03098 mday++;
03099 }
03100 return mday;
03101 }
03102
03118 static int
03119 str2date(int jdconv, char *str, DATE_STRUCT *ds)
03120 {
03121 int i, err = 0;
03122 double jd;
03123 char *p, *q, sepc = '\0';
03124
03125 ds->year = ds->month = ds->day = 0;
03126 if (jdconv) {
03127 p = strchr(str, '.');
03128 if (p) {
03129
03130 p = 0;
03131 jd = ln_strtod(str, &p);
03132 if (p && p > str) {
03133 convJD2YMD(jd, ds);
03134 return 0;
03135 }
03136 }
03137 }
03138 p = str;
03139 while (*p && !ISDIGIT(*p)) {
03140 ++p;
03141 }
03142 q = p;
03143 i = 0;
03144 while (*q && !ISDIGIT(*q)) {
03145 ++i;
03146 ++q;
03147 }
03148 if (i >= 8) {
03149 char buf[8];
03150
03151 strncpy(buf, p + 0, 4); buf[4] = '\0';
03152 ds->year = strtol(buf, NULL, 10);
03153 strncpy(buf, p + 4, 2); buf[2] = '\0';
03154 ds->month = strtol(buf, NULL, 10);
03155 strncpy(buf, p + 6, 2); buf[2] = '\0';
03156 ds->day = strtol(buf, NULL, 10);
03157 goto done;
03158 }
03159 i = 0;
03160 while (i < 3) {
03161 int n;
03162
03163 q = NULL;
03164 n = strtol(p, &q, 10);
03165 if (!q || q == p) {
03166 if (*q == '\0') {
03167 if (i == 0) {
03168 err = 1;
03169 }
03170 goto done;
03171 }
03172 }
03173 if (!sepc) {
03174 sepc = *q;
03175 }
03176 if (*q == '-' || *q == '/' || *q == '\0' || i == 2) {
03177 switch (i) {
03178 case 0: ds->year = n; break;
03179 case 1: ds->month = n; break;
03180 case 2: ds->day = n; break;
03181 }
03182 ++i;
03183 if (*q) {
03184 ++q;
03185 }
03186 } else {
03187 i = 0;
03188 while (*q && !ISDIGIT(*q)) {
03189 ++q;
03190 }
03191 }
03192 p = q;
03193 }
03194 done:
03195
03196 if (err ||
03197 ds->month < 1 || ds->month > 12 ||
03198 ds->day < 1 || ds->day > getmdays(ds->year, ds->month)) {
03199 if (sepc == '/') {
03200
03201 int t[3];
03202
03203 t[0] = ds->year;
03204 t[1] = ds->month;
03205 t[2] = ds->day;
03206 ds->year = t[2];
03207 ds->day = t[1];
03208 ds->month = t[0];
03209 if (ds->month >= 1 && ds->month <= 12 &&
03210 (ds->day >= 1 || ds->day <= getmdays(ds->year, ds->month))) {
03211 return 0;
03212 }
03213 }
03214 return -1;
03215 }
03216 return 0;
03217 }
03218
03233 static int
03234 str2time(int jdconv, char *str, TIME_STRUCT *ts)
03235 {
03236 int i, err = 0, ampm = -1;
03237 double jd;
03238 char *p, *q;
03239
03240 ts->hour = ts->minute = ts->second = 0;
03241 if (jdconv) {
03242 p = strchr(str, '.');
03243 if (p) {
03244
03245 p = 0;
03246 jd = ln_strtod(str, &p);
03247 if (p && p > str) {
03248 convJD2HMS(jd, ts, 0);
03249 return 0;
03250 }
03251 }
03252 }
03253 p = str;
03254 while (*p && !ISDIGIT(*p)) {
03255 ++p;
03256 }
03257 q = p;
03258 i = 0;
03259 while (*q && ISDIGIT(*q)) {
03260 ++i;
03261 ++q;
03262 }
03263 if (i >= 6) {
03264 char buf[4];
03265
03266 strncpy(buf, p + 0, 2); buf[2] = '\0';
03267 ts->hour = strtol(buf, NULL, 10);
03268 strncpy(buf, p + 2, 2); buf[2] = '\0';
03269 ts->minute = strtol(buf, NULL, 10);
03270 strncpy(buf, p + 4, 2); buf[2] = '\0';
03271 ts->second = strtol(buf, NULL, 10);
03272 goto done;
03273 }
03274 i = 0;
03275 while (i < 3) {
03276 int n;
03277
03278 q = NULL;
03279 n = strtol(p, &q, 10);
03280 if (!q || q == p) {
03281 if (*q == '\0') {
03282 if (i == 0) {
03283 err = 1;
03284 }
03285 goto done;
03286 }
03287 }
03288 if (*q == ':' || *q == '\0' || i == 2) {
03289 switch (i) {
03290 case 0: ts->hour = n; break;
03291 case 1: ts->minute = n; break;
03292 case 2: ts->second = n; break;
03293 }
03294 ++i;
03295 if (*q) {
03296 ++q;
03297 }
03298 } else {
03299 i = 0;
03300 while (*q && !ISDIGIT(*q)) {
03301 ++q;
03302 }
03303 }
03304 p = q;
03305 }
03306 if (!err) {
03307 while (*p) {
03308 if ((p[0] == 'p' || p[0] == 'P') &&
03309 (p[1] == 'm' || p[1] == 'M')) {
03310 ampm = 1;
03311 } else if ((p[0] == 'a' || p[0] == 'A') &&
03312 (p[1] == 'm' || p[1] == 'M')) {
03313 ampm = 0;
03314 }
03315 ++p;
03316 }
03317 if (ampm > 0) {
03318 if (ts->hour < 12) {
03319 ts->hour += 12;
03320 }
03321 } else if (ampm == 0) {
03322 if (ts->hour == 12) {
03323 ts->hour = 0;
03324 }
03325 }
03326 }
03327 done:
03328
03329 if (err || ts->hour > 23 || ts->minute > 59 || ts->second > 59) {
03330 return -1;
03331 }
03332 return 0;
03333 }
03334
03354 static int
03355 str2timestamp(int jdconv, char *str, TIMESTAMP_STRUCT *tss)
03356 {
03357 int i, m, n, err = 0, ampm = -1;
03358 double jd;
03359 char *p, *q, in = '\0', sepc = '\0';
03360
03361 tss->year = tss->month = tss->day = 0;
03362 tss->hour = tss->minute = tss->second = 0;
03363 tss->fraction = 0;
03364 if (jdconv) {
03365 p = strchr(str, '.');
03366 if (p) {
03367 q = strchr(str, '-');
03368 if (q == str) {
03369 q = 0;
03370 }
03371 if (!q) {
03372 q = strchr(str, '/');
03373 if (!q) {
03374 q = strchr(str, ':');
03375 }
03376 }
03377 if (!q || q > p) {
03378
03379 p = 0;
03380 jd = ln_strtod(str, &p);
03381 if (p && p > str) {
03382 DATE_STRUCT ds;
03383 TIME_STRUCT ts;
03384
03385 convJD2YMD(jd, &ds);
03386 convJD2HMS(jd, &ts, &n);
03387 tss->year = ds.year;
03388 tss->month = ds.month;
03389 tss->day = ds.day;
03390 tss->hour = ts.hour;
03391 tss->minute = ts.minute;
03392 tss->second = ts.second;
03393 tss->fraction = n;
03394 return 0;
03395 }
03396 }
03397 }
03398 }
03399 p = str;
03400 while (*p && !ISDIGIT(*p)) {
03401 ++p;
03402 }
03403 q = p;
03404 i = 0;
03405 while (*q && ISDIGIT(*q)) {
03406 ++i;
03407 ++q;
03408 }
03409 if (i >= 14) {
03410 char buf[16];
03411
03412 strncpy(buf, p + 0, 4); buf[4] = '\0';
03413 tss->year = strtol(buf, NULL, 10);
03414 strncpy(buf, p + 4, 2); buf[2] = '\0';
03415 tss->month = strtol(buf, NULL, 10);
03416 strncpy(buf, p + 6, 2); buf[2] = '\0';
03417 tss->day = strtol(buf, NULL, 10);
03418 strncpy(buf, p + 8, 2); buf[2] = '\0';
03419 tss->hour = strtol(buf, NULL, 10);
03420 strncpy(buf, p + 10, 2); buf[2] = '\0';
03421 tss->minute = strtol(buf, NULL, 10);
03422 strncpy(buf, p + 12, 2); buf[2] = '\0';
03423 tss->second = strtol(buf, NULL, 10);
03424 if (i > 14) {
03425 m = i - 14;
03426 strncpy(buf, p + 14, m);
03427 while (m < 9) {
03428 buf[m] = '0';
03429 ++m;
03430 }
03431 buf[m] = '\0';
03432 tss->fraction = strtol(buf, NULL, 10);
03433 }
03434 m = 7;
03435 goto done;
03436 }
03437 m = i = 0;
03438 while ((m & 7) != 7) {
03439 q = NULL;
03440 n = strtol(p, &q, 10);
03441 if (!q || q == p) {
03442 if (*q == '\0') {
03443 if (m < 1) {
03444 err = 1;
03445 }
03446 goto done;
03447 }
03448 }
03449 if (in == '\0') {
03450 switch (*q) {
03451 case '-':
03452 case '/':
03453 if ((m & 1) == 0) {
03454 in = *q;
03455 i = 0;
03456 }
03457 break;
03458 case ':':
03459 if ((m & 2) == 0) {
03460 in = *q;
03461 i = 0;
03462 }
03463 break;
03464 case ' ':
03465 case '.':
03466 break;
03467 default:
03468 in = '\0';
03469 i = 0;
03470 break;
03471 }
03472 }
03473 switch (in) {
03474 case '-':
03475 case '/':
03476 if (!sepc) {
03477 sepc = in;
03478 }
03479 switch (i) {
03480 case 0: tss->year = n; break;
03481 case 1: tss->month = n; break;
03482 case 2: tss->day = n; break;
03483 }
03484 if (++i >= 3) {
03485 i = 0;
03486 m |= 1;
03487 if (!(m & 2)) {
03488 m |= 8;
03489 }
03490 goto skip;
03491 } else {
03492 ++q;
03493 }
03494 break;
03495 case ':':
03496 switch (i) {
03497 case 0: tss->hour = n; break;
03498 case 1: tss->minute = n; break;
03499 case 2: tss->second = n; break;
03500 }
03501 if (++i >= 3) {
03502 i = 0;
03503 m |= 2;
03504 if (*q == '.') {
03505 in = '.';
03506 goto skip2;
03507 }
03508 if (*q == ' ') {
03509 if ((m & 1) == 0) {
03510 char *e = NULL;
03511
03512 (void) strtol(q + 1, &e, 10);
03513 if (e && *e == '-') {
03514 goto skip;
03515 }
03516 }
03517 in = '.';
03518 goto skip2;
03519 }
03520 goto skip;
03521 } else {
03522 ++q;
03523 }
03524 break;
03525 case '.':
03526 if (++i >= 1) {
03527 int ndig = q - p;
03528
03529 if (p[0] == '+' || p[0] == '-') {
03530 ndig--;
03531 }
03532 while (ndig < 9) {
03533 n = n * 10;
03534 ++ndig;
03535 }
03536 tss->fraction = n;
03537 m |= 4;
03538 i = 0;
03539 }
03540 default:
03541 skip:
03542 in = '\0';
03543 skip2:
03544 while (*q && !ISDIGIT(*q)) {
03545 if ((q[0] == 'a' || q[0] == 'A') &&
03546 (q[1] == 'm' || q[1] == 'M')) {
03547 ampm = 0;
03548 ++q;
03549 } else if ((q[0] == 'p' || q[0] == 'P') &&
03550 (q[1] == 'm' || q[1] == 'M')) {
03551 ampm = 1;
03552 ++q;
03553 }
03554 ++q;
03555 }
03556 }
03557 p = q;
03558 }
03559 if ((m & 7) > 1 && (m & 8)) {
03560
03561 if (p > str && ISDIGIT(*p)) {
03562 int nn, sign;
03563
03564 q = p - 1;
03565 if (*q != '+' && *q != '-') {
03566 goto done;
03567 }
03568 sign = (*q == '+') ? -1 : 1;
03569 q = NULL;
03570 n = strtol(p, &q, 10);
03571 if (!q || *q++ != ':' || !ISDIGIT(*q)) {
03572 goto done;
03573 }
03574 p = q;
03575 q = NULL;
03576 nn = strtol(p, &q, 10);
03577 tss->minute += nn * sign;
03578 if ((SQLSMALLINT) tss->minute < 0) {
03579 tss->hour -= 1;
03580 tss->minute += 60;
03581 } else if (tss->minute >= 60) {
03582 tss->hour += 1;
03583 tss->minute -= 60;
03584 }
03585 tss->hour += n * sign;
03586 if ((SQLSMALLINT) tss->hour < 0) {
03587 tss->day -= 1;
03588 tss->hour += 24;
03589 } else if (tss->hour >= 24) {
03590 tss->day += 1;
03591 tss->hour -= 24;
03592 }
03593 if ((short) tss->day < 1 || tss->day >= 28) {
03594 int mday, pday, pmon;
03595
03596 mday = getmdays(tss->year, tss->month);
03597 pmon = tss->month - 1;
03598 if (pmon < 1) {
03599 pmon = 12;
03600 }
03601 pday = getmdays(tss->year, pmon);
03602 if ((SQLSMALLINT) tss->day < 1) {
03603 tss->month -= 1;
03604 tss->day = pday;
03605 } else if (tss->day > mday) {
03606 tss->month += 1;
03607 tss->day = 1;
03608 }
03609 if ((SQLSMALLINT) tss->month < 1) {
03610 tss->year -= 1;
03611 tss->month = 12;
03612 } else if (tss->month > 12) {
03613 tss->year += 1;
03614 tss->month = 1;
03615 }
03616 }
03617 }
03618 }
03619 done:
03620 if ((m & 1) &&
03621 (tss->month < 1 || tss->month > 12 ||
03622 tss->day < 1 || tss->day > getmdays(tss->year, tss->month))) {
03623 if (sepc == '/') {
03624
03625 int t[3];
03626
03627 t[0] = tss->year;
03628 t[1] = tss->month;
03629 t[2] = tss->day;
03630 tss->year = t[2];
03631 tss->day = t[1];
03632 tss->month = t[0];
03633 }
03634 }
03635
03636 if (!err && (m & 1) == 0) {
03637 #ifdef _WIN32
03638 SYSTEMTIME t;
03639
03640 GetLocalTime(&t);
03641 tss->year = t.wYear;
03642 tss->month = t.wMonth;
03643 tss->day = t.wDay;
03644 #else
03645 struct timeval tv;
03646 struct tm tm;
03647
03648 gettimeofday(&tv, NULL);
03649 tm = *localtime(&tv.tv_sec);
03650 tss->year = tm.tm_year + 1900;
03651 tss->month = tm.tm_mon + 1;
03652 tss->day = tm.tm_mday;
03653 #endif
03654 }
03655
03656 if (tss->fraction < 0) {
03657 tss->fraction = 0;
03658 }
03659
03660 if (err ||
03661 tss->month < 1 || tss->month > 12 ||
03662 tss->day < 1 || tss->day > getmdays(tss->year, tss->month) ||
03663 tss->hour > 23 || tss->minute > 59 || tss->second > 59) {
03664 return -1;
03665 }
03666 if ((m & 7) > 1) {
03667 if (ampm > 0) {
03668 if (tss->hour < 12) {
03669 tss->hour += 12;
03670 }
03671 } else if (ampm == 0) {
03672 if (tss->hour == 12) {
03673 tss->hour = 0;
03674 }
03675 }
03676 }
03677 return ((m & 7) < 1) ? -1 : 0;
03678 }
03679
03686 static int
03687 getbool(char *string)
03688 {
03689 if (string) {
03690 return string[0] && strchr("Yy123456789Tt", string[0]) != NULL;
03691 }
03692 return 0;
03693 }
03694
03702 static void
03703 blob_import(sqlite3_context *ctx, int nargs, sqlite3_value **args)
03704 {
03705 #if 0
03706 DBC *d = (DBC *) sqlite3_user_data(ctx);
03707 #endif
03708 char *filename = 0;
03709
03710 if (nargs > 0) {
03711 if (sqlite3_value_type(args[0]) != SQLITE_NULL) {
03712 filename = (char *) sqlite3_value_text(args[0]);
03713 }
03714 }
03715 if (filename) {
03716 #ifdef _WIN32
03717 char *wname = utf_to_wmb(filename, -1);
03718 FILE *f;
03719 #else
03720 FILE *f = fopen(filename, "r");
03721 #endif
03722 char *p;
03723 long n, nn;
03724
03725 #ifdef _WIN32
03726 if (wname) {
03727 f = fopen(wname, "rb");
03728 } else {
03729 sqlite3_result_error(ctx, "out of memory", -1);
03730 return;
03731 }
03732 uc_free(wname);
03733 #endif
03734 if (f) {
03735 if (fseek(f, 0, SEEK_END) == 0) {
03736 n = ftell(f);
03737 if (fseek(f, 0, SEEK_SET) == 0) {
03738 p = sqlite3_malloc(n);
03739 if (p) {
03740 nn = fread(p, 1, n, f);
03741 if (nn != n) {
03742 sqlite3_result_error(ctx, "read error", -1);
03743 sqlite3_free(p);
03744 } else {
03745 sqlite3_result_blob(ctx, p, n, sqlite3_free);
03746 }
03747 } else {
03748 sqlite3_result_error(ctx, "out of memory", -1);
03749 }
03750 } else {
03751 sqlite3_result_error(ctx, "seek error", -1);
03752 }
03753 } else {
03754 sqlite3_result_error(ctx, "seek error", -1);
03755 }
03756 fclose(f);
03757 } else {
03758 sqlite3_result_error(ctx, "cannot open file", -1);
03759 }
03760 } else {
03761 sqlite3_result_error(ctx, "no filename given", -1);
03762 }
03763 }
03764
03772 static void
03773 blob_export(sqlite3_context *ctx, int nargs, sqlite3_value **args)
03774 {
03775 #if 0
03776 DBC *d = (DBC *) sqlite3_user_data(ctx);
03777 #endif
03778 char *filename = 0;
03779 char *p = 0;
03780 int n = 0;
03781
03782 if (nargs > 0) {
03783 p = (char *) sqlite3_value_blob(args[0]);
03784 n = sqlite3_value_bytes(args[0]);
03785 }
03786 if (nargs > 1) {
03787 if (sqlite3_value_type(args[1]) != SQLITE_NULL) {
03788 filename = (char *) sqlite3_value_text(args[1]);
03789 }
03790 }
03791 if (p) {
03792 if (filename) {
03793 #ifdef _WIN32
03794 char *wname = utf_to_wmb(filename, -1);
03795 FILE *f;
03796 #else
03797 FILE *f = fopen(filename, "w");
03798 #endif
03799 int nn;
03800
03801 #ifdef _WIN32
03802 if (wname) {
03803 f = fopen(wname, "wb");
03804 } else {
03805 sqlite3_result_error(ctx, "out of memory", -1);
03806 return;
03807 }
03808 uc_free(wname);
03809 #endif
03810 if (f) {
03811 nn = fwrite(p, 1, n, f);
03812 fclose(f);
03813 if (nn != n) {
03814 sqlite3_result_error(ctx, "write error", -1);
03815 } else {
03816 sqlite3_result_int(ctx, nn);
03817 }
03818 } else {
03819 sqlite3_result_error(ctx, "cannot open file", -1);
03820 }
03821 } else {
03822 sqlite3_result_error(ctx, "no filename given", -1);
03823 }
03824 } else {
03825 sqlite3_result_null(ctx);
03826 }
03827 }
03828
03836 static void
03837 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03838 dbtrace(void *arg, const char *msg, sqlite_uint64 et)
03839 #else
03840 dbtrace(void *arg, const char *msg)
03841 #endif
03842 {
03843 DBC *d = (DBC *) arg;
03844
03845 if (msg && d->trace) {
03846 int len = strlen(msg);
03847 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03848 unsigned long s, f;
03849 #endif
03850
03851 if (len > 0) {
03852 char *end = "\n";
03853
03854 if (msg[len - 1] != ';') {
03855 end = ";\n";
03856 }
03857 fprintf(d->trace, "%s%s", msg, end);
03858 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
03859 s = et / 1000000000LL;
03860 f = et % 1000000000LL;
03861 fprintf(d->trace, "-- took %lu.%09lu seconds\n", s, f);
03862 #endif
03863 fflush(d->trace);
03864 }
03865 }
03866 }
03867
03875 static void
03876 dbtraceapi(DBC *d, char *fn, const char *sql)
03877 {
03878 if (fn && d->trace) {
03879 if (sql) {
03880 fprintf(d->trace, "-- %s: %s\n", fn, sql);
03881 } else {
03882 fprintf(d->trace, "-- %s\n", fn);
03883 }
03884 fflush(d->trace);
03885 }
03886 }
03887
03895 static void
03896 dbtracerc(DBC *d, int rc, char *err)
03897 {
03898 if (rc != SQLITE_OK && d->trace) {
03899 fprintf(d->trace, "-- SQLITE ERROR CODE %d", rc);
03900 fprintf(d->trace, err ? ": %s\n" : "\n", err);
03901 fflush(d->trace);
03902 }
03903 }
03904
03919 static SQLRETURN
03920 dbopen(DBC *d, char *name, int isu, char *dsn, char *sflag,
03921 char *spflag, char *ntflag, char *jmode, char *busy)
03922 {
03923 char *endp = NULL;
03924 int rc, tmp, busyto = 100000;
03925 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
03926 int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
03927 char *uname = name;
03928 const char *vfs_name = NULL;
03929 #endif
03930
03931 if (d->sqlite) {
03932 if (d->trace) {
03933 fprintf(d->trace, "-- sqlite3_close (deferred): '%s'\n",
03934 d->dbname);
03935 fflush(d->trace);
03936 }
03937 #if defined(HAVE_SQLITE3CLOSEV2) && (HAVE_SQLITE3CLOSEV2)
03938 sqlite3_close_v2(d->sqlite);
03939 #else
03940 sqlite3_close(d->sqlite);
03941 #endif
03942 d->sqlite = NULL;
03943 }
03944 #if defined(HAVE_SQLITE3VFS) && (HAVE_SQLITE3VFS)
03945 if (d->nocreat) {
03946 flags &= ~ SQLITE_OPEN_CREATE;
03947 }
03948 #if defined(_WIN32) || defined(_WIN64)
03949 if (!isu) {
03950 char expname[SQL_MAX_MESSAGE_LENGTH * 2];
03951
03952 expname[0] = '\0';
03953 rc = ExpandEnvironmentStrings(name, expname, sizeof (expname));
03954 if (rc <= sizeof (expname)) {
03955 uname = wmb_to_utf(expname, rc - 1);
03956 } else {
03957 uname = wmb_to_utf(name, -1);
03958 }
03959 if (!uname) {
03960 rc = SQLITE_NOMEM;
03961 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
03962 return SQL_ERROR;
03963 }
03964 }
03965 #endif
03966 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
03967 vfs_name = nvfs_makevfs(uname);
03968 #endif
03969 #ifdef SQLITE_OPEN_URI
03970 flags |= SQLITE_OPEN_URI;
03971 #endif
03972 rc = sqlite3_open_v2(uname, &d->sqlite, flags, vfs_name);
03973 #if defined(WINTERFACE) || defined(_WIN32) || defined(_WIN64)
03974 if (uname != name) {
03975 uc_free(uname);
03976 }
03977 #endif
03978 #else
03979 #if defined(_WIN32) || defined(_WIN64)
03980 if (d->nocreat) {
03981 char *cname = NULL;
03982
03983 if (isu) {
03984 cname = utf_to_wmb(name, -1);
03985 }
03986 if (GetFileAttributesA(cname ? cname : name) ==
03987 INVALID_FILE_ATTRIBUTES) {
03988 uc_free(cname);
03989 rc = SQLITE_CANTOPEN;
03990 setstatd(d, rc, "cannot open database",
03991 (*d->ov3) ? "HY000" : "S1000");
03992 return SQL_ERROR;
03993 }
03994 uc_free(cname);
03995 }
03996 #else
03997 if (d->nocreat && access(name, 004) < 0) {
03998 rc = SQLITE_CANTOPEN;
03999 setstatd(d, rc, "cannot open database", (*d->ov3) ? "HY000" : "S1000");
04000 return SQL_ERROR;
04001 }
04002 #endif
04003 #if defined(_WIN32) || defined(_WIN64)
04004 if (!isu) {
04005 WCHAR *wname = wmb_to_uc(name, -1);
04006
04007 if (!wname) {
04008 rc = SQLITE_NOMEM;
04009 setstatd(d, rc, "out of memory", (*d->ov3) ? "HY000" : "S1000");
04010 return SQL_ERROR;
04011 }
04012 rc = sqlite3_open16(wname, &d->sqlite);
04013 uc_free(wname);
04014 } else
04015 #endif
04016 rc = sqlite3_open(name, &d->sqlite);
04017 #endif
04018 if (rc != SQLITE_OK) {
04019 connfail:
04020 setstatd(d, rc, "connect failed", (*d->ov3) ? "HY000" : "S1000");
04021 if (d->sqlite) {
04022 sqlite3_close(d->sqlite);
04023 d->sqlite = NULL;
04024 }
04025 return SQL_ERROR;
04026 }
04027 #if defined(SQLITE_DYNLOAD) || defined(SQLITE_HAS_CODEC)
04028 if (d->pwd) {
04029 sqlite3_key(d->sqlite, d->pwd, d->pwdLen);
04030 }
04031 #endif
04032 d->pwd = NULL;
04033 d->pwdLen = 0;
04034 if (d->trace) {
04035 #if defined(HAVE_SQLITE3PROFILE) && (HAVE_SQLITE3PROFILE)
04036 sqlite3_profile(d->sqlite, dbtrace, d);
04037 #else
04038 sqlite3_trace(d->sqlite, dbtrace, d);
04039 #endif
04040 }
04041 d->step_enable = getbool(sflag);
04042 d->trans_disable = getbool(ntflag);
04043 d->curtype = d->step_enable ?
04044 SQL_CURSOR_FORWARD_ONLY : SQL_CURSOR_STATIC;
04045 tmp = strtol(busy, &endp, 0);
04046 if (endp && *endp == '\0' && endp != busy) {
04047 busyto = tmp;
04048 }
04049 if (busyto < 1 || busyto > 1000000) {
04050 busyto = 1000000;
04051 }
04052 d->timeout = busyto;
04053 freep(&d->dbname);
04054 d->dbname = xstrdup(name);
04055 freep(&d->dsn);
04056 d->dsn = xstrdup(dsn);
04057 if ((rc = setsqliteopts(d->sqlite, d)) != SQLITE_OK) {
04058 if (d->trace) {
04059 fprintf(d->trace, "-- sqlite3_close: '%s'\n",
04060 d->dbname);
04061 fflush(d->trace);
04062 }
04063 sqlite3_close(d->sqlite);
04064 d->sqlite = NULL;
04065 goto connfail;
04066 }
04067 if (!spflag || spflag[0] == '\0') {
04068 spflag = "NORMAL";
04069 }
04070 if (spflag[0] != '\0') {
04071 char syncp[128];
04072
04073 sprintf(syncp, "PRAGMA synchronous = %8.8s;", spflag);
04074 sqlite3_exec(d->sqlite, syncp, NULL, NULL, NULL);
04075 }
04076 if (jmode[0] != '\0') {
04077 char jourp[128];
04078
04079 sprintf(jourp, "PRAGMA journal_mode = %16.16s;", jmode);
04080 sqlite3_exec(d->sqlite, jourp, NULL, NULL, NULL);
04081 }
04082 if (d->trace) {
04083 fprintf(d->trace, "-- sqlite3_open: '%s'\n", d->dbname);
04084 fflush(d->trace);
04085 }
04086 #if defined(_WIN32) || defined(_WIN64)
04087 {
04088 char pname[MAX_PATH];
04089 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
04090 FALSE, GetCurrentProcessId());
04091
04092 pname[0] = '\0';
04093 if (h) {
04094 HMODULE m = NULL, l = LoadLibrary("psapi.dll");
04095 DWORD need;
04096 typedef BOOL (WINAPI *epmfunc)(HANDLE, HMODULE *, DWORD, LPDWORD);
04097 typedef BOOL (WINAPI *gmbfunc)(HANDLE, HMODULE, LPSTR, DWORD);
04098 epmfunc epm;
04099 gmbfunc gmb;
04100
04101 if (l) {
04102 epm = (epmfunc) GetProcAddress(l, "EnumProcessModules");
04103 gmb = (gmbfunc) GetProcAddress(l, "GetModuleBaseNameA");
04104 if (epm && gmb && epm(h, &m, sizeof (m), &need)) {
04105 gmb(h, m, pname, sizeof (pname));
04106 }
04107 FreeLibrary(l);
04108 }
04109 CloseHandle(h);
04110 }
04111 d->xcelqrx = strncasecmp(pname, "EXCEL", 5) == 0 ||
04112 strncasecmp(pname, "MSQRY", 5) == 0;
04113 if (d->trace && d->xcelqrx) {
04114
04115 fprintf(d->trace, "-- enabled EXCEL quirks\n");
04116 fflush(d->trace);
04117 }
04118 }
04119 #endif
04120 sqlite3_create_function(d->sqlite, "blob_import", 1, SQLITE_UTF8,
04121 d, blob_import, 0, 0);
04122 sqlite3_create_function(d->sqlite, "blob_export", 2, SQLITE_UTF8,
04123 d, blob_export, 0, 0);
04124 return SQL_SUCCESS;
04125 }
04126
04133 static void
04134 dbloadext(DBC *d, char *exts)
04135 {
04136 #if defined(HAVE_SQLITE3LOADEXTENSION) && (HAVE_SQLITE3LOADEXTENSION)
04137 char *p;
04138 char path[SQL_MAX_MESSAGE_LENGTH];
04139 int plen = 0;
04140
04141 if (!d->sqlite) {
04142 return;
04143 }
04144 sqlite3_enable_load_extension(d->sqlite, 1);
04145 #if defined(_WIN32) || defined(_WIN64)
04146 GetModuleFileName(hModule, path, sizeof (path));
04147 p = strrchr(path, '\\');
04148 plen = p ? ((p + 1) - path) : 0;
04149 #endif
04150 do {
04151 p = strchr(exts, ',');
04152 if (p) {
04153 strncpy(path + plen, exts, p - exts);
04154 path[plen + (p - exts)] = '\0';
04155 } else {
04156 strcpy(path + plen, exts);
04157 }
04158 if (exts[0]) {
04159 char *errmsg = NULL;
04160 int rc;
04161 #if defined(_WIN32) || defined(_WIN64)
04162 int i;
04163 char *q;
04164
04165 q = path + plen;
04166 if (!(q[0] &&
04167 ((q[1] == ':' && (q[2] == '\\' || q[2] == '/')) ||
04168 q[0] == '\\' || q[0] == '/' || q[0] == '.'))) {
04169 q = path;
04170 }
04171
04172 for (i = 0; q[i] != '\0'; i++) {
04173 if (q[i] == '\\') {
04174 q[i] = '/';
04175 }
04176 }
04177 rc = sqlite3_load_extension(d->sqlite, q, 0, &errmsg);
04178 #else
04179 rc = sqlite3_load_extension(d->sqlite, path, 0, &errmsg);
04180 #endif
04181 if (rc != SQLITE_OK) {
04182 #if defined(_WIN32) || defined(_WIN64)
04183 char buf[512], msg[512];
04184
04185 LoadString(hModule, IDS_EXTERR, buf, sizeof (buf));
04186 wsprintf(msg, buf, q, errmsg ?
04187 errmsg : "no error info available");
04188 LoadString(hModule, IDS_EXTTITLE, buf, sizeof (buf));
04189 MessageBox(NULL, msg, buf,
04190 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
04191 MB_SETFOREGROUND);
04192 #else
04193 fprintf(stderr, "extension '%s' did not load%s%s\n",
04194 path, errmsg ? ": " : "", errmsg ? errmsg : "");
04195 #endif
04196 }
04197 }
04198 if (p) {
04199 exts = p + 1;
04200 }
04201 } while (p);
04202 #endif
04203 }
04204
04214 static char *
04215 s3stmt_coltype(sqlite3_stmt *s3stmt, int col, DBC *d, int *guessed_types)
04216 {
04217 char *typename = (char *) sqlite3_column_decltype(s3stmt, col);
04218 char guess[64];
04219
04220 guess[0] = '\0';
04221 if (!typename) {
04222 int coltype = sqlite3_column_type(s3stmt, col);
04223
04224 if (guessed_types) {
04225 guessed_types[0]++;
04226 }
04227 if (d->trace) {
04228 sprintf(guess, " (guessed from %d)", coltype);
04229 }
04230 switch (coltype) {
04231 case SQLITE_INTEGER: typename = "integer"; break;
04232 case SQLITE_FLOAT: typename = "double"; break;
04233 default:
04234 case SQLITE_TEXT: typename = "varchar"; break;
04235 case SQLITE_BLOB: typename = "blob"; break;
04236 #if 0
04237 case SQLITE_NULL: typename = "null"; break;
04238 #endif
04239 }
04240 }
04241 if (d->trace) {
04242 fprintf(d->trace, "-- column %d type%s: '%s'\n", col + 1,
04243 guess, typename);
04244 fflush(d->trace);
04245 }
04246 return typename;
04247 }
04248
04249 #ifdef FULL_METADATA
04250
04259 static void
04260 s3stmt_addmeta(sqlite3_stmt *s3stmt, int col, DBC *d, COL *ci)
04261 {
04262 int nn = 0, pk = 0, ai = 0;
04263 const char *dn = NULL, *tn = NULL, *cn = NULL, *dummy[4];
04264
04265 dn = sqlite3_column_database_name(s3stmt, col);
04266 tn = sqlite3_column_table_name(s3stmt, col);
04267 cn = sqlite3_column_origin_name(s3stmt, col);
04268 dummy[0] = dummy[1] = 0;
04269 if (tn && cn) {
04270 sqlite3_table_column_metadata(d->sqlite, dn, tn, cn,
04271 dummy, dummy + 1,
04272 &nn, &pk, &ai);
04273 }
04274 ci->autoinc = ai ? SQL_TRUE: SQL_FALSE;
04275 ci->notnull = nn ? SQL_NO_NULLS : SQL_NULLABLE;
04276 ci->ispk = pk ? 1 : 0;
04277 if (d->trace) {
04278 fprintf(d->trace, "-- column %d %s\n",
04279 col + 1, nn ? "notnull" : "nullable");
04280 if (ai) {
04281 fprintf(d->trace, "-- column %d autoincrement\n", col + 1);
04282 }
04283 fflush(d->trace);
04284 }
04285 ci->isrowid = 0;
04286 if (ci->ispk && tn) {
04287 nn = pk = ai = 0;
04288 dummy[2] = dummy[3] = 0;
04289
04290 sqlite3_table_column_metadata(d->sqlite, dn, tn, "rowid",
04291 dummy + 2, dummy + 3,
04292 &nn, &pk, &ai);
04293 if (pk && dummy[0] && dummy[0] == dummy[2]) {
04294 ci->isrowid = 1;
04295 }
04296 }
04297 }
04298
04299 #endif
04300
04307 static int
04308 s3stmt_step(STMT *s)
04309 {
04310 DBC *d = (DBC *) s->dbc;
04311 char **rowd = NULL;
04312 const char *errp = NULL;
04313 int i, ncols, rc;
04314
04315 if (s != d->cur_s3stmt || !s->s3stmt) {
04316 setstat(s, -1, "stale statement", (*s->ov3) ? "HY000" : "S1000");
04317 return SQL_ERROR;
04318 }
04319 rc = sqlite3_step(s->s3stmt);
04320 if (rc == SQLITE_ROW || rc == SQLITE_DONE) {
04321 ++s->s3stmt_rownum;
04322 ncols = sqlite3_column_count(s->s3stmt);
04323 if (d->s3stmt_needmeta && s->s3stmt_rownum == 0 && ncols > 0) {
04324 PTRDIFF_T size;
04325 char *p;
04326 COL *dyncols;
04327 const char *colname, *typename;
04328 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04329 char *tblname;
04330 #endif
04331
04332 for (i = size = 0; i < ncols; i++) {
04333 colname = sqlite3_column_name(s->s3stmt, i);
04334 size += 3 + 3 * strlen(colname);
04335 }
04336 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04337 tblname = (char *) size;
04338 for (i = 0; i < ncols; i++) {
04339 p = (char *) sqlite3_column_table_name(s->s3stmt, i);
04340 size += 2 + (p ? strlen(p) : 0);
04341 }
04342 #endif
04343 dyncols = xmalloc(ncols * sizeof (COL) + size);
04344 if (!dyncols) {
04345 freedyncols(s);
04346 s->ncols = 0;
04347 dbtraceapi(d, "sqlite3_finalize", 0);
04348 sqlite3_finalize(s->s3stmt);
04349 s->s3stmt = NULL;
04350 d->cur_s3stmt = NULL;
04351 return nomem(s);
04352 }
04353 p = (char *) (dyncols + ncols);
04354 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04355 tblname = p + (PTRDIFF_T) tblname;
04356 #endif
04357 for (i = 0; i < ncols; i++) {
04358 char *q;
04359
04360 colname = sqlite3_column_name(s->s3stmt, i);
04361 if (d->trace) {
04362 fprintf(d->trace, "-- column %d name: '%s'\n",
04363 i + 1, colname);
04364 fflush(d->trace);
04365 }
04366 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
04367 q = (char *) sqlite3_column_table_name(s->s3stmt, i);
04368 strcpy(tblname, q ? q : "");
04369 if (d->trace) {
04370 fprintf(d->trace, "-- table %d name: '%s'\n",
04371 i + 1, tblname);
04372 fflush(d->trace);
04373 }
04374 dyncols[i].table = tblname;
04375 tblname += strlen(tblname) + 1;
04376 #endif
04377 typename = s3stmt_coltype(s->s3stmt, i, d, 0);
04378 dyncols[i].db = ((DBC *) (s->dbc))->dbname;
04379 strcpy(p, colname);
04380 dyncols[i].label = p;
04381 p += strlen(p) + 1;
04382 q = strchr(colname, '.');
04383 if (q) {
04384 char *q2 = strchr(q + 1, '.');
04385
04386
04387 if (q2) {
04388 q = q2;
04389 }
04390 }
04391 if (q) {
04392 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
04393 dyncols[i].table = p;
04394 #endif
04395 strncpy(p, colname, q - colname);
04396 p[q - colname] = '\0';
04397 p += strlen(p) + 1;
04398 strcpy(p, q + 1);
04399 dyncols[i].column = p;
04400 p += strlen(p) + 1;
04401 } else {
04402 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
04403 dyncols[i].table = "";
04404 #endif
04405 strcpy(p, colname);
04406 dyncols[i].column = p;
04407 p += strlen(p) + 1;
04408 }
04409 if (s->longnames) {
04410 dyncols[i].column = dyncols[i].label;
04411 }
04412 #ifdef SQL_LONGVARCHAR
04413 dyncols[i].type = SQL_LONGVARCHAR;
04414 dyncols[i].size = 65535;
04415 #else
04416 dyncols[i].type = SQL_VARCHAR;
04417 dyncols[i].size = 255;
04418 #endif
04419 dyncols[i].index = i;
04420 dyncols[i].scale = 0;
04421 dyncols[i].prec = 0;
04422 dyncols[i].nosign = 1;
04423 dyncols[i].autoinc = SQL_FALSE;
04424 dyncols[i].notnull = SQL_NULLABLE;
04425 dyncols[i].ispk = -1;
04426 dyncols[i].isrowid = -1;
04427 #ifdef FULL_METADATA
04428 s3stmt_addmeta(s->s3stmt, i, d, &dyncols[i]);
04429 #endif
04430 dyncols[i].typename = xstrdup(typename);
04431 }
04432 freedyncols(s);
04433 s->ncols = s->dcols = ncols;
04434 s->dyncols = s->cols = dyncols;
04435 fixupdyncols(s, d);
04436 mkbindcols(s, s->ncols);
04437 d->s3stmt_needmeta = 0;
04438 }
04439 if (ncols <= 0) {
04440 goto killstmt;
04441 }
04442 if (rc == SQLITE_DONE) {
04443 freeresult(s, 0);
04444 s->nrows = 0;
04445 dbtraceapi(d, "sqlite3_finalize", 0);
04446 sqlite3_finalize(s->s3stmt);
04447 s->s3stmt = NULL;
04448 d->cur_s3stmt = NULL;
04449 return SQL_SUCCESS;
04450 }
04451 rowd = xmalloc((1 + 2 * ncols) * sizeof (char *));
04452 if (rowd) {
04453 const unsigned char *value;
04454
04455 rowd[0] = (char *) ((PTRDIFF_T) (ncols * 2));
04456 ++rowd;
04457 for (i = 0; i < ncols; i++) {
04458 int coltype = sqlite3_column_type(s->s3stmt, i);
04459
04460 rowd[i] = rowd[i + ncols] = NULL;
04461 if (coltype == SQLITE_BLOB) {
04462 int k, nbytes = sqlite3_column_bytes(s->s3stmt, i);
04463 char *qp;
04464 unsigned const char *bp;
04465
04466 bp = sqlite3_column_blob(s->s3stmt, i);
04467 qp = xmalloc(nbytes * 2 + 4);
04468 if (qp) {
04469 rowd[i + ncols] = qp;
04470 *qp++ = 'X';
04471 *qp++ = '\'';
04472 for (k = 0; k < nbytes; k++) {
04473 *qp++ = xdigits[(bp[k] >> 4)];
04474 *qp++ = xdigits[(bp[k] & 0xF)];
04475 }
04476 *qp++ = '\'';
04477 *qp = '\0';
04478 }
04479 #ifdef _MSC_VER
04480 } else if (coltype == SQLITE_FLOAT) {
04481 struct lconv *lc = 0;
04482 double d = sqlite3_column_double(s->s3stmt, i);
04483 char *p, buffer[128];
04484
04485
04486
04487
04488
04489
04490 snprintf(buffer, sizeof (buffer), "%.15g", d);
04491 lc = localeconv();
04492 if (lc && lc->decimal_point && lc->decimal_point[0] &&
04493 lc->decimal_point[0] != '.') {
04494 p = strchr(buffer, lc->decimal_point[0]);
04495 if (p) {
04496 *p = '.';
04497 }
04498 }
04499 rowd[i + ncols] = xstrdup(buffer);
04500 #endif
04501 } else if (coltype != SQLITE_NULL) {
04502 value = sqlite3_column_text(s->s3stmt, i);
04503 rowd[i + ncols] = xstrdup((char *) value);
04504 }
04505 }
04506 for (i = 0; i < ncols; i++) {
04507 int coltype = sqlite3_column_type(s->s3stmt, i);
04508
04509 value = NULL;
04510 if (coltype == SQLITE_BLOB) {
04511 value = sqlite3_column_blob(s->s3stmt, i);
04512 } else if (coltype != SQLITE_NULL) {
04513 value = sqlite3_column_text(s->s3stmt, i);
04514 }
04515 if (value && !rowd[i + ncols]) {
04516 freerows(rowd);
04517 rowd = 0;
04518 break;
04519 }
04520 }
04521 }
04522 if (rowd) {
04523 freeresult(s, 0);
04524 s->nrows = 1;
04525 s->rows = rowd;
04526 s->rowfree = freerows;
04527 if (rc == SQLITE_DONE) {
04528 dbtraceapi(d, "sqlite3_finalize", 0);
04529 sqlite3_finalize(s->s3stmt);
04530 s->s3stmt = NULL;
04531 d->cur_s3stmt = NULL;
04532 }
04533 return SQL_SUCCESS;
04534 }
04535 }
04536 killstmt:
04537 dbtraceapi(d, "sqlite3_reset", 0);
04538 rc = sqlite3_reset(s->s3stmt);
04539 s->s3stmt_noreset = 1;
04540 errp = sqlite3_errmsg(d->sqlite);
04541 if (d->cur_s3stmt == s) {
04542 d->cur_s3stmt = NULL;
04543 }
04544 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
04545 errp ? errp : "unknown error", rc);
04546 return SQL_ERROR;
04547 }
04548
04554 static void
04555 s3stmt_end(STMT *s)
04556 {
04557 DBC *d;
04558
04559 if (!s || !s->s3stmt) {
04560 return;
04561 }
04562 d = (DBC *) s->dbc;
04563 if (d) {
04564 d->busyint = 0;
04565 }
04566 if (!s->s3stmt_noreset) {
04567 dbtraceapi(d, "sqlite3_reset", 0);
04568 sqlite3_reset(s->s3stmt);
04569 s->s3stmt_noreset = 1;
04570 s->s3stmt_rownum = -1;
04571 }
04572 if (d->cur_s3stmt == s) {
04573 d->cur_s3stmt = NULL;
04574 }
04575 }
04576
04582 static void
04583 s3stmt_end_if(STMT *s)
04584 {
04585 DBC *d = (DBC *) s->dbc;
04586
04587 if (d) {
04588 d->busyint = 0;
04589 }
04590 if (d && d->cur_s3stmt == s) {
04591 s3stmt_end(s);
04592 }
04593 }
04594
04600 static void
04601 s3stmt_drop(STMT *s)
04602 {
04603 if (s->s3stmt) {
04604 DBC *d = (DBC *) s->dbc;
04605
04606 if (d) {
04607 dbtraceapi(d, "sqlite3_finalize", 0);
04608 }
04609 sqlite3_finalize(s->s3stmt);
04610 s->s3stmt = NULL;
04611 s->s3stmt_rownum = 0;
04612 }
04613 }
04614
04621 static SQLRETURN
04622 s3stmt_start(STMT *s)
04623 {
04624 DBC *d = (DBC *) s->dbc;
04625 const char *endp;
04626 sqlite3_stmt *s3stmt = NULL;
04627 int rc, nretry = 0;
04628
04629 d->s3stmt_needmeta = 0;
04630 if (!s->s3stmt) {
04631 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
04632 dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
04633 #else
04634 dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
04635 #endif
04636 do {
04637 s3stmt = NULL;
04638 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
04639 rc = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
04640 &s3stmt, &endp);
04641 #else
04642 rc = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
04643 &s3stmt, &endp);
04644 #endif
04645 if (rc != SQLITE_OK) {
04646 if (s3stmt) {
04647 sqlite3_finalize(s3stmt);
04648 s3stmt = NULL;
04649 }
04650 }
04651 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
04652 dbtracerc(d, rc, NULL);
04653 if (rc != SQLITE_OK) {
04654 if (s3stmt) {
04655 dbtraceapi(d, "sqlite3_finalize", NULL);
04656 sqlite3_finalize(s3stmt);
04657 }
04658 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
04659 sqlite3_errmsg(d->sqlite), rc);
04660 return SQL_ERROR;
04661 }
04662 if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
04663 dbtraceapi(d, "sqlite3_finalize", 0);
04664 sqlite3_finalize(s3stmt);
04665 setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
04666 (*s->ov3) ? "HY000" : "S1000");
04667 return SQL_ERROR;
04668 }
04669 s->s3stmt = s3stmt;
04670 s->s3stmt_noreset = 1;
04671 d->s3stmt_needmeta = 1;
04672 }
04673 d->cur_s3stmt = s;
04674 s->s3stmt_rownum = -1;
04675 s3bind(d, s->s3stmt, s->nparams, s->bindparms);
04676 return SQL_SUCCESS;
04677 }
04678
04679 #ifndef WINTERFACE
04680
04684 SQLRETURN SQL_API
04685 SQLDataSources(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *srvname,
04686 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
04687 SQLCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
04688 {
04689 if (env == SQL_NULL_HENV) {
04690 return SQL_INVALID_HANDLE;
04691 }
04692 return SQL_ERROR;
04693 }
04694 #endif
04695
04696 #ifdef WINTERFACE
04697
04701 SQLRETURN SQL_API
04702 SQLDataSourcesW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *srvname,
04703 SQLSMALLINT buflen1, SQLSMALLINT *lenp1,
04704 SQLWCHAR *desc, SQLSMALLINT buflen2, SQLSMALLINT *lenp2)
04705 {
04706 if (env == SQL_NULL_HENV) {
04707 return SQL_INVALID_HANDLE;
04708 }
04709 return SQL_ERROR;
04710 }
04711 #endif
04712
04713 #ifndef WINTERFACE
04714
04718 SQLRETURN SQL_API
04719 SQLDrivers(SQLHENV env, SQLUSMALLINT dir, SQLCHAR *drvdesc,
04720 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
04721 SQLCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
04722 {
04723 if (env == SQL_NULL_HENV) {
04724 return SQL_INVALID_HANDLE;
04725 }
04726 return SQL_ERROR;
04727 }
04728 #endif
04729
04730 #ifdef WINTERFACE
04731
04735 SQLRETURN SQL_API
04736 SQLDriversW(SQLHENV env, SQLUSMALLINT dir, SQLWCHAR *drvdesc,
04737 SQLSMALLINT descmax, SQLSMALLINT *desclenp,
04738 SQLWCHAR *drvattr, SQLSMALLINT attrmax, SQLSMALLINT *attrlenp)
04739 {
04740 if (env == SQL_NULL_HENV) {
04741 return SQL_INVALID_HANDLE;
04742 }
04743 return SQL_ERROR;
04744 }
04745 #endif
04746
04747 #ifndef WINTERFACE
04748
04752 SQLRETURN SQL_API
04753 SQLBrowseConnect(SQLHDBC dbc, SQLCHAR *connin, SQLSMALLINT conninLen,
04754 SQLCHAR *connout, SQLSMALLINT connoutMax,
04755 SQLSMALLINT *connoutLen)
04756 {
04757 SQLRETURN ret;
04758
04759 HDBC_LOCK(dbc);
04760 ret = drvunimpldbc(dbc);
04761 HDBC_UNLOCK(dbc);
04762 return ret;
04763 }
04764 #endif
04765
04766 #ifdef WINTERFACE
04767
04771 SQLRETURN SQL_API
04772 SQLBrowseConnectW(SQLHDBC dbc, SQLWCHAR *connin, SQLSMALLINT conninLen,
04773 SQLWCHAR *connout, SQLSMALLINT connoutMax,
04774 SQLSMALLINT *connoutLen)
04775 {
04776 SQLRETURN ret;
04777
04778 HDBC_LOCK(dbc);
04779 ret = drvunimpldbc(dbc);
04780 HDBC_UNLOCK(dbc);
04781 return ret;
04782 }
04783 #endif
04784
04793 static SQLRETURN
04794 drvputdata(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
04795 {
04796 STMT *s;
04797 int i, dlen, done = 0;
04798 BINDPARM *p;
04799
04800 if (stmt == SQL_NULL_HSTMT) {
04801 return SQL_INVALID_HANDLE;
04802 }
04803 s = (STMT *) stmt;
04804 if (!s->query || s->nparams <= 0) {
04805 seqerr:
04806 setstat(s, -1, "sequence error", "HY010");
04807 return SQL_ERROR;
04808 }
04809 for (i = (s->pdcount < 0) ? 0 : s->pdcount; i < s->nparams; i++) {
04810 p = &s->bindparms[i];
04811 if (p->need > 0) {
04812 int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
04813
04814 if (len == SQL_NULL_DATA) {
04815 freep(&p->parbuf);
04816 p->param = NULL;
04817 p->len = SQL_NULL_DATA;
04818 p->need = -1;
04819 } else if (type != SQL_C_CHAR
04820 #ifdef WCHARSUPPORT
04821 && type != SQL_C_WCHAR
04822 #endif
04823 && type != SQL_C_BINARY) {
04824 int size = 0;
04825
04826 switch (type) {
04827 case SQL_C_TINYINT:
04828 case SQL_C_UTINYINT:
04829 case SQL_C_STINYINT:
04830 #ifdef SQL_BIT
04831 case SQL_C_BIT:
04832 #endif
04833 size = sizeof (SQLCHAR);
04834 break;
04835 case SQL_C_SHORT:
04836 case SQL_C_USHORT:
04837 case SQL_C_SSHORT:
04838 size = sizeof (SQLSMALLINT);
04839 break;
04840 case SQL_C_LONG:
04841 case SQL_C_ULONG:
04842 case SQL_C_SLONG:
04843 size = sizeof (SQLINTEGER);
04844 break;
04845 #ifdef SQL_BIGINT
04846 case SQL_C_UBIGINT:
04847 case SQL_C_SBIGINT:
04848 size = sizeof (SQLBIGINT);
04849 break;
04850 #endif
04851 case SQL_C_FLOAT:
04852 size = sizeof (float);
04853 break;
04854 case SQL_C_DOUBLE:
04855 size = sizeof (double);
04856 break;
04857 #ifdef SQL_C_TYPE_DATE
04858 case SQL_C_TYPE_DATE:
04859 #endif
04860 case SQL_C_DATE:
04861 size = sizeof (DATE_STRUCT);
04862 break;
04863 #ifdef SQL_C_TYPE_DATE
04864 case SQL_C_TYPE_TIME:
04865 #endif
04866 case SQL_C_TIME:
04867 size = sizeof (TIME_STRUCT);
04868 break;
04869 #ifdef SQL_C_TYPE_DATE
04870 case SQL_C_TYPE_TIMESTAMP:
04871 #endif
04872 case SQL_C_TIMESTAMP:
04873 size = sizeof (TIMESTAMP_STRUCT);
04874 break;
04875 }
04876 freep(&p->parbuf);
04877 p->parbuf = xmalloc(size);
04878 if (!p->parbuf) {
04879 return nomem(s);
04880 }
04881 p->param = p->parbuf;
04882 memcpy(p->param, data, size);
04883 p->len = size;
04884 p->need = -1;
04885 } else if (len == SQL_NTS && (
04886 type == SQL_C_CHAR
04887 #ifdef WCHARSUPPORT
04888 || type == SQL_C_WCHAR
04889 #endif
04890 )) {
04891 char *dp = data;
04892
04893 #ifdef WCHARSUPPORT
04894 if (type == SQL_C_WCHAR) {
04895 dp = uc_to_utf(data, len);
04896 if (!dp) {
04897 return nomem(s);
04898 }
04899 }
04900 #endif
04901 #if defined(_WIN32) || defined(_WIN64)
04902 if (*s->oemcp) {
04903 dp = wmb_to_utf(data, strlen (data));
04904 if (!dp) {
04905 return nomem(s);
04906 }
04907 }
04908 #endif
04909 dlen = strlen(dp);
04910 freep(&p->parbuf);
04911 p->parbuf = xmalloc(dlen + 1);
04912 if (!p->parbuf) {
04913 if (dp != data) {
04914 uc_free(dp);
04915 }
04916 return nomem(s);
04917 }
04918 p->param = p->parbuf;
04919 strcpy(p->param, dp);
04920 if (dp != data) {
04921 uc_free(dp);
04922 }
04923 p->len = dlen;
04924 p->need = -1;
04925 } else if (len < 0) {
04926 setstat(s, -1, "invalid length", "HY090");
04927 return SQL_ERROR;
04928 } else {
04929 dlen = min(p->len - p->offs, len);
04930 if (!p->param) {
04931 setstat(s, -1, "no memory for parameter", "HY013");
04932 return SQL_ERROR;
04933 }
04934 memcpy((char *) p->param + p->offs, data, dlen);
04935 p->offs += dlen;
04936 if (p->offs >= p->len) {
04937 #ifdef WCHARSUPPORT
04938 if (type == SQL_C_WCHAR) {
04939 char *dp = uc_to_utf(p->param, p->len);
04940 char *np;
04941 int nlen;
04942
04943 if (!dp) {
04944 return nomem(s);
04945 }
04946 nlen = strlen(dp);
04947 np = xmalloc(nlen + 1);
04948 if (!np) {
04949 uc_free(dp);
04950 return nomem(s);
04951 }
04952 strcpy(np, dp);
04953 uc_free(dp);
04954 if (p->param == p->parbuf) {
04955 freep(&p->parbuf);
04956 }
04957 p->parbuf = p->param = np;
04958 p->len = nlen;
04959 } else {
04960 *((char *) p->param + p->len) = '\0';
04961 }
04962 p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR)
04963 ? -1 : 0;
04964 #else
04965 *((char *) p->param + p->len) = '\0';
04966 p->need = (type == SQL_C_CHAR) ? -1 : 0;
04967 #endif
04968 #if defined(_WIN32) || defined(_WIN64)
04969 if (type == SQL_C_CHAR && *s->oemcp &&
04970 !(p->stype == SQL_BINARY ||
04971 p->stype == SQL_VARBINARY ||
04972 p->stype == SQL_LONGVARBINARY)) {
04973 char *dp = wmb_to_utf(p->param, p->len);
04974
04975 if (!dp) {
04976 return nomem(s);
04977 }
04978 if (p->param == p->parbuf) {
04979 freep(&p->parbuf);
04980 }
04981 p->parbuf = p->param = dp;
04982 p->len = strlen(dp);
04983 }
04984 if (p->type == SQL_C_WCHAR &&
04985 (p->stype == SQL_VARCHAR ||
04986 p->stype == SQL_LONGVARCHAR) &&
04987 p->len == p->coldef * sizeof (SQLWCHAR)) {
04988
04989 p->len = p->coldef;
04990 }
04991 #endif
04992 }
04993 }
04994 done = 1;
04995 break;
04996 }
04997 }
04998 if (!done) {
04999 goto seqerr;
05000 }
05001 return SQL_SUCCESS;
05002 }
05003
05012 SQLRETURN SQL_API
05013 SQLPutData(SQLHSTMT stmt, SQLPOINTER data, SQLLEN len)
05014 {
05015 SQLRETURN ret;
05016
05017 HSTMT_LOCK(stmt);
05018 ret = drvputdata(stmt, data, len);
05019 HSTMT_UNLOCK(stmt);
05020 return ret;
05021 }
05022
05028 static SQLRETURN
05029 freeparams(STMT *s)
05030 {
05031 if (s->bindparms) {
05032 int n;
05033
05034 for (n = 0; n < s->nbindparms; n++) {
05035 freep(&s->bindparms[n].parbuf);
05036 memset(&s->bindparms[n], 0, sizeof (BINDPARM));
05037 }
05038 }
05039 return SQL_SUCCESS;
05040 }
05041
05053 static SQLRETURN
05054 setupparam(STMT *s, char *sql, int pnum)
05055 {
05056 int type, len = 0, needalloc = 0;
05057 BINDPARM *p;
05058
05059 if (!s->bindparms || pnum < 0 || pnum >= s->nbindparms) {
05060 goto error;
05061 }
05062 p = &s->bindparms[pnum];
05063 type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
05064 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
05065
05066 if (type == SQL_C_WCHAR && p->type == SQL_C_DEFAULT) {
05067 type = SQL_C_CHAR;
05068 }
05069 #endif
05070 if (p->need > 0) {
05071 return setupparbuf(s, p);
05072 }
05073 p->strbuf[0] = '\0';
05074 if (!p->param || (p->lenp && *p->lenp == SQL_NULL_DATA)) {
05075 p->s3type = SQLITE_NULL;
05076 p->s3size = 0;
05077 return SQL_SUCCESS;
05078 }
05079 if (type == SQL_C_CHAR &&
05080 (p->stype == SQL_BINARY ||
05081 p->stype == SQL_VARBINARY ||
05082 p->stype == SQL_LONGVARBINARY)) {
05083 type = SQL_C_BINARY;
05084 }
05085 switch (type) {
05086 case SQL_C_BINARY:
05087 p->s3type = SQLITE_BLOB;
05088 p->s3size = p->len;
05089 p->s3val = p->param;
05090 if (p->need < 0) {
05091 break;
05092 }
05093 if (!p->lenp) {
05094 len = p->len;
05095 } else if (*p->lenp == SQL_DATA_AT_EXEC) {
05096 len = p->len;
05097 } else {
05098 len = *p->lenp;
05099 if (len <= SQL_LEN_DATA_AT_EXEC_OFFSET) {
05100 len = SQL_LEN_DATA_AT_EXEC(len);
05101 }
05102 }
05103 if (len < 0) {
05104 setstat(s, -1, "invalid length", "HY009");
05105 return SQL_ERROR;
05106 }
05107 p->len = len;
05108 p->max = p->len;
05109 p->need = -1;
05110 p->s3size = len;
05111 break;
05112 #ifdef WCHARSUPPORT
05113 case SQL_C_WCHAR:
05114 #endif
05115 case SQL_C_CHAR:
05116 p->s3type = SQLITE_TEXT;
05117 p->s3size = -1;
05118 p->s3val = p->param;
05119 if (!p->parbuf) {
05120 #ifdef WCHARSUPPORT
05121 if (type == SQL_C_WCHAR) {
05122 if (!p->lenp || *p->lenp == SQL_NTS) {
05123 p->max = uc_strlen(p->param) * sizeof (SQLWCHAR);
05124 } else if (*p->lenp >= 0) {
05125 p->max = *p->lenp;
05126 }
05127 } else
05128 #endif
05129 if (type == SQL_C_CHAR) {
05130 if (!p->lenp || *p->lenp == SQL_NTS) {
05131 p->len = p->max = strlen(p->param);
05132 #if defined(_WIN32) || defined(_WIN64)
05133 needalloc = 1;
05134 #endif
05135 } else if (*p->lenp >= 0) {
05136 p->len = p->max = *p->lenp;
05137 needalloc = 1;
05138 }
05139 }
05140 }
05141 if (p->need < 0 && p->parbuf == p->param) {
05142 break;
05143 }
05144 #ifdef WCHARSUPPORT
05145 if (type == SQL_C_WCHAR) {
05146 char *dp = uc_to_utf(p->param, p->max);
05147
05148 if (!dp) {
05149 return nomem(s);
05150 }
05151 if (p->param == p->parbuf) {
05152 freep(&p->parbuf);
05153 }
05154 p->parbuf = p->param = dp;
05155 p->need = -1;
05156 p->len = strlen(p->param);
05157 p->s3val = p->param;
05158 p->s3size = p->len;
05159 } else
05160 #endif
05161 if (type == SQL_C_CHAR) {
05162 p->s3val = p->param;
05163 if (needalloc) {
05164 char *dp;
05165
05166 #if defined(_WIN32) || defined(_WIN64)
05167 if (*s->oemcp) {
05168 dp = wmb_to_utf(p->param, p->len);
05169 } else {
05170 dp = xmalloc(p->len + 1);
05171 }
05172 #else
05173 dp = xmalloc(p->len + 1);
05174 #endif
05175 if (!dp) {
05176 return nomem(s);
05177 }
05178 #if defined(_WIN32) || defined(_WIN64)
05179 if (*s->oemcp) {
05180 p->len = strlen(dp);
05181 } else {
05182 memcpy(dp, p->param, p->len);
05183 dp[p->len] = '\0';
05184 }
05185 #else
05186 memcpy(dp, p->param, p->len);
05187 dp[p->len] = '\0';
05188 #endif
05189 if (p->param == p->parbuf) {
05190 freep(&p->parbuf);
05191 }
05192 p->parbuf = p->param = dp;
05193 p->need = -1;
05194 p->s3val = p->param;
05195 p->s3size = p->len;
05196 }
05197 }
05198 break;
05199 case SQL_C_UTINYINT:
05200 case SQL_C_TINYINT:
05201 case SQL_C_STINYINT:
05202 p->s3type = SQLITE_INTEGER;
05203 p->s3size = sizeof (int);
05204 p->s3ival = *((SQLCHAR *) p->param);
05205 break;
05206 case SQL_C_USHORT:
05207 p->s3type = SQLITE_INTEGER;
05208 p->s3size = sizeof (int);
05209 p->s3ival = *((SQLUSMALLINT *) p->param);
05210 break;
05211 case SQL_C_SHORT:
05212 case SQL_C_SSHORT:
05213 p->s3type = SQLITE_INTEGER;
05214 p->s3size = sizeof (int);
05215 p->s3ival = *((SQLSMALLINT *) p->param);
05216 break;
05217 case SQL_C_ULONG:
05218 p->s3type = SQLITE_INTEGER;
05219 p->s3size = sizeof (int);
05220 p->s3ival = *((SQLUINTEGER *) p->param);
05221 break;
05222 case SQL_C_LONG:
05223 case SQL_C_SLONG:
05224 p->s3type = SQLITE_INTEGER;
05225 p->s3size = sizeof (int);
05226 p->s3ival = *((SQLINTEGER *) p->param);
05227 break;
05228 #ifdef SQL_BIT
05229 case SQL_C_BIT:
05230 p->s3type = SQLITE_INTEGER;
05231 p->s3size = sizeof (int);
05232 p->s3ival = (*((SQLCHAR *) p->param)) ? 1 : 0;
05233 break;
05234 #endif
05235 #ifdef SQL_BIGINT
05236 case SQL_C_SBIGINT:
05237 p->s3type = SQLITE_INTEGER;
05238 p->s3size = sizeof (sqlite_int64);
05239 p->s3lival = *((sqlite_int64 *) p->param);
05240 break;
05241 case SQL_C_UBIGINT:
05242 p->s3type = SQLITE_INTEGER;
05243 p->s3size = sizeof (sqlite_int64);
05244 p->s3lival = *((sqlite_uint64 *) p->param);
05245 break;
05246 #endif
05247 case SQL_C_FLOAT:
05248 p->s3type = SQLITE_FLOAT;
05249 p->s3size = sizeof (double);
05250 p->s3dval = *((float *) p->param);
05251 break;
05252 case SQL_C_DOUBLE:
05253 p->s3type = SQLITE_FLOAT;
05254 p->s3size = sizeof (double);
05255 p->s3dval = *((double *) p->param);
05256 break;
05257 #ifdef SQL_C_TYPE_DATE
05258 case SQL_C_TYPE_DATE:
05259 #endif
05260 case SQL_C_DATE:
05261 if (*s->jdconv) {
05262 int a, b, x1, x2, y, m, d;
05263
05264 p->s3type = SQLITE_FLOAT;
05265 p->s3size = sizeof (double);
05266 y = ((DATE_STRUCT *) p->param)->year;
05267 m = ((DATE_STRUCT *) p->param)->month;
05268 d = ((DATE_STRUCT *) p->param)->day;
05269 if (m <= 2) {
05270 y--;
05271 m += 12;
05272 }
05273 a = y / 100;
05274 b = 2 - a + (a / 4);
05275 x1 = 36525 * (y + 4716) / 100;
05276 x2 = 306001 * (m + 1) / 10000;
05277 p->s3dval = x1 + x2 + d + b - 1524.5;
05278 break;
05279 }
05280 sprintf(p->strbuf, "%04d-%02d-%02d",
05281 ((DATE_STRUCT *) p->param)->year,
05282 ((DATE_STRUCT *) p->param)->month,
05283 ((DATE_STRUCT *) p->param)->day);
05284 p->s3type = SQLITE_TEXT;
05285 p->s3size = -1;
05286 p->s3val = p->strbuf;
05287 break;
05288 #ifdef SQL_C_TYPE_TIME
05289 case SQL_C_TYPE_TIME:
05290 #endif
05291 case SQL_C_TIME:
05292 if (*s->jdconv) {
05293 p->s3type = SQLITE_FLOAT;
05294 p->s3size = sizeof (double);
05295 p->s3dval = 2451544.5 +
05296 (((TIME_STRUCT *) p->param)->hour * 3600000.0 +
05297 ((TIME_STRUCT *) p->param)->minute * 60000.0 +
05298 ((TIME_STRUCT *) p->param)->second * 1000.0) / 86400000.0;
05299 break;
05300 }
05301 sprintf(p->strbuf, "%02d:%02d:%02d",
05302 ((TIME_STRUCT *) p->param)->hour,
05303 ((TIME_STRUCT *) p->param)->minute,
05304 ((TIME_STRUCT *) p->param)->second);
05305 p->s3type = SQLITE_TEXT;
05306 p->s3size = -1;
05307 p->s3val = p->strbuf;
05308 break;
05309 #ifdef SQL_C_TYPE_TIMESTAMP
05310 case SQL_C_TYPE_TIMESTAMP:
05311 #endif
05312 case SQL_C_TIMESTAMP:
05313 if (*s->jdconv) {
05314 int a, b, x1, x2, y, m, d;
05315
05316 p->s3type = SQLITE_FLOAT;
05317 p->s3size = sizeof (double);
05318 y = ((TIMESTAMP_STRUCT *) p->param)->year;
05319 m = ((TIMESTAMP_STRUCT *) p->param)->month;
05320 d = ((TIMESTAMP_STRUCT *) p->param)->day;
05321 if (m <= 2) {
05322 y--;
05323 m += 12;
05324 }
05325 a = y / 100;
05326 b = 2 - a + (a / 4);
05327 x1 = 36525 * (y + 4716) / 100;
05328 x2 = 306001 * (m + 1) / 10000;
05329 p->s3dval = x1 + x2 + d + b - 1524.5 +
05330 (((TIMESTAMP_STRUCT *) p->param)->hour * 3600000.0 +
05331 ((TIMESTAMP_STRUCT *) p->param)->minute * 60000.0 +
05332 ((TIMESTAMP_STRUCT *) p->param)->second * 1000.0 +
05333 ((TIMESTAMP_STRUCT *) p->param)->fraction / 1.0E6)
05334 / 86400000.0;
05335 break;
05336 }
05337 len = (int) ((TIMESTAMP_STRUCT *) p->param)->fraction;
05338 len /= 1000000;
05339 len = len % 1000;
05340 if (len < 0) {
05341 len = 0;
05342 }
05343 if (p->coldef && p->coldef <= 16) {
05344 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
05345 ((TIMESTAMP_STRUCT *) p->param)->year,
05346 ((TIMESTAMP_STRUCT *) p->param)->month,
05347 ((TIMESTAMP_STRUCT *) p->param)->day,
05348 ((TIMESTAMP_STRUCT *) p->param)->hour,
05349 ((TIMESTAMP_STRUCT *) p->param)->minute);
05350 } else if (p->coldef && p->coldef <= 19) {
05351 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
05352 ((TIMESTAMP_STRUCT *) p->param)->year,
05353 ((TIMESTAMP_STRUCT *) p->param)->month,
05354 ((TIMESTAMP_STRUCT *) p->param)->day,
05355 ((TIMESTAMP_STRUCT *) p->param)->hour,
05356 ((TIMESTAMP_STRUCT *) p->param)->minute,
05357 ((TIMESTAMP_STRUCT *) p->param)->second);
05358 } else {
05359 sprintf(p->strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
05360 ((TIMESTAMP_STRUCT *) p->param)->year,
05361 ((TIMESTAMP_STRUCT *) p->param)->month,
05362 ((TIMESTAMP_STRUCT *) p->param)->day,
05363 ((TIMESTAMP_STRUCT *) p->param)->hour,
05364 ((TIMESTAMP_STRUCT *) p->param)->minute,
05365 ((TIMESTAMP_STRUCT *) p->param)->second,
05366 len);
05367 }
05368 p->s3type = SQLITE_TEXT;
05369 p->s3size = -1;
05370 p->s3val = p->strbuf;
05371 break;
05372 default:
05373 error:
05374 setstat(s, -1, "unsupported parameter type",
05375 (*s->ov3) ? "07009" : "S1093");
05376 return SQL_ERROR;
05377 }
05378 return SQL_SUCCESS;
05379 }
05380
05396 static SQLRETURN
05397 drvbindparam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
05398 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLUINTEGER coldef,
05399 SQLSMALLINT scale,
05400 SQLPOINTER data, SQLINTEGER buflen, SQLLEN *len)
05401 {
05402 STMT *s;
05403 BINDPARM *p;
05404
05405 if (stmt == SQL_NULL_HSTMT) {
05406 return SQL_INVALID_HANDLE;
05407 }
05408 s = (STMT *) stmt;
05409 if (pnum == 0) {
05410 setstat(s, -1, "invalid parameter", (*s->ov3) ? "07009" : "S1093");
05411 return SQL_ERROR;
05412 }
05413 if (!data && !len) {
05414 setstat(s, -1, "invalid buffer", "HY003");
05415 return SQL_ERROR;
05416 }
05417 --pnum;
05418 if (s->bindparms) {
05419 if (pnum >= s->nbindparms) {
05420 BINDPARM *newparms;
05421
05422 newparms = xrealloc(s->bindparms,
05423 (pnum + 1) * sizeof (BINDPARM));
05424 if (!newparms) {
05425 outofmem:
05426 return nomem(s);
05427 }
05428 s->bindparms = newparms;
05429 memset(&s->bindparms[s->nbindparms], 0,
05430 (pnum + 1 - s->nbindparms) * sizeof (BINDPARM));
05431 s->nbindparms = pnum + 1;
05432 }
05433 } else {
05434 int npar = max(10, pnum + 1);
05435
05436 s->bindparms = xmalloc(npar * sizeof (BINDPARM));
05437 if (!s->bindparms) {
05438 goto outofmem;
05439 }
05440 memset(s->bindparms, 0, npar * sizeof (BINDPARM));
05441 s->nbindparms = npar;
05442 }
05443 switch (buftype) {
05444 case SQL_C_STINYINT:
05445 case SQL_C_UTINYINT:
05446 case SQL_C_TINYINT:
05447 #ifdef SQL_C_BIT
05448 case SQL_C_BIT:
05449 #endif
05450 buflen = sizeof (SQLCHAR);
05451 break;
05452 case SQL_C_SHORT:
05453 case SQL_C_USHORT:
05454 case SQL_C_SSHORT:
05455 buflen = sizeof (SQLSMALLINT);
05456 break;
05457 case SQL_C_SLONG:
05458 case SQL_C_ULONG:
05459 case SQL_C_LONG:
05460 buflen = sizeof (SQLINTEGER);
05461 break;
05462 case SQL_C_FLOAT:
05463 buflen = sizeof (float);
05464 break;
05465 case SQL_C_DOUBLE:
05466 buflen = sizeof (double);
05467 break;
05468 case SQL_C_TIMESTAMP:
05469 #ifdef SQL_C_TYPE_TIMESTAMP
05470 case SQL_C_TYPE_TIMESTAMP:
05471 #endif
05472 buflen = sizeof (TIMESTAMP_STRUCT);
05473 break;
05474 case SQL_C_TIME:
05475 #ifdef SQL_C_TYPE_TIME
05476 case SQL_C_TYPE_TIME:
05477 #endif
05478 buflen = sizeof (TIME_STRUCT);
05479 break;
05480 case SQL_C_DATE:
05481 #ifdef SQL_C_TYPE_DATE
05482 case SQL_C_TYPE_DATE:
05483 #endif
05484 buflen = sizeof (DATE_STRUCT);
05485 break;
05486 #ifdef SQL_C_UBIGINT
05487 case SQL_C_UBIGINT:
05488 buflen = sizeof (SQLBIGINT);
05489 break;
05490 #endif
05491 #ifdef SQL_C_SBIGINT
05492 case SQL_C_SBIGINT:
05493 buflen = sizeof (SQLBIGINT);
05494 break;
05495 #endif
05496 #ifdef SQL_C_BIGINT
05497 case SQL_C_BIGINT:
05498 buflen = sizeof (SQLBIGINT);
05499 break;
05500 #endif
05501 }
05502 p = &s->bindparms[pnum];
05503 p->type = buftype;
05504 p->stype = ptype;
05505 p->coldef = coldef;
05506 p->scale = scale;
05507 p->max = buflen;
05508 p->inc = buflen;
05509 p->lenp = p->lenp0 = len;
05510 p->offs = 0;
05511 p->len = 0;
05512 p->param0 = data;
05513 freep(&p->parbuf);
05514 p->param = p->param0;
05515 p->bound = 1;
05516 p->need = 0;
05517 return SQL_SUCCESS;
05518 }
05519
05535 SQLRETURN SQL_API
05536 SQLBindParameter(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT iotype,
05537 SQLSMALLINT buftype, SQLSMALLINT ptype, SQLULEN coldef,
05538 SQLSMALLINT scale,
05539 SQLPOINTER data, SQLLEN buflen, SQLLEN *len)
05540 {
05541 SQLRETURN ret;
05542
05543 HSTMT_LOCK(stmt);
05544 ret = drvbindparam(stmt, pnum, iotype, buftype, ptype, coldef,
05545 scale, data, buflen, len);
05546 HSTMT_UNLOCK(stmt);
05547 return ret;
05548 }
05549
05550 #ifndef HAVE_IODBC
05551
05564 SQLRETURN SQL_API
05565 SQLBindParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT vtype,
05566 SQLSMALLINT ptype, SQLULEN lenprec,
05567 SQLSMALLINT scale, SQLPOINTER val,
05568 SQLLEN *lenp)
05569 {
05570 SQLRETURN ret;
05571
05572 HSTMT_LOCK(stmt);
05573 ret = drvbindparam(stmt, pnum, SQL_PARAM_INPUT, vtype, ptype,
05574 lenprec, scale, val, 0, lenp);
05575 HSTMT_UNLOCK(stmt);
05576 return ret;
05577 }
05578 #endif
05579
05587 SQLRETURN SQL_API
05588 SQLNumParams(SQLHSTMT stmt, SQLSMALLINT *nparam)
05589 {
05590 STMT *s;
05591 SQLSMALLINT dummy;
05592
05593 HSTMT_LOCK(stmt);
05594 if (stmt == SQL_NULL_HSTMT) {
05595 return SQL_INVALID_HANDLE;
05596 }
05597 s = (STMT *) stmt;
05598 if (!nparam) {
05599 nparam = &dummy;
05600 }
05601 *nparam = s->nparams;
05602 HSTMT_UNLOCK(stmt);
05603 return SQL_SUCCESS;
05604 }
05605
05613 static SQLRETURN
05614 setupparbuf(STMT *s, BINDPARM *p)
05615 {
05616 if (!p->parbuf) {
05617 if (*p->lenp == SQL_DATA_AT_EXEC) {
05618 p->len = p->max;
05619 } else {
05620 p->len = SQL_LEN_DATA_AT_EXEC(*p->lenp);
05621 }
05622 if (p->len < 0 && p->len != SQL_NTS &&
05623 p->len != SQL_NULL_DATA) {
05624 setstat(s, -1, "invalid length", "HY009");
05625 return SQL_ERROR;
05626 }
05627 if (p->len >= 0) {
05628 p->parbuf = xmalloc(p->len + 2);
05629 if (!p->parbuf) {
05630 return nomem(s);
05631 }
05632 p->param = p->parbuf;
05633 } else {
05634 p->param = NULL;
05635 }
05636 }
05637 return SQL_NEED_DATA;
05638 }
05639
05647 SQLRETURN SQL_API
05648 SQLParamData(SQLHSTMT stmt, SQLPOINTER *pind)
05649 {
05650 STMT *s;
05651 int i;
05652 SQLPOINTER dummy;
05653 SQLRETURN ret;
05654 BINDPARM *p;
05655
05656 HSTMT_LOCK(stmt);
05657 if (stmt == SQL_NULL_HSTMT) {
05658 return SQL_INVALID_HANDLE;
05659 }
05660 s = (STMT *) stmt;
05661 if (!pind) {
05662 pind = &dummy;
05663 }
05664 if (s->pdcount < s->nparams) {
05665 s->pdcount++;
05666 }
05667 for (i = 0; i < s->pdcount; i++) {
05668 p = &s->bindparms[i];
05669 if (p->need > 0) {
05670 int type = mapdeftype(p->type, p->stype, -1, s->nowchar[0]);
05671
05672 p->need = (type == SQL_C_CHAR || type == SQL_C_WCHAR) ? -1 : 0;
05673 }
05674 }
05675 for (; i < s->nparams; i++) {
05676 p = &s->bindparms[i];
05677 if (p->need > 0) {
05678 *pind = (SQLPOINTER) p->param0;
05679 ret = setupparbuf(s, p);
05680 s->pdcount = i;
05681 goto done;
05682 }
05683 }
05684 ret = drvexecute(stmt, 0);
05685 done:
05686 HSTMT_UNLOCK(stmt);
05687 return ret;
05688 }
05689
05701 SQLRETURN SQL_API
05702 SQLDescribeParam(SQLHSTMT stmt, SQLUSMALLINT pnum, SQLSMALLINT *dtype,
05703 SQLULEN *size, SQLSMALLINT *decdigits, SQLSMALLINT *nullable)
05704 {
05705 STMT *s;
05706 SQLRETURN ret = SQL_ERROR;
05707
05708 HSTMT_LOCK(stmt);
05709 if (stmt == SQL_NULL_HSTMT) {
05710 return SQL_INVALID_HANDLE;
05711 }
05712 s = (STMT *) stmt;
05713 --pnum;
05714 if (pnum >= s->nparams) {
05715 setstat(s, -1, "invalid parameter index",
05716 (*s->ov3) ? "HY000" : "S1000");
05717 goto done;
05718 }
05719 if (dtype) {
05720 #ifdef SQL_LONGVARCHAR
05721 #ifdef WINTERFACE
05722 *dtype = s->nowchar[0] ? SQL_LONGVARCHAR : SQL_WLONGVARCHAR;
05723 #else
05724 *dtype = SQL_LONGVARCHAR;
05725 #endif
05726 #else
05727 #ifdef WINTERFACE
05728 *dtype = s->nowchar[0] ? SQL_VARCHAR : SQL_WVARCHAR;
05729 #else
05730 *dtype = SQL_VARCHAR;
05731 #endif
05732 #endif
05733 }
05734 if (size) {
05735 #ifdef SQL_LONGVARCHAR
05736 *size = 65536;
05737 #else
05738 *size = 255;
05739 #endif
05740 }
05741 if (decdigits) {
05742 *decdigits = 0;
05743 }
05744 if (nullable) {
05745 *nullable = SQL_NULLABLE;
05746 }
05747 ret = SQL_SUCCESS;
05748 done:
05749 HSTMT_UNLOCK(stmt);
05750 return ret;
05751 }
05752
05766 SQLRETURN SQL_API
05767 SQLSetParam(SQLHSTMT stmt, SQLUSMALLINT par, SQLSMALLINT type,
05768 SQLSMALLINT sqltype, SQLULEN coldef,
05769 SQLSMALLINT scale, SQLPOINTER val, SQLLEN *nval)
05770 {
05771 SQLRETURN ret;
05772
05773 HSTMT_LOCK(stmt);
05774 ret = drvbindparam(stmt, par, SQL_PARAM_INPUT,
05775 type, sqltype, coldef, scale, val,
05776 SQL_SETPARAM_VALUE_MAX, nval);
05777 HSTMT_UNLOCK(stmt);
05778 return ret;
05779 }
05780
05785 SQLRETURN SQL_API
05786 SQLParamOptions(SQLHSTMT stmt, SQLULEN rows, SQLULEN *rowp)
05787 {
05788 SQLRETURN ret;
05789
05790 HSTMT_LOCK(stmt);
05791 ret = drvunimplstmt(stmt);
05792 HSTMT_UNLOCK(stmt);
05793 return ret;
05794 }
05795
05796 #ifndef WINTERFACE
05797
05801 SQLRETURN SQL_API
05802 SQLGetDescField(SQLHDESC handle, SQLSMALLINT recno,
05803 SQLSMALLINT fieldid, SQLPOINTER value,
05804 SQLINTEGER buflen, SQLINTEGER *strlen)
05805 {
05806 return SQL_ERROR;
05807 }
05808 #endif
05809
05810 #ifdef WINTERFACE
05811
05815 SQLRETURN SQL_API
05816 SQLGetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
05817 SQLSMALLINT fieldid, SQLPOINTER value,
05818 SQLINTEGER buflen, SQLINTEGER *strlen)
05819 {
05820 return SQL_ERROR;
05821 }
05822 #endif
05823
05824 #ifndef WINTERFACE
05825
05829 SQLRETURN SQL_API
05830 SQLSetDescField(SQLHDESC handle, SQLSMALLINT recno,
05831 SQLSMALLINT fieldid, SQLPOINTER value,
05832 SQLINTEGER buflen)
05833 {
05834 return SQL_ERROR;
05835 }
05836 #endif
05837
05838 #ifdef WINTERFACE
05839
05843 SQLRETURN SQL_API
05844 SQLSetDescFieldW(SQLHDESC handle, SQLSMALLINT recno,
05845 SQLSMALLINT fieldid, SQLPOINTER value,
05846 SQLINTEGER buflen)
05847 {
05848 return SQL_ERROR;
05849 }
05850 #endif
05851
05852 #ifndef WINTERFACE
05853
05857 SQLRETURN SQL_API
05858 SQLGetDescRec(SQLHDESC handle, SQLSMALLINT recno,
05859 SQLCHAR *name, SQLSMALLINT buflen,
05860 SQLSMALLINT *strlen, SQLSMALLINT *type,
05861 SQLSMALLINT *subtype, SQLLEN *len,
05862 SQLSMALLINT *prec, SQLSMALLINT *scale,
05863 SQLSMALLINT *nullable)
05864 {
05865 return SQL_ERROR;
05866 }
05867 #endif
05868
05869 #ifdef WINTERFACE
05870
05874 SQLRETURN SQL_API
05875 SQLGetDescRecW(SQLHDESC handle, SQLSMALLINT recno,
05876 SQLWCHAR *name, SQLSMALLINT buflen,
05877 SQLSMALLINT *strlen, SQLSMALLINT *type,
05878 SQLSMALLINT *subtype, SQLLEN *len,
05879 SQLSMALLINT *prec, SQLSMALLINT *scale,
05880 SQLSMALLINT *nullable)
05881 {
05882 return SQL_ERROR;
05883 }
05884 #endif
05885
05890 SQLRETURN SQL_API
05891 SQLSetDescRec(SQLHDESC handle, SQLSMALLINT recno,
05892 SQLSMALLINT type, SQLSMALLINT subtype,
05893 SQLLEN len, SQLSMALLINT prec,
05894 SQLSMALLINT scale, SQLPOINTER data,
05895 SQLLEN *strlen, SQLLEN *indicator)
05896 {
05897 return SQL_ERROR;
05898 }
05899
05911 static SQLRETURN
05912 mkresultset(HSTMT stmt, COL *colspec, int ncols, COL *colspec3,
05913 int ncols3, int *nret)
05914 {
05915 STMT *s;
05916 DBC *d;
05917
05918 if (stmt == SQL_NULL_HSTMT) {
05919 return SQL_INVALID_HANDLE;
05920 }
05921 s = (STMT *) stmt;
05922 if (s->dbc == SQL_NULL_HDBC) {
05923 noconn:
05924 return noconn(s);
05925 }
05926 d = (DBC *) s->dbc;
05927 if (!d->sqlite) {
05928 goto noconn;
05929 }
05930 s3stmt_end_if(s);
05931 freeresult(s, 0);
05932 if (colspec3 && *s->ov3) {
05933 s->ncols = ncols3;
05934 s->cols = colspec3;
05935 } else {
05936 s->ncols = ncols;
05937 s->cols = colspec;
05938 }
05939 mkbindcols(s, s->ncols);
05940 s->nowchar[1] = 1;
05941 s->nrows = 0;
05942 s->rowp = s->rowprs = -1;
05943 s->isselect = -1;
05944 if (nret) {
05945 *nret = s->ncols;
05946 }
05947 return SQL_SUCCESS;
05948 }
05949
05954 static COL tablePrivSpec2[] = {
05955 { "SYSTEM", "TABLEPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
05956 { "SYSTEM", "TABLEPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
05957 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
05958 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
05959 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
05960 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
05961 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
05962 };
05963
05964 static COL tablePrivSpec3[] = {
05965 { "SYSTEM", "TABLEPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
05966 { "SYSTEM", "TABLEPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
05967 { "SYSTEM", "TABLEPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
05968 { "SYSTEM", "TABLEPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
05969 { "SYSTEM", "TABLEPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
05970 { "SYSTEM", "TABLEPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 },
05971 { "SYSTEM", "TABLEPRIV", "IS_GRANTABLE", SCOL_VARCHAR, 50 }
05972 };
05973
05986 static SQLRETURN
05987 drvtableprivileges(SQLHSTMT stmt,
05988 SQLCHAR *cat, SQLSMALLINT catLen,
05989 SQLCHAR *schema, SQLSMALLINT schemaLen,
05990 SQLCHAR *table, SQLSMALLINT tableLen)
05991 {
05992 SQLRETURN ret;
05993 STMT *s;
05994 DBC *d;
05995 int ncols, rc, size, npatt;
05996 char *errp = NULL, *sql, tname[512];
05997
05998 ret = mkresultset(stmt, tablePrivSpec2, array_size(tablePrivSpec2),
05999 tablePrivSpec3, array_size(tablePrivSpec3), NULL);
06000 if (ret != SQL_SUCCESS) {
06001 return ret;
06002 }
06003 s = (STMT *) stmt;
06004 d = (DBC *) s->dbc;
06005 if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
06006 table = NULL;
06007 goto doit;
06008 }
06009 if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
06010 schema[0] == '%') {
06011 if ((!cat || catLen == 0 || !cat[0]) &&
06012 (!table || tableLen == 0 || !table[0])) {
06013 table = NULL;
06014 goto doit;
06015 }
06016 }
06017 doit:
06018 if (!table) {
06019 size = 1;
06020 tname[0] = '%';
06021 } else {
06022 if (tableLen == SQL_NTS) {
06023 size = sizeof (tname) - 1;
06024 } else {
06025 size = min(sizeof (tname) - 1, tableLen);
06026 }
06027 strncpy(tname, (char *) table, size);
06028 }
06029 tname[size] = '\0';
06030 npatt = unescpat(tname);
06031 #if defined(_WIN32) || defined(_WIN64)
06032 sql = sqlite3_mprintf("select %s as 'TABLE_QUALIFIER', "
06033 "%s as 'TABLE_OWNER', "
06034 "tbl_name as 'TABLE_NAME', "
06035 "'' as 'GRANTOR', "
06036 "'' as 'GRANTEE', "
06037 "'SELECT' AS 'PRIVILEGE', "
06038 "NULL as 'IS_GRANTABLE' "
06039 "from sqlite_master where "
06040 "(type = 'table' or type = 'view') "
06041 "and tbl_name %s %Q "
06042 "UNION "
06043 "select %s as 'TABLE_QUALIFIER', "
06044 "%s as 'TABLE_OWNER', "
06045 "tbl_name as 'TABLE_NAME', "
06046 "'' as 'GRANTOR', "
06047 "'' as 'GRANTEE', "
06048 "'UPDATE' AS 'PRIVILEGE', "
06049 "NULL as 'IS_GRANTABLE' "
06050 "from sqlite_master where "
06051 "(type = 'table' or type = 'view') "
06052 "and tbl_name %s %Q "
06053 "UNION "
06054 "select %s as 'TABLE_QUALIFIER', "
06055 "%s as 'TABLE_OWNER', "
06056 "tbl_name as 'TABLE_NAME', "
06057 "'' as 'GRANTOR', "
06058 "'' as 'GRANTEE', "
06059 "'DELETE' AS 'PRIVILEGE', "
06060 "NULL as 'IS_GRANTABLE' "
06061 "from sqlite_master where "
06062 "(type = 'table' or type = 'view') "
06063 "and tbl_name %s %Q "
06064 "UNION "
06065 "select %s as 'TABLE_QUALIFIER', "
06066 "%s as 'TABLE_OWNER', "
06067 "tbl_name as 'TABLE_NAME', "
06068 "'' as 'GRANTOR', "
06069 "'' as 'GRANTEE', "
06070 "'INSERT' AS 'PRIVILEGE', "
06071 "NULL as 'IS_GRANTABLE' "
06072 "from sqlite_master where "
06073 "(type = 'table' or type = 'view') "
06074 "and tbl_name %s %Q "
06075 "UNION "
06076 "select %s as 'TABLE_QUALIFIER', "
06077 "%s as 'TABLE_OWNER', "
06078 "tbl_name as 'TABLE_NAME', "
06079 "'' as 'GRANTOR', "
06080 "'' as 'GRANTEE', "
06081 "'REFERENCES' AS 'PRIVILEGE', "
06082 "NULL as 'IS_GRANTABLE' "
06083 "from sqlite_master where "
06084 "(type = 'table' or type = 'view') "
06085 "and tbl_name %s %Q",
06086 d->xcelqrx ? "'main'" : "NULL",
06087 d->xcelqrx ? "''" : "NULL",
06088 npatt ? "like" : "=", tname,
06089 d->xcelqrx ? "'main'" : "NULL",
06090 d->xcelqrx ? "''" : "NULL",
06091 npatt ? "like" : "=", tname,
06092 d->xcelqrx ? "'main'" : "NULL",
06093 d->xcelqrx ? "''" : "NULL",
06094 npatt ? "like" : "=", tname,
06095 d->xcelqrx ? "'main'" : "NULL",
06096 d->xcelqrx ? "''" : "NULL",
06097 npatt ? "like" : "=", tname,
06098 d->xcelqrx ? "'main'" : "NULL",
06099 d->xcelqrx ? "''" : "NULL",
06100 npatt ? "like" : "=", tname);
06101 #else
06102 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
06103 "NULL as 'TABLE_OWNER', "
06104 "tbl_name as 'TABLE_NAME', "
06105 "'' as 'GRANTOR', "
06106 "'' as 'GRANTEE', "
06107 "'SELECT' AS 'PRIVILEGE', "
06108 "NULL as 'IS_GRANTABLE' "
06109 "from sqlite_master where "
06110 "(type = 'table' or type = 'view') "
06111 "and tbl_name %s %Q "
06112 "UNION "
06113 "select NULL as 'TABLE_QUALIFIER', "
06114 "NULL as 'TABLE_OWNER', "
06115 "tbl_name as 'TABLE_NAME', "
06116 "'' as 'GRANTOR', "
06117 "'' as 'GRANTEE', "
06118 "'UPDATE' AS 'PRIVILEGE', "
06119 "NULL as 'IS_GRANTABLE' "
06120 "from sqlite_master where "
06121 "(type = 'table' or type = 'view') "
06122 "and tbl_name %s %Q "
06123 "UNION "
06124 "select NULL as 'TABLE_QUALIFIER', "
06125 "NULL as 'TABLE_OWNER', "
06126 "tbl_name as 'TABLE_NAME', "
06127 "'' as 'GRANTOR', "
06128 "'' as 'GRANTEE', "
06129 "'DELETE' AS 'PRIVILEGE', "
06130 "NULL as 'IS_GRANTABLE' "
06131 "from sqlite_master where "
06132 "(type = 'table' or type = 'view') "
06133 "and tbl_name %s %Q "
06134 "UNION "
06135 "select NULL as 'TABLE_QUALIFIER', "
06136 "NULL as 'TABLE_OWNER', "
06137 "tbl_name as 'TABLE_NAME', "
06138 "'' as 'GRANTOR', "
06139 "'' as 'GRANTEE', "
06140 "'INSERT' AS 'PRIVILEGE', "
06141 "NULL as 'IS_GRANTABLE' "
06142 "from sqlite_master where "
06143 "(type = 'table' or type = 'view') "
06144 "and tbl_name %s %Q "
06145 "UNION "
06146 "select NULL as 'TABLE_QUALIFIER', "
06147 "NULL as 'TABLE_OWNER', "
06148 "tbl_name as 'TABLE_NAME', "
06149 "'' as 'GRANTOR', "
06150 "'' as 'GRANTEE', "
06151 "'REFERENCES' AS 'PRIVILEGE', "
06152 "NULL as 'IS_GRANTABLE' "
06153 "from sqlite_master where "
06154 "(type = 'table' or type = 'view') "
06155 "and tbl_name %s %Q",
06156 npatt ? "like" : "=", tname,
06157 npatt ? "like" : "=", tname,
06158 npatt ? "like" : "=", tname,
06159 npatt ? "like" : "=", tname,
06160 npatt ? "like" : "=", tname);
06161 #endif
06162 if (!sql) {
06163 return nomem(s);
06164 }
06165 ret = starttran(s);
06166 if (ret != SQL_SUCCESS) {
06167 sqlite3_free(sql);
06168 return ret;
06169 }
06170 dbtraceapi(d, "sqlite3_get_table", sql);
06171 rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
06172 sqlite3_free(sql);
06173 if (rc == SQLITE_OK) {
06174 if (ncols != s->ncols) {
06175 freeresult(s, 0);
06176 s->nrows = 0;
06177 } else {
06178 s->rowfree = sqlite3_free_table;
06179 }
06180 } else {
06181 s->nrows = 0;
06182 s->rows = NULL;
06183 s->rowfree = NULL;
06184 }
06185 if (errp) {
06186 sqlite3_free(errp);
06187 errp = NULL;
06188 }
06189 s->rowp = s->rowprs = -1;
06190 return SQL_SUCCESS;
06191 }
06192
06193
06194 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
06195
06207 SQLRETURN SQL_API
06208 SQLTablePrivileges(SQLHSTMT stmt,
06209 SQLCHAR *catalog, SQLSMALLINT catalogLen,
06210 SQLCHAR *schema, SQLSMALLINT schemaLen,
06211 SQLCHAR *table, SQLSMALLINT tableLen)
06212 {
06213 #if defined(_WIN32) || defined(_WIN64)
06214 char *c = NULL, *s = NULL, *t = NULL;
06215 #endif
06216 SQLRETURN ret;
06217
06218 HSTMT_LOCK(stmt);
06219 #if defined(_WIN32) || defined(_WIN64)
06220 if (!((STMT *) stmt)->oemcp[0]) {
06221 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
06222 table, tableLen);
06223 goto done2;
06224 }
06225 if (catalog) {
06226 c = wmb_to_utf_c((char *) catalog, catalogLen);
06227 if (!c) {
06228 ret = nomem((STMT *) stmt);
06229 goto done;
06230 }
06231 }
06232 if (schema) {
06233 s = wmb_to_utf_c((char *) schema, schemaLen);
06234 if (!s) {
06235 ret = nomem((STMT *) stmt);
06236 goto done;
06237 }
06238 }
06239 if (table) {
06240 t = wmb_to_utf_c((char *) table, tableLen);
06241 if (!t) {
06242 ret = nomem((STMT *) stmt);
06243 goto done;
06244 }
06245 }
06246 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
06247 (SQLCHAR *) s, SQL_NTS,
06248 (SQLCHAR *) t, SQL_NTS);
06249 #else
06250 ret = drvtableprivileges(stmt, catalog, catalogLen, schema, schemaLen,
06251 table, tableLen);
06252 #endif
06253 #if defined(_WIN32) || defined(_WIN64)
06254 done:
06255 uc_free(t);
06256 uc_free(s);
06257 uc_free(c);
06258 done2:
06259 ;
06260 #endif
06261 HSTMT_UNLOCK(stmt);
06262 return ret;
06263 }
06264 #endif
06265
06266 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
06267 #ifdef WINTERFACE
06268
06280 SQLRETURN SQL_API
06281 SQLTablePrivilegesW(SQLHSTMT stmt,
06282 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
06283 SQLWCHAR *schema, SQLSMALLINT schemaLen,
06284 SQLWCHAR *table, SQLSMALLINT tableLen)
06285 {
06286 char *c = NULL, *s = NULL, *t = NULL;
06287 SQLRETURN ret;
06288
06289 HSTMT_LOCK(stmt);
06290 if (catalog) {
06291 c = uc_to_utf_c(catalog, catalogLen);
06292 if (!c) {
06293 ret = nomem((STMT *) stmt);
06294 goto done;
06295 }
06296 }
06297 if (schema) {
06298 s = uc_to_utf_c(schema, schemaLen);
06299 if (!s) {
06300 ret = nomem((STMT *) stmt);
06301 goto done;
06302 }
06303 }
06304 if (table) {
06305 t = uc_to_utf_c(table, tableLen);
06306 if (!t) {
06307 ret = nomem((STMT *) stmt);
06308 goto done;
06309 }
06310 }
06311 ret = drvtableprivileges(stmt, (SQLCHAR *) c, SQL_NTS,
06312 (SQLCHAR *) s, SQL_NTS,
06313 (SQLCHAR *) t, SQL_NTS);
06314 done:
06315 uc_free(t);
06316 uc_free(s);
06317 uc_free(c);
06318 HSTMT_UNLOCK(stmt);
06319 return ret;
06320 }
06321 #endif
06322 #endif
06323
06328 static COL colPrivSpec2[] = {
06329 { "SYSTEM", "COLPRIV", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
06330 { "SYSTEM", "COLPRIV", "TABLE_OWNER", SCOL_VARCHAR, 50 },
06331 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
06332 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06333 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
06334 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
06335 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
06336 };
06337
06338 static COL colPrivSpec3[] = {
06339 { "SYSTEM", "COLPRIV", "TABLE_CAT", SCOL_VARCHAR, 50 },
06340 { "SYSTEM", "COLPRIV", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
06341 { "SYSTEM", "COLPRIV", "TABLE_NAME", SCOL_VARCHAR, 255 },
06342 { "SYSTEM", "COLPRIV", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06343 { "SYSTEM", "COLPRIV", "GRANTOR", SCOL_VARCHAR, 50 },
06344 { "SYSTEM", "COLPRIV", "GRANTEE", SCOL_VARCHAR, 50 },
06345 { "SYSTEM", "COLPRIV", "PRIVILEGE", SCOL_VARCHAR, 50 }
06346 };
06347
06348 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
06349
06363 SQLRETURN SQL_API
06364 SQLColumnPrivileges(SQLHSTMT stmt,
06365 SQLCHAR *catalog, SQLSMALLINT catalogLen,
06366 SQLCHAR *schema, SQLSMALLINT schemaLen,
06367 SQLCHAR *table, SQLSMALLINT tableLen,
06368 SQLCHAR *column, SQLSMALLINT columnLen)
06369 {
06370 SQLRETURN ret;
06371
06372 HSTMT_LOCK(stmt);
06373 ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
06374 colPrivSpec3, array_size(colPrivSpec3), NULL);
06375 HSTMT_UNLOCK(stmt);
06376 return ret;
06377 }
06378 #endif
06379
06380 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
06381 #ifdef WINTERFACE
06382
06396 SQLRETURN SQL_API
06397 SQLColumnPrivilegesW(SQLHSTMT stmt,
06398 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
06399 SQLWCHAR *schema, SQLSMALLINT schemaLen,
06400 SQLWCHAR *table, SQLSMALLINT tableLen,
06401 SQLWCHAR *column, SQLSMALLINT columnLen)
06402 {
06403 SQLRETURN ret;
06404
06405 HSTMT_LOCK(stmt);
06406 ret = mkresultset(stmt, colPrivSpec2, array_size(colPrivSpec2),
06407 colPrivSpec3, array_size(colPrivSpec3), NULL);
06408 HSTMT_UNLOCK(stmt);
06409 return ret;
06410 }
06411 #endif
06412 #endif
06413
06418 static COL pkeySpec2[] = {
06419 { "SYSTEM", "PRIMARYKEY", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
06420 { "SYSTEM", "PRIMARYKEY", "TABLE_OWNER", SCOL_VARCHAR, 50 },
06421 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
06422 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06423 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
06424 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
06425 };
06426
06427 static COL pkeySpec3[] = {
06428 { "SYSTEM", "PRIMARYKEY", "TABLE_CAT", SCOL_VARCHAR, 50 },
06429 { "SYSTEM", "PRIMARYKEY", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
06430 { "SYSTEM", "PRIMARYKEY", "TABLE_NAME", SCOL_VARCHAR, 255 },
06431 { "SYSTEM", "PRIMARYKEY", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06432 { "SYSTEM", "PRIMARYKEY", "KEY_SEQ", SQL_SMALLINT, 50 },
06433 { "SYSTEM", "PRIMARYKEY", "PK_NAME", SCOL_VARCHAR, 50 }
06434 };
06435
06448 static SQLRETURN
06449 drvprimarykeys(SQLHSTMT stmt,
06450 SQLCHAR *cat, SQLSMALLINT catLen,
06451 SQLCHAR *schema, SQLSMALLINT schemaLen,
06452 SQLCHAR *table, SQLSMALLINT tableLen)
06453 {
06454 STMT *s;
06455 DBC *d;
06456 SQLRETURN sret;
06457 int i, asize, ret, nrows, ncols, nrows2 = 0, ncols2 = 0;
06458 int namec = -1, uniquec = -1, namec2 = -1, uniquec2 = -1, offs, seq = 1;
06459 PTRDIFF_T size;
06460 char **rowp = NULL, **rowp2 = NULL, *errp = NULL, *sql, tname[512];
06461
06462 sret = mkresultset(stmt, pkeySpec2, array_size(pkeySpec2),
06463 pkeySpec3, array_size(pkeySpec3), &asize);
06464 if (sret != SQL_SUCCESS) {
06465 return sret;
06466 }
06467 s = (STMT *) stmt;
06468 d = (DBC *) s->dbc;
06469 if (!table || table[0] == '\0' || table[0] == '%') {
06470 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
06471 return SQL_ERROR;
06472 }
06473 if (tableLen == SQL_NTS) {
06474 size = sizeof (tname) - 1;
06475 } else {
06476 size = min(sizeof (tname) - 1, tableLen);
06477 }
06478 strncpy(tname, (char *) table, size);
06479 tname[size] = '\0';
06480 unescpat(tname);
06481 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
06482 if (!sql) {
06483 return nomem(s);
06484 }
06485 sret = starttran(s);
06486 if (sret != SQL_SUCCESS) {
06487 sqlite3_free(sql);
06488 return sret;
06489 }
06490 dbtraceapi(d, "sqlite3_get_table", sql);
06491 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
06492 sqlite3_free(sql);
06493 if (ret != SQLITE_OK) {
06494 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
06495 errp ? errp : "unknown error", ret);
06496 if (errp) {
06497 sqlite3_free(errp);
06498 errp = NULL;
06499 }
06500 return SQL_ERROR;
06501 }
06502 if (errp) {
06503 sqlite3_free(errp);
06504 errp = NULL;
06505 }
06506 size = 0;
06507 if (ncols * nrows > 0) {
06508 int typec;
06509
06510 namec = findcol(rowp, ncols, "name");
06511 uniquec = findcol(rowp, ncols, "pk");
06512 typec = findcol(rowp, ncols, "type");
06513 if (namec >= 0 && uniquec >= 0 && typec >= 0) {
06514 for (i = 1; i <= nrows; i++) {
06515 if (*rowp[i * ncols + uniquec] != '0') {
06516 size++;
06517 }
06518 }
06519 }
06520 }
06521 if (size == 0) {
06522 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
06523 if (!sql) {
06524 sqlite3_free_table(rowp);
06525 return nomem(s);
06526 }
06527 dbtraceapi(d, "sqlite3_get_table", sql);
06528 ret = sqlite3_get_table(d->sqlite, sql, &rowp2, &nrows2, &ncols2,
06529 &errp);
06530 sqlite3_free(sql);
06531 if (ret != SQLITE_OK) {
06532 sqlite3_free_table(rowp);
06533 sqlite3_free_table(rowp2);
06534 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
06535 errp ? errp : "unknown error", ret);
06536 if (errp) {
06537 sqlite3_free(errp);
06538 errp = NULL;
06539 }
06540 return SQL_ERROR;
06541 }
06542 if (errp) {
06543 sqlite3_free(errp);
06544 errp = NULL;
06545 }
06546 }
06547 if (ncols2 * nrows2 > 0) {
06548 namec2 = findcol(rowp2, ncols2, "name");
06549 uniquec2 = findcol(rowp2, ncols2, "unique");
06550 if (namec2 >= 0 && uniquec2 >= 0) {
06551 for (i = 1; i <= nrows2; i++) {
06552 int nnrows, nncols, nlen = 0;
06553 char **rowpp;
06554
06555 if (rowp2[i * ncols2 + namec2]) {
06556 nlen = strlen(rowp2[i * ncols2 + namec2]);
06557 }
06558 if (nlen < 17 ||
06559 strncmp(rowp2[i * ncols2 + namec2],
06560 "sqlite_autoindex_", 17)) {
06561 continue;
06562 }
06563 if (*rowp2[i * ncols2 + uniquec2] != '0') {
06564 ret = SQLITE_ERROR;
06565 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06566 rowp2[i * ncols2 + namec2]);
06567 if (sql) {
06568 dbtraceapi(d, "sqlite3_get_table", sql);
06569 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06570 &nnrows, &nncols, NULL);
06571 sqlite3_free(sql);
06572 }
06573 if (ret == SQLITE_OK) {
06574 size += nnrows;
06575 sqlite3_free_table(rowpp);
06576 }
06577 }
06578 }
06579 }
06580 }
06581 if (size == 0) {
06582 sqlite3_free_table(rowp);
06583 sqlite3_free_table(rowp2);
06584 return SQL_SUCCESS;
06585 }
06586 s->nrows = size;
06587 size = (size + 1) * asize;
06588 s->rows = xmalloc((size + 1) * sizeof (char *));
06589 if (!s->rows) {
06590 s->nrows = 0;
06591 sqlite3_free_table(rowp);
06592 sqlite3_free_table(rowp2);
06593 return nomem(s);
06594 }
06595 s->rows[0] = (char *) size;
06596 s->rows += 1;
06597 memset(s->rows, 0, sizeof (char *) * size);
06598 s->rowfree = freerows;
06599 offs = s->ncols;
06600 if (rowp) {
06601 for (i = 1; i <= nrows; i++) {
06602 if (*rowp[i * ncols + uniquec] != '0') {
06603 char buf[32];
06604
06605 #if defined(_WIN32) || defined(_WIN64)
06606 s->rows[offs + 0] = xstrdup(d->xcelqrx ? "main" : "");
06607 s->rows[offs + 1] = xstrdup("");
06608 #else
06609 s->rows[offs + 0] = xstrdup("");
06610 s->rows[offs + 1] = xstrdup("");
06611 #endif
06612 s->rows[offs + 2] = xstrdup(tname);
06613 s->rows[offs + 3] = xstrdup(rowp[i * ncols + namec]);
06614 sprintf(buf, "%d", seq++);
06615 s->rows[offs + 4] = xstrdup(buf);
06616 offs += s->ncols;
06617 }
06618 }
06619 }
06620 if (rowp2) {
06621 for (i = 1; i <= nrows2; i++) {
06622 int nnrows, nncols, nlen = 0;
06623 char **rowpp;
06624
06625 if (rowp2[i * ncols2 + namec2]) {
06626 nlen = strlen(rowp2[i * ncols2 + namec2]);
06627 }
06628 if (nlen < 17 ||
06629 strncmp(rowp2[i * ncols2 + namec2], "sqlite_autoindex_", 17)) {
06630 continue;
06631 }
06632 if (*rowp2[i * ncols2 + uniquec2] != '0') {
06633 int k;
06634
06635 ret = SQLITE_ERROR;
06636 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06637 rowp2[i * ncols2 + namec2]);
06638 if (sql) {
06639 dbtraceapi(d, "sqlite3_get_table", sql);
06640 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06641 &nnrows, &nncols, NULL);
06642 sqlite3_free(sql);
06643 }
06644 if (ret != SQLITE_OK) {
06645 continue;
06646 }
06647 for (k = 0; nnrows && k < nncols; k++) {
06648 if (strcmp(rowpp[k], "name") == 0) {
06649 int m;
06650
06651 for (m = 1; m <= nnrows; m++) {
06652 int roffs = offs + (m - 1) * s->ncols;
06653
06654 #if defined(_WIN32) || defined(_WIN64)
06655 s->rows[roffs + 0] =
06656 xstrdup(d->xcelqrx ? "main" : "");
06657 s->rows[roffs + 1] = xstrdup("");
06658 #else
06659 s->rows[roffs + 0] = xstrdup("");
06660 s->rows[roffs + 1] = xstrdup("");
06661 #endif
06662 s->rows[roffs + 2] = xstrdup(tname);
06663 s->rows[roffs + 3] =
06664 xstrdup(rowpp[m * nncols + k]);
06665 s->rows[roffs + 5] =
06666 xstrdup(rowp2[i * ncols2 + namec2]);
06667 }
06668 } else if (strcmp(rowpp[k], "seqno") == 0) {
06669 int m;
06670
06671 for (m = 1; m <= nnrows; m++) {
06672 int roffs = offs + (m - 1) * s->ncols;
06673 int pos = m - 1;
06674 char buf[32];
06675
06676 sscanf(rowpp[m * nncols + k], "%d", &pos);
06677 sprintf(buf, "%d", pos + 1);
06678 s->rows[roffs + 4] = xstrdup(buf);
06679 }
06680 }
06681 }
06682 offs += nnrows * s->ncols;
06683 sqlite3_free_table(rowpp);
06684 }
06685 }
06686 }
06687 sqlite3_free_table(rowp);
06688 sqlite3_free_table(rowp2);
06689 return SQL_SUCCESS;
06690 }
06691
06692 #ifndef WINTERFACE
06693
06705 SQLRETURN SQL_API
06706 SQLPrimaryKeys(SQLHSTMT stmt,
06707 SQLCHAR *cat, SQLSMALLINT catLen,
06708 SQLCHAR *schema, SQLSMALLINT schemaLen,
06709 SQLCHAR *table, SQLSMALLINT tableLen)
06710 {
06711 #if defined(_WIN32) || defined(_WIN64)
06712 char *c = NULL, *s = NULL, *t = NULL;
06713 #endif
06714 SQLRETURN ret;
06715
06716 HSTMT_LOCK(stmt);
06717 #if defined(_WIN32) || defined(_WIN64)
06718 if (!((STMT *) stmt)->oemcp[0]) {
06719 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
06720 table, tableLen);
06721 goto done2;
06722 }
06723 if (cat) {
06724 c = wmb_to_utf_c((char *) cat, catLen);
06725 if (!c) {
06726 ret = nomem((STMT *) stmt);
06727 goto done;
06728 }
06729 }
06730 if (schema) {
06731 s = wmb_to_utf_c((char *) schema, schemaLen);
06732 if (!s) {
06733 ret = nomem((STMT *) stmt);
06734 goto done;
06735 }
06736 }
06737 if (table) {
06738 t = wmb_to_utf_c((char *) table, tableLen);
06739 if (!t) {
06740 ret = nomem((STMT *) stmt);
06741 goto done;
06742 }
06743 }
06744 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
06745 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
06746 #else
06747 ret = drvprimarykeys(stmt, cat, catLen, schema, schemaLen,
06748 table, tableLen);
06749 #endif
06750 #if defined(_WIN32) || defined(_WIN64)
06751 done:
06752 uc_free(t);
06753 uc_free(s);
06754 uc_free(c);
06755 done2:
06756 ;
06757 #endif
06758 HSTMT_UNLOCK(stmt);
06759 return ret;
06760 }
06761 #endif
06762
06763 #ifdef WINTERFACE
06764
06776 SQLRETURN SQL_API
06777 SQLPrimaryKeysW(SQLHSTMT stmt,
06778 SQLWCHAR *cat, SQLSMALLINT catLen,
06779 SQLWCHAR *schema, SQLSMALLINT schemaLen,
06780 SQLWCHAR *table, SQLSMALLINT tableLen)
06781 {
06782 char *c = NULL, *s = NULL, *t = NULL;
06783 SQLRETURN ret;
06784
06785 HSTMT_LOCK(stmt);
06786 if (cat) {
06787 c = uc_to_utf_c(cat, catLen);
06788 if (!c) {
06789 ret = nomem((STMT *) stmt);
06790 goto done;
06791 }
06792 }
06793 if (schema) {
06794 s = uc_to_utf_c(schema, schemaLen);
06795 if (!s) {
06796 ret = nomem((STMT *) stmt);
06797 goto done;
06798 }
06799 }
06800 if (table) {
06801 t = uc_to_utf_c(table, tableLen);
06802 if (!t) {
06803 ret = nomem((STMT *) stmt);
06804 goto done;
06805 }
06806 }
06807 ret = drvprimarykeys(stmt, (SQLCHAR *) c, SQL_NTS,
06808 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS);
06809 done:
06810 uc_free(t);
06811 uc_free(s);
06812 uc_free(c);
06813 HSTMT_UNLOCK(stmt);
06814 return ret;
06815 }
06816 #endif
06817
06822 static COL scolSpec2[] = {
06823 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
06824 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06825 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
06826 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
06827 { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
06828 { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
06829 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
06830 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
06831 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
06832 };
06833
06834 static COL scolSpec3[] = {
06835 { "SYSTEM", "COLUMN", "SCOPE", SQL_SMALLINT, 1 },
06836 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
06837 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
06838 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
06839 { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
06840 { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
06841 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_INTEGER, 50 },
06842 { "SYSTEM", "COLUMN", "PSEUDO_COLUMN", SQL_SMALLINT, 1 },
06843 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 1 }
06844 };
06845
06861 static SQLRETURN
06862 drvspecialcolumns(SQLHSTMT stmt, SQLUSMALLINT id,
06863 SQLCHAR *cat, SQLSMALLINT catLen,
06864 SQLCHAR *schema, SQLSMALLINT schemaLen,
06865 SQLCHAR *table, SQLSMALLINT tableLen,
06866 SQLUSMALLINT scope, SQLUSMALLINT nullable)
06867 {
06868 STMT *s;
06869 DBC *d;
06870 SQLRETURN sret;
06871 int i, asize, ret, nrows, ncols, nnnrows, nnncols, offs;
06872 PTRDIFF_T size;
06873 int namec = -1, uniquec = -1, namecc = -1, typecc = -1;
06874 int notnullcc = -1, mkrowid = 0;
06875 char *errp = NULL, *sql, tname[512];
06876 char **rowp = NULL, **rowppp = NULL;
06877
06878 sret = mkresultset(stmt, scolSpec2, array_size(scolSpec2),
06879 scolSpec3, array_size(scolSpec3), &asize);
06880 if (sret != SQL_SUCCESS) {
06881 return sret;
06882 }
06883 s = (STMT *) stmt;
06884 d = (DBC *) s->dbc;
06885 if (!table || table[0] == '\0' || table[0] == '%') {
06886 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
06887 return SQL_ERROR;
06888 }
06889 if (tableLen == SQL_NTS) {
06890 size = sizeof (tname) - 1;
06891 } else {
06892 size = min(sizeof (tname) - 1, tableLen);
06893 }
06894 strncpy(tname, (char *) table, size);
06895 tname[size] = '\0';
06896 unescpat(tname);
06897 if (id != SQL_BEST_ROWID) {
06898 return SQL_SUCCESS;
06899 }
06900 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
06901 if (!sql) {
06902 return nomem(s);
06903 }
06904 sret = starttran(s);
06905 if (sret != SQL_SUCCESS) {
06906 sqlite3_free(sql);
06907 return sret;
06908 }
06909 dbtraceapi(d, "sqlite3_get_table", sql);
06910 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
06911 sqlite3_free(sql);
06912 if (ret != SQLITE_OK) {
06913 doerr:
06914 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
06915 errp ? errp : "unknown error", ret);
06916 if (errp) {
06917 sqlite3_free(errp);
06918 errp = NULL;
06919 }
06920 return SQL_ERROR;
06921 }
06922 if (errp) {
06923 sqlite3_free(errp);
06924 errp = NULL;
06925 }
06926 size = 0;
06927 if (ncols * nrows <= 0) {
06928 goto nodata_but_rowid;
06929 }
06930 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
06931 if (!sql) {
06932 return nomem(s);
06933 }
06934 dbtraceapi(d, "sqlite3_get_table", sql);
06935 ret = sqlite3_get_table(d->sqlite, sql, &rowppp, &nnnrows, &nnncols,
06936 &errp);
06937 sqlite3_free(sql);
06938 if (ret != SQLITE_OK) {
06939 sqlite3_free_table(rowp);
06940 goto doerr;
06941 }
06942 if (errp) {
06943 sqlite3_free(errp);
06944 errp = NULL;
06945 }
06946 namec = findcol(rowp, ncols, "name");
06947 uniquec = findcol(rowp, ncols, "unique");
06948 if (namec < 0 || uniquec < 0) {
06949 goto nodata_but_rowid;
06950 }
06951 namecc = findcol(rowppp, nnncols, "name");
06952 typecc = findcol(rowppp, nnncols, "type");
06953 notnullcc = findcol(rowppp, nnncols, "notnull");
06954 for (i = 1; i <= nrows; i++) {
06955 int nnrows, nncols;
06956 char **rowpp = NULL;
06957
06958 if (*rowp[i * ncols + uniquec] != '0') {
06959 ret = SQLITE_ERROR;
06960 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
06961 rowp[i * ncols + namec]);
06962 if (sql) {
06963 dbtraceapi(d, "sqlite3_get_table", sql);
06964 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
06965 &nnrows, &nncols, NULL);
06966 sqlite3_free(sql);
06967 }
06968 if (ret == SQLITE_OK) {
06969 size += nnrows;
06970 sqlite3_free_table(rowpp);
06971 }
06972 }
06973 }
06974 nodata_but_rowid:
06975 if (size == 0) {
06976 size = 1;
06977 mkrowid = 1;
06978 }
06979 s->nrows = size;
06980 size = (size + 1) * asize;
06981 s->rows = xmalloc((size + 1) * sizeof (char *));
06982 if (!s->rows) {
06983 s->nrows = 0;
06984 sqlite3_free_table(rowp);
06985 sqlite3_free_table(rowppp);
06986 return nomem(s);
06987 }
06988 s->rows[0] = (char *) size;
06989 s->rows += 1;
06990 memset(s->rows, 0, sizeof (char *) * size);
06991 s->rowfree = freerows;
06992 if (mkrowid) {
06993 s->nrows = 0;
06994 goto mkrowid;
06995 }
06996 offs = 0;
06997 for (i = 1; i <= nrows; i++) {
06998 int nnrows, nncols;
06999 char **rowpp = NULL;
07000
07001 if (*rowp[i * ncols + uniquec] != '0') {
07002 int k;
07003
07004 ret = SQLITE_ERROR;
07005 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
07006 rowp[i * ncols + namec]);
07007 if (sql) {
07008 dbtraceapi(d, "sqlite3_get_table", sql);
07009 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
07010 &nnrows, &nncols, NULL);
07011 sqlite3_free(sql);
07012 }
07013 if (ret != SQLITE_OK) {
07014 continue;
07015 }
07016 for (k = 0; nnrows && k < nncols; k++) {
07017 if (strcmp(rowpp[k], "name") == 0) {
07018 int m;
07019
07020 for (m = 1; m <= nnrows; m++) {
07021 int roffs = (offs + m) * s->ncols;
07022
07023 s->rows[roffs + 0] =
07024 xstrdup(stringify(SQL_SCOPE_SESSION));
07025 s->rows[roffs + 1] = xstrdup(rowpp[m * nncols + k]);
07026 s->rows[roffs + 4] = xstrdup("0");
07027 s->rows[roffs + 7] =
07028 xstrdup(stringify(SQL_PC_NOT_PSEUDO));
07029 if (namecc >= 0 && typecc >= 0) {
07030 int ii;
07031
07032 for (ii = 1; ii <= nnnrows; ii++) {
07033 if (strcmp(rowppp[ii * nnncols + namecc],
07034 rowpp[m * nncols + k]) == 0) {
07035 char *typen = rowppp[ii * nnncols + typecc];
07036 int sqltype, mm, dd, isnullable = 0;
07037 char buf[32];
07038
07039 s->rows[roffs + 3] = xstrdup(typen);
07040 sqltype = mapsqltype(typen, NULL, *s->ov3,
07041 s->nowchar[0],
07042 s->dobigint);
07043 getmd(typen, sqltype, &mm, &dd);
07044 #ifdef SQL_LONGVARCHAR
07045 if (sqltype == SQL_VARCHAR && mm > 255) {
07046 sqltype = SQL_LONGVARCHAR;
07047 }
07048 #endif
07049 #ifdef WINTERFACE
07050 #ifdef SQL_WLONGVARCHAR
07051 if (sqltype == SQL_WVARCHAR && mm > 255) {
07052 sqltype = SQL_WLONGVARCHAR;
07053 }
07054 #endif
07055 #endif
07056 if (sqltype == SQL_VARBINARY && mm > 255) {
07057 sqltype = SQL_LONGVARBINARY;
07058 }
07059 sprintf(buf, "%d", sqltype);
07060 s->rows[roffs + 2] = xstrdup(buf);
07061 sprintf(buf, "%d", mm);
07062 s->rows[roffs + 5] = xstrdup(buf);
07063 sprintf(buf, "%d", dd);
07064 s->rows[roffs + 6] = xstrdup(buf);
07065 if (notnullcc >= 0) {
07066 char *inp =
07067 rowppp[ii * nnncols + notnullcc];
07068
07069 isnullable = inp[0] != '0';
07070 }
07071 sprintf(buf, "%d", isnullable);
07072 s->rows[roffs + 8] = xstrdup(buf);
07073 }
07074 }
07075 }
07076 }
07077 }
07078 }
07079 offs += nnrows;
07080 sqlite3_free_table(rowpp);
07081 }
07082 }
07083 if (nullable == SQL_NO_NULLS) {
07084 for (i = 1; i < s->nrows; i++) {
07085 if (s->rows[i * s->ncols + 8][0] == '0') {
07086 int m, i1 = i + 1;
07087
07088 for (m = 0; m < s->ncols; m++) {
07089 freep(&s->rows[i * s->ncols + m]);
07090 }
07091 size = s->ncols * sizeof (char *) * (s->nrows - i1);
07092 if (size > 0) {
07093 memmove(s->rows + i * s->ncols,
07094 s->rows + i1 * s->ncols,
07095 size);
07096 memset(s->rows + s->nrows * s->ncols, 0,
07097 s->ncols * sizeof (char *));
07098 }
07099 s->nrows--;
07100 --i;
07101 }
07102 }
07103 }
07104 mkrowid:
07105 sqlite3_free_table(rowp);
07106 sqlite3_free_table(rowppp);
07107 if (s->nrows == 0) {
07108 s->rows[s->ncols + 0] = xstrdup(stringify(SQL_SCOPE_SESSION));
07109 s->rows[s->ncols + 1] = xstrdup("_ROWID_");
07110 s->rows[s->ncols + 2] = xstrdup(stringify(SQL_INTEGER));
07111 s->rows[s->ncols + 3] = xstrdup("integer");
07112 s->rows[s->ncols + 4] = xstrdup("0");
07113 s->rows[s->ncols + 5] = xstrdup("10");
07114 s->rows[s->ncols + 6] = xstrdup("9");
07115 s->rows[s->ncols + 7] = xstrdup(stringify(SQL_PC_PSEUDO));
07116 s->rows[s->ncols + 8] = xstrdup(stringify(SQL_FALSE));
07117 s->nrows = 1;
07118 }
07119 return SQL_SUCCESS;
07120 }
07121
07122 #ifndef WINTERFACE
07123
07138 SQLRETURN SQL_API
07139 SQLSpecialColumns(SQLHSTMT stmt, SQLUSMALLINT id,
07140 SQLCHAR *cat, SQLSMALLINT catLen,
07141 SQLCHAR *schema, SQLSMALLINT schemaLen,
07142 SQLCHAR *table, SQLSMALLINT tableLen,
07143 SQLUSMALLINT scope, SQLUSMALLINT nullable)
07144 {
07145 #if defined(_WIN32) || defined(_WIN64)
07146 char *c = NULL, *s = NULL, *t = NULL;
07147 #endif
07148 SQLRETURN ret;
07149
07150 HSTMT_LOCK(stmt);
07151 #if defined(_WIN32) || defined(_WIN64)
07152 if (!((STMT *) stmt)->oemcp[0]) {
07153 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
07154 table, tableLen, scope, nullable);
07155 goto done2;
07156 }
07157 if (cat) {
07158 c = wmb_to_utf_c((char *) cat, catLen);
07159 if (!c) {
07160 ret = nomem((STMT *) stmt);
07161 goto done;
07162 }
07163 }
07164 if (schema) {
07165 s = wmb_to_utf_c((char *) schema, schemaLen);
07166 if (!s) {
07167 ret = nomem((STMT *) stmt);
07168 goto done;
07169 }
07170 }
07171 if (table) {
07172 t = wmb_to_utf_c((char *) table, tableLen);
07173 if (!t) {
07174 ret = nomem((STMT *) stmt);
07175 goto done;
07176 }
07177 }
07178 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
07179 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
07180 scope, nullable);
07181 #else
07182 ret = drvspecialcolumns(stmt, id, cat, catLen, schema, schemaLen,
07183 table, tableLen, scope, nullable);
07184 #endif
07185 #if defined(_WIN32) || defined(_WIN64)
07186 done:
07187 uc_free(t);
07188 uc_free(s);
07189 uc_free(c);
07190 done2:
07191 ;
07192 #endif
07193 HSTMT_UNLOCK(stmt);
07194 return ret;
07195 }
07196 #endif
07197
07198 #ifdef WINTERFACE
07199
07214 SQLRETURN SQL_API
07215 SQLSpecialColumnsW(SQLHSTMT stmt, SQLUSMALLINT id,
07216 SQLWCHAR *cat, SQLSMALLINT catLen,
07217 SQLWCHAR *schema, SQLSMALLINT schemaLen,
07218 SQLWCHAR *table, SQLSMALLINT tableLen,
07219 SQLUSMALLINT scope, SQLUSMALLINT nullable)
07220 {
07221 char *c = NULL, *s = NULL, *t = NULL;
07222 SQLRETURN ret;
07223
07224 HSTMT_LOCK(stmt);
07225 if (cat) {
07226 c = uc_to_utf_c(cat, catLen);
07227 if (!c) {
07228 ret = nomem((STMT *) stmt);
07229 goto done;
07230 }
07231 }
07232 if (schema) {
07233 s = uc_to_utf_c(schema, schemaLen);
07234 if (!s) {
07235 ret = nomem((STMT *) stmt);
07236 goto done;
07237 }
07238 }
07239 if (table) {
07240 t = uc_to_utf_c(table, tableLen);
07241 if (!t) {
07242 ret = nomem((STMT *) stmt);
07243 goto done;
07244 }
07245 }
07246 ret = drvspecialcolumns(stmt, id, (SQLCHAR *) c, SQL_NTS,
07247 (SQLCHAR *) s, SQL_NTS, (SQLCHAR *) t, SQL_NTS,
07248 scope, nullable);
07249 done:
07250 uc_free(t);
07251 uc_free(s);
07252 uc_free(c);
07253 HSTMT_UNLOCK(stmt);
07254 return ret;
07255 }
07256 #endif
07257
07262 static COL fkeySpec2[] = {
07263 { "SYSTEM", "FOREIGNKEY", "PKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
07264 { "SYSTEM", "FOREIGNKEY", "PKTABLE_OWNER", SCOL_VARCHAR, 50 },
07265 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
07266 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
07267 { "SYSTEM", "FOREIGNKEY", "FKTABLE_QUALIFIER", SCOL_VARCHAR, 50 },
07268 { "SYSTEM", "FOREIGNKEY", "FKTABLE_OWNER", SCOL_VARCHAR, 50 },
07269 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
07270 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
07271 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
07272 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
07273 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
07274 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
07275 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
07276 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
07277 };
07278
07279 static COL fkeySpec3[] = {
07280 { "SYSTEM", "FOREIGNKEY", "PKTABLE_CAT", SCOL_VARCHAR, 50 },
07281 { "SYSTEM", "FOREIGNKEY", "PKTABLE_SCHEM", SCOL_VARCHAR, 50 },
07282 { "SYSTEM", "FOREIGNKEY", "PKTABLE_NAME", SCOL_VARCHAR, 255 },
07283 { "SYSTEM", "FOREIGNKEY", "PKCOLUMN_NAME", SCOL_VARCHAR, 255 },
07284 { "SYSTEM", "FOREIGNKEY", "FKTABLE_CAT", SCOL_VARCHAR, 50 },
07285 { "SYSTEM", "FOREIGNKEY", "FKTABLE_SCHEM", SCOL_VARCHAR, 50 },
07286 { "SYSTEM", "FOREIGNKEY", "FKTABLE_NAME", SCOL_VARCHAR, 255 },
07287 { "SYSTEM", "FOREIGNKEY", "FKCOLUMN_NAME", SCOL_VARCHAR, 255 },
07288 { "SYSTEM", "FOREIGNKEY", "KEY_SEQ", SQL_SMALLINT, 5 },
07289 { "SYSTEM", "FOREIGNKEY", "UPDATE_RULE", SQL_SMALLINT, 5 },
07290 { "SYSTEM", "FOREIGNKEY", "DELETE_RULE", SQL_SMALLINT, 5 },
07291 { "SYSTEM", "FOREIGNKEY", "FK_NAME", SCOL_VARCHAR, 255 },
07292 { "SYSTEM", "FOREIGNKEY", "PK_NAME", SCOL_VARCHAR, 255 },
07293 { "SYSTEM", "FOREIGNKEY", "DEFERRABILITY", SQL_SMALLINT, 5 }
07294 };
07295
07314 static SQLRETURN SQL_API
07315 drvforeignkeys(SQLHSTMT stmt,
07316 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
07317 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
07318 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
07319 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
07320 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
07321 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
07322 {
07323 STMT *s;
07324 DBC *d;
07325 SQLRETURN sret;
07326 int i, asize, ret, nrows, ncols, offs, namec, seqc, fromc, toc;
07327 int onu, ond;
07328 PTRDIFF_T size;
07329 char **rowp, *errp = NULL, *sql, pname[512], fname[512];
07330
07331 sret = mkresultset(stmt, fkeySpec2, array_size(fkeySpec2),
07332 fkeySpec3, array_size(fkeySpec3), &asize);
07333 if (sret != SQL_SUCCESS) {
07334 return sret;
07335 }
07336 s = (STMT *) stmt;
07337 sret = starttran(s);
07338 if (sret != SQL_SUCCESS) {
07339 return sret;
07340 }
07341 d = (DBC *) s->dbc;
07342 if ((!PKtable || PKtable[0] == '\0' || PKtable[0] == '%') &&
07343 (!FKtable || FKtable[0] == '\0' || FKtable[0] == '%')) {
07344 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
07345 return SQL_ERROR;
07346 }
07347 size = 0;
07348 if (PKtable) {
07349 if (PKtableLen == SQL_NTS) {
07350 size = sizeof (pname) - 1;
07351 } else {
07352 size = min(sizeof (pname) - 1, PKtableLen);
07353 }
07354 strncpy(pname, (char *) PKtable, size);
07355 }
07356 pname[size] = '\0';
07357 size = 0;
07358 if (FKtable) {
07359
07360 if (FKtableLen == SQL_NTS) {
07361 size = sizeof (fname) - 1;
07362 } else {
07363 size = min(sizeof (fname) - 1, FKtableLen);
07364 }
07365 strncpy(fname, (char *) FKtable, size);
07366 }
07367 fname[size] = '\0';
07368 if (fname[0] != '\0') {
07369 int plen;
07370
07371 ret = SQLITE_ERROR;
07372 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", fname);
07373 if (sql) {
07374 dbtraceapi(d, "sqlite3_get_table", sql);
07375 ret = sqlite3_get_table(d->sqlite, sql, &rowp,
07376 &nrows, &ncols, &errp);
07377 sqlite3_free(sql);
07378 }
07379 if (ret != SQLITE_OK) {
07380 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
07381 errp ? errp : "unknown error", ret);
07382 if (errp) {
07383 sqlite3_free(errp);
07384 errp = NULL;
07385 }
07386 return SQL_ERROR;
07387 }
07388 if (errp) {
07389 sqlite3_free(errp);
07390 errp = NULL;
07391 }
07392 if (ncols * nrows <= 0) {
07393 nodata:
07394 sqlite3_free_table(rowp);
07395 return SQL_SUCCESS;
07396 }
07397 size = 0;
07398 namec = findcol(rowp, ncols, "table");
07399 seqc = findcol(rowp, ncols, "seq");
07400 fromc = findcol(rowp, ncols, "from");
07401 toc = findcol(rowp, ncols, "to");
07402 onu = findcol(rowp, ncols, "on_update");
07403 ond = findcol(rowp, ncols, "on_delete");
07404 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
07405 goto nodata;
07406 }
07407 plen = strlen(pname);
07408 for (i = 1; i <= nrows; i++) {
07409 char *ptab = unquote(rowp[i * ncols + namec]);
07410
07411 if (plen && ptab) {
07412 int len = strlen(ptab);
07413
07414 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
07415 continue;
07416 }
07417 }
07418 size++;
07419 }
07420 if (size == 0) {
07421 goto nodata;
07422 }
07423 s->nrows = size;
07424 size = (size + 1) * asize;
07425 s->rows = xmalloc((size + 1) * sizeof (char *));
07426 if (!s->rows) {
07427 s->nrows = 0;
07428 return nomem(s);
07429 }
07430 s->rows[0] = (char *) size;
07431 s->rows += 1;
07432 memset(s->rows, 0, sizeof (char *) * size);
07433 s->rowfree = freerows;
07434 offs = 0;
07435 for (i = 1; i <= nrows; i++) {
07436 int pos = 0, roffs = (offs + 1) * s->ncols;
07437 char *ptab = rowp[i * ncols + namec];
07438 char buf[32];
07439
07440 if (plen && ptab) {
07441 int len = strlen(ptab);
07442
07443 if (plen != len || strncasecmp(pname, ptab, plen) != 0) {
07444 continue;
07445 }
07446 }
07447 #if defined(_WIN32) || defined(_WIN64)
07448 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
07449 s->rows[roffs + 1] = xstrdup("");
07450 #else
07451 s->rows[roffs + 0] = xstrdup("");
07452 s->rows[roffs + 1] = xstrdup("");
07453 #endif
07454 s->rows[roffs + 2] = xstrdup(ptab);
07455 s->rows[roffs + 3] = xstrdup(rowp[i * ncols + toc]);
07456 s->rows[roffs + 4] = xstrdup("");
07457 s->rows[roffs + 5] = xstrdup("");
07458 s->rows[roffs + 6] = xstrdup(fname);
07459 s->rows[roffs + 7] = xstrdup(rowp[i * ncols + fromc]);
07460 sscanf(rowp[i * ncols + seqc], "%d", &pos);
07461 sprintf(buf, "%d", pos + 1);
07462 s->rows[roffs + 8] = xstrdup(buf);
07463 if (onu < 0) {
07464 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
07465 } else {
07466 if (strcmp(rowp[i * ncols + onu], "SET NULL") == 0) {
07467 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
07468 } else if (strcmp(rowp[i * ncols + onu], "SET DEFAULT") == 0) {
07469 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_DEFAULT));
07470 } else if (strcmp(rowp[i * ncols + onu], "CASCADE") == 0) {
07471 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
07472 } else if (strcmp(rowp[i * ncols + onu], "RESTRICT") == 0) {
07473 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
07474 } else {
07475 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
07476 }
07477 }
07478 if (ond < 0) {
07479 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
07480 } else {
07481 if (strcmp(rowp[i * ncols + ond], "SET NULL") == 0) {
07482 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
07483 } else if (strcmp(rowp[i * ncols + ond], "SET DEFAULT") == 0) {
07484 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_DEFAULT));
07485 } else if (strcmp(rowp[i * ncols + ond], "CASCADE") == 0) {
07486 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
07487 } else if (strcmp(rowp[i * ncols + ond], "RESTRICT") == 0) {
07488 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
07489 } else {
07490 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
07491 }
07492 }
07493 s->rows[roffs + 11] = NULL;
07494 s->rows[roffs + 12] = NULL;
07495 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
07496 offs++;
07497 }
07498 sqlite3_free_table(rowp);
07499 } else {
07500 int nnrows, nncols, plen = strlen(pname);
07501 char **rowpp;
07502
07503 sql = "select name from sqlite_master where type='table'";
07504 dbtraceapi(d, "sqlite3_get_table", sql);
07505 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
07506 if (ret != SQLITE_OK) {
07507 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
07508 errp ? errp : "unknown error", ret);
07509 if (errp) {
07510 sqlite3_free(errp);
07511 errp = NULL;
07512 }
07513 return SQL_ERROR;
07514 }
07515 if (errp) {
07516 sqlite3_free(errp);
07517 errp = NULL;
07518 }
07519 if (ncols * nrows <= 0) {
07520 goto nodata;
07521 }
07522 size = 0;
07523 for (i = 1; i <= nrows; i++) {
07524 int k;
07525
07526 if (!rowp[i]) {
07527 continue;
07528 }
07529 rowpp = NULL;
07530 ret = SQLITE_ERROR;
07531 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
07532 if (sql) {
07533 dbtraceapi(d, "sqlite3_get_table", sql);
07534 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
07535 &nnrows, &nncols, NULL);
07536 sqlite3_free(sql);
07537 }
07538 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
07539 sqlite3_free_table(rowpp);
07540 continue;
07541 }
07542 namec = findcol(rowpp, nncols, "table");
07543 seqc = findcol(rowpp, nncols, "seq");
07544 fromc = findcol(rowpp, nncols, "from");
07545 toc = findcol(rowpp, nncols, "to");
07546 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
07547 sqlite3_free_table(rowpp);
07548 continue;
07549 }
07550 for (k = 1; k <= nnrows; k++) {
07551 char *ptab = unquote(rowpp[k * nncols + namec]);
07552
07553 if (plen && ptab) {
07554 int len = strlen(ptab);
07555
07556 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
07557 continue;
07558 }
07559 }
07560 size++;
07561 }
07562 sqlite3_free_table(rowpp);
07563 }
07564 if (size == 0) {
07565 goto nodata;
07566 }
07567 s->nrows = size;
07568 size = (size + 1) * asize;
07569 s->rows = xmalloc((size + 1) * sizeof (char *));
07570 if (!s->rows) {
07571 s->nrows = 0;
07572 return nomem(s);
07573 }
07574 s->rows[0] = (char *) size;
07575 s->rows += 1;
07576 memset(s->rows, 0, sizeof (char *) * size);
07577 s->rowfree = freerows;
07578 offs = 0;
07579 for (i = 1; i <= nrows; i++) {
07580 int k;
07581
07582 if (!rowp[i]) {
07583 continue;
07584 }
07585 rowpp = NULL;
07586 ret = SQLITE_ERROR;
07587 sql = sqlite3_mprintf("PRAGMA foreign_key_list(%Q)", rowp[i]);
07588 if (sql) {
07589 dbtraceapi(d, "sqlite3_get_table", sql);
07590 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
07591 &nnrows, &nncols, NULL);
07592 sqlite3_free(sql);
07593 }
07594 if (ret != SQLITE_OK || nncols * nnrows <= 0) {
07595 sqlite3_free_table(rowpp);
07596 continue;
07597 }
07598 namec = findcol(rowpp, nncols, "table");
07599 seqc = findcol(rowpp, nncols, "seq");
07600 fromc = findcol(rowpp, nncols, "from");
07601 toc = findcol(rowpp, nncols, "to");
07602 onu = findcol(rowpp, nncols, "on_update");
07603 ond = findcol(rowpp, nncols, "on_delete");
07604 if (namec < 0 || seqc < 0 || fromc < 0 || toc < 0) {
07605 sqlite3_free_table(rowpp);
07606 continue;
07607 }
07608 for (k = 1; k <= nnrows; k++) {
07609 int pos = 0, roffs = (offs + 1) * s->ncols;
07610 char *ptab = unquote(rowpp[k * nncols + namec]);
07611 char buf[32];
07612
07613 if (plen && ptab) {
07614 int len = strlen(ptab);
07615
07616 if (len != plen || strncasecmp(pname, ptab, plen) != 0) {
07617 continue;
07618 }
07619 }
07620 #if defined(_WIN32) || defined(_WIN64)
07621 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
07622 s->rows[roffs + 1] = xstrdup("");
07623 #else
07624 s->rows[roffs + 0] = xstrdup("");
07625 s->rows[roffs + 1] = xstrdup("");
07626 #endif
07627 s->rows[roffs + 2] = xstrdup(ptab);
07628 s->rows[roffs + 3] = xstrdup(rowpp[k * nncols + toc]);
07629 s->rows[roffs + 4] = xstrdup("");
07630 s->rows[roffs + 5] = xstrdup("");
07631 s->rows[roffs + 6] = xstrdup(rowp[i]);
07632 s->rows[roffs + 7] = xstrdup(rowpp[k * nncols + fromc]);
07633 sscanf(rowpp[k * nncols + seqc], "%d", &pos);
07634 sprintf(buf, "%d", pos + 1);
07635 s->rows[roffs + 8] = xstrdup(buf);
07636 if (onu < 0) {
07637 s->rows[roffs + 9] = xstrdup(stringify(SQL_NO_ACTION));
07638 } else {
07639 if (strcmp(rowpp[k * nncols + onu], "SET NULL") == 0) {
07640 s->rows[roffs + 9] = xstrdup(stringify(SQL_SET_NULL));
07641 } else if (strcmp(rowpp[k * nncols + onu], "SET DEFAULT")
07642 == 0) {
07643 s->rows[roffs + 9] =
07644 xstrdup(stringify(SQL_SET_DEFAULT));
07645 } else if (strcmp(rowpp[k * nncols + onu], "CASCADE")
07646 == 0) {
07647 s->rows[roffs + 9] = xstrdup(stringify(SQL_CASCADE));
07648 } else if (strcmp(rowpp[k * nncols + onu], "RESTRICT")
07649 == 0) {
07650 s->rows[roffs + 9] = xstrdup(stringify(SQL_RESTRICT));
07651 } else {
07652 s->rows[roffs + 9] =
07653 xstrdup(stringify(SQL_NO_ACTION));
07654 }
07655 }
07656 if (ond < 0) {
07657 s->rows[roffs + 10] = xstrdup(stringify(SQL_NO_ACTION));
07658 } else {
07659 if (strcmp(rowpp[k * nncols + ond], "SET NULL") == 0) {
07660 s->rows[roffs + 10] = xstrdup(stringify(SQL_SET_NULL));
07661 } else if (strcmp(rowpp[k * nncols + ond], "SET DEFAULT")
07662 == 0) {
07663 s->rows[roffs + 10] =
07664 xstrdup(stringify(SQL_SET_DEFAULT));
07665 } else if (strcmp(rowpp[k * nncols + ond], "CASCADE")
07666 == 0) {
07667 s->rows[roffs + 10] = xstrdup(stringify(SQL_CASCADE));
07668 } else if (strcmp(rowpp[k * nncols + ond], "RESTRICT")
07669 == 0) {
07670 s->rows[roffs + 10] = xstrdup(stringify(SQL_RESTRICT));
07671 } else {
07672 s->rows[roffs + 10] =
07673 xstrdup(stringify(SQL_NO_ACTION));
07674 }
07675 }
07676 s->rows[roffs + 11] = NULL;
07677 s->rows[roffs + 12] = NULL;
07678 s->rows[roffs + 13] = xstrdup(stringify(SQL_NOT_DEFERRABLE));
07679 offs++;
07680 }
07681 sqlite3_free_table(rowpp);
07682 }
07683 sqlite3_free_table(rowp);
07684 }
07685 return SQL_SUCCESS;
07686 }
07687
07688 #ifndef WINTERFACE
07689
07707 SQLRETURN SQL_API
07708 SQLForeignKeys(SQLHSTMT stmt,
07709 SQLCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
07710 SQLCHAR *PKschema, SQLSMALLINT PKschemaLen,
07711 SQLCHAR *PKtable, SQLSMALLINT PKtableLen,
07712 SQLCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
07713 SQLCHAR *FKschema, SQLSMALLINT FKschemaLen,
07714 SQLCHAR *FKtable, SQLSMALLINT FKtableLen)
07715 {
07716 #if defined(_WIN32) || defined(_WIN64)
07717 char *pc = NULL, *ps = NULL, *pt = NULL;
07718 char *fc = NULL, *fs = NULL, *ft = NULL;
07719 #endif
07720 SQLRETURN ret;
07721
07722 HSTMT_LOCK(stmt);
07723 #if defined(_WIN32) || defined(_WIN64)
07724 if (!((STMT *) stmt)->oemcp[0]) {
07725 ret = drvforeignkeys(stmt,
07726 PKcatalog, PKcatalogLen,
07727 PKschema, PKschemaLen, PKtable, PKtableLen,
07728 FKcatalog, FKcatalogLen,
07729 FKschema, FKschemaLen,
07730 FKtable, FKtableLen);
07731 goto done2;
07732 }
07733 if (PKcatalog) {
07734 pc = wmb_to_utf_c((char *) PKcatalog, PKcatalogLen);
07735 if (!pc) {
07736 ret = nomem((STMT *) stmt);
07737 goto done;
07738 }
07739 }
07740 if (PKschema) {
07741 ps = wmb_to_utf_c((char *) PKschema, PKschemaLen);
07742 if (!ps) {
07743 ret = nomem((STMT *) stmt);
07744 goto done;
07745 }
07746 }
07747 if (PKtable) {
07748 pt = wmb_to_utf_c((char *) PKtable, PKtableLen);
07749 if (!pt) {
07750 ret = nomem((STMT *) stmt);
07751 goto done;
07752 }
07753 }
07754 if (FKcatalog) {
07755 fc = wmb_to_utf_c((char *) FKcatalog, FKcatalogLen);
07756 if (!fc) {
07757 ret = nomem((STMT *) stmt);
07758 goto done;
07759 }
07760 }
07761 if (FKschema) {
07762 fs = wmb_to_utf_c((char *) FKschema, FKschemaLen);
07763 if (!fs) {
07764 ret = nomem((STMT *) stmt);
07765 goto done;
07766 }
07767 }
07768 if (FKtable) {
07769 ft = wmb_to_utf_c((char *) FKtable, FKtableLen);
07770 if (!ft) {
07771 ret = nomem((STMT *) stmt);
07772 goto done;
07773 }
07774 }
07775 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
07776 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
07777 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
07778 (SQLCHAR *) ft, SQL_NTS);
07779 #else
07780 ret = drvforeignkeys(stmt,
07781 PKcatalog, PKcatalogLen,
07782 PKschema, PKschemaLen, PKtable, PKtableLen,
07783 FKcatalog, FKcatalogLen,
07784 FKschema, FKschemaLen,
07785 FKtable, FKtableLen);
07786 #endif
07787 #if defined(_WIN32) || defined(_WIN64)
07788 done:
07789 uc_free(ft);
07790 uc_free(fs);
07791 uc_free(fc);
07792 uc_free(pt);
07793 uc_free(ps);
07794 uc_free(pc);
07795 done2:
07796 ;
07797 #endif
07798 HSTMT_UNLOCK(stmt);
07799 return ret;
07800 }
07801 #endif
07802
07803 #ifdef WINTERFACE
07804
07822 SQLRETURN SQL_API
07823 SQLForeignKeysW(SQLHSTMT stmt,
07824 SQLWCHAR *PKcatalog, SQLSMALLINT PKcatalogLen,
07825 SQLWCHAR *PKschema, SQLSMALLINT PKschemaLen,
07826 SQLWCHAR *PKtable, SQLSMALLINT PKtableLen,
07827 SQLWCHAR *FKcatalog, SQLSMALLINT FKcatalogLen,
07828 SQLWCHAR *FKschema, SQLSMALLINT FKschemaLen,
07829 SQLWCHAR *FKtable, SQLSMALLINT FKtableLen)
07830 {
07831 char *pc = NULL, *ps = NULL, *pt = NULL;
07832 char *fc = NULL, *fs = NULL, *ft = NULL;
07833 SQLRETURN ret;
07834
07835 HSTMT_LOCK(stmt);
07836 if (PKcatalog) {
07837 pc = uc_to_utf_c(PKcatalog, PKcatalogLen);
07838 if (!pc) {
07839 ret = nomem((STMT *) stmt);
07840 goto done;
07841 }
07842 }
07843 if (PKschema) {
07844 ps = uc_to_utf_c(PKschema, PKschemaLen);
07845 if (!ps) {
07846 ret = nomem((STMT *) stmt);
07847 goto done;
07848 }
07849 }
07850 if (PKtable) {
07851 pt = uc_to_utf_c(PKtable, PKtableLen);
07852 if (!pt) {
07853 ret = nomem((STMT *) stmt);
07854 goto done;
07855 }
07856 }
07857 if (FKcatalog) {
07858 fc = uc_to_utf_c(FKcatalog, FKcatalogLen);
07859 if (!fc) {
07860 ret = nomem((STMT *) stmt);
07861 goto done;
07862 }
07863 }
07864 if (FKschema) {
07865 fs = uc_to_utf_c(FKschema, FKschemaLen);
07866 if (!fs) {
07867 ret = nomem((STMT *) stmt);
07868 goto done;
07869 }
07870 }
07871 if (FKtable) {
07872 ft = uc_to_utf_c(FKtable, FKtableLen);
07873 if (!ft) {
07874 ret = nomem((STMT *) stmt);
07875 goto done;
07876 }
07877 }
07878 ret = drvforeignkeys(stmt, (SQLCHAR *) pc, SQL_NTS,
07879 (SQLCHAR *) ps, SQL_NTS, (SQLCHAR *) pt, SQL_NTS,
07880 (SQLCHAR *) fc, SQL_NTS, (SQLCHAR *) fs, SQL_NTS,
07881 (SQLCHAR *) ft, SQL_NTS);
07882 done:
07883 uc_free(ft);
07884 uc_free(fs);
07885 uc_free(fc);
07886 uc_free(pt);
07887 uc_free(ps);
07888 uc_free(pc);
07889 HSTMT_UNLOCK(stmt);
07890 return ret;
07891 }
07892 #endif
07893
07900 static SQLRETURN
07901 starttran(STMT *s)
07902 {
07903 int ret = SQL_SUCCESS, rc, busy_count = 0;
07904 char *errp = NULL;
07905 DBC *d = (DBC *) s->dbc;
07906
07907 if (!d->autocommit && !d->intrans && !d->trans_disable) {
07908 begin_again:
07909 rc = sqlite3_exec(d->sqlite, "BEGIN TRANSACTION", NULL, NULL, &errp);
07910 if (rc == SQLITE_BUSY) {
07911 if (busy_handler((void *) d, ++busy_count)) {
07912 if (errp) {
07913 sqlite3_free(errp);
07914 errp = NULL;
07915 }
07916 goto begin_again;
07917 }
07918 }
07919 dbtracerc(d, rc, errp);
07920 if (rc != SQLITE_OK) {
07921 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
07922 errp ? errp : "unknown error", rc);
07923 ret = SQL_ERROR;
07924 } else {
07925 d->intrans = 1;
07926 }
07927 if (errp) {
07928 sqlite3_free(errp);
07929 errp = NULL;
07930 }
07931 }
07932 return ret;
07933 }
07934
07943 static SQLRETURN
07944 endtran(DBC *d, SQLSMALLINT comptype, int force)
07945 {
07946 int ret, busy_count = 0;
07947 char *sql, *errp = NULL;
07948
07949 if (!d->sqlite) {
07950 setstatd(d, -1, "not connected", (*d->ov3) ? "HY000" : "S1000");
07951 return SQL_ERROR;
07952 }
07953 if ((!force && d->autocommit) || !d->intrans) {
07954 return SQL_SUCCESS;
07955 }
07956 switch (comptype) {
07957 case SQL_COMMIT:
07958 sql = "COMMIT TRANSACTION";
07959 goto doit;
07960 case SQL_ROLLBACK:
07961 sql = "ROLLBACK TRANSACTION";
07962 doit:
07963 ret = sqlite3_exec(d->sqlite, sql, NULL, NULL, &errp);
07964 dbtracerc(d, ret, errp);
07965 if (ret == SQLITE_BUSY && busy_count < 10) {
07966 if (busy_handler((void *) d, ++busy_count)) {
07967 if (errp) {
07968 sqlite3_free(errp);
07969 errp = NULL;
07970 }
07971 goto doit;
07972 }
07973 }
07974 if (ret != SQLITE_OK) {
07975 setstatd(d, ret, "%s", (*d->ov3) ? "HY000" : "S1000",
07976 errp ? errp : "transaction failed");
07977 if (errp) {
07978 sqlite3_free(errp);
07979 errp = NULL;
07980 }
07981 return SQL_ERROR;
07982 }
07983 if (errp) {
07984 sqlite3_free(errp);
07985 errp = NULL;
07986 }
07987 d->intrans = 0;
07988 return SQL_SUCCESS;
07989 }
07990 setstatd(d, -1, "invalid completion type", (*d->ov3) ? "HY000" : "S1000");
07991 return SQL_ERROR;
07992 }
07993
08002 static SQLRETURN
08003 drvendtran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
08004 {
08005 DBC *dbc = NULL;
08006 int fail = 0;
08007 SQLRETURN ret;
08008 #if defined(_WIN32) || defined(_WIN64)
08009 ENV *env;
08010 #endif
08011
08012 switch (type) {
08013 case SQL_HANDLE_DBC:
08014 HDBC_LOCK((SQLHDBC) handle);
08015 if (handle == SQL_NULL_HDBC) {
08016 return SQL_INVALID_HANDLE;
08017 }
08018 dbc = (DBC *) handle;
08019 ret = endtran(dbc, comptype, 0);
08020 HDBC_UNLOCK((SQLHDBC) handle);
08021 return ret;
08022 case SQL_HANDLE_ENV:
08023 if (handle == SQL_NULL_HENV) {
08024 return SQL_INVALID_HANDLE;
08025 }
08026 #if defined(_WIN32) || defined(_WIN64)
08027 env = (ENV *) handle;
08028 if (env->magic != ENV_MAGIC) {
08029 return SQL_INVALID_HANDLE;
08030 }
08031 EnterCriticalSection(&env->cs);
08032 #endif
08033 dbc = ((ENV *) handle)->dbcs;
08034 while (dbc) {
08035 HDBC_LOCK((SQLHDBC) dbc);
08036 ret = endtran(dbc, comptype, 0);
08037 HDBC_UNLOCK((SQLHDBC) dbc);
08038 if (ret != SQL_SUCCESS) {
08039 fail++;
08040 }
08041 dbc = dbc->next;
08042 }
08043 #if defined(_WIN32) || defined(_WIN64)
08044 LeaveCriticalSection(&env->cs);
08045 #endif
08046 return fail ? SQL_ERROR : SQL_SUCCESS;
08047 }
08048 return SQL_INVALID_HANDLE;
08049 }
08050
08059 SQLRETURN SQL_API
08060 SQLEndTran(SQLSMALLINT type, SQLHANDLE handle, SQLSMALLINT comptype)
08061 {
08062 return drvendtran(type, handle, comptype);
08063 }
08064
08073 SQLRETURN SQL_API
08074 SQLTransact(SQLHENV env, SQLHDBC dbc, SQLUSMALLINT type)
08075 {
08076 if (dbc != SQL_NULL_HDBC) {
08077 return drvendtran(SQL_HANDLE_DBC, (SQLHANDLE) dbc, type);
08078 }
08079 return drvendtran(SQL_HANDLE_ENV, (SQLHANDLE) env, type);
08080 }
08081
08086 SQLRETURN SQL_API
08087 SQLCopyDesc(SQLHDESC source, SQLHDESC target)
08088 {
08089 return SQL_ERROR;
08090 }
08091
08092 #ifndef WINTERFACE
08093
08104 SQLRETURN SQL_API
08105 SQLNativeSql(SQLHSTMT stmt, SQLCHAR *sqlin, SQLINTEGER sqlinLen,
08106 SQLCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
08107 {
08108 int outLen = 0;
08109 SQLRETURN ret = SQL_SUCCESS;
08110
08111 HSTMT_LOCK(stmt);
08112 if (sqlinLen == SQL_NTS) {
08113 sqlinLen = strlen((char *) sqlin);
08114 }
08115 if (sql) {
08116 if (sqlMax > 0) {
08117 strncpy((char *) sql, (char *) sqlin, sqlMax - 1);
08118 sqlin[sqlMax - 1] = '\0';
08119 outLen = min(sqlMax - 1, sqlinLen);
08120 }
08121 } else {
08122 outLen = sqlinLen;
08123 }
08124 if (sqlLen) {
08125 *sqlLen = outLen;
08126 }
08127 if (sql && outLen < sqlinLen) {
08128 setstat((STMT *) stmt, -1, "data right truncated", "01004");
08129 ret = SQL_SUCCESS_WITH_INFO;
08130 }
08131 HSTMT_UNLOCK(stmt);
08132 return ret;
08133 }
08134 #endif
08135
08136 #ifdef WINTERFACE
08137
08148 SQLRETURN SQL_API
08149 SQLNativeSqlW(SQLHSTMT stmt, SQLWCHAR *sqlin, SQLINTEGER sqlinLen,
08150 SQLWCHAR *sql, SQLINTEGER sqlMax, SQLINTEGER *sqlLen)
08151 {
08152 int outLen = 0;
08153 SQLRETURN ret = SQL_SUCCESS;
08154
08155 HSTMT_LOCK(stmt);
08156 if (sqlinLen == SQL_NTS) {
08157 sqlinLen = uc_strlen(sqlin);
08158 }
08159 if (sql) {
08160 if (sqlMax > 0) {
08161 uc_strncpy(sql, sqlin, sqlMax - 1);
08162 sqlin[sqlMax - 1] = 0;
08163 outLen = min(sqlMax - 1, sqlinLen);
08164 }
08165 } else {
08166 outLen = sqlinLen;
08167 }
08168 if (sqlLen) {
08169 *sqlLen = outLen;
08170 }
08171 if (sql && outLen < sqlinLen) {
08172 setstat((STMT *) stmt, -1, "data right truncated", "01004");
08173 ret = SQL_SUCCESS_WITH_INFO;
08174 }
08175 HSTMT_UNLOCK(stmt);
08176 return ret;
08177 }
08178 #endif
08179
08184 static COL procSpec2[] = {
08185 { "SYSTEM", "PROCEDURE", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
08186 { "SYSTEM", "PROCEDURE", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
08187 { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
08188 { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
08189 { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
08190 { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
08191 { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
08192 { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
08193 };
08194
08195 static COL procSpec3[] = {
08196 { "SYSTEM", "PROCEDURE", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
08197 { "SYSTEM", "PROCEDURE", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
08198 { "SYSTEM", "PROCEDURE", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
08199 { "SYSTEM", "PROCEDURE", "NUM_INPUT_PARAMS", SQL_SMALLINT, 5 },
08200 { "SYSTEM", "PROCEDURE", "NUM_OUTPUT_PARAMS", SQL_SMALLINT, 5 },
08201 { "SYSTEM", "PROCEDURE", "NUM_RESULT_SETS", SQL_SMALLINT, 5 },
08202 { "SYSTEM", "PROCEDURE", "REMARKS", SCOL_VARCHAR, 255 },
08203 { "SYSTEM", "PROCEDURE", "PROCEDURE_TYPE", SQL_SMALLINT, 5 }
08204 };
08205
08206 #ifndef WINTERFACE
08207
08219 SQLRETURN SQL_API
08220 SQLProcedures(SQLHSTMT stmt,
08221 SQLCHAR *catalog, SQLSMALLINT catalogLen,
08222 SQLCHAR *schema, SQLSMALLINT schemaLen,
08223 SQLCHAR *proc, SQLSMALLINT procLen)
08224 {
08225 SQLRETURN ret;
08226
08227 HSTMT_LOCK(stmt);
08228 ret = mkresultset(stmt, procSpec2, array_size(procSpec2),
08229 procSpec3, array_size(procSpec3), NULL);
08230 HSTMT_UNLOCK(stmt);
08231 return ret;
08232 }
08233 #endif
08234
08235 #ifdef WINTERFACE
08236
08248 SQLRETURN SQL_API
08249 SQLProceduresW(SQLHSTMT stmt,
08250 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
08251 SQLWCHAR *schema, SQLSMALLINT schemaLen,
08252 SQLWCHAR *proc, SQLSMALLINT procLen)
08253 {
08254 SQLRETURN ret;
08255
08256 HSTMT_LOCK(stmt);
08257 ret = mkresultset(stmt, procSpec2, array_size(procSpec2),
08258 procSpec3, array_size(procSpec3), NULL);
08259 HSTMT_UNLOCK(stmt);
08260 return ret;
08261 }
08262 #endif
08263
08268 static COL procColSpec2[] = {
08269 { "SYSTEM", "PROCCOL", "PROCEDURE_QUALIFIER", SCOL_VARCHAR, 50 },
08270 { "SYSTEM", "PROCCOL", "PROCEDURE_OWNER", SCOL_VARCHAR, 50 },
08271 { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
08272 { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
08273 { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
08274 { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
08275 { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
08276 { "SYSTEM", "PROCCOL", "PRECISION", SQL_INTEGER, 10 },
08277 { "SYSTEM", "PROCCOL", "LENGTH", SQL_INTEGER, 10 },
08278 { "SYSTEM", "PROCCOL", "SCALE", SQL_SMALLINT, 5 },
08279 { "SYSTEM", "PROCCOL", "RADIX", SQL_SMALLINT, 5 },
08280 { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
08281 { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
08282 { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
08283 { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
08284 { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
08285 { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
08286 { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
08287 { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
08288 };
08289
08290 static COL procColSpec3[] = {
08291 { "SYSTEM", "PROCCOL", "PROCEDURE_CAT", SCOL_VARCHAR, 50 },
08292 { "SYSTEM", "PROCCOL", "PROCEDURE_SCHEM", SCOL_VARCHAR, 50 },
08293 { "SYSTEM", "PROCCOL", "PROCEDURE_NAME", SCOL_VARCHAR, 255 },
08294 { "SYSTEM", "PROCCOL", "COLUMN_NAME", SCOL_VARCHAR, 255 },
08295 { "SYSTEM", "PROCCOL", "COLUMN_TYPE", SQL_SMALLINT, 5 },
08296 { "SYSTEM", "PROCCOL", "DATA_TYPE", SQL_SMALLINT, 5 },
08297 { "SYSTEM", "PROCCOL", "TYPE_NAME", SCOL_VARCHAR, 50 },
08298 { "SYSTEM", "PROCCOL", "COLUMN_SIZE", SQL_INTEGER, 10 },
08299 { "SYSTEM", "PROCCOL", "BUFFER_LENGTH", SQL_INTEGER, 10 },
08300 { "SYSTEM", "PROCCOL", "DECIMAL_DIGITS", SQL_SMALLINT, 5 },
08301 { "SYSTEM", "PROCCOL", "NUM_PREC_RADIX", SQL_SMALLINT, 5 },
08302 { "SYSTEM", "PROCCOL", "NULLABLE", SQL_SMALLINT, 5 },
08303 { "SYSTEM", "PROCCOL", "REMARKS", SCOL_VARCHAR, 50 },
08304 { "SYSTEM", "PROCCOL", "COLUMN_DEF", SCOL_VARCHAR, 50 },
08305 { "SYSTEM", "PROCCOL", "SQL_DATA_TYPE", SQL_SMALLINT, 5 },
08306 { "SYSTEM", "PROCCOL", "SQL_DATETIME_SUB", SQL_SMALLINT, 5 },
08307 { "SYSTEM", "PROCCOL", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 5 },
08308 { "SYSTEM", "PROCCOL", "ORDINAL_POSITION", SQL_SMALLINT, 5 },
08309 { "SYSTEM", "PROCCOL", "IS_NULLABLE", SCOL_VARCHAR, 50 }
08310 };
08311
08312 #ifndef WINTERFACE
08313
08327 SQLRETURN SQL_API
08328 SQLProcedureColumns(SQLHSTMT stmt,
08329 SQLCHAR *catalog, SQLSMALLINT catalogLen,
08330 SQLCHAR *schema, SQLSMALLINT schemaLen,
08331 SQLCHAR *proc, SQLSMALLINT procLen,
08332 SQLCHAR *column, SQLSMALLINT columnLen)
08333 {
08334 SQLRETURN ret;
08335
08336 HSTMT_LOCK(stmt);
08337 ret = mkresultset(stmt, procColSpec2, array_size(procColSpec2),
08338 procColSpec3, array_size(procColSpec3), NULL);
08339 HSTMT_UNLOCK(stmt);
08340 return ret;
08341 }
08342 #endif
08343
08344 #ifdef WINTERFACE
08345
08360 SQLRETURN SQL_API
08361 SQLProcedureColumnsW(SQLHSTMT stmt,
08362 SQLWCHAR *catalog, SQLSMALLINT catalogLen,
08363 SQLWCHAR *schema, SQLSMALLINT schemaLen,
08364 SQLWCHAR *proc, SQLSMALLINT procLen,
08365 SQLWCHAR *column, SQLSMALLINT columnLen)
08366 {
08367 SQLRETURN ret;
08368
08369 HSTMT_LOCK(stmt);
08370 ret = mkresultset(stmt, procColSpec2, array_size(procColSpec2),
08371 procColSpec3, array_size(procColSpec3), NULL);
08372 HSTMT_UNLOCK(stmt);
08373 return ret;
08374 }
08375 #endif
08376
08387 SQLRETURN SQL_API
08388 SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val,
08389 SQLINTEGER len, SQLINTEGER *lenp)
08390 {
08391 ENV *e;
08392 SQLRETURN ret = SQL_ERROR;
08393
08394 if (env == SQL_NULL_HENV) {
08395 return SQL_INVALID_HANDLE;
08396 }
08397 e = (ENV *) env;
08398 if (!e || e->magic != ENV_MAGIC) {
08399 return SQL_INVALID_HANDLE;
08400 }
08401 #if defined(_WIN32) || defined(_WIN64)
08402 EnterCriticalSection(&e->cs);
08403 #endif
08404 switch (attr) {
08405 case SQL_ATTR_CONNECTION_POOLING:
08406 ret = SQL_ERROR;
08407 break;
08408 case SQL_ATTR_CP_MATCH:
08409 ret = SQL_NO_DATA;
08410 break;
08411 case SQL_ATTR_OUTPUT_NTS:
08412 if (val) {
08413 *((SQLINTEGER *) val) = SQL_TRUE;
08414 }
08415 if (lenp) {
08416 *lenp = sizeof (SQLINTEGER);
08417 }
08418 ret = SQL_SUCCESS;
08419 break;
08420 case SQL_ATTR_ODBC_VERSION:
08421 if (val) {
08422 *((SQLINTEGER *) val) = e->ov3 ? SQL_OV_ODBC3 : SQL_OV_ODBC2;
08423 }
08424 if (lenp) {
08425 *lenp = sizeof (SQLINTEGER);
08426 }
08427 ret = SQL_SUCCESS;
08428 break;
08429 }
08430 #if defined(_WIN32) || defined(_WIN64)
08431 LeaveCriticalSection(&e->cs);
08432 #endif
08433 return ret;
08434 }
08435
08445 SQLRETURN SQL_API
08446 SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER val, SQLINTEGER len)
08447 {
08448 ENV *e;
08449 SQLRETURN ret = SQL_ERROR;
08450
08451 if (env == SQL_NULL_HENV) {
08452 return SQL_INVALID_HANDLE;
08453 }
08454 e = (ENV *) env;
08455 if (!e || e->magic != ENV_MAGIC) {
08456 return SQL_INVALID_HANDLE;
08457 }
08458 #if defined(_WIN32) || defined(_WIN64)
08459 EnterCriticalSection(&e->cs);
08460 #endif
08461 switch (attr) {
08462 case SQL_ATTR_CONNECTION_POOLING:
08463 ret = SQL_SUCCESS;
08464 break;
08465 case SQL_ATTR_CP_MATCH:
08466 ret = SQL_NO_DATA;
08467 break;
08468 case SQL_ATTR_OUTPUT_NTS:
08469 if (val == (SQLPOINTER) SQL_TRUE) {
08470 ret = SQL_SUCCESS;
08471 }
08472 break;
08473 case SQL_ATTR_ODBC_VERSION:
08474 if (!val) {
08475 break;
08476 }
08477 if (val == (SQLPOINTER) SQL_OV_ODBC2) {
08478 e->ov3 = 0;
08479 ret = SQL_SUCCESS;
08480 }
08481 if (val == (SQLPOINTER) SQL_OV_ODBC3) {
08482 e->ov3 = 1;
08483 ret = SQL_SUCCESS;
08484 }
08485 break;
08486 }
08487 #if defined(_WIN32) || defined(_WIN64)
08488 LeaveCriticalSection(&e->cs);
08489 #endif
08490 return ret;
08491 }
08492
08506 static SQLRETURN
08507 drvgetdiagrec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08508 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
08509 SQLSMALLINT buflen, SQLSMALLINT *msglen)
08510 {
08511 DBC *d = NULL;
08512 STMT *s = NULL;
08513 int len, naterr;
08514 char *logmsg, *sqlst;
08515 SQLRETURN ret = SQL_ERROR;
08516
08517 if (handle == SQL_NULL_HANDLE) {
08518 return SQL_INVALID_HANDLE;
08519 }
08520 if (sqlstate) {
08521 sqlstate[0] = '\0';
08522 }
08523 if (msg && buflen > 0) {
08524 msg[0] = '\0';
08525 }
08526 if (msglen) {
08527 *msglen = 0;
08528 }
08529 if (nativeerr) {
08530 *nativeerr = 0;
08531 }
08532 switch (htype) {
08533 case SQL_HANDLE_ENV:
08534 case SQL_HANDLE_DESC:
08535 return SQL_NO_DATA;
08536 case SQL_HANDLE_DBC:
08537 HDBC_LOCK((SQLHDBC) handle);
08538 d = (DBC *) handle;
08539 logmsg = (char *) d->logmsg;
08540 sqlst = d->sqlstate;
08541 naterr = d->naterr;
08542 break;
08543 case SQL_HANDLE_STMT:
08544 HSTMT_LOCK((SQLHSTMT) handle);
08545 s = (STMT *) handle;
08546 logmsg = (char *) s->logmsg;
08547 sqlst = s->sqlstate;
08548 naterr = s->naterr;
08549 break;
08550 default:
08551 return SQL_INVALID_HANDLE;
08552 }
08553 if (buflen < 0) {
08554 goto done;
08555 }
08556 if (recno > 1) {
08557 ret = SQL_NO_DATA;
08558 goto done;
08559 }
08560 len = strlen(logmsg);
08561 if (len == 0) {
08562 ret = SQL_NO_DATA;
08563 goto done;
08564 }
08565 if (nativeerr) {
08566 *nativeerr = naterr;
08567 }
08568 if (sqlstate) {
08569 strcpy((char *) sqlstate, sqlst);
08570 }
08571 if (msglen) {
08572 *msglen = len;
08573 }
08574 if (len >= buflen) {
08575 if (msg && buflen > 0) {
08576 strncpy((char *) msg, logmsg, buflen);
08577 msg[buflen - 1] = '\0';
08578 logmsg[0] = '\0';
08579 }
08580 } else if (msg) {
08581 strcpy((char *) msg, logmsg);
08582 logmsg[0] = '\0';
08583 }
08584 ret = SQL_SUCCESS;
08585 done:
08586 switch (htype) {
08587 case SQL_HANDLE_DBC:
08588 HDBC_UNLOCK((SQLHDBC) handle);
08589 break;
08590 case SQL_HANDLE_STMT:
08591 HSTMT_UNLOCK((SQLHSTMT) handle);
08592 break;
08593 }
08594 return ret;
08595 }
08596
08597 #if !defined(WINTERFACE) || (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC))
08598
08611 SQLRETURN SQL_API
08612 SQLGetDiagRec(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08613 SQLCHAR *sqlstate, SQLINTEGER *nativeerr, SQLCHAR *msg,
08614 SQLSMALLINT buflen, SQLSMALLINT *msglen)
08615 {
08616 return drvgetdiagrec(htype, handle, recno, sqlstate,
08617 nativeerr, msg, buflen, msglen);
08618 }
08619 #endif
08620
08621 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
08622 #ifdef WINTERFACE
08623
08637 SQLRETURN SQL_API
08638 SQLGetDiagRecW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08639 SQLWCHAR *sqlstate, SQLINTEGER *nativeerr, SQLWCHAR *msg,
08640 SQLSMALLINT buflen, SQLSMALLINT *msglen)
08641 {
08642 char state[16];
08643 SQLSMALLINT len;
08644 SQLRETURN ret;
08645
08646 ret = drvgetdiagrec(htype, handle, recno, (SQLCHAR *) state,
08647 nativeerr, (SQLCHAR *) msg, buflen, &len);
08648 if (ret == SQL_SUCCESS) {
08649 if (sqlstate) {
08650 uc_from_utf_buf((SQLCHAR *) state, -1, sqlstate,
08651 6 * sizeof (SQLWCHAR));
08652 }
08653 if (msg) {
08654 if (len > 0) {
08655 SQLWCHAR *m = NULL;
08656
08657 m = uc_from_utf((unsigned char *) msg, len);
08658 if (m) {
08659 if (buflen) {
08660 buflen /= sizeof (SQLWCHAR);
08661 uc_strncpy(msg, m, buflen);
08662 m[len] = 0;
08663 len = min(buflen, uc_strlen(m));
08664 } else {
08665 len = uc_strlen(m);
08666 }
08667 uc_free(m);
08668 } else {
08669 len = 0;
08670 }
08671 }
08672 if (len <= 0) {
08673 len = 0;
08674 if (buflen > 0) {
08675 msg[0] = 0;
08676 }
08677 }
08678 } else {
08679
08680 len *= sizeof (SQLWCHAR);
08681 }
08682 if (msglen) {
08683 *msglen = len;
08684 }
08685 } else if (ret == SQL_NO_DATA) {
08686 if (sqlstate) {
08687 sqlstate[0] = 0;
08688 }
08689 if (msg) {
08690 if (buflen > 0) {
08691 msg[0] = 0;
08692 }
08693 }
08694 if (msglen) {
08695 *msglen = 0;
08696 }
08697 }
08698 return ret;
08699 }
08700 #endif
08701 #endif
08702
08715 static SQLRETURN
08716 drvgetdiagfield(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08717 SQLSMALLINT id, SQLPOINTER info,
08718 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
08719 {
08720 DBC *d = NULL;
08721 STMT *s = NULL;
08722 int len, naterr, strbuf = 1;
08723 char *logmsg, *sqlst, *clrmsg = NULL;
08724 SQLRETURN ret = SQL_ERROR;
08725
08726 if (handle == SQL_NULL_HANDLE) {
08727 return SQL_INVALID_HANDLE;
08728 }
08729 if (stringlen) {
08730 *stringlen = 0;
08731 }
08732 switch (htype) {
08733 case SQL_HANDLE_ENV:
08734 case SQL_HANDLE_DESC:
08735 return SQL_NO_DATA;
08736 case SQL_HANDLE_DBC:
08737 HDBC_LOCK((SQLHDBC) handle);
08738 d = (DBC *) handle;
08739 logmsg = (char *) d->logmsg;
08740 sqlst = d->sqlstate;
08741 naterr = d->naterr;
08742 break;
08743 case SQL_HANDLE_STMT:
08744 HSTMT_LOCK((SQLHSTMT) handle);
08745 s = (STMT *) handle;
08746 d = (DBC *) s->dbc;
08747 logmsg = (char *) s->logmsg;
08748 sqlst = s->sqlstate;
08749 naterr = s->naterr;
08750 break;
08751 default:
08752 return SQL_INVALID_HANDLE;
08753 }
08754 if (buflen < 0) {
08755 switch (buflen) {
08756 case SQL_IS_POINTER:
08757 case SQL_IS_UINTEGER:
08758 case SQL_IS_INTEGER:
08759 case SQL_IS_USMALLINT:
08760 case SQL_IS_SMALLINT:
08761 strbuf = 0;
08762 break;
08763 default:
08764 ret = SQL_ERROR;
08765 goto done;
08766 }
08767 }
08768 if (recno > 1) {
08769 ret = SQL_NO_DATA;
08770 goto done;
08771 }
08772 switch (id) {
08773 case SQL_DIAG_CLASS_ORIGIN:
08774 logmsg = "ISO 9075";
08775 if (sqlst[0] == 'I' && sqlst[1] == 'M') {
08776 logmsg = "ODBC 3.0";
08777 }
08778 break;
08779 case SQL_DIAG_SUBCLASS_ORIGIN:
08780 logmsg = "ISO 9075";
08781 if (sqlst[0] == 'I' && sqlst[1] == 'M') {
08782 logmsg = "ODBC 3.0";
08783 } else if (sqlst[0] == 'H' && sqlst[1] == 'Y') {
08784 logmsg = "ODBC 3.0";
08785 } else if (sqlst[0] == '2' || sqlst[0] == '0' || sqlst[0] == '4') {
08786 logmsg = "ODBC 3.0";
08787 }
08788 break;
08789 case SQL_DIAG_CONNECTION_NAME:
08790 case SQL_DIAG_SERVER_NAME:
08791 logmsg = d->dsn ? d->dsn : "No DSN";
08792 break;
08793 case SQL_DIAG_SQLSTATE:
08794 logmsg = sqlst;
08795 break;
08796 case SQL_DIAG_MESSAGE_TEXT:
08797 if (info) {
08798 clrmsg = logmsg;
08799 }
08800 break;
08801 case SQL_DIAG_NUMBER:
08802 naterr = 1;
08803
08804 case SQL_DIAG_NATIVE:
08805 len = strlen(logmsg);
08806 if (len == 0) {
08807 ret = SQL_NO_DATA;
08808 goto done;
08809 }
08810 if (info) {
08811 *((SQLINTEGER *) info) = naterr;
08812 }
08813 ret = SQL_SUCCESS;
08814 goto done;
08815 case SQL_DIAG_DYNAMIC_FUNCTION:
08816 logmsg = "";
08817 break;
08818 case SQL_DIAG_CURSOR_ROW_COUNT:
08819 if (htype == SQL_HANDLE_STMT) {
08820 SQLULEN count;
08821
08822 count = (s->isselect == 1 || s->isselect == -1) ? s->nrows : 0;
08823 *((SQLULEN *) info) = count;
08824 ret = SQL_SUCCESS;
08825 }
08826 goto done;
08827 case SQL_DIAG_ROW_COUNT:
08828 if (htype == SQL_HANDLE_STMT) {
08829 SQLULEN count;
08830
08831 count = s->isselect ? 0 : s->nrows;
08832 *((SQLULEN *) info) = count;
08833 ret = SQL_SUCCESS;
08834 }
08835 goto done;
08836 default:
08837 goto done;
08838 }
08839 if (info && buflen > 0) {
08840 ((char *) info)[0] = '\0';
08841 }
08842 len = strlen(logmsg);
08843 if (len == 0) {
08844 ret = SQL_NO_DATA;
08845 goto done;
08846 }
08847 if (stringlen) {
08848 *stringlen = len;
08849 }
08850 if (strbuf) {
08851 if (len >= buflen) {
08852 if (info && buflen > 0) {
08853 if (stringlen) {
08854 *stringlen = buflen - 1;
08855 }
08856 strncpy((char *) info, logmsg, buflen);
08857 ((char *) info)[buflen - 1] = '\0';
08858 }
08859 } else if (info) {
08860 strcpy((char *) info, logmsg);
08861 }
08862 }
08863 if (clrmsg) {
08864 *clrmsg = '\0';
08865 }
08866 ret = SQL_SUCCESS;
08867 done:
08868 switch (htype) {
08869 case SQL_HANDLE_DBC:
08870 HDBC_UNLOCK((SQLHDBC) handle);
08871 break;
08872 case SQL_HANDLE_STMT:
08873 HSTMT_UNLOCK((SQLHSTMT) handle);
08874 break;
08875 }
08876 return ret;
08877 }
08878
08879 #ifndef WINTERFACE
08880
08892 SQLRETURN SQL_API
08893 SQLGetDiagField(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08894 SQLSMALLINT id, SQLPOINTER info,
08895 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
08896 {
08897 return drvgetdiagfield(htype, handle, recno, id, info, buflen, stringlen);
08898 }
08899 #endif
08900
08901 #ifdef WINTERFACE
08902
08914 SQLRETURN SQL_API
08915 SQLGetDiagFieldW(SQLSMALLINT htype, SQLHANDLE handle, SQLSMALLINT recno,
08916 SQLSMALLINT id, SQLPOINTER info,
08917 SQLSMALLINT buflen, SQLSMALLINT *stringlen)
08918 {
08919 SQLSMALLINT len;
08920 SQLRETURN ret;
08921
08922 ret = drvgetdiagfield(htype, handle, recno, id, info, buflen, &len);
08923 if (ret == SQL_SUCCESS) {
08924 if (info) {
08925 switch (id) {
08926 case SQL_DIAG_CLASS_ORIGIN:
08927 case SQL_DIAG_SUBCLASS_ORIGIN:
08928 case SQL_DIAG_CONNECTION_NAME:
08929 case SQL_DIAG_SERVER_NAME:
08930 case SQL_DIAG_SQLSTATE:
08931 case SQL_DIAG_MESSAGE_TEXT:
08932 case SQL_DIAG_DYNAMIC_FUNCTION:
08933 if (len > 0) {
08934 SQLWCHAR *m = NULL;
08935
08936 m = uc_from_utf((unsigned char *) info, len);
08937 if (m) {
08938 if (buflen) {
08939 buflen /= sizeof (SQLWCHAR);
08940 uc_strncpy(info, m, buflen);
08941 m[len] = 0;
08942 len = min(buflen, uc_strlen(m));
08943 } else {
08944 len = uc_strlen(m);
08945 }
08946 uc_free(m);
08947 len *= sizeof (SQLWCHAR);
08948 } else {
08949 len = 0;
08950 }
08951 }
08952 if (len <= 0) {
08953 len = 0;
08954 if (buflen > 0) {
08955 ((SQLWCHAR *) info)[0] = 0;
08956 }
08957 }
08958 }
08959 } else {
08960 switch (id) {
08961 case SQL_DIAG_CLASS_ORIGIN:
08962 case SQL_DIAG_SUBCLASS_ORIGIN:
08963 case SQL_DIAG_CONNECTION_NAME:
08964 case SQL_DIAG_SERVER_NAME:
08965 case SQL_DIAG_SQLSTATE:
08966 case SQL_DIAG_MESSAGE_TEXT:
08967 case SQL_DIAG_DYNAMIC_FUNCTION:
08968 len *= sizeof (SQLWCHAR);
08969 break;
08970 }
08971 }
08972 if (stringlen) {
08973 *stringlen = len;
08974 }
08975 }
08976 return ret;
08977 }
08978 #endif
08979
08990 static SQLRETURN
08991 drvgetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
08992 SQLINTEGER bufmax, SQLINTEGER *buflen)
08993 {
08994 STMT *s = (STMT *) stmt;
08995 SQLULEN *uval = (SQLULEN *) val;
08996 SQLINTEGER dummy;
08997 char dummybuf[16];
08998
08999 if (!buflen) {
09000 buflen = &dummy;
09001 }
09002 if (!uval) {
09003 uval = (SQLPOINTER) dummybuf;
09004 }
09005 switch (attr) {
09006 case SQL_QUERY_TIMEOUT:
09007 *uval = 0;
09008 *buflen = sizeof (SQLULEN);
09009 return SQL_SUCCESS;
09010 case SQL_ATTR_CURSOR_TYPE:
09011 *uval = s->curtype;
09012 *buflen = sizeof (SQLULEN);
09013 return SQL_SUCCESS;
09014 case SQL_ATTR_CURSOR_SCROLLABLE:
09015 *uval = (s->curtype != SQL_CURSOR_FORWARD_ONLY) ?
09016 SQL_SCROLLABLE : SQL_NONSCROLLABLE;
09017 *buflen = sizeof (SQLULEN);
09018 return SQL_SUCCESS;
09019 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
09020 case SQL_ATTR_CURSOR_SENSITIVITY:
09021 *uval = SQL_UNSPECIFIED;
09022 *buflen = sizeof (SQLULEN);
09023 return SQL_SUCCESS;
09024 #endif
09025 case SQL_ATTR_ROW_NUMBER:
09026 if (s->s3stmt) {
09027 *uval = (s->s3stmt_rownum < 0) ?
09028 SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
09029 } else {
09030 *uval = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
09031 }
09032 *buflen = sizeof (SQLULEN);
09033 return SQL_SUCCESS;
09034 case SQL_ATTR_ASYNC_ENABLE:
09035 *uval = SQL_ASYNC_ENABLE_OFF;
09036 *buflen = sizeof (SQLULEN);
09037 return SQL_SUCCESS;
09038 case SQL_CONCURRENCY:
09039 *uval = SQL_CONCUR_LOCK;
09040 *buflen = sizeof (SQLULEN);
09041 return SQL_SUCCESS;
09042 case SQL_ATTR_RETRIEVE_DATA:
09043 *uval = s->retr_data;
09044 *buflen = sizeof (SQLULEN);
09045 return SQL_SUCCESS;
09046 case SQL_ROWSET_SIZE:
09047 case SQL_ATTR_ROW_ARRAY_SIZE:
09048 *uval = s->rowset_size;
09049 *buflen = sizeof (SQLULEN);
09050 return SQL_SUCCESS;
09051
09052 case SQL_ATTR_IMP_ROW_DESC:
09053 case SQL_ATTR_APP_ROW_DESC:
09054 case SQL_ATTR_IMP_PARAM_DESC:
09055 case SQL_ATTR_APP_PARAM_DESC:
09056 *((SQLHDESC *) uval) = (SQLHDESC) DEAD_MAGIC;
09057 *buflen = sizeof (SQLHDESC);
09058 return SQL_SUCCESS;
09059 case SQL_ATTR_ROW_STATUS_PTR:
09060 *((SQLUSMALLINT **) uval) = s->row_status;
09061 *buflen = sizeof (SQLUSMALLINT *);
09062 return SQL_SUCCESS;
09063 case SQL_ATTR_ROWS_FETCHED_PTR:
09064 *((SQLULEN **) uval) = s->row_count;
09065 *buflen = sizeof (SQLULEN *);
09066 return SQL_SUCCESS;
09067 case SQL_ATTR_USE_BOOKMARKS: {
09068 STMT *s = (STMT *) stmt;
09069
09070 *(SQLUINTEGER *) uval = s->bkmrk;
09071 *buflen = sizeof (SQLUINTEGER);
09072 return SQL_SUCCESS;
09073 }
09074 case SQL_ATTR_FETCH_BOOKMARK_PTR:
09075 *(SQLPOINTER *) uval = s->bkmrkptr;
09076 *buflen = sizeof (SQLPOINTER);
09077 return SQL_SUCCESS;
09078 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
09079 *((SQLULEN **) uval) = s->parm_bind_offs;
09080 *buflen = sizeof (SQLULEN *);
09081 return SQL_SUCCESS;
09082 case SQL_ATTR_PARAM_BIND_TYPE:
09083 *((SQLULEN *) uval) = s->parm_bind_type;
09084 *buflen = sizeof (SQLULEN);
09085 return SQL_SUCCESS;
09086 case SQL_ATTR_PARAM_OPERATION_PTR:
09087 *((SQLUSMALLINT **) uval) = s->parm_oper;
09088 *buflen = sizeof (SQLUSMALLINT *);
09089 return SQL_SUCCESS;
09090 case SQL_ATTR_PARAM_STATUS_PTR:
09091 *((SQLUSMALLINT **) uval) = s->parm_status;
09092 *buflen = sizeof (SQLUSMALLINT *);
09093 return SQL_SUCCESS;
09094 case SQL_ATTR_PARAMS_PROCESSED_PTR:
09095 *((SQLULEN **) uval) = s->parm_proc;
09096 *buflen = sizeof (SQLULEN *);
09097 return SQL_SUCCESS;
09098 case SQL_ATTR_PARAMSET_SIZE:
09099 *((SQLULEN *) uval) = s->paramset_size;
09100 *buflen = sizeof (SQLULEN);
09101 return SQL_SUCCESS;
09102 case SQL_ATTR_ROW_BIND_TYPE:
09103 *(SQLULEN *) uval = s->bind_type;
09104 *buflen = sizeof (SQLULEN);
09105 return SQL_SUCCESS;
09106 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
09107 *((SQLULEN **) uval) = s->bind_offs;
09108 *buflen = sizeof (SQLULEN *);
09109 return SQL_SUCCESS;
09110 case SQL_ATTR_MAX_ROWS:
09111 *((SQLULEN *) uval) = s->max_rows;
09112 *buflen = sizeof (SQLULEN);
09113 return SQL_SUCCESS;
09114 case SQL_ATTR_MAX_LENGTH:
09115 *((SQLULEN *) uval) = 1000000000;
09116 *buflen = sizeof (SQLULEN);
09117 return SQL_SUCCESS;
09118 #ifdef SQL_ATTR_METADATA_ID
09119 case SQL_ATTR_METADATA_ID:
09120 *((SQLULEN *) uval) = SQL_FALSE;
09121 *buflen = sizeof (SQLULEN);
09122 return SQL_SUCCESS;
09123 #endif
09124 }
09125 return drvunimplstmt(stmt);
09126 }
09127
09128 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
09129
09139 SQLRETURN SQL_API
09140 SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09141 SQLINTEGER bufmax, SQLINTEGER *buflen)
09142 {
09143 SQLRETURN ret;
09144
09145 HSTMT_LOCK(stmt);
09146 ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
09147 HSTMT_UNLOCK(stmt);
09148 return ret;
09149 }
09150 #endif
09151
09152 #ifdef WINTERFACE
09153
09163 SQLRETURN SQL_API
09164 SQLGetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09165 SQLINTEGER bufmax, SQLINTEGER *buflen)
09166 {
09167 SQLRETURN ret;
09168
09169 HSTMT_LOCK(stmt);
09170 ret = drvgetstmtattr(stmt, attr, val, bufmax, buflen);
09171 HSTMT_UNLOCK(stmt);
09172 return ret;
09173 }
09174 #endif
09175
09185 static SQLRETURN
09186 drvsetstmtattr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09187 SQLINTEGER buflen)
09188 {
09189 STMT *s = (STMT *) stmt;
09190 #if defined(SQL_BIGINT) && defined(__WORDSIZE) && (__WORDSIZE == 64)
09191 SQLBIGINT uval;
09192
09193 uval = (SQLBIGINT) val;
09194 #else
09195 SQLULEN uval;
09196
09197 uval = (SQLULEN) val;
09198 #endif
09199 switch (attr) {
09200 case SQL_ATTR_CURSOR_TYPE:
09201 if (val == (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY) {
09202 s->curtype = SQL_CURSOR_FORWARD_ONLY;
09203 } else {
09204 s->curtype = SQL_CURSOR_STATIC;
09205 }
09206 if (val != (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY &&
09207 val != (SQLPOINTER) SQL_CURSOR_STATIC) {
09208 goto e01s02;
09209 }
09210 return SQL_SUCCESS;
09211 case SQL_ATTR_CURSOR_SCROLLABLE:
09212 if (val == (SQLPOINTER) SQL_NONSCROLLABLE) {
09213 s->curtype = SQL_CURSOR_FORWARD_ONLY;
09214 } else {
09215 s->curtype = SQL_CURSOR_STATIC;
09216 }
09217 return SQL_SUCCESS;
09218 case SQL_ATTR_ASYNC_ENABLE:
09219 if (val != (SQLPOINTER) SQL_ASYNC_ENABLE_OFF) {
09220 e01s02:
09221 setstat(s, -1, "option value changed", "01S02");
09222 return SQL_SUCCESS_WITH_INFO;
09223 }
09224 return SQL_SUCCESS;
09225 case SQL_CONCURRENCY:
09226 if (val != (SQLPOINTER) SQL_CONCUR_LOCK) {
09227 goto e01s02;
09228 }
09229 return SQL_SUCCESS;
09230 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
09231 case SQL_ATTR_CURSOR_SENSITIVITY:
09232 if (val != (SQLPOINTER) SQL_UNSPECIFIED) {
09233 goto e01s02;
09234 }
09235 return SQL_SUCCESS;
09236 #endif
09237 case SQL_ATTR_QUERY_TIMEOUT:
09238 return SQL_SUCCESS;
09239 case SQL_ATTR_RETRIEVE_DATA:
09240 if (val != (SQLPOINTER) SQL_RD_ON &&
09241 val != (SQLPOINTER) SQL_RD_OFF) {
09242 goto e01s02;
09243 }
09244 s->retr_data = uval;
09245 return SQL_SUCCESS;
09246 case SQL_ROWSET_SIZE:
09247 case SQL_ATTR_ROW_ARRAY_SIZE:
09248 if (uval < 1) {
09249 setstat(s, -1, "invalid rowset size", "HY000");
09250 return SQL_ERROR;
09251 } else {
09252 SQLUSMALLINT *rst = &s->row_status1;
09253
09254 if (uval > 1) {
09255 rst = xmalloc(sizeof (SQLUSMALLINT) * uval);
09256 if (!rst) {
09257 return nomem(s);
09258 }
09259 }
09260 if (s->row_status0 != &s->row_status1) {
09261 freep(&s->row_status0);
09262 }
09263 s->row_status0 = rst;
09264 s->rowset_size = uval;
09265 }
09266 return SQL_SUCCESS;
09267 case SQL_ATTR_ROW_STATUS_PTR:
09268 s->row_status = (SQLUSMALLINT *) val;
09269 return SQL_SUCCESS;
09270 case SQL_ATTR_ROWS_FETCHED_PTR:
09271 s->row_count = (SQLULEN *) val;
09272 return SQL_SUCCESS;
09273 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
09274 s->parm_bind_offs = (SQLULEN *) val;
09275 return SQL_SUCCESS;
09276 case SQL_ATTR_PARAM_BIND_TYPE:
09277 s->parm_bind_type = uval;
09278 return SQL_SUCCESS;
09279 case SQL_ATTR_PARAM_OPERATION_PTR:
09280 s->parm_oper = (SQLUSMALLINT *) val;
09281 return SQL_SUCCESS;
09282 case SQL_ATTR_PARAM_STATUS_PTR:
09283 s->parm_status = (SQLUSMALLINT *) val;
09284 return SQL_SUCCESS;
09285 case SQL_ATTR_PARAMS_PROCESSED_PTR:
09286 s->parm_proc = (SQLULEN *) val;
09287 return SQL_SUCCESS;
09288 case SQL_ATTR_PARAMSET_SIZE:
09289 if (uval < 1) {
09290 goto e01s02;
09291 }
09292 s->paramset_size = uval;
09293 s->paramset_count = 0;
09294 return SQL_SUCCESS;
09295 case SQL_ATTR_ROW_BIND_TYPE:
09296 s->bind_type = uval;
09297 return SQL_SUCCESS;
09298 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
09299 s->bind_offs = (SQLULEN *) val;
09300 return SQL_SUCCESS;
09301 case SQL_ATTR_USE_BOOKMARKS:
09302 if (val != (SQLPOINTER) SQL_UB_OFF &&
09303 val != (SQLPOINTER) SQL_UB_ON &&
09304 val != (SQLPOINTER) SQL_UB_VARIABLE) {
09305 goto e01s02;
09306 }
09307 if (*s->ov3 && val == (SQLPOINTER) SQL_UB_VARIABLE) {
09308 s->bkmrk = SQL_UB_VARIABLE;
09309 return SQL_SUCCESS;
09310 }
09311 if (val == (SQLPOINTER) SQL_UB_VARIABLE) {
09312 s->bkmrk = SQL_UB_ON;
09313 goto e01s02;
09314 }
09315 s->bkmrk = (val == (SQLPOINTER) SQL_UB_ON) ? SQL_UB_ON : SQL_UB_OFF;
09316 return SQL_SUCCESS;
09317 case SQL_ATTR_FETCH_BOOKMARK_PTR:
09318 s->bkmrkptr = (SQLINTEGER *) val;
09319 return SQL_SUCCESS;
09320 case SQL_ATTR_MAX_ROWS:
09321 s->max_rows = uval;
09322 return SQL_SUCCESS;
09323 case SQL_ATTR_MAX_LENGTH:
09324 if (val != (SQLPOINTER) 1000000000) {
09325 goto e01s02;
09326 }
09327 return SQL_SUCCESS;
09328 #ifdef SQL_ATTR_METADATA_ID
09329 case SQL_ATTR_METADATA_ID:
09330 if (val != (SQLPOINTER) SQL_FALSE) {
09331 goto e01s02;
09332 }
09333 return SQL_SUCCESS;
09334 #endif
09335 }
09336 return drvunimplstmt(stmt);
09337 }
09338
09339 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
09340
09349 SQLRETURN SQL_API
09350 SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09351 SQLINTEGER buflen)
09352 {
09353 SQLRETURN ret;
09354
09355 HSTMT_LOCK(stmt);
09356 ret = drvsetstmtattr(stmt, attr, val, buflen);
09357 HSTMT_UNLOCK(stmt);
09358 return ret;
09359 }
09360 #endif
09361
09362 #ifdef WINTERFACE
09363
09372 SQLRETURN SQL_API
09373 SQLSetStmtAttrW(SQLHSTMT stmt, SQLINTEGER attr, SQLPOINTER val,
09374 SQLINTEGER buflen)
09375 {
09376 SQLRETURN ret;
09377
09378 HSTMT_LOCK(stmt);
09379 ret = drvsetstmtattr(stmt, attr, val, buflen);
09380 HSTMT_UNLOCK(stmt);
09381 return ret;
09382 }
09383 #endif
09384
09393 static SQLRETURN
09394 drvgetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
09395 {
09396 STMT *s = (STMT *) stmt;
09397 SQLUINTEGER *ret = (SQLUINTEGER *) param;
09398
09399 switch (opt) {
09400 case SQL_QUERY_TIMEOUT:
09401 *ret = 0;
09402 return SQL_SUCCESS;
09403 case SQL_CURSOR_TYPE:
09404 *ret = s->curtype;
09405 return SQL_SUCCESS;
09406 case SQL_ROW_NUMBER:
09407 if (s->s3stmt) {
09408 *ret = (s->s3stmt_rownum < 0) ?
09409 SQL_ROW_NUMBER_UNKNOWN : (s->s3stmt_rownum + 1);
09410 } else {
09411 *ret = (s->rowp < 0) ? SQL_ROW_NUMBER_UNKNOWN : (s->rowp + 1);
09412 }
09413 return SQL_SUCCESS;
09414 case SQL_ASYNC_ENABLE:
09415 *ret = SQL_ASYNC_ENABLE_OFF;
09416 return SQL_SUCCESS;
09417 case SQL_CONCURRENCY:
09418 *ret = SQL_CONCUR_LOCK;
09419 return SQL_SUCCESS;
09420 case SQL_ATTR_RETRIEVE_DATA:
09421 *ret = s->retr_data;
09422 return SQL_SUCCESS;
09423 case SQL_ROWSET_SIZE:
09424 case SQL_ATTR_ROW_ARRAY_SIZE:
09425 *ret = s->rowset_size;
09426 return SQL_SUCCESS;
09427 case SQL_ATTR_MAX_ROWS:
09428 *ret = s->max_rows;
09429 return SQL_SUCCESS;
09430 case SQL_ATTR_MAX_LENGTH:
09431 *ret = 1000000000;
09432 return SQL_SUCCESS;
09433 }
09434 return drvunimplstmt(stmt);
09435 }
09436
09445 SQLRETURN SQL_API
09446 SQLGetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
09447 {
09448 SQLRETURN ret;
09449
09450 HSTMT_LOCK(stmt);
09451 ret = drvgetstmtoption(stmt, opt, param);
09452 HSTMT_UNLOCK(stmt);
09453 return ret;
09454 }
09455
09456 #ifdef WINTERFACE
09457
09465 SQLRETURN SQL_API
09466 SQLGetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt, SQLPOINTER param)
09467 {
09468 SQLRETURN ret;
09469
09470 HSTMT_LOCK(stmt);
09471 ret = drvgetstmtoption(stmt, opt, param);
09472 HSTMT_UNLOCK(stmt);
09473 return ret;
09474 }
09475 #endif
09476
09485 static SQLRETURN
09486 drvsetstmtoption(SQLHSTMT stmt, SQLUSMALLINT opt, SQLUINTEGER param)
09487 {
09488 STMT *s = (STMT *) stmt;
09489
09490 switch (opt) {
09491 case SQL_CURSOR_TYPE:
09492 if (param == SQL_CURSOR_FORWARD_ONLY) {
09493 s->curtype = param;
09494 } else {
09495 s->curtype = SQL_CURSOR_STATIC;
09496 }
09497 if (param != SQL_CURSOR_FORWARD_ONLY &&
09498 param != SQL_CURSOR_STATIC) {
09499 goto e01s02;
09500 }
09501 return SQL_SUCCESS;
09502 case SQL_ASYNC_ENABLE:
09503 if (param != SQL_ASYNC_ENABLE_OFF) {
09504 goto e01s02;
09505 }
09506 return SQL_SUCCESS;
09507 case SQL_CONCURRENCY:
09508 if (param != SQL_CONCUR_LOCK) {
09509 goto e01s02;
09510 }
09511 return SQL_SUCCESS;
09512 case SQL_QUERY_TIMEOUT:
09513 return SQL_SUCCESS;
09514 case SQL_RETRIEVE_DATA:
09515 if (param != SQL_RD_ON && param != SQL_RD_OFF) {
09516 e01s02:
09517 setstat(s, -1, "option value changed", "01S02");
09518 return SQL_SUCCESS_WITH_INFO;
09519 }
09520 s->retr_data = (int) param;
09521 return SQL_SUCCESS;
09522 case SQL_ROWSET_SIZE:
09523 case SQL_ATTR_ROW_ARRAY_SIZE:
09524 if (param < 1) {
09525 setstat(s, -1, "invalid rowset size", "HY000");
09526 return SQL_ERROR;
09527 } else {
09528 SQLUSMALLINT *rst = &s->row_status1;
09529
09530 if (param > 1) {
09531 rst = xmalloc(sizeof (SQLUSMALLINT) * param);
09532 if (!rst) {
09533 return nomem(s);
09534 }
09535 }
09536 if (s->row_status0 != &s->row_status1) {
09537 freep(&s->row_status0);
09538 }
09539 s->row_status0 = rst;
09540 s->rowset_size = param;
09541 }
09542 return SQL_SUCCESS;
09543 case SQL_ATTR_MAX_ROWS:
09544 s->max_rows = param;
09545 return SQL_SUCCESS;
09546 case SQL_ATTR_MAX_LENGTH:
09547 if (param != 1000000000) {
09548 goto e01s02;
09549 }
09550 return SQL_SUCCESS;
09551 }
09552 return drvunimplstmt(stmt);
09553 }
09554
09563 SQLRETURN SQL_API
09564 SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT opt,
09565 SETSTMTOPTION_LAST_ARG_TYPE param)
09566 {
09567 SQLRETURN ret;
09568
09569 HSTMT_LOCK(stmt);
09570 ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
09571 HSTMT_UNLOCK(stmt);
09572 return ret;
09573 }
09574
09575 #ifdef WINTERFACE
09576
09584 SQLRETURN SQL_API
09585 SQLSetStmtOptionW(SQLHSTMT stmt, SQLUSMALLINT opt,
09586 SETSTMTOPTION_LAST_ARG_TYPE param)
09587 {
09588 SQLRETURN ret;
09589
09590 HSTMT_LOCK(stmt);
09591 ret = drvsetstmtoption(stmt, opt, (SQLUINTEGER) param);
09592 HSTMT_UNLOCK(stmt);
09593 return ret;
09594 }
09595 #endif
09596
09603 static SQLRETURN
09604 chkunbound(STMT *s)
09605 {
09606 int i;
09607
09608 if (!s->bindcols || s->nbindcols < s->ncols) {
09609 unbound:
09610 setstat(s, -1, "unbound columns", (*s->ov3) ? "HY000" : "S1000");
09611 return SQL_ERROR;
09612 }
09613 for (i = 0; i < s->ncols; i++) {
09614 BINDCOL *b = &s->bindcols[i];
09615
09616 if (b->type == SQL_UNKNOWN_TYPE || !b->valp) {
09617 goto unbound;
09618 }
09619 }
09620 return SQL_SUCCESS;
09621 }
09622
09634 static SQLRETURN
09635 setposbind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
09636 {
09637 DBC *d = (DBC *) s->dbc;
09638 SQLPOINTER dp = 0;
09639 SQLLEN *lp = 0;
09640 BINDCOL *b = &s->bindcols[i];
09641 COL *c = &s->cols[i];
09642 char strbuf[128], *cp;
09643
09644 if (b->valp) {
09645 if (s->bind_type != SQL_BIND_BY_COLUMN) {
09646 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
09647 } else {
09648 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
09649 }
09650 if (s->bind_offs) {
09651 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
09652 }
09653 }
09654 if (b->lenp) {
09655 if (s->bind_type != SQL_BIND_BY_COLUMN) {
09656 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
09657 } else {
09658 lp = b->lenp + rsi;
09659 }
09660 if (s->bind_offs) {
09661 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
09662 }
09663 }
09664 if (!dp || !lp) {
09665 setstat(s, -1, "unbound column in positional update",
09666 (*s->ov3) ? "HY000" : "S1000");
09667 return SQL_ERROR;
09668 }
09669 if (*lp == SQL_NULL_DATA) {
09670 sqlite3_bind_null(stmt, si);
09671 if (d->trace) {
09672 fprintf(d->trace, "-- parameter %d: NULL\n", si);
09673 fflush(d->trace);
09674 }
09675 return SQL_SUCCESS;
09676 }
09677 switch (b->type) {
09678 case SQL_C_UTINYINT:
09679 case SQL_C_TINYINT:
09680 case SQL_C_STINYINT:
09681 sqlite3_bind_int(stmt, si, *(SQLCHAR *) dp);
09682 if (d->trace) {
09683 fprintf(d->trace, "-- parameter %d: %d\n", si, *(SQLCHAR *) dp);
09684 fflush(d->trace);
09685 }
09686 break;
09687 #ifdef SQL_BIT
09688 case SQL_C_BIT:
09689 sqlite3_bind_int(stmt, si, (*(SQLCHAR *) dp) ? 1 : 0);
09690 if (d->trace) {
09691 fprintf(d->trace, "-- parameter %d: %d\n", si,
09692 (*(SQLCHAR *) dp) ? 1 : 0);
09693 fflush(d->trace);
09694 }
09695 break;
09696 #endif
09697 case SQL_C_USHORT:
09698 sqlite3_bind_int(stmt, si, *(SQLUSMALLINT *) dp);
09699 if (d->trace) {
09700 fprintf(d->trace, "-- parameter %d: %d\n", si,
09701 *(SQLUSMALLINT *) dp);
09702 fflush(d->trace);
09703 }
09704 break;
09705 case SQL_C_SHORT:
09706 case SQL_C_SSHORT:
09707 sqlite3_bind_int(stmt, si, *(SQLSMALLINT *) dp);
09708 if (d->trace) {
09709 fprintf(d->trace, "-- parameter %d: %d\n", si,
09710 *(SQLSMALLINT *) dp);
09711 fflush(d->trace);
09712 }
09713 break;
09714 case SQL_C_ULONG:
09715 sqlite3_bind_int(stmt, si, *(SQLUINTEGER *) dp);
09716 if (d->trace) {
09717 fprintf(d->trace, "-- parameter %d: %ld\n", si,
09718 (long) *(SQLUINTEGER *) dp);
09719 fflush(d->trace);
09720 }
09721 break;
09722 case SQL_C_LONG:
09723 case SQL_C_SLONG:
09724 sqlite3_bind_int(stmt, si, *(SQLINTEGER *) dp);
09725 if (d->trace) {
09726 fprintf(d->trace, "-- parameter %d: %ld\n", si,
09727 (long) *(SQLINTEGER *) dp);
09728 fflush(d->trace);
09729 }
09730 break;
09731 #ifdef SQL_BIGINT
09732 case SQL_C_UBIGINT:
09733 case SQL_C_SBIGINT:
09734 sqlite3_bind_int64(stmt, si, *(SQLBIGINT *) dp);
09735 if (d->trace) {
09736 fprintf(d->trace,
09737 #ifdef _WIN32
09738 "-- parameter %d: %I64d\n",
09739 #else
09740 "-- parameter %d: %lld\n",
09741 #endif
09742 si, (sqlite_int64) *(SQLBIGINT *) dp);
09743 fflush(d->trace);
09744 }
09745 break;
09746 #endif
09747 case SQL_C_FLOAT:
09748 sqlite3_bind_double(stmt, si, *(float *) dp);
09749 if (d->trace) {
09750 fprintf(d->trace, "-- parameter %d: %g\n", si,
09751 *(float *) dp);
09752 fflush(d->trace);
09753 }
09754 break;
09755 case SQL_C_DOUBLE:
09756 sqlite3_bind_double(stmt, si, *(double *) dp);
09757 if (d->trace) {
09758 fprintf(d->trace, "-- parameter %d: %g\n", si,
09759 *(double *) dp);
09760 fflush(d->trace);
09761 }
09762 break;
09763 case SQL_C_BINARY:
09764 sqlite3_bind_blob(stmt, si, (char *) dp, *lp, SQLITE_STATIC);
09765 if (d->trace) {
09766 fprintf(d->trace, "-- parameter %d: [BLOB]\n", si);
09767 fflush(d->trace);
09768 }
09769 break;
09770 #ifdef WCHARSUPPORT
09771 case SQL_C_WCHAR:
09772 cp = uc_to_utf((SQLWCHAR *) dp, *lp);
09773 if (!cp) {
09774 return nomem(s);
09775 }
09776 sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
09777 if (d->trace) {
09778 fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
09779 fflush(d->trace);
09780 }
09781 uc_free(cp);
09782 break;
09783 #endif
09784 case SQL_C_CHAR:
09785 #if defined(_WIN32) || defined(_WIN64)
09786 if (*s->oemcp) {
09787 cp = wmb_to_utf((char *) dp, *lp);
09788 if (!cp) {
09789 return nomem(s);
09790 }
09791 sqlite3_bind_text(stmt, si, cp, -1, SQLITE_TRANSIENT);
09792 if (d->trace) {
09793 fprintf(d->trace, "-- parameter %d: '%s'\n", si, cp);
09794 fflush(d->trace);
09795 }
09796 uc_free(cp);
09797 } else
09798 #endif
09799 {
09800 if (*lp == SQL_NTS) {
09801 sqlite3_bind_text(stmt, si, (char *) dp, -1,
09802 SQLITE_STATIC);
09803 if (d->trace) {
09804 fprintf(d->trace, "-- parameter %d: '%s'\n", si,
09805 (char *) dp);
09806 fflush(d->trace);
09807 }
09808 } else {
09809 sqlite3_bind_text(stmt, si, (char *) dp, *lp,
09810 SQLITE_STATIC);
09811 if (d->trace) {
09812 fprintf(d->trace, "-- parameter %d: '%*s'\n", si,
09813 (int) *lp, (char *) dp);
09814 fflush(d->trace);
09815 }
09816 }
09817 }
09818 break;
09819 #ifdef SQL_C_TYPE_DATE
09820 case SQL_C_TYPE_DATE:
09821 #endif
09822 case SQL_C_DATE:
09823 if (*s->jdconv) {
09824 int a, b, x1, x2, y, m, dd;
09825 double v;
09826
09827 y = ((DATE_STRUCT *) dp)->year;
09828 m = ((DATE_STRUCT *) dp)->month;
09829 dd = ((DATE_STRUCT *) dp)->day;
09830 if (m <= 2) {
09831 y--;
09832 m += 12;
09833 }
09834 a = y / 100;
09835 b = 2 - a + (a / 4);
09836 x1 = 36525 * (y + 4716) / 100;
09837 x2 = 306001 * (m + 1) / 10000;
09838 v = x1 + x2 + dd + b - 1524.5;
09839 sqlite3_bind_double(stmt, si, v);
09840 if (d->trace) {
09841 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
09842 fflush(d->trace);
09843 }
09844 } else {
09845 sprintf(strbuf, "%04d-%02d-%02d",
09846 ((DATE_STRUCT *) dp)->year,
09847 ((DATE_STRUCT *) dp)->month,
09848 ((DATE_STRUCT *) dp)->day);
09849 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
09850 if (d->trace) {
09851 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
09852 fflush(d->trace);
09853 }
09854 }
09855 break;
09856 #ifdef SQL_C_TYPE_TIME
09857 case SQL_C_TYPE_TIME:
09858 #endif
09859 case SQL_C_TIME:
09860 if (*s->jdconv) {
09861 double v;
09862
09863 v = 2451544.5 +
09864 (((TIME_STRUCT *) dp)->hour * 3600000.0 +
09865 ((TIME_STRUCT *) dp)->minute * 60000.0 +
09866 ((TIME_STRUCT *) dp)->second * 1000.0) / 86400000.0;
09867 sqlite3_bind_double(stmt, si, v);
09868 if (d->trace) {
09869 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
09870 fflush(d->trace);
09871 }
09872 } else {
09873 sprintf(strbuf, "%02d:%02d:%02d",
09874 ((TIME_STRUCT *) dp)->hour,
09875 ((TIME_STRUCT *) dp)->minute,
09876 ((TIME_STRUCT *) dp)->second);
09877 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
09878 if (d->trace) {
09879 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
09880 fflush(d->trace);
09881 }
09882 }
09883 break;
09884 #ifdef SQL_C_TYPE_TIMESTAMP
09885 case SQL_C_TYPE_TIMESTAMP:
09886 #endif
09887 case SQL_C_TIMESTAMP:
09888 if (*s->jdconv) {
09889 int a, b, x1, x2, y, m, dd;
09890 double v;
09891
09892 y = ((TIMESTAMP_STRUCT *) dp)->year;
09893 m = ((TIMESTAMP_STRUCT *) dp)->month;
09894 dd = ((TIMESTAMP_STRUCT *) dp)->day;
09895 if (m <= 2) {
09896 y--;
09897 m += 12;
09898 }
09899 a = y / 100;
09900 b = 2 - a + (a / 4);
09901 x1 = 36525 * (y + 4716) / 100;
09902 x2 = 306001 * (m + 1) / 10000;
09903 v = x1 + x2 + dd + b - 1524.5 +
09904 (((TIMESTAMP_STRUCT *) dp)->hour * 3600000.0 +
09905 ((TIMESTAMP_STRUCT *) dp)->minute * 60000.0 +
09906 ((TIMESTAMP_STRUCT *) dp)->second * 1000.0 +
09907 ((TIMESTAMP_STRUCT *) dp)->fraction / 1.0E6)
09908 / 86400000.0;
09909 sqlite3_bind_double(stmt, si, v);
09910 if (d->trace) {
09911 fprintf(d->trace, "-- parameter %d: %g\n", si, v);
09912 fflush(d->trace);
09913 }
09914 } else {
09915 int frac;
09916
09917 frac = (int) ((TIMESTAMP_STRUCT *) dp)->fraction;
09918 frac /= 1000000;
09919 frac = frac % 1000;
09920 if (frac < 0) {
09921 frac = 0;
09922 }
09923 if (c->prec && c->prec <= 16) {
09924 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:00.000",
09925 ((TIMESTAMP_STRUCT *) dp)->year,
09926 ((TIMESTAMP_STRUCT *) dp)->month,
09927 ((TIMESTAMP_STRUCT *) dp)->day,
09928 ((TIMESTAMP_STRUCT *) dp)->hour,
09929 ((TIMESTAMP_STRUCT *) dp)->minute);
09930 } else if (c->prec && c->prec <= 19) {
09931 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.000",
09932 ((TIMESTAMP_STRUCT *) dp)->year,
09933 ((TIMESTAMP_STRUCT *) dp)->month,
09934 ((TIMESTAMP_STRUCT *) dp)->day,
09935 ((TIMESTAMP_STRUCT *) dp)->hour,
09936 ((TIMESTAMP_STRUCT *) dp)->minute,
09937 ((TIMESTAMP_STRUCT *) dp)->second);
09938 } else {
09939 sprintf(strbuf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
09940 ((TIMESTAMP_STRUCT *) dp)->year,
09941 ((TIMESTAMP_STRUCT *) dp)->month,
09942 ((TIMESTAMP_STRUCT *) dp)->day,
09943 ((TIMESTAMP_STRUCT *) dp)->hour,
09944 ((TIMESTAMP_STRUCT *) dp)->minute,
09945 ((TIMESTAMP_STRUCT *) dp)->second,
09946 frac);
09947 }
09948 sqlite3_bind_text(stmt, si, strbuf, -1, SQLITE_TRANSIENT);
09949 if (d->trace) {
09950 fprintf(d->trace, "-- parameter %d: '%s'\n", si, strbuf);
09951 fflush(d->trace);
09952 }
09953 }
09954 break;
09955 default:
09956 setstat(s, -1, "unsupported column type in positional update",
09957 (*s->ov3) ? "HY000" : "S1000");
09958 return SQL_ERROR;
09959 }
09960 return SQL_SUCCESS;
09961 }
09962
09974 static SQLRETURN
09975 setposibind(STMT *s, sqlite3_stmt *stmt, int i, int si, int rsi)
09976 {
09977 DBC *d = (DBC *) s->dbc;
09978 char **data;
09979 int pos;
09980
09981 pos = s->rowprs;
09982 if (pos < 0) {
09983 setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
09984 return SQL_ERROR;
09985 }
09986 pos += rsi;
09987 data = s->rows + s->ncols + (pos * s->ncols) + i;
09988 if (*data == NULL) {
09989 sqlite3_bind_null(stmt, si);
09990 if (d->trace) {
09991 fprintf(d->trace, "-- parameter %d: NULL\n", si);
09992 fflush(d->trace);
09993 }
09994 } else {
09995 sqlite3_bind_text(stmt, si, *data, -1, SQLITE_STATIC);
09996 if (d->trace) {
09997 fprintf(d->trace, "-- parameter %d: '%s'\n", si, *data);
09998 fflush(d->trace);
09999 }
10000 }
10001 return SQL_SUCCESS;
10002 }
10003
10011 static SQLRETURN
10012 setposrefr(STMT *s, int rsi)
10013 {
10014 int i, withinfo = 0;
10015 SQLRETURN ret = SQL_SUCCESS;
10016
10017 for (i = 0; s->bindcols && i < s->ncols; i++) {
10018 BINDCOL *b = &s->bindcols[i];
10019 SQLPOINTER dp = 0;
10020 SQLLEN *lp = 0;
10021
10022 b->offs = 0;
10023 if (b->valp) {
10024 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10025 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
10026 } else {
10027 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
10028 }
10029 if (s->bind_offs) {
10030 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
10031 }
10032 }
10033 if (b->lenp) {
10034 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10035 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
10036 } else {
10037 lp = b->lenp + rsi;
10038 }
10039 if (s->bind_offs) {
10040 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
10041 }
10042 }
10043 if (dp || lp) {
10044 int rowp = s->rowp;
10045
10046 s->rowp = s->rowprs + rsi;
10047 ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp,
10048 b->max, lp, 0);
10049 s->rowp = rowp;
10050 if (!SQL_SUCCEEDED(ret)) {
10051 s->row_status0[rsi] = SQL_ROW_ERROR;
10052 break;
10053 }
10054 if (ret != SQL_SUCCESS) {
10055 withinfo = 1;
10056 #ifdef SQL_ROW_SUCCESS_WITH_INFO
10057 s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
10058 #endif
10059 }
10060 }
10061 }
10062 if (SQL_SUCCEEDED(ret)) {
10063 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
10064 }
10065 return ret;
10066 }
10067
10077 static SQLRETURN
10078 drvsetpos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10079 {
10080 STMT *s = (STMT *) stmt;
10081 DBC *d = (DBC *) s->dbc;
10082 int rowp, i, k, rc, nretry = 0;
10083 dstr *sql = 0;
10084 const char *endp;
10085 sqlite3_stmt *s3stmt = NULL;
10086 SQLRETURN ret;
10087
10088 if (lock != SQL_LOCK_NO_CHANGE) {
10089 setstat(s, -1, "unsupported locking mode",
10090 (*s->ov3) ? "HY000" : "S1000");
10091 return SQL_ERROR;
10092 }
10093 if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10094 setstat(s, -1, "incompatible statement",
10095 (*s->ov3) ? "HY000" : "S1000");
10096 return SQL_ERROR;
10097 }
10098 if (op == SQL_ADD) {
10099 if (s->one_tbl <= 0) {
10100 setstat(s, -1, "incompatible rowset",
10101 (*s->ov3) ? "HY000" : "S1000");
10102 return SQL_ERROR;
10103 }
10104 if (row == 0 || row > s->rowset_size + 1) {
10105 goto rowoor;
10106 }
10107 ret = chkunbound(s);
10108 if (ret != SQL_SUCCESS) {
10109 return ret;
10110 }
10111 sql = dsappend(sql, "INSERT INTO ");
10112 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10113 sql = dsappendq(sql, s->dyncols[0].db);
10114 sql = dsappend(sql, ".");
10115 }
10116 sql = dsappendq(sql, s->dyncols[0].table);
10117 for (i = 0; i < s->ncols; i++) {
10118 sql = dsappend(sql, (i > 0) ? "," : "(");
10119 sql = dsappendq(sql, s->dyncols[i].column);
10120 }
10121 sql = dsappend(sql, ") VALUES ");
10122 for (i = 0; i < s->ncols; i++) {
10123 sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10124 }
10125 sql = dsappend(sql, ")");
10126 if (dserr(sql)) {
10127 dsfree(sql);
10128 return nomem(s);
10129 }
10130 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10131 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10132 #else
10133 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10134 #endif
10135 do {
10136 s3stmt = NULL;
10137 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10138 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10139 &s3stmt, &endp);
10140 #else
10141 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10142 &s3stmt, &endp);
10143 #endif
10144 if (rc != SQLITE_OK) {
10145 if (s3stmt) {
10146 sqlite3_finalize(s3stmt);
10147 s3stmt = NULL;
10148 }
10149 }
10150 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10151 dbtracerc(d, rc, NULL);
10152 dsfree(sql);
10153 if (rc != SQLITE_OK) {
10154 istmterr:
10155 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10156 sqlite3_errmsg(d->sqlite), rc);
10157 if (s3stmt) {
10158 dbtraceapi(d, "sqlite3_finalize", NULL);
10159 sqlite3_finalize(s3stmt);
10160 }
10161 return SQL_ERROR;
10162 }
10163 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10164 ret = setposbind(s, s3stmt, i, k, row - 1);
10165 if (ret != SQL_SUCCESS) {
10166 dbtraceapi(d, "sqlite3_finalize", NULL);
10167 sqlite3_finalize(s3stmt);
10168 return ret;
10169 }
10170 k++;
10171 }
10172 rc = sqlite3_step(s3stmt);
10173 if (rc != SQLITE_DONE) {
10174 goto istmterr;
10175 }
10176 sqlite3_finalize(s3stmt);
10177 if (sqlite3_changes(d->sqlite) > 0 && row <= s->rowset_size) {
10178 if (s->row_status0) {
10179 s->row_status0[row - 1] = SQL_ROW_ADDED;
10180 }
10181 if (s->row_status) {
10182 s->row_status[row - 1] = SQL_ROW_ADDED;
10183 }
10184 }
10185 return SQL_SUCCESS;
10186 } else if (op == SQL_UPDATE || op == SQL_DELETE) {
10187 if (s->one_tbl <= 0 || s->has_pk <= 0) {
10188 setstat(s, -1, "incompatible rowset",
10189 (*s->ov3) ? "HY000" : "S1000");
10190 return SQL_ERROR;
10191 }
10192 if (row == 0) {
10193 ret = SQL_SUCCESS;
10194 for (i = 1; i <= s->rowset_size; i++) {
10195 ret = drvsetpos(stmt, i, op, lock);
10196 if (!SQL_SUCCEEDED(ret)) {
10197 break;
10198 }
10199 }
10200 return ret;
10201 }
10202 if (row > s->rowset_size) {
10203 goto rowoor;
10204 }
10205 }
10206 if (op != SQL_POSITION && op != SQL_REFRESH &&
10207 op != SQL_DELETE && op != SQL_UPDATE) {
10208 return drvunimplstmt(stmt);
10209 }
10210 if (op == SQL_POSITION) {
10211 rowp = s->rowp + row - 1;
10212 if (!s->rows || row == 0 || rowp < -1 || rowp >= s->nrows) {
10213 rowoor:
10214 setstat(s, -1, "row out of range", (*s->ov3) ? "HY107" : "S1107");
10215 return SQL_ERROR;
10216 }
10217 s->rowp = rowp;
10218 } else if (op == SQL_REFRESH) {
10219 if (row > s->rowset_size) {
10220 goto rowoor;
10221 }
10222 if (row == 0) {
10223 ret = SQL_SUCCESS;
10224 for (i = 0; i < s->rowset_size; i++) {
10225 ret = setposrefr(s, i);
10226 if (!SQL_SUCCEEDED(ret)) {
10227 break;
10228 }
10229 }
10230 return ret;
10231 }
10232 return setposrefr(s, row - 1);
10233 } else if (op == SQL_DELETE) {
10234 sql = dsappend(sql, "DELETE FROM ");
10235 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10236 sql = dsappendq(sql, s->dyncols[0].db);
10237 sql = dsappend(sql, ".");
10238 }
10239 sql = dsappendq(sql, s->dyncols[0].table);
10240 for (i = k = 0; i < s->ncols; i++) {
10241 if (s->dyncols[i].ispk <= 0) {
10242 continue;
10243 }
10244 sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10245 sql = dsappendq(sql, s->dyncols[i].column);
10246 sql = dsappend(sql, " = ?");
10247 k++;
10248 }
10249 if (dserr(sql)) {
10250 dsfree(sql);
10251 return nomem(s);
10252 }
10253 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10254 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10255 #else
10256 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10257 #endif
10258 do {
10259 s3stmt = NULL;
10260 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10261 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10262 &s3stmt, &endp);
10263 #else
10264 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10265 &s3stmt, &endp);
10266 #endif
10267 if (rc != SQLITE_OK) {
10268 if (s3stmt) {
10269 sqlite3_finalize(s3stmt);
10270 s3stmt = NULL;
10271 }
10272 }
10273 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10274 dbtracerc(d, rc, NULL);
10275 dsfree(sql);
10276 if (rc != SQLITE_OK) {
10277 dstmterr:
10278 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10279 sqlite3_errmsg(d->sqlite), rc);
10280 if (s3stmt) {
10281 dbtraceapi(d, "sqlite3_finalize", NULL);
10282 sqlite3_finalize(s3stmt);
10283 }
10284 return SQL_ERROR;
10285 }
10286 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10287 if (s->dyncols[i].ispk <= 0) {
10288 continue;
10289 }
10290 ret = setposibind(s, s3stmt, i, k, row - 1);
10291 if (ret != SQL_SUCCESS) {
10292 dbtraceapi(d, "sqlite3_finalize", NULL);
10293 sqlite3_finalize(s3stmt);
10294 return ret;
10295 }
10296 k++;
10297 }
10298 rc = sqlite3_step(s3stmt);
10299 if (rc != SQLITE_DONE) {
10300 goto dstmterr;
10301 }
10302 sqlite3_finalize(s3stmt);
10303 if (sqlite3_changes(d->sqlite) > 0) {
10304 if (s->row_status0) {
10305 s->row_status0[row - 1] = SQL_ROW_DELETED;
10306 }
10307 if (s->row_status) {
10308 s->row_status[row - 1] = SQL_ROW_DELETED;
10309 }
10310 }
10311 return SQL_SUCCESS;
10312 } else if (op == SQL_UPDATE) {
10313 ret = chkunbound(s);
10314 if (ret != SQL_SUCCESS) {
10315 return ret;
10316 }
10317 sql = dsappend(sql, "UPDATE ");
10318 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10319 sql = dsappendq(sql, s->dyncols[0].db);
10320 sql = dsappend(sql, ".");
10321 }
10322 sql = dsappendq(sql, s->dyncols[0].table);
10323 for (i = 0; i < s->ncols; i++) {
10324 sql = dsappend(sql, (i > 0) ? ", " : " SET ");
10325 sql = dsappendq(sql, s->dyncols[i].column);
10326 sql = dsappend(sql, " = ?");
10327 }
10328 for (i = k = 0; i < s->ncols; i++) {
10329 if (s->dyncols[i].ispk <= 0) {
10330 continue;
10331 }
10332 sql = dsappend(sql, (k > 0) ? " AND " : " WHERE ");
10333 sql = dsappendq(sql, s->dyncols[i].column);
10334 sql = dsappend(sql, " = ?");
10335 k++;
10336 }
10337 if (dserr(sql)) {
10338 dsfree(sql);
10339 return nomem(s);
10340 }
10341 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10342 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10343 #else
10344 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10345 #endif
10346 do {
10347 s3stmt = NULL;
10348 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10349 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10350 &s3stmt, &endp);
10351 #else
10352 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10353 &s3stmt, &endp);
10354 #endif
10355 if (rc != SQLITE_OK) {
10356 if (s3stmt) {
10357 sqlite3_finalize(s3stmt);
10358 s3stmt = NULL;
10359 }
10360 }
10361 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10362 dbtracerc(d, rc, NULL);
10363 dsfree(sql);
10364 if (rc != SQLITE_OK) {
10365 ustmterr:
10366 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10367 sqlite3_errmsg(d->sqlite), rc);
10368 if (s3stmt) {
10369 dbtraceapi(d, "sqlite3_finalize", NULL);
10370 sqlite3_finalize(s3stmt);
10371 }
10372 return SQL_ERROR;
10373 }
10374 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10375 ret = setposbind(s, s3stmt, i, k, row - 1);
10376 if (ret != SQL_SUCCESS) {
10377 dbtraceapi(d, "sqlite3_finalize", NULL);
10378 sqlite3_finalize(s3stmt);
10379 return ret;
10380 }
10381 k++;
10382 }
10383 for (i = 0; s->bindcols && i < s->ncols; i++) {
10384 if (s->dyncols[i].ispk <= 0) {
10385 continue;
10386 }
10387 ret = setposibind(s, s3stmt, i, k, row - 1);
10388 if (ret != SQL_SUCCESS) {
10389 dbtraceapi(d, "sqlite3_finalize", NULL);
10390 sqlite3_finalize(s3stmt);
10391 return ret;
10392 }
10393 k++;
10394 }
10395 rc = sqlite3_step(s3stmt);
10396 if (rc != SQLITE_DONE) {
10397 goto ustmterr;
10398 }
10399 sqlite3_finalize(s3stmt);
10400 if (sqlite3_changes(d->sqlite) > 0) {
10401 if (s->row_status0) {
10402 s->row_status0[row - 1] = SQL_ROW_UPDATED;
10403 }
10404 if (s->row_status) {
10405 s->row_status[row - 1] = SQL_ROW_UPDATED;
10406 }
10407 }
10408 return SQL_SUCCESS;
10409 }
10410 return SQL_SUCCESS;
10411 }
10412
10422 SQLRETURN SQL_API
10423 SQLSetPos(SQLHSTMT stmt, SQLSETPOSIROW row, SQLUSMALLINT op, SQLUSMALLINT lock)
10424 {
10425 SQLRETURN ret;
10426
10427 HSTMT_LOCK(stmt);
10428 ret = drvsetpos(stmt, row, op, lock);
10429 HSTMT_UNLOCK(stmt);
10430 return ret;
10431 }
10432
10440 static SQLRETURN
10441 drvbulkoperations(SQLHSTMT stmt, SQLSMALLINT op)
10442 {
10443 STMT *s = (STMT *) stmt;
10444 DBC *d = (DBC *) s->dbc;
10445 int row, i, k, rc, nretry = 0;
10446 dstr *sql = 0;
10447 const char *endp;
10448 sqlite3_stmt *s3stmt = NULL;
10449 SQLRETURN ret;
10450
10451 if (s->isselect != 1 || s->curtype != SQL_CURSOR_STATIC) {
10452 setstat(s, -1, "incompatible statement",
10453 (*s->ov3) ? "HY000" : "S1000");
10454 return SQL_ERROR;
10455 }
10456 if (op == SQL_ADD) {
10457 if (s->one_tbl <= 0) {
10458 setstat(s, -1, "incompatible rowset",
10459 (*s->ov3) ? "HY000" : "S1000");
10460 return SQL_ERROR;
10461 }
10462 ret = chkunbound(s);
10463 if (ret != SQL_SUCCESS) {
10464 return ret;
10465 }
10466 sql = dsappend(sql, "INSERT INTO ");
10467 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10468 sql = dsappendq(sql, s->dyncols[0].db);
10469 sql = dsappend(sql, ".");
10470 }
10471 sql = dsappendq(sql, s->dyncols[0].table);
10472 for (i = 0; i < s->ncols; i++) {
10473 sql = dsappend(sql, (i > 0) ? "," : "(");
10474 sql = dsappendq(sql, s->dyncols[i].column);
10475 }
10476 sql = dsappend(sql, ") VALUES ");
10477 for (i = 0; i < s->ncols; i++) {
10478 sql = dsappend(sql, (i > 0) ? ",?" : "(?");
10479 }
10480 sql = dsappend(sql, ")");
10481 if (dserr(sql)) {
10482 dsfree(sql);
10483 return nomem(s);
10484 }
10485 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10486 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10487 #else
10488 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10489 #endif
10490 do {
10491 s3stmt = NULL;
10492 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10493 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10494 &s3stmt, &endp);
10495 #else
10496 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10497 &s3stmt, &endp);
10498 #endif
10499 if (rc != SQLITE_OK) {
10500 if (s3stmt) {
10501 sqlite3_finalize(s3stmt);
10502 s3stmt = NULL;
10503 }
10504 }
10505 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10506 dbtracerc(d, rc, NULL);
10507 dsfree(sql);
10508 if (rc != SQLITE_OK) {
10509 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10510 sqlite3_errmsg(d->sqlite), rc);
10511 if (s3stmt) {
10512 dbtraceapi(d, "sqlite3_finalize", NULL);
10513 sqlite3_finalize(s3stmt);
10514 }
10515 return SQL_ERROR;
10516 }
10517 for (row = 0; row < s->rowset_size; row++) {
10518 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10519 ret = setposbind(s, s3stmt, i, k, row);
10520 if (ret != SQL_SUCCESS) {
10521 istmterr:
10522 if (s->row_status0) {
10523 s->row_status0[row] = SQL_ROW_ERROR;
10524 }
10525 if (s->row_status) {
10526 s->row_status[row] = SQL_ROW_ERROR;
10527 }
10528 dbtraceapi(d, "sqlite3_finalize", NULL);
10529 sqlite3_finalize(s3stmt);
10530 return ret;
10531 }
10532 k++;
10533 }
10534 rc = sqlite3_step(s3stmt);
10535 if (rc != SQLITE_DONE) {
10536 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10537 sqlite3_errmsg(d->sqlite), rc);
10538 ret = SQL_ERROR;
10539 goto istmterr;
10540 }
10541 if (sqlite3_changes(d->sqlite) > 0) {
10542 if (s->row_status0) {
10543 s->row_status0[row] = SQL_ROW_ADDED;
10544 }
10545 if (s->row_status) {
10546 s->row_status[row] = SQL_ROW_ADDED;
10547 }
10548 }
10549 if (s->bkmrk == SQL_UB_VARIABLE &&
10550 s->bkmrkcol.type == SQL_C_VARBOOKMARK &&
10551 s->bkmrkcol.valp) {
10552 SQLPOINTER *val;
10553
10554 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10555 val = (SQLPOINTER)
10556 ((char *) s->bkmrkcol.valp + s->bind_type * row);
10557 } else {
10558 val = (SQLPOINTER)
10559 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10560 }
10561 if (s->bind_offs) {
10562 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10563 }
10564 *(sqlite_int64 *) val = sqlite3_last_insert_rowid(d->sqlite);
10565 if (s->bkmrkcol.lenp) {
10566 SQLLEN *ival;
10567
10568 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10569 ival = (SQLLEN *)
10570 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10571 } else {
10572 ival = &s->bkmrkcol.lenp[row];
10573 }
10574 if (s->bind_offs) {
10575 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10576 }
10577 *ival = sizeof (sqlite_int64);
10578 }
10579 }
10580 dbtraceapi(d, "sqlite3_reset", NULL);
10581 sqlite3_reset(s3stmt);
10582 }
10583 dbtraceapi(d, "sqlite3_finalize", NULL);
10584 sqlite3_finalize(s3stmt);
10585 return SQL_SUCCESS;
10586 } else if (op == SQL_DELETE_BY_BOOKMARK) {
10587 if (s->has_rowid < 0 ||
10588 s->bkmrk != SQL_UB_VARIABLE ||
10589 s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10590 !s->bkmrkcol.valp) {
10591 setstat(s, -1, "incompatible rowset",
10592 (*s->ov3) ? "HY000" : "S1000");
10593 return SQL_ERROR;
10594 }
10595 sql = dsappend(sql, "DELETE FROM ");
10596 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10597 sql = dsappendq(sql, s->dyncols[0].db);
10598 sql = dsappend(sql, ".");
10599 }
10600 sql = dsappendq(sql, s->dyncols[0].table);
10601 sql = dsappend(sql, " WHERE ");
10602 sql = dsappendq(sql, s->dyncols[0].column);
10603 sql = dsappend(sql, " = ?");
10604 if (dserr(sql)) {
10605 dsfree(sql);
10606 return nomem(s);
10607 }
10608 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10609 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10610 #else
10611 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10612 #endif
10613 do {
10614 s3stmt = NULL;
10615 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10616 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10617 &s3stmt, &endp);
10618 #else
10619 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10620 &s3stmt, &endp);
10621 #endif
10622 if (rc != SQLITE_OK) {
10623 if (s3stmt) {
10624 sqlite3_finalize(s3stmt);
10625 s3stmt = NULL;
10626 }
10627 }
10628 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10629 dbtracerc(d, rc, NULL);
10630 dsfree(sql);
10631 if (rc != SQLITE_OK) {
10632 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10633 sqlite3_errmsg(d->sqlite), rc);
10634 if (s3stmt) {
10635 dbtraceapi(d, "sqlite3_finalize", NULL);
10636 sqlite3_finalize(s3stmt);
10637 }
10638 return SQL_ERROR;
10639 }
10640 for (row = 0; row < s->rowset_size; row++) {
10641 SQLPOINTER *val;
10642 sqlite_int64 rowid;
10643
10644 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10645 val = (SQLPOINTER)
10646 ((char *) s->bkmrkcol.valp + s->bind_type * row);
10647 } else {
10648 val = (SQLPOINTER)
10649 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10650 }
10651 if (s->bind_offs) {
10652 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10653 }
10654 if (s->bkmrkcol.lenp) {
10655 SQLLEN *ival;
10656
10657 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10658 ival = (SQLLEN *)
10659 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10660 } else {
10661 ival = &s->bkmrkcol.lenp[row];
10662 }
10663 if (s->bind_offs) {
10664 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10665 }
10666 if (*ival != sizeof (sqlite_int64)) {
10667 continue;
10668 }
10669 }
10670 rowid = *(sqlite_int64 *) val;
10671 sqlite3_bind_int64(s3stmt, 1, rowid);
10672 if (d->trace) {
10673 fprintf(d->trace,
10674 #ifdef _WIN32
10675 "-- parameter 1: %I64d\n",
10676 #else
10677 "-- parameter 1: %lld\n",
10678 #endif
10679 rowid);
10680 fflush(d->trace);
10681 }
10682 rc = sqlite3_step(s3stmt);
10683 if (rc != SQLITE_DONE) {
10684 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10685 sqlite3_errmsg(d->sqlite), rc);
10686 if (s->row_status0) {
10687 s->row_status0[row] = SQL_ROW_ERROR;
10688 }
10689 if (s->row_status) {
10690 s->row_status[row] = SQL_ROW_ERROR;
10691 }
10692 dbtraceapi(d, "sqlite3_finalize", NULL);
10693 sqlite3_finalize(s3stmt);
10694 return SQL_ERROR;
10695 }
10696 if (sqlite3_changes(d->sqlite) > 0) {
10697 if (s->row_status0) {
10698 s->row_status0[row] = SQL_ROW_DELETED;
10699 }
10700 if (s->row_status) {
10701 s->row_status[row] = SQL_ROW_DELETED;
10702 }
10703 }
10704 dbtraceapi(d, "sqlite3_reset", NULL);
10705 sqlite3_reset(s3stmt);
10706 }
10707 dbtraceapi(d, "sqlite3_finalize", NULL);
10708 sqlite3_finalize(s3stmt);
10709 return SQL_SUCCESS;
10710 } else if (op == SQL_UPDATE_BY_BOOKMARK) {
10711 if (s->has_rowid < 0 ||
10712 s->bkmrk != SQL_UB_VARIABLE ||
10713 s->bkmrkcol.type != SQL_C_VARBOOKMARK ||
10714 !s->bkmrkcol.valp) {
10715 setstat(s, -1, "incompatible rowset",
10716 (*s->ov3) ? "HY000" : "S1000");
10717 return SQL_ERROR;
10718 }
10719 ret = chkunbound(s);
10720 if (ret != SQL_SUCCESS) {
10721 return ret;
10722 }
10723 sql = dsappend(sql, "UPDATE ");
10724 if (s->dyncols[0].db && s->dyncols[0].db[0]) {
10725 sql = dsappendq(sql, s->dyncols[0].db);
10726 sql = dsappend(sql, ".");
10727 }
10728 sql = dsappendq(sql, s->dyncols[0].table);
10729 for (i = 0, k = 0; i < s->ncols; i++) {
10730 if (i == s->has_rowid) {
10731 continue;
10732 }
10733 sql = dsappend(sql, (k > 0) ? ", " : " SET ");
10734 sql = dsappendq(sql, s->dyncols[i].column);
10735 sql = dsappend(sql, " = ?");
10736 k++;
10737 }
10738 sql = dsappend(sql, " WHERE ");
10739 sql = dsappendq(sql, s->dyncols[s->has_rowid].column);
10740 sql = dsappend(sql, " = ?");
10741 if (dserr(sql)) {
10742 dsfree(sql);
10743 return nomem(s);
10744 }
10745 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10746 dbtraceapi(d, "sqlite3_prepare_v2", dsval(sql));
10747 #else
10748 dbtraceapi(d, "sqlite3_prepare", dsval(sql));
10749 #endif
10750 do {
10751 s3stmt = NULL;
10752 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
10753 rc = sqlite3_prepare_v2(d->sqlite, dsval(sql), -1,
10754 &s3stmt, &endp);
10755 #else
10756 rc = sqlite3_prepare(d->sqlite, dsval(sql), -1,
10757 &s3stmt, &endp);
10758 #endif
10759 if (rc != SQLITE_OK) {
10760 if (s3stmt) {
10761 sqlite3_finalize(s3stmt);
10762 s3stmt = NULL;
10763 }
10764 }
10765 } while (rc == SQLITE_SCHEMA && (++nretry) < 2);
10766 dbtracerc(d, rc, NULL);
10767 dsfree(sql);
10768 if (rc != SQLITE_OK) {
10769 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10770 sqlite3_errmsg(d->sqlite), rc);
10771 if (s3stmt) {
10772 dbtraceapi(d, "sqlite3_finalize", NULL);
10773 sqlite3_finalize(s3stmt);
10774 }
10775 return SQL_ERROR;
10776 }
10777 for (row = 0; row < s->rowset_size; row++) {
10778 SQLPOINTER *val;
10779 sqlite_int64 rowid;
10780
10781 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10782 val = (SQLPOINTER)
10783 ((char *) s->bkmrkcol.valp + s->bind_type * row);
10784 } else {
10785 val = (SQLPOINTER)
10786 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * row);
10787 }
10788 if (s->bind_offs) {
10789 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
10790 }
10791 if (s->bkmrkcol.lenp) {
10792 SQLLEN *ival;
10793
10794 if (s->bind_type != SQL_BIND_BY_COLUMN) {
10795 ival = (SQLLEN *)
10796 ((char *) s->bkmrkcol.lenp + s->bind_type * row);
10797 } else {
10798 ival = &s->bkmrkcol.lenp[row];
10799 }
10800 if (s->bind_offs) {
10801 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
10802 }
10803 if (*ival != sizeof (sqlite_int64)) {
10804 continue;
10805 }
10806 }
10807 for (i = 0, k = 1; s->bindcols && i < s->ncols; i++) {
10808 if (i == s->has_rowid) {
10809 continue;
10810 }
10811 ret = setposbind(s, s3stmt, i, k, row);
10812 if (ret != SQL_SUCCESS) {
10813 ustmterr:
10814 if (s->row_status0) {
10815 s->row_status0[row] = SQL_ROW_ERROR;
10816 }
10817 if (s->row_status) {
10818 s->row_status[row] = SQL_ROW_ERROR;
10819 }
10820 dbtraceapi(d, "sqlite3_finalize", NULL);
10821 sqlite3_finalize(s3stmt);
10822 return ret;
10823 }
10824 k++;
10825 }
10826 rowid = *(sqlite_int64 *) val;
10827 sqlite3_bind_int64(s3stmt, k, rowid);
10828 if (d->trace) {
10829 fprintf(d->trace,
10830 #ifdef _WIN32
10831 "-- parameter %d: %I64d\n",
10832 #else
10833 "-- parameter %d: %lld\n",
10834 #endif
10835 k, rowid);
10836 fflush(d->trace);
10837 }
10838 rc = sqlite3_step(s3stmt);
10839 if (rc != SQLITE_DONE) {
10840 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
10841 sqlite3_errmsg(d->sqlite), rc);
10842 ret = SQL_ERROR;
10843 goto ustmterr;
10844 }
10845 if (sqlite3_changes(d->sqlite) > 0) {
10846 if (s->row_status0) {
10847 s->row_status0[row] = SQL_ROW_UPDATED;
10848 }
10849 if (s->row_status) {
10850 s->row_status[row] = SQL_ROW_UPDATED;
10851 }
10852 }
10853 dbtraceapi(d, "sqlite3_reset", NULL);
10854 sqlite3_reset(s3stmt);
10855 }
10856 dbtraceapi(d, "sqlite3_finalize", NULL);
10857 sqlite3_finalize(s3stmt);
10858 return SQL_SUCCESS;
10859 }
10860 setstat(s, -1, "unsupported operation", (*s->ov3) ? "HY000" : "S1000");
10861 return SQL_ERROR;
10862 }
10863
10871 SQLRETURN SQL_API
10872 SQLBulkOperations(SQLHSTMT stmt, SQLSMALLINT oper)
10873 {
10874 SQLRETURN ret;
10875
10876 HSTMT_LOCK(stmt);
10877 ret = drvbulkoperations(stmt, oper);
10878 HSTMT_UNLOCK(stmt);
10879 return ret;
10880 }
10881
10882
10887 SQLRETURN SQL_API
10888 SQLSetScrollOptions(SQLHSTMT stmt, SQLUSMALLINT concur, SQLLEN rowkeyset,
10889 SQLUSMALLINT rowset)
10890 {
10891 SQLRETURN ret;
10892
10893 HSTMT_LOCK(stmt);
10894 ret = drvunimplstmt(stmt);
10895 HSTMT_UNLOCK(stmt);
10896 return ret;
10897 }
10898
10899 #define strmak(dst, src, max, lenp) { \
10900 int len = strlen(src); \
10901 int cnt = min(len + 1, max); \
10902 strncpy(dst, src, cnt); \
10903 *lenp = (cnt > len) ? len : cnt; \
10904 }
10905
10916 static SQLRETURN
10917 drvgetinfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
10918 SQLSMALLINT *valLen)
10919 {
10920 DBC *d;
10921 char dummyc[16];
10922 SQLSMALLINT dummy;
10923 #if defined(_WIN32) || defined(_WIN64)
10924 char pathbuf[301], *drvname;
10925 #else
10926 static char drvname[] = "sqlite3odbc.so";
10927 #endif
10928
10929 if (dbc == SQL_NULL_HDBC) {
10930 return SQL_INVALID_HANDLE;
10931 }
10932 d = (DBC *) dbc;
10933 if (valMax) {
10934 valMax--;
10935 }
10936 if (!valLen) {
10937 valLen = &dummy;
10938 }
10939 if (!val) {
10940 val = dummyc;
10941 valMax = sizeof (dummyc) - 1;
10942 }
10943 switch (type) {
10944 case SQL_MAX_USER_NAME_LEN:
10945 *((SQLSMALLINT *) val) = 16;
10946 *valLen = sizeof (SQLSMALLINT);
10947 break;
10948 case SQL_USER_NAME:
10949 strmak(val, "", valMax, valLen);
10950 break;
10951 case SQL_DRIVER_ODBC_VER:
10952 #if 0
10953 strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
10954 #else
10955 strmak(val, "03.00", valMax, valLen);
10956 #endif
10957 break;
10958 case SQL_ACTIVE_CONNECTIONS:
10959 case SQL_ACTIVE_STATEMENTS:
10960 *((SQLSMALLINT *) val) = 0;
10961 *valLen = sizeof (SQLSMALLINT);
10962 break;
10963 #ifdef SQL_ASYNC_MODE
10964 case SQL_ASYNC_MODE:
10965 *((SQLUINTEGER *) val) = SQL_AM_NONE;
10966 *valLen = sizeof (SQLUINTEGER);
10967 break;
10968 #endif
10969 #ifdef SQL_CREATE_TABLE
10970 case SQL_CREATE_TABLE:
10971 *((SQLUINTEGER *) val) = SQL_CT_CREATE_TABLE |
10972 SQL_CT_COLUMN_DEFAULT |
10973 SQL_CT_COLUMN_CONSTRAINT |
10974 SQL_CT_CONSTRAINT_NON_DEFERRABLE;
10975 *valLen = sizeof (SQLUINTEGER);
10976 break;
10977 #endif
10978 #ifdef SQL_CREATE_VIEW
10979 case SQL_CREATE_VIEW:
10980 *((SQLUINTEGER *) val) = SQL_CV_CREATE_VIEW;
10981 *valLen = sizeof (SQLUINTEGER);
10982 break;
10983 #endif
10984 #ifdef SQL_DDL_INDEX
10985 case SQL_DDL_INDEX:
10986 *((SQLUINTEGER *) val) = SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX;
10987 *valLen = sizeof (SQLUINTEGER);
10988 break;
10989 #endif
10990 #ifdef SQL_DROP_TABLE
10991 case SQL_DROP_TABLE:
10992 *((SQLUINTEGER *) val) = SQL_DT_DROP_TABLE;
10993 *valLen = sizeof (SQLUINTEGER);
10994 break;
10995 #endif
10996 #ifdef SQL_DROP_VIEW
10997 case SQL_DROP_VIEW:
10998 *((SQLUINTEGER *) val) = SQL_DV_DROP_VIEW;
10999 *valLen = sizeof (SQLUINTEGER);
11000 break;
11001 #endif
11002 #ifdef SQL_INDEX_KEYWORDS
11003 case SQL_INDEX_KEYWORDS:
11004 *((SQLUINTEGER *) val) = SQL_IK_ALL;
11005 *valLen = sizeof (SQLUINTEGER);
11006 break;
11007 #endif
11008 case SQL_DATA_SOURCE_NAME:
11009 strmak(val, d->dsn ? d->dsn : "", valMax, valLen);
11010 break;
11011 case SQL_DRIVER_NAME:
11012 #if defined(_WIN32) || defined(_WIN64)
11013 GetModuleFileName(hModule, pathbuf, sizeof (pathbuf));
11014 drvname = strrchr(pathbuf, '\\');
11015 if (drvname == NULL) {
11016 drvname = strrchr(pathbuf, '/');
11017 }
11018 if (drvname == NULL) {
11019 drvname = pathbuf;
11020 } else {
11021 drvname++;
11022 }
11023 #endif
11024 strmak(val, drvname, valMax, valLen);
11025 break;
11026 case SQL_DRIVER_VER:
11027 strmak(val, DRIVER_VER_INFO, valMax, valLen);
11028 break;
11029 case SQL_FETCH_DIRECTION:
11030 *((SQLUINTEGER *) val) = SQL_FD_FETCH_NEXT | SQL_FD_FETCH_FIRST |
11031 SQL_FD_FETCH_LAST | SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_ABSOLUTE;
11032 *valLen = sizeof (SQLUINTEGER);
11033 break;
11034 case SQL_ODBC_VER:
11035 strmak(val, (*d->ov3) ? "03.00" : "02.50", valMax, valLen);
11036 break;
11037 case SQL_ODBC_SAG_CLI_CONFORMANCE:
11038 *((SQLSMALLINT *) val) = SQL_OSCC_NOT_COMPLIANT;
11039 *valLen = sizeof (SQLSMALLINT);
11040 break;
11041 case SQL_STANDARD_CLI_CONFORMANCE:
11042 *((SQLUINTEGER *) val) = SQL_SCC_XOPEN_CLI_VERSION1;
11043 *valLen = sizeof (SQLUINTEGER);
11044 break;
11045 case SQL_SQL_CONFORMANCE:
11046 *((SQLUINTEGER *) val) = SQL_SC_SQL92_ENTRY;
11047 *valLen = sizeof (SQLUINTEGER);
11048 break;
11049 case SQL_SERVER_NAME:
11050 case SQL_DATABASE_NAME:
11051 strmak(val, d->dbname ? d->dbname : "", valMax, valLen);
11052 break;
11053 case SQL_SEARCH_PATTERN_ESCAPE:
11054 strmak(val, "\\", valMax, valLen);
11055 break;
11056 case SQL_ODBC_SQL_CONFORMANCE:
11057 *((SQLSMALLINT *) val) = SQL_OSC_MINIMUM;
11058 *valLen = sizeof (SQLSMALLINT);
11059 break;
11060 case SQL_ODBC_API_CONFORMANCE:
11061 *((SQLSMALLINT *) val) = SQL_OAC_LEVEL1;
11062 *valLen = sizeof (SQLSMALLINT);
11063 break;
11064 case SQL_DBMS_NAME:
11065 strmak(val, "SQLite", valMax, valLen);
11066 break;
11067 case SQL_DBMS_VER:
11068 strmak(val, SQLITE_VERSION, valMax, valLen);
11069 break;
11070 case SQL_COLUMN_ALIAS:
11071 case SQL_NEED_LONG_DATA_LEN:
11072 strmak(val, "Y", valMax, valLen);
11073 break;
11074 case SQL_ROW_UPDATES:
11075 case SQL_ACCESSIBLE_PROCEDURES:
11076 case SQL_PROCEDURES:
11077 case SQL_EXPRESSIONS_IN_ORDERBY:
11078 case SQL_ODBC_SQL_OPT_IEF:
11079 case SQL_LIKE_ESCAPE_CLAUSE:
11080 case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11081 case SQL_OUTER_JOINS:
11082 case SQL_ACCESSIBLE_TABLES:
11083 case SQL_MULT_RESULT_SETS:
11084 case SQL_MULTIPLE_ACTIVE_TXN:
11085 case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11086 strmak(val, "N", valMax, valLen);
11087 break;
11088 #ifdef SQL_CATALOG_NAME
11089 case SQL_CATALOG_NAME:
11090 #if defined(_WIN32) || defined(_WIN64)
11091 strmak(val, d->xcelqrx ? "Y" : "N", valMax, valLen);
11092 #else
11093 strmak(val, "N", valMax, valLen);
11094 #endif
11095 break;
11096 #endif
11097 case SQL_DATA_SOURCE_READ_ONLY:
11098 strmak(val, "N", valMax, valLen);
11099 break;
11100 #ifdef SQL_OJ_CAPABILITIES
11101 case SQL_OJ_CAPABILITIES:
11102 *((SQLUINTEGER *) val) = 0;
11103 *valLen = sizeof (SQLUINTEGER);
11104 break;
11105 #endif
11106 #ifdef SQL_MAX_IDENTIFIER_LEN
11107 case SQL_MAX_IDENTIFIER_LEN:
11108 *((SQLUSMALLINT *) val) = 255;
11109 *valLen = sizeof (SQLUSMALLINT);
11110 break;
11111 #endif
11112 case SQL_CONCAT_NULL_BEHAVIOR:
11113 *((SQLSMALLINT *) val) = SQL_CB_NULL;
11114 *valLen = sizeof (SQLSMALLINT);
11115 break;
11116 case SQL_CURSOR_COMMIT_BEHAVIOR:
11117 case SQL_CURSOR_ROLLBACK_BEHAVIOR:
11118 *((SQLSMALLINT *) val) = SQL_CB_PRESERVE;
11119 *valLen = sizeof (SQLSMALLINT);
11120 break;
11121 #ifdef SQL_CURSOR_SENSITIVITY
11122 case SQL_CURSOR_SENSITIVITY:
11123 *((SQLUINTEGER *) val) = SQL_UNSPECIFIED;
11124 *valLen = sizeof (SQLUINTEGER);
11125 break;
11126 #endif
11127 case SQL_DEFAULT_TXN_ISOLATION:
11128 *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11129 *valLen = sizeof (SQLUINTEGER);
11130 break;
11131 #ifdef SQL_DESCRIBE_PARAMETER
11132 case SQL_DESCRIBE_PARAMETER:
11133 strmak(val, "Y", valMax, valLen);
11134 break;
11135 #endif
11136 case SQL_TXN_ISOLATION_OPTION:
11137 *((SQLUINTEGER *) val) = SQL_TXN_SERIALIZABLE;
11138 *valLen = sizeof (SQLUINTEGER);
11139 break;
11140 case SQL_IDENTIFIER_CASE:
11141 *((SQLSMALLINT *) val) = SQL_IC_SENSITIVE;
11142 *valLen = sizeof (SQLSMALLINT);
11143 break;
11144 case SQL_IDENTIFIER_QUOTE_CHAR:
11145 strmak(val, "\"", valMax, valLen);
11146 break;
11147 case SQL_MAX_TABLE_NAME_LEN:
11148 case SQL_MAX_COLUMN_NAME_LEN:
11149 *((SQLSMALLINT *) val) = 255;
11150 *valLen = sizeof (SQLSMALLINT);
11151 break;
11152 case SQL_MAX_CURSOR_NAME_LEN:
11153 *((SQLSMALLINT *) val) = 255;
11154 *valLen = sizeof (SQLSMALLINT);
11155 break;
11156 case SQL_MAX_PROCEDURE_NAME_LEN:
11157 *((SQLSMALLINT *) val) = 0;
11158 break;
11159 case SQL_MAX_QUALIFIER_NAME_LEN:
11160 case SQL_MAX_OWNER_NAME_LEN:
11161 *((SQLSMALLINT *) val) = 255;
11162 break;
11163 case SQL_OWNER_TERM:
11164 strmak(val, "", valMax, valLen);
11165 break;
11166 case SQL_PROCEDURE_TERM:
11167 strmak(val, "PROCEDURE", valMax, valLen);
11168 break;
11169 case SQL_QUALIFIER_NAME_SEPARATOR:
11170 strmak(val, ".", valMax, valLen);
11171 break;
11172 case SQL_QUALIFIER_TERM:
11173 #if defined(_WIN32) || defined(_WIN64)
11174 strmak(val, d->xcelqrx ? "catalog" : "", valMax, valLen);
11175 #else
11176 strmak(val, "", valMax, valLen);
11177 #endif
11178 break;
11179 case SQL_QUALIFIER_USAGE:
11180 #if defined(_WIN32) || defined(_WIN64)
11181 *((SQLUINTEGER *) val) = d->xcelqrx ?
11182 (SQL_CU_DML_STATEMENTS | SQL_CU_INDEX_DEFINITION |
11183 SQL_CU_TABLE_DEFINITION) : 0;
11184 #else
11185 *((SQLUINTEGER *) val) = 0;
11186 #endif
11187 *valLen = sizeof (SQLUINTEGER);
11188 break;
11189 case SQL_SCROLL_CONCURRENCY:
11190 *((SQLUINTEGER *) val) = SQL_SCCO_LOCK;
11191 *valLen = sizeof (SQLUINTEGER);
11192 break;
11193 case SQL_SCROLL_OPTIONS:
11194 *((SQLUINTEGER *) val) = SQL_SO_STATIC | SQL_SO_FORWARD_ONLY;
11195 *valLen = sizeof (SQLUINTEGER);
11196 break;
11197 case SQL_TABLE_TERM:
11198 strmak(val, "TABLE", valMax, valLen);
11199 break;
11200 case SQL_TXN_CAPABLE:
11201 *((SQLSMALLINT *) val) = SQL_TC_ALL;
11202 *valLen = sizeof (SQLSMALLINT);
11203 break;
11204 case SQL_CONVERT_FUNCTIONS:
11205 *((SQLUINTEGER *) val) = 0;
11206 *valLen = sizeof (SQLUINTEGER);
11207 break;
11208 case SQL_SYSTEM_FUNCTIONS:
11209 case SQL_NUMERIC_FUNCTIONS:
11210 case SQL_STRING_FUNCTIONS:
11211 case SQL_TIMEDATE_FUNCTIONS:
11212 *((SQLUINTEGER *) val) = 0;
11213 *valLen = sizeof (SQLUINTEGER);
11214 break;
11215 case SQL_CONVERT_BIGINT:
11216 case SQL_CONVERT_BIT:
11217 case SQL_CONVERT_CHAR:
11218 case SQL_CONVERT_DATE:
11219 case SQL_CONVERT_DECIMAL:
11220 case SQL_CONVERT_DOUBLE:
11221 case SQL_CONVERT_FLOAT:
11222 case SQL_CONVERT_INTEGER:
11223 case SQL_CONVERT_LONGVARCHAR:
11224 case SQL_CONVERT_NUMERIC:
11225 case SQL_CONVERT_REAL:
11226 case SQL_CONVERT_SMALLINT:
11227 case SQL_CONVERT_TIME:
11228 case SQL_CONVERT_TIMESTAMP:
11229 case SQL_CONVERT_TINYINT:
11230 case SQL_CONVERT_VARCHAR:
11231 *((SQLUINTEGER *) val) =
11232 SQL_CVT_CHAR | SQL_CVT_NUMERIC | SQL_CVT_DECIMAL |
11233 SQL_CVT_INTEGER | SQL_CVT_SMALLINT | SQL_CVT_FLOAT | SQL_CVT_REAL |
11234 SQL_CVT_DOUBLE | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR |
11235 SQL_CVT_BIT | SQL_CVT_TINYINT | SQL_CVT_BIGINT |
11236 SQL_CVT_DATE | SQL_CVT_TIME | SQL_CVT_TIMESTAMP;
11237 *valLen = sizeof (SQLUINTEGER);
11238 break;
11239 case SQL_CONVERT_BINARY:
11240 case SQL_CONVERT_VARBINARY:
11241 case SQL_CONVERT_LONGVARBINARY:
11242 *((SQLUINTEGER *) val) = 0;
11243 *valLen = sizeof (SQLUINTEGER);
11244 break;
11245 case SQL_POSITIONED_STATEMENTS:
11246 *((SQLUINTEGER *) val) = 0;
11247 *valLen = sizeof (SQLUINTEGER);
11248 break;
11249 case SQL_LOCK_TYPES:
11250 *((SQLUINTEGER *) val) = SQL_LCK_NO_CHANGE;
11251 *valLen = sizeof (SQLUINTEGER);
11252 break;
11253 case SQL_BOOKMARK_PERSISTENCE:
11254 *((SQLUINTEGER *) val) = SQL_BP_SCROLL;
11255 *valLen = sizeof (SQLUINTEGER);
11256 break;
11257 case SQL_UNION:
11258 *((SQLUINTEGER *) val) = SQL_U_UNION | SQL_U_UNION_ALL;
11259 *valLen = sizeof (SQLUINTEGER);
11260 break;
11261 case SQL_OWNER_USAGE:
11262 case SQL_SUBQUERIES:
11263 case SQL_TIMEDATE_ADD_INTERVALS:
11264 case SQL_TIMEDATE_DIFF_INTERVALS:
11265 *((SQLUINTEGER *) val) = 0;
11266 *valLen = sizeof (SQLUINTEGER);
11267 break;
11268 case SQL_QUOTED_IDENTIFIER_CASE:
11269 *((SQLUSMALLINT *) val) = SQL_IC_SENSITIVE;
11270 *valLen = sizeof (SQLUSMALLINT);
11271 break;
11272 case SQL_POS_OPERATIONS:
11273 *((SQLUINTEGER *) val) = SQL_POS_POSITION | SQL_POS_UPDATE |
11274 SQL_POS_DELETE | SQL_POS_ADD | SQL_POS_REFRESH;
11275 *valLen = sizeof (SQLUINTEGER);
11276 break;
11277 case SQL_ALTER_TABLE:
11278 *((SQLUINTEGER *) val) = 0;
11279 *valLen = sizeof (SQLUINTEGER);
11280 break;
11281 case SQL_CORRELATION_NAME:
11282 *((SQLSMALLINT *) val) = SQL_CN_DIFFERENT;
11283 *valLen = sizeof (SQLSMALLINT);
11284 break;
11285 case SQL_NON_NULLABLE_COLUMNS:
11286 *((SQLSMALLINT *) val) = SQL_NNC_NON_NULL;
11287 *valLen = sizeof (SQLSMALLINT);
11288 break;
11289 case SQL_NULL_COLLATION:
11290 *((SQLSMALLINT *) val) = SQL_NC_START;
11291 *valLen = sizeof (SQLSMALLINT);
11292 break;
11293 case SQL_MAX_COLUMNS_IN_GROUP_BY:
11294 case SQL_MAX_COLUMNS_IN_ORDER_BY:
11295 case SQL_MAX_COLUMNS_IN_SELECT:
11296 case SQL_MAX_COLUMNS_IN_TABLE:
11297 case SQL_MAX_ROW_SIZE:
11298 case SQL_MAX_TABLES_IN_SELECT:
11299 *((SQLSMALLINT *) val) = 0;
11300 *valLen = sizeof (SQLSMALLINT);
11301 break;
11302 case SQL_MAX_BINARY_LITERAL_LEN:
11303 case SQL_MAX_CHAR_LITERAL_LEN:
11304 *((SQLUINTEGER *) val) = 0;
11305 *valLen = sizeof (SQLUINTEGER);
11306 break;
11307 case SQL_MAX_COLUMNS_IN_INDEX:
11308 *((SQLSMALLINT *) val) = 0;
11309 *valLen = sizeof (SQLSMALLINT);
11310 break;
11311 case SQL_MAX_INDEX_SIZE:
11312 *((SQLUINTEGER *) val) = 0;
11313 *valLen = sizeof (SQLUINTEGER);
11314 break;
11315 #ifdef SQL_MAX_IDENTIFIER_LENGTH
11316 case SQL_MAX_IDENTIFIER_LENGTH:
11317 *((SQLUINTEGER *) val) = 255;
11318 *valLen = sizeof (SQLUINTEGER);
11319 break;
11320 #endif
11321 case SQL_MAX_STATEMENT_LEN:
11322 *((SQLUINTEGER *) val) = 16384;
11323 *valLen = sizeof (SQLUINTEGER);
11324 break;
11325 case SQL_QUALIFIER_LOCATION:
11326 *((SQLSMALLINT *) val) = SQL_QL_START;
11327 *valLen = sizeof (SQLSMALLINT);
11328 break;
11329 case SQL_GETDATA_EXTENSIONS:
11330 *((SQLUINTEGER *) val) =
11331 SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER | SQL_GD_BOUND;
11332 *valLen = sizeof (SQLUINTEGER);
11333 break;
11334 case SQL_STATIC_SENSITIVITY:
11335 *((SQLUINTEGER *) val) = 0;
11336 *valLen = sizeof (SQLUINTEGER);
11337 break;
11338 case SQL_FILE_USAGE:
11339 #if defined(_WIN32) || defined(_WIN64)
11340 *((SQLSMALLINT *) val) =
11341 d->xcelqrx ? SQL_FILE_CATALOG : SQL_FILE_NOT_SUPPORTED;
11342 #else
11343 *((SQLSMALLINT *) val) = SQL_FILE_NOT_SUPPORTED;
11344 #endif
11345 *valLen = sizeof (SQLSMALLINT);
11346 break;
11347 case SQL_GROUP_BY:
11348 *((SQLSMALLINT *) val) = SQL_GB_GROUP_BY_EQUALS_SELECT;
11349 *valLen = sizeof (SQLSMALLINT);
11350 break;
11351 case SQL_KEYWORDS:
11352 strmak(val, "CREATE,SELECT,DROP,DELETE,UPDATE,INSERT,"
11353 "INTO,VALUES,TABLE,INDEX,FROM,SET,WHERE,AND,CURRENT,OF",
11354 valMax, valLen);
11355 break;
11356 case SQL_SPECIAL_CHARACTERS:
11357 #ifdef SQL_COLLATION_SEQ
11358 case SQL_COLLATION_SEQ:
11359 #endif
11360 strmak(val, "", valMax, valLen);
11361 break;
11362 case SQL_BATCH_SUPPORT:
11363 case SQL_BATCH_ROW_COUNT:
11364 case SQL_PARAM_ARRAY_ROW_COUNTS:
11365 *((SQLUINTEGER *) val) = 0;
11366 *valLen = sizeof (SQLUINTEGER);
11367 break;
11368 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
11369 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_BOOKMARK;
11370 *valLen = sizeof (SQLUINTEGER);
11371 break;
11372 case SQL_STATIC_CURSOR_ATTRIBUTES1:
11373 *((SQLUINTEGER *) val) = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
11374 SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK | SQL_CA1_POS_POSITION |
11375 SQL_CA1_POS_DELETE | SQL_CA1_POS_UPDATE | SQL_CA1_POS_REFRESH |
11376 SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_BULK_ADD |
11377 SQL_CA1_BULK_UPDATE_BY_BOOKMARK | SQL_CA1_BULK_DELETE_BY_BOOKMARK;
11378 *valLen = sizeof (SQLUINTEGER);
11379 break;
11380 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
11381 case SQL_STATIC_CURSOR_ATTRIBUTES2:
11382 *((SQLUINTEGER *) val) = SQL_CA2_READ_ONLY_CONCURRENCY |
11383 SQL_CA2_LOCK_CONCURRENCY;
11384 *valLen = sizeof (SQLUINTEGER);
11385 break;
11386 case SQL_KEYSET_CURSOR_ATTRIBUTES1:
11387 case SQL_KEYSET_CURSOR_ATTRIBUTES2:
11388 case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
11389 case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
11390 *((SQLUINTEGER *) val) = 0;
11391 *valLen = sizeof (SQLUINTEGER);
11392 break;
11393 case SQL_ODBC_INTERFACE_CONFORMANCE:
11394 *((SQLUINTEGER *) val) = SQL_OIC_CORE;
11395 *valLen = sizeof (SQLUINTEGER);
11396 break;
11397 default:
11398 setstatd(d, -1, "unsupported info option %d",
11399 (*d->ov3) ? "HYC00" : "S1C00", type);
11400 return SQL_ERROR;
11401 }
11402 return SQL_SUCCESS;
11403 }
11404
11405 #if (defined(HAVE_UNIXODBC) && (HAVE_UNIXODBC)) || !defined(WINTERFACE)
11406
11416 SQLRETURN SQL_API
11417 SQLGetInfo(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11418 SQLSMALLINT *valLen)
11419 {
11420 SQLRETURN ret;
11421
11422 HDBC_LOCK(dbc);
11423 ret = drvgetinfo(dbc, type, val, valMax, valLen);
11424 HDBC_UNLOCK(dbc);
11425 return ret;
11426 }
11427 #endif
11428
11429 #ifdef WINTERFACE
11430
11440 SQLRETURN SQL_API
11441 SQLGetInfoW(SQLHDBC dbc, SQLUSMALLINT type, SQLPOINTER val, SQLSMALLINT valMax,
11442 SQLSMALLINT *valLen)
11443 {
11444 SQLRETURN ret;
11445 SQLSMALLINT len = 0;
11446
11447 HDBC_LOCK(dbc);
11448 ret = drvgetinfo(dbc, type, val, valMax, &len);
11449 HDBC_UNLOCK(dbc);
11450 if (ret == SQL_SUCCESS) {
11451 SQLWCHAR *v = NULL;
11452
11453 switch (type) {
11454 case SQL_USER_NAME:
11455 case SQL_DRIVER_ODBC_VER:
11456 case SQL_DATA_SOURCE_NAME:
11457 case SQL_DRIVER_NAME:
11458 case SQL_DRIVER_VER:
11459 case SQL_ODBC_VER:
11460 case SQL_SERVER_NAME:
11461 case SQL_DATABASE_NAME:
11462 case SQL_SEARCH_PATTERN_ESCAPE:
11463 case SQL_DBMS_NAME:
11464 case SQL_DBMS_VER:
11465 case SQL_NEED_LONG_DATA_LEN:
11466 case SQL_ROW_UPDATES:
11467 case SQL_ACCESSIBLE_PROCEDURES:
11468 case SQL_PROCEDURES:
11469 case SQL_EXPRESSIONS_IN_ORDERBY:
11470 case SQL_ODBC_SQL_OPT_IEF:
11471 case SQL_LIKE_ESCAPE_CLAUSE:
11472 case SQL_ORDER_BY_COLUMNS_IN_SELECT:
11473 case SQL_OUTER_JOINS:
11474 case SQL_COLUMN_ALIAS:
11475 case SQL_ACCESSIBLE_TABLES:
11476 case SQL_MULT_RESULT_SETS:
11477 case SQL_MULTIPLE_ACTIVE_TXN:
11478 case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
11479 case SQL_DATA_SOURCE_READ_ONLY:
11480 #ifdef SQL_DESCRIBE_PARAMETER
11481 case SQL_DESCRIBE_PARAMETER:
11482 #endif
11483 case SQL_IDENTIFIER_QUOTE_CHAR:
11484 case SQL_OWNER_TERM:
11485 case SQL_PROCEDURE_TERM:
11486 case SQL_QUALIFIER_NAME_SEPARATOR:
11487 case SQL_QUALIFIER_TERM:
11488 case SQL_TABLE_TERM:
11489 case SQL_KEYWORDS:
11490 case SQL_SPECIAL_CHARACTERS:
11491 #ifdef SQL_CATALOG_NAME
11492 case SQL_CATALOG_NAME:
11493 #endif
11494 #ifdef SQL_COLLATION_SEQ
11495 case SQL_COLLATION_SEQ:
11496 #endif
11497 if (val) {
11498 if (len > 0) {
11499 v = uc_from_utf((SQLCHAR *) val, len);
11500 if (v) {
11501 int vmax = valMax / sizeof (SQLWCHAR);
11502
11503 uc_strncpy(val, v, vmax);
11504 if (len < vmax) {
11505 len = min(vmax, uc_strlen(v));
11506 v[len] = 0;
11507 } else {
11508 len = vmax;
11509 }
11510 uc_free(v);
11511 len *= sizeof (SQLWCHAR);
11512 } else {
11513 len = 0;
11514 }
11515 }
11516 if (len <= 0) {
11517 len = 0;
11518 if (valMax >= sizeof (SQLWCHAR)) {
11519 *((SQLWCHAR *)val) = 0;
11520 }
11521 }
11522 } else {
11523 len *= sizeof (SQLWCHAR);
11524 }
11525 break;
11526 }
11527 if (valLen) {
11528 *valLen = len;
11529 }
11530 }
11531 return ret;
11532 }
11533 #endif
11534
11543 SQLRETURN SQL_API
11544 SQLGetFunctions(SQLHDBC dbc, SQLUSMALLINT func,
11545 SQLUSMALLINT *flags)
11546 {
11547 int i;
11548 SQLUSMALLINT exists[100];
11549
11550 if (dbc == SQL_NULL_HDBC) {
11551 return SQL_INVALID_HANDLE;
11552 }
11553 for (i = 0; i < array_size(exists); i++) {
11554 exists[i] = SQL_FALSE;
11555 }
11556 exists[SQL_API_SQLALLOCCONNECT] = SQL_TRUE;
11557 exists[SQL_API_SQLFETCH] = SQL_TRUE;
11558 exists[SQL_API_SQLALLOCENV] = SQL_TRUE;
11559 exists[SQL_API_SQLFREECONNECT] = SQL_TRUE;
11560 exists[SQL_API_SQLALLOCSTMT] = SQL_TRUE;
11561 exists[SQL_API_SQLFREEENV] = SQL_TRUE;
11562 exists[SQL_API_SQLBINDCOL] = SQL_TRUE;
11563 exists[SQL_API_SQLFREESTMT] = SQL_TRUE;
11564 exists[SQL_API_SQLCANCEL] = SQL_TRUE;
11565 exists[SQL_API_SQLGETCURSORNAME] = SQL_TRUE;
11566 exists[SQL_API_SQLCOLATTRIBUTES] = SQL_TRUE;
11567 exists[SQL_API_SQLNUMRESULTCOLS] = SQL_TRUE;
11568 exists[SQL_API_SQLCONNECT] = SQL_TRUE;
11569 exists[SQL_API_SQLPREPARE] = SQL_TRUE;
11570 exists[SQL_API_SQLDESCRIBECOL] = SQL_TRUE;
11571 exists[SQL_API_SQLROWCOUNT] = SQL_TRUE;
11572 exists[SQL_API_SQLDISCONNECT] = SQL_TRUE;
11573 exists[SQL_API_SQLSETCURSORNAME] = SQL_FALSE;
11574 exists[SQL_API_SQLERROR] = SQL_TRUE;
11575 exists[SQL_API_SQLSETPARAM] = SQL_TRUE;
11576 exists[SQL_API_SQLEXECDIRECT] = SQL_TRUE;
11577 exists[SQL_API_SQLTRANSACT] = SQL_TRUE;
11578 exists[SQL_API_SQLBULKOPERATIONS] = SQL_TRUE;
11579 exists[SQL_API_SQLEXECUTE] = SQL_TRUE;
11580 exists[SQL_API_SQLBINDPARAMETER] = SQL_TRUE;
11581 exists[SQL_API_SQLGETTYPEINFO] = SQL_TRUE;
11582 exists[SQL_API_SQLCOLUMNS] = SQL_TRUE;
11583 exists[SQL_API_SQLPARAMDATA] = SQL_TRUE;
11584 exists[SQL_API_SQLDRIVERCONNECT] = SQL_TRUE;
11585 exists[SQL_API_SQLPUTDATA] = SQL_TRUE;
11586 exists[SQL_API_SQLGETCONNECTOPTION] = SQL_TRUE;
11587 exists[SQL_API_SQLSETCONNECTOPTION] = SQL_TRUE;
11588 exists[SQL_API_SQLGETDATA] = SQL_TRUE;
11589 exists[SQL_API_SQLSETSTMTOPTION] = SQL_TRUE;
11590 exists[SQL_API_SQLGETFUNCTIONS] = SQL_TRUE;
11591 exists[SQL_API_SQLSPECIALCOLUMNS] = SQL_TRUE;
11592 exists[SQL_API_SQLGETINFO] = SQL_TRUE;
11593 exists[SQL_API_SQLSTATISTICS] = SQL_TRUE;
11594 exists[SQL_API_SQLGETSTMTOPTION] = SQL_TRUE;
11595 exists[SQL_API_SQLTABLES] = SQL_TRUE;
11596 exists[SQL_API_SQLBROWSECONNECT] = SQL_FALSE;
11597 exists[SQL_API_SQLNUMPARAMS] = SQL_TRUE;
11598 exists[SQL_API_SQLCOLUMNPRIVILEGES] = SQL_FALSE;
11599 exists[SQL_API_SQLPARAMOPTIONS] = SQL_FALSE;
11600 exists[SQL_API_SQLDATASOURCES] = SQL_TRUE;
11601 exists[SQL_API_SQLPRIMARYKEYS] = SQL_TRUE;
11602 exists[SQL_API_SQLDESCRIBEPARAM] = SQL_TRUE;
11603 exists[SQL_API_SQLPROCEDURECOLUMNS] = SQL_TRUE;
11604 exists[SQL_API_SQLDRIVERS] = SQL_FALSE;
11605 exists[SQL_API_SQLPROCEDURES] = SQL_TRUE;
11606 exists[SQL_API_SQLEXTENDEDFETCH] = SQL_TRUE;
11607 exists[SQL_API_SQLSETPOS] = SQL_TRUE;
11608 exists[SQL_API_SQLFOREIGNKEYS] = SQL_TRUE;
11609 exists[SQL_API_SQLSETSCROLLOPTIONS] = SQL_TRUE;
11610 exists[SQL_API_SQLMORERESULTS] = SQL_TRUE;
11611 exists[SQL_API_SQLTABLEPRIVILEGES] = SQL_TRUE;
11612 exists[SQL_API_SQLNATIVESQL] = SQL_TRUE;
11613 if (func == SQL_API_ALL_FUNCTIONS) {
11614 memcpy(flags, exists, sizeof (exists));
11615 } else if (func == SQL_API_ODBC3_ALL_FUNCTIONS) {
11616 int i;
11617 #define SET_EXISTS(x) \
11618 flags[(x) >> 4] |= (1 << ((x) & 0xF))
11619 #define CLR_EXISTS(x) \
11620 flags[(x) >> 4] &= ~(1 << ((x) & 0xF))
11621
11622 memset(flags, 0,
11623 sizeof (SQLUSMALLINT) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
11624 for (i = 0; i < array_size(exists); i++) {
11625 if (exists[i]) {
11626 flags[i >> 4] |= (1 << (i & 0xF));
11627 }
11628 }
11629 SET_EXISTS(SQL_API_SQLALLOCHANDLE);
11630 SET_EXISTS(SQL_API_SQLFREEHANDLE);
11631 SET_EXISTS(SQL_API_SQLGETSTMTATTR);
11632 SET_EXISTS(SQL_API_SQLSETSTMTATTR);
11633 SET_EXISTS(SQL_API_SQLGETCONNECTATTR);
11634 SET_EXISTS(SQL_API_SQLSETCONNECTATTR);
11635 SET_EXISTS(SQL_API_SQLGETENVATTR);
11636 SET_EXISTS(SQL_API_SQLSETENVATTR);
11637 SET_EXISTS(SQL_API_SQLCLOSECURSOR);
11638 SET_EXISTS(SQL_API_SQLBINDPARAM);
11639 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11640
11641
11642
11643
11644
11645 SET_EXISTS(SQL_API_SQLGETDIAGREC);
11646 #endif
11647 SET_EXISTS(SQL_API_SQLGETDIAGFIELD);
11648 SET_EXISTS(SQL_API_SQLFETCHSCROLL);
11649 SET_EXISTS(SQL_API_SQLENDTRAN);
11650 } else {
11651 if (func < array_size(exists)) {
11652 *flags = exists[func];
11653 } else {
11654 switch (func) {
11655 case SQL_API_SQLALLOCHANDLE:
11656 case SQL_API_SQLFREEHANDLE:
11657 case SQL_API_SQLGETSTMTATTR:
11658 case SQL_API_SQLSETSTMTATTR:
11659 case SQL_API_SQLGETCONNECTATTR:
11660 case SQL_API_SQLSETCONNECTATTR:
11661 case SQL_API_SQLGETENVATTR:
11662 case SQL_API_SQLSETENVATTR:
11663 case SQL_API_SQLCLOSECURSOR:
11664 case SQL_API_SQLBINDPARAM:
11665 #if !defined(HAVE_UNIXODBC) || !(HAVE_UNIXODBC)
11666
11667
11668
11669
11670
11671 case SQL_API_SQLGETDIAGREC:
11672 #endif
11673 case SQL_API_SQLGETDIAGFIELD:
11674 case SQL_API_SQLFETCHSCROLL:
11675 case SQL_API_SQLENDTRAN:
11676 *flags = SQL_TRUE;
11677 break;
11678 default:
11679 *flags = SQL_FALSE;
11680 }
11681 }
11682 }
11683 return SQL_SUCCESS;
11684 }
11685
11692 static SQLRETURN
11693 drvallocenv(SQLHENV *env)
11694 {
11695 ENV *e;
11696
11697 if (env == NULL) {
11698 return SQL_INVALID_HANDLE;
11699 }
11700 e = (ENV *) xmalloc(sizeof (ENV));
11701 if (e == NULL) {
11702 *env = SQL_NULL_HENV;
11703 return SQL_ERROR;
11704 }
11705 e->magic = ENV_MAGIC;
11706 e->ov3 = 0;
11707 #if defined(_WIN32) || defined(_WIN64)
11708 InitializeCriticalSection(&e->cs);
11709 #else
11710 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
11711 nvfs_init();
11712 #endif
11713 #endif
11714 e->dbcs = NULL;
11715 *env = (SQLHENV) e;
11716 return SQL_SUCCESS;
11717 }
11718
11725 SQLRETURN SQL_API
11726 SQLAllocEnv(SQLHENV *env)
11727 {
11728 return drvallocenv(env);
11729 }
11730
11737 static SQLRETURN
11738 drvfreeenv(SQLHENV env)
11739 {
11740 ENV *e;
11741
11742 if (env == SQL_NULL_HENV) {
11743 return SQL_INVALID_HANDLE;
11744 }
11745 e = (ENV *) env;
11746 if (e->magic != ENV_MAGIC) {
11747 return SQL_SUCCESS;
11748 }
11749 #if defined(_WIN32) || defined(_WIN64)
11750 EnterCriticalSection(&e->cs);
11751 #endif
11752 if (e->dbcs) {
11753 #if defined(_WIN32) || defined(_WIN64)
11754 LeaveCriticalSection(&e->cs);
11755 #endif
11756 return SQL_ERROR;
11757 }
11758 e->magic = DEAD_MAGIC;
11759 #if defined(_WIN32) || defined(_WIN64)
11760 LeaveCriticalSection(&e->cs);
11761 DeleteCriticalSection(&e->cs);
11762 #endif
11763 xfree(e);
11764 return SQL_SUCCESS;
11765 }
11766
11773 SQLRETURN SQL_API
11774 SQLFreeEnv(SQLHENV env)
11775 {
11776 return drvfreeenv(env);
11777 }
11778
11786 static SQLRETURN
11787 drvallocconnect(SQLHENV env, SQLHDBC *dbc)
11788 {
11789 DBC *d;
11790 ENV *e;
11791 const char *verstr;
11792 int maj = 0, min = 0, lev = 0;
11793
11794 if (dbc == NULL) {
11795 return SQL_ERROR;
11796 }
11797 d = (DBC *) xmalloc(sizeof (DBC));
11798 if (d == NULL) {
11799 *dbc = SQL_NULL_HDBC;
11800 return SQL_ERROR;
11801 }
11802 memset(d, 0, sizeof (DBC));
11803 d->curtype = SQL_CURSOR_STATIC;
11804 d->ov3 = &d->ov3val;
11805 verstr = sqlite3_libversion();
11806 sscanf(verstr, "%d.%d.%d", &maj, &min, &lev);
11807 d->version = verinfo(maj & 0xFF, min & 0xFF, lev & 0xFF);
11808 e = (ENV *) env;
11809 #if defined(_WIN32) || defined(_WIN64)
11810 if (e->magic == ENV_MAGIC) {
11811 EnterCriticalSection(&e->cs);
11812 }
11813 #endif
11814 if (e->magic == ENV_MAGIC) {
11815 DBC *n, *p;
11816
11817 d->env = e;
11818 d->ov3 = &e->ov3;
11819 p = NULL;
11820 n = e->dbcs;
11821 while (n) {
11822 p = n;
11823 n = n->next;
11824 }
11825 if (p) {
11826 p->next = d;
11827 } else {
11828 e->dbcs = d;
11829 }
11830 }
11831 #if defined(_WIN32) || defined(_WIN64)
11832 InitializeCriticalSection(&d->cs);
11833 d->owner = 0;
11834 if (e->magic == ENV_MAGIC) {
11835 LeaveCriticalSection(&e->cs);
11836 }
11837 d->oemcp = 1;
11838 #endif
11839 d->autocommit = 1;
11840 d->magic = DBC_MAGIC;
11841 *dbc = (SQLHDBC) d;
11842 drvgetgpps(d);
11843 return SQL_SUCCESS;
11844 }
11845
11853 SQLRETURN SQL_API
11854 SQLAllocConnect(SQLHENV env, SQLHDBC *dbc)
11855 {
11856 return drvallocconnect(env, dbc);
11857 }
11858
11865 static SQLRETURN
11866 drvfreeconnect(SQLHDBC dbc)
11867 {
11868 DBC *d;
11869 ENV *e;
11870 SQLRETURN ret = SQL_ERROR;
11871
11872 if (dbc == SQL_NULL_HDBC) {
11873 return SQL_INVALID_HANDLE;
11874 }
11875 d = (DBC *) dbc;
11876 if (d->magic != DBC_MAGIC) {
11877 return SQL_INVALID_HANDLE;
11878 }
11879 e = d->env;
11880 if (e && e->magic == ENV_MAGIC) {
11881 #if defined(_WIN32) || defined(_WIN64)
11882 EnterCriticalSection(&e->cs);
11883 #endif
11884 } else {
11885 e = NULL;
11886 }
11887 HDBC_LOCK(dbc);
11888 if (d->sqlite) {
11889 setstatd(d, -1, "not disconnected", (*d->ov3) ? "HY000" : "S1000");
11890 HDBC_UNLOCK(dbc);
11891 goto done;
11892 }
11893 while (d->stmt) {
11894 freestmt((HSTMT) d->stmt);
11895 }
11896 if (e && e->magic == ENV_MAGIC) {
11897 DBC *n, *p;
11898
11899 p = NULL;
11900 n = e->dbcs;
11901 while (n) {
11902 if (n == d) {
11903 break;
11904 }
11905 p = n;
11906 n = n->next;
11907 }
11908 if (n) {
11909 if (p) {
11910 p->next = d->next;
11911 } else {
11912 e->dbcs = d->next;
11913 }
11914 }
11915 }
11916 drvrelgpps(d);
11917 d->magic = DEAD_MAGIC;
11918 if (d->trace) {
11919 fclose(d->trace);
11920 }
11921 #if defined(_WIN32) || defined(_WIN64)
11922 d->owner = 0;
11923 LeaveCriticalSection(&d->cs);
11924 DeleteCriticalSection(&d->cs);
11925 #endif
11926 xfree(d);
11927 ret = SQL_SUCCESS;
11928 done:
11929 #if defined(_WIN32) || defined(_WIN64)
11930 if (e) {
11931 LeaveCriticalSection(&e->cs);
11932 }
11933 #endif
11934 return ret;
11935 }
11936
11943 SQLRETURN SQL_API
11944 SQLFreeConnect(SQLHDBC dbc)
11945 {
11946 return drvfreeconnect(dbc);
11947 }
11948
11959 static SQLRETURN
11960 drvgetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
11961 SQLINTEGER bufmax, SQLINTEGER *buflen)
11962 {
11963 DBC *d;
11964 SQLINTEGER dummy;
11965
11966 if (dbc == SQL_NULL_HDBC) {
11967 return SQL_INVALID_HANDLE;
11968 }
11969 d = (DBC *) dbc;
11970 if (!val) {
11971 val = (SQLPOINTER) &dummy;
11972 }
11973 if (!buflen) {
11974 buflen = &dummy;
11975 }
11976 switch (attr) {
11977 case SQL_ATTR_CONNECTION_DEAD:
11978 *((SQLINTEGER *) val) = d->sqlite ? SQL_CD_FALSE : SQL_CD_TRUE;
11979 *buflen = sizeof (SQLINTEGER);
11980 break;
11981 case SQL_ATTR_ACCESS_MODE:
11982 *((SQLINTEGER *) val) = SQL_MODE_READ_WRITE;
11983 *buflen = sizeof (SQLINTEGER);
11984 break;
11985 case SQL_ATTR_AUTOCOMMIT:
11986 *((SQLINTEGER *) val) =
11987 d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
11988 *buflen = sizeof (SQLINTEGER);
11989 break;
11990 case SQL_ATTR_LOGIN_TIMEOUT:
11991 *((SQLINTEGER *) val) = 100;
11992 *buflen = sizeof (SQLINTEGER);
11993 break;
11994 case SQL_ATTR_ODBC_CURSORS:
11995 *((SQLINTEGER *) val) = SQL_CUR_USE_DRIVER;
11996 *buflen = sizeof (SQLINTEGER);
11997 break;
11998 case SQL_ATTR_PACKET_SIZE:
11999 *((SQLINTEGER *) val) = 16384;
12000 *buflen = sizeof (SQLINTEGER);
12001 break;
12002 case SQL_ATTR_TXN_ISOLATION:
12003 *((SQLINTEGER *) val) = SQL_TXN_SERIALIZABLE;
12004 *buflen = sizeof (SQLINTEGER);
12005 break;
12006 case SQL_ATTR_TRACEFILE:
12007 case SQL_ATTR_TRANSLATE_LIB:
12008 *((SQLCHAR *) val) = 0;
12009 *buflen = 0;
12010 break;
12011 case SQL_ATTR_CURRENT_CATALOG:
12012 #if defined(_WIN32) || defined(_WIN64)
12013 if (d->xcelqrx) {
12014 if ((bufmax > 4) && (val != (SQLPOINTER) &dummy)) {
12015 strcpy((char *) val, "main");
12016 *buflen = 4;
12017 break;
12018 }
12019 }
12020 #endif
12021 *((SQLCHAR *) val) = 0;
12022 *buflen = 0;
12023 break;
12024 case SQL_ATTR_TRACE:
12025 case SQL_ATTR_QUIET_MODE:
12026 case SQL_ATTR_TRANSLATE_OPTION:
12027 case SQL_ATTR_KEYSET_SIZE:
12028 case SQL_ATTR_QUERY_TIMEOUT:
12029 *((SQLINTEGER *) val) = 0;
12030 *buflen = sizeof (SQLINTEGER);
12031 break;
12032 case SQL_ATTR_PARAM_BIND_TYPE:
12033 *((SQLULEN *) val) = SQL_PARAM_BIND_BY_COLUMN;
12034 *buflen = sizeof (SQLUINTEGER);
12035 break;
12036 case SQL_ATTR_ROW_BIND_TYPE:
12037 *((SQLULEN *) val) = SQL_BIND_BY_COLUMN;
12038 *buflen = sizeof (SQLULEN);
12039 break;
12040 case SQL_ATTR_USE_BOOKMARKS:
12041 *((SQLINTEGER *) val) = SQL_UB_OFF;
12042 *buflen = sizeof (SQLINTEGER);
12043 break;
12044 case SQL_ATTR_ASYNC_ENABLE:
12045 *((SQLINTEGER *) val) = SQL_ASYNC_ENABLE_OFF;
12046 *buflen = sizeof (SQLINTEGER);
12047 break;
12048 case SQL_ATTR_NOSCAN:
12049 *((SQLINTEGER *) val) = SQL_NOSCAN_ON;
12050 *buflen = sizeof (SQLINTEGER);
12051 break;
12052 case SQL_ATTR_CONCURRENCY:
12053 *((SQLINTEGER *) val) = SQL_CONCUR_LOCK;
12054 *buflen = sizeof (SQLINTEGER);
12055 break;
12056 #ifdef SQL_ATTR_CURSOR_SENSITIVITY
12057 case SQL_ATTR_CURSOR_SENSITIVITY:
12058 *((SQLINTEGER *) val) = SQL_UNSPECIFIED;
12059 *buflen = sizeof (SQLINTEGER);
12060 break;
12061 #endif
12062 case SQL_ATTR_SIMULATE_CURSOR:
12063 *((SQLINTEGER *) val) = SQL_SC_NON_UNIQUE;
12064 *buflen = sizeof (SQLINTEGER);
12065 break;
12066 case SQL_ATTR_MAX_ROWS:
12067 *((SQLINTEGER *) val) = 0;
12068 *buflen = sizeof (SQLINTEGER);
12069 case SQL_ATTR_MAX_LENGTH:
12070 *((SQLINTEGER *) val) = 1000000000;
12071 *buflen = sizeof (SQLINTEGER);
12072 break;
12073 case SQL_ATTR_CURSOR_TYPE:
12074 *((SQLINTEGER *) val) = d->curtype;
12075 *buflen = sizeof (SQLINTEGER);
12076 break;
12077 case SQL_ATTR_RETRIEVE_DATA:
12078 *((SQLINTEGER *) val) = SQL_RD_ON;
12079 *buflen = sizeof (SQLINTEGER);
12080 break;
12081 #ifdef SQL_ATTR_METADATA_ID
12082 case SQL_ATTR_METADATA_ID:
12083 *((SQLULEN *) val) = SQL_FALSE;
12084 return SQL_SUCCESS;
12085 #endif
12086 default:
12087 *((SQLINTEGER *) val) = 0;
12088 *buflen = sizeof (SQLINTEGER);
12089 setstatd(d, -1, "unsupported connect attribute %d",
12090 (*d->ov3) ? "HYC00" : "S1C00", (int) attr);
12091 return SQL_ERROR;
12092 }
12093 return SQL_SUCCESS;
12094 }
12095
12096 #ifndef WINTERFACE
12097
12107 SQLRETURN SQL_API
12108 SQLGetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12109 SQLINTEGER bufmax, SQLINTEGER *buflen)
12110 {
12111 SQLRETURN ret;
12112
12113 HDBC_LOCK(dbc);
12114 ret = drvgetconnectattr(dbc, attr, val, bufmax, buflen);
12115 HDBC_UNLOCK(dbc);
12116 return ret;
12117 }
12118 #endif
12119
12120 #ifdef WINTERFACE
12121
12131 SQLRETURN SQL_API
12132 SQLGetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12133 SQLINTEGER bufmax, SQLINTEGER *buflen)
12134 {
12135 SQLRETURN ret;
12136 SQLINTEGER len = 0;
12137
12138 HDBC_LOCK(dbc);
12139 ret = drvgetconnectattr(dbc, attr, val, bufmax, &len);
12140 if (ret == SQL_SUCCESS) {
12141 SQLWCHAR *v = NULL;
12142
12143 switch (attr) {
12144 case SQL_ATTR_TRACEFILE:
12145 case SQL_ATTR_CURRENT_CATALOG:
12146 case SQL_ATTR_TRANSLATE_LIB:
12147 if (val) {
12148 if (len > 0) {
12149 v = uc_from_utf((SQLCHAR *) val, len);
12150 if (v) {
12151 int vmax = bufmax / sizeof (SQLWCHAR);
12152
12153 uc_strncpy(val, v, vmax);
12154 if (len < vmax) {
12155 len = min(vmax, uc_strlen(v));
12156 v[len] = 0;
12157 } else {
12158 len = vmax;
12159 }
12160 uc_free(v);
12161 len *= sizeof (SQLWCHAR);
12162 } else {
12163 len = 0;
12164 }
12165 }
12166 if (len <= 0) {
12167 len = 0;
12168 if (bufmax >= sizeof (SQLWCHAR)) {
12169 *((SQLWCHAR *)val) = 0;
12170 }
12171 }
12172 } else {
12173 len *= sizeof (SQLWCHAR);
12174 }
12175 break;
12176 }
12177 if (buflen) {
12178 *buflen = len;
12179 }
12180 }
12181 HDBC_UNLOCK(dbc);
12182 return ret;
12183 }
12184 #endif
12185
12195 static SQLRETURN
12196 drvsetconnectattr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12197 SQLINTEGER len)
12198 {
12199 DBC *d;
12200
12201 if (dbc == SQL_NULL_HDBC) {
12202 return SQL_INVALID_HANDLE;
12203 }
12204 d = (DBC *) dbc;
12205 switch (attr) {
12206 case SQL_AUTOCOMMIT:
12207 d->autocommit = val == (SQLPOINTER) SQL_AUTOCOMMIT_ON;
12208 if (d->autocommit && d->intrans) {
12209 return endtran(d, SQL_COMMIT, 1);
12210 } else if (!d->autocommit) {
12211 s3stmt_end(d->cur_s3stmt);
12212 }
12213 break;
12214 return SQL_SUCCESS;
12215 #ifdef SQL_ATTR_METADATA_ID
12216 case SQL_ATTR_METADATA_ID:
12217 if (val == (SQLPOINTER) SQL_FALSE) {
12218 break;
12219 }
12220
12221 #endif
12222 default:
12223 setstatd(d, -1, "option value changed", "01S02");
12224 return SQL_SUCCESS_WITH_INFO;
12225 }
12226 return SQL_SUCCESS;
12227 }
12228
12229 #ifndef WINTERFACE
12230
12239 SQLRETURN SQL_API
12240 SQLSetConnectAttr(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12241 SQLINTEGER len)
12242 {
12243 SQLRETURN ret;
12244
12245 HDBC_LOCK(dbc);
12246 ret = drvsetconnectattr(dbc, attr, val, len);
12247 HDBC_UNLOCK(dbc);
12248 return ret;
12249 }
12250 #endif
12251
12252 #ifdef WINTERFACE
12253
12262 SQLRETURN SQL_API
12263 SQLSetConnectAttrW(SQLHDBC dbc, SQLINTEGER attr, SQLPOINTER val,
12264 SQLINTEGER len)
12265 {
12266 SQLRETURN ret;
12267
12268 HDBC_LOCK(dbc);
12269 ret = drvsetconnectattr(dbc, attr, val, len);
12270 HDBC_UNLOCK(dbc);
12271 return ret;
12272 }
12273 #endif
12274
12283 static SQLRETURN
12284 drvgetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12285 {
12286 DBC *d;
12287 SQLINTEGER dummy;
12288
12289 if (dbc == SQL_NULL_HDBC) {
12290 return SQL_INVALID_HANDLE;
12291 }
12292 d = (DBC *) dbc;
12293 if (!param) {
12294 param = (SQLPOINTER) &dummy;
12295 }
12296 switch (opt) {
12297 case SQL_ACCESS_MODE:
12298 *((SQLINTEGER *) param) = SQL_MODE_READ_WRITE;
12299 break;
12300 case SQL_AUTOCOMMIT:
12301 *((SQLINTEGER *) param) =
12302 d->autocommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
12303 break;
12304 case SQL_LOGIN_TIMEOUT:
12305 *((SQLINTEGER *) param) = 100;
12306 break;
12307 case SQL_ODBC_CURSORS:
12308 *((SQLINTEGER *) param) = SQL_CUR_USE_DRIVER;
12309 break;
12310 case SQL_PACKET_SIZE:
12311 *((SQLINTEGER *) param) = 16384;
12312 break;
12313 case SQL_TXN_ISOLATION:
12314 *((SQLINTEGER *) param) = SQL_TXN_SERIALIZABLE;
12315 break;
12316 case SQL_OPT_TRACE:
12317 case SQL_OPT_TRACEFILE:
12318 case SQL_QUIET_MODE:
12319 case SQL_TRANSLATE_DLL:
12320 case SQL_TRANSLATE_OPTION:
12321 case SQL_KEYSET_SIZE:
12322 case SQL_QUERY_TIMEOUT:
12323 case SQL_BIND_TYPE:
12324 case SQL_CURRENT_QUALIFIER:
12325 *((SQLINTEGER *) param) = 0;
12326 break;
12327 case SQL_USE_BOOKMARKS:
12328 *((SQLINTEGER *) param) = SQL_UB_OFF;
12329 break;
12330 case SQL_ASYNC_ENABLE:
12331 *((SQLINTEGER *) param) = SQL_ASYNC_ENABLE_OFF;
12332 break;
12333 case SQL_NOSCAN:
12334 *((SQLINTEGER *) param) = SQL_NOSCAN_ON;
12335 break;
12336 case SQL_CONCURRENCY:
12337 *((SQLINTEGER *) param) = SQL_CONCUR_LOCK;
12338 break;
12339 case SQL_SIMULATE_CURSOR:
12340 *((SQLINTEGER *) param) = SQL_SC_NON_UNIQUE;
12341 break;
12342 case SQL_MAX_ROWS:
12343 *((SQLINTEGER *) param) = 0;
12344 break;
12345 case SQL_ROWSET_SIZE:
12346 case SQL_MAX_LENGTH:
12347 *((SQLINTEGER *) param) = 1000000000;
12348 break;
12349 case SQL_CURSOR_TYPE:
12350 *((SQLINTEGER *) param) = d->curtype;
12351 break;
12352 case SQL_RETRIEVE_DATA:
12353 *((SQLINTEGER *) param) = SQL_RD_ON;
12354 break;
12355 default:
12356 *((SQLINTEGER *) param) = 0;
12357 setstatd(d, -1, "unsupported connect option %d",
12358 (*d->ov3) ? "HYC00" : "S1C00", opt);
12359 return SQL_ERROR;
12360 }
12361 return SQL_SUCCESS;
12362 }
12363
12364 #ifndef WINTERFACE
12365
12373 SQLRETURN SQL_API
12374 SQLGetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12375 {
12376 SQLRETURN ret;
12377
12378 HDBC_LOCK(dbc);
12379 ret = drvgetconnectoption(dbc, opt, param);
12380 HDBC_UNLOCK(dbc);
12381 return ret;
12382 }
12383 #endif
12384
12385 #ifdef WINTERFACE
12386
12394 SQLRETURN SQL_API
12395 SQLGetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLPOINTER param)
12396 {
12397 SQLRETURN ret;
12398
12399 HDBC_LOCK(dbc);
12400 ret = drvgetconnectoption(dbc, opt, param);
12401 if (SQL_SUCCEEDED(ret)) {
12402 switch (opt) {
12403 case SQL_OPT_TRACEFILE:
12404 case SQL_CURRENT_QUALIFIER:
12405 case SQL_TRANSLATE_DLL:
12406 if (param) {
12407 *(SQLWCHAR *) param = 0;
12408 }
12409 break;
12410 }
12411 }
12412 HDBC_UNLOCK(dbc);
12413 return ret;
12414 }
12415 #endif
12416
12425 static SQLRETURN
12426 drvsetconnectoption(SQLHDBC dbc, SQLUSMALLINT opt, SQLUINTEGER param)
12427 {
12428 DBC *d;
12429
12430 if (dbc == SQL_NULL_HDBC) {
12431 return SQL_INVALID_HANDLE;
12432 }
12433 d = (DBC *) dbc;
12434 switch (opt) {
12435 case SQL_AUTOCOMMIT:
12436 d->autocommit = param == SQL_AUTOCOMMIT_ON;
12437 if (d->autocommit && d->intrans) {
12438 return endtran(d, SQL_COMMIT, 1);
12439 } else if (!d->autocommit) {
12440 s3stmt_end(d->cur_s3stmt);
12441 }
12442 break;
12443 default:
12444 setstatd(d, -1, "option value changed", "01S02");
12445 return SQL_SUCCESS_WITH_INFO;
12446 }
12447 return SQL_SUCCESS;
12448 }
12449
12450 #ifndef WINTERFACE
12451
12459 SQLRETURN SQL_API
12460 SQLSetConnectOption(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12461 {
12462 SQLRETURN ret;
12463
12464 HDBC_LOCK(dbc);
12465 ret = drvsetconnectoption(dbc, opt, param);
12466 HDBC_UNLOCK(dbc);
12467 return ret;
12468 }
12469 #endif
12470
12471 #ifdef WINTERFACE
12472
12480 SQLRETURN SQL_API
12481 SQLSetConnectOptionW(SQLHDBC dbc, SQLUSMALLINT opt, SQLULEN param)
12482 {
12483 SQLRETURN ret;
12484
12485 HDBC_LOCK(dbc);
12486 ret = drvsetconnectoption(dbc, opt, param);
12487 HDBC_UNLOCK(dbc);
12488 return ret;
12489 }
12490 #endif
12491
12492 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12493
12504 static int
12505 getdsnattr(char *dsn, char *attr, char *out, int outLen)
12506 {
12507 char *str = dsn, *start;
12508 int len = strlen(attr);
12509
12510 while (*str) {
12511 while (*str && *str == ';') {
12512 ++str;
12513 }
12514 start = str;
12515 if ((str = strchr(str, '=')) == NULL) {
12516 return 0;
12517 }
12518 if (str - start == len && strncasecmp(start, attr, len) == 0) {
12519 start = ++str;
12520 while (*str && *str != ';') {
12521 ++str;
12522 }
12523 len = min(outLen - 1, str - start);
12524 strncpy(out, start, len);
12525 out[len] = '\0';
12526 return 1;
12527 }
12528 while (*str && *str != ';') {
12529 ++str;
12530 }
12531 }
12532 return 0;
12533 }
12534 #endif
12535
12547 static SQLRETURN
12548 drvconnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen, char *pwd,
12549 int pwdLen, int isu)
12550 {
12551 DBC *d;
12552 int len;
12553 SQLRETURN ret;
12554 char buf[SQL_MAX_MESSAGE_LENGTH * 6], dbname[SQL_MAX_MESSAGE_LENGTH];
12555 char busy[SQL_MAX_MESSAGE_LENGTH / 4], tracef[SQL_MAX_MESSAGE_LENGTH];
12556 char loadext[SQL_MAX_MESSAGE_LENGTH];
12557 char sflag[32], spflag[32], ntflag[32], nwflag[32], biflag[32];
12558 char snflag[32], lnflag[32], ncflag[32], fkflag[32], jmode[32];
12559 char jdflag[32];
12560 #if defined(_WIN32) || defined(_WIN64)
12561 char oemcp[32];
12562 #endif
12563
12564 if (dbc == SQL_NULL_HDBC) {
12565 return SQL_INVALID_HANDLE;
12566 }
12567 d = (DBC *) dbc;
12568 if (d->magic != DBC_MAGIC) {
12569 return SQL_INVALID_HANDLE;
12570 }
12571 if (d->sqlite != NULL) {
12572 setstatd(d, -1, "connection already established", "08002");
12573 return SQL_ERROR;
12574 }
12575 buf[0] = '\0';
12576 if (dsnLen == SQL_NTS) {
12577 len = sizeof (buf) - 1;
12578 } else {
12579 len = min(sizeof (buf) - 1, dsnLen);
12580 }
12581 if (dsn != NULL) {
12582 strncpy(buf, (char *) dsn, len);
12583 }
12584 buf[len] = '\0';
12585 if (buf[0] == '\0') {
12586 setstatd(d, -1, "invalid DSN", (*d->ov3) ? "HY090" : "S1090");
12587 return SQL_ERROR;
12588 }
12589 #if defined(_WIN32) || defined(_WIN64)
12590
12591
12592
12593
12594 if (isu) {
12595 char *cdsn = utf_to_wmb(buf, len);
12596
12597 if (!cdsn) {
12598 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12599 return SQL_ERROR;
12600 }
12601 strcpy(buf, cdsn);
12602 uc_free(cdsn);
12603 }
12604 #endif
12605 busy[0] = '\0';
12606 dbname[0] = '\0';
12607 #ifdef WITHOUT_DRIVERMGR
12608 getdsnattr(buf, "database", dbname, sizeof (dbname));
12609 if (dbname[0] == '\0') {
12610 strncpy(dbname, buf, sizeof (dbname));
12611 dbname[sizeof (dbname) - 1] = '\0';
12612 }
12613 getdsnattr(buf, "timeout", busy, sizeof (busy));
12614 sflag[0] = '\0';
12615 getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12616 spflag[0] = '\0';
12617 getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12618 ntflag[0] = '\0';
12619 getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12620 nwflag[0] = '\0';
12621 getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12622 snflag[0] = '\0';
12623 getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12624 lnflag[0] = '\0';
12625 getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12626 ncflag[0] = '\0';
12627 getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12628 fkflag[0] = '\0';
12629 getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12630 loadext[0] = '\0';
12631 getdsnattr(buf, "loadext", loadext, sizeof (loadext));
12632 jmode[0] = '\0';
12633 getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
12634 jdflag[0] = '\0';
12635 getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
12636 #if defined(_WIN32) || defined(_WIN64)
12637 oemcp[0] = '\0';
12638 getdsnattr(buf, "oemcp", oemcp, sizeof (oemcp));
12639 #endif
12640 biflag[0] = '\0';
12641 getdsnattr(buf, "bigint", biflag, sizeof (biflag));
12642 #else
12643 SQLGetPrivateProfileString(buf, "timeout", "100000",
12644 busy, sizeof (busy), ODBC_INI);
12645 SQLGetPrivateProfileString(buf, "database", "",
12646 dbname, sizeof (dbname), ODBC_INI);
12647 #if defined(_WIN32) || defined(_WIN64)
12648
12649 isu = 0;
12650 #endif
12651 SQLGetPrivateProfileString(buf, "stepapi", "",
12652 sflag, sizeof (sflag), ODBC_INI);
12653 SQLGetPrivateProfileString(buf, "syncpragma", "NORMAL",
12654 spflag, sizeof (spflag), ODBC_INI);
12655 SQLGetPrivateProfileString(buf, "notxn", "",
12656 ntflag, sizeof (ntflag), ODBC_INI);
12657 SQLGetPrivateProfileString(buf, "nowchar", "",
12658 nwflag, sizeof (nwflag), ODBC_INI);
12659 SQLGetPrivateProfileString(buf, "shortnames", "",
12660 snflag, sizeof (snflag), ODBC_INI);
12661 SQLGetPrivateProfileString(buf, "longnames", "",
12662 lnflag, sizeof (lnflag), ODBC_INI);
12663 SQLGetPrivateProfileString(buf, "nocreat", "",
12664 ncflag, sizeof (ncflag), ODBC_INI);
12665 SQLGetPrivateProfileString(buf, "fksupport", "",
12666 fkflag, sizeof (fkflag), ODBC_INI);
12667 SQLGetPrivateProfileString(buf, "loadext", "",
12668 loadext, sizeof (loadext), ODBC_INI);
12669 SQLGetPrivateProfileString(buf, "journalmode", "",
12670 jmode, sizeof (jmode), ODBC_INI);
12671 SQLGetPrivateProfileString(buf, "jdconv", "",
12672 jdflag, sizeof (jdflag), ODBC_INI);
12673 #if defined(_WIN32) || defined(_WIN64)
12674 SQLGetPrivateProfileString(buf, "oemcp", "1",
12675 oemcp, sizeof (oemcp), ODBC_INI);
12676 #endif
12677 SQLGetPrivateProfileString(buf, "bigint", "",
12678 biflag, sizeof (biflag), ODBC_INI);
12679 #endif
12680 tracef[0] = '\0';
12681 #ifdef WITHOUT_DRIVERMGR
12682 getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
12683 #else
12684 SQLGetPrivateProfileString(buf, "tracefile", "",
12685 tracef, sizeof (tracef), ODBC_INI);
12686 #endif
12687 if (tracef[0] != '\0') {
12688 d->trace = fopen(tracef, "a");
12689 }
12690 d->nowchar = getbool(nwflag);
12691 d->shortnames = getbool(snflag);
12692 d->longnames = getbool(lnflag);
12693 d->nocreat = getbool(ncflag);
12694 d->fksupport = getbool(fkflag);
12695 d->jdconv = getbool(jdflag);
12696 #if defined(_WIN32) || defined(_WIN64)
12697 d->oemcp = getbool(oemcp);
12698 #else
12699 d->oemcp = 0;
12700 #endif
12701 d->dobigint = getbool(biflag);
12702 d->pwd = pwd;
12703 d->pwdLen = 0;
12704 if (d->pwd) {
12705 d->pwdLen = (pwdLen == SQL_NTS) ? strlen(d->pwd) : pwdLen;
12706 }
12707 ret = dbopen(d, dbname, isu, (char *) dsn, sflag, spflag, ntflag,
12708 jmode, busy);
12709 if (ret == SQL_SUCCESS) {
12710 dbloadext(d, loadext);
12711 }
12712 return ret;
12713 }
12714
12715 #ifndef WINTERFACE
12716
12728 SQLRETURN SQL_API
12729 SQLConnect(SQLHDBC dbc, SQLCHAR *dsn, SQLSMALLINT dsnLen,
12730 SQLCHAR *uid, SQLSMALLINT uidLen,
12731 SQLCHAR *pwd, SQLSMALLINT pwdLen)
12732 {
12733 SQLRETURN ret;
12734
12735 HDBC_LOCK(dbc);
12736 ret = drvconnect(dbc, dsn, dsnLen, (char *) pwd, pwdLen, 0);
12737 HDBC_UNLOCK(dbc);
12738 return ret;
12739 }
12740 #endif
12741
12742 #ifdef WINTERFACE
12743
12755 SQLRETURN SQL_API
12756 SQLConnectW(SQLHDBC dbc, SQLWCHAR *dsn, SQLSMALLINT dsnLen,
12757 SQLWCHAR *uid, SQLSMALLINT uidLen,
12758 SQLWCHAR *pwd, SQLSMALLINT pwdLen)
12759 {
12760 char *dsna = NULL;
12761 char *pwda = NULL;
12762 SQLRETURN ret;
12763
12764 HDBC_LOCK(dbc);
12765 if (dsn) {
12766 dsna = uc_to_utf_c(dsn, dsnLen);
12767 if (!dsna) {
12768 DBC *d = (DBC *) dbc;
12769
12770 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12771 ret = SQL_ERROR;
12772 goto done;
12773 }
12774 }
12775 if (pwd) {
12776 pwda = uc_to_utf_c(pwd, pwdLen);
12777 if (!pwda) {
12778 DBC *d = (DBC *) dbc;
12779
12780 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
12781 ret = SQL_ERROR;
12782 goto done;
12783 }
12784 }
12785 ret = drvconnect(dbc, (SQLCHAR *) dsna, SQL_NTS, pwda, SQL_NTS, 1);
12786 done:
12787 HDBC_UNLOCK(dbc);
12788 uc_free(dsna);
12789 uc_free(pwda);
12790 return ret;
12791 }
12792 #endif
12793
12800 static SQLRETURN
12801 drvdisconnect(SQLHDBC dbc)
12802 {
12803 DBC *d;
12804 int rc;
12805
12806 if (dbc == SQL_NULL_HDBC) {
12807 return SQL_INVALID_HANDLE;
12808 }
12809 d = (DBC *) dbc;
12810 if (d->magic != DBC_MAGIC) {
12811 return SQL_INVALID_HANDLE;
12812 }
12813 if (d->intrans) {
12814 setstatd(d, -1, "incomplete transaction", "25000");
12815 return SQL_ERROR;
12816 }
12817 if (d->cur_s3stmt) {
12818 s3stmt_end(d->cur_s3stmt);
12819 }
12820 if (d->sqlite) {
12821 if (d->trace) {
12822 fprintf(d->trace, "-- sqlite3_close: '%s'\n",
12823 d->dbname);
12824 fflush(d->trace);
12825 }
12826 rc = sqlite3_close(d->sqlite);
12827 if (rc == SQLITE_BUSY) {
12828 setstatd(d, -1, "unfinished statements", "25000");
12829 return SQL_ERROR;
12830 }
12831 d->sqlite = NULL;
12832 }
12833 freep(&d->dbname);
12834 freep(&d->dsn);
12835 return SQL_SUCCESS;
12836 }
12837
12844 SQLRETURN SQL_API
12845 SQLDisconnect(SQLHDBC dbc)
12846 {
12847 SQLRETURN ret;
12848
12849 HDBC_LOCK(dbc);
12850 ret = drvdisconnect(dbc);
12851 HDBC_UNLOCK(dbc);
12852 return ret;
12853 }
12854
12855 #if defined(WITHOUT_DRIVERMGR) || (!defined(_WIN32) && !defined(_WIN64))
12856
12870 static SQLRETURN
12871 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
12872 SQLCHAR *connIn, SQLSMALLINT connInLen,
12873 SQLCHAR *connOut, SQLSMALLINT connOutMax,
12874 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
12875 {
12876 DBC *d;
12877 int len;
12878 SQLRETURN ret;
12879 char buf[SQL_MAX_MESSAGE_LENGTH * 8], dbname[SQL_MAX_MESSAGE_LENGTH];
12880 char dsn[SQL_MAX_MESSAGE_LENGTH], busy[SQL_MAX_MESSAGE_LENGTH / 4];
12881 char tracef[SQL_MAX_MESSAGE_LENGTH], loadext[SQL_MAX_MESSAGE_LENGTH];
12882 char pwd[SQL_MAX_MESSAGE_LENGTH];
12883 char sflag[32], spflag[32], ntflag[32], snflag[32], lnflag[32];
12884 char ncflag[32], nwflag[32], fkflag[32], jmode[32], biflag[32];
12885 char jdflag[32];
12886
12887 if (dbc == SQL_NULL_HDBC) {
12888 return SQL_INVALID_HANDLE;
12889 }
12890 if (drvcompl != SQL_DRIVER_COMPLETE &&
12891 drvcompl != SQL_DRIVER_COMPLETE_REQUIRED &&
12892 drvcompl != SQL_DRIVER_PROMPT &&
12893 drvcompl != SQL_DRIVER_NOPROMPT) {
12894 return SQL_NO_DATA;
12895 }
12896 d = (DBC *) dbc;
12897 if (d->sqlite) {
12898 setstatd(d, -1, "connection already established", "08002");
12899 return SQL_ERROR;
12900 }
12901 buf[0] = '\0';
12902 if (connInLen == SQL_NTS) {
12903 len = sizeof (buf) - 1;
12904 } else {
12905 len = min(connInLen, sizeof (buf) - 1);
12906 }
12907 if (connIn != NULL) {
12908 strncpy(buf, (char *) connIn, len);
12909 }
12910 buf[len] = '\0';
12911 if (!buf[0]) {
12912 setstatd(d, -1, "invalid connect attributes",
12913 (*d->ov3) ? "HY090" : "S1090");
12914 return SQL_ERROR;
12915 }
12916 dsn[0] = '\0';
12917 getdsnattr(buf, "DSN", dsn, sizeof (dsn));
12918
12919
12920 if (!dsn[0] && !strchr(buf, ';') && !strchr(buf, '=')) {
12921 strncpy(dsn, buf, sizeof (dsn) - 1);
12922 dsn[sizeof (dsn) - 1] = '\0';
12923 }
12924
12925 busy[0] = '\0';
12926 getdsnattr(buf, "timeout", busy, sizeof (busy));
12927 #ifndef WITHOUT_DRIVERMGR
12928 if (dsn[0] && !busy[0]) {
12929 SQLGetPrivateProfileString(dsn, "timeout", "100000",
12930 busy, sizeof (busy), ODBC_INI);
12931 }
12932 #endif
12933 dbname[0] = '\0';
12934 getdsnattr(buf, "database", dbname, sizeof (dbname));
12935 #ifndef WITHOUT_DRIVERMGR
12936 if (dsn[0] && !dbname[0]) {
12937 SQLGetPrivateProfileString(dsn, "database", "",
12938 dbname, sizeof (dbname), ODBC_INI);
12939 }
12940 #endif
12941 sflag[0] = '\0';
12942 getdsnattr(buf, "stepapi", sflag, sizeof (sflag));
12943 #ifndef WITHOUT_DRIVERMGR
12944 if (dsn[0] && !sflag[0]) {
12945 SQLGetPrivateProfileString(dsn, "stepapi", "",
12946 sflag, sizeof (sflag), ODBC_INI);
12947 }
12948 #endif
12949 spflag[0] = '\0';
12950 getdsnattr(buf, "syncpragma", spflag, sizeof (spflag));
12951 #ifndef WITHOUT_DRIVERMGR
12952 if (dsn[0] && !spflag[0]) {
12953 SQLGetPrivateProfileString(dsn, "syncpragma", "NORMAL",
12954 spflag, sizeof (spflag), ODBC_INI);
12955 }
12956 #endif
12957 ntflag[0] = '\0';
12958 getdsnattr(buf, "notxn", ntflag, sizeof (ntflag));
12959 #ifndef WITHOUT_DRIVERMGR
12960 if (dsn[0] && !ntflag[0]) {
12961 SQLGetPrivateProfileString(dsn, "notxn", "",
12962 ntflag, sizeof (ntflag), ODBC_INI);
12963 }
12964 #endif
12965 snflag[0] = '\0';
12966 getdsnattr(buf, "shortnames", snflag, sizeof (snflag));
12967 #ifndef WITHOUT_DRIVERMGR
12968 if (dsn[0] && !snflag[0]) {
12969 SQLGetPrivateProfileString(dsn, "shortnames", "",
12970 snflag, sizeof (snflag), ODBC_INI);
12971 }
12972 #endif
12973 lnflag[0] = '\0';
12974 getdsnattr(buf, "longnames", lnflag, sizeof (lnflag));
12975 #ifndef WITHOUT_DRIVERMGR
12976 if (dsn[0] && !lnflag[0]) {
12977 SQLGetPrivateProfileString(dsn, "longnames", "",
12978 lnflag, sizeof (lnflag), ODBC_INI);
12979 }
12980 #endif
12981 ncflag[0] = '\0';
12982 getdsnattr(buf, "nocreat", ncflag, sizeof (ncflag));
12983 #ifndef WITHOUT_DRIVERMGR
12984 if (dsn[0] && !ncflag[0]) {
12985 SQLGetPrivateProfileString(dsn, "nocreat", "",
12986 ncflag, sizeof (ncflag), ODBC_INI);
12987 }
12988 #endif
12989 nwflag[0] = '\0';
12990 getdsnattr(buf, "nowchar", nwflag, sizeof (nwflag));
12991 #ifndef WITHOUT_DRIVERMGR
12992 if (dsn[0] && !nwflag[0]) {
12993 SQLGetPrivateProfileString(dsn, "nowchar", "",
12994 nwflag, sizeof (nwflag), ODBC_INI);
12995 }
12996 #endif
12997 fkflag[0] = '\0';
12998 getdsnattr(buf, "fksupport", fkflag, sizeof (fkflag));
12999 #ifndef WITHOUT_DRIVERMGR
13000 if (dsn[0] && !fkflag[0]) {
13001 SQLGetPrivateProfileString(dsn, "fksupport", "",
13002 fkflag, sizeof (fkflag), ODBC_INI);
13003 }
13004 #endif
13005 loadext[0] = '\0';
13006 getdsnattr(buf, "loadext", loadext, sizeof (loadext));
13007 #ifndef WITHOUT_DRIVERMGR
13008 if (dsn[0] && !loadext[0]) {
13009 SQLGetPrivateProfileString(dsn, "loadext", "",
13010 loadext, sizeof (loadext), ODBC_INI);
13011 }
13012 #endif
13013 jmode[0] = '\0';
13014 getdsnattr(buf, "journalmode", jmode, sizeof (jmode));
13015 #ifndef WITHOUT_DRIVERMGR
13016 if (dsn[0] && !jmode[0]) {
13017 SQLGetPrivateProfileString(dsn, "journalmode", "",
13018 jmode, sizeof (jmode), ODBC_INI);
13019 }
13020 #endif
13021 biflag[0] = '\0';
13022 getdsnattr(buf, "bigint", biflag, sizeof (biflag));
13023 #ifndef WITHOUT_DRIVERMGR
13024 if (dsn[0] && !biflag[0]) {
13025 SQLGetPrivateProfileString(dsn, "bigint", "",
13026 biflag, sizeof (biflag), ODBC_INI);
13027 }
13028 #endif
13029 jdflag[0] = '\0';
13030 getdsnattr(buf, "jdconv", jdflag, sizeof (jdflag));
13031 #ifndef WITHOUT_DRIVERMGR
13032 if (dsn[0] && !jdflag[0]) {
13033 SQLGetPrivateProfileString(dsn, "jdconv", "",
13034 jdflag, sizeof (jdflag), ODBC_INI);
13035 }
13036 #endif
13037 pwd[0] = '\0';
13038 getdsnattr(buf, "pwd", pwd, sizeof (pwd));
13039 #ifndef WITHOUT_DRIVERMGR
13040 if (dsn[0] && !pwd[0]) {
13041 SQLGetPrivateProfileString(dsn, "pwd", "",
13042 pwd, sizeof (pwd), ODBC_INI);
13043 }
13044 #endif
13045
13046 if (!dbname[0] && !dsn[0]) {
13047 strcpy(dsn, "SQLite");
13048 strncpy(dbname, buf, sizeof (dbname));
13049 dbname[sizeof (dbname) - 1] = '\0';
13050 }
13051 tracef[0] = '\0';
13052 getdsnattr(buf, "tracefile", tracef, sizeof (tracef));
13053 #ifndef WITHOUT_DRIVERMGR
13054 if (dsn[0] && !tracef[0]) {
13055 SQLGetPrivateProfileString(dsn, "tracefile", "",
13056 tracef, sizeof (tracef), ODBC_INI);
13057 }
13058 #endif
13059 if (connOut || connOutLen) {
13060 int count;
13061
13062 buf[0] = '\0';
13063 count = snprintf(buf, sizeof (buf),
13064 "DSN=%s;Database=%s;StepAPI=%s;Timeout=%s;"
13065 "SyncPragma=%s;NoTXN=%s;ShortNames=%s;LongNames=%s;"
13066 "NoCreat=%s;NoWCHAR=%s;FKSupport=%s;Tracefile=%s;"
13067 "JournalMode=%s;LoadExt=%s;BigInt=%s;JDConv=%s;"
13068 "PWD=%s",
13069 dsn, dbname, sflag, busy, spflag, ntflag,
13070 snflag, lnflag, ncflag, nwflag, fkflag, tracef,
13071 jmode, loadext, biflag, jdflag, pwd);
13072 if (count < 0) {
13073 buf[sizeof (buf) - 1] = '\0';
13074 }
13075 len = min(connOutMax - 1, strlen(buf));
13076 if (connOut) {
13077 strncpy((char *) connOut, buf, len);
13078 connOut[len] = '\0';
13079 }
13080 if (connOutLen) {
13081 *connOutLen = len;
13082 }
13083 }
13084 if (tracef[0] != '\0') {
13085 d->trace = fopen(tracef, "a");
13086 }
13087 d->shortnames = getbool(snflag);
13088 d->longnames = getbool(lnflag);
13089 d->nocreat = getbool(ncflag);
13090 d->nowchar = getbool(nwflag);
13091 d->fksupport = getbool(fkflag);
13092 d->dobigint = getbool(biflag);
13093 d->jdconv = getbool(jdflag);
13094 d->oemcp = 0;
13095 d->pwdLen = strlen(pwd);
13096 d->pwd = (d->pwdLen > 0) ? pwd : NULL;
13097 ret = dbopen(d, dbname, 0, dsn, sflag, spflag, ntflag, jmode, busy);
13098 memset(pwd, 0, sizeof (pwd));
13099 if (ret == SQL_SUCCESS) {
13100 dbloadext(d, loadext);
13101 }
13102 return ret;
13103 }
13104 #endif
13105
13112 static SQLRETURN
13113 freestmt(SQLHSTMT stmt)
13114 {
13115 STMT *s;
13116 DBC *d;
13117
13118 if (stmt == SQL_NULL_HSTMT) {
13119 return SQL_INVALID_HANDLE;
13120 }
13121 s = (STMT *) stmt;
13122 s3stmt_drop(s);
13123 freeresult(s, 1);
13124 freep(&s->query);
13125 d = (DBC *) s->dbc;
13126 if (d && d->magic == DBC_MAGIC) {
13127 STMT *p, *n;
13128
13129 p = NULL;
13130 n = d->stmt;
13131 while (n) {
13132 if (n == s) {
13133 break;
13134 }
13135 p = n;
13136 n = n->next;
13137 }
13138 if (n) {
13139 if (p) {
13140 p->next = s->next;
13141 } else {
13142 d->stmt = s->next;
13143 }
13144 }
13145 }
13146 freeparams(s);
13147 freep(&s->bindparms);
13148 if (s->row_status0 != &s->row_status1) {
13149 freep(&s->row_status0);
13150 s->rowset_size = 1;
13151 s->row_status0 = &s->row_status1;
13152 }
13153 xfree(s);
13154 return SQL_SUCCESS;
13155 }
13156
13164 static SQLRETURN
13165 drvallocstmt(SQLHDBC dbc, SQLHSTMT *stmt)
13166 {
13167 DBC *d;
13168 STMT *s, *sl, *pl;
13169
13170 if (dbc == SQL_NULL_HDBC) {
13171 return SQL_INVALID_HANDLE;
13172 }
13173 d = (DBC *) dbc;
13174 if (d->magic != DBC_MAGIC || stmt == NULL) {
13175 return SQL_INVALID_HANDLE;
13176 }
13177 s = (STMT *) xmalloc(sizeof (STMT));
13178 if (s == NULL) {
13179 *stmt = SQL_NULL_HSTMT;
13180 return SQL_ERROR;
13181 }
13182 *stmt = (SQLHSTMT) s;
13183 memset(s, 0, sizeof (STMT));
13184 s->dbc = dbc;
13185 s->ov3 = d->ov3;
13186 s->bkmrk = SQL_UB_OFF;
13187 s->bkmrkptr = 0;
13188 s->oemcp = &d->oemcp;
13189 s->jdconv = &d->jdconv;
13190 s->nowchar[0] = d->nowchar;
13191 s->nowchar[1] = 0;
13192 s->dobigint = d->dobigint;
13193 s->curtype = d->curtype;
13194 s->row_status0 = &s->row_status1;
13195 s->rowset_size = 1;
13196 s->longnames = d->longnames;
13197 s->retr_data = SQL_RD_ON;
13198 s->max_rows = 0;
13199 s->bind_type = SQL_BIND_BY_COLUMN;
13200 s->bind_offs = NULL;
13201 s->paramset_size = 1;
13202 s->parm_bind_type = SQL_PARAM_BIND_BY_COLUMN;
13203 s->one_tbl = -1;
13204 s->has_pk = -1;
13205 s->has_rowid = -1;
13206 #ifdef _WIN64
13207 sprintf((char *) s->cursorname, "CUR_%I64X", (SQLUBIGINT) *stmt);
13208 #else
13209 sprintf((char *) s->cursorname, "CUR_%016lX", (long) *stmt);
13210 #endif
13211 sl = d->stmt;
13212 pl = NULL;
13213 while (sl) {
13214 pl = sl;
13215 sl = sl->next;
13216 }
13217 if (pl) {
13218 pl->next = s;
13219 } else {
13220 d->stmt = s;
13221 }
13222 return SQL_SUCCESS;
13223 }
13224
13232 SQLRETURN SQL_API
13233 SQLAllocStmt(SQLHDBC dbc, SQLHSTMT *stmt)
13234 {
13235 SQLRETURN ret;
13236
13237 HDBC_LOCK(dbc);
13238 ret = drvallocstmt(dbc, stmt);
13239 HDBC_UNLOCK(dbc);
13240 return ret;
13241 }
13242
13250 static SQLRETURN
13251 drvfreestmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13252 {
13253 STMT *s;
13254 SQLRETURN ret = SQL_SUCCESS;
13255 SQLHDBC dbc;
13256
13257 if (stmt == SQL_NULL_HSTMT) {
13258 return SQL_INVALID_HANDLE;
13259 }
13260 HSTMT_LOCK(stmt);
13261 s = (STMT *) stmt;
13262 dbc = s->dbc;
13263 switch (opt) {
13264 case SQL_RESET_PARAMS:
13265 freeparams(s);
13266 break;
13267 case SQL_UNBIND:
13268 unbindcols(s);
13269 break;
13270 case SQL_CLOSE:
13271 s3stmt_end_if(s);
13272 freeresult(s, 0);
13273 break;
13274 case SQL_DROP:
13275 s3stmt_end_if(s);
13276 ret = freestmt(stmt);
13277 break;
13278 default:
13279 setstat(s, -1, "unsupported option", (*s->ov3) ? "HYC00" : "S1C00");
13280 ret = SQL_ERROR;
13281 break;
13282 }
13283 HDBC_UNLOCK(dbc);
13284 return ret;
13285 }
13286
13294 SQLRETURN SQL_API
13295 SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT opt)
13296 {
13297 return drvfreestmt(stmt, opt);
13298 }
13299
13306 SQLRETURN SQL_API
13307 SQLCancel(SQLHSTMT stmt)
13308 {
13309 if (stmt != SQL_NULL_HSTMT) {
13310 DBC *d = (DBC *) ((STMT *) stmt)->dbc;
13311 #if defined(_WIN32) || defined(_WIN64)
13312
13313 if (d->magic == DBC_MAGIC && d->owner != GetCurrentThreadId() &&
13314 d->owner != 0) {
13315 d->busyint = 1;
13316 sqlite3_interrupt(d->sqlite);
13317 return SQL_SUCCESS;
13318 }
13319 #else
13320 if (d->magic == DBC_MAGIC) {
13321 d->busyint = 1;
13322 sqlite3_interrupt(d->sqlite);
13323 }
13324 #endif
13325 }
13326 return drvfreestmt(stmt, SQL_CLOSE);
13327 }
13328
13338 static SQLRETURN
13339 drvgetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13340 SQLSMALLINT *lenp)
13341 {
13342 STMT *s;
13343
13344 if (stmt == SQL_NULL_HSTMT) {
13345 return SQL_INVALID_HANDLE;
13346 }
13347 s = (STMT *) stmt;
13348 if (lenp && !cursor) {
13349 *lenp = strlen((char *) s->cursorname);
13350 return SQL_SUCCESS;
13351 }
13352 if (cursor) {
13353 if (buflen > 0) {
13354 strncpy((char *) cursor, (char *) s->cursorname, buflen - 1);
13355 cursor[buflen - 1] = '\0';
13356 }
13357 if (lenp) {
13358 *lenp = min(strlen((char *) s->cursorname), buflen - 1);
13359 }
13360 }
13361 return SQL_SUCCESS;
13362 }
13363
13364 #ifndef WINTERFACE
13365
13374 SQLRETURN SQL_API
13375 SQLGetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT buflen,
13376 SQLSMALLINT *lenp)
13377 {
13378 SQLRETURN ret;
13379 #if defined(_WIN32) || defined(_WIN64)
13380 SQLSMALLINT len = 0;
13381 #endif
13382
13383 HSTMT_LOCK(stmt);
13384 #if defined(_WIN32) || defined(_WIN64)
13385 if (!((STMT *) stmt)->oemcp[0]) {
13386 ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13387 goto done;
13388 }
13389 ret = drvgetcursorname(stmt, cursor, buflen, &len);
13390 if (ret == SQL_SUCCESS) {
13391 char *c = NULL;
13392
13393 if (cursor) {
13394 c = utf_to_wmb((char *) cursor, len);
13395 if (!c) {
13396 ret = nomem((STMT *) stmt);
13397 goto done;
13398 }
13399 c[len] = 0;
13400 len = strlen(c);
13401 if (buflen > 0) {
13402 strncpy((char *) cursor, c, buflen - 1);
13403 cursor[buflen - 1] = 0;
13404 }
13405 uc_free(c);
13406 }
13407 if (lenp) {
13408 *lenp = min(len, buflen - 1);
13409 }
13410 }
13411 done:
13412 ;
13413 #else
13414 ret = drvgetcursorname(stmt, cursor, buflen, lenp);
13415 #endif
13416 HSTMT_UNLOCK(stmt);
13417 return ret;
13418 }
13419 #endif
13420
13421 #ifdef WINTERFACE
13422
13431 SQLRETURN SQL_API
13432 SQLGetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT buflen,
13433 SQLSMALLINT *lenp)
13434 {
13435 SQLRETURN ret;
13436 SQLSMALLINT len = 0;
13437
13438 HSTMT_LOCK(stmt);
13439 ret = drvgetcursorname(stmt, (SQLCHAR *) cursor, buflen, &len);
13440 if (ret == SQL_SUCCESS) {
13441 SQLWCHAR *c = NULL;
13442
13443 if (cursor) {
13444 c = uc_from_utf((SQLCHAR *) cursor, len);
13445 if (!c) {
13446 ret = nomem((STMT *) stmt);
13447 goto done;
13448 }
13449 c[len] = 0;
13450 len = uc_strlen(c);
13451 if (buflen > 0) {
13452 uc_strncpy(cursor, c, buflen - 1);
13453 cursor[buflen - 1] = 0;
13454 }
13455 uc_free(c);
13456 }
13457 if (lenp) {
13458 *lenp = min(len, buflen - 1);
13459 }
13460 }
13461 done:
13462 HSTMT_UNLOCK(stmt);
13463 return ret;
13464 }
13465 #endif
13466
13475 static SQLRETURN
13476 drvsetcursorname(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13477 {
13478 STMT *s;
13479
13480 if (stmt == SQL_NULL_HSTMT) {
13481 return SQL_INVALID_HANDLE;
13482 }
13483 s = (STMT *) stmt;
13484 if (!cursor ||
13485 !((cursor[0] >= 'A' && cursor[0] <= 'Z') ||
13486 (cursor[0] >= 'a' && cursor[0] <= 'z'))) {
13487 setstat(s, -1, "invalid cursor name", (*s->ov3) ? "HYC00" : "S1C00");
13488 return SQL_ERROR;
13489 }
13490 if (len == SQL_NTS) {
13491 len = sizeof (s->cursorname) - 1;
13492 } else {
13493 len = min(sizeof (s->cursorname) - 1, len);
13494 }
13495 strncpy((char *) s->cursorname, (char *) cursor, len);
13496 s->cursorname[len] = '\0';
13497 return SQL_SUCCESS;
13498 }
13499
13500 #ifndef WINTERFACE
13501
13509 SQLRETURN SQL_API
13510 SQLSetCursorName(SQLHSTMT stmt, SQLCHAR *cursor, SQLSMALLINT len)
13511 {
13512 #if defined(_WIN32) || defined(_WIN64)
13513 char *c = NULL;
13514 #endif
13515 SQLRETURN ret;
13516
13517 HSTMT_LOCK(stmt);
13518 #if defined(_WIN32) || defined(_WIN64)
13519 if (!((STMT *) stmt)->oemcp[0]) {
13520 ret = drvsetcursorname(stmt, cursor, len);
13521 goto done2;
13522 }
13523 if (cursor) {
13524 c = wmb_to_utf_c((char *) cursor, len);
13525 if (!c) {
13526 ret = nomem((STMT *) stmt);
13527 goto done;
13528 }
13529 }
13530 ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13531 #else
13532 ret = drvsetcursorname(stmt, cursor, len);
13533 #endif
13534 #if defined(_WIN32) || defined(_WIN64)
13535 done:
13536 uc_free(c);
13537 done2:
13538 ;
13539 #endif
13540 HSTMT_UNLOCK(stmt);
13541 return ret;
13542 }
13543 #endif
13544
13545 #ifdef WINTERFACE
13546
13554 SQLRETURN SQL_API
13555 SQLSetCursorNameW(SQLHSTMT stmt, SQLWCHAR *cursor, SQLSMALLINT len)
13556 {
13557 char *c = NULL;
13558 SQLRETURN ret;
13559
13560 HSTMT_LOCK(stmt);
13561 if (cursor) {
13562 c = uc_to_utf_c(cursor, len);
13563 if (!c) {
13564 ret = nomem((STMT *) stmt);
13565 goto done;
13566 }
13567 }
13568 ret = drvsetcursorname(stmt, (SQLCHAR *) c, SQL_NTS);
13569 done:
13570 uc_free(c);
13571 HSTMT_UNLOCK(stmt);
13572 return ret;
13573 }
13574 #endif
13575
13582 SQLRETURN SQL_API
13583 SQLCloseCursor(SQLHSTMT stmt)
13584 {
13585 return drvfreestmt(stmt, SQL_CLOSE);
13586 }
13587
13596 SQLRETURN SQL_API
13597 SQLAllocHandle(SQLSMALLINT type, SQLHANDLE input, SQLHANDLE *output)
13598 {
13599 SQLRETURN ret;
13600
13601 switch (type) {
13602 case SQL_HANDLE_ENV:
13603 ret = drvallocenv((SQLHENV *) output);
13604 if (ret == SQL_SUCCESS) {
13605 ENV *e = (ENV *) *output;
13606
13607 if (e && e->magic == ENV_MAGIC) {
13608 e->ov3 = 1;
13609 }
13610 }
13611 return ret;
13612 case SQL_HANDLE_DBC:
13613 return drvallocconnect((SQLHENV) input, (SQLHDBC *) output);
13614 case SQL_HANDLE_STMT:
13615 HDBC_LOCK((SQLHDBC) input);
13616 ret = drvallocstmt((SQLHDBC) input, (SQLHSTMT *) output);
13617 HDBC_UNLOCK((SQLHDBC) input);
13618 return ret;
13619 }
13620 return SQL_ERROR;
13621 }
13622
13630 SQLRETURN SQL_API
13631 SQLFreeHandle(SQLSMALLINT type, SQLHANDLE h)
13632 {
13633 switch (type) {
13634 case SQL_HANDLE_ENV:
13635 return drvfreeenv((SQLHENV) h);
13636 case SQL_HANDLE_DBC:
13637 return drvfreeconnect((SQLHDBC) h);
13638 case SQL_HANDLE_STMT:
13639 return drvfreestmt((SQLHSTMT) h, SQL_DROP);
13640 }
13641 return SQL_ERROR;
13642 }
13643
13649 static void
13650 freedyncols(STMT *s)
13651 {
13652 if (s->dyncols) {
13653 int i;
13654
13655 for (i = 0; i < s->dcols; i++) {
13656 freep(&s->dyncols[i].typename);
13657 }
13658 if (s->cols == s->dyncols) {
13659 s->cols = NULL;
13660 s->ncols = 0;
13661 }
13662 freep(&s->dyncols);
13663 }
13664 s->dcols = 0;
13665 }
13666
13678 static void
13679 freeresult(STMT *s, int clrcols)
13680 {
13681 freep(&s->bincache);
13682 s->bincell = NULL;
13683 s->binlen = 0;
13684 if (s->rows) {
13685 if (s->rowfree) {
13686 s->rowfree(s->rows);
13687 s->rowfree = NULL;
13688 }
13689 s->rows = NULL;
13690 }
13691 s->nrows = -1;
13692 if (clrcols > 0) {
13693 freep(&s->bindcols);
13694 s->nbindcols = 0;
13695 }
13696 if (clrcols) {
13697 freedyncols(s);
13698 s->cols = NULL;
13699 s->ncols = 0;
13700 s->nowchar[1] = 0;
13701 s->one_tbl = -1;
13702 s->has_pk = -1;
13703 s->has_rowid = -1;
13704 }
13705 }
13706
13712 static void
13713 unbindcols(STMT *s)
13714 {
13715 int i;
13716
13717 for (i = 0; s->bindcols && i < s->nbindcols; i++) {
13718 s->bindcols[i].type = SQL_UNKNOWN_TYPE;
13719 s->bindcols[i].max = 0;
13720 s->bindcols[i].lenp = NULL;
13721 s->bindcols[i].valp = NULL;
13722 s->bindcols[i].index = i;
13723 s->bindcols[i].offs = 0;
13724 }
13725 }
13726
13734 static SQLRETURN
13735 mkbindcols(STMT *s, int ncols)
13736 {
13737 if (s->bindcols) {
13738 if (s->nbindcols < ncols) {
13739 int i;
13740 BINDCOL *bindcols =
13741 xrealloc(s->bindcols, ncols * sizeof (BINDCOL));
13742
13743 if (!bindcols) {
13744 return nomem(s);
13745 }
13746 for (i = s->nbindcols; i < ncols; i++) {
13747 bindcols[i].type = SQL_UNKNOWN_TYPE;
13748 bindcols[i].max = 0;
13749 bindcols[i].lenp = NULL;
13750 bindcols[i].valp = NULL;
13751 bindcols[i].index = i;
13752 bindcols[i].offs = 0;
13753 }
13754 s->bindcols = bindcols;
13755 s->nbindcols = ncols;
13756 }
13757 } else if (ncols > 0) {
13758 s->bindcols = (BINDCOL *) xmalloc(ncols * sizeof (BINDCOL));
13759 if (!s->bindcols) {
13760 return nomem(s);
13761 }
13762 s->nbindcols = ncols;
13763 unbindcols(s);
13764 }
13765 return SQL_SUCCESS;
13766 }
13767
13781 static SQLRETURN
13782 getrowdata(STMT *s, SQLUSMALLINT col, SQLSMALLINT otype,
13783 SQLPOINTER val, SQLINTEGER len, SQLLEN *lenp, int partial)
13784 {
13785 char **data, valdummy[16];
13786 SQLLEN dummy;
13787 SQLINTEGER *ilenp = NULL;
13788 int valnull = 0;
13789 int type = otype;
13790 SQLRETURN sret = SQL_NO_DATA;
13791
13792 if (!lenp) {
13793 lenp = &dummy;
13794 }
13795
13796 if (((SQLINTEGER *) lenp) + 1 == (SQLINTEGER *) val) {
13797 ilenp = (SQLINTEGER *) lenp;
13798 lenp = &dummy;
13799 }
13800 if (col >= s->ncols) {
13801 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
13802 return SQL_ERROR;
13803 }
13804 if (s->retr_data != SQL_RD_ON) {
13805 return SQL_SUCCESS;
13806 }
13807 if (!s->rows) {
13808 *lenp = SQL_NULL_DATA;
13809 goto done;
13810 }
13811 if (s->rowp < 0 || s->rowp >= s->nrows) {
13812 *lenp = SQL_NULL_DATA;
13813 goto done;
13814 }
13815 type = mapdeftype(type, s->cols[col].type, s->cols[col].nosign ? 1 : 0,
13816 s->nowchar[0]);
13817 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
13818
13819 if (type == SQL_C_WCHAR && otype == SQL_C_DEFAULT) {
13820 type = SQL_C_CHAR;
13821 }
13822 #endif
13823 data = s->rows + s->ncols + (s->rowp * s->ncols) + col;
13824 if (!val) {
13825 valnull = 1;
13826 val = (SQLPOINTER) valdummy;
13827 }
13828 if (*data == NULL) {
13829 *lenp = SQL_NULL_DATA;
13830 switch (type) {
13831 case SQL_C_UTINYINT:
13832 case SQL_C_TINYINT:
13833 case SQL_C_STINYINT:
13834 #ifdef SQL_BIT
13835 case SQL_C_BIT:
13836 #endif
13837 *((SQLCHAR *) val) = 0;
13838 break;
13839 case SQL_C_USHORT:
13840 case SQL_C_SHORT:
13841 case SQL_C_SSHORT:
13842 *((SQLSMALLINT *) val) = 0;
13843 break;
13844 case SQL_C_ULONG:
13845 case SQL_C_LONG:
13846 case SQL_C_SLONG:
13847 *((SQLINTEGER *) val) = 0;
13848 break;
13849 #ifdef SQL_BIGINT
13850 case SQL_C_SBIGINT:
13851 case SQL_C_UBIGINT:
13852 *((SQLBIGINT *) val) = 0;
13853 break;
13854 #endif
13855 case SQL_C_FLOAT:
13856 *((float *) val) = 0;
13857 break;
13858 case SQL_C_DOUBLE:
13859 *((double *) val) = 0;
13860 break;
13861 case SQL_C_BINARY:
13862 case SQL_C_CHAR:
13863 if (len > 0) {
13864 *((SQLCHAR *) val) = '\0';
13865 }
13866 break;
13867 #ifdef WCHARSUPPORT
13868 case SQL_C_WCHAR:
13869 if (len > 0) {
13870 *((SQLWCHAR *) val) = '\0';
13871 }
13872 break;
13873 #endif
13874 #ifdef SQL_C_TYPE_DATE
13875 case SQL_C_TYPE_DATE:
13876 #endif
13877 case SQL_C_DATE:
13878 memset((DATE_STRUCT *) val, 0, sizeof (DATE_STRUCT));
13879 break;
13880 #ifdef SQL_C_TYPE_TIME
13881 case SQL_C_TYPE_TIME:
13882 #endif
13883 case SQL_C_TIME:
13884 memset((TIME_STRUCT *) val, 0, sizeof (TIME_STRUCT));
13885 break;
13886 #ifdef SQL_C_TYPE_TIMESTAMP
13887 case SQL_C_TYPE_TIMESTAMP:
13888 #endif
13889 case SQL_C_TIMESTAMP:
13890 memset((TIMESTAMP_STRUCT *) val, 0, sizeof (TIMESTAMP_STRUCT));
13891 break;
13892 default:
13893 return SQL_ERROR;
13894 }
13895 } else {
13896 char *endp = NULL;
13897 #if defined(_WIN32) || defined(_WIN64)
13898 #ifdef SQL_BIGINT
13899 char endc;
13900 #endif
13901 #endif
13902
13903 switch (type) {
13904 case SQL_C_UTINYINT:
13905 case SQL_C_TINYINT:
13906 case SQL_C_STINYINT:
13907 *((SQLCHAR *) val) = strtol(*data, &endp, 0);
13908 if (endp && endp == *data) {
13909 *lenp = SQL_NULL_DATA;
13910 } else {
13911 *lenp = sizeof (SQLCHAR);
13912 }
13913 break;
13914 #ifdef SQL_BIT
13915 case SQL_C_BIT:
13916 *((SQLCHAR *) val) = getbool(*data);
13917 *lenp = sizeof (SQLCHAR);
13918 break;
13919 #endif
13920 case SQL_C_USHORT:
13921 case SQL_C_SHORT:
13922 case SQL_C_SSHORT:
13923 *((SQLSMALLINT *) val) = strtol(*data, &endp, 0);
13924 if (endp && endp == *data) {
13925 *lenp = SQL_NULL_DATA;
13926 } else {
13927 *lenp = sizeof (SQLSMALLINT);
13928 }
13929 break;
13930 case SQL_C_ULONG:
13931 case SQL_C_LONG:
13932 case SQL_C_SLONG:
13933 *((SQLINTEGER *) val) = strtol(*data, &endp, 0);
13934 if (endp && endp == *data) {
13935 *lenp = SQL_NULL_DATA;
13936 } else {
13937 *lenp = sizeof (SQLINTEGER);
13938 }
13939 break;
13940 #ifdef SQL_BIGINT
13941 case SQL_C_UBIGINT:
13942 #if defined(_WIN32) || defined(_WIN64)
13943 if (sscanf(*data, "%I64u%c", (SQLUBIGINT *) val, &endc) != 1) {
13944 *lenp = SQL_NULL_DATA;
13945 } else {
13946 *lenp = sizeof (SQLUBIGINT);
13947 }
13948 #else
13949 #ifdef __osf__
13950 *((SQLUBIGINT *) val) = strtoul(*data, &endp, 0);
13951 #else
13952 *((SQLUBIGINT *) val) = strtoull(*data, &endp, 0);
13953 #endif
13954 if (endp && endp == *data) {
13955 *lenp = SQL_NULL_DATA;
13956 } else {
13957 *lenp = sizeof (SQLUBIGINT);
13958 }
13959 #endif
13960 break;
13961 case SQL_C_SBIGINT:
13962 #if defined(_WIN32) || defined(_WIN64)
13963 if (sscanf(*data, "%I64d%c", (SQLBIGINT *) val, &endc) != 1) {
13964 *lenp = SQL_NULL_DATA;
13965 } else {
13966 *lenp = sizeof (SQLBIGINT);
13967 }
13968 #else
13969 #ifdef __osf__
13970 *((SQLBIGINT *) val) = strtol(*data, &endp, 0);
13971 #else
13972 *((SQLBIGINT *) val) = strtoll(*data, &endp, 0);
13973 #endif
13974 if (endp && endp == *data) {
13975 *lenp = SQL_NULL_DATA;
13976 } else {
13977 *lenp = sizeof (SQLBIGINT);
13978 }
13979 #endif
13980 break;
13981 #endif
13982 case SQL_C_FLOAT:
13983 *((float *) val) = ln_strtod(*data, &endp);
13984 if (endp && endp == *data) {
13985 *lenp = SQL_NULL_DATA;
13986 } else {
13987 *lenp = sizeof (float);
13988 }
13989 break;
13990 case SQL_C_DOUBLE:
13991 *((double *) val) = ln_strtod(*data, &endp);
13992 if (endp && endp == *data) {
13993 *lenp = SQL_NULL_DATA;
13994 } else {
13995 *lenp = sizeof (double);
13996 }
13997 break;
13998 case SQL_C_BINARY: {
13999 int dlen, offs = 0;
14000 char *bin;
14001
14002 if (valnull) {
14003 freep(&s->bincache);
14004 s->binlen = 0;
14005 goto doCHAR;
14006 }
14007 if (*data == s->bincell) {
14008 if (s->bincache) {
14009 bin = s->bincache;
14010 dlen = s->binlen;
14011 } else {
14012 goto doCHAR;
14013 }
14014 } else {
14015 char *dp;
14016 int i;
14017
14018 freep(&s->bincache);
14019 dp = *data;
14020 dlen = strlen(dp);
14021 s->bincell = dp;
14022 s->binlen = 0;
14023 if (!(dp[0] == 'x' || dp[0] == 'X') || dp[1] != '\'' ||
14024 dp[dlen - 1] != '\'') {
14025 goto doCHAR;
14026 }
14027 dlen -= 2;
14028 dp += 2;
14029 dlen = dlen / 2;
14030 s->bincache = bin = xmalloc(dlen + 1);
14031 if (!bin) {
14032 return nomem(s);
14033 }
14034 s->binlen = dlen;
14035 memset(bin, 0, dlen);
14036 bin[dlen] = '\0';
14037 for (i = 0; i < dlen; i++) {
14038 char *x;
14039 int v;
14040
14041 if (!*dp || !(x = strchr(xdigits, *dp))) {
14042 goto converr;
14043 }
14044 v = x - xdigits;
14045 bin[i] = (v >= 16) ? ((v - 6) << 4) : (v << 4);
14046 ++dp;
14047 if (!*dp || !(x = strchr(xdigits, *dp))) {
14048 converr:
14049 freep(&s->bincache);
14050 s->binlen = 0;
14051 setstat(s, -1, "conversion error",
14052 (*s->ov3) ? "HY000" : "S1000");
14053 return SQL_ERROR;
14054 }
14055 v = x - xdigits;
14056 bin[i] |= (v >= 16) ? (v - 6) : v;
14057 ++dp;
14058 }
14059 bin = s->bincache;
14060 }
14061 if (partial && len && s->bindcols) {
14062 if (s->bindcols[col].offs >= dlen) {
14063 *lenp = 0;
14064 if (!dlen && s->bindcols[col].offs == dlen) {
14065 s->bindcols[col].offs = 1;
14066 sret = SQL_SUCCESS;
14067 goto done;
14068 }
14069 s->bindcols[col].offs = 0;
14070 sret = SQL_NO_DATA;
14071 goto done;
14072 }
14073 offs = s->bindcols[col].offs;
14074 dlen -= offs;
14075 }
14076 if (val && len) {
14077 memcpy(val, bin + offs, min(len, dlen));
14078 }
14079 if (len < 1) {
14080 *lenp = dlen;
14081 } else {
14082 *lenp = min(len, dlen);
14083 if (*lenp == len && *lenp != dlen) {
14084 *lenp = SQL_NO_TOTAL;
14085 }
14086 }
14087 if (partial && len && s->bindcols) {
14088 if (*lenp == SQL_NO_TOTAL) {
14089 *lenp = dlen;
14090 s->bindcols[col].offs += len;
14091 setstat(s, -1, "data right truncated", "01004");
14092 if (s->bindcols[col].lenp) {
14093 *s->bindcols[col].lenp = dlen;
14094 }
14095 sret = SQL_SUCCESS_WITH_INFO;
14096 goto done;
14097 }
14098 s->bindcols[col].offs += *lenp;
14099 }
14100 if (*lenp == SQL_NO_TOTAL) {
14101 *lenp = dlen;
14102 setstat(s, -1, "data right truncated", "01004");
14103 sret = SQL_SUCCESS_WITH_INFO;
14104 goto done;
14105 }
14106 break;
14107 }
14108 doCHAR:
14109 #ifdef WCHARSUPPORT
14110 case SQL_C_WCHAR:
14111 #endif
14112 case SQL_C_CHAR: {
14113 int doz, zlen = len - 1;
14114 int dlen = strlen(*data);
14115 int offs = 0;
14116 #ifdef WCHARSUPPORT
14117 SQLWCHAR *ucdata = NULL;
14118 SQLCHAR *cdata = (SQLCHAR *) *data;
14119 #endif
14120
14121 #if (defined(_WIN32) || defined(_WIN64)) && defined(WINTERFACE)
14122
14123 if (!valnull &&
14124 (s->cols == statSpec2P || s->cols == statSpec3P) &&
14125 type == SQL_C_WCHAR) {
14126 if (len > 0 && len <= sizeof (SQLWCHAR)) {
14127 ((char *) val)[0] = data[0][0];
14128 memset((char *) val + 1, 0, len - 1);
14129 *lenp = 1;
14130 sret = SQL_SUCCESS;
14131 goto done;
14132 }
14133 }
14134 #endif
14135
14136 #ifdef WCHARSUPPORT
14137 switch (type) {
14138 case SQL_C_CHAR:
14139 doz = 1;
14140 break;
14141 case SQL_C_WCHAR:
14142 doz = sizeof (SQLWCHAR);
14143 break;
14144 default:
14145 doz = 0;
14146 break;
14147 }
14148 if (type == SQL_C_WCHAR) {
14149 ucdata = uc_from_utf(cdata, dlen);
14150 if (!ucdata) {
14151 return nomem(s);
14152 }
14153 dlen = uc_strlen(ucdata) * sizeof (SQLWCHAR);
14154 }
14155 #if defined(_WIN32) || defined(_WIN64)
14156 else if (*s->oemcp && type == SQL_C_CHAR) {
14157 ucdata = (SQLWCHAR *) utf_to_wmb((char *) cdata, dlen);
14158 if (!ucdata) {
14159 return nomem(s);
14160 }
14161 cdata = (SQLCHAR *) ucdata;
14162 dlen = strlen((char *) cdata);
14163 }
14164 #endif
14165 #else
14166 doz = (type == SQL_C_CHAR) ? 1 : 0;
14167 #endif
14168 if (partial && len && s->bindcols) {
14169 if (s->bindcols[col].offs >= dlen) {
14170 #ifdef WCHARSUPPORT
14171 uc_free(ucdata);
14172 #endif
14173 *lenp = 0;
14174 if (doz && val) {
14175 #ifdef WCHARSUPPORT
14176 if (type == SQL_C_WCHAR) {
14177 ((SQLWCHAR *) val)[0] = 0;
14178 } else {
14179 ((char *) val)[0] = '\0';
14180 }
14181 #else
14182 ((char *) val)[0] = '\0';
14183 #endif
14184 }
14185 if (!dlen && s->bindcols[col].offs == dlen) {
14186 s->bindcols[col].offs = 1;
14187 sret = SQL_SUCCESS;
14188 goto done;
14189 }
14190 s->bindcols[col].offs = 0;
14191 sret = SQL_NO_DATA;
14192 goto done;
14193 }
14194 offs = s->bindcols[col].offs;
14195 dlen -= offs;
14196 }
14197 if (val && !valnull && len) {
14198 #ifdef WCHARSUPPORT
14199 if (type == SQL_C_WCHAR) {
14200 uc_strncpy(val, ucdata + offs / sizeof (SQLWCHAR),
14201 (len - doz) / sizeof (SQLWCHAR));
14202 } else {
14203 strncpy(val, (char *) cdata + offs, len - doz);
14204 }
14205 #else
14206 strncpy(val, *data + offs, len - doz);
14207 #endif
14208 }
14209 if (valnull || len < 1) {
14210 *lenp = dlen;
14211 } else {
14212 *lenp = min(len - doz, dlen);
14213 if (*lenp == len - doz && *lenp != dlen) {
14214 *lenp = SQL_NO_TOTAL;
14215 } else if (*lenp < zlen) {
14216 zlen = *lenp;
14217 }
14218 }
14219 if (len && !valnull && doz) {
14220 #ifdef WCHARSUPPORT
14221 if (type == SQL_C_WCHAR) {
14222 ((SQLWCHAR *) val)[zlen / sizeof (SQLWCHAR)] = 0;
14223 } else {
14224 ((char *) val)[zlen] = '\0';
14225 }
14226 #else
14227 ((char *) val)[zlen] = '\0';
14228 #endif
14229 }
14230 #ifdef WCHARSUPPORT
14231 uc_free(ucdata);
14232 #endif
14233 if (partial && len && s->bindcols) {
14234 if (*lenp == SQL_NO_TOTAL) {
14235 *lenp = dlen;
14236 s->bindcols[col].offs += len - doz;
14237 setstat(s, -1, "data right truncated", "01004");
14238 if (s->bindcols[col].lenp) {
14239 *s->bindcols[col].lenp = dlen;
14240 }
14241 sret = SQL_SUCCESS_WITH_INFO;
14242 goto done;
14243 }
14244 s->bindcols[col].offs += *lenp;
14245 }
14246 if (*lenp == SQL_NO_TOTAL) {
14247 *lenp = dlen;
14248 setstat(s, -1, "data right truncated", "01004");
14249 sret = SQL_SUCCESS_WITH_INFO;
14250 goto done;
14251 }
14252 break;
14253 }
14254 #ifdef SQL_C_TYPE_DATE
14255 case SQL_C_TYPE_DATE:
14256 #endif
14257 case SQL_C_DATE:
14258 if (str2date(*s->jdconv, *data, (DATE_STRUCT *) val) < 0) {
14259 *lenp = SQL_NULL_DATA;
14260 } else {
14261 *lenp = sizeof (DATE_STRUCT);
14262 }
14263 break;
14264 #ifdef SQL_C_TYPE_TIME
14265 case SQL_C_TYPE_TIME:
14266 #endif
14267 case SQL_C_TIME:
14268 if (str2time(*s->jdconv, *data, (TIME_STRUCT *) val) < 0) {
14269 *lenp = SQL_NULL_DATA;
14270 } else {
14271 *lenp = sizeof (TIME_STRUCT);
14272 }
14273 break;
14274 #ifdef SQL_C_TYPE_TIMESTAMP
14275 case SQL_C_TYPE_TIMESTAMP:
14276 #endif
14277 case SQL_C_TIMESTAMP:
14278 if (str2timestamp(*s->jdconv, *data,
14279 (TIMESTAMP_STRUCT *) val) < 0) {
14280 *lenp = SQL_NULL_DATA;
14281 } else {
14282 *lenp = sizeof (TIMESTAMP_STRUCT);
14283 }
14284 switch (s->cols[col].prec) {
14285 case 0:
14286 ((TIMESTAMP_STRUCT *) val)->fraction = 0;
14287 break;
14288 case 1:
14289 ((TIMESTAMP_STRUCT *) val)->fraction /= 100000000;
14290 ((TIMESTAMP_STRUCT *) val)->fraction *= 100000000;
14291 break;
14292 case 2:
14293 ((TIMESTAMP_STRUCT *) val)->fraction /= 10000000;
14294 ((TIMESTAMP_STRUCT *) val)->fraction *= 10000000;
14295 break;
14296 }
14297 break;
14298 default:
14299 return SQL_ERROR;
14300 }
14301 }
14302 sret = SQL_SUCCESS;
14303 done:
14304 if (ilenp) {
14305 *ilenp = *lenp;
14306 }
14307 return sret;
14308 }
14309
14321 static SQLRETURN
14322 drvbindcol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14323 SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14324 {
14325 STMT *s;
14326 int sz = 0;
14327
14328 if (stmt == SQL_NULL_HSTMT) {
14329 return SQL_INVALID_HANDLE;
14330 }
14331 s = (STMT *) stmt;
14332 if (col < 1) {
14333 if (col == 0 && s->bkmrk == SQL_UB_ON &&
14334 type == SQL_C_BOOKMARK) {
14335 s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14336 s->bkmrkcol.max = val ? sizeof (SQLINTEGER) : 0;
14337 s->bkmrkcol.lenp = val ? lenp : 0;
14338 s->bkmrkcol.valp = val;
14339 s->bkmrkcol.offs = 0;
14340 if (val && lenp) {
14341 *lenp = 0;
14342 }
14343 return SQL_SUCCESS;
14344 } else if (col == 0 && s->bkmrk == SQL_UB_VARIABLE &&
14345 type == SQL_C_VARBOOKMARK &&
14346 max >= sizeof (sqlite_int64)) {
14347 s->bkmrkcol.type = val ? type : SQL_UNKNOWN_TYPE;
14348 s->bkmrkcol.max = val ? max : 0;
14349 s->bkmrkcol.lenp = val ? lenp : 0;
14350 s->bkmrkcol.valp = val;
14351 s->bkmrkcol.offs = 0;
14352 if (val && lenp) {
14353 *lenp = 0;
14354 }
14355 return SQL_SUCCESS;
14356 }
14357 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
14358 return SQL_ERROR;
14359 }
14360 if (mkbindcols(s, col) != SQL_SUCCESS) {
14361 return SQL_ERROR;
14362 }
14363 --col;
14364 if (type == SQL_C_DEFAULT) {
14365 type = mapdeftype(type, s->cols[col].type, 0,
14366 s->nowchar[0] || s->nowchar[1]);
14367 }
14368 switch (type) {
14369 case SQL_C_LONG:
14370 case SQL_C_ULONG:
14371 case SQL_C_SLONG:
14372 sz = sizeof (SQLINTEGER);
14373 break;
14374 case SQL_C_TINYINT:
14375 case SQL_C_UTINYINT:
14376 case SQL_C_STINYINT:
14377 sz = sizeof (SQLCHAR);
14378 break;
14379 case SQL_C_SHORT:
14380 case SQL_C_USHORT:
14381 case SQL_C_SSHORT:
14382 sz = sizeof (SQLSMALLINT);
14383 break;
14384 case SQL_C_FLOAT:
14385 sz = sizeof (SQLFLOAT);
14386 break;
14387 case SQL_C_DOUBLE:
14388 sz = sizeof (SQLDOUBLE);
14389 break;
14390 case SQL_C_TIMESTAMP:
14391 sz = sizeof (SQL_TIMESTAMP_STRUCT);
14392 break;
14393 case SQL_C_TIME:
14394 sz = sizeof (SQL_TIME_STRUCT);
14395 break;
14396 case SQL_C_DATE:
14397 sz = sizeof (SQL_DATE_STRUCT);
14398 break;
14399 case SQL_C_CHAR:
14400 break;
14401 #ifdef WCHARSUPPORT
14402 case SQL_C_WCHAR:
14403 break;
14404 #endif
14405 #ifdef SQL_C_TYPE_DATE
14406 case SQL_C_TYPE_DATE:
14407 sz = sizeof (SQL_DATE_STRUCT);
14408 break;
14409 #endif
14410 #ifdef SQL_C_TYPE_TIME
14411 case SQL_C_TYPE_TIME:
14412 sz = sizeof (SQL_TIME_STRUCT);
14413 break;
14414 #endif
14415 #ifdef SQL_C_TYPE_TIMESTAMP
14416 case SQL_C_TYPE_TIMESTAMP:
14417 sz = sizeof (SQL_TIMESTAMP_STRUCT);
14418 break;
14419 #endif
14420 #ifdef SQL_BIT
14421 case SQL_C_BIT:
14422 sz = sizeof (SQLCHAR);
14423 break;
14424 #endif
14425 case SQL_C_BINARY:
14426 break;
14427 #ifdef SQL_BIGINT
14428 case SQL_C_SBIGINT:
14429 case SQL_C_UBIGINT:
14430 sz = sizeof (SQLBIGINT);
14431 break;
14432 #endif
14433 default:
14434 if (val == NULL) {
14435
14436 break;
14437 }
14438 setstat(s, -1, "invalid type %d", "HY003", type);
14439 return SQL_ERROR;
14440 }
14441 if (val == NULL) {
14442
14443 s->bindcols[col].type = SQL_UNKNOWN_TYPE;
14444 s->bindcols[col].max = 0;
14445 s->bindcols[col].lenp = NULL;
14446 s->bindcols[col].valp = NULL;
14447 s->bindcols[col].offs = 0;
14448 } else {
14449 if (sz == 0 && max < 0) {
14450 setstat(s, -1, "invalid length", "HY090");
14451 return SQL_ERROR;
14452 }
14453 s->bindcols[col].type = type;
14454 s->bindcols[col].max = (sz == 0) ? max : sz;
14455 s->bindcols[col].lenp = lenp;
14456 s->bindcols[col].valp = val;
14457 s->bindcols[col].offs = 0;
14458 if (lenp) {
14459 *lenp = 0;
14460 }
14461 }
14462 return SQL_SUCCESS;
14463 }
14464
14476 SQLRETURN SQL_API
14477 SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
14478 SQLPOINTER val, SQLLEN max, SQLLEN *lenp)
14479 {
14480 SQLRETURN ret;
14481
14482 HSTMT_LOCK(stmt);
14483 ret = drvbindcol(stmt, col, type, val, max, lenp);
14484 HSTMT_UNLOCK(stmt);
14485 return ret;
14486 }
14487
14492 static COL tableSpec2[] = {
14493 { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14494 { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14495 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14496 { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14497 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14498 };
14499
14500 static COL tableSpec3[] = {
14501 { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14502 { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14503 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14504 { "SYSTEM", "COLUMN", "TABLE_TYPE", SCOL_VARCHAR, 50 },
14505 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 }
14506 };
14507
14522 static SQLRETURN
14523 drvtables(SQLHSTMT stmt,
14524 SQLCHAR *cat, SQLSMALLINT catLen,
14525 SQLCHAR *schema, SQLSMALLINT schemaLen,
14526 SQLCHAR *table, SQLSMALLINT tableLen,
14527 SQLCHAR *type, SQLSMALLINT typeLen)
14528 {
14529 SQLRETURN ret;
14530 STMT *s;
14531 DBC *d;
14532 int ncols, asize, rc, size, npatt;
14533 char *errp = NULL, *sql, tname[512];
14534 char *where = "(type = 'table' or type = 'view')";
14535
14536 ret = mkresultset(stmt, tableSpec2, array_size(tableSpec2),
14537 tableSpec3, array_size(tableSpec3), &asize);
14538 if (ret != SQL_SUCCESS) {
14539 return ret;
14540 }
14541 s = (STMT *) stmt;
14542 d = (DBC *) s->dbc;
14543 if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] == '%') {
14544 int size = 3 * asize;
14545
14546 s->rows = xmalloc(size * sizeof (char *));
14547 if (!s->rows) {
14548 s->nrows = 0;
14549 return nomem(s);
14550 }
14551 memset(s->rows, 0, sizeof (char *) * size);
14552 s->ncols = asize;
14553 s->rows[s->ncols + 0] = "";
14554 s->rows[s->ncols + 1] = "";
14555 s->rows[s->ncols + 2] = "";
14556 s->rows[s->ncols + 3] = "TABLE";
14557 s->rows[s->ncols + 5] = "";
14558 s->rows[s->ncols + 6] = "";
14559 s->rows[s->ncols + 7] = "";
14560 s->rows[s->ncols + 8] = "VIEW";
14561 #ifdef MEMORY_DEBUG
14562 s->rowfree = xfree__;
14563 #else
14564 s->rowfree = sqlite3_free;
14565 #endif
14566 s->nrows = 2;
14567 s->rowp = s->rowprs = -1;
14568 return SQL_SUCCESS;
14569 }
14570 if (cat && (catLen > 0 || catLen == SQL_NTS) && cat[0] == '%') {
14571 table = NULL;
14572 goto doit;
14573 }
14574 if (schema && (schemaLen > 0 || schemaLen == SQL_NTS) &&
14575 schema[0] == '%') {
14576 if ((!cat || catLen == 0 || !cat[0]) &&
14577 (!table || tableLen == 0 || !table[0])) {
14578 table = NULL;
14579 goto doit;
14580 }
14581 }
14582 if (type && (typeLen > 0 || typeLen == SQL_NTS) && type[0] != '\0') {
14583 char tmp[256], *t;
14584 int with_view = 0, with_table = 0;
14585
14586 if (typeLen == SQL_NTS) {
14587 strncpy(tmp, (char *) type, sizeof (tmp));
14588 tmp[sizeof (tmp) - 1] = '\0';
14589 } else {
14590 int len = min(sizeof (tmp) - 1, typeLen);
14591
14592 strncpy(tmp, (char *) type, len);
14593 tmp[len] = '\0';
14594 }
14595 t = tmp;
14596 while (*t) {
14597 *t = TOLOWER(*t);
14598 t++;
14599 }
14600 t = tmp;
14601 unescpat(t);
14602 while (t) {
14603 if (t[0] == '\'') {
14604 ++t;
14605 }
14606 if (strncmp(t, "table", 5) == 0) {
14607 with_table++;
14608 } else if (strncmp(t, "view", 4) == 0) {
14609 with_view++;
14610 }
14611 t = strchr(t, ',');
14612 if (t) {
14613 ++t;
14614 }
14615 }
14616 if (with_view && with_table) {
14617
14618 } else if (with_view && !with_table) {
14619 where = "type = 'view'";
14620 } else if (!with_view && with_table) {
14621 where = "type = 'table'";
14622 } else {
14623 return SQL_SUCCESS;
14624 }
14625 }
14626 doit:
14627 if (!table) {
14628 size = 1;
14629 tname[0] = '%';
14630 } else {
14631 if (tableLen == SQL_NTS) {
14632 size = sizeof (tname) - 1;
14633 } else {
14634 size = min(sizeof (tname) - 1, tableLen);
14635 }
14636 strncpy(tname, (char *) table, size);
14637 }
14638 tname[size] = '\0';
14639 npatt = unescpat(tname);
14640 #if defined(_WIN32) || defined(_WIN64)
14641 sql = sqlite3_mprintf("select %s as 'TABLE_CAT', "
14642 "%s as 'TABLE_SCHEM', "
14643 "tbl_name as 'TABLE_NAME', "
14644 "upper(type) as 'TABLE_TYPE', "
14645 "NULL as 'REMARKS' "
14646 "from sqlite_master where %s "
14647 "and tbl_name %s %Q",
14648 d->xcelqrx ? "'main'" : "NULL",
14649 d->xcelqrx ? "''" : "NULL",
14650 where,
14651 npatt ? "like" : "=", tname);
14652 #else
14653 sql = sqlite3_mprintf("select NULL as 'TABLE_QUALIFIER', "
14654 "NULL as 'TABLE_OWNER', "
14655 "tbl_name as 'TABLE_NAME', "
14656 "upper(type) as 'TABLE_TYPE', "
14657 "NULL as 'REMARKS' "
14658 "from sqlite_master where %s "
14659 "and tbl_name %s %Q", where,
14660 npatt ? "like" : "=", tname);
14661 #endif
14662 if (!sql) {
14663 return nomem(s);
14664 }
14665 ret = starttran(s);
14666 if (ret != SQL_SUCCESS) {
14667 sqlite3_free(sql);
14668 return ret;
14669 }
14670 dbtraceapi(d, "sqlite3_get_table", sql);
14671 rc = sqlite3_get_table(d->sqlite, sql, &s->rows, &s->nrows, &ncols, &errp);
14672 sqlite3_free(sql);
14673 if (rc == SQLITE_OK) {
14674 if (ncols != s->ncols) {
14675 freeresult(s, 0);
14676 s->nrows = 0;
14677 } else {
14678 s->rowfree = sqlite3_free_table;
14679 }
14680 } else {
14681 s->nrows = 0;
14682 s->rows = NULL;
14683 s->rowfree = NULL;
14684 }
14685 if (errp) {
14686 sqlite3_free(errp);
14687 errp = NULL;
14688 }
14689 s->rowp = s->rowprs = -1;
14690 return SQL_SUCCESS;
14691 }
14692
14693 #ifndef WINTERFACE
14694
14708 SQLRETURN SQL_API
14709 SQLTables(SQLHSTMT stmt,
14710 SQLCHAR *cat, SQLSMALLINT catLen,
14711 SQLCHAR *schema, SQLSMALLINT schemaLen,
14712 SQLCHAR *table, SQLSMALLINT tableLen,
14713 SQLCHAR *type, SQLSMALLINT typeLen)
14714 {
14715 #if defined(_WIN32) || defined(_WIN64)
14716 char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14717 #endif
14718 SQLRETURN ret;
14719
14720 HSTMT_LOCK(stmt);
14721 #if defined(_WIN32) || defined(_WIN64)
14722 if (!((STMT *) stmt)->oemcp[0]) {
14723 ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14724 table, tableLen, type, typeLen);
14725 goto done2;
14726 }
14727 if (cat) {
14728 c = wmb_to_utf_c((char *) cat, catLen);
14729 if (!c) {
14730 ret = nomem((STMT *) stmt);
14731 goto done;
14732 }
14733 }
14734 if (schema) {
14735 s = wmb_to_utf_c((char *) schema, schemaLen);
14736 if (!s) {
14737 ret = nomem((STMT *) stmt);
14738 goto done;
14739 }
14740 }
14741 if (table) {
14742 t = wmb_to_utf_c((char *) table, tableLen);
14743 if (!t) {
14744 ret = nomem((STMT *) stmt);
14745 goto done;
14746 }
14747 }
14748 if (type) {
14749 y = wmb_to_utf_c((char *) type, typeLen);
14750 if (!y) {
14751 ret = nomem((STMT *) stmt);
14752 goto done;
14753 }
14754 }
14755 ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14756 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14757 #else
14758 ret = drvtables(stmt, cat, catLen, schema, schemaLen,
14759 table, tableLen, type, typeLen);
14760 #endif
14761 #if defined(_WIN32) || defined(_WIN64)
14762 done:
14763 uc_free(y);
14764 uc_free(t);
14765 uc_free(s);
14766 uc_free(c);
14767 done2:
14768 ;
14769 #endif
14770 HSTMT_UNLOCK(stmt);
14771 return ret;
14772 }
14773 #endif
14774
14775 #ifdef WINTERFACE
14776
14790 SQLRETURN SQL_API
14791 SQLTablesW(SQLHSTMT stmt,
14792 SQLWCHAR *cat, SQLSMALLINT catLen,
14793 SQLWCHAR *schema, SQLSMALLINT schemaLen,
14794 SQLWCHAR *table, SQLSMALLINT tableLen,
14795 SQLWCHAR *type, SQLSMALLINT typeLen)
14796 {
14797 char *c = NULL, *s = NULL, *t = NULL, *y = NULL;
14798 SQLRETURN ret;
14799
14800 HSTMT_LOCK(stmt);
14801 if (cat) {
14802 c = uc_to_utf_c(cat, catLen);
14803 if (!c) {
14804 ret = nomem((STMT *) stmt);
14805 goto done;
14806 }
14807 }
14808 if (schema) {
14809 s = uc_to_utf_c(schema, schemaLen);
14810 if (!s) {
14811 ret = nomem((STMT *) stmt);
14812 goto done;
14813 }
14814 }
14815 if (table) {
14816 t = uc_to_utf_c(table, tableLen);
14817 if (!t) {
14818 ret = nomem((STMT *) stmt);
14819 goto done;
14820 }
14821 }
14822 if (type) {
14823 y = uc_to_utf_c(type, typeLen);
14824 if (!y) {
14825 ret = nomem((STMT *) stmt);
14826 goto done;
14827 }
14828 }
14829 ret = drvtables(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
14830 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) y, SQL_NTS);
14831 done:
14832 uc_free(y);
14833 uc_free(t);
14834 uc_free(s);
14835 uc_free(c);
14836 HSTMT_UNLOCK(stmt);
14837 return ret;
14838 }
14839 #endif
14840
14845 static COL colSpec2[] = {
14846 { "SYSTEM", "COLUMN", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
14847 { "SYSTEM", "COLUMN", "TABLE_OWNER", SCOL_VARCHAR, 50 },
14848 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14849 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
14850 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
14851 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
14852 { "SYSTEM", "COLUMN", "PRECISION", SQL_INTEGER, 50 },
14853 { "SYSTEM", "COLUMN", "LENGTH", SQL_INTEGER, 50 },
14854 { "SYSTEM", "COLUMN", "SCALE", SQL_SMALLINT, 50 },
14855 { "SYSTEM", "COLUMN", "RADIX", SQL_SMALLINT, 50 },
14856 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
14857 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
14858 { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
14859 { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
14860 { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
14861 { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
14862 { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
14863 { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
14864 };
14865
14866 static COL colSpec3[] = {
14867 { "SYSTEM", "COLUMN", "TABLE_CAT", SCOL_VARCHAR, 50 },
14868 { "SYSTEM", "COLUMN", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
14869 { "SYSTEM", "COLUMN", "TABLE_NAME", SCOL_VARCHAR, 255 },
14870 { "SYSTEM", "COLUMN", "COLUMN_NAME", SCOL_VARCHAR, 255 },
14871 { "SYSTEM", "COLUMN", "DATA_TYPE", SQL_SMALLINT, 50 },
14872 { "SYSTEM", "COLUMN", "TYPE_NAME", SCOL_VARCHAR, 50 },
14873 { "SYSTEM", "COLUMN", "COLUMN_SIZE", SQL_INTEGER, 50 },
14874 { "SYSTEM", "COLUMN", "BUFFER_LENGTH", SQL_INTEGER, 50 },
14875 { "SYSTEM", "COLUMN", "DECIMAL_DIGITS", SQL_SMALLINT, 50 },
14876 { "SYSTEM", "COLUMN", "NUM_PREC_RADIX", SQL_SMALLINT, 50 },
14877 { "SYSTEM", "COLUMN", "NULLABLE", SQL_SMALLINT, 50 },
14878 { "SYSTEM", "COLUMN", "REMARKS", SCOL_VARCHAR, 50 },
14879 { "SYSTEM", "COLUMN", "COLUMN_DEF", SCOL_VARCHAR, 50 },
14880 { "SYSTEM", "COLUMN", "SQL_DATA_TYPE", SQL_SMALLINT, 50 },
14881 { "SYSTEM", "COLUMN", "SQL_DATETIME_SUB", SQL_SMALLINT, 50 },
14882 { "SYSTEM", "COLUMN", "CHAR_OCTET_LENGTH", SQL_SMALLINT, 50 },
14883 { "SYSTEM", "COLUMN", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
14884 { "SYSTEM", "COLUMN", "IS_NULLABLE", SCOL_VARCHAR, 50 }
14885 };
14886
14901 static SQLRETURN
14902 drvcolumns(SQLHSTMT stmt,
14903 SQLCHAR *cat, SQLSMALLINT catLen,
14904 SQLCHAR *schema, SQLSMALLINT schemaLen,
14905 SQLCHAR *table, SQLSMALLINT tableLen,
14906 SQLCHAR *col, SQLSMALLINT colLen)
14907 {
14908 SQLRETURN sret;
14909 STMT *s;
14910 DBC *d;
14911 int ret, nrows, ncols, asize, i, k, roffs, namec;
14912 int tnrows, tncols, npatt;
14913 PTRDIFF_T size;
14914 char *errp = NULL, *sql, tname[512], cname[512], **rowp, **trows;
14915
14916 sret = mkresultset(stmt, colSpec2, array_size(colSpec2),
14917 colSpec3, array_size(colSpec3), &asize);
14918 if (sret != SQL_SUCCESS) {
14919 return sret;
14920 }
14921 s = (STMT *) stmt;
14922 d = (DBC *) s->dbc;
14923 if (!table) {
14924 size = 1;
14925 tname[0] = '%';
14926 } else {
14927 if (tableLen == SQL_NTS) {
14928 size = sizeof (tname) - 1;
14929 } else {
14930 size = min(sizeof (tname) - 1, tableLen);
14931 }
14932 strncpy(tname, (char *) table, size);
14933 }
14934 tname[size] = '\0';
14935 npatt = unescpat(tname);
14936 size = 0;
14937 if (col) {
14938 if (colLen == SQL_NTS) {
14939 size = sizeof (cname) - 1;
14940 } else {
14941 size = min(sizeof (cname) - 1, colLen);
14942 }
14943 strncpy(cname, (char *) col, size);
14944 }
14945 cname[size] = '\0';
14946 if (!strcmp(cname, "%")) {
14947 cname[0] = '\0';
14948 }
14949 sql = sqlite3_mprintf("select tbl_name from sqlite_master where "
14950 "(type = 'table' or type = 'view') "
14951 "and tbl_name %s %Q", npatt ? "like" : "=", tname);
14952 if (!sql) {
14953 return nomem(s);
14954 }
14955 sret = starttran(s);
14956 if (sret != SQL_SUCCESS) {
14957 sqlite3_free(sql);
14958 return sret;
14959 }
14960 dbtraceapi(d, "sqlite3_get_table", sql);
14961 ret = sqlite3_get_table(d->sqlite, sql, &trows, &tnrows, &tncols, &errp);
14962 sqlite3_free(sql);
14963 if (ret != SQLITE_OK) {
14964 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
14965 errp ? errp : "unknown error", ret);
14966 if (errp) {
14967 sqlite3_free(errp);
14968 errp = NULL;
14969 }
14970 return SQL_ERROR;
14971 }
14972 if (errp) {
14973 sqlite3_free(errp);
14974 errp = NULL;
14975 }
14976
14977 if (tncols * tnrows <= 0) {
14978 sqlite3_free_table(trows);
14979 return SQL_SUCCESS;
14980 }
14981 size = 0;
14982 for (i = 1; i <= tnrows; i++) {
14983 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
14984 if (!sql) {
14985 sqlite3_free_table(trows);
14986 return nomem(s);
14987 }
14988 dbtraceapi(d, "sqlite3_get_table", sql);
14989 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
14990 sqlite3_free(sql);
14991 if (ret != SQLITE_OK) {
14992 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
14993 errp ? errp : "unknown error", ret);
14994 if (errp) {
14995 sqlite3_free(errp);
14996 errp = NULL;
14997 }
14998 sqlite3_free_table(trows);
14999 return SQL_ERROR;
15000 }
15001 if (errp) {
15002 sqlite3_free(errp);
15003 errp = NULL;
15004 }
15005 if (ncols * nrows > 0) {
15006 namec = -1;
15007 for (k = 0; k < ncols; k++) {
15008 if (strcmp(rowp[k], "name") == 0) {
15009 namec = k;
15010 break;
15011 }
15012 }
15013 if (cname[0]) {
15014 if (namec >= 0) {
15015 for (k = 1; k <= nrows; k++) {
15016 if (namematch(rowp[k * ncols + namec], cname, 1)) {
15017 size++;
15018 }
15019 }
15020 }
15021 } else {
15022 size += nrows;
15023 }
15024 }
15025 sqlite3_free_table(rowp);
15026 }
15027
15028 if (size <= 0) {
15029 sqlite3_free_table(trows);
15030 return SQL_SUCCESS;
15031 }
15032 s->nrows = size;
15033 size = (size + 1) * asize;
15034 s->rows = xmalloc((size + 1) * sizeof (char *));
15035 if (!s->rows) {
15036 s->nrows = 0;
15037 sqlite3_free_table(trows);
15038 return nomem(s);
15039 }
15040 s->rows[0] = (char *) size;
15041 s->rows += 1;
15042 memset(s->rows, 0, sizeof (char *) * size);
15043 s->rowfree = freerows;
15044 roffs = 1;
15045 for (i = 1; i <= tnrows; i++) {
15046 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", trows[i]);
15047 if (!sql) {
15048 sqlite3_free_table(trows);
15049 return nomem(s);
15050 }
15051 dbtraceapi(d, "sqlite3_get_table", sql);
15052 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15053 sqlite3_free(sql);
15054 if (ret != SQLITE_OK) {
15055 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15056 errp ? errp : "unknown error", ret);
15057 if (errp) {
15058 sqlite3_free(errp);
15059 errp = NULL;
15060 }
15061 sqlite3_free_table(trows);
15062 return SQL_ERROR;
15063 }
15064 if (errp) {
15065 sqlite3_free(errp);
15066 errp = NULL;
15067 }
15068 if (ncols * nrows > 0) {
15069 int m, mr, nr = nrows;
15070
15071 namec = -1;
15072 for (k = 0; k < ncols; k++) {
15073 if (strcmp(rowp[k], "name") == 0) {
15074 namec = k;
15075 break;
15076 }
15077 }
15078 if (cname[0]) {
15079 nr = 0;
15080 if (namec >= 0) {
15081 for (k = 1; k <= nrows; k++) {
15082 if (namematch(rowp[k * ncols + namec], cname, 1)) {
15083 nr++;
15084 }
15085 }
15086 }
15087 }
15088 for (k = 0; k < nr; k++) {
15089 m = asize * (roffs + k);
15090 #if defined(_WIN32) || defined(_WIN64)
15091 s->rows[m + 0] = xstrdup(d->xcelqrx ? "main" : "");
15092 s->rows[m + 1] = xstrdup("");
15093 #else
15094 s->rows[m + 0] = xstrdup("");
15095 s->rows[m + 1] = xstrdup("");
15096 #endif
15097 s->rows[m + 2] = xstrdup(trows[i]);
15098 s->rows[m + 8] = xstrdup("10");
15099 s->rows[m + 9] = xstrdup("0");
15100 s->rows[m + 15] = xstrdup("16384");
15101 }
15102 for (k = 0; nr && k < ncols; k++) {
15103 if (strcmp(rowp[k], "cid") == 0) {
15104 for (mr = 0, m = 1; m <= nrows; m++) {
15105 char buf[256];
15106 int ir, coln = k;
15107
15108 if (cname[0] &&
15109 !namematch(rowp[m * ncols + namec], cname, 1)) {
15110 continue;
15111 }
15112 ir = asize * (roffs + mr);
15113 sscanf(rowp[m * ncols + k], "%d", &coln);
15114 sprintf(buf, "%d", coln + 1);
15115 s->rows[ir + 16] = xstrdup(buf);
15116 ++mr;
15117 }
15118 } else if (k == namec) {
15119 for (mr = 0, m = 1; m <= nrows; m++) {
15120 int ir;
15121
15122 if (cname[0] &&
15123 !namematch(rowp[m * ncols + namec], cname, 1)) {
15124 continue;
15125 }
15126 ir = asize * (roffs + mr);
15127 s->rows[ir + 3] = xstrdup(rowp[m * ncols + k]);
15128 ++mr;
15129 }
15130 } else if (strcmp(rowp[k], "notnull") == 0) {
15131 for (mr = 0, m = 1; m <= nrows; m++) {
15132 int ir;
15133
15134 if (cname[0] &&
15135 !namematch(rowp[m * ncols + namec], cname, 1)) {
15136 continue;
15137 }
15138 ir = asize * (roffs + mr);
15139 if (*rowp[m * ncols + k] != '0') {
15140 s->rows[ir + 10] = xstrdup(stringify(SQL_FALSE));
15141 } else {
15142 s->rows[ir + 10] = xstrdup(stringify(SQL_TRUE));
15143 }
15144 s->rows[ir + 17] =
15145 xstrdup((*rowp[m * ncols + k] != '0') ?
15146 "NO" : "YES");
15147 ++mr;
15148 }
15149 } else if (strcmp(rowp[k], "dflt_value") == 0) {
15150 for (mr = 0, m = 1; m <= nrows; m++) {
15151 char *dflt = unquote(rowp[m * ncols + k]);
15152 int ir;
15153
15154 if (cname[0] &&
15155 !namematch(rowp[m * ncols + namec], cname, 1)) {
15156 continue;
15157 }
15158 ir = asize * (roffs + mr);
15159 s->rows[ir + 12] = xstrdup(dflt ? dflt : "NULL");
15160 ++mr;
15161 }
15162 } else if (strcmp(rowp[k], "type") == 0) {
15163 for (mr = 0, m = 1; m <= nrows; m++) {
15164 char *typename = rowp[m * ncols + k];
15165 int sqltype, mm, dd, ir;
15166 char buf[256];
15167
15168 if (cname[0] &&
15169 !namematch(rowp[m * ncols + namec], cname, 1)) {
15170 continue;
15171 }
15172 ir = asize * (roffs + mr);
15173 s->rows[ir + 5] = xstrdup(typename);
15174 sqltype = mapsqltype(typename, NULL, *s->ov3,
15175 s->nowchar[0], s->dobigint);
15176 getmd(typename, sqltype, &mm, &dd);
15177 #ifdef SQL_LONGVARCHAR
15178 if (sqltype == SQL_VARCHAR && mm > 255) {
15179 sqltype = SQL_LONGVARCHAR;
15180 }
15181 #endif
15182 #ifdef WINTERFACE
15183 #ifdef SQL_WLONGVARCHAR
15184 if (sqltype == SQL_WVARCHAR && mm > 255) {
15185 sqltype = SQL_WLONGVARCHAR;
15186 }
15187 #endif
15188 #endif
15189 if (sqltype == SQL_VARBINARY && mm > 255) {
15190 sqltype = SQL_LONGVARBINARY;
15191 }
15192 sprintf(buf, "%d", sqltype);
15193 s->rows[ir + 4] = xstrdup(buf);
15194 s->rows[ir + 13] = xstrdup(buf);
15195 sprintf(buf, "%d", mm);
15196 s->rows[ir + 7] = xstrdup(buf);
15197 sprintf(buf, "%d", dd);
15198 s->rows[ir + 6] = xstrdup(buf);
15199 ++mr;
15200 }
15201 }
15202 }
15203 roffs += nr;
15204 }
15205 sqlite3_free_table(rowp);
15206 }
15207 sqlite3_free_table(trows);
15208 return SQL_SUCCESS;
15209 }
15210
15211 #ifndef WINTERFACE
15212
15226 SQLRETURN SQL_API
15227 SQLColumns(SQLHSTMT stmt,
15228 SQLCHAR *cat, SQLSMALLINT catLen,
15229 SQLCHAR *schema, SQLSMALLINT schemaLen,
15230 SQLCHAR *table, SQLSMALLINT tableLen,
15231 SQLCHAR *col, SQLSMALLINT colLen)
15232 {
15233 #if defined(_WIN32) || defined(_WIN64)
15234 char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15235 #endif
15236 SQLRETURN ret;
15237
15238 HSTMT_LOCK(stmt);
15239 #if defined(_WIN32) || defined(_WIN64)
15240 if (!((STMT *) stmt)->oemcp[0]) {
15241 ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15242 table, tableLen, col, colLen);
15243 goto done2;
15244 }
15245 if (cat) {
15246 c = wmb_to_utf_c((char *) cat, catLen);
15247 if (!c) {
15248 ret = nomem((STMT *) stmt);
15249 goto done;
15250 }
15251 }
15252 if (schema) {
15253 s = wmb_to_utf_c((char *) schema, schemaLen);
15254 if (!s) {
15255 ret = nomem((STMT *) stmt);
15256 goto done;
15257 }
15258 }
15259 if (table) {
15260 t = wmb_to_utf_c((char *) table, tableLen);
15261 if (!t) {
15262 ret = nomem((STMT *) stmt);
15263 goto done;
15264 }
15265 }
15266 if (col) {
15267 k = wmb_to_utf_c((char *) col, colLen);
15268 if (!k) {
15269 ret = nomem((STMT *) stmt);
15270 goto done;
15271 }
15272 }
15273 ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15274 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15275 #else
15276 ret = drvcolumns(stmt, cat, catLen, schema, schemaLen,
15277 table, tableLen, col, colLen);
15278 #endif
15279 #if defined(_WIN32) || defined(_WIN64)
15280 done:
15281 uc_free(k);
15282 uc_free(t);
15283 uc_free(s);
15284 uc_free(c);
15285 done2:
15286 ;
15287 #endif
15288 HSTMT_UNLOCK(stmt);
15289 return ret;
15290 }
15291 #endif
15292
15293 #ifdef WINTERFACE
15294
15308 SQLRETURN SQL_API
15309 SQLColumnsW(SQLHSTMT stmt,
15310 SQLWCHAR *cat, SQLSMALLINT catLen,
15311 SQLWCHAR *schema, SQLSMALLINT schemaLen,
15312 SQLWCHAR *table, SQLSMALLINT tableLen,
15313 SQLWCHAR *col, SQLSMALLINT colLen)
15314 {
15315 char *c = NULL, *s = NULL, *t = NULL, *k = NULL;
15316 SQLRETURN ret;
15317
15318 HSTMT_LOCK(stmt);
15319 if (cat) {
15320 c = uc_to_utf_c(cat, catLen);
15321 if (!c) {
15322 ret = nomem((STMT *) stmt);
15323 goto done;
15324 }
15325 }
15326 if (schema) {
15327 s = uc_to_utf_c(schema, schemaLen);
15328 if (!s) {
15329 ret = nomem((STMT *) stmt);
15330 goto done;
15331 }
15332 }
15333 if (table) {
15334 t = uc_to_utf_c(table, tableLen);
15335 if (!t) {
15336 ret = nomem((STMT *) stmt);
15337 goto done;
15338 }
15339 }
15340 if (col) {
15341 k = uc_to_utf_c(col, colLen);
15342 if (!k) {
15343 ret = nomem((STMT *) stmt);
15344 goto done;
15345 }
15346 }
15347 ret = drvcolumns(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
15348 (SQLCHAR *) t, SQL_NTS, (SQLCHAR *) k, SQL_NTS);
15349 done:
15350 uc_free(k);
15351 uc_free(t);
15352 uc_free(s);
15353 uc_free(c);
15354 HSTMT_UNLOCK(stmt);
15355 return ret;
15356
15357 }
15358 #endif
15359
15364 static COL typeSpec2[] = {
15365 { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15366 { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15367 { "SYSTEM", "TYPE", "PRECISION", SQL_INTEGER, 9 },
15368 { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15369 { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15370 { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15371 { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15372 { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15373 { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15374 { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15375 { "SYSTEM", "TYPE", "MONEY", SQL_SMALLINT, 2 },
15376 { "SYSTEM", "TYPE", "AUTO_INCREMENT", SQL_SMALLINT, 2 },
15377 { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15378 { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15379 { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 }
15380 };
15381
15382 static COL typeSpec3[] = {
15383 { "SYSTEM", "TYPE", "TYPE_NAME", SCOL_VARCHAR, 50 },
15384 { "SYSTEM", "TYPE", "DATA_TYPE", SQL_SMALLINT, 2 },
15385 { "SYSTEM", "TYPE", "COLUMN_SIZE", SQL_INTEGER, 9 },
15386 { "SYSTEM", "TYPE", "LITERAL_PREFIX", SCOL_VARCHAR, 50 },
15387 { "SYSTEM", "TYPE", "LITERAL_SUFFIX", SCOL_VARCHAR, 50 },
15388 { "SYSTEM", "TYPE", "CREATE_PARAMS", SCOL_VARCHAR, 50 },
15389 { "SYSTEM", "TYPE", "NULLABLE", SQL_SMALLINT, 2 },
15390 { "SYSTEM", "TYPE", "CASE_SENSITIVE", SQL_SMALLINT, 2 },
15391 { "SYSTEM", "TYPE", "SEARCHABLE", SQL_SMALLINT, 2 },
15392 { "SYSTEM", "TYPE", "UNSIGNED_ATTRIBUTE", SQL_SMALLINT, 2 },
15393 { "SYSTEM", "TYPE", "FIXED_PREC_SCALE", SQL_SMALLINT, 2 },
15394 { "SYSTEM", "TYPE", "AUTO_UNIQUE_VALUE", SQL_SMALLINT, 2 },
15395 { "SYSTEM", "TYPE", "LOCAL_TYPE_NAME", SCOL_VARCHAR, 50 },
15396 { "SYSTEM", "TYPE", "MINIMUM_SCALE", SQL_SMALLINT, 2 },
15397 { "SYSTEM", "TYPE", "MAXIMUM_SCALE", SQL_SMALLINT, 2 },
15398 { "SYSTEM", "TYPE", "SQL_DATA_TYPE", SQL_SMALLINT, 2 },
15399 { "SYSTEM", "TYPE", "SQL_DATETIME_SUB", SQL_SMALLINT, 2 },
15400 { "SYSTEM", "TYPE", "NUM_PREC_RADIX", SQL_INTEGER, 4 },
15401 { "SYSTEM", "TYPE", "INTERVAL_PRECISION", SQL_SMALLINT, 2 }
15402 };
15403
15414 static void
15415 mktypeinfo(STMT *s, int row, int asize, char *typename, int type, int tind)
15416 {
15417 int offs = row * asize;
15418 char *tcode, *crpar = NULL, *quote = NULL, *sign = stringify(SQL_FALSE);
15419 static char tcodes[32 * 32];
15420
15421 if (tind <= 0) {
15422 tind = row;
15423 }
15424 tcode = tcodes + tind * 32;
15425 sprintf(tcode, "%d", type);
15426 s->rows[offs + 0] = typename;
15427 s->rows[offs + 1] = tcode;
15428 if (asize >= 17) {
15429 s->rows[offs + 15] = tcode;
15430 s->rows[offs + 16] = "0";
15431 }
15432 switch (type) {
15433 default:
15434 #ifdef SQL_LONGVARCHAR
15435 case SQL_LONGVARCHAR:
15436 #ifdef WINTERFACE
15437 case SQL_WLONGVARCHAR:
15438 #endif
15439 crpar = "length";
15440 quote = "'";
15441 sign = NULL;
15442 s->rows[offs + 2] = "65536";
15443 break;
15444 #endif
15445 #ifdef SQL_BIT
15446 case SQL_BIT:
15447 sign = NULL;
15448 s->rows[offs + 2] = "1";
15449 break;
15450 #endif
15451 case SQL_CHAR:
15452 case SQL_VARCHAR:
15453 #ifdef WINTERFACE
15454 case SQL_WCHAR:
15455 case SQL_WVARCHAR:
15456 #endif
15457 s->rows[offs + 2] = "255";
15458 crpar = "length";
15459 quote = "'";
15460 sign = NULL;
15461 break;
15462 case SQL_TINYINT:
15463 s->rows[offs + 2] = "3";
15464 break;
15465 case SQL_SMALLINT:
15466 s->rows[offs + 2] = "5";
15467 break;
15468 case SQL_INTEGER:
15469 s->rows[offs + 2] = "9";
15470 break;
15471 #ifdef SQL_BIGINT
15472 case SQL_BIGINT:
15473 s->rows[offs + 2] = "19";
15474 break;
15475 #endif
15476 case SQL_FLOAT:
15477 s->rows[offs + 2] = "7";
15478 break;
15479 case SQL_DOUBLE:
15480 s->rows[offs + 2] = "15";
15481 break;
15482 #ifdef SQL_TYPE_DATE
15483 case SQL_TYPE_DATE:
15484 #endif
15485 case SQL_DATE:
15486 s->rows[offs + 2] = "10";
15487 quote = "'";
15488 sign = NULL;
15489 break;
15490 #ifdef SQL_TYPE_TIME
15491 case SQL_TYPE_TIME:
15492 #endif
15493 case SQL_TIME:
15494 s->rows[offs + 2] = "8";
15495 quote = "'";
15496 sign = NULL;
15497 break;
15498 #ifdef SQL_TYPE_TIMESTAMP
15499 case SQL_TYPE_TIMESTAMP:
15500 #endif
15501 case SQL_TIMESTAMP:
15502 s->rows[offs + 2] = "32";
15503 quote = "'";
15504 sign = NULL;
15505 break;
15506 case SQL_VARBINARY:
15507 sign = NULL;
15508 s->rows[offs + 2] = "255";
15509 break;
15510 case SQL_LONGVARBINARY:
15511 sign = NULL;
15512 s->rows[offs + 2] = "65536";
15513 break;
15514 }
15515 s->rows[offs + 3] = s->rows[offs + 4] = quote;
15516 s->rows[offs + 5] = crpar;
15517 s->rows[offs + 6] = stringify(SQL_NULLABLE);
15518 s->rows[offs + 7] = stringify(SQL_FALSE);
15519 s->rows[offs + 8] = stringify(SQL_SEARCHABLE);
15520 s->rows[offs + 9] = sign;
15521 s->rows[offs + 10] = stringify(SQL_FALSE);
15522 s->rows[offs + 11] = stringify(SQL_FALSE);
15523 s->rows[offs + 12] = typename;
15524 switch (type) {
15525 case SQL_DATE:
15526 case SQL_TIME:
15527 s->rows[offs + 13] = "0";
15528 s->rows[offs + 14] = "0";
15529 break;
15530 #ifdef SQL_TYPE_TIMESTAMP
15531 case SQL_TYPE_TIMESTAMP:
15532 #endif
15533 case SQL_TIMESTAMP:
15534 s->rows[offs + 13] = "0";
15535 s->rows[offs + 14] = "3";
15536 break;
15537 default:
15538 s->rows[offs + 13] = NULL;
15539 s->rows[offs + 14] = NULL;
15540 break;
15541 }
15542 }
15543
15552 static int
15553 typeinfosort(const void *a, const void *b)
15554 {
15555 char **pa = (char **) a;
15556 char **pb = (char **) b;
15557 int na, nb;
15558
15559 na = strtol(pa[1], NULL, 0);
15560 nb = strtol(pb[1], NULL, 0);
15561 return na - nb;
15562 }
15563
15571 static SQLRETURN
15572 drvgettypeinfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15573 {
15574 SQLRETURN ret;
15575 STMT *s;
15576 int asize;
15577
15578 ret = mkresultset(stmt, typeSpec2, array_size(typeSpec2),
15579 typeSpec3, array_size(typeSpec3), &asize);
15580 if (ret != SQL_SUCCESS) {
15581 return ret;
15582 }
15583 s = (STMT *) stmt;
15584 #ifdef SQL_LONGVARCHAR
15585 s->nrows = (sqltype == SQL_ALL_TYPES) ? 13 : 1;
15586 #else
15587 s->nrows = (sqltype == SQL_ALL_TYPES) ? 12 : 1;
15588 #endif
15589 if (sqltype == SQL_ALL_TYPES) {
15590 #ifdef WINTERFACE
15591 s->nrows += 2;
15592 #ifdef SQL_WLONGVARCHAR
15593 s->nrows += 2;
15594 #endif
15595 #endif
15596 }
15597 if (sqltype == SQL_ALL_TYPES) {
15598 s->nrows += 2;
15599 #ifdef SQL_BIT
15600 s->nrows += 1;
15601 #endif
15602 #ifdef SQL_BIGINT
15603 s->nrows += 1;
15604 #endif
15605 }
15606 s->rows = (char **) xmalloc(sizeof (char *) * (s->nrows + 1) * asize);
15607 if (!s->rows) {
15608 s->nrows = 0;
15609 return nomem(s);
15610 }
15611 #ifdef MEMORY_DEBUG
15612 s->rowfree = xfree__;
15613 #else
15614 s->rowfree = sqlite3_free;
15615 #endif
15616 memset(s->rows, 0, sizeof (char *) * (s->nrows + 1) * asize);
15617 if (sqltype == SQL_ALL_TYPES) {
15618 int cc = 1;
15619
15620 mktypeinfo(s, cc++, asize, "varchar", SQL_VARCHAR, 0);
15621 mktypeinfo(s, cc++, asize, "tinyint", SQL_TINYINT, 0);
15622 mktypeinfo(s, cc++, asize, "smallint", SQL_SMALLINT, 0);
15623 mktypeinfo(s, cc++, asize, "integer", SQL_INTEGER, 0);
15624 mktypeinfo(s, cc++, asize, "float", SQL_FLOAT, 0);
15625 mktypeinfo(s, cc++, asize, "double", SQL_DOUBLE, 0);
15626 #ifdef SQL_TYPE_DATE
15627 mktypeinfo(s, cc++, asize, "date",
15628 (*s->ov3) ? SQL_TYPE_DATE : SQL_DATE, 0);
15629 #else
15630 mktypeinfo(s, cc++, asize, "date", SQL_DATE, 0);
15631 #endif
15632 #ifdef SQL_TYPE_TIME
15633 mktypeinfo(s, cc++, asize, "time",
15634 (*s->ov3) ? SQL_TYPE_TIME : SQL_TIME, 0);
15635 #else
15636 mktypeinfo(s, cc++, asize, "time", SQL_TIME, 0);
15637 #endif
15638 #ifdef SQL_TYPE_TIMESTAMP
15639 mktypeinfo(s, cc++, asize, "timestamp",
15640 (*s->ov3) ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP, 0);
15641 #else
15642 mktypeinfo(s, cc++, asize, "timestamp", SQL_TIMESTAMP, 0);
15643 #endif
15644 mktypeinfo(s, cc++, asize, "char", SQL_CHAR, 0);
15645 mktypeinfo(s, cc++, asize, "numeric", SQL_DOUBLE, 0);
15646 #ifdef SQL_LONGVARCHAR
15647 mktypeinfo(s, cc++, asize, "text", SQL_LONGVARCHAR, 0);
15648 mktypeinfo(s, cc++, asize, "longvarchar", SQL_LONGVARCHAR, 0);
15649 #else
15650 mktypeinfo(s, cc++, asize, "text", SQL_VARCHAR, 0);
15651 #endif
15652 mktypeinfo(s, cc++, asize, "varbinary", SQL_VARBINARY, 0);
15653 mktypeinfo(s, cc++, asize, "longvarbinary", SQL_LONGVARBINARY, 0);
15654 #ifdef SQL_BIT
15655 mktypeinfo(s, cc++, asize, "bit", SQL_BIT, 0);
15656 #endif
15657 #ifdef SQL_BIGINT
15658 mktypeinfo(s, cc++, asize, "bigint", SQL_BIGINT, 0);
15659 #endif
15660 #ifdef WINTERFACE
15661 mktypeinfo(s, cc++, asize, "wvarchar", SQL_WVARCHAR, 0);
15662 mktypeinfo(s, cc++, asize, "wchar", SQL_WCHAR, 0);
15663 #ifdef SQL_WLONGVARCHAR
15664 mktypeinfo(s, cc++, asize, "wtext", SQL_WLONGVARCHAR, 0);
15665 mktypeinfo(s, cc++, asize, "longwvarchar", SQL_WLONGVARCHAR, 0);
15666 #endif
15667 #endif
15668 qsort(s->rows + asize, s->nrows, sizeof (char *) * asize,
15669 typeinfosort);
15670 } else {
15671 switch (sqltype) {
15672 case SQL_CHAR:
15673 mktypeinfo(s, 1, asize, "char", SQL_CHAR, 10);
15674 break;
15675 case SQL_VARCHAR:
15676 mktypeinfo(s, 1, asize, "varchar", SQL_VARCHAR, 1);
15677 break;
15678 case SQL_TINYINT:
15679 mktypeinfo(s, 1, asize, "tinyint", SQL_TINYINT, 2);
15680 break;
15681 case SQL_SMALLINT:
15682 mktypeinfo(s, 1, asize, "smallint", SQL_SMALLINT, 3);
15683 break;
15684 case SQL_INTEGER:
15685 mktypeinfo(s, 1, asize, "integer", SQL_INTEGER, 4);
15686 break;
15687 case SQL_FLOAT:
15688 mktypeinfo(s, 1, asize, "float", SQL_FLOAT, 5);
15689 break;
15690 case SQL_DOUBLE:
15691 mktypeinfo(s, 1, asize, "double", SQL_DOUBLE, 6);
15692 break;
15693 #ifdef SQL_TYPE_DATE
15694 case SQL_TYPE_DATE:
15695 mktypeinfo(s, 1, asize, "date", SQL_TYPE_DATE, 25);
15696 break;
15697 #endif
15698 case SQL_DATE:
15699 mktypeinfo(s, 1, asize, "date", SQL_DATE, 7);
15700 break;
15701 #ifdef SQL_TYPE_TIME
15702 case SQL_TYPE_TIME:
15703 mktypeinfo(s, 1, asize, "time", SQL_TYPE_TIME, 26);
15704 break;
15705 #endif
15706 case SQL_TIME:
15707 mktypeinfo(s, 1, asize, "time", SQL_TIME, 8);
15708 break;
15709 #ifdef SQL_TYPE_TIMESTAMP
15710 case SQL_TYPE_TIMESTAMP:
15711 mktypeinfo(s, 1, asize, "timestamp", SQL_TYPE_TIMESTAMP, 27);
15712 break;
15713 #endif
15714 case SQL_TIMESTAMP:
15715 mktypeinfo(s, 1, asize, "timestamp", SQL_TIMESTAMP, 9);
15716 break;
15717 #ifdef SQL_LONGVARCHAR
15718 case SQL_LONGVARCHAR:
15719 mktypeinfo(s, 1, asize, "longvarchar", SQL_LONGVARCHAR, 12);
15720 break;
15721 #endif
15722 case SQL_VARBINARY:
15723 mktypeinfo(s, 1, asize, "varbinary", SQL_VARBINARY, 30);
15724 break;
15725 case SQL_LONGVARBINARY:
15726 mktypeinfo(s, 1, asize, "longvarbinary", SQL_LONGVARBINARY, 31);
15727 break;
15728 #ifdef SQL_BIT
15729 case SQL_BIT:
15730 mktypeinfo(s, 1, asize, "bit", SQL_BIT, 29);
15731 break;
15732 #endif
15733 #ifdef SQL_BIGINT
15734 case SQL_BIGINT:
15735 mktypeinfo(s, 1, asize, "bigint", SQL_BIGINT, 28);
15736 break;
15737 #endif
15738 #ifdef WINTERFACE
15739 #ifdef SQL_WCHAR
15740 case SQL_WCHAR:
15741 mktypeinfo(s, 1, asize, "wchar", SQL_WCHAR, 18);
15742 break;
15743 #endif
15744 #ifdef SQL_WVARCHAR
15745 case SQL_WVARCHAR:
15746 mktypeinfo(s, 1, asize, "wvarchar", SQL_WVARCHAR, 19);
15747 break;
15748 #endif
15749 #ifdef SQL_WLONGVARCHAR
15750 case SQL_WLONGVARCHAR:
15751 mktypeinfo(s, 1, asize, "longwvarchar", SQL_WLONGVARCHAR, 20);
15752 break;
15753 #endif
15754 #endif
15755 default:
15756 s->nrows = 0;
15757 }
15758 }
15759 return SQL_SUCCESS;
15760 }
15761
15762 #ifndef WINTERFACE
15763
15770 SQLRETURN SQL_API
15771 SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT sqltype)
15772 {
15773 SQLRETURN ret;
15774
15775 HSTMT_LOCK(stmt);
15776 ret = drvgettypeinfo(stmt, sqltype);
15777 HSTMT_UNLOCK(stmt);
15778 return ret;
15779 }
15780 #endif
15781
15782 #ifdef WINTERFACE
15783
15790 SQLRETURN SQL_API
15791 SQLGetTypeInfoW(SQLHSTMT stmt, SQLSMALLINT sqltype)
15792 {
15793 SQLRETURN ret;
15794
15795 HSTMT_LOCK(stmt);
15796 ret = drvgettypeinfo(stmt, sqltype);
15797 HSTMT_UNLOCK(stmt);
15798 return ret;
15799 }
15800 #endif
15801
15806 static COL statSpec2[] = {
15807 { "SYSTEM", "STATISTICS", "TABLE_QUALIFIER", SCOL_VARCHAR, 50 },
15808 { "SYSTEM", "STATISTICS", "TABLE_OWNER", SCOL_VARCHAR, 50 },
15809 { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15810 { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15811 { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
15812 { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
15813 { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
15814 { "SYSTEM", "STATISTICS", "SEQ_IN_INDEX", SQL_SMALLINT, 50 },
15815 { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15816 { "SYSTEM", "STATISTICS", "COLLATION", SCOL_CHAR, 1 },
15817 { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
15818 { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
15819 { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
15820 };
15821
15822 static COL statSpec3[] = {
15823 { "SYSTEM", "STATISTICS", "TABLE_CAT", SCOL_VARCHAR, 50 },
15824 { "SYSTEM", "STATISTICS", "TABLE_SCHEM", SCOL_VARCHAR, 50 },
15825 { "SYSTEM", "STATISTICS", "TABLE_NAME", SCOL_VARCHAR, 255 },
15826 { "SYSTEM", "STATISTICS", "NON_UNIQUE", SQL_SMALLINT, 50 },
15827 { "SYSTEM", "STATISTICS", "INDEX_QUALIFIER", SCOL_VARCHAR, 255 },
15828 { "SYSTEM", "STATISTICS", "INDEX_NAME", SCOL_VARCHAR, 255 },
15829 { "SYSTEM", "STATISTICS", "TYPE", SQL_SMALLINT, 50 },
15830 { "SYSTEM", "STATISTICS", "ORDINAL_POSITION", SQL_SMALLINT, 50 },
15831 { "SYSTEM", "STATISTICS", "COLUMN_NAME", SCOL_VARCHAR, 255 },
15832 { "SYSTEM", "STATISTICS", "ASC_OR_DESC", SCOL_CHAR, 1 },
15833 { "SYSTEM", "STATISTICS", "CARDINALITY", SQL_INTEGER, 50 },
15834 { "SYSTEM", "STATISTICS", "PAGES", SQL_INTEGER, 50 },
15835 { "SYSTEM", "STATISTICS", "FILTER_CONDITION", SCOL_VARCHAR, 255 }
15836 };
15837
15852 static SQLRETURN
15853 drvstatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
15854 SQLCHAR *schema, SQLSMALLINT schemaLen,
15855 SQLCHAR *table, SQLSMALLINT tableLen,
15856 SQLUSMALLINT itype, SQLUSMALLINT resv)
15857 {
15858 SQLRETURN sret;
15859 STMT *s;
15860 DBC *d;
15861 int i, asize, ret, nrows, ncols, offs, namec, uniquec, addipk = 0;
15862 PTRDIFF_T size;
15863 char **rowp, *errp = NULL, *sql, tname[512];
15864
15865 sret = mkresultset(stmt, statSpec2, array_size(statSpec2),
15866 statSpec3, array_size(statSpec3), &asize);
15867 if (sret != SQL_SUCCESS) {
15868 return sret;
15869 }
15870 s = (STMT *) stmt;
15871 d = (DBC *) s->dbc;
15872 if (!table || table[0] == '\0' || table[0] == '%') {
15873 setstat(s, -1, "need table name", (*s->ov3) ? "HY000" : "S1000");
15874 return SQL_ERROR;
15875 }
15876 if (tableLen == SQL_NTS) {
15877 size = sizeof (tname) - 1;
15878 } else {
15879 size = min(sizeof (tname) - 1, tableLen);
15880 }
15881 strncpy(tname, (char *) table, size);
15882 tname[size] = '\0';
15883 unescpat(tname);
15884 sret = starttran(s);
15885 if (sret != SQL_SUCCESS) {
15886 return sret;
15887 }
15888
15889
15890
15891 if (itype == SQL_INDEX_UNIQUE || itype == SQL_INDEX_ALL) {
15892 rowp = 0;
15893 ret = SQLITE_ERROR;
15894 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
15895 if (sql) {
15896 dbtraceapi(d, "sqlite3_get_table", sql);
15897 ret = sqlite3_get_table(d->sqlite, sql, &rowp,
15898 &nrows, &ncols, NULL);
15899 sqlite3_free(sql);
15900 }
15901 if (ret == SQLITE_OK) {
15902 int colid, typec, npk = 0, npkint = 0;
15903
15904 namec = findcol(rowp, ncols, "name");
15905 uniquec = findcol(rowp, ncols, "pk");
15906 typec = findcol(rowp, ncols, "type");
15907 colid = findcol(rowp, ncols, "cid");
15908 if (namec < 0 || uniquec < 0 || typec < 0 || colid < 0) {
15909 goto noipk;
15910 }
15911 for (i = 1; i <= nrows; i++) {
15912 if (*rowp[i * ncols + uniquec] != '0') {
15913 npk++;
15914 if (strlen(rowp[i * ncols + typec]) == 7 &&
15915 strncasecmp(rowp[i * ncols + typec], "integer", 7)
15916 == 0) {
15917 npkint++;
15918 }
15919 }
15920 }
15921 if (npkint == 1 && npk == npkint) {
15922 addipk = 1;
15923 }
15924 }
15925 noipk:
15926 sqlite3_free_table(rowp);
15927 }
15928 sql = sqlite3_mprintf("PRAGMA index_list(%Q)", tname);
15929 if (!sql) {
15930 return nomem(s);
15931 }
15932 dbtraceapi(d, "sqlite3_get_table", sql);
15933 ret = sqlite3_get_table(d->sqlite, sql, &rowp, &nrows, &ncols, &errp);
15934 sqlite3_free(sql);
15935 if (ret != SQLITE_OK) {
15936 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
15937 errp ? errp : "unknown error", ret);
15938 if (errp) {
15939 sqlite3_free(errp);
15940 errp = NULL;
15941 }
15942 return SQL_ERROR;
15943 }
15944 if (errp) {
15945 sqlite3_free(errp);
15946 errp = NULL;
15947 }
15948 size = 0;
15949 namec = findcol(rowp, ncols, "name");
15950 uniquec = findcol(rowp, ncols, "unique");
15951 if (namec < 0 || uniquec < 0) {
15952 goto nodata;
15953 }
15954 for (i = 1; i <= nrows; i++) {
15955 int nnrows, nncols;
15956 char **rowpp;
15957 int isuniq;
15958
15959 isuniq = *rowp[i * ncols + uniquec] != '0';
15960 if (isuniq || itype == SQL_INDEX_ALL) {
15961 ret = SQLITE_ERROR;
15962 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
15963 rowp[i * ncols + namec]);
15964 if (sql) {
15965 dbtraceapi(d, "sqlite3_get_table", sql);
15966 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
15967 &nnrows, &nncols, NULL);
15968 sqlite3_free(sql);
15969 }
15970 if (ret == SQLITE_OK) {
15971 size += nnrows;
15972 sqlite3_free_table(rowpp);
15973 }
15974 }
15975 }
15976 nodata:
15977 if (addipk) {
15978 size++;
15979 }
15980 if (size == 0) {
15981 sqlite3_free_table(rowp);
15982 return SQL_SUCCESS;
15983 }
15984 s->nrows = size;
15985 size = (size + 1) * asize;
15986 s->rows = xmalloc((size + 1) * sizeof (char *));
15987 if (!s->rows) {
15988 s->nrows = 0;
15989 return nomem(s);
15990 }
15991 s->rows[0] = (char *) size;
15992 s->rows += 1;
15993 memset(s->rows, 0, sizeof (char *) * size);
15994 s->rowfree = freerows;
15995 offs = 0;
15996 if (addipk) {
15997 char **rowpp = 0;
15998 int nrows2, ncols2;
15999
16000 sql = sqlite3_mprintf("PRAGMA table_info(%Q)", tname);
16001 if (sql) {
16002 dbtraceapi(d, "sqlite3_get_table", sql);
16003 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16004 &nrows2, &ncols2, NULL);
16005 sqlite3_free(sql);
16006 }
16007 if (ret == SQLITE_OK) {
16008 int colid, typec, roffs, namecc, uniquecc;
16009
16010 namecc = findcol(rowpp, ncols2, "name");
16011 uniquecc = findcol(rowpp, ncols2, "pk");
16012 typec = findcol(rowpp, ncols2, "type");
16013 colid = findcol(rowpp, ncols2, "cid");
16014 if (namecc < 0 || uniquecc < 0 || typec < 0 || colid < 0) {
16015 addipk = 0;
16016 s->nrows--;
16017 goto nodata2;
16018 }
16019 for (i = 1; i <= nrows2; i++) {
16020 if (*rowpp[i * ncols2 + uniquecc] != '0' &&
16021 strlen(rowpp[i * ncols2 + typec]) == 7 &&
16022 strncasecmp(rowpp[i * ncols2 + typec], "integer", 7)
16023 == 0) {
16024 break;
16025 }
16026 }
16027 if (i > nrows2) {
16028 addipk = 0;
16029 s->nrows--;
16030 goto nodata2;
16031 }
16032 roffs = s->ncols;
16033 #if defined(_WIN32) || defined(_WIN64)
16034 s->rows[roffs + 0] = xstrdup(d->xcelqrx ? "main" : "");
16035 s->rows[roffs + 1] = xstrdup("");
16036 #else
16037 s->rows[roffs + 0] = xstrdup("");
16038 s->rows[roffs + 1] = xstrdup("");
16039 #endif
16040 s->rows[roffs + 2] = xstrdup(tname);
16041 s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16042 s->rows[roffs + 5] = xstrdup("sqlite_autoindex_0");
16043 s->rows[roffs + 6] = xstrdup(stringify(SQL_INDEX_OTHER));
16044 s->rows[roffs + 7] = xstrdup("1");
16045 s->rows[roffs + 8] = xstrdup(rowpp[i * ncols2 + namecc]);
16046 s->rows[roffs + 9] = xstrdup("A");
16047 }
16048 nodata2:
16049 sqlite3_free_table(rowpp);
16050 }
16051 for (i = 1; i <= nrows; i++) {
16052 int nnrows, nncols;
16053 char **rowpp = 0;
16054
16055 if (*rowp[i * ncols + uniquec] != '0' || itype == SQL_INDEX_ALL) {
16056 int k;
16057
16058 ret = SQLITE_ERROR;
16059 sql = sqlite3_mprintf("PRAGMA index_info(%Q)",
16060 rowp[i * ncols + namec]);
16061 if (sql) {
16062 dbtraceapi(d, "sqlite3_get_table", sql);
16063 ret = sqlite3_get_table(d->sqlite, sql, &rowpp,
16064 &nnrows, &nncols, NULL);
16065 sqlite3_free(sql);
16066 }
16067 if (ret != SQLITE_OK) {
16068 continue;
16069 }
16070 for (k = 0; nnrows && k < nncols; k++) {
16071 if (strcmp(rowpp[k], "name") == 0) {
16072 int m;
16073
16074 for (m = 1; m <= nnrows; m++) {
16075 int roffs = (offs + addipk + m) * s->ncols;
16076 int isuniq;
16077
16078 isuniq = *rowp[i * ncols + uniquec] != '0';
16079 s->rows[roffs + 0] = xstrdup("");
16080 s->rows[roffs + 1] = xstrdup("");
16081 s->rows[roffs + 2] = xstrdup(tname);
16082 if (isuniq) {
16083 s->rows[roffs + 3] = xstrdup(stringify(SQL_FALSE));
16084 } else {
16085 s->rows[roffs + 3] = xstrdup(stringify(SQL_TRUE));
16086 }
16087 s->rows[roffs + 5] = xstrdup(rowp[i * ncols + namec]);
16088 s->rows[roffs + 6] =
16089 xstrdup(stringify(SQL_INDEX_OTHER));
16090 s->rows[roffs + 8] = xstrdup(rowpp[m * nncols + k]);
16091 s->rows[roffs + 9] = xstrdup("A");
16092 }
16093 } else if (strcmp(rowpp[k], "seqno") == 0) {
16094 int m;
16095
16096 for (m = 1; m <= nnrows; m++) {
16097 int roffs = (offs + addipk + m) * s->ncols;
16098 int pos = m - 1;
16099 char buf[32];
16100
16101 sscanf(rowpp[m * nncols + k], "%d", &pos);
16102 sprintf(buf, "%d", pos + 1);
16103 s->rows[roffs + 7] = xstrdup(buf);
16104 }
16105 }
16106 }
16107 offs += nnrows;
16108 sqlite3_free_table(rowpp);
16109 }
16110 }
16111 sqlite3_free_table(rowp);
16112 return SQL_SUCCESS;
16113 }
16114
16115 #ifndef WINTERFACE
16116
16130 SQLRETURN SQL_API
16131 SQLStatistics(SQLHSTMT stmt, SQLCHAR *cat, SQLSMALLINT catLen,
16132 SQLCHAR *schema, SQLSMALLINT schemaLen,
16133 SQLCHAR *table, SQLSMALLINT tableLen,
16134 SQLUSMALLINT itype, SQLUSMALLINT resv)
16135 {
16136 #if defined(_WIN32) || defined(_WIN64)
16137 char *c = NULL, *s = NULL, *t = NULL;
16138 #endif
16139 SQLRETURN ret;
16140
16141 HSTMT_LOCK(stmt);
16142 #if defined(_WIN32) || defined(_WIN64)
16143 if (!((STMT *) stmt)->oemcp[0]) {
16144 ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16145 table, tableLen, itype, resv);
16146 goto done2;
16147 }
16148 if (cat) {
16149 c = wmb_to_utf_c((char *) cat, catLen);
16150 if (!c) {
16151 ret = nomem((STMT *) stmt);
16152 goto done;
16153 }
16154 }
16155 if (schema) {
16156 s = wmb_to_utf_c((char *) schema, schemaLen);
16157 if (!s) {
16158 ret = nomem((STMT *) stmt);
16159 goto done;
16160 }
16161 }
16162 if (table) {
16163 t = wmb_to_utf_c((char *) table, tableLen);
16164 if (!t) {
16165 ret = nomem((STMT *) stmt);
16166 goto done;
16167 }
16168 }
16169 ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16170 (SQLCHAR *) t, SQL_NTS, itype, resv);
16171 #else
16172 ret = drvstatistics(stmt, cat, catLen, schema, schemaLen,
16173 table, tableLen, itype, resv);
16174 #endif
16175 #if defined(_WIN32) || defined(_WIN64)
16176 done:
16177 uc_free(t);
16178 uc_free(s);
16179 uc_free(c);
16180 done2:
16181 ;
16182 #endif
16183 HSTMT_UNLOCK(stmt);
16184 return ret;
16185 }
16186 #endif
16187
16188 #ifdef WINTERFACE
16189
16203 SQLRETURN SQL_API
16204 SQLStatisticsW(SQLHSTMT stmt, SQLWCHAR *cat, SQLSMALLINT catLen,
16205 SQLWCHAR *schema, SQLSMALLINT schemaLen,
16206 SQLWCHAR *table, SQLSMALLINT tableLen,
16207 SQLUSMALLINT itype, SQLUSMALLINT resv)
16208 {
16209 char *c = NULL, *s = NULL, *t = NULL;
16210 SQLRETURN ret;
16211
16212 HSTMT_LOCK(stmt);
16213 if (cat) {
16214 c = uc_to_utf_c(cat, catLen);
16215 if (!c) {
16216 ret = nomem((STMT *) stmt);
16217 goto done;
16218 }
16219 }
16220 if (schema) {
16221 s = uc_to_utf_c(schema, schemaLen);
16222 if (!s) {
16223 ret = nomem((STMT *) stmt);
16224 goto done;
16225 }
16226 }
16227 if (table) {
16228 t = uc_to_utf_c(table, tableLen);
16229 if (!t) {
16230 ret = nomem((STMT *) stmt);
16231 goto done;
16232 }
16233 }
16234 ret = drvstatistics(stmt, (SQLCHAR *) c, SQL_NTS, (SQLCHAR *) s, SQL_NTS,
16235 (SQLCHAR *) t, SQL_NTS, itype, resv);
16236 done:
16237 uc_free(t);
16238 uc_free(s);
16239 uc_free(c);
16240 HSTMT_UNLOCK(stmt);
16241 return ret;
16242 }
16243 #endif
16244
16256 SQLRETURN SQL_API
16257 SQLGetData(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT type,
16258 SQLPOINTER val, SQLLEN len, SQLLEN *lenp)
16259 {
16260 STMT *s;
16261 SQLRETURN ret = SQL_ERROR;
16262
16263 HSTMT_LOCK(stmt);
16264 if (stmt == SQL_NULL_HSTMT) {
16265 return SQL_INVALID_HANDLE;
16266 }
16267 s = (STMT *) stmt;
16268 if (col == 0 && s->bkmrk != SQL_UB_OFF) {
16269 if (s->bkmrk == SQL_UB_ON && type == SQL_C_BOOKMARK) {
16270 *((SQLINTEGER *) val) = s->rowp;
16271 if (lenp) {
16272 *lenp = sizeof (SQLINTEGER);
16273 }
16274 ret = SQL_SUCCESS;
16275 goto done;
16276 } else if (s->bkmrk == SQL_UB_VARIABLE && type == SQL_C_VARBOOKMARK) {
16277 if (s->has_rowid >= 0) {
16278 char **data, *endp = 0;
16279
16280 data = s->rows + s->ncols + (s->rowp * s->ncols)
16281 + s->has_rowid;
16282 #ifdef __osf__
16283 *((sqlite_int64 *) val) = strtol(*data, &endp, 0);
16284 #else
16285 *((sqlite_int64 *) val) = strtoll(*data, &endp, 0);
16286 #endif
16287 } else {
16288 *((sqlite_int64 *) val) = s->rowp;
16289 }
16290 if (lenp) {
16291 *lenp = sizeof (sqlite_int64);
16292 }
16293 ret = SQL_SUCCESS;
16294 goto done;
16295 }
16296 }
16297 if (col < 1 || col > s->ncols) {
16298 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16299 goto done;
16300 }
16301 --col;
16302 ret = getrowdata(s, col, type, val, len, lenp, 1);
16303 done:
16304 HSTMT_UNLOCK(stmt);
16305 return ret;
16306 }
16307
16315 static SQLRETURN
16316 dofetchbind(STMT *s, int rsi)
16317 {
16318 int ret, i, withinfo = 0;
16319
16320 s->row_status0[rsi] = SQL_ROW_SUCCESS;
16321 if (s->bkmrk != SQL_UB_OFF && s->bkmrkcol.valp) {
16322 int bsize = sizeof (SQLINTEGER);
16323
16324 if (s->bkmrkcol.type == SQL_C_VARBOOKMARK) {
16325 SQLPOINTER *val;
16326
16327 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16328 val = (SQLPOINTER)
16329 ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16330 } else {
16331 val = (SQLPOINTER)
16332 ((char *) s->bkmrkcol.valp + s->bkmrkcol.max * rsi);
16333 }
16334 if (s->bind_offs) {
16335 val = (SQLPOINTER) ((char *) val + *s->bind_offs);
16336 }
16337 if (s->has_rowid >= 0) {
16338 char **data, *endp = 0;
16339
16340 data = s->rows + s->ncols + (s->rowp * s->ncols)
16341 + s->has_rowid;
16342 #ifdef __osf__
16343 *(sqlite_int64 *) val = strtol(*data, &endp, 0);
16344 #else
16345 *(sqlite_int64 *) val = strtoll(*data, &endp, 0);
16346 #endif
16347 } else {
16348 *(sqlite_int64 *) val = s->rowp;
16349 }
16350 bsize = sizeof (sqlite_int64);
16351 } else {
16352 SQLINTEGER *val;
16353
16354 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16355 val = (SQLINTEGER *)
16356 ((char *) s->bkmrkcol.valp + s->bind_type * rsi);
16357 } else {
16358 val = (SQLINTEGER *) s->bkmrkcol.valp + rsi;
16359 }
16360 if (s->bind_offs) {
16361 val = (SQLINTEGER *) ((char *) val + *s->bind_offs);
16362 }
16363 *val = s->rowp;
16364 }
16365 if (s->bkmrkcol.lenp) {
16366 SQLLEN *ival;
16367
16368 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16369 ival = (SQLLEN *)
16370 ((char *) s->bkmrkcol.lenp + s->bind_type * rsi);
16371 } else {
16372 ival = &s->bkmrkcol.lenp[rsi];
16373 }
16374 if (s->bind_offs) {
16375 ival = (SQLLEN *) ((char *) ival + *s->bind_offs);
16376 }
16377 *ival = bsize;
16378 }
16379 }
16380 ret = SQL_SUCCESS;
16381 for (i = 0; s->bindcols && i < s->ncols; i++) {
16382 BINDCOL *b = &s->bindcols[i];
16383 SQLPOINTER dp = 0;
16384 SQLLEN *lp = 0;
16385
16386 b->offs = 0;
16387 if (b->valp) {
16388 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16389 dp = (SQLPOINTER) ((char *) b->valp + s->bind_type * rsi);
16390 } else {
16391 dp = (SQLPOINTER) ((char *) b->valp + b->max * rsi);
16392 }
16393 if (s->bind_offs) {
16394 dp = (SQLPOINTER) ((char *) dp + *s->bind_offs);
16395 }
16396 }
16397 if (b->lenp) {
16398 if (s->bind_type != SQL_BIND_BY_COLUMN) {
16399 lp = (SQLLEN *) ((char *) b->lenp + s->bind_type * rsi);
16400 } else {
16401 lp = b->lenp + rsi;
16402 }
16403 if (s->bind_offs) {
16404 lp = (SQLLEN *) ((char *) lp + *s->bind_offs);
16405 }
16406 }
16407 if (dp || lp) {
16408 ret = getrowdata(s, (SQLUSMALLINT) i, b->type, dp, b->max, lp, 0);
16409 if (!SQL_SUCCEEDED(ret)) {
16410 s->row_status0[rsi] = SQL_ROW_ERROR;
16411 break;
16412 }
16413 if (ret != SQL_SUCCESS) {
16414 withinfo = 1;
16415 #ifdef SQL_ROW_SUCCESS_WITH_INFO
16416 s->row_status0[rsi] = SQL_ROW_SUCCESS_WITH_INFO;
16417 #endif
16418 }
16419 }
16420 }
16421 if (SQL_SUCCEEDED(ret)) {
16422 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16423 }
16424 return ret;
16425 }
16426
16435 static SQLRETURN
16436 drvfetchscroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLINTEGER offset)
16437 {
16438 STMT *s;
16439 int i, withinfo = 0;
16440 SQLRETURN ret;
16441
16442 if (stmt == SQL_NULL_HSTMT) {
16443 return SQL_INVALID_HANDLE;
16444 }
16445 s = (STMT *) stmt;
16446 for (i = 0; i < s->rowset_size; i++) {
16447 s->row_status0[i] = SQL_ROW_NOROW;
16448 }
16449 if (s->row_status) {
16450 memcpy(s->row_status, s->row_status0,
16451 sizeof (SQLUSMALLINT) * s->rowset_size);
16452 }
16453 s->row_count0 = 0;
16454 if (s->row_count) {
16455 *s->row_count = s->row_count0;
16456 }
16457 if (!s->bindcols) {
16458 for (i = 0; i < s->rowset_size; i++) {
16459 s->row_status0[i] = SQL_ROW_ERROR;
16460 }
16461 ret = SQL_ERROR;
16462 i = 0;
16463 goto done2;
16464 }
16465 if (s->isselect != 1 && s->isselect != -1) {
16466 setstat(s, -1, "no result set available", "24000");
16467 ret = SQL_ERROR;
16468 i = s->nrows;
16469 goto done2;
16470 }
16471 if (s->curtype == SQL_CURSOR_FORWARD_ONLY && orient != SQL_FETCH_NEXT) {
16472 setstat(s, -1, "wrong fetch direction", "01000");
16473 ret = SQL_ERROR;
16474 i = 0;
16475 goto done2;
16476 }
16477 ret = SQL_SUCCESS;
16478 i = 0;
16479 if (((DBC *) (s->dbc))->cur_s3stmt == s && s->s3stmt) {
16480 s->rowp = s->rowprs = 0;
16481 for (; i < s->rowset_size; i++) {
16482 if (s->max_rows && s->s3stmt_rownum + 1 >= s->max_rows) {
16483 ret = (i == 0) ? SQL_NO_DATA : SQL_SUCCESS;
16484 break;
16485 }
16486 ret = s3stmt_step(s);
16487 if (ret != SQL_SUCCESS) {
16488 s->row_status0[i] = SQL_ROW_ERROR;
16489 break;
16490 }
16491 if (s->nrows < 1) {
16492 break;
16493 }
16494 ret = dofetchbind(s, i);
16495 if (!SQL_SUCCEEDED(ret)) {
16496 break;
16497 } else if (ret == SQL_SUCCESS_WITH_INFO) {
16498 withinfo = 1;
16499 }
16500 }
16501 } else if (s->rows) {
16502 switch (orient) {
16503 case SQL_FETCH_NEXT:
16504 if (s->nrows < 1) {
16505 return SQL_NO_DATA;
16506 }
16507 if (s->rowp < 0) {
16508 s->rowp = -1;
16509 }
16510 if (s->rowp >= s->nrows) {
16511 s->rowp = s->rowprs = s->nrows;
16512 return SQL_NO_DATA;
16513 }
16514 break;
16515 case SQL_FETCH_PRIOR:
16516 if (s->nrows < 1 || s->rowp <= 0) {
16517 s->rowp = s->rowprs = -1;
16518 return SQL_NO_DATA;
16519 }
16520 s->rowp -= s->rowset_size + 1;
16521 if (s->rowp < -1) {
16522 s->rowp = s->rowprs = -1;
16523 return SQL_NO_DATA;
16524 }
16525 break;
16526 case SQL_FETCH_FIRST:
16527 if (s->nrows < 1) {
16528 return SQL_NO_DATA;
16529 }
16530 s->rowp = -1;
16531 break;
16532 case SQL_FETCH_LAST:
16533 if (s->nrows < 1) {
16534 return SQL_NO_DATA;
16535 }
16536 s->rowp = s->nrows - s->rowset_size;
16537 if (--s->rowp < -1) {
16538 s->rowp = -1;
16539 }
16540 break;
16541 case SQL_FETCH_ABSOLUTE:
16542 if (offset == 0) {
16543 s->rowp = s->rowprs = -1;
16544 return SQL_NO_DATA;
16545 } else if (offset < 0) {
16546 if (0 - offset <= s->nrows) {
16547 s->rowp = s->nrows + offset - 1;
16548 break;
16549 }
16550 s->rowp = s->rowprs = -1;
16551 return SQL_NO_DATA;
16552 } else if (offset > s->nrows) {
16553 s->rowp = s->rowprs = s->nrows;
16554 return SQL_NO_DATA;
16555 }
16556 s->rowp = offset - 1 - 1;
16557 break;
16558 case SQL_FETCH_RELATIVE:
16559 if (offset >= 0) {
16560 s->rowp += offset * s->rowset_size - 1;
16561 if (s->rowp >= s->nrows) {
16562 s->rowp = s->rowprs = s->nrows;
16563 return SQL_NO_DATA;
16564 }
16565 } else {
16566 s->rowp += offset * s->rowset_size - 1;
16567 if (s->rowp < -1) {
16568 s->rowp = s->rowprs = -1;
16569 return SQL_NO_DATA;
16570 }
16571 }
16572 break;
16573 case SQL_FETCH_BOOKMARK:
16574 if (s->bkmrk == SQL_UB_ON && !s->bkmrkptr) {
16575 if (offset < 0 || offset >= s->nrows) {
16576 return SQL_NO_DATA;
16577 }
16578 s->rowp = offset - 1;
16579 break;
16580 }
16581 if (s->bkmrk != SQL_UB_OFF && s->bkmrkptr) {
16582 int rowp;
16583
16584 if (s->bkmrk == SQL_UB_VARIABLE) {
16585 if (s->has_rowid >= 0) {
16586 sqlite_int64 bkmrk, rowid;
16587
16588 bkmrk = *(sqlite_int64 *) s->bkmrkptr;
16589 for (rowp = 0; rowp < s->nrows; rowp++) {
16590 char **data, *endp = 0;
16591
16592 data = s->rows + s->ncols + (rowp * s->ncols)
16593 + s->has_rowid;
16594 #ifdef __osf__
16595 rowid = strtol(*data, &endp, 0);
16596 #else
16597 rowid = strtoll(*data, &endp, 0);
16598 #endif
16599 if (rowid == bkmrk) {
16600 break;
16601 }
16602 }
16603 } else {
16604 rowp = *(sqlite_int64 *) s->bkmrkptr;
16605 }
16606 } else {
16607 rowp = *(int *) s->bkmrkptr;
16608 }
16609 if (rowp + offset < 0 || rowp + offset >= s->nrows) {
16610 return SQL_NO_DATA;
16611 }
16612 s->rowp = rowp + offset - 1;
16613 break;
16614 }
16615
16616 default:
16617 s->row_status0[0] = SQL_ROW_ERROR;
16618 ret = SQL_ERROR;
16619 goto done;
16620 }
16621 s->rowprs = s->rowp + 1;
16622 for (; i < s->rowset_size; i++) {
16623 ++s->rowp;
16624 if (s->rowp < 0 || s->rowp >= s->nrows) {
16625 break;
16626 }
16627 ret = dofetchbind(s, i);
16628 if (!SQL_SUCCEEDED(ret)) {
16629 break;
16630 } else if (ret == SQL_SUCCESS_WITH_INFO) {
16631 withinfo = 1;
16632 }
16633 }
16634 }
16635 done:
16636 if (i == 0) {
16637 if (SQL_SUCCEEDED(ret)) {
16638 return SQL_NO_DATA;
16639 }
16640 return ret;
16641 }
16642 if (SQL_SUCCEEDED(ret)) {
16643 ret = withinfo ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS;
16644 }
16645 done2:
16646 if (s->row_status) {
16647 memcpy(s->row_status, s->row_status0,
16648 sizeof (SQLUSMALLINT) * s->rowset_size);
16649 }
16650 s->row_count0 = i;
16651 if (s->row_count) {
16652 *s->row_count = s->row_count0;
16653 }
16654 return ret;
16655 }
16656
16663 SQLRETURN SQL_API
16664 SQLFetch(SQLHSTMT stmt)
16665 {
16666 SQLRETURN ret;
16667
16668 HSTMT_LOCK(stmt);
16669 ret = drvfetchscroll(stmt, SQL_FETCH_NEXT, 0);
16670 HSTMT_UNLOCK(stmt);
16671 return ret;
16672 }
16673
16682 SQLRETURN SQL_API
16683 SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orient, SQLLEN offset)
16684 {
16685 SQLRETURN ret;
16686
16687 HSTMT_LOCK(stmt);
16688 ret = drvfetchscroll(stmt, orient, offset);
16689 HSTMT_UNLOCK(stmt);
16690 return ret;
16691 }
16692
16703 SQLRETURN SQL_API
16704 SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT orient, SQLROWOFFSET offset,
16705 SQLROWSETSIZE *rowcount, SQLUSMALLINT *rowstatus)
16706 {
16707 STMT *s;
16708 SQLRETURN ret;
16709 SQLUSMALLINT *rst;
16710 SQLINTEGER *bkmrkptr;
16711
16712 HSTMT_LOCK(stmt);
16713 if (stmt == SQL_NULL_HSTMT) {
16714 return SQL_INVALID_HANDLE;
16715 }
16716 s = (STMT *) stmt;
16717
16718 rst = s->row_status;
16719 s->row_status = 0;
16720 bkmrkptr = s->bkmrkptr;
16721 s->bkmrkptr = 0;
16722 ret = drvfetchscroll(stmt, orient, offset);
16723 s->row_status = rst;
16724 s->bkmrkptr = bkmrkptr;
16725 if (rowstatus) {
16726 memcpy(rowstatus, s->row_status0,
16727 sizeof (SQLUSMALLINT) * s->rowset_size);
16728 }
16729 if (rowcount) {
16730 *rowcount = s->row_count0;
16731 }
16732 HSTMT_UNLOCK(stmt);
16733 return ret;
16734 }
16735
16743 SQLRETURN SQL_API
16744 SQLRowCount(SQLHSTMT stmt, SQLLEN *nrows)
16745 {
16746 STMT *s;
16747
16748 HSTMT_LOCK(stmt);
16749 if (stmt == SQL_NULL_HSTMT) {
16750 return SQL_INVALID_HANDLE;
16751 }
16752 s = (STMT *) stmt;
16753 if (nrows) {
16754 *nrows = s->isselect ? 0 : s->nrows;
16755 }
16756 HSTMT_UNLOCK(stmt);
16757 return SQL_SUCCESS;
16758 }
16759
16767 SQLRETURN SQL_API
16768 SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *ncols)
16769 {
16770 STMT *s;
16771
16772 HSTMT_LOCK(stmt);
16773 if (stmt == SQL_NULL_HSTMT) {
16774 return SQL_INVALID_HANDLE;
16775 }
16776 s = (STMT *) stmt;
16777 if (ncols) {
16778 *ncols = s->ncols;
16779 }
16780 HSTMT_UNLOCK(stmt);
16781 return SQL_SUCCESS;
16782 }
16783
16798 static SQLRETURN
16799 drvdescribecol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16800 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16801 SQLSMALLINT *type, SQLULEN *size,
16802 SQLSMALLINT *digits, SQLSMALLINT *nullable)
16803 {
16804 STMT *s;
16805 COL *c;
16806 int didname = 0;
16807
16808 if (stmt == SQL_NULL_HSTMT) {
16809 return SQL_INVALID_HANDLE;
16810 }
16811 s = (STMT *) stmt;
16812 if (!s->cols) {
16813 setstat(s, -1, "no columns", (*s->ov3) ? "07009" : "S1002");
16814 return SQL_ERROR;
16815 }
16816 if (col < 1 || col > s->ncols) {
16817 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
16818 return SQL_ERROR;
16819 }
16820 c = s->cols + col - 1;
16821 if (name && nameMax > 0) {
16822 strncpy((char *) name, c->column, nameMax);
16823 name[nameMax - 1] = '\0';
16824 didname = 1;
16825 }
16826 if (nameLen) {
16827 if (didname) {
16828 *nameLen = strlen((char *) name);
16829 } else {
16830 *nameLen = strlen(c->column);
16831 }
16832 }
16833 if (type) {
16834 *type = c->type;
16835 #ifdef WINTERFACE
16836 if (s->nowchar[0] || s->nowchar[1]) {
16837 switch (c->type) {
16838 case SQL_WCHAR:
16839 *type = SQL_CHAR;
16840 break;
16841 case SQL_WVARCHAR:
16842 *type = SQL_VARCHAR;
16843 break;
16844 #ifdef SQL_LONGVARCHAR
16845 case SQL_WLONGVARCHAR:
16846 *type = SQL_LONGVARCHAR;
16847 break;
16848 #endif
16849 }
16850 }
16851 #endif
16852 }
16853 if (size) {
16854 *size = c->size;
16855 }
16856 if (digits) {
16857 *digits = 0;
16858 }
16859 if (nullable) {
16860 *nullable = 1;
16861 }
16862 return SQL_SUCCESS;
16863 }
16864
16865 #ifndef WINTERFACE
16866
16880 SQLRETURN SQL_API
16881 SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT col, SQLCHAR *name,
16882 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16883 SQLSMALLINT *type, SQLULEN *size,
16884 SQLSMALLINT *digits, SQLSMALLINT *nullable)
16885 {
16886 #if defined(_WIN32) || defined(_WIN64)
16887 SQLSMALLINT len = 0;
16888 #endif
16889 SQLRETURN ret;
16890
16891 HSTMT_LOCK(stmt);
16892 #if defined(_WIN32) || defined(_WIN64)
16893 if (!((STMT *) stmt)->oemcp[0]) {
16894 ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
16895 type, size, digits, nullable);
16896 goto done;
16897 }
16898 ret = drvdescribecol(stmt, col, name, nameMax,
16899 &len, type, size, digits, nullable);
16900 if (ret == SQL_SUCCESS) {
16901 if (name) {
16902 if (len > 0) {
16903 SQLCHAR *n = NULL;
16904
16905 n = (SQLCHAR *) utf_to_wmb((char *) name, len);
16906 if (n) {
16907 strncpy((char *) name, (char *) n, nameMax);
16908 n[len] = 0;
16909 len = min(nameMax, strlen((char *) n));
16910 uc_free(n);
16911 } else {
16912 len = 0;
16913 }
16914 }
16915 if (len <= 0) {
16916 len = 0;
16917 if (nameMax > 0) {
16918 name[0] = 0;
16919 }
16920 }
16921 } else {
16922 STMT *s = (STMT *) stmt;
16923 COL *c = s->cols + col - 1;
16924
16925 len = 0;
16926 if (c->column) {
16927 len = strlen(c->column);
16928 }
16929 }
16930 if (nameLen) {
16931 *nameLen = len;
16932 }
16933 }
16934 done:
16935 ;
16936 #else
16937 ret = drvdescribecol(stmt, col, name, nameMax, nameLen,
16938 type, size, digits, nullable);
16939 #endif
16940 HSTMT_UNLOCK(stmt);
16941 return ret;
16942 }
16943 #endif
16944
16945 #ifdef WINTERFACE
16946
16960 SQLRETURN SQL_API
16961 SQLDescribeColW(SQLHSTMT stmt, SQLUSMALLINT col, SQLWCHAR *name,
16962 SQLSMALLINT nameMax, SQLSMALLINT *nameLen,
16963 SQLSMALLINT *type, SQLULEN *size,
16964 SQLSMALLINT *digits, SQLSMALLINT *nullable)
16965 {
16966 SQLRETURN ret;
16967 SQLSMALLINT len = 0;
16968
16969 HSTMT_LOCK(stmt);
16970 ret = drvdescribecol(stmt, col, (SQLCHAR *) name,
16971 (SQLSMALLINT) (nameMax * sizeof (SQLWCHAR)),
16972 &len, type, size, digits, nullable);
16973 if (ret == SQL_SUCCESS) {
16974 if (name) {
16975 if (len > 0) {
16976 SQLWCHAR *n = NULL;
16977
16978 n = uc_from_utf((SQLCHAR *) name, len);
16979 if (n) {
16980 uc_strncpy(name, n, nameMax);
16981 n[len] = 0;
16982 len = min(nameMax, uc_strlen(n));
16983 uc_free(n);
16984 } else {
16985 len = 0;
16986 }
16987 }
16988 if (len <= 0) {
16989 len = 0;
16990 if (nameMax > 0) {
16991 name[0] = 0;
16992 }
16993 }
16994 } else {
16995 STMT *s = (STMT *) stmt;
16996 COL *c = s->cols + col - 1;
16997
16998 len = 0;
16999 if (c->column) {
17000 len = strlen(c->column);
17001 }
17002 }
17003 if (nameLen) {
17004 *nameLen = len;
17005 }
17006 }
17007 HSTMT_UNLOCK(stmt);
17008 return ret;
17009 }
17010 #endif
17011
17024 static SQLRETURN
17025 drvcolattributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17026 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17027 SQLLEN *val2)
17028 {
17029 STMT *s;
17030 COL *c;
17031 SQLSMALLINT dummy;
17032 char *valc = (char *) val;
17033
17034 if (stmt == SQL_NULL_HSTMT) {
17035 return SQL_INVALID_HANDLE;
17036 }
17037 s = (STMT *) stmt;
17038 if (!s->cols) {
17039 return SQL_ERROR;
17040 }
17041 if (!valLen) {
17042 valLen = &dummy;
17043 }
17044 if (id == SQL_COLUMN_COUNT) {
17045 if (val2) {
17046 *val2 = s->ncols;
17047 }
17048 *valLen = sizeof (int);
17049 return SQL_SUCCESS;
17050 }
17051 if (id == SQL_COLUMN_TYPE && col == 0) {
17052 if (val2) {
17053 *val2 = SQL_INTEGER;
17054 }
17055 *valLen = sizeof (int);
17056 return SQL_SUCCESS;
17057 }
17058 #ifdef SQL_DESC_OCTET_LENGTH
17059 if (id == SQL_DESC_OCTET_LENGTH && col == 0) {
17060 if (val2) {
17061 *val2 = 4;
17062 }
17063 *valLen = sizeof (int);
17064 return SQL_SUCCESS;
17065 }
17066 #endif
17067 if (col < 1 || col > s->ncols) {
17068 setstat(s, -1, "invalid column", (*s->ov3) ? "07009": "S1002");
17069 return SQL_ERROR;
17070 }
17071 c = s->cols + col - 1;
17072
17073 switch (id) {
17074 case SQL_COLUMN_LABEL:
17075 if (c->label) {
17076 if (valc && valMax > 0) {
17077 strncpy(valc, c->label, valMax);
17078 valc[valMax - 1] = '\0';
17079 }
17080 *valLen = strlen(c->label);
17081 goto checkLen;
17082 }
17083
17084 case SQL_COLUMN_NAME:
17085 case SQL_DESC_NAME:
17086 if (valc && valMax > 0) {
17087 strncpy(valc, c->column, valMax);
17088 valc[valMax - 1] = '\0';
17089 }
17090 *valLen = strlen(c->column);
17091 checkLen:
17092 if (*valLen >= valMax) {
17093 setstat(s, -1, "data right truncated", "01004");
17094 return SQL_SUCCESS_WITH_INFO;
17095 }
17096 return SQL_SUCCESS;
17097 #ifdef SQL_DESC_BASE_COLUMN_NAME
17098 case SQL_DESC_BASE_COLUMN_NAME:
17099 if (strchr(c->column, '(') || strchr(c->column, ')')) {
17100 if (valc && valMax > 0) {
17101 valc[0] = '\0';
17102 }
17103 *valLen = 0;
17104 } else if (valc && valMax > 0) {
17105 strncpy(valc, c->column, valMax);
17106 valc[valMax - 1] = '\0';
17107 *valLen = strlen(c->column);
17108 }
17109 goto checkLen;
17110 #endif
17111 case SQL_COLUMN_TYPE:
17112 case SQL_DESC_TYPE:
17113 #ifdef WINTERFACE
17114 {
17115 int type = c->type;
17116
17117 if (s->nowchar[0] || s->nowchar[1]) {
17118 switch (type) {
17119 case SQL_WCHAR:
17120 type = SQL_CHAR;
17121 break;
17122 case SQL_WVARCHAR:
17123 type = SQL_VARCHAR;
17124 break;
17125 #ifdef SQL_LONGVARCHAR
17126 case SQL_WLONGVARCHAR:
17127 type = SQL_LONGVARCHAR;
17128 break;
17129 }
17130 }
17131 if (val2) {
17132 *val2 = type;
17133 }
17134 #endif
17135 }
17136 #else
17137 if (val2) {
17138 *val2 = c->type;
17139 }
17140 #endif
17141 *valLen = sizeof (int);
17142 return SQL_SUCCESS;
17143 case SQL_COLUMN_DISPLAY_SIZE:
17144 if (val2) {
17145 *val2 = c->size;
17146 }
17147 *valLen = sizeof (int);
17148 return SQL_SUCCESS;
17149 case SQL_COLUMN_UNSIGNED:
17150 if (val2) {
17151 *val2 = c->nosign ? SQL_TRUE : SQL_FALSE;
17152 }
17153 *valLen = sizeof (int);
17154 return SQL_SUCCESS;
17155 case SQL_COLUMN_SCALE:
17156 case SQL_DESC_SCALE:
17157 if (val2) {
17158 *val2 = c->scale;
17159 }
17160 *valLen = sizeof (int);
17161 return SQL_SUCCESS;
17162 case SQL_COLUMN_PRECISION:
17163 case SQL_DESC_PRECISION:
17164 if (val2) {
17165 switch (c->type) {
17166 case SQL_SMALLINT:
17167 *val2 = 5;
17168 break;
17169 case SQL_INTEGER:
17170 *val2 = 10;
17171 break;
17172 case SQL_FLOAT:
17173 case SQL_REAL:
17174 case SQL_DOUBLE:
17175 *val2 = 15;
17176 break;
17177 case SQL_DATE:
17178 *val2 = 0;
17179 break;
17180 case SQL_TIME:
17181 *val2 = 0;
17182 break;
17183 #ifdef SQL_TYPE_TIMESTAMP
17184 case SQL_TYPE_TIMESTAMP:
17185 #endif
17186 case SQL_TIMESTAMP:
17187 *val2 = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17188 break;
17189 default:
17190 *val2 = c->prec;
17191 break;
17192 }
17193 }
17194 *valLen = sizeof (int);
17195 return SQL_SUCCESS;
17196 case SQL_COLUMN_MONEY:
17197 if (val2) {
17198 *val2 = SQL_FALSE;
17199 }
17200 *valLen = sizeof (int);
17201 return SQL_SUCCESS;
17202 case SQL_COLUMN_AUTO_INCREMENT:
17203 if (val2) {
17204 *val2 = c->autoinc;
17205 }
17206 *valLen = sizeof (int);
17207 return SQL_SUCCESS;
17208 case SQL_COLUMN_LENGTH:
17209 case SQL_DESC_LENGTH:
17210 if (val2) {
17211 *val2 = c->size;
17212 }
17213 *valLen = sizeof (int);
17214 return SQL_SUCCESS;
17215 case SQL_COLUMN_NULLABLE:
17216 case SQL_DESC_NULLABLE:
17217 if (val2) {
17218 *val2 = c->notnull;
17219 }
17220 *valLen = sizeof (int);
17221 return SQL_SUCCESS;
17222 case SQL_COLUMN_SEARCHABLE:
17223 if (val2) {
17224 *val2 = SQL_SEARCHABLE;
17225 }
17226 *valLen = sizeof (int);
17227 return SQL_SUCCESS;
17228 case SQL_COLUMN_CASE_SENSITIVE:
17229 if (val2) {
17230 *val2 = SQL_TRUE;
17231 }
17232 *valLen = sizeof (int);
17233 return SQL_SUCCESS;
17234 case SQL_COLUMN_UPDATABLE:
17235 if (val2) {
17236 *val2 = SQL_TRUE;
17237 }
17238 *valLen = sizeof (int);
17239 return SQL_SUCCESS;
17240 case SQL_DESC_COUNT:
17241 if (val2) {
17242 *val2 = s->ncols;
17243 }
17244 *valLen = sizeof (int);
17245 return SQL_SUCCESS;
17246 case SQL_COLUMN_TYPE_NAME: {
17247 char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17248
17249 #ifdef WINTERFACE
17250 if (c->type == SQL_WCHAR ||
17251 c->type == SQL_WVARCHAR ||
17252 c->type == SQL_WLONGVARCHAR) {
17253 if (!(s->nowchar[0] || s->nowchar[1])) {
17254 if (strcasecmp(tn, "varchar") == 0) {
17255 tn = "wvarchar";
17256 }
17257 }
17258 }
17259 #endif
17260 if (valc && valMax > 0) {
17261 strncpy(valc, tn, valMax);
17262 valc[valMax - 1] = '\0';
17263 p = strchr(valc, '(');
17264 if (p) {
17265 *p = '\0';
17266 while (p > valc && ISSPACE(p[-1])) {
17267 --p;
17268 *p = '\0';
17269 }
17270 }
17271 *valLen = strlen(valc);
17272 } else {
17273 *valLen = strlen(tn);
17274 p = strchr(tn, '(');
17275 if (p) {
17276 *valLen = p - tn;
17277 while (p > tn && ISSPACE(p[-1])) {
17278 --p;
17279 *valLen -= 1;
17280 }
17281 }
17282 }
17283 goto checkLen;
17284 }
17285 case SQL_COLUMN_OWNER_NAME:
17286 case SQL_COLUMN_QUALIFIER_NAME: {
17287 char *z = "";
17288
17289 if (valc && valMax > 0) {
17290 strncpy(valc, z, valMax);
17291 valc[valMax - 1] = '\0';
17292 }
17293 *valLen = strlen(z);
17294 goto checkLen;
17295 }
17296 case SQL_COLUMN_TABLE_NAME:
17297 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17298 case SQL_DESC_TABLE_NAME:
17299 #endif
17300 #ifdef SQL_DESC_BASE_TABLE_NAME
17301 case SQL_DESC_BASE_TABLE_NAME:
17302 #endif
17303 if (valc && valMax > 0) {
17304 strncpy(valc, c->table, valMax);
17305 valc[valMax - 1] = '\0';
17306 }
17307 *valLen = strlen(c->table);
17308 goto checkLen;
17309 #ifdef SQL_DESC_NUM_PREC_RADIX
17310 case SQL_DESC_NUM_PREC_RADIX:
17311 if (val2) {
17312 switch (c->type) {
17313 #ifdef WINTERFACE
17314 case SQL_WCHAR:
17315 case SQL_WVARCHAR:
17316 #ifdef SQL_LONGVARCHAR
17317 case SQL_WLONGVARCHAR:
17318 #endif
17319 #endif
17320 case SQL_CHAR:
17321 case SQL_VARCHAR:
17322 #ifdef SQL_LONGVARCHAR
17323 case SQL_LONGVARCHAR:
17324 #endif
17325 case SQL_BINARY:
17326 case SQL_VARBINARY:
17327 case SQL_LONGVARBINARY:
17328 *val2 = 0;
17329 break;
17330 default:
17331 *val2 = 2;
17332 }
17333 }
17334 *valLen = sizeof (int);
17335 return SQL_SUCCESS;
17336 #endif
17337 }
17338 setstat(s, -1, "unsupported column attributes %d", "HY091", id);
17339 return SQL_ERROR;
17340 }
17341
17342 #ifndef WINTERFACE
17343
17355 SQLRETURN SQL_API
17356 SQLColAttributes(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17357 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17358 SQLLEN *val2)
17359 {
17360 #if defined(_WIN32) || defined(_WIN64)
17361 SQLSMALLINT len = 0;
17362 #endif
17363 SQLRETURN ret;
17364
17365 HSTMT_LOCK(stmt);
17366 #if defined(_WIN32) || defined(_WIN64)
17367 if (!((STMT *) stmt)->oemcp[0]) {
17368 ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17369 goto done;
17370 }
17371 ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17372 if (SQL_SUCCEEDED(ret)) {
17373 char *v = NULL;
17374
17375 switch (id) {
17376 case SQL_COLUMN_LABEL:
17377 case SQL_COLUMN_NAME:
17378 case SQL_DESC_NAME:
17379 case SQL_COLUMN_TYPE_NAME:
17380 case SQL_COLUMN_OWNER_NAME:
17381 case SQL_COLUMN_QUALIFIER_NAME:
17382 case SQL_COLUMN_TABLE_NAME:
17383 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17384 case SQL_DESC_TABLE_NAME:
17385 #endif
17386 #ifdef SQL_DESC_BASE_COLUMN_NAME
17387 case SQL_DESC_BASE_COLUMN_NAME:
17388 #endif
17389 #ifdef SQL_DESC_BASE_TABLE_NAME
17390 case SQL_DESC_BASE_TABLE_NAME:
17391 #endif
17392 if (val && valMax > 0) {
17393 int vmax = valMax;
17394
17395 v = utf_to_wmb((char *) val, SQL_NTS);
17396 if (v) {
17397 strncpy(val, v, vmax);
17398 len = min(vmax, strlen(v));
17399 uc_free(v);
17400 }
17401 if (vmax > 0) {
17402 v = (char *) val;
17403 v[vmax - 1] = '\0';
17404 }
17405 }
17406 if (len <= 0) {
17407 len = 0;
17408 }
17409 break;
17410 }
17411 if (valLen) {
17412 *valLen = len;
17413 }
17414 }
17415 done:
17416 ;
17417 #else
17418 ret = drvcolattributes(stmt, col, id, val, valMax, valLen, val2);
17419 #endif
17420 HSTMT_UNLOCK(stmt);
17421 return ret;
17422 }
17423 #endif
17424
17425 #ifdef WINTERFACE
17426
17438 SQLRETURN SQL_API
17439 SQLColAttributesW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17440 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17441 SQLLEN *val2)
17442 {
17443 SQLRETURN ret;
17444 SQLSMALLINT len = 0;
17445
17446 HSTMT_LOCK(stmt);
17447 ret = drvcolattributes(stmt, col, id, val, valMax, &len, val2);
17448 if (SQL_SUCCEEDED(ret)) {
17449 SQLWCHAR *v = NULL;
17450
17451 switch (id) {
17452 case SQL_COLUMN_LABEL:
17453 case SQL_COLUMN_NAME:
17454 case SQL_DESC_NAME:
17455 case SQL_COLUMN_TYPE_NAME:
17456 case SQL_COLUMN_OWNER_NAME:
17457 case SQL_COLUMN_QUALIFIER_NAME:
17458 case SQL_COLUMN_TABLE_NAME:
17459 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17460 case SQL_DESC_TABLE_NAME:
17461 #endif
17462 #ifdef SQL_DESC_BASE_COLUMN_NAME
17463 case SQL_DESC_BASE_COLUMN_NAME:
17464 #endif
17465 #ifdef SQL_DESC_BASE_TABLE_NAME
17466 case SQL_DESC_BASE_TABLE_NAME:
17467 #endif
17468 if (val && valMax > 0) {
17469 int vmax = valMax / sizeof (SQLWCHAR);
17470
17471 v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17472 if (v) {
17473 uc_strncpy(val, v, vmax);
17474 len = min(vmax, uc_strlen(v));
17475 uc_free(v);
17476 len *= sizeof (SQLWCHAR);
17477 }
17478 if (vmax > 0) {
17479 v = (SQLWCHAR *) val;
17480 v[vmax - 1] = '\0';
17481 }
17482 }
17483 if (len <= 0) {
17484 len = 0;
17485 }
17486 break;
17487 }
17488 if (valLen) {
17489 *valLen = len;
17490 }
17491 }
17492 HSTMT_UNLOCK(stmt);
17493 return ret;
17494 }
17495 #endif
17496
17509 static SQLRETURN
17510 drvcolattribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17511 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17512 SQLPOINTER val2)
17513 {
17514 STMT *s;
17515 COL *c;
17516 int v = 0;
17517 char *valc = (char *) val;
17518 SQLSMALLINT dummy;
17519
17520 if (stmt == SQL_NULL_HSTMT) {
17521 return SQL_INVALID_HANDLE;
17522 }
17523 s = (STMT *) stmt;
17524 if (!s->cols) {
17525 return SQL_ERROR;
17526 }
17527 if (col < 1 || col > s->ncols) {
17528 setstat(s, -1, "invalid column", (*s->ov3) ? "07009" : "S1002");
17529 return SQL_ERROR;
17530 }
17531 if (!valLen) {
17532 valLen = &dummy;
17533 }
17534 c = s->cols + col - 1;
17535 switch (id) {
17536 case SQL_DESC_COUNT:
17537 v = s->ncols;
17538 break;
17539 case SQL_DESC_CATALOG_NAME:
17540 if (valc && valMax > 0) {
17541 strncpy(valc, c->db, valMax);
17542 valc[valMax - 1] = '\0';
17543 }
17544 *valLen = strlen(c->db);
17545 checkLen:
17546 if (*valLen >= valMax) {
17547 setstat(s, -1, "data right truncated", "01004");
17548 return SQL_SUCCESS_WITH_INFO;
17549 }
17550 break;
17551 case SQL_COLUMN_LENGTH:
17552 case SQL_DESC_LENGTH:
17553 v = c->size;
17554 break;
17555 case SQL_COLUMN_LABEL:
17556 if (c->label) {
17557 if (valc && valMax > 0) {
17558 strncpy(valc, c->label, valMax);
17559 valc[valMax - 1] = '\0';
17560 }
17561 *valLen = strlen(c->label);
17562 goto checkLen;
17563 }
17564
17565 case SQL_COLUMN_NAME:
17566 case SQL_DESC_NAME:
17567 if (valc && valMax > 0) {
17568 strncpy(valc, c->column, valMax);
17569 valc[valMax - 1] = '\0';
17570 }
17571 *valLen = strlen(c->column);
17572 goto checkLen;
17573 case SQL_DESC_SCHEMA_NAME: {
17574 char *z = "";
17575
17576 if (valc && valMax > 0) {
17577 strncpy(valc, z, valMax);
17578 valc[valMax - 1] = '\0';
17579 }
17580 *valLen = strlen(z);
17581 goto checkLen;
17582 }
17583 #ifdef SQL_DESC_BASE_COLUMN_NAME
17584 case SQL_DESC_BASE_COLUMN_NAME:
17585 if (strchr(c->column, '(') || strchr(c->column, ')')) {
17586 valc[0] = '\0';
17587 *valLen = 0;
17588 } else if (valc && valMax > 0) {
17589 strncpy(valc, c->column, valMax);
17590 valc[valMax - 1] = '\0';
17591 *valLen = strlen(c->column);
17592 }
17593 goto checkLen;
17594 #endif
17595 case SQL_DESC_TYPE_NAME: {
17596 char *p = NULL, *tn = c->typename ? c->typename : "varchar";
17597
17598 #ifdef WINTERFACE
17599 if (c->type == SQL_WCHAR ||
17600 c->type == SQL_WVARCHAR ||
17601 c->type == SQL_WLONGVARCHAR) {
17602 if (!(s->nowchar[0] || s->nowchar[1])) {
17603 if (strcasecmp(tn, "varchar") == 0) {
17604 tn = "wvarchar";
17605 }
17606 }
17607 }
17608 #endif
17609 if (valc && valMax > 0) {
17610 strncpy(valc, tn, valMax);
17611 valc[valMax - 1] = '\0';
17612 p = strchr(valc, '(');
17613 if (p) {
17614 *p = '\0';
17615 while (p > valc && ISSPACE(p[-1])) {
17616 --p;
17617 *p = '\0';
17618 }
17619 }
17620 *valLen = strlen(valc);
17621 } else {
17622 *valLen = strlen(tn);
17623 p = strchr(tn, '(');
17624 if (p) {
17625 *valLen = p - tn;
17626 while (p > tn && ISSPACE(p[-1])) {
17627 --p;
17628 *valLen -= 1;
17629 }
17630 }
17631 }
17632 goto checkLen;
17633 }
17634 case SQL_DESC_OCTET_LENGTH:
17635 v = c->size;
17636 #ifdef WINTERFACE
17637 if (c->type == SQL_WCHAR ||
17638 c->type == SQL_WVARCHAR ||
17639 c->type == SQL_WLONGVARCHAR) {
17640 if (!(s->nowchar[0] || s->nowchar[1])) {
17641 v *= sizeof (SQLWCHAR);
17642 }
17643 }
17644 #endif
17645 break;
17646 #if (SQL_COLUMN_TABLE_NAME != SQL_DESC_TABLE_NAME)
17647 case SQL_COLUMN_TABLE_NAME:
17648 #endif
17649 #ifdef SQL_DESC_BASE_TABLE_NAME
17650 case SQL_DESC_BASE_TABLE_NAME:
17651 #endif
17652 case SQL_DESC_TABLE_NAME:
17653 if (valc && valMax > 0) {
17654 strncpy(valc, c->table, valMax);
17655 valc[valMax - 1] = '\0';
17656 }
17657 *valLen = strlen(c->table);
17658 goto checkLen;
17659 case SQL_DESC_TYPE:
17660 v = c->type;
17661 #ifdef WINTERFACE
17662 if (s->nowchar[0] || s->nowchar[1]) {
17663 switch (v) {
17664 case SQL_WCHAR:
17665 v = SQL_CHAR;
17666 break;
17667 case SQL_WVARCHAR:
17668 v = SQL_VARCHAR;
17669 break;
17670 #ifdef SQL_LONGVARCHAR
17671 case SQL_WLONGVARCHAR:
17672 v = SQL_LONGVARCHAR;
17673 break;
17674 #endif
17675 }
17676 }
17677 #endif
17678 break;
17679 case SQL_DESC_CONCISE_TYPE:
17680 switch (c->type) {
17681 case SQL_INTEGER:
17682 v = SQL_C_LONG;
17683 break;
17684 case SQL_TINYINT:
17685 v = SQL_C_TINYINT;
17686 break;
17687 case SQL_SMALLINT:
17688 v = SQL_C_SHORT;
17689 break;
17690 case SQL_FLOAT:
17691 v = SQL_C_FLOAT;
17692 break;
17693 case SQL_DOUBLE:
17694 v = SQL_C_DOUBLE;
17695 break;
17696 case SQL_TIMESTAMP:
17697 v = SQL_C_TIMESTAMP;
17698 break;
17699 case SQL_TIME:
17700 v = SQL_C_TIME;
17701 break;
17702 case SQL_DATE:
17703 v = SQL_C_DATE;
17704 break;
17705 #ifdef SQL_C_TYPE_TIMESTAMP
17706 case SQL_TYPE_TIMESTAMP:
17707 v = SQL_C_TYPE_TIMESTAMP;
17708 break;
17709 #endif
17710 #ifdef SQL_C_TYPE_TIME
17711 case SQL_TYPE_TIME:
17712 v = SQL_C_TYPE_TIME;
17713 break;
17714 #endif
17715 #ifdef SQL_C_TYPE_DATE
17716 case SQL_TYPE_DATE:
17717 v = SQL_C_TYPE_DATE;
17718 break;
17719 #endif
17720 #ifdef SQL_BIT
17721 case SQL_BIT:
17722 v = SQL_C_BIT;
17723 break;
17724 #endif
17725 #ifdef SQL_BIGINT
17726 case SQL_BIGINT:
17727 v = SQL_C_SBIGINT;
17728 break;
17729 #endif
17730 default:
17731 #ifdef WINTERFACE
17732 v = (s->nowchar[0] || s->nowchar[1]) ? SQL_C_CHAR : SQL_C_WCHAR;
17733 #else
17734 v = SQL_C_CHAR;
17735 #endif
17736 break;
17737 }
17738 break;
17739 case SQL_DESC_UPDATABLE:
17740 v = SQL_TRUE;
17741 break;
17742 case SQL_COLUMN_DISPLAY_SIZE:
17743 v = c->size;
17744 break;
17745 case SQL_COLUMN_UNSIGNED:
17746 v = c->nosign ? SQL_TRUE : SQL_FALSE;
17747 break;
17748 case SQL_COLUMN_SEARCHABLE:
17749 v = SQL_SEARCHABLE;
17750 break;
17751 case SQL_COLUMN_SCALE:
17752 case SQL_DESC_SCALE:
17753 v = c->scale;
17754 break;
17755 case SQL_COLUMN_PRECISION:
17756 case SQL_DESC_PRECISION:
17757 switch (c->type) {
17758 case SQL_SMALLINT:
17759 v = 5;
17760 break;
17761 case SQL_INTEGER:
17762 v = 10;
17763 break;
17764 case SQL_FLOAT:
17765 case SQL_REAL:
17766 case SQL_DOUBLE:
17767 v = 15;
17768 break;
17769 case SQL_DATE:
17770 v = 0;
17771 break;
17772 case SQL_TIME:
17773 v = 0;
17774 break;
17775 #ifdef SQL_TYPE_TIMESTAMP
17776 case SQL_TYPE_TIMESTAMP:
17777 #endif
17778 case SQL_TIMESTAMP:
17779 v = (c->prec >= 0 && c->prec <= 3) ? c->prec : 3;
17780 break;
17781 default:
17782 v = c->prec;
17783 break;
17784 }
17785 break;
17786 case SQL_COLUMN_MONEY:
17787 v = SQL_FALSE;
17788 break;
17789 case SQL_COLUMN_AUTO_INCREMENT:
17790 v = c->autoinc;
17791 break;
17792 case SQL_DESC_NULLABLE:
17793 v = c->notnull;
17794 break;
17795 #ifdef SQL_DESC_NUM_PREC_RADIX
17796 case SQL_DESC_NUM_PREC_RADIX:
17797 switch (c->type) {
17798 #ifdef WINTERFACE
17799 case SQL_WCHAR:
17800 case SQL_WVARCHAR:
17801 #ifdef SQL_LONGVARCHAR
17802 case SQL_WLONGVARCHAR:
17803 #endif
17804 #endif
17805 case SQL_CHAR:
17806 case SQL_VARCHAR:
17807 #ifdef SQL_LONGVARCHAR
17808 case SQL_LONGVARCHAR:
17809 #endif
17810 case SQL_BINARY:
17811 case SQL_VARBINARY:
17812 case SQL_LONGVARBINARY:
17813 v = 0;
17814 break;
17815 default:
17816 v = 2;
17817 }
17818 break;
17819 #endif
17820 default:
17821 setstat(s, -1, "unsupported column attribute %d", "HY091", id);
17822 return SQL_ERROR;
17823 }
17824 if (val2) {
17825 *(SQLLEN *) val2 = v;
17826 }
17827 return SQL_SUCCESS;
17828 }
17829
17830 #ifndef WINTERFACE
17831
17843 SQLRETURN SQL_API
17844 SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17845 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17846 COLATTRIBUTE_LAST_ARG_TYPE val2)
17847 {
17848 #if defined(_WIN32) || defined(_WIN64)
17849 SQLSMALLINT len = 0;
17850 #endif
17851 SQLRETURN ret;
17852
17853 HSTMT_LOCK(stmt);
17854 #if defined(_WIN32) || defined(_WIN64)
17855 if (!((STMT *) stmt)->oemcp[0]) {
17856 ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
17857 (SQLPOINTER) val2);
17858 goto done;
17859 }
17860 ret = drvcolattribute(stmt, col, id, val, valMax, &len,
17861 (SQLPOINTER) val2);
17862 if (SQL_SUCCEEDED(ret)) {
17863 char *v = NULL;
17864
17865 switch (id) {
17866 case SQL_DESC_SCHEMA_NAME:
17867 case SQL_DESC_CATALOG_NAME:
17868 case SQL_COLUMN_LABEL:
17869 case SQL_DESC_NAME:
17870 case SQL_DESC_TABLE_NAME:
17871 #ifdef SQL_DESC_BASE_TABLE_NAME
17872 case SQL_DESC_BASE_TABLE_NAME:
17873 #endif
17874 #ifdef SQL_DESC_BASE_COLUMN_NAME
17875 case SQL_DESC_BASE_COLUMN_NAME:
17876 #endif
17877 case SQL_DESC_TYPE_NAME:
17878 if (val && valMax > 0) {
17879 int vmax = valMax;
17880
17881 v = utf_to_wmb((char *) val, SQL_NTS);
17882 if (v) {
17883 strncpy(val, v, vmax);
17884 len = min(vmax, strlen(v));
17885 uc_free(v);
17886 }
17887 if (vmax > 0) {
17888 v = (char *) val;
17889 v[vmax - 1] = '\0';
17890 }
17891 }
17892 if (len <= 0) {
17893 len = 0;
17894 }
17895 break;
17896 }
17897 if (valLen) {
17898 *valLen = len;
17899 }
17900 }
17901 done:
17902 ;
17903 #else
17904 ret = drvcolattribute(stmt, col, id, val, valMax, valLen,
17905 (SQLPOINTER) val2);
17906 #endif
17907 HSTMT_UNLOCK(stmt);
17908 return ret;
17909 }
17910 #endif
17911
17912 #ifdef WINTERFACE
17913
17925 SQLRETURN SQL_API
17926 SQLColAttributeW(SQLHSTMT stmt, SQLUSMALLINT col, SQLUSMALLINT id,
17927 SQLPOINTER val, SQLSMALLINT valMax, SQLSMALLINT *valLen,
17928 COLATTRIBUTE_LAST_ARG_TYPE val2)
17929 {
17930 SQLRETURN ret;
17931 SQLSMALLINT len = 0;
17932
17933 HSTMT_LOCK(stmt);
17934 ret = drvcolattribute(stmt, col, id, val, valMax, &len,
17935 (SQLPOINTER) val2);
17936 if (SQL_SUCCEEDED(ret)) {
17937 SQLWCHAR *v = NULL;
17938
17939 switch (id) {
17940 case SQL_DESC_SCHEMA_NAME:
17941 case SQL_DESC_CATALOG_NAME:
17942 case SQL_COLUMN_LABEL:
17943 case SQL_DESC_NAME:
17944 case SQL_DESC_TABLE_NAME:
17945 #ifdef SQL_DESC_BASE_TABLE_NAME
17946 case SQL_DESC_BASE_TABLE_NAME:
17947 #endif
17948 #ifdef SQL_DESC_BASE_COLUMN_NAME
17949 case SQL_DESC_BASE_COLUMN_NAME:
17950 #endif
17951 case SQL_DESC_TYPE_NAME:
17952 if (val && valMax > 0) {
17953 int vmax = valMax / sizeof (SQLWCHAR);
17954
17955 v = uc_from_utf((SQLCHAR *) val, SQL_NTS);
17956 if (v) {
17957 uc_strncpy(val, v, vmax);
17958 len = min(vmax, uc_strlen(v));
17959 uc_free(v);
17960 len *= sizeof (SQLWCHAR);
17961 }
17962 if (vmax > 0) {
17963 v = (SQLWCHAR *) val;
17964 v[vmax - 1] = '\0';
17965 }
17966 }
17967 if (len <= 0) {
17968 len = 0;
17969 }
17970 break;
17971 }
17972 if (valLen) {
17973 *valLen = len;
17974 }
17975 }
17976 HSTMT_UNLOCK(stmt);
17977 return ret;
17978 }
17979 #endif
17980
17994 static SQLRETURN
17995 drverror(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
17996 SQLCHAR *sqlState, SQLINTEGER *nativeErr,
17997 SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
17998 {
17999 SQLCHAR dummy0[6];
18000 SQLINTEGER dummy1;
18001 SQLSMALLINT dummy2;
18002
18003 if (env == SQL_NULL_HENV &&
18004 dbc == SQL_NULL_HDBC &&
18005 stmt == SQL_NULL_HSTMT) {
18006 return SQL_INVALID_HANDLE;
18007 }
18008 if (sqlState) {
18009 sqlState[0] = '\0';
18010 } else {
18011 sqlState = dummy0;
18012 }
18013 if (!nativeErr) {
18014 nativeErr = &dummy1;
18015 }
18016 *nativeErr = 0;
18017 if (!errlen) {
18018 errlen = &dummy2;
18019 }
18020 *errlen = 0;
18021 if (errmsg) {
18022 if (errmax > 0) {
18023 errmsg[0] = '\0';
18024 }
18025 } else {
18026 errmsg = dummy0;
18027 errmax = 0;
18028 }
18029 if (stmt) {
18030 STMT *s = (STMT *) stmt;
18031
18032 HSTMT_LOCK(stmt);
18033 if (s->logmsg[0] == '\0') {
18034 HSTMT_UNLOCK(stmt);
18035 goto noerr;
18036 }
18037 *nativeErr = s->naterr;
18038 strcpy((char *) sqlState, s->sqlstate);
18039 if (errmax == SQL_NTS) {
18040 strcpy((char *) errmsg, "[SQLite]");
18041 strcat((char *) errmsg, (char *) s->logmsg);
18042 *errlen = strlen((char *) errmsg);
18043 } else {
18044 strncpy((char *) errmsg, "[SQLite]", errmax);
18045 if (errmax - 8 > 0) {
18046 strncpy((char *) errmsg + 8, (char *) s->logmsg, errmax - 8);
18047 }
18048 *errlen = min(strlen((char *) s->logmsg) + 8, errmax);
18049 }
18050 s->logmsg[0] = '\0';
18051 HSTMT_UNLOCK(stmt);
18052 return SQL_SUCCESS;
18053 }
18054 if (dbc) {
18055 DBC *d = (DBC *) dbc;
18056
18057 HDBC_LOCK(dbc);
18058 if (d->magic != DBC_MAGIC || d->logmsg[0] == '\0') {
18059 HDBC_UNLOCK(dbc);
18060 goto noerr;
18061 }
18062 *nativeErr = d->naterr;
18063 strcpy((char *) sqlState, d->sqlstate);
18064 if (errmax == SQL_NTS) {
18065 strcpy((char *) errmsg, "[SQLite]");
18066 strcat((char *) errmsg, (char *) d->logmsg);
18067 *errlen = strlen((char *) errmsg);
18068 } else {
18069 strncpy((char *) errmsg, "[SQLite]", errmax);
18070 if (errmax - 8 > 0) {
18071 strncpy((char *) errmsg + 8, (char *) d->logmsg, errmax - 8);
18072 }
18073 *errlen = min(strlen((char *) d->logmsg) + 8, errmax);
18074 }
18075 d->logmsg[0] = '\0';
18076 HDBC_UNLOCK(dbc);
18077 return SQL_SUCCESS;
18078 }
18079 noerr:
18080 sqlState[0] = '\0';
18081 errmsg[0] = '\0';
18082 *nativeErr = 0;
18083 *errlen = 0;
18084 return SQL_NO_DATA;
18085 }
18086
18087 #ifndef WINTERFACE
18088
18101 SQLRETURN SQL_API
18102 SQLError(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18103 SQLCHAR *sqlState, SQLINTEGER *nativeErr,
18104 SQLCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18105 {
18106 return drverror(env, dbc, stmt, sqlState, nativeErr,
18107 errmsg, errmax, errlen);
18108 }
18109 #endif
18110
18111 #ifdef WINTERFACE
18112
18125 SQLRETURN SQL_API
18126 SQLErrorW(SQLHENV env, SQLHDBC dbc, SQLHSTMT stmt,
18127 SQLWCHAR *sqlState, SQLINTEGER *nativeErr,
18128 SQLWCHAR *errmsg, SQLSMALLINT errmax, SQLSMALLINT *errlen)
18129 {
18130 char state[16];
18131 SQLSMALLINT len = 0;
18132 SQLRETURN ret;
18133
18134 ret = drverror(env, dbc, stmt, (SQLCHAR *) state, nativeErr,
18135 (SQLCHAR *) errmsg, errmax, &len);
18136 if (ret == SQL_SUCCESS) {
18137 if (sqlState) {
18138 uc_from_utf_buf((SQLCHAR *) state, -1, sqlState,
18139 6 * sizeof (SQLWCHAR));
18140 }
18141 if (errmsg) {
18142 if (len > 0) {
18143 SQLWCHAR *e = NULL;
18144
18145 e = uc_from_utf((SQLCHAR *) errmsg, len);
18146 if (e) {
18147 if (errmax > 0) {
18148 uc_strncpy(errmsg, e, errmax);
18149 e[len] = 0;
18150 len = min(errmax, uc_strlen(e));
18151 } else {
18152 len = uc_strlen(e);
18153 }
18154 uc_free(e);
18155 } else {
18156 len = 0;
18157 }
18158 }
18159 if (len <= 0) {
18160 len = 0;
18161 if (errmax > 0) {
18162 errmsg[0] = 0;
18163 }
18164 }
18165 } else {
18166 len = 0;
18167 }
18168 if (errlen) {
18169 *errlen = len;
18170 }
18171 } else if (ret == SQL_NO_DATA) {
18172 if (sqlState) {
18173 sqlState[0] = 0;
18174 }
18175 if (errmsg) {
18176 if (errmax > 0) {
18177 errmsg[0] = 0;
18178 }
18179 }
18180 if (errlen) {
18181 *errlen = 0;
18182 }
18183 }
18184 return ret;
18185 }
18186 #endif
18187
18194 SQLRETURN SQL_API
18195 SQLMoreResults(SQLHSTMT stmt)
18196 {
18197 HSTMT_LOCK(stmt);
18198 if (stmt == SQL_NULL_HSTMT) {
18199 return SQL_INVALID_HANDLE;
18200 }
18201 HSTMT_UNLOCK(stmt);
18202 return SQL_NO_DATA;
18203 }
18204
18213 static SQLRETURN
18214 setupdyncols(STMT *s, sqlite3_stmt *s3stmt, int *ncolsp)
18215 {
18216 int ncols = *ncolsp, guessed_types = 0;
18217 SQLRETURN ret = SQL_SUCCESS;
18218
18219 if (ncols > 0) {
18220 int i;
18221 PTRDIFF_T size;
18222 char *p;
18223 COL *dyncols;
18224 DBC *d = (DBC *) s->dbc;
18225 const char *colname, *typename;
18226 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18227 char *tblname;
18228 #endif
18229
18230 for (i = size = 0; i < ncols; i++) {
18231 colname = sqlite3_column_name(s3stmt, i);
18232 size += 3 + 3 * strlen(colname);
18233 }
18234 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18235 tblname = (char *) size;
18236 for (i = 0; i < ncols; i++) {
18237 p = (char *) sqlite3_column_table_name(s3stmt, i);
18238 size += 2 + (p ? strlen(p) : 0);
18239 }
18240 #endif
18241 dyncols = xmalloc(ncols * sizeof (COL) + size);
18242 if (!dyncols) {
18243 freedyncols(s);
18244 *ncolsp = 0;
18245 ret = SQL_ERROR;
18246 } else {
18247 p = (char *) (dyncols + ncols);
18248 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18249 tblname = p + (PTRDIFF_T) tblname;
18250 #endif
18251 for (i = 0; i < ncols; i++) {
18252 char *q;
18253
18254 colname = sqlite3_column_name(s3stmt, i);
18255 if (d->trace) {
18256 fprintf(d->trace, "-- column %d name: '%s'\n",
18257 i + 1, colname);
18258 fflush(d->trace);
18259 }
18260 #if defined(HAVE_SQLITE3COLUMNTABLENAME) && (HAVE_SQLITE3COLUMNTABLENAME)
18261 q = (char *) sqlite3_column_table_name(s3stmt, i);
18262 strcpy(tblname, q ? q : "");
18263 if (d->trace) {
18264 fprintf(d->trace, "-- table %d name: '%s'\n",
18265 i + 1, tblname);
18266 fflush(d->trace);
18267 }
18268 dyncols[i].table = tblname;
18269 tblname += strlen(tblname) + 1;
18270 #endif
18271 typename = s3stmt_coltype(s3stmt, i, d, &guessed_types);
18272 dyncols[i].db = ((DBC *) (s->dbc))->dbname;
18273 strcpy(p, colname);
18274 dyncols[i].label = p;
18275 p += strlen(p) + 1;
18276 q = strchr(colname, '.');
18277 if (q) {
18278 char *q2 = strchr(q + 1, '.');
18279
18280
18281 if (q2) {
18282 q = q2;
18283 }
18284 }
18285 if (q) {
18286 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18287 dyncols[i].table = p;
18288 #endif
18289 strncpy(p, colname, q - colname);
18290 p[q - colname] = '\0';
18291 p += strlen(p) + 1;
18292 strcpy(p, q + 1);
18293 dyncols[i].column = p;
18294 p += strlen(p) + 1;
18295 } else {
18296 #if !defined(HAVE_SQLITE3COLUMNTABLENAME) || !(HAVE_SQLITE3COLUMNTABLENAME)
18297 dyncols[i].table = "";
18298 #endif
18299 strcpy(p, colname);
18300 dyncols[i].column = p;
18301 p += strlen(p) + 1;
18302 }
18303 if (s->longnames) {
18304 dyncols[i].column = dyncols[i].label;
18305 }
18306 #ifdef SQL_LONGVARCHAR
18307 dyncols[i].type = SQL_LONGVARCHAR;
18308 dyncols[i].size = 65535;
18309 #else
18310 dyncols[i].type = SQL_VARCHAR;
18311 dyncols[i].size = 255;
18312 #endif
18313 dyncols[i].index = i;
18314 dyncols[i].scale = 0;
18315 dyncols[i].prec = 0;
18316 dyncols[i].nosign = 1;
18317 dyncols[i].autoinc = SQL_FALSE;
18318 dyncols[i].notnull = SQL_NULLABLE;
18319 dyncols[i].ispk = -1;
18320 dyncols[i].isrowid = -1;
18321 #ifdef FULL_METADATA
18322 s3stmt_addmeta(s3stmt, i, d, &dyncols[i]);
18323 #endif
18324 dyncols[i].typename = xstrdup(typename);
18325 }
18326 freedyncols(s);
18327 s->dyncols = s->cols = dyncols;
18328 s->dcols = ncols;
18329 fixupdyncols(s, d);
18330 s->guessed_types = guessed_types;
18331 }
18332 }
18333 return ret;
18334 }
18335
18344 static SQLRETURN
18345 drvprepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18346 {
18347 STMT *s;
18348 DBC *d;
18349 char *errp = NULL;
18350 SQLRETURN sret;
18351
18352 if (stmt == SQL_NULL_HSTMT) {
18353 return SQL_INVALID_HANDLE;
18354 }
18355 s = (STMT *) stmt;
18356 if (s->dbc == SQL_NULL_HDBC) {
18357 noconn:
18358 return noconn(s);
18359 }
18360 d = s->dbc;
18361 if (!d->sqlite) {
18362 goto noconn;
18363 }
18364 s3stmt_end(s);
18365 s3stmt_drop(s);
18366 sret = starttran(s);
18367 if (sret != SQL_SUCCESS) {
18368 return sret;
18369 }
18370 freep(&s->query);
18371 s->query = (SQLCHAR *) fixupsql((char *) query, queryLen,
18372 (d->version >= 0x030805),
18373 &s->nparams, &s->isselect, &errp);
18374 if (!s->query) {
18375 if (errp) {
18376 setstat(s, -1, "%s", (*s->ov3) ? "HY000" : "S1000", errp);
18377 return SQL_ERROR;
18378 }
18379 return nomem(s);
18380 }
18381 errp = NULL;
18382 freeresult(s, -1);
18383 if (s->isselect == 1) {
18384 int ret, ncols, nretry = 0;
18385 const char *rest;
18386 sqlite3_stmt *s3stmt = NULL;
18387
18388 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18389 dbtraceapi(d, "sqlite3_prepare_v2", (char *) s->query);
18390 #else
18391 dbtraceapi(d, "sqlite3_prepare", (char *) s->query);
18392 #endif
18393 do {
18394 s3stmt = NULL;
18395 #if defined(HAVE_SQLITE3PREPAREV2) && (HAVE_SQLITE3PREPAREV2)
18396 ret = sqlite3_prepare_v2(d->sqlite, (char *) s->query, -1,
18397 &s3stmt, &rest);
18398 #else
18399 ret = sqlite3_prepare(d->sqlite, (char *) s->query, -1,
18400 &s3stmt, &rest);
18401 #endif
18402 if (ret != SQLITE_OK) {
18403 if (s3stmt) {
18404 sqlite3_finalize(s3stmt);
18405 s3stmt = NULL;
18406 }
18407 }
18408 } while (ret == SQLITE_SCHEMA && (++nretry) < 2);
18409 dbtracerc(d, ret, NULL);
18410 if (ret != SQLITE_OK) {
18411 if (s3stmt) {
18412 dbtraceapi(d, "sqlite3_finalize", 0);
18413 sqlite3_finalize(s3stmt);
18414 }
18415 setstat(s, ret, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18416 sqlite3_errmsg(d->sqlite), ret);
18417 return SQL_ERROR;
18418 }
18419 if (sqlite3_bind_parameter_count(s3stmt) != s->nparams) {
18420 dbtraceapi(d, "sqlite3_finalize", 0);
18421 sqlite3_finalize(s3stmt);
18422 setstat(s, SQLITE_ERROR, "parameter marker count incorrect",
18423 (*s->ov3) ? "HY000" : "S1000");
18424 return SQL_ERROR;
18425 }
18426 ncols = sqlite3_column_count(s3stmt);
18427 s->guessed_types = 0;
18428 setupdyncols(s, s3stmt, &ncols);
18429 s->ncols = ncols;
18430 s->s3stmt = s3stmt;
18431 }
18432 mkbindcols(s, s->ncols);
18433 s->paramset_count = 0;
18434 return SQL_SUCCESS;
18435 }
18436
18444 static SQLRETURN
18445 drvexecute(SQLHSTMT stmt, int initial)
18446 {
18447 STMT *s;
18448 DBC *d;
18449 char *errp = NULL;
18450 int rc, i, ncols = 0, nrows = 0, busy_count;
18451 SQLRETURN ret;
18452
18453 if (stmt == SQL_NULL_HSTMT) {
18454 return SQL_INVALID_HANDLE;
18455 }
18456 s = (STMT *) stmt;
18457 if (s->dbc == SQL_NULL_HDBC) {
18458 noconn:
18459 return noconn(s);
18460 }
18461 d = (DBC *) s->dbc;
18462 if (!d->sqlite) {
18463 goto noconn;
18464 }
18465 if (!s->query) {
18466 setstat(s, -1, "no query prepared", (*s->ov3) ? "HY000" : "S1000");
18467 return SQL_ERROR;
18468 }
18469 if (s->nbindparms < s->nparams) {
18470 unbound:
18471 setstat(s, -1, "unbound parameters in query",
18472 (*s->ov3) ? "HY000" : "S1000");
18473 return SQL_ERROR;
18474 }
18475 for (i = 0; i < s->nparams; i++) {
18476 BINDPARM *p = &s->bindparms[i];
18477
18478 if (!p->bound) {
18479 goto unbound;
18480 }
18481 if (initial) {
18482 SQLLEN *lenp = p->lenp;
18483
18484 if (lenp && *lenp < 0 && *lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18485 *lenp != SQL_NTS && *lenp != SQL_NULL_DATA &&
18486 *lenp != SQL_DATA_AT_EXEC) {
18487 setstat(s, -1, "invalid length reference", "HY009");
18488 return SQL_ERROR;
18489 }
18490 if (lenp && (*lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18491 *lenp == SQL_DATA_AT_EXEC)) {
18492 p->need = 1;
18493 p->offs = 0;
18494 p->len = 0;
18495 }
18496 }
18497 }
18498 ret = starttran(s);
18499 if (ret != SQL_SUCCESS) {
18500 goto cleanup;
18501 }
18502 busy_count = 0;
18503 again:
18504 s3stmt_end(s);
18505 if (initial) {
18506
18507 s->pdcount = -1;
18508 for (i = 0; i < s->nparams; i++) {
18509 BINDPARM *p = &s->bindparms[i];
18510
18511 if (p->param == p->parbuf) {
18512 p->param = NULL;
18513 }
18514 freep(&p->parbuf);
18515 if (p->need <= 0 &&
18516 p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18517 *p->lenp == SQL_DATA_AT_EXEC)) {
18518 p->need = 1;
18519 p->offs = 0;
18520 p->len = 0;
18521 }
18522 }
18523 }
18524 if (s->nparams) {
18525 for (i = 0; i < s->nparams; i++) {
18526 ret = setupparam(s, (char *) s->query, i);
18527 if (ret != SQL_SUCCESS) {
18528 goto cleanup;
18529 }
18530 }
18531 }
18532 freeresult(s, 0);
18533 if (s->isselect == 1 && !d->intrans &&
18534 s->curtype == SQL_CURSOR_FORWARD_ONLY &&
18535 d->step_enable && s->nparams == 0 && d->cur_s3stmt == NULL) {
18536 s->nrows = -1;
18537 ret = s3stmt_start(s);
18538 if (ret == SQL_SUCCESS) {
18539 goto done2;
18540 }
18541 }
18542 rc = drvgettable(s, s->s3stmt ? NULL : (char *) s->query, &s->rows,
18543 &s->nrows, &ncols, &errp, s->nparams, s->bindparms);
18544 dbtracerc(d, rc, errp);
18545 if (rc == SQLITE_BUSY) {
18546 if (busy_handler((void *) d, ++busy_count)) {
18547 if (errp) {
18548 sqlite3_free(errp);
18549 errp = NULL;
18550 }
18551 for (i = 0; i < s->nparams; i++) {
18552 BINDPARM *p = &s->bindparms[i];
18553
18554 if (p->param == p->parbuf) {
18555 p->param = NULL;
18556 }
18557 freep(&p->parbuf);
18558 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18559 *p->lenp != SQL_DATA_AT_EXEC)) {
18560 p->param = p->param0;
18561 }
18562 p->lenp = p->lenp0;
18563 }
18564 s->nrows = 0;
18565 goto again;
18566 }
18567 }
18568 if (rc != SQLITE_OK) {
18569 setstat(s, rc, "%s (%d)", (*s->ov3) ? "HY000" : "S1000",
18570 errp ? errp : "unknown error", rc);
18571 if (errp) {
18572 sqlite3_free(errp);
18573 errp = NULL;
18574 }
18575 ret = SQL_ERROR;
18576 goto cleanup;
18577 }
18578 if (errp) {
18579 sqlite3_free(errp);
18580 errp = NULL;
18581 }
18582 s->rowfree = freerows;
18583 if (s->isselect <= 0 || s->isselect > 1) {
18584
18585
18586
18587 freeresult(s, -1);
18588 nrows += sqlite3_changes(d->sqlite);
18589 s->nrows = nrows;
18590 goto done;
18591 }
18592 if (s->ncols != ncols) {
18593
18594
18595
18596 setstat(s, -1, "broken result set %d/%d",
18597 (*s->ov3) ? "HY000" : "S1000", s->ncols, ncols);
18598 ret = SQL_ERROR;
18599 goto cleanup;
18600 }
18601 done:
18602 mkbindcols(s, s->ncols);
18603 done2:
18604 ret = SQL_SUCCESS;
18605 s->rowp = s->rowprs = -1;
18606 s->paramset_count++;
18607 s->paramset_nrows = s->nrows;
18608 if (s->paramset_count < s->paramset_size) {
18609 for (i = 0; i < s->nparams; i++) {
18610 BINDPARM *p = &s->bindparms[i];
18611
18612 if (p->param == p->parbuf) {
18613 p->param = NULL;
18614 }
18615 freep(&p->parbuf);
18616 if (p->lenp0 &&
18617 s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18618 p->lenp = (SQLLEN *) ((char *) p->lenp0 +
18619 s->paramset_count * s->parm_bind_type);
18620 } else if (p->lenp0 && p->inc > 0) {
18621 p->lenp = p->lenp0 + s->paramset_count;
18622 }
18623 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18624 *p->lenp != SQL_DATA_AT_EXEC)) {
18625 if (p->param0 &&
18626 s->parm_bind_type != SQL_PARAM_BIND_BY_COLUMN) {
18627 p->param = (char *) p->param0 +
18628 s->paramset_count * s->parm_bind_type;
18629 } else if (p->param0 && p->inc > 0) {
18630 p->param = (char *) p->param0 +
18631 s->paramset_count * p->inc;
18632 }
18633 } else if (p->lenp && (*p->lenp <= SQL_LEN_DATA_AT_EXEC_OFFSET ||
18634 *p->lenp == SQL_DATA_AT_EXEC)) {
18635 p->need = 1;
18636 p->offs = 0;
18637 p->len = 0;
18638 }
18639 }
18640 goto again;
18641 }
18642 cleanup:
18643 if (ret != SQL_NEED_DATA) {
18644 for (i = 0; i < s->nparams; i++) {
18645 BINDPARM *p = &s->bindparms[i];
18646
18647 if (p->param == p->parbuf) {
18648 p->param = NULL;
18649 }
18650 freep(&p->parbuf);
18651 if (!p->lenp || (*p->lenp > SQL_LEN_DATA_AT_EXEC_OFFSET &&
18652 *p->lenp != SQL_DATA_AT_EXEC)) {
18653 p->param = p->param0;
18654 }
18655 p->lenp = p->lenp0;
18656 }
18657 s->nrows = s->paramset_nrows;
18658 if (s->parm_proc) {
18659 *s->parm_proc = s->paramset_count;
18660 }
18661 s->paramset_count = 0;
18662 s->paramset_nrows = 0;
18663 }
18664
18665
18666
18667
18668 if (*s->ov3 && s->isselect == 0 &&
18669 ret == SQL_SUCCESS && nrows == 0) {
18670 ret = SQL_NO_DATA;
18671 }
18672 return ret;
18673 }
18674
18675 #ifndef WINTERFACE
18676
18684 SQLRETURN SQL_API
18685 SQLPrepare(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18686 {
18687 SQLRETURN ret;
18688 #if defined(_WIN32) || defined(_WIN64)
18689 char *q;
18690 #endif
18691
18692 HSTMT_LOCK(stmt);
18693 #if defined(_WIN32) || defined(_WIN64)
18694 if (!((STMT *) stmt)->oemcp[0]) {
18695 ret = drvprepare(stmt, query, queryLen);
18696 goto done;
18697 }
18698 q = wmb_to_utf_c((char *) query, queryLen);
18699 if (!q) {
18700 ret = nomem((STMT *) stmt);
18701 goto done;
18702 }
18703 query = (SQLCHAR *) q;
18704 queryLen = SQL_NTS;
18705 #endif
18706 ret = drvprepare(stmt, query, queryLen);
18707 #if defined(_WIN32) || defined(_WIN64)
18708 uc_free(q);
18709 done:
18710 ;
18711 #endif
18712 HSTMT_UNLOCK(stmt);
18713 return ret;
18714 }
18715 #endif
18716
18717 #ifdef WINTERFACE
18718
18726 SQLRETURN SQL_API
18727 SQLPrepareW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18728 {
18729 SQLRETURN ret;
18730 char *q = uc_to_utf_c(query, queryLen);
18731
18732 HSTMT_LOCK(stmt);
18733 if (!q) {
18734 ret = nomem((STMT *) stmt);
18735 goto done;
18736 }
18737 ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18738 uc_free(q);
18739 done:
18740 HSTMT_UNLOCK(stmt);
18741 return ret;
18742 }
18743 #endif
18744
18751 SQLRETURN SQL_API
18752 SQLExecute(SQLHSTMT stmt)
18753 {
18754 SQLRETURN ret;
18755
18756 HSTMT_LOCK(stmt);
18757 ret = drvexecute(stmt, 1);
18758 HSTMT_UNLOCK(stmt);
18759 return ret;
18760 }
18761
18762 #ifndef WINTERFACE
18763
18771 SQLRETURN SQL_API
18772 SQLExecDirect(SQLHSTMT stmt, SQLCHAR *query, SQLINTEGER queryLen)
18773 {
18774 SQLRETURN ret;
18775 #if defined(_WIN32) || defined(_WIN64)
18776 char *q;
18777 #endif
18778
18779 HSTMT_LOCK(stmt);
18780 #if defined(_WIN32) || defined(_WIN64)
18781 if (!((STMT *) stmt)->oemcp[0]) {
18782 ret = drvprepare(stmt, query, queryLen);
18783 if (ret == SQL_SUCCESS) {
18784 ret = drvexecute(stmt, 1);
18785 }
18786 goto done;
18787 }
18788 q = wmb_to_utf_c((char *) query, queryLen);
18789 if (!q) {
18790 ret = nomem((STMT *) stmt);
18791 goto done;
18792 }
18793 query = (SQLCHAR *) q;
18794 queryLen = SQL_NTS;
18795 #endif
18796 ret = drvprepare(stmt, query, queryLen);
18797 if (ret == SQL_SUCCESS) {
18798 ret = drvexecute(stmt, 1);
18799 }
18800 #if defined(_WIN32) || defined(_WIN64)
18801 uc_free(q);
18802 done:
18803 ;
18804 #endif
18805 HSTMT_UNLOCK(stmt);
18806 return ret;
18807 }
18808 #endif
18809
18810 #ifdef WINTERFACE
18811
18819 SQLRETURN SQL_API
18820 SQLExecDirectW(SQLHSTMT stmt, SQLWCHAR *query, SQLINTEGER queryLen)
18821 {
18822 SQLRETURN ret;
18823 char *q = uc_to_utf_c(query, queryLen);
18824
18825 HSTMT_LOCK(stmt);
18826 if (!q) {
18827 ret = nomem((STMT *) stmt);
18828 goto done;
18829 }
18830 ret = drvprepare(stmt, (SQLCHAR *) q, SQL_NTS);
18831 uc_free(q);
18832 if (ret == SQL_SUCCESS) {
18833 ret = drvexecute(stmt, 1);
18834 }
18835 done:
18836 HSTMT_UNLOCK(stmt);
18837 return ret;
18838 }
18839 #endif
18840
18841
18842 #if defined(_WIN32) || defined(_WIN64)
18843 #ifndef WITHOUT_DRIVERMGR
18844
18845
18846
18847
18848
18849 #include <windowsx.h>
18850 #include <winuser.h>
18851
18852 #define MAXPATHLEN (259+1)
18853 #define MAXKEYLEN (15+1)
18854 #define MAXDESC (255+1)
18855 #define MAXDSNAME (255+1)
18856 #define MAXTONAME (32+1)
18857 #define MAXDBNAME MAXPATHLEN
18858
18859
18860
18861 #define KEY_DSN 0
18862 #define KEY_DESC 1
18863 #define KEY_DBNAME 2
18864 #define KEY_BUSY 3
18865 #define KEY_DRIVER 4
18866 #define KEY_STEPAPI 5
18867 #define KEY_SYNCP 6
18868 #define KEY_NOTXN 7
18869 #define KEY_SHORTNAM 8
18870 #define KEY_LONGNAM 9
18871 #define KEY_NOCREAT 10
18872 #define KEY_NOWCHAR 11
18873 #define KEY_LOADEXT 12
18874 #define KEY_JMODE 13
18875 #define KEY_FKSUPPORT 14
18876 #define KEY_OEMCP 15
18877 #define KEY_BIGINT 16
18878 #define KEY_PASSWD 17
18879 #define KEY_JDCONV 18
18880 #define NUMOFKEYS 19
18881
18882 typedef struct {
18883 BOOL supplied;
18884 char attr[MAXPATHLEN*4];
18885 } ATTR;
18886
18887 typedef struct {
18888 SQLHWND parent;
18889 LPCSTR driver;
18890 ATTR attr[NUMOFKEYS];
18891 char DSN[MAXDSNAME];
18892 BOOL newDSN;
18893 BOOL defDSN;
18894 } SETUPDLG;
18895
18896 static struct {
18897 char *key;
18898 int ikey;
18899 } attrLookup[] = {
18900 { "DSN", KEY_DSN },
18901 { "DESC", KEY_DESC },
18902 { "Description", KEY_DESC},
18903 { "Database", KEY_DBNAME },
18904 { "Timeout", KEY_BUSY },
18905 { "Driver", KEY_DRIVER },
18906 { "StepAPI", KEY_STEPAPI },
18907 { "SyncPragma", KEY_SYNCP },
18908 { "NoTXN", KEY_NOTXN },
18909 { "ShortNames", KEY_SHORTNAM },
18910 { "LongNames", KEY_LONGNAM },
18911 { "NoCreat", KEY_NOCREAT },
18912 { "NoWCHAR", KEY_NOWCHAR },
18913 { "LoadExt", KEY_LOADEXT },
18914 { "JournalMode", KEY_JMODE },
18915 { "FKSupport", KEY_FKSUPPORT },
18916 { "OEMCP", KEY_OEMCP },
18917 { "BigInt", KEY_BIGINT },
18918 { "PWD", KEY_PASSWD },
18919 { "JDConv", KEY_JDCONV },
18920 { NULL, 0 }
18921 };
18922
18929 static void
18930 ParseAttributes(LPCSTR attribs, SETUPDLG *setupdlg)
18931 {
18932 char *str = (char *) attribs, *start, key[MAXKEYLEN];
18933 int elem, nkey;
18934
18935 while (*str) {
18936 start = str;
18937 if ((str = strchr(str, '=')) == NULL) {
18938 return;
18939 }
18940 elem = -1;
18941 nkey = str - start;
18942 if (nkey < sizeof (key)) {
18943 int i;
18944
18945 memcpy(key, start, nkey);
18946 key[nkey] = '\0';
18947 for (i = 0; attrLookup[i].key; i++) {
18948 if (strcasecmp(attrLookup[i].key, key) == 0) {
18949 elem = attrLookup[i].ikey;
18950 break;
18951 }
18952 }
18953 }
18954 start = ++str;
18955 while (*str && *str != ';') {
18956 ++str;
18957 }
18958 if (elem >= 0) {
18959 int end = min(str - start, sizeof (setupdlg->attr[elem].attr) - 1);
18960
18961 setupdlg->attr[elem].supplied = TRUE;
18962 memcpy(setupdlg->attr[elem].attr, start, end);
18963 setupdlg->attr[elem].attr[end] = '\0';
18964 }
18965 ++str;
18966 }
18967 }
18968
18976 static BOOL
18977 SetDSNAttributes(HWND parent, SETUPDLG *setupdlg)
18978 {
18979 char *dsn = setupdlg->attr[KEY_DSN].attr;
18980
18981 if (setupdlg->newDSN && strlen(dsn) == 0) {
18982 return FALSE;
18983 }
18984 if (!SQLWriteDSNToIni(dsn, setupdlg->driver)) {
18985 if (parent) {
18986 char buf[MAXPATHLEN], msg[MAXPATHLEN];
18987
18988 LoadString(hModule, IDS_BADDSN, buf, sizeof (buf));
18989 wsprintf(msg, buf, dsn);
18990 LoadString(hModule, IDS_MSGTITLE, buf, sizeof (buf));
18991 MessageBox(parent, msg, buf,
18992 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
18993 MB_SETFOREGROUND);
18994 }
18995 return FALSE;
18996 }
18997 if (parent || setupdlg->attr[KEY_DESC].supplied) {
18998 SQLWritePrivateProfileString(dsn, "Description",
18999 setupdlg->attr[KEY_DESC].attr,
19000 ODBC_INI);
19001 }
19002 if (parent || setupdlg->attr[KEY_DBNAME].supplied) {
19003 SQLWritePrivateProfileString(dsn, "Database",
19004 setupdlg->attr[KEY_DBNAME].attr,
19005 ODBC_INI);
19006 }
19007 if (parent || setupdlg->attr[KEY_BUSY].supplied) {
19008 SQLWritePrivateProfileString(dsn, "Timeout",
19009 setupdlg->attr[KEY_BUSY].attr,
19010 ODBC_INI);
19011 }
19012 if (parent || setupdlg->attr[KEY_STEPAPI].supplied) {
19013 SQLWritePrivateProfileString(dsn, "StepAPI",
19014 setupdlg->attr[KEY_STEPAPI].attr,
19015 ODBC_INI);
19016 }
19017 if (parent || setupdlg->attr[KEY_SYNCP].supplied) {
19018 SQLWritePrivateProfileString(dsn, "SyncPragma",
19019 setupdlg->attr[KEY_SYNCP].attr,
19020 ODBC_INI);
19021 }
19022 if (parent || setupdlg->attr[KEY_NOTXN].supplied) {
19023 SQLWritePrivateProfileString(dsn, "NoTXN",
19024 setupdlg->attr[KEY_NOTXN].attr,
19025 ODBC_INI);
19026 }
19027 if (parent || setupdlg->attr[KEY_SHORTNAM].supplied) {
19028 SQLWritePrivateProfileString(dsn, "ShortNames",
19029 setupdlg->attr[KEY_SHORTNAM].attr,
19030 ODBC_INI);
19031 }
19032 if (parent || setupdlg->attr[KEY_LONGNAM].supplied) {
19033 SQLWritePrivateProfileString(dsn, "LongNames",
19034 setupdlg->attr[KEY_LONGNAM].attr,
19035 ODBC_INI);
19036 }
19037 if (parent || setupdlg->attr[KEY_NOCREAT].supplied) {
19038 SQLWritePrivateProfileString(dsn, "NoCreat",
19039 setupdlg->attr[KEY_NOCREAT].attr,
19040 ODBC_INI);
19041 }
19042 if (parent || setupdlg->attr[KEY_NOWCHAR].supplied) {
19043 SQLWritePrivateProfileString(dsn, "NoWCHAR",
19044 setupdlg->attr[KEY_NOWCHAR].attr,
19045 ODBC_INI);
19046 }
19047 if (parent || setupdlg->attr[KEY_FKSUPPORT].supplied) {
19048 SQLWritePrivateProfileString(dsn, "FKSupport",
19049 setupdlg->attr[KEY_FKSUPPORT].attr,
19050 ODBC_INI);
19051 }
19052 if (parent || setupdlg->attr[KEY_OEMCP].supplied) {
19053 SQLWritePrivateProfileString(dsn, "OEMCP",
19054 setupdlg->attr[KEY_OEMCP].attr,
19055 ODBC_INI);
19056 }
19057 if (parent || setupdlg->attr[KEY_LOADEXT].supplied) {
19058 SQLWritePrivateProfileString(dsn, "LoadExt",
19059 setupdlg->attr[KEY_LOADEXT].attr,
19060 ODBC_INI);
19061 }
19062 if (parent || setupdlg->attr[KEY_BIGINT].supplied) {
19063 SQLWritePrivateProfileString(dsn, "BigInt",
19064 setupdlg->attr[KEY_BIGINT].attr,
19065 ODBC_INI);
19066 }
19067 if (parent || setupdlg->attr[KEY_JDCONV].supplied) {
19068 SQLWritePrivateProfileString(dsn, "JDConv",
19069 setupdlg->attr[KEY_JDCONV].attr,
19070 ODBC_INI);
19071 }
19072 if (parent || setupdlg->attr[KEY_PASSWD].supplied) {
19073 SQLWritePrivateProfileString(dsn, "PWD",
19074 setupdlg->attr[KEY_PASSWD].attr,
19075 ODBC_INI);
19076 }
19077 if (setupdlg->attr[KEY_DSN].supplied &&
19078 strcasecmp(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr)) {
19079 SQLRemoveDSNFromIni(setupdlg->DSN);
19080 }
19081 return TRUE;
19082 }
19083
19089 static void
19090 GetAttributes(SETUPDLG *setupdlg)
19091 {
19092 char *dsn = setupdlg->attr[KEY_DSN].attr;
19093
19094 if (!setupdlg->attr[KEY_DESC].supplied) {
19095 SQLGetPrivateProfileString(dsn, "Description", "",
19096 setupdlg->attr[KEY_DESC].attr,
19097 sizeof (setupdlg->attr[KEY_DESC].attr),
19098 ODBC_INI);
19099 }
19100 if (!setupdlg->attr[KEY_DBNAME].supplied) {
19101 SQLGetPrivateProfileString(dsn, "Database", "",
19102 setupdlg->attr[KEY_DBNAME].attr,
19103 sizeof (setupdlg->attr[KEY_DBNAME].attr),
19104 ODBC_INI);
19105 }
19106 if (!setupdlg->attr[KEY_BUSY].supplied) {
19107 SQLGetPrivateProfileString(dsn, "Timeout", "100000",
19108 setupdlg->attr[KEY_BUSY].attr,
19109 sizeof (setupdlg->attr[KEY_BUSY].attr),
19110 ODBC_INI);
19111 }
19112 if (!setupdlg->attr[KEY_STEPAPI].supplied) {
19113 SQLGetPrivateProfileString(dsn, "StepAPI", "0",
19114 setupdlg->attr[KEY_STEPAPI].attr,
19115 sizeof (setupdlg->attr[KEY_STEPAPI].attr),
19116 ODBC_INI);
19117 }
19118 if (!setupdlg->attr[KEY_SYNCP].supplied) {
19119 SQLGetPrivateProfileString(dsn, "SyncPragma", "NORMAL",
19120 setupdlg->attr[KEY_SYNCP].attr,
19121 sizeof (setupdlg->attr[KEY_SYNCP].attr),
19122 ODBC_INI);
19123 }
19124 if (!setupdlg->attr[KEY_NOTXN].supplied) {
19125 SQLGetPrivateProfileString(dsn, "NoTXN", "",
19126 setupdlg->attr[KEY_NOTXN].attr,
19127 sizeof (setupdlg->attr[KEY_NOTXN].attr),
19128 ODBC_INI);
19129 }
19130 if (!setupdlg->attr[KEY_SHORTNAM].supplied) {
19131 SQLGetPrivateProfileString(dsn, "ShortNames", "",
19132 setupdlg->attr[KEY_SHORTNAM].attr,
19133 sizeof (setupdlg->attr[KEY_SHORTNAM].attr),
19134 ODBC_INI);
19135 }
19136 if (!setupdlg->attr[KEY_LONGNAM].supplied) {
19137 SQLGetPrivateProfileString(dsn, "LongNames", "",
19138 setupdlg->attr[KEY_LONGNAM].attr,
19139 sizeof (setupdlg->attr[KEY_LONGNAM].attr),
19140 ODBC_INI);
19141 }
19142 if (!setupdlg->attr[KEY_NOCREAT].supplied) {
19143 SQLGetPrivateProfileString(dsn, "NoCreat", "",
19144 setupdlg->attr[KEY_NOCREAT].attr,
19145 sizeof (setupdlg->attr[KEY_NOCREAT].attr),
19146 ODBC_INI);
19147 }
19148 if (!setupdlg->attr[KEY_NOWCHAR].supplied) {
19149 SQLGetPrivateProfileString(dsn, "NoWCHAR", "",
19150 setupdlg->attr[KEY_NOWCHAR].attr,
19151 sizeof (setupdlg->attr[KEY_NOWCHAR].attr),
19152 ODBC_INI);
19153 }
19154 if (!setupdlg->attr[KEY_FKSUPPORT].supplied) {
19155 SQLGetPrivateProfileString(dsn, "FKSupport", "",
19156 setupdlg->attr[KEY_FKSUPPORT].attr,
19157 sizeof (setupdlg->attr[KEY_FKSUPPORT].attr),
19158 ODBC_INI);
19159 }
19160 if (!setupdlg->attr[KEY_OEMCP].supplied) {
19161 SQLGetPrivateProfileString(dsn, "OEMCP", "",
19162 setupdlg->attr[KEY_OEMCP].attr,
19163 sizeof (setupdlg->attr[KEY_OEMCP].attr),
19164 ODBC_INI);
19165 }
19166 if (!setupdlg->attr[KEY_LOADEXT].supplied) {
19167 SQLGetPrivateProfileString(dsn, "LoadExt", "",
19168 setupdlg->attr[KEY_LOADEXT].attr,
19169 sizeof (setupdlg->attr[KEY_LOADEXT].attr),
19170 ODBC_INI);
19171 }
19172 if (!setupdlg->attr[KEY_JMODE].supplied) {
19173 SQLGetPrivateProfileString(dsn, "JournalMode", "",
19174 setupdlg->attr[KEY_JMODE].attr,
19175 sizeof (setupdlg->attr[KEY_JMODE].attr),
19176 ODBC_INI);
19177 }
19178 if (!setupdlg->attr[KEY_BIGINT].supplied) {
19179 SQLGetPrivateProfileString(dsn, "BigInt", "",
19180 setupdlg->attr[KEY_BIGINT].attr,
19181 sizeof (setupdlg->attr[KEY_BIGINT].attr),
19182 ODBC_INI);
19183 }
19184 if (!setupdlg->attr[KEY_PASSWD].supplied) {
19185 SQLGetPrivateProfileString(dsn, "PWD", "",
19186 setupdlg->attr[KEY_PASSWD].attr,
19187 sizeof (setupdlg->attr[KEY_PASSWD].attr),
19188 ODBC_INI);
19189 }
19190 if (!setupdlg->attr[KEY_JDCONV].supplied) {
19191 SQLGetPrivateProfileString(dsn, "JDConv", "",
19192 setupdlg->attr[KEY_JDCONV].attr,
19193 sizeof (setupdlg->attr[KEY_JDCONV].attr),
19194 ODBC_INI);
19195 }
19196 }
19197
19203 static void
19204 GetDBFile(HWND hdlg)
19205 {
19206 #ifdef _WIN64
19207 SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19208 #else
19209 SETUPDLG *setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19210 #endif
19211 OPENFILENAME ofn;
19212
19213 memset(&ofn, 0, sizeof (ofn));
19214 ofn.lStructSize = sizeof (ofn);
19215 ofn.hwndOwner = hdlg;
19216 #ifdef _WIN64
19217 ofn.hInstance = (HINSTANCE) GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
19218 #else
19219 ofn.hInstance = (HINSTANCE) GetWindowLong(hdlg, GWL_HINSTANCE);
19220 #endif
19221 ofn.lpstrFile = (LPTSTR) setupdlg->attr[KEY_DBNAME].attr;
19222 ofn.nMaxFile = MAXPATHLEN;
19223 ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST |
19224 OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST;
19225 if (GetOpenFileName(&ofn)) {
19226 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19227 setupdlg->attr[KEY_DBNAME].supplied = TRUE;
19228 }
19229 }
19230
19240 static BOOL CALLBACK
19241 ConfigDlgProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19242 {
19243 SETUPDLG *setupdlg = NULL;
19244 WORD index;
19245
19246 switch (wmsg) {
19247 case WM_INITDIALOG:
19248 #ifdef _WIN64
19249 SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19250 #else
19251 SetWindowLong(hdlg, DWL_USER, lparam);
19252 #endif
19253 setupdlg = (SETUPDLG *) lparam;
19254 GetAttributes(setupdlg);
19255 SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19256 SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19257 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19258 SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19259 SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19260 SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19261 (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19262 SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19263 (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19264 SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19265 (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19266 SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19267 (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19268 SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19269 (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19270 CheckDlgButton(hdlg, IDC_STEPAPI,
19271 getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19272 BST_CHECKED : BST_UNCHECKED);
19273 CheckDlgButton(hdlg, IDC_NOTXN,
19274 getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19275 BST_CHECKED : BST_UNCHECKED);
19276 CheckDlgButton(hdlg, IDC_SHORTNAM,
19277 getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19278 BST_CHECKED : BST_UNCHECKED);
19279 CheckDlgButton(hdlg, IDC_LONGNAM,
19280 getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19281 BST_CHECKED : BST_UNCHECKED);
19282 CheckDlgButton(hdlg, IDC_NOCREAT,
19283 getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19284 BST_CHECKED : BST_UNCHECKED);
19285 CheckDlgButton(hdlg, IDC_NOWCHAR,
19286 getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19287 BST_CHECKED : BST_UNCHECKED);
19288 CheckDlgButton(hdlg, IDC_FKSUPPORT,
19289 getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19290 BST_CHECKED : BST_UNCHECKED);
19291 CheckDlgButton(hdlg, IDC_OEMCP,
19292 getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19293 BST_CHECKED : BST_UNCHECKED);
19294 CheckDlgButton(hdlg, IDC_BIGINT,
19295 getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19296 BST_CHECKED : BST_UNCHECKED);
19297 CheckDlgButton(hdlg, IDC_JDCONV,
19298 getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19299 BST_CHECKED : BST_UNCHECKED);
19300 SendDlgItemMessage(hdlg, IDC_SYNCP,
19301 CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19302 SendDlgItemMessage(hdlg, IDC_SYNCP,
19303 CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19304 SendDlgItemMessage(hdlg, IDC_SYNCP,
19305 CB_ADDSTRING, 0, (LPARAM) "OFF");
19306 SendDlgItemMessage(hdlg, IDC_SYNCP,
19307 CB_ADDSTRING, 0, (LPARAM) "FULL");
19308 SendDlgItemMessage(hdlg, IDC_SYNCP,
19309 CB_SELECTSTRING, (WPARAM) -1,
19310 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19311 if (setupdlg->defDSN) {
19312 EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19313 EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19314 }
19315 return TRUE;
19316 case WM_COMMAND:
19317 switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19318 case IDC_DSNAME:
19319 if (GET_WM_COMMAND_CMD(wparam, lparam) == EN_CHANGE) {
19320 char item[MAXDSNAME];
19321
19322 EnableWindow(GetDlgItem(hdlg, IDOK),
19323 GetDlgItemText(hdlg, IDC_DSNAME,
19324 item, sizeof (item)));
19325 return TRUE;
19326 }
19327 break;
19328 case IDC_BROWSE:
19329 GetDBFile(hdlg);
19330 break;
19331 case IDOK:
19332 #ifdef _WIN64
19333 setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19334 #else
19335 setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19336 #endif
19337 if (!setupdlg->defDSN) {
19338 GetDlgItemText(hdlg, IDC_DSNAME,
19339 setupdlg->attr[KEY_DSN].attr,
19340 sizeof (setupdlg->attr[KEY_DSN].attr));
19341 }
19342 GetDlgItemText(hdlg, IDC_DESC,
19343 setupdlg->attr[KEY_DESC].attr,
19344 sizeof (setupdlg->attr[KEY_DESC].attr));
19345 GetDlgItemText(hdlg, IDC_DBNAME,
19346 setupdlg->attr[KEY_DBNAME].attr,
19347 sizeof (setupdlg->attr[KEY_DBNAME].attr));
19348 GetDlgItemText(hdlg, IDC_TONAME,
19349 setupdlg->attr[KEY_BUSY].attr,
19350 sizeof (setupdlg->attr[KEY_BUSY].attr));
19351 GetDlgItemText(hdlg, IDC_LOADEXT,
19352 setupdlg->attr[KEY_LOADEXT].attr,
19353 sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19354 index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19355 CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19356 if (index != (WORD) CB_ERR) {
19357 SendDlgItemMessage(hdlg, IDC_SYNCP,
19358 CB_GETLBTEXT, index,
19359 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19360 }
19361 strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19362 (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19363 "1" : "0");
19364 strcpy(setupdlg->attr[KEY_NOTXN].attr,
19365 (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19366 "1" : "0");
19367 strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19368 (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19369 "1" : "0");
19370 strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19371 (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19372 "1" : "0");
19373 strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19374 (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19375 "1" : "0");
19376 strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19377 (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19378 "1" : "0");
19379 strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19380 (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19381 "1" : "0");
19382 strcpy(setupdlg->attr[KEY_OEMCP].attr,
19383 (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19384 "1" : "0");
19385 strcpy(setupdlg->attr[KEY_BIGINT].attr,
19386 (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19387 "1" : "0");
19388 strcpy(setupdlg->attr[KEY_JDCONV].attr,
19389 (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19390 "1" : "0");
19391 SetDSNAttributes(hdlg, setupdlg);
19392
19393 case IDCANCEL:
19394 EndDialog(hdlg, wparam);
19395 return TRUE;
19396 }
19397 break;
19398 }
19399 return FALSE;
19400 }
19401
19411 BOOL INSTAPI
19412 ConfigDSN(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attribs)
19413 {
19414 BOOL success;
19415 SETUPDLG *setupdlg;
19416
19417 setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19418 if (setupdlg == NULL) {
19419 return FALSE;
19420 }
19421 memset(setupdlg, 0, sizeof (SETUPDLG));
19422 if (attribs) {
19423 ParseAttributes(attribs, setupdlg);
19424 }
19425 if (setupdlg->attr[KEY_DSN].supplied) {
19426 strcpy(setupdlg->DSN, setupdlg->attr[KEY_DSN].attr);
19427 } else {
19428 setupdlg->DSN[0] = '\0';
19429 }
19430 if (request == ODBC_REMOVE_DSN) {
19431 if (!setupdlg->attr[KEY_DSN].supplied) {
19432 success = FALSE;
19433 } else {
19434 success = SQLRemoveDSNFromIni(setupdlg->attr[KEY_DSN].attr);
19435 }
19436 } else {
19437 setupdlg->parent = hwnd;
19438 setupdlg->driver = driver;
19439 setupdlg->newDSN = request == ODBC_ADD_DSN;
19440 setupdlg->defDSN = strcasecmp(setupdlg->attr[KEY_DSN].attr,
19441 "Default") == 0;
19442 if (hwnd) {
19443 success = DialogBoxParam(hModule, MAKEINTRESOURCE(CONFIGDSN),
19444 hwnd, (DLGPROC) ConfigDlgProc,
19445 (LPARAM) setupdlg) == IDOK;
19446 } else if (setupdlg->attr[KEY_DSN].supplied) {
19447 success = SetDSNAttributes(hwnd, setupdlg);
19448 } else {
19449 success = FALSE;
19450 }
19451 }
19452 xfree(setupdlg);
19453 return success;
19454 }
19455
19465 static BOOL CALLBACK
19466 DriverConnectProc(HWND hdlg, WORD wmsg, WPARAM wparam, LPARAM lparam)
19467 {
19468 SETUPDLG *setupdlg;
19469 WORD index;
19470
19471 switch (wmsg) {
19472 case WM_INITDIALOG:
19473 #ifdef _WIN64
19474 SetWindowLongPtr(hdlg, DWLP_USER, lparam);
19475 #else
19476 SetWindowLong(hdlg, DWL_USER, lparam);
19477 #endif
19478 setupdlg = (SETUPDLG *) lparam;
19479 SetDlgItemText(hdlg, IDC_DSNAME, setupdlg->attr[KEY_DSN].attr);
19480 SetDlgItemText(hdlg, IDC_DESC, setupdlg->attr[KEY_DESC].attr);
19481 SetDlgItemText(hdlg, IDC_DBNAME, setupdlg->attr[KEY_DBNAME].attr);
19482 SetDlgItemText(hdlg, IDC_TONAME, setupdlg->attr[KEY_BUSY].attr);
19483 SetDlgItemText(hdlg, IDC_LOADEXT, setupdlg->attr[KEY_LOADEXT].attr);
19484 SendDlgItemMessage(hdlg, IDC_DSNAME, EM_LIMITTEXT,
19485 (WPARAM) (MAXDSNAME - 1), (LPARAM) 0);
19486 SendDlgItemMessage(hdlg, IDC_DESC, EM_LIMITTEXT,
19487 (WPARAM) (MAXDESC - 1), (LPARAM) 0);
19488 SendDlgItemMessage(hdlg, IDC_DBNAME, EM_LIMITTEXT,
19489 (WPARAM) (MAXDBNAME - 1), (LPARAM) 0);
19490 SendDlgItemMessage(hdlg, IDC_TONAME, EM_LIMITTEXT,
19491 (WPARAM) (MAXTONAME - 1), (LPARAM) 0);
19492 SendDlgItemMessage(hdlg, IDC_LOADEXT, EM_LIMITTEXT,
19493 (WPARAM) (MAXPATHLEN*4 - 1), (LPARAM) 0);
19494 CheckDlgButton(hdlg, IDC_STEPAPI,
19495 getbool(setupdlg->attr[KEY_STEPAPI].attr) ?
19496 BST_CHECKED : BST_UNCHECKED);
19497 CheckDlgButton(hdlg, IDC_NOTXN,
19498 getbool(setupdlg->attr[KEY_NOTXN].attr) ?
19499 BST_CHECKED : BST_UNCHECKED);
19500 CheckDlgButton(hdlg, IDC_SHORTNAM,
19501 getbool(setupdlg->attr[KEY_SHORTNAM].attr) ?
19502 BST_CHECKED : BST_UNCHECKED);
19503 CheckDlgButton(hdlg, IDC_LONGNAM,
19504 getbool(setupdlg->attr[KEY_LONGNAM].attr) ?
19505 BST_CHECKED : BST_UNCHECKED);
19506 CheckDlgButton(hdlg, IDC_NOCREAT,
19507 getbool(setupdlg->attr[KEY_NOCREAT].attr) ?
19508 BST_CHECKED : BST_UNCHECKED);
19509 CheckDlgButton(hdlg, IDC_NOWCHAR,
19510 getbool(setupdlg->attr[KEY_NOWCHAR].attr) ?
19511 BST_CHECKED : BST_UNCHECKED);
19512 CheckDlgButton(hdlg, IDC_FKSUPPORT,
19513 getbool(setupdlg->attr[KEY_FKSUPPORT].attr) ?
19514 BST_CHECKED : BST_UNCHECKED);
19515 CheckDlgButton(hdlg, IDC_OEMCP,
19516 getbool(setupdlg->attr[KEY_OEMCP].attr) ?
19517 BST_CHECKED : BST_UNCHECKED);
19518 CheckDlgButton(hdlg, IDC_BIGINT,
19519 getbool(setupdlg->attr[KEY_BIGINT].attr) ?
19520 BST_CHECKED : BST_UNCHECKED);
19521 CheckDlgButton(hdlg, IDC_JDCONV,
19522 getbool(setupdlg->attr[KEY_JDCONV].attr) ?
19523 BST_CHECKED : BST_UNCHECKED);
19524 SendDlgItemMessage(hdlg, IDC_SYNCP,
19525 CB_LIMITTEXT, (WPARAM) 10, (LPARAM) 0);
19526 SendDlgItemMessage(hdlg, IDC_SYNCP,
19527 CB_ADDSTRING, 0, (LPARAM) "NORMAL");
19528 SendDlgItemMessage(hdlg, IDC_SYNCP,
19529 CB_ADDSTRING, 0, (LPARAM) "OFF");
19530 SendDlgItemMessage(hdlg, IDC_SYNCP,
19531 CB_ADDSTRING, 0, (LPARAM) "FULL");
19532 SendDlgItemMessage(hdlg, IDC_SYNCP,
19533 CB_SELECTSTRING, (WORD) -1,
19534 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19535 if (setupdlg->defDSN) {
19536 EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
19537 EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
19538 }
19539 return TRUE;
19540 case WM_COMMAND:
19541 switch (GET_WM_COMMAND_ID(wparam, lparam)) {
19542 case IDC_BROWSE:
19543 GetDBFile(hdlg);
19544 break;
19545 case IDOK:
19546 #ifdef _WIN64
19547 setupdlg = (SETUPDLG *) GetWindowLongPtr(hdlg, DWLP_USER);
19548 #else
19549 setupdlg = (SETUPDLG *) GetWindowLong(hdlg, DWL_USER);
19550 #endif
19551 GetDlgItemText(hdlg, IDC_DSNAME,
19552 setupdlg->attr[KEY_DSN].attr,
19553 sizeof (setupdlg->attr[KEY_DSN].attr));
19554 GetDlgItemText(hdlg, IDC_DBNAME,
19555 setupdlg->attr[KEY_DBNAME].attr,
19556 sizeof (setupdlg->attr[KEY_DBNAME].attr));
19557 GetDlgItemText(hdlg, IDC_TONAME,
19558 setupdlg->attr[KEY_BUSY].attr,
19559 sizeof (setupdlg->attr[KEY_BUSY].attr));
19560 GetDlgItemText(hdlg, IDC_LOADEXT,
19561 setupdlg->attr[KEY_LOADEXT].attr,
19562 sizeof (setupdlg->attr[KEY_LOADEXT].attr));
19563 index = SendDlgItemMessage(hdlg, IDC_SYNCP,
19564 CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
19565 if (index != (WORD) CB_ERR) {
19566 SendDlgItemMessage(hdlg, IDC_SYNCP,
19567 CB_GETLBTEXT, index,
19568 (LPARAM) setupdlg->attr[KEY_SYNCP].attr);
19569 }
19570 strcpy(setupdlg->attr[KEY_STEPAPI].attr,
19571 (IsDlgButtonChecked(hdlg, IDC_STEPAPI) == BST_CHECKED) ?
19572 "1" : "0");
19573 strcpy(setupdlg->attr[KEY_NOTXN].attr,
19574 (IsDlgButtonChecked(hdlg, IDC_NOTXN) == BST_CHECKED) ?
19575 "1" : "0");
19576 strcpy(setupdlg->attr[KEY_SHORTNAM].attr,
19577 (IsDlgButtonChecked(hdlg, IDC_SHORTNAM) == BST_CHECKED) ?
19578 "1" : "0");
19579 strcpy(setupdlg->attr[KEY_LONGNAM].attr,
19580 (IsDlgButtonChecked(hdlg, IDC_LONGNAM) == BST_CHECKED) ?
19581 "1" : "0");
19582 strcpy(setupdlg->attr[KEY_NOCREAT].attr,
19583 (IsDlgButtonChecked(hdlg, IDC_NOCREAT) == BST_CHECKED) ?
19584 "1" : "0");
19585 strcpy(setupdlg->attr[KEY_NOWCHAR].attr,
19586 (IsDlgButtonChecked(hdlg, IDC_NOWCHAR) == BST_CHECKED) ?
19587 "1" : "0");
19588 strcpy(setupdlg->attr[KEY_FKSUPPORT].attr,
19589 (IsDlgButtonChecked(hdlg, IDC_FKSUPPORT) == BST_CHECKED) ?
19590 "1" : "0");
19591 strcpy(setupdlg->attr[KEY_OEMCP].attr,
19592 (IsDlgButtonChecked(hdlg, IDC_OEMCP) == BST_CHECKED) ?
19593 "1" : "0");
19594 strcpy(setupdlg->attr[KEY_BIGINT].attr,
19595 (IsDlgButtonChecked(hdlg, IDC_BIGINT) == BST_CHECKED) ?
19596 "1" : "0");
19597 strcpy(setupdlg->attr[KEY_JDCONV].attr,
19598 (IsDlgButtonChecked(hdlg, IDC_JDCONV) == BST_CHECKED) ?
19599 "1" : "0");
19600
19601 case IDCANCEL:
19602 EndDialog(hdlg, GET_WM_COMMAND_ID(wparam, lparam) == IDOK);
19603 return TRUE;
19604 }
19605 }
19606 return FALSE;
19607 }
19608
19622 static SQLRETURN
19623 drvdriverconnect(SQLHDBC dbc, SQLHWND hwnd,
19624 SQLCHAR *connIn, SQLSMALLINT connInLen,
19625 SQLCHAR *connOut, SQLSMALLINT connOutMax,
19626 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19627 {
19628 BOOL maybeprompt, prompt = FALSE, defaultdsn = FALSE;
19629 DBC *d;
19630 SETUPDLG *setupdlg;
19631 SQLRETURN ret;
19632 char *dsn = NULL, *driver = NULL, *dbname = NULL;
19633
19634 if (dbc == SQL_NULL_HDBC) {
19635 return SQL_INVALID_HANDLE;
19636 }
19637 d = (DBC *) dbc;
19638 if (d->sqlite) {
19639 setstatd(d, -1, "connection already established", "08002");
19640 return SQL_ERROR;
19641 }
19642 setupdlg = (SETUPDLG *) xmalloc(sizeof (SETUPDLG));
19643 if (setupdlg == NULL) {
19644 return SQL_ERROR;
19645 }
19646 memset(setupdlg, 0, sizeof (SETUPDLG));
19647 maybeprompt = drvcompl == SQL_DRIVER_COMPLETE ||
19648 drvcompl == SQL_DRIVER_COMPLETE_REQUIRED;
19649 if (connIn == NULL || !connInLen ||
19650 (connInLen == SQL_NTS && !connIn[0])) {
19651 prompt = TRUE;
19652 } else {
19653 ParseAttributes((LPCSTR) connIn, setupdlg);
19654 if (!setupdlg->attr[KEY_DSN].attr[0] &&
19655 drvcompl == SQL_DRIVER_COMPLETE_REQUIRED) {
19656 strcpy(setupdlg->attr[KEY_DSN].attr, "DEFAULT");
19657 defaultdsn = TRUE;
19658 }
19659 GetAttributes(setupdlg);
19660 if (drvcompl == SQL_DRIVER_PROMPT ||
19661 (maybeprompt &&
19662 !setupdlg->attr[KEY_DBNAME].attr[0])) {
19663 prompt = TRUE;
19664 }
19665 }
19666 retry:
19667 if (prompt) {
19668 short dlgret;
19669
19670 setupdlg->defDSN = setupdlg->attr[KEY_DRIVER].attr[0] != '\0';
19671 dlgret = DialogBoxParam(hModule, MAKEINTRESOURCE(DRIVERCONNECT),
19672 hwnd, (DLGPROC) DriverConnectProc,
19673 (LPARAM) setupdlg);
19674
19675 if (!dlgret || dlgret == -1) {
19676 xfree(setupdlg);
19677 return SQL_NO_DATA;
19678 }
19679 }
19680 dsn = setupdlg->attr[KEY_DSN].attr;
19681 driver = setupdlg->attr[KEY_DRIVER].attr;
19682 dbname = setupdlg->attr[KEY_DBNAME].attr;
19683 if (connOut || connOutLen) {
19684 char buf[SQL_MAX_MESSAGE_LENGTH * 8];
19685 int len, count;
19686 char dsn_0 = (dsn && !defaultdsn) ? dsn[0] : '\0';
19687 char drv_0 = driver ? driver[0] : '\0';
19688
19689 buf[0] = '\0';
19690 count = snprintf(buf, sizeof (buf),
19691 "%s%s%s%s%s%sDatabase=%s;StepAPI=%s;"
19692 "SyncPragma=%s;NoTXN=%s;Timeout=%s;"
19693 "ShortNames=%s;LongNames=%s;"
19694 "NoCreat=%s;NoWCHAR=%s;"
19695 "FKSupport=%s;JournalMode=%s;OEMCP=%s;LoadExt=%s;"
19696 "BigInt=%s;JDConv=%s;PWD=%s",
19697 dsn_0 ? "DSN=" : "",
19698 dsn_0 ? dsn : "",
19699 dsn_0 ? ";" : "",
19700 drv_0 ? "Driver=" : "",
19701 drv_0 ? driver : "",
19702 drv_0 ? ";" : "",
19703 dbname ? dbname : "",
19704 setupdlg->attr[KEY_STEPAPI].attr,
19705 setupdlg->attr[KEY_SYNCP].attr,
19706 setupdlg->attr[KEY_NOTXN].attr,
19707 setupdlg->attr[KEY_BUSY].attr,
19708 setupdlg->attr[KEY_SHORTNAM].attr,
19709 setupdlg->attr[KEY_LONGNAM].attr,
19710 setupdlg->attr[KEY_NOCREAT].attr,
19711 setupdlg->attr[KEY_NOWCHAR].attr,
19712 setupdlg->attr[KEY_FKSUPPORT].attr,
19713 setupdlg->attr[KEY_JMODE].attr,
19714 setupdlg->attr[KEY_OEMCP].attr,
19715 setupdlg->attr[KEY_LOADEXT].attr,
19716 setupdlg->attr[KEY_BIGINT].attr,
19717 setupdlg->attr[KEY_JDCONV].attr,
19718 setupdlg->attr[KEY_PASSWD].attr);
19719 if (count < 0) {
19720 buf[sizeof (buf) - 1] = '\0';
19721 }
19722 len = min(connOutMax - 1, strlen(buf));
19723 if (connOut) {
19724 strncpy((char *) connOut, buf, len);
19725 connOut[len] = '\0';
19726 }
19727 if (connOutLen) {
19728 *connOutLen = len;
19729 }
19730 }
19731 if (dsn[0]) {
19732 char tracef[SQL_MAX_MESSAGE_LENGTH];
19733
19734 tracef[0] = '\0';
19735 SQLGetPrivateProfileString(setupdlg->attr[KEY_DSN].attr,
19736 "tracefile", "", tracef,
19737 sizeof (tracef), ODBC_INI);
19738 if (tracef[0] != '\0') {
19739 d->trace = fopen(tracef, "a");
19740 }
19741 }
19742 d->nowchar = getbool(setupdlg->attr[KEY_NOWCHAR].attr);
19743 d->shortnames = getbool(setupdlg->attr[KEY_SHORTNAM].attr);
19744 d->longnames = getbool(setupdlg->attr[KEY_LONGNAM].attr);
19745 d->nocreat = getbool(setupdlg->attr[KEY_NOCREAT].attr);
19746 d->fksupport = getbool(setupdlg->attr[KEY_FKSUPPORT].attr);
19747 d->oemcp = getbool(setupdlg->attr[KEY_OEMCP].attr);
19748 d->dobigint = getbool(setupdlg->attr[KEY_BIGINT].attr);
19749 d->jdconv = getbool(setupdlg->attr[KEY_JDCONV].attr);
19750 d->pwdLen = strlen(setupdlg->attr[KEY_PASSWD].attr);
19751 d->pwd = (d->pwdLen > 0) ? setupdlg->attr[KEY_PASSWD].attr : NULL;
19752 ret = dbopen(d, dbname ? dbname : "", 0,
19753 dsn ? dsn : "",
19754 setupdlg->attr[KEY_STEPAPI].attr,
19755 setupdlg->attr[KEY_SYNCP].attr,
19756 setupdlg->attr[KEY_NOTXN].attr,
19757 setupdlg->attr[KEY_JMODE].attr,
19758 setupdlg->attr[KEY_BUSY].attr);
19759 if (ret != SQL_SUCCESS) {
19760 if (maybeprompt && !prompt) {
19761 prompt = TRUE;
19762 goto retry;
19763 }
19764 }
19765 memset(setupdlg->attr[KEY_PASSWD].attr, 0,
19766 sizeof (setupdlg->attr[KEY_PASSWD].attr));
19767 if (ret == SQL_SUCCESS) {
19768 dbloadext(d, setupdlg->attr[KEY_LOADEXT].attr);
19769 }
19770 xfree(setupdlg);
19771 return ret;
19772 }
19773
19774 #endif
19775 #endif
19776
19777 #ifndef WINTERFACE
19778
19791 SQLRETURN SQL_API
19792 SQLDriverConnect(SQLHDBC dbc, SQLHWND hwnd,
19793 SQLCHAR *connIn, SQLSMALLINT connInLen,
19794 SQLCHAR *connOut, SQLSMALLINT connOutMax,
19795 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19796 {
19797 SQLRETURN ret;
19798
19799 HDBC_LOCK(dbc);
19800 ret = drvdriverconnect(dbc, hwnd, connIn, connInLen,
19801 connOut, connOutMax, connOutLen, drvcompl);
19802 HDBC_UNLOCK(dbc);
19803 return ret;
19804 }
19805 #endif
19806
19807 #ifdef WINTERFACE
19808
19821 SQLRETURN SQL_API
19822 SQLDriverConnectW(SQLHDBC dbc, SQLHWND hwnd,
19823 SQLWCHAR *connIn, SQLSMALLINT connInLen,
19824 SQLWCHAR *connOut, SQLSMALLINT connOutMax,
19825 SQLSMALLINT *connOutLen, SQLUSMALLINT drvcompl)
19826 {
19827 SQLRETURN ret;
19828 char *ci = NULL;
19829 SQLSMALLINT len = 0;
19830
19831 HDBC_LOCK(dbc);
19832 if (connIn) {
19833 #if defined(_WIN32) || defined(_WIN64)
19834 if (connInLen == SQL_NTS) {
19835 connInLen = -1;
19836 }
19837 ci = uc_to_wmb(connIn, connInLen);
19838 #else
19839 ci = uc_to_utf(connIn, connInLen);
19840 #endif
19841 if (!ci) {
19842 DBC *d = (DBC *) dbc;
19843
19844 setstatd(d, -1, "out of memory", (*d->ov3) ? "HY000" : "S1000");
19845 HDBC_UNLOCK(dbc);
19846 return SQL_ERROR;
19847 }
19848 }
19849 ret = drvdriverconnect(dbc, hwnd, (SQLCHAR *) ci, SQL_NTS,
19850 (SQLCHAR *) connOut, connOutMax, &len, drvcompl);
19851 HDBC_UNLOCK(dbc);
19852 uc_free(ci);
19853 if (ret == SQL_SUCCESS) {
19854 SQLWCHAR *co = NULL;
19855
19856 if (connOut) {
19857 if (len > 0) {
19858 #if defined(_WIN32) || defined(_WIN64)
19859 co = wmb_to_uc((char *) connOut, len);
19860 #else
19861 co = uc_from_utf((SQLCHAR *) connOut, len);
19862 #endif
19863 if (co) {
19864 uc_strncpy(connOut, co, connOutMax / sizeof (SQLWCHAR));
19865 len = min(connOutMax / sizeof (SQLWCHAR), uc_strlen(co));
19866 uc_free(co);
19867 } else {
19868 len = 0;
19869 }
19870 }
19871 if (len <= 0) {
19872 len = 0;
19873 connOut[0] = 0;
19874 }
19875 } else {
19876 len = 0;
19877 }
19878 if (connOutLen) {
19879 *connOutLen = len;
19880 }
19881 }
19882 return ret;
19883 }
19884 #endif
19885
19886 #if defined(_WIN32) || defined(_WIN64)
19887
19896 BOOL APIENTRY
19897 LibMain(HANDLE hinst, DWORD reason, LPVOID reserved)
19898 {
19899 static int initialized = 0;
19900
19901 switch (reason) {
19902 case DLL_PROCESS_ATTACH:
19903 if (!initialized++) {
19904 hModule = hinst;
19905 #ifdef WINTERFACE
19906
19907 statSpec2P = statSpec2;
19908 statSpec3P = statSpec3;
19909 #endif
19910 #ifdef SQLITE_DYNLOAD
19911 dls_init();
19912 #endif
19913 #ifdef SQLITE_HAS_CODEC
19914 sqlite3_activate_see(SQLITE_ACTIVATION_KEY);
19915 #endif
19916 }
19917 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
19918 nvfs_init();
19919 #endif
19920 break;
19921 case DLL_THREAD_ATTACH:
19922 break;
19923 case DLL_PROCESS_DETACH:
19924 if (--initialized <= 0) {
19925 #ifdef SQLITE_DYNLOAD
19926 dls_fini();
19927 #endif
19928 }
19929 break;
19930 case DLL_THREAD_DETACH:
19931 break;
19932 default:
19933 break;
19934 }
19935 return TRUE;
19936 }
19937
19946 int __stdcall
19947 DllMain(HANDLE hinst, DWORD reason, LPVOID reserved)
19948 {
19949 return LibMain(hinst, reason, reserved);
19950 }
19951
19952 #ifndef WITHOUT_INSTALLER
19953
19960 static BOOL
19961 InUnError(char *name)
19962 {
19963 WORD err = 1;
19964 DWORD code;
19965 char errmsg[301];
19966 WORD errlen, errmax = sizeof (errmsg) - 1;
19967 int sqlret;
19968 BOOL ret = FALSE;
19969
19970 do {
19971 errmsg[0] = '\0';
19972 sqlret = SQLInstallerError(err, &code, errmsg, errmax, &errlen);
19973 if (SQL_SUCCEEDED(sqlret)) {
19974 MessageBox(NULL, errmsg, name,
19975 MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
19976 ret = TRUE;
19977 }
19978 err++;
19979 } while (sqlret != SQL_NO_DATA);
19980 return ret;
19981 }
19982
19989 static BOOL
19990 InUn(int remove, char *cmdline)
19991 {
19992 #ifdef SQLITE_HAS_CODEC
19993 static char *drivername = "SQLite3 ODBC Driver (SEE)";
19994 static char *dsname = "SQLite3 SEE Datasource";
19995 #else
19996 static char *drivername = "SQLite3 ODBC Driver";
19997 static char *dsname = "SQLite3 Datasource";
19998 #endif
19999 char *dllname, *p;
20000 char dllbuf[301], path[301], driver[300], attr[300], inst[400];
20001 WORD pathmax = sizeof (path) - 1, pathlen;
20002 DWORD usecnt, mincnt;
20003 int quiet = 0;
20004
20005 dllbuf[0] = '\0';
20006 GetModuleFileName(hModule, dllbuf, sizeof (dllbuf));
20007 p = strrchr(dllbuf, '\\');
20008 dllname = p ? (p + 1) : dllbuf;
20009 quiet = cmdline && strstr(cmdline, "quiet");
20010 if (SQLInstallDriverManager(path, pathmax, &pathlen)) {
20011 sprintf(driver, "%s;Driver=%s;Setup=%s;",
20012 drivername, dllname, dllname);
20013 p = driver;
20014 while (*p) {
20015 if (*p == ';') {
20016 *p = '\0';
20017 }
20018 ++p;
20019 }
20020 usecnt = 0;
20021 path[0] = '\0';
20022 SQLInstallDriverEx(driver, NULL, path, pathmax, NULL,
20023 ODBC_INSTALL_INQUIRY, &usecnt);
20024 pathlen = strlen(path);
20025 while (pathlen > 0 && path[pathlen - 1] == '\\') {
20026 --pathlen;
20027 path[pathlen] = '\0';
20028 }
20029 sprintf(driver, "%s;Driver=%s\\%s;Setup=%s\\%s;",
20030 drivername, path, dllname, path, dllname);
20031 p = driver;
20032 while (*p) {
20033 if (*p == ';') {
20034 *p = '\0';
20035 }
20036 ++p;
20037 }
20038 sprintf(inst, "%s\\%s", path, dllname);
20039 if (!remove && usecnt > 0) {
20040
20041 if (GetFileAttributesA(dllbuf) != INVALID_FILE_ATTRIBUTES &&
20042 CopyFile(dllbuf, inst, 0)) {
20043 if (!quiet) {
20044 char buf[512];
20045
20046 sprintf(buf, "%s replaced.", drivername);
20047 MessageBox(NULL, buf, "Info",
20048 MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20049 MB_SETFOREGROUND);
20050 }
20051 return TRUE;
20052 }
20053 }
20054 mincnt = remove ? 1 : 0;
20055 while (usecnt != mincnt) {
20056 if (!SQLRemoveDriver(driver, TRUE, &usecnt)) {
20057 break;
20058 }
20059 }
20060 if (remove) {
20061 if (usecnt && !SQLRemoveDriver(driver, TRUE, &usecnt)) {
20062 InUnError("SQLRemoveDriver");
20063 return FALSE;
20064 }
20065 if (!usecnt) {
20066 char buf[512];
20067
20068 DeleteFile(inst);
20069 if (!quiet) {
20070 sprintf(buf, "%s uninstalled.", drivername);
20071 MessageBox(NULL, buf, "Info",
20072 MB_ICONINFORMATION |MB_OK | MB_TASKMODAL |
20073 MB_SETFOREGROUND);
20074 }
20075 }
20076 sprintf(attr, "DSN=%s;Database=;", dsname);
20077 p = attr;
20078 while (*p) {
20079 if (*p == ';') {
20080 *p = '\0';
20081 }
20082 ++p;
20083 }
20084 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20085 return TRUE;
20086 }
20087 if (GetFileAttributesA(dllbuf) == INVALID_FILE_ATTRIBUTES) {
20088 return FALSE;
20089 }
20090 if (strcasecmp(dllbuf, inst) != 0 && !CopyFile(dllbuf, inst, 0)) {
20091 char buf[512];
20092
20093 sprintf(buf, "Copy %s to %s failed.", dllbuf, inst);
20094 MessageBox(NULL, buf, "CopyFile",
20095 MB_ICONSTOP |MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
20096 return FALSE;
20097 }
20098 if (!SQLInstallDriverEx(driver, path, path, pathmax, &pathlen,
20099 ODBC_INSTALL_COMPLETE, &usecnt)) {
20100 InUnError("SQLInstallDriverEx");
20101 return FALSE;
20102 }
20103 sprintf(attr, "DSN=%s;Database=;", dsname);
20104 p = attr;
20105 while (*p) {
20106 if (*p == ';') {
20107 *p = '\0';
20108 }
20109 ++p;
20110 }
20111 SQLConfigDataSource(NULL, ODBC_REMOVE_SYS_DSN, drivername, attr);
20112 if (!SQLConfigDataSource(NULL, ODBC_ADD_SYS_DSN, drivername, attr)) {
20113 InUnError("SQLConfigDataSource");
20114 return FALSE;
20115 }
20116 if (!quiet) {
20117 char buf[512];
20118
20119 sprintf(buf, "%s installed.", drivername);
20120 MessageBox(NULL, buf, "Info",
20121 MB_ICONINFORMATION | MB_OK | MB_TASKMODAL |
20122 MB_SETFOREGROUND);
20123 }
20124 } else {
20125 InUnError("SQLInstallDriverManager");
20126 return FALSE;
20127 }
20128 return TRUE;
20129 }
20130
20139 void CALLBACK
20140 install(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20141 {
20142 InUn(0, lpszCmdLine);
20143 }
20144
20153 void CALLBACK
20154 uninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20155 {
20156 InUn(1, lpszCmdLine);
20157 }
20158
20159 #endif
20160
20161 #ifndef WITHOUT_SHELL
20162
20171 static void
20172 setargv(int *argcp, char ***argvp, char *cmdline, char *argv0)
20173 {
20174 char *p, *arg, *argspace, **argv;
20175 int argc, size, inquote, copy, slashes;
20176
20177 size = 2 + (argv0 ? 1 : 0);
20178 for (p = cmdline; *p != '\0'; p++) {
20179 if (ISSPACE(*p)) {
20180 size++;
20181 while (ISSPACE(*p)) {
20182 p++;
20183 }
20184 if (*p == '\0') {
20185 break;
20186 }
20187 }
20188 }
20189 argspace = malloc(size * sizeof (char *) + strlen(cmdline) + 1);
20190 argv = (char **) argspace;
20191 argspace += size * sizeof (char *);
20192 size--;
20193 argc = 0;
20194 if (argv0) {
20195 argv[argc++] = argv0;
20196 }
20197 p = cmdline;
20198 for (; argc < size; argc++) {
20199 argv[argc] = arg = argspace;
20200 while (ISSPACE(*p)) {
20201 p++;
20202 }
20203 if (*p == '\0') {
20204 break;
20205 }
20206 inquote = 0;
20207 slashes = 0;
20208 while (1) {
20209 copy = 1;
20210 while (*p == '\\') {
20211 slashes++;
20212 p++;
20213 }
20214 if (*p == '"') {
20215 if ((slashes & 1) == 0) {
20216 copy = 0;
20217 if (inquote && p[1] == '"') {
20218 p++;
20219 copy = 1;
20220 } else {
20221 inquote = !inquote;
20222 }
20223 }
20224 slashes >>= 1;
20225 }
20226 while (slashes) {
20227 *arg = '\\';
20228 arg++;
20229 slashes--;
20230 }
20231 if (*p == '\0' || (!inquote && ISSPACE(*p))) {
20232 break;
20233 }
20234 if (copy != 0) {
20235 *arg = *p;
20236 arg++;
20237 }
20238 p++;
20239 }
20240 *arg = '\0';
20241 argspace = arg + 1;
20242 }
20243 argv[argc] = 0;
20244 *argcp = argc;
20245 *argvp = argv;
20246 }
20247
20256 void CALLBACK
20257 shell(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
20258 {
20259 int argc, needcon = 0;
20260 char **argv;
20261 extern int sqlite3_main(int, char **);
20262 static const char *name = "SQLite3 Shell";
20263 DWORD ftype0, ftype1, ftype2;
20264
20265 ftype0 = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
20266 ftype1 = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
20267 ftype2 = GetFileType(GetStdHandle(STD_ERROR_HANDLE));
20268 if (ftype0 != FILE_TYPE_DISK && ftype0 != FILE_TYPE_CHAR &&
20269 ftype0 != FILE_TYPE_PIPE) {
20270 fclose(stdin);
20271 ++needcon;
20272 ftype0 = FILE_TYPE_UNKNOWN;
20273 }
20274 if (ftype1 != FILE_TYPE_DISK && ftype1 != FILE_TYPE_CHAR &&
20275 ftype1 != FILE_TYPE_PIPE) {
20276 fclose(stdout);
20277 ++needcon;
20278 ftype1 = FILE_TYPE_UNKNOWN;
20279 }
20280 if (ftype2 != FILE_TYPE_DISK && ftype2 != FILE_TYPE_CHAR &&
20281 ftype2 != FILE_TYPE_PIPE) {
20282 fclose(stderr);
20283 ++needcon;
20284 ftype2 = FILE_TYPE_UNKNOWN;
20285 }
20286 if (needcon > 0) {
20287 AllocConsole();
20288 SetConsoleTitle(name);
20289 }
20290 if (ftype0 == FILE_TYPE_UNKNOWN) {
20291 freopen("CONIN$", "r", stdin);
20292 }
20293 if (ftype1 == FILE_TYPE_UNKNOWN) {
20294 freopen("CONOUT$", "w", stdout);
20295 }
20296 if (ftype2 == FILE_TYPE_UNKNOWN) {
20297 freopen("CONOUT$", "w", stderr);
20298 }
20299 setargv(&argc, &argv, lpszCmdLine, (char *) name);
20300 #if defined(ENABLE_NVFS) && (ENABLE_NVFS)
20301 nvfs_init();
20302 #endif
20303 sqlite3_main(argc, argv);
20304 }
20305
20306 #endif
20307
20308 #endif
20309
20310 #if defined(HAVE_ODBCINSTEXT_H) && (HAVE_ODBCINSTEXT_H)
20311
20312
20313
20314
20315
20316
20317 #include <odbcinstext.h>
20318
20319 int
20320 ODBCINSTGetProperties(HODBCINSTPROPERTY prop)
20321 {
20322 static const char *instYN[] = { "No", "Yes", NULL };
20323 static const char *syncPragma[] = { "NORMAL", "OFF", "FULL", NULL };
20324 static const char *jmPragma[] = {
20325 "DELETE", "PERSIST", "OFF", "TRUNCATE", "MEMORY", "WAL", NULL
20326 };
20327
20328 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20329 prop = prop->pNext;
20330 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20331 prop->nPromptType = ODBCINST_PROMPTTYPE_FILENAME;
20332 strncpy(prop->szName, "Database", INI_MAX_PROPERTY_NAME);
20333 strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20334 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20335 prop = prop->pNext;
20336 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20337 prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20338 strncpy(prop->szName, "Timeout", INI_MAX_PROPERTY_NAME);
20339 strncpy(prop->szValue, "100000", INI_MAX_PROPERTY_VALUE);
20340 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20341 prop = prop->pNext;
20342 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20343 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20344 prop->aPromptData = malloc(sizeof (instYN));
20345 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20346 strncpy(prop->szName, "StepAPI", INI_MAX_PROPERTY_NAME);
20347 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20348 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20349 prop = prop->pNext;
20350 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20351 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20352 prop->aPromptData = malloc(sizeof (instYN));
20353 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20354 strncpy(prop->szName, "ShortNames", INI_MAX_PROPERTY_NAME);
20355 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20356 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20357 prop = prop->pNext;
20358 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20359 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20360 prop->aPromptData = malloc(sizeof (instYN));
20361 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20362 strncpy(prop->szName, "LongNames", INI_MAX_PROPERTY_NAME);
20363 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20364 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20365 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20366 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20367 prop->aPromptData = malloc(sizeof (instYN));
20368 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20369 strncpy(prop->szName, "NoCreat", INI_MAX_PROPERTY_NAME);
20370 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20371 #ifdef WINTERFACE
20372 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20373 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20374 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20375 prop->aPromptData = malloc(sizeof (instYN));
20376 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20377 strncpy(prop->szName, "NoWCHAR", INI_MAX_PROPERTY_NAME);
20378 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20379 #endif
20380 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20381 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20382 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20383 prop->aPromptData = malloc(sizeof (instYN));
20384 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20385 strncpy(prop->szName, "FKSupport", INI_MAX_PROPERTY_NAME);
20386 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20387 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20388 prop = prop->pNext;
20389 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20390 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20391 prop->aPromptData = malloc(sizeof (syncPragma));
20392 memcpy(prop->aPromptData, syncPragma, sizeof (syncPragma));
20393 strncpy(prop->szName, "SyncPragma", INI_MAX_PROPERTY_NAME);
20394 strncpy(prop->szValue, "NORMAL", INI_MAX_PROPERTY_VALUE);
20395 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20396 prop = prop->pNext;
20397 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20398 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20399 prop->aPromptData = malloc(sizeof (jmPragma));
20400 memcpy(prop->aPromptData, jmPragma, sizeof (jmPragma));
20401 strncpy(prop->szName, "JournalMode", INI_MAX_PROPERTY_NAME);
20402 strncpy(prop->szValue, "DELETE", INI_MAX_PROPERTY_VALUE);
20403 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20404 prop = prop->pNext;
20405 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20406 prop->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
20407 strncpy(prop->szName, "LoadExt", INI_MAX_PROPERTY_NAME);
20408 strncpy(prop->szValue, "", INI_MAX_PROPERTY_VALUE);
20409 prop->pNext = (HODBCINSTPROPERTY) malloc(sizeof (ODBCINSTPROPERTY));
20410 memset(prop, 0, sizeof (ODBCINSTPROPERTY));
20411 prop->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
20412 prop->aPromptData = malloc(sizeof (instYN));
20413 memcpy(prop->aPromptData, instYN, sizeof (instYN));
20414 strncpy(prop->szName, "BigInt", INI_MAX_PROPERTY_NAME);
20415 strncpy(prop->szValue, "No", INI_MAX_PROPERTY_VALUE);
20416 return 1;
20417 }
20418
20419 #endif
20420
20421 #ifdef SQLITE_DYNLOAD
20422
20423
20424
20425
20426
20427 static void
20428 dls_void(void)
20429 {
20430 }
20431
20432 static int
20433 dls_error(void)
20434 {
20435 return SQLITE_ERROR;
20436 }
20437
20438 static int
20439 dls_0(void)
20440 {
20441 return 0;
20442 }
20443
20444 static sqlite_int64
20445 dls_0LL(void)
20446 {
20447 return 0;
20448 }
20449
20450 static double
20451 dls_00(void)
20452 {
20453 return 0;
20454 }
20455
20456 static void *
20457 dls_null(void)
20458 {
20459 return NULL;
20460 }
20461
20462 static const char *
20463 dls_empty(void)
20464 {
20465 return "";
20466 }
20467
20468 static int
20469 dls_snull(void)
20470 {
20471 return SQLITE_NULL;
20472 }
20473
20474 #define DLS_ENT(name, func) \
20475 { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, name), \
20476 (void *) func }
20477
20478 #define DLS_ENT3(name, off, func) \
20479 { "sqlite3_" #name, offsetof(struct dl_sqlite3_funcs, off), \
20480 (void *) func }
20481
20482 #define DLS_END { NULL, 0, NULL }
20483
20484 static struct {
20485 const char *name;
20486 int offset;
20487 void *func;
20488 } dls_nametab[] = {
20489 DLS_ENT(activate_see, dls_void),
20490 DLS_ENT(bind_blob, dls_error),
20491 DLS_ENT(bind_double, dls_error),
20492 DLS_ENT(bind_int, dls_error),
20493 DLS_ENT(bind_int64, dls_error),
20494 DLS_ENT(bind_null, dls_error),
20495 DLS_ENT(bind_parameter_count, dls_0),
20496 DLS_ENT(bind_text, dls_error),
20497 DLS_ENT(busy_handler, dls_error),
20498 DLS_ENT(changes, dls_0),
20499 DLS_ENT(close, dls_error),
20500 DLS_ENT(column_blob, dls_null),
20501 DLS_ENT(column_bytes, dls_0),
20502 DLS_ENT(column_count, dls_0),
20503 DLS_ENT(column_database_name, dls_empty),
20504 DLS_ENT(column_decltype, dls_empty),
20505 DLS_ENT(column_double, dls_00),
20506 DLS_ENT(column_name, dls_empty),
20507 DLS_ENT(column_origin_name, dls_null),
20508 DLS_ENT(column_table_name, dls_null),
20509 DLS_ENT(column_text, dls_null),
20510 DLS_ENT(column_type, dls_snull),
20511 DLS_ENT(create_function, dls_error),
20512 DLS_ENT(enable_load_extension, dls_error),
20513 DLS_ENT(errcode, dls_error),
20514 DLS_ENT(errmsg, dls_empty),
20515 DLS_ENT(exec, dls_error),
20516 DLS_ENT(finalize, dls_error),
20517 DLS_ENT(free, free),
20518 DLS_ENT(free_table, dls_void),
20519 DLS_ENT(get_table, dls_error),
20520 DLS_ENT(interrupt, dls_void),
20521 DLS_ENT(key, dls_error),
20522 DLS_ENT(last_insert_rowid, dls_0LL),
20523 DLS_ENT(libversion, dls_empty),
20524 DLS_ENT(load_extension, dls_error),
20525 DLS_ENT(malloc, malloc),
20526 DLS_ENT(mprintf, dls_null),
20527 DLS_ENT(open, dls_error),
20528 DLS_ENT(open16, dls_error),
20529 DLS_ENT(open_v2, dls_error),
20530 DLS_ENT(prepare, dls_error),
20531 DLS_ENT(prepare_v2, dls_error),
20532 DLS_ENT(profile, dls_null),
20533 DLS_ENT(realloc, realloc),
20534 DLS_ENT(rekey, dls_error),
20535 DLS_ENT(reset, dls_error),
20536 DLS_ENT(result_blob, dls_void),
20537 DLS_ENT(result_error, dls_void),
20538 DLS_ENT(result_int, dls_void),
20539 DLS_ENT(result_null, dls_void),
20540 DLS_ENT(step, dls_error),
20541 #if defined(_WIN32) || defined(_WIN64)
20542 DLS_ENT3(strnicmp, xstrnicmp, _strnicmp),
20543 #else
20544 DLS_ENT3(strnicmp, xstrnicmp, strncasecmp),
20545 #endif
20546 DLS_ENT(table_column_metadata, dls_error),
20547 DLS_ENT(trace, dls_null),
20548 DLS_ENT(user_data, dls_null),
20549 DLS_ENT(value_blob, dls_null),
20550 DLS_ENT(value_bytes, dls_0),
20551 DLS_ENT(value_text, dls_empty),
20552 DLS_ENT(value_type, dls_snull),
20553 DLS_END
20554 };
20555
20556 #if defined(_WIN32) || defined(_WIN64)
20557
20558 static HMODULE sqlite3_dll = 0;
20559
20560 static void
20561 dls_init(void)
20562 {
20563 int i;
20564 static const char *dll_names[] = {
20565 "System.Data.SQLite.dll",
20566 "sqlite3.dll",
20567 NULL,
20568 };
20569
20570 i = 0;
20571 while (dll_names[i]) {
20572 sqlite3_dll = LoadLibrary(dll_names[i]);
20573 if (sqlite3_dll) {
20574 break;
20575 }
20576 ++i;
20577 }
20578 i = 0;
20579 while (dls_nametab[i].name) {
20580 void *func = 0, **loc;
20581
20582 if (sqlite3_dll) {
20583 func = (void *) GetProcAddress(sqlite3_dll, dls_nametab[i].name);
20584 }
20585 if (!func) {
20586 func = dls_nametab[i].func;
20587 }
20588 loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20589 *loc = func;
20590 ++i;
20591 }
20592 if (!sqlite3_dll) {
20593 char buf[MAXPATHLEN], msg[MAXPATHLEN];
20594
20595 LoadString(hModule, IDS_DRVTITLE, buf, sizeof (buf));
20596 LoadString(hModule, IDS_DLLERR, msg, sizeof (msg));
20597 MessageBox(NULL, msg, buf,
20598 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL |
20599 MB_SETFOREGROUND);
20600 }
20601 }
20602
20603 static void
20604 dls_fini(void)
20605 {
20606 if (sqlite3_dll) {
20607 FreeLibrary(sqlite3_dll);
20608 sqlite3_dll = 0;
20609 }
20610 }
20611
20612 #else
20613
20614 #include <dlfcn.h>
20615
20616 static void *libsqlite3_so = 0;
20617
20618 void
20619 dls_init(void)
20620 {
20621 int i;
20622
20623 libsqlite3_so = dlopen("libsqlite3.so.0", RTLD_NOW | RTLD_GLOBAL);
20624 i = 0;
20625 while (dls_nametab[i].name) {
20626 void *func = 0, **loc;
20627
20628 if (libsqlite3_so) {
20629 func = dlsym(libsqlite3_so, dls_nametab[i].name);
20630 }
20631 if (!func) {
20632 func = dls_nametab[i].func;
20633 }
20634 loc = (void **) ((char *) &dls_funcs + dls_nametab[i].offset);
20635 *loc = func;
20636 ++i;
20637 }
20638 if (!libsqlite3_so) {
20639 const char errmsg[] = "SQLite3 shared library not found.\n";
20640
20641 write(2, errmsg, sizeof (errmsg) - 1);
20642 }
20643 }
20644
20645 void
20646 dls_fini(void)
20647 {
20648 if (libsqlite3_so) {
20649 dlclose(libsqlite3_so);
20650 libsqlite3_so = 0;
20651 }
20652 }
20653
20654 #endif
20655
20656 #endif
20657
20658
20659
20660
20661
20662
20663
20664
20665