Home | History | Annotate | Download | only in native
      1 #include "sqlite_jni_defs.h"
      2 
      3 #include <stdlib.h>
      4 #include <stdio.h>
      5 #include <string.h>
      6 
      7 #if HAVE_SQLITE2
      8 #include "sqlite.h"
      9 #endif
     10 
     11 #if HAVE_SQLITE3
     12 #include "sqlite3.h"
     13 #undef  HAVE_SQLITE_COMPILE
     14 #define HAVE_SQLITE_COMPILE 1
     15 #undef  HAVE_SQLITE_PROGRESS_HANDLER
     16 #define HAVE_SQLITE_PROGRESS_HANDLER 1
     17 #undef  HAVE_SQLITE_TRACE
     18 #define HAVE_SQLITE_TRACE 1
     19 #if !HAVE_SQLITE3_MALLOC
     20 #define sqlite3_malloc malloc
     21 #define sqlite3_free   free
     22 #endif
     23 #if !HAVE_SQLITE3_BIND_PARAMETER_COUNT
     24 #define sqlite3_bind_parameter_count(dummy) (1000)
     25 #endif
     26 #endif
     27 
     28 #if HAVE_SQLITE2 && HAVE_SQLITE3
     29 #define HAVE_BOTH_SQLITE 1
     30 #endif
     31 
     32 #ifndef HAVE_SQLITE3_SHARED_CACHE
     33 #define HAVE_SQLITE3_SHARED_CACHE 0
     34 #endif
     35 
     36 #include "sqlite_jni.h"
     37 
     38 #if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
     39 #define MAX_PARAMS 256
     40 #else
     41 #define MAX_PARAMS 32
     42 #endif
     43 
     44 /* free memory proc */
     45 
     46 typedef void (freemem)(void *);
     47 
     48 /* internal handle for SQLite database */
     49 
     50 typedef struct {
     51     void *sqlite;		/* SQLite handle */
     52 #if HAVE_BOTH_SQLITE
     53     int is3;			/* True for SQLITE3 handle */
     54 #endif
     55     int ver;			/* version code */
     56     jobject bh;			/* BusyHandler object */
     57     jobject cb;			/* Callback object */
     58     jobject ai;			/* Authorizer object */
     59     jobject tr;			/* Trace object */
     60     jobject pr;			/* Profile object */
     61     jobject ph;			/* ProgressHandler object */
     62     JNIEnv *env;		/* Java environment for callbacks */
     63     int row1;			/* true while processing first row */
     64     int haveutf;		/* true for SQLite UTF-8 support */
     65     jstring enc;		/* encoding or 0 */
     66     struct hfunc *funcs;	/* SQLite user defined function handles */
     67 #if HAVE_SQLITE_COMPILE
     68     struct hvm *vms;		/* Compiled SQLite VMs */
     69 #endif
     70 #if HAVE_SQLITE3
     71     sqlite3_stmt *stmt;		/* For callback() */
     72 #endif
     73 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
     74     struct hbl *blobs;		/* SQLite3 blob handles */
     75 #endif
     76 #if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
     77   struct hbk *backups;		/* SQLite3 backup handles */
     78 #endif
     79 } handle;
     80 
     81 /* internal handle for SQLite user defined function */
     82 
     83 typedef struct hfunc {
     84     struct hfunc *next;		/* next function */
     85 #if HAVE_BOTH_SQLITE
     86     int is3;			/* True for SQLITE3 handle */
     87 #endif
     88     jobject fc;			/* FunctionContext object */
     89     jobject fi;			/* Function object */
     90     jobject db;			/* Database object */
     91     handle *h;			/* SQLite database handle */
     92     void *sf;			/* SQLite function handle */
     93     JNIEnv *env;		/* Java environment for callbacks */
     94 } hfunc;
     95 
     96 #if HAVE_SQLITE_COMPILE
     97 /* internal handle for SQLite VM (sqlite_compile()) */
     98 
     99 typedef struct hvm {
    100     struct hvm *next;		/* next vm handle */
    101 #if HAVE_BOTH_SQLITE
    102     int is3;			/* True for SQLITE3 handle */
    103 #endif
    104     void *vm;			/* SQLite 2/3 VM/statement */
    105     char *tail;			/* tail SQL string */
    106     int tail_len;		/* only for SQLite3/prepare */
    107     handle *h;			/* SQLite database handle */
    108     handle hh;			/* fake SQLite database handle */
    109 } hvm;
    110 #endif
    111 
    112 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
    113 /* internal handle for sqlite3_blob */
    114 
    115 typedef struct hbl {
    116     struct hbl *next;		/* next blob handle */
    117     sqlite3_blob *blob;		/* SQLite3 blob */
    118     handle *h;			/* SQLite database handle */
    119 } hbl;
    120 #endif
    121 
    122 #if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
    123 /* internal handle for sqlite3_backup */
    124 
    125 typedef struct hbk {
    126     struct hbk *next;		/* next blob handle */
    127     sqlite3_backup *bkup;	/* SQLite3 backup handle */
    128     handle *h;			/* SQLite database handle (source) */
    129 } hbk;
    130 #endif
    131 
    132 /* ISO to/from UTF-8 translation */
    133 
    134 typedef struct {
    135     char *result;		/* translated C string result */
    136     char *tofree;		/* memory to be free'd, or 0 */
    137     jstring jstr;		/* resulting Java string or 0 */
    138 } transstr;
    139 
    140 /* static cached weak class refs, field and method ids */
    141 
    142 static jclass C_java_lang_String = 0;
    143 
    144 static jfieldID F_SQLite_Database_handle = 0;
    145 static jfieldID F_SQLite_Database_error_code = 0;
    146 static jfieldID F_SQLite_FunctionContext_handle = 0;
    147 static jfieldID F_SQLite_Vm_handle = 0;
    148 static jfieldID F_SQLite_Vm_error_code = 0;
    149 static jfieldID F_SQLite_Stmt_handle = 0;
    150 static jfieldID F_SQLite_Stmt_error_code = 0;
    151 static jfieldID F_SQLite_Blob_handle = 0;
    152 static jfieldID F_SQLite_Blob_size = 0;
    153 static jfieldID F_SQLite_Backup_handle = 0;
    154 
    155 static jmethodID M_java_lang_String_getBytes = 0;
    156 static jmethodID M_java_lang_String_getBytes2 = 0;
    157 static jmethodID M_java_lang_String_initBytes = 0;
    158 static jmethodID M_java_lang_String_initBytes2 = 0;
    159 
    160 static const char xdigits[] = "0123456789ABCDEF";
    161 
    162 static void
    163 seterr(JNIEnv *env, jobject obj, int err)
    164 {
    165     jvalue v;
    166 
    167     v.j = 0;
    168     v.i = (jint) err;
    169     (*env)->SetIntField(env, obj, F_SQLite_Database_error_code, v.i);
    170 }
    171 
    172 #if HAVE_SQLITE_COMPILE
    173 static void
    174 setvmerr(JNIEnv *env, jobject obj, int err)
    175 {
    176     jvalue v;
    177 
    178     v.j = 0;
    179     v.i = (jint) err;
    180     (*env)->SetIntField(env, obj, F_SQLite_Vm_error_code, v.i);
    181 }
    182 
    183 #if HAVE_SQLITE3
    184 static void
    185 setstmterr(JNIEnv *env, jobject obj, int err)
    186 {
    187     jvalue v;
    188 
    189     v.j = 0;
    190     v.i = (jint) err;
    191     (*env)->SetIntField(env, obj, F_SQLite_Stmt_error_code, v.i);
    192 }
    193 
    194 static int
    195 jstrlen(const jchar *jstr)
    196 {
    197     int len = 0;
    198 
    199     if (jstr) {
    200 	while (*jstr++) {
    201 	    len++;
    202 	}
    203     }
    204     return len;
    205 }
    206 #endif
    207 #endif
    208 
    209 static void *
    210 gethandle(JNIEnv *env, jobject obj)
    211 {
    212     jvalue v;
    213 
    214     v.j = (*env)->GetLongField(env, obj, F_SQLite_Database_handle);
    215     return (void *) v.l;
    216 }
    217 
    218 #if HAVE_SQLITE_COMPILE
    219 static void *
    220 gethvm(JNIEnv *env, jobject obj)
    221 {
    222     jvalue v;
    223 
    224     v.j = (*env)->GetLongField(env, obj, F_SQLite_Vm_handle);
    225     return (void *) v.l;
    226 }
    227 
    228 #if HAVE_SQLITE3
    229 static void *
    230 gethstmt(JNIEnv *env, jobject obj)
    231 {
    232     jvalue v;
    233 
    234     v.j = (*env)->GetLongField(env, obj, F_SQLite_Stmt_handle);
    235     return (void *) v.l;
    236 }
    237 #endif
    238 #endif
    239 
    240 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
    241 static void *
    242 gethbl(JNIEnv *env, jobject obj)
    243 {
    244     jvalue v;
    245 
    246     v.j = (*env)->GetLongField(env, obj, F_SQLite_Blob_handle);
    247     return (void *) v.l;
    248 }
    249 #endif
    250 
    251 #if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
    252 static void *
    253 gethbk(JNIEnv *env, jobject obj)
    254 {
    255     jvalue v;
    256 
    257     v.j = (*env)->GetLongField(env, obj, F_SQLite_Backup_handle);
    258     return (void *) v.l;
    259 }
    260 #endif
    261 
    262 static void
    263 delglobrefp(JNIEnv *env, jobject *obj)
    264 {
    265     if (*obj) {
    266 	(*env)->DeleteGlobalRef(env, *obj);
    267 	*obj = 0;
    268     }
    269 }
    270 
    271 static jobject
    272 globrefpop(JNIEnv *env, jobject *obj)
    273 {
    274     jobject ret = 0;
    275 
    276     if (*obj) {
    277 	ret = *obj;
    278 	*obj = 0;
    279     }
    280     return ret;
    281 }
    282 
    283 static void
    284 globrefset(JNIEnv *env, jobject obj, jobject *ref)
    285 {
    286     if (ref) {
    287 	if (obj) {
    288 	    *ref = (*env)->NewGlobalRef(env, obj);
    289 	} else {
    290 	    *ref = 0;
    291 	}
    292     }
    293 }
    294 
    295 static void
    296 freep(char **strp)
    297 {
    298     if (strp && *strp) {
    299 	free(*strp);
    300 	*strp = 0;
    301     }
    302 }
    303 
    304 static void
    305 throwex(JNIEnv *env, const char *msg)
    306 {
    307     jclass except = (*env)->FindClass(env, "SQLite/Exception");
    308 
    309     (*env)->ExceptionClear(env);
    310     if (except) {
    311 	(*env)->ThrowNew(env, except, msg);
    312     }
    313 }
    314 
    315 static void
    316 throwoom(JNIEnv *env, const char *msg)
    317 {
    318     jclass except = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
    319 
    320     (*env)->ExceptionClear(env);
    321     if (except) {
    322 	(*env)->ThrowNew(env, except, msg);
    323     }
    324 }
    325 
    326 static void
    327 throwclosed(JNIEnv *env)
    328 {
    329     throwex(env, "database already closed");
    330 }
    331 
    332 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
    333 static void
    334 throwioex(JNIEnv *env, const char *msg)
    335 {
    336     jclass except = (*env)->FindClass(env, "java/io/IOException");
    337 
    338     (*env)->ExceptionClear(env);
    339     if (except) {
    340 	(*env)->ThrowNew(env, except, msg);
    341     }
    342 }
    343 #endif
    344 
    345 static void
    346 transfree(transstr *dest)
    347 {
    348     dest->result = 0;
    349     freep(&dest->tofree);
    350 }
    351 
    352 static char *
    353 trans2iso(JNIEnv *env, int haveutf, jstring enc, jstring src,
    354 	  transstr *dest)
    355 {
    356     jbyteArray bytes = 0;
    357     jthrowable exc;
    358 
    359     dest->result = 0;
    360     dest->tofree = 0;
    361     if (haveutf) {
    362 #ifndef JNI_VERSION_1_2
    363 	const char *utf = (*env)->GetStringUTFChars(env, src, 0);
    364 
    365 	dest->result = dest->tofree = malloc(strlen(utf) + 1);
    366 #else
    367 	jsize utflen = (*env)->GetStringUTFLength(env, src);
    368 	jsize uclen = (*env)->GetStringLength(env, src);
    369 
    370 	dest->result = dest->tofree = malloc(utflen + 1);
    371 #endif
    372 	if (!dest->tofree) {
    373 	    throwoom(env, "string translation failed");
    374 	    return dest->result;
    375 	}
    376 #ifndef JNI_VERSION_1_2
    377 	strcpy(dest->result, utf);
    378 	(*env)->ReleaseStringUTFChars(env, src, utf);
    379 #else
    380 	(*env)->GetStringUTFRegion(env, src, 0, uclen, dest->result);
    381 	dest->result[utflen] = '\0';
    382 #endif
    383 	return dest->result;
    384     }
    385     if (enc) {
    386 	bytes = (*env)->CallObjectMethod(env, src,
    387 					 M_java_lang_String_getBytes2, enc);
    388     } else {
    389 	bytes = (*env)->CallObjectMethod(env, src,
    390 					 M_java_lang_String_getBytes);
    391     }
    392     exc = (*env)->ExceptionOccurred(env);
    393     if (!exc) {
    394 	jint len = (*env)->GetArrayLength(env, bytes);
    395 	dest->tofree = malloc(len + 1);
    396 	if (!dest->tofree) {
    397 	    throwoom(env, "string translation failed");
    398 	    return dest->result;
    399 	}
    400 	dest->result = dest->tofree;
    401 	(*env)->GetByteArrayRegion(env, bytes, 0, len, (jbyte *) dest->result);
    402 	dest->result[len] = '\0';
    403     } else {
    404 	(*env)->DeleteLocalRef(env, exc);
    405     }
    406     return dest->result;
    407 }
    408 
    409 static jstring
    410 trans2utf(JNIEnv *env, int haveutf, jstring enc, const char *src,
    411 	  transstr *dest)
    412 {
    413     jbyteArray bytes = 0;
    414     int len;
    415 
    416     dest->result = 0;
    417     dest->tofree = 0;
    418     dest->jstr = 0;
    419     if (!src) {
    420 	return dest->jstr;
    421     }
    422     if (haveutf) {
    423 	dest->jstr = (*env)->NewStringUTF(env, src);
    424 	return dest->jstr;
    425     }
    426     len = strlen(src);
    427     bytes = (*env)->NewByteArray(env, len);
    428     if (bytes) {
    429 	(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *) src);
    430 	if (enc) {
    431 	    dest->jstr =
    432 		(*env)->NewObject(env, C_java_lang_String,
    433 				  M_java_lang_String_initBytes2, bytes, enc);
    434 	} else {
    435 	    dest->jstr =
    436 		(*env)->NewObject(env, C_java_lang_String,
    437 				  M_java_lang_String_initBytes, bytes);
    438 	}
    439 	(*env)->DeleteLocalRef(env, bytes);
    440 	return dest->jstr;
    441     }
    442     throwoom(env, "string translation failed");
    443     return dest->jstr;
    444 }
    445 
    446 #if HAVE_SQLITE2
    447 static int
    448 busyhandler(void *udata, const char *table, int count)
    449 {
    450     handle *h = (handle *) udata;
    451     JNIEnv *env = h->env;
    452     int ret = 0;
    453 
    454     if (env && h->bh) {
    455 	transstr tabstr;
    456 	jclass cls = (*env)->GetObjectClass(env, h->bh);
    457 	jmethodID mid = (*env)->GetMethodID(env, cls, "busy",
    458 					    "(Ljava/lang/String;I)Z");
    459 
    460 	if (mid == 0) {
    461 	    (*env)->DeleteLocalRef(env, cls);
    462 	    return ret;
    463 	}
    464 	trans2utf(env, h->haveutf, h->enc, table, &tabstr);
    465 	ret = (*env)->CallBooleanMethod(env, h->bh, mid, tabstr.jstr,
    466 					(jint) count)
    467 	      != JNI_FALSE;
    468 	(*env)->DeleteLocalRef(env, tabstr.jstr);
    469 	(*env)->DeleteLocalRef(env, cls);
    470     }
    471     return ret;
    472 }
    473 #endif
    474 
    475 #if HAVE_SQLITE3
    476 static int
    477 busyhandler3(void *udata, int count)
    478 {
    479     handle *h = (handle *) udata;
    480     JNIEnv *env = h->env;
    481     int ret = 0;
    482 
    483     if (env && h->bh) {
    484 	jclass cls = (*env)->GetObjectClass(env, h->bh);
    485 	jmethodID mid = (*env)->GetMethodID(env, cls, "busy",
    486 					    "(Ljava/lang/String;I)Z");
    487 
    488 	if (mid == 0) {
    489 	    (*env)->DeleteLocalRef(env, cls);
    490 	    return ret;
    491 	}
    492 	ret = (*env)->CallBooleanMethod(env, h->bh, mid, 0, (jint) count)
    493 	    != JNI_FALSE;
    494 	(*env)->DeleteLocalRef(env, cls);
    495     }
    496     return ret;
    497 }
    498 #endif
    499 
    500 static int
    501 progresshandler(void *udata)
    502 {
    503     handle *h = (handle *) udata;
    504     JNIEnv *env = h->env;
    505     int ret = 0;
    506 
    507     if (env && h->ph) {
    508 	jclass cls = (*env)->GetObjectClass(env, h->ph);
    509 	jmethodID mid = (*env)->GetMethodID(env, cls, "progress", "()Z");
    510 
    511 	if (mid == 0) {
    512 	    (*env)->DeleteLocalRef(env, cls);
    513 	    return ret;
    514 	}
    515 	ret = (*env)->CallBooleanMethod(env, h->ph, mid) != JNI_TRUE;
    516 	(*env)->DeleteLocalRef(env, cls);
    517     }
    518     return ret;
    519 }
    520 
    521 static int
    522 callback(void *udata, int ncol, char **data, char **cols)
    523 {
    524     handle *h = (handle *) udata;
    525     JNIEnv *env = h->env;
    526 
    527     if (env && h->cb) {
    528 	jthrowable exc;
    529 	jclass cls = (*env)->GetObjectClass(env, h->cb);
    530 	jmethodID mid;
    531 	jobjectArray arr = 0;
    532 	jint i;
    533 
    534 	if (h->row1) {
    535 	    mid = (*env)->GetMethodID(env, cls, "columns",
    536 				      "([Ljava/lang/String;)V");
    537 
    538 	    if (mid) {
    539 		arr = (*env)->NewObjectArray(env, ncol, C_java_lang_String, 0);
    540 		for (i = 0; i < ncol; i++) {
    541 		    if (cols[i]) {
    542 			transstr col;
    543 
    544 			trans2utf(env, h->haveutf, h->enc, cols[i], &col);
    545 			(*env)->SetObjectArrayElement(env, arr, i, col.jstr);
    546 			exc = (*env)->ExceptionOccurred(env);
    547 			if (exc) {
    548 			    (*env)->DeleteLocalRef(env, exc);
    549 			    return 1;
    550 			}
    551 			(*env)->DeleteLocalRef(env, col.jstr);
    552 		    }
    553 		}
    554 		h->row1 = 0;
    555 		(*env)->CallVoidMethod(env, h->cb, mid, arr);
    556 		exc = (*env)->ExceptionOccurred(env);
    557 		if (exc) {
    558 		    (*env)->DeleteLocalRef(env, exc);
    559 		    return 1;
    560 		}
    561 		(*env)->DeleteLocalRef(env, arr);
    562 	    }
    563 #if HAVE_BOTH_SQLITE
    564 	    if (h->is3) {
    565 		mid = (*env)->GetMethodID(env, cls, "types",
    566 					  "([Ljava/lang/String;)V");
    567 
    568 		if (mid && h->stmt) {
    569 		    arr = (*env)->NewObjectArray(env, ncol,
    570 						 C_java_lang_String, 0);
    571 		    for (i = 0; i < ncol; i++) {
    572 			const char *ctype =
    573 			    sqlite3_column_decltype(h->stmt, i);
    574 
    575 			if (!ctype) {
    576 			    switch (sqlite3_column_type(h->stmt, i)) {
    577 			    case SQLITE_INTEGER: ctype = "integer"; break;
    578 			    case SQLITE_FLOAT:   ctype = "double";  break;
    579 			    default:
    580 #if defined(SQLITE_TEXT) && defined(SQLITE3_TEXT) && (SQLITE_TEXT != SQLITE3_TEXT)
    581 			    case SQLITE_TEXT:
    582 #else
    583 #ifdef SQLITE3_TEXT
    584 			    case SQLITE3_TEXT:
    585 #endif
    586 #endif
    587 						 ctype = "text";    break;
    588 			    case SQLITE_BLOB:    ctype = "blob";    break;
    589 			    case SQLITE_NULL:    ctype = "null";    break;
    590 			    }
    591 			}
    592 			if (ctype) {
    593 			    transstr ty;
    594 
    595 			    trans2utf(env, 1, 0, ctype, &ty);
    596 			    (*env)->SetObjectArrayElement(env, arr, i,
    597 							  ty.jstr);
    598 			    exc = (*env)->ExceptionOccurred(env);
    599 			    if (exc) {
    600 				(*env)->DeleteLocalRef(env, exc);
    601 				return 1;
    602 			    }
    603 			    (*env)->DeleteLocalRef(env, ty.jstr);
    604 			}
    605 		    }
    606 		    (*env)->CallVoidMethod(env, h->cb, mid, arr);
    607 		    exc = (*env)->ExceptionOccurred(env);
    608 		    if (exc) {
    609 			(*env)->DeleteLocalRef(env, exc);
    610 			return 1;
    611 		    }
    612 		    (*env)->DeleteLocalRef(env, arr);
    613 		}
    614 	    } else {
    615 		if (h->ver >= 0x020506 && cols[ncol]) {
    616 		    mid = (*env)->GetMethodID(env, cls, "types",
    617 					      "([Ljava/lang/String;)V");
    618 
    619 		    if (mid) {
    620 			arr = (*env)->NewObjectArray(env, ncol,
    621 						     C_java_lang_String, 0);
    622 			for (i = 0; i < ncol; i++) {
    623 			    if (cols[i + ncol]) {
    624 				transstr ty;
    625 
    626 				trans2utf(env, h->haveutf, h->enc,
    627 					  cols[i + ncol], &ty);
    628 				(*env)->SetObjectArrayElement(env, arr, i,
    629 							      ty.jstr);
    630 				exc = (*env)->ExceptionOccurred(env);
    631 				if (exc) {
    632 				    (*env)->DeleteLocalRef(env, exc);
    633 				    return 1;
    634 				}
    635 				(*env)->DeleteLocalRef(env, ty.jstr);
    636 			    }
    637 			}
    638 			(*env)->CallVoidMethod(env, h->cb, mid, arr);
    639 			exc = (*env)->ExceptionOccurred(env);
    640 			if (exc) {
    641 			    (*env)->DeleteLocalRef(env, exc);
    642 			    return 1;
    643 			}
    644 			(*env)->DeleteLocalRef(env, arr);
    645 		    }
    646 		}
    647 	    }
    648 #else
    649 #if HAVE_SQLITE2
    650 	    if (h->ver >= 0x020506 && cols[ncol]) {
    651 		mid = (*env)->GetMethodID(env, cls, "types",
    652 					  "([Ljava/lang/String;)V");
    653 
    654 		if (mid) {
    655 		    arr = (*env)->NewObjectArray(env, ncol,
    656 						 C_java_lang_String, 0);
    657 		    for (i = 0; i < ncol; i++) {
    658 			if (cols[i + ncol]) {
    659 			    transstr ty;
    660 
    661 			    trans2utf(env, h->haveutf, h->enc,
    662 				      cols[i + ncol], &ty);
    663 			    (*env)->SetObjectArrayElement(env, arr, i,
    664 							  ty.jstr);
    665 			    exc = (*env)->ExceptionOccurred(env);
    666 			    if (exc) {
    667 				(*env)->DeleteLocalRef(env, exc);
    668 				return 1;
    669 			    }
    670 			    (*env)->DeleteLocalRef(env, ty.jstr);
    671 			}
    672 		    }
    673 		    (*env)->CallVoidMethod(env, h->cb, mid, arr);
    674 		    exc = (*env)->ExceptionOccurred(env);
    675 		    if (exc) {
    676 			(*env)->DeleteLocalRef(env, exc);
    677 			return 1;
    678 		    }
    679 		    (*env)->DeleteLocalRef(env, arr);
    680 		}
    681 	    }
    682 #endif
    683 #if HAVE_SQLITE3
    684 	    mid = (*env)->GetMethodID(env, cls, "types",
    685 				      "([Ljava/lang/String;)V");
    686 
    687 	    if (mid && h->stmt) {
    688 		arr = (*env)->NewObjectArray(env, ncol,
    689 					     C_java_lang_String, 0);
    690 		for (i = 0; i < ncol; i++) {
    691 		    const char *ctype = sqlite3_column_decltype(h->stmt, i);
    692 
    693 		    if (!ctype) {
    694 			switch (sqlite3_column_type(h->stmt, i)) {
    695 			case SQLITE_INTEGER: ctype = "integer"; break;
    696 			case SQLITE_FLOAT:   ctype = "double";  break;
    697 			default:
    698 #if defined(SQLITE_TEXT) && defined(SQLITE3_TEXT) && (SQLITE_TEXT != SQLITE3_TEXT)
    699 			case SQLITE_TEXT:
    700 #else
    701 #ifdef SQLITE3_TEXT
    702 			case SQLITE3_TEXT:
    703 #endif
    704 #endif
    705 					     ctype = "text";    break;
    706 			case SQLITE_BLOB:    ctype = "blob";    break;
    707 			case SQLITE_NULL:    ctype = "null";    break;
    708 			}
    709 		    }
    710 		    if (ctype) {
    711 			transstr ty;
    712 
    713 			trans2utf(env, 1, 0, ctype, &ty);
    714 			(*env)->SetObjectArrayElement(env, arr, i, ty.jstr);
    715 			exc = (*env)->ExceptionOccurred(env);
    716 			if (exc) {
    717 			    (*env)->DeleteLocalRef(env, exc);
    718 			    return 1;
    719 			}
    720 			(*env)->DeleteLocalRef(env, ty.jstr);
    721 		    }
    722 		}
    723 		(*env)->CallVoidMethod(env, h->cb, mid, arr);
    724 		exc = (*env)->ExceptionOccurred(env);
    725 		if (exc) {
    726 		    (*env)->DeleteLocalRef(env, exc);
    727 		    return 1;
    728 		}
    729 		(*env)->DeleteLocalRef(env, arr);
    730 	    }
    731 #endif
    732 #endif
    733 	}
    734 	if (data) {
    735 	    mid = (*env)->GetMethodID(env, cls, "newrow",
    736 				      "([Ljava/lang/String;)Z");
    737 	    if (mid) {
    738 		jboolean rc;
    739 
    740 		arr = (*env)->NewObjectArray(env, ncol, C_java_lang_String, 0);
    741 		for (i = 0; arr && i < ncol; i++) {
    742 		    if (data[i]) {
    743 			transstr dats;
    744 
    745 			trans2utf(env, h->haveutf, h->enc, data[i], &dats);
    746 			(*env)->SetObjectArrayElement(env, arr, i, dats.jstr);
    747 			exc = (*env)->ExceptionOccurred(env);
    748 			if (exc) {
    749 			    (*env)->DeleteLocalRef(env, exc);
    750 			    return 1;
    751 			}
    752 			(*env)->DeleteLocalRef(env, dats.jstr);
    753 		    }
    754 		}
    755 		rc = (*env)->CallBooleanMethod(env, h->cb, mid, arr);
    756 		exc = (*env)->ExceptionOccurred(env);
    757 		if (exc) {
    758 		    (*env)->DeleteLocalRef(env, exc);
    759 		    return 1;
    760 		}
    761 		if (arr) {
    762 		    (*env)->DeleteLocalRef(env, arr);
    763 		}
    764 		(*env)->DeleteLocalRef(env, cls);
    765 		return rc != JNI_FALSE;
    766 	    }
    767 	}
    768     }
    769     return 0;
    770 }
    771 
    772 static void
    773 doclose(JNIEnv *env, jobject obj, int final)
    774 {
    775     handle *h = gethandle(env, obj);
    776 
    777     if (h) {
    778 	hfunc *f;
    779 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
    780 	hbl *bl;
    781 #endif
    782 #if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
    783 	hbk *bk;
    784 #endif
    785 #if HAVE_SQLITE_COMPILE
    786 	hvm *v;
    787 
    788 	while ((v = h->vms)) {
    789 	    h->vms = v->next;
    790 	    v->next = 0;
    791 	    v->h = 0;
    792 	    if (v->vm) {
    793 #if HAVE_BOTH_SQLITE
    794 		if (h->is3) {
    795 		    sqlite3_finalize((sqlite3_stmt *) v->vm);
    796 		} else {
    797 		    sqlite_finalize((sqlite_vm *) v->vm, 0);
    798 		}
    799 #else
    800 #if HAVE_SQLITE2
    801 		sqlite_finalize((sqlite_vm *) v->vm, 0);
    802 #endif
    803 #if HAVE_SQLITE3
    804 		sqlite3_finalize((sqlite3_stmt *) v->vm);
    805 #endif
    806 #endif
    807 		v->vm = 0;
    808 	    }
    809 	}
    810 #endif
    811 	if (h->sqlite) {
    812 #if HAVE_BOTH_SQLITE
    813 	    if (h->is3) {
    814 		sqlite3_close((sqlite3 *) h->sqlite);
    815 	    } else {
    816 		sqlite_close((sqlite *) h->sqlite);
    817 	    }
    818 #else
    819 #if HAVE_SQLITE2
    820 	    sqlite_close((sqlite *) h->sqlite);
    821 #endif
    822 #if HAVE_SQLITE3
    823 	    sqlite3_close((sqlite3 *) h->sqlite);
    824 #endif
    825 #endif
    826 	    h->sqlite = 0;
    827 	}
    828 	while ((f = h->funcs)) {
    829 	    h->funcs = f->next;
    830 	    f->h = 0;
    831 	    f->sf = 0;
    832 	    f->env = 0;
    833 	    if (f->fc) {
    834 		(*env)->SetLongField(env, f->fc,
    835 				     F_SQLite_FunctionContext_handle, 0);
    836 	    }
    837 	    delglobrefp(env, &f->db);
    838 	    delglobrefp(env, &f->fi);
    839 	    delglobrefp(env, &f->fc);
    840 	    free(f);
    841 	}
    842 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
    843 	while ((bl = h->blobs)) {
    844 	    h->blobs = bl->next;
    845 	    bl->next = 0;
    846 	    bl->h = 0;
    847 	    if (bl->blob) {
    848 		sqlite3_blob_close(bl->blob);
    849 	    }
    850 	    bl->blob = 0;
    851 	}
    852 #endif
    853 #if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
    854 	while ((bk = h->backups)) {
    855 	    h->backups = bk->next;
    856 	    bk->next = 0;
    857 	    bk->h = 0;
    858 	    if (bk->bkup) {
    859 		sqlite3_backup_finish(bk->bkup);
    860 	    }
    861 	    bk->bkup = 0;
    862 	}
    863 #endif
    864 	delglobrefp(env, &h->bh);
    865 	delglobrefp(env, &h->cb);
    866 	delglobrefp(env, &h->ai);
    867 	delglobrefp(env, &h->tr);
    868 	delglobrefp(env, &h->ph);
    869 	delglobrefp(env, &h->enc);
    870 	free(h);
    871 	(*env)->SetLongField(env, obj, F_SQLite_Database_handle, 0);
    872 	return;
    873     }
    874     if (!final) {
    875 	throwclosed(env);
    876     }
    877 }
    878 
    879 JNIEXPORT void JNICALL
    880 Java_SQLite_Database__1close(JNIEnv *env, jobject obj)
    881 {
    882     doclose(env, obj, 0);
    883 }
    884 
    885 JNIEXPORT void JNICALL
    886 Java_SQLite_Database__1finalize(JNIEnv *env, jobject obj)
    887 {
    888     doclose(env, obj, 1);
    889 }
    890 
    891 JNIEXPORT void JNICALL
    892 Java_SQLite_Database__1busy_1timeout(JNIEnv *env, jobject obj, jint ms)
    893 {
    894     handle *h = gethandle(env, obj);
    895 
    896     if (h && h->sqlite) {
    897 #if HAVE_BOTH_SQLITE
    898 	if (h->is3) {
    899 	    sqlite3_busy_timeout((sqlite3 * ) h->sqlite, ms);
    900 	} else {
    901 	    sqlite_busy_timeout((sqlite *) h->sqlite, ms);
    902 	}
    903 #else
    904 #if HAVE_SQLITE2
    905 	sqlite_busy_timeout((sqlite *) h->sqlite, ms);
    906 #endif
    907 #if HAVE_SQLITE3
    908 	sqlite3_busy_timeout((sqlite3 * ) h->sqlite, ms);
    909 #endif
    910 #endif
    911 	return;
    912     }
    913     throwclosed(env);
    914 }
    915 
    916 JNIEXPORT jstring JNICALL
    917 Java_SQLite_Database_version(JNIEnv *env, jclass cls)
    918 {
    919     /* CHECK THIS */
    920 #if HAVE_BOTH_SQLITE
    921     return (*env)->NewStringUTF(env, sqlite_libversion());
    922 #else
    923 #if HAVE_SQLITE2
    924     return (*env)->NewStringUTF(env, sqlite_libversion());
    925 #else
    926     return (*env)->NewStringUTF(env, sqlite3_libversion());
    927 #endif
    928 #endif
    929 }
    930 
    931 JNIEXPORT jstring JNICALL
    932 Java_SQLite_Database_dbversion(JNIEnv *env, jobject obj)
    933 {
    934     handle *h = gethandle(env, obj);
    935 
    936     if (h && h->sqlite) {
    937 #if HAVE_BOTH_SQLITE
    938 	if (h->is3) {
    939 	    return (*env)->NewStringUTF(env, sqlite3_libversion());
    940 	} else {
    941 	    return (*env)->NewStringUTF(env, sqlite_libversion());
    942 	}
    943 #else
    944 #if HAVE_SQLITE2
    945 	return (*env)->NewStringUTF(env, sqlite_libversion());
    946 #else
    947 	return (*env)->NewStringUTF(env, sqlite3_libversion());
    948 #endif
    949 #endif
    950     }
    951     return (*env)->NewStringUTF(env, "unknown");
    952 }
    953 
    954 JNIEXPORT jlong JNICALL
    955 Java_SQLite_Database__1last_1insert_1rowid(JNIEnv *env, jobject obj)
    956 {
    957     handle *h = gethandle(env, obj);
    958 
    959     if (h && h->sqlite) {
    960 #if HAVE_BOTH_SQLITE
    961 	if (h->is3) {
    962 	    return (jlong) sqlite3_last_insert_rowid((sqlite3 *) h->sqlite);
    963 	} else {
    964 	    return (jlong) sqlite_last_insert_rowid((sqlite *) h->sqlite);
    965 	}
    966 #else
    967 #if HAVE_SQLITE2
    968 	return (jlong) sqlite_last_insert_rowid((sqlite *) h->sqlite);
    969 #endif
    970 #if HAVE_SQLITE3
    971 	return (jlong) sqlite3_last_insert_rowid((sqlite3 *) h->sqlite);
    972 #endif
    973 #endif
    974     }
    975     throwclosed(env);
    976     return (jlong) 0;
    977 }
    978 
    979 JNIEXPORT jlong JNICALL
    980 Java_SQLite_Database__1changes(JNIEnv *env, jobject obj)
    981 {
    982     handle *h = gethandle(env, obj);
    983 
    984     if (h && h->sqlite) {
    985 #if HAVE_BOTH_SQLITE
    986 	if (h->is3) {
    987 	    return (jlong) sqlite3_changes((sqlite3 *) h->sqlite);
    988 	} else {
    989 	    return (jlong) sqlite_changes((sqlite *) h->sqlite);
    990 	}
    991 #else
    992 #if HAVE_SQLITE2
    993 	return (jlong) sqlite_changes((sqlite *) h->sqlite);
    994 #endif
    995 #if HAVE_SQLITE3
    996 	return (jlong) sqlite3_changes((sqlite3 *) h->sqlite);
    997 #endif
    998 #endif
    999     }
   1000     throwclosed(env);
   1001     return (jlong) 0;
   1002 }
   1003 
   1004 JNIEXPORT jboolean JNICALL
   1005 Java_SQLite_Database__1complete(JNIEnv *env, jclass cls, jstring sql)
   1006 {
   1007     transstr sqlstr;
   1008     jboolean result;
   1009 
   1010     if (!sql) {
   1011 	return JNI_FALSE;
   1012     }
   1013 #if HAVE_BOTH_SQLITE || HAVE_SQLITE3
   1014     /* CHECK THIS */
   1015     trans2iso(env, 1, 0, sql, &sqlstr);
   1016     result = sqlite3_complete(sqlstr.result) ? JNI_TRUE : JNI_FALSE;
   1017 #else
   1018     trans2iso(env, strcmp(sqlite_libencoding(), "UTF-8") == 0, 0,
   1019 	      sql, &sqlstr);
   1020     result = sqlite_complete(sqlstr.result) ? JNI_TRUE : JNI_FALSE;
   1021 #endif
   1022     transfree(&sqlstr);
   1023     return result;
   1024 }
   1025 
   1026 JNIEXPORT void JNICALL
   1027 Java_SQLite_Database__1interrupt(JNIEnv *env, jobject obj)
   1028 {
   1029     handle *h = gethandle(env, obj);
   1030 
   1031     if (h && h->sqlite) {
   1032 #if HAVE_BOTH_SQLITE
   1033 	if (h->is3) {
   1034 	    sqlite3_interrupt((sqlite3 *) h->sqlite);
   1035 	} else {
   1036 	    sqlite_interrupt((sqlite *) h->sqlite);
   1037 	}
   1038 #else
   1039 #if HAVE_SQLITE2
   1040 	sqlite_interrupt((sqlite *) h->sqlite);
   1041 #endif
   1042 #if HAVE_SQLITE3
   1043 	sqlite3_interrupt((sqlite3 *) h->sqlite);
   1044 #endif
   1045 #endif
   1046 	return;
   1047     }
   1048     throwclosed(env);
   1049 }
   1050 
   1051 JNIEXPORT void JNICALL
   1052 Java_SQLite_Database__1open4(JNIEnv *env, jobject obj, jstring file, jint mode,
   1053 			     jstring vfs, jboolean ver2)
   1054 {
   1055     handle *h = gethandle(env, obj);
   1056     jthrowable exc;
   1057     char *err = 0;
   1058     transstr filename;
   1059     int maj, min, lev;
   1060 #if HAVE_SQLITE3_OPEN_V2
   1061     transstr vfsname;
   1062 
   1063     vfsname.result = 0;
   1064     vfsname.tofree = 0;
   1065     vfsname.jstr = 0;
   1066 #endif
   1067 
   1068     if (h) {
   1069 	if (h->sqlite) {
   1070 #if HAVE_BOTH_SQLITE
   1071 	    if (h->is3) {
   1072 		sqlite3_close((sqlite3 *) h->sqlite);
   1073 	    } else {
   1074 		sqlite_close((sqlite *) h->sqlite);
   1075 	    }
   1076 	    h->is3 = 0;
   1077 #else
   1078 #if HAVE_SQLITE2
   1079 	    sqlite_close((sqlite *) h->sqlite);
   1080 #endif
   1081 #if HAVE_SQLITE3
   1082 	    sqlite3_close((sqlite3 *) h->sqlite);
   1083 #endif
   1084 #endif
   1085 	    h->sqlite = 0;
   1086 	}
   1087     } else {
   1088 	h = malloc(sizeof (handle));
   1089 	if (!h) {
   1090 	    throwoom(env, "unable to get SQLite handle");
   1091 	    return;
   1092 	}
   1093 	h->sqlite = 0;
   1094 	h->bh = h->cb = h->ai = h->tr = h->pr = h->ph = 0;
   1095 	/* CHECK THIS */
   1096 #if HAVE_BOTH_SQLITE
   1097 	h->is3 = 0;
   1098 	h->stmt = 0;
   1099 	h->haveutf = 1;
   1100 #else
   1101 #if HAVE_SQLITE2
   1102 	h->haveutf = strcmp(sqlite_libencoding(), "UTF-8") == 0;
   1103 #endif
   1104 #if HAVE_SQLITE3
   1105 	h->stmt = 0;
   1106 	h->haveutf = 1;
   1107 #endif
   1108 #endif
   1109 	h->enc = 0;
   1110 	h->funcs = 0;
   1111 	h->ver = 0;
   1112 #if HAVE_SQLITE_COMPILE
   1113 	h->vms = 0;
   1114 #endif
   1115 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
   1116 	h->blobs = 0;
   1117 #endif
   1118 #if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
   1119 	h->backups = 0;
   1120 #endif
   1121     }
   1122     h->env = 0;
   1123     if (!file) {
   1124 	throwex(env, err ? err : "invalid file name");
   1125 	return;
   1126     }
   1127     trans2iso(env, h->haveutf, h->enc, file, &filename);
   1128     exc = (*env)->ExceptionOccurred(env);
   1129     if (exc) {
   1130 	(*env)->DeleteLocalRef(env, exc);
   1131 	return;
   1132     }
   1133 #if HAVE_SQLITE3_OPEN_V2
   1134     if (vfs) {
   1135 	trans2iso(env, 1, h->enc, vfs, &vfsname);
   1136 	exc = (*env)->ExceptionOccurred(env);
   1137 	if (exc) {
   1138 	    transfree(&filename);
   1139 	    (*env)->DeleteLocalRef(env, exc);
   1140 	    return;
   1141 	}
   1142     }
   1143 #endif
   1144 #if HAVE_BOTH_SQLITE
   1145     {
   1146 	FILE *f = fopen(filename.result, "rb");
   1147 	int c_0 = EOF;
   1148 
   1149 	if (f) {
   1150 	    c_0 = fgetc(f);
   1151 	    fclose(f);
   1152 	}
   1153 	if (c_0 != '*' && ver2 == JNI_FALSE) {
   1154 #if HAVE_SQLITE3_OPEN_V2
   1155 	    int rc = sqlite3_open_v2(filename.result, (sqlite3 **) &h->sqlite,
   1156 				     (int) mode, vfsname.result);
   1157 #else
   1158 	    int rc = sqlite3_open(filename.result, (sqlite3 **) &h->sqlite);
   1159 #endif
   1160 
   1161 	    if (rc == SQLITE_OK) {
   1162 		h->is3 = 1;
   1163 	    } else if (h->sqlite) {
   1164 		sqlite3_close((sqlite3 *) h->sqlite);
   1165 		h->sqlite = 0;
   1166 	    }
   1167 	} else {
   1168 	    h->sqlite = (void *) sqlite_open(filename.result,
   1169 					     (int) mode, &err);
   1170 	}
   1171     }
   1172 #else
   1173 #if HAVE_SQLITE2
   1174     h->sqlite = (void *) sqlite_open(filename.result, (int) mode, &err);
   1175 #endif
   1176 #if HAVE_SQLITE3
   1177 #if HAVE_SQLITE3_OPEN_V2
   1178     if (sqlite3_open_v2(filename.result, (sqlite3 **) &h->sqlite,
   1179 			(int) mode, vfsname.result) != SQLITE_OK)
   1180 #else
   1181     if (sqlite3_open(filename.result, (sqlite3 **) &h->sqlite) != SQLITE_OK)
   1182 #endif
   1183     {
   1184 	if (h->sqlite) {
   1185 	    sqlite3_close((sqlite3 *) h->sqlite);
   1186 	    h->sqlite = 0;
   1187 	}
   1188     }
   1189 #endif
   1190 #endif
   1191     transfree(&filename);
   1192 #if HAVE_SQLITE3_OPEN_V2
   1193     transfree(&vfsname);
   1194 #endif
   1195     exc = (*env)->ExceptionOccurred(env);
   1196     if (exc) {
   1197 	(*env)->DeleteLocalRef(env, exc);
   1198 #if HAVE_SQLITE2
   1199 	if (err) {
   1200 	    sqlite_freemem(err);
   1201 	}
   1202 #endif
   1203 	if (h->sqlite) {
   1204 #if HAVE_BOTH_SQLITE
   1205 	    if (h->is3) {
   1206 		sqlite3_close((sqlite3 *) h->sqlite);
   1207 		h->is3 = 0;
   1208 	    } else {
   1209 		sqlite_close((sqlite *) h->sqlite);
   1210 	    }
   1211 #else
   1212 #if HAVE_SQLITE2
   1213 	    sqlite_close((sqlite *) h->sqlite);
   1214 #endif
   1215 #if HAVE_SQLITE3
   1216 	    sqlite3_close((sqlite3 *) h->sqlite);
   1217 #endif
   1218 #endif
   1219 	}
   1220 	h->sqlite = 0;
   1221 	return;
   1222     }
   1223     if (h->sqlite) {
   1224 	jvalue v;
   1225 
   1226 	v.j = 0;
   1227 	v.l = (jobject) h;
   1228 	(*env)->SetLongField(env, obj, F_SQLite_Database_handle, v.j);
   1229 #if HAVE_SQLITE2
   1230 	if (err) {
   1231 	    sqlite_freemem(err);
   1232 	}
   1233 #endif
   1234 #if HAVE_BOTH_SQLITE
   1235 	if (h->is3) {
   1236 	    sscanf(sqlite3_libversion(), "%d.%d.%d", &maj, &min, &lev);
   1237 #if HAVE_SQLITE3_LOAD_EXTENSION
   1238 	    sqlite3_enable_load_extension((sqlite3 *) h->sqlite, 1);
   1239 #endif
   1240 	} else {
   1241 	    sscanf(sqlite_libversion(), "%d.%d.%d", &maj, &min, &lev);
   1242 	}
   1243 #else
   1244 #if HAVE_SQLITE2
   1245 	sscanf(sqlite_libversion(), "%d.%d.%d", &maj, &min, &lev);
   1246 #endif
   1247 #if HAVE_SQLITE3
   1248 	sscanf(sqlite3_libversion(), "%d.%d.%d", &maj, &min, &lev);
   1249 #if HAVE_SQLITE3_LOAD_EXTENSION
   1250 	sqlite3_enable_load_extension((sqlite3 *) h->sqlite, 1);
   1251 #endif
   1252 #endif
   1253 #endif
   1254 	h->ver = ((maj & 0xFF) << 16) | ((min & 0xFF) << 8) | (lev & 0xFF);
   1255 	return;
   1256     }
   1257     throwex(env, err ? err : "unknown error in open");
   1258 #if HAVE_SQLITE2
   1259     if (err) {
   1260 	sqlite_freemem(err);
   1261     }
   1262 #endif
   1263 }
   1264 
   1265 JNIEXPORT void JNICALL
   1266 Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode)
   1267 {
   1268     Java_SQLite_Database__1open4(env, obj, file, mode, 0, 0);
   1269 }
   1270 
   1271 JNIEXPORT void JNICALL
   1272 Java_SQLite_Database__1open_1aux_1file(JNIEnv *env, jobject obj, jstring file)
   1273 {
   1274     handle *h = gethandle(env, obj);
   1275 #if HAVE_SQLITE_OPEN_AUX_FILE
   1276     jthrowable exc;
   1277     char *err = 0;
   1278     transstr filename;
   1279     int ret;
   1280 #endif
   1281 
   1282     if (h && h->sqlite) {
   1283 #if HAVE_SQLITE_OPEN_AUX_FILE
   1284 #if HAVE_BOTH_SQLITE
   1285 	if (h->is3) {
   1286 	    throwex(env, "unsupported");
   1287 	}
   1288 #endif
   1289 	trans2iso(env, h->haveutf, h->enc, file, &filename);
   1290 	exc = (*env)->ExceptionOccurred(env);
   1291 	if (exc) {
   1292 	    (*env)->DeleteLocalRef(env, exc);
   1293 	    return;
   1294 	}
   1295 	ret = sqlite_open_aux_file((sqlite *) h->sqlite,
   1296 				   filename.result, &err);
   1297 	transfree(&filename);
   1298 	exc = (*env)->ExceptionOccurred(env);
   1299 	if (exc) {
   1300 	    (*env)->DeleteLocalRef(env, exc);
   1301 	    if (err) {
   1302 		sqlite_freemem(err);
   1303 	    }
   1304 	    return;
   1305 	}
   1306 	if (ret != SQLITE_OK) {
   1307 	    throwex(env, err ? err : sqlite_error_string(ret));
   1308 	}
   1309 	if (err) {
   1310 	    sqlite_freemem(err);
   1311 	}
   1312 #else
   1313 	throwex(env, "unsupported");
   1314 #endif
   1315 	return;
   1316     }
   1317     throwclosed(env);
   1318 }
   1319 
   1320 JNIEXPORT void JNICALL
   1321 Java_SQLite_Database__1busy_1handler(JNIEnv *env, jobject obj, jobject bh)
   1322 {
   1323     handle *h = gethandle(env, obj);
   1324 
   1325     if (h && h->sqlite) {
   1326 	delglobrefp(env, &h->bh);
   1327 	globrefset(env, bh, &h->bh);
   1328 #if HAVE_BOTH_SQLITE
   1329 	if (h->is3) {
   1330 	    sqlite3_busy_handler((sqlite3 *) h->sqlite, busyhandler3, h);
   1331 	} else {
   1332 	    sqlite_busy_handler((sqlite *) h->sqlite, busyhandler, h);
   1333 	}
   1334 #else
   1335 #if HAVE_SQLITE2
   1336 	sqlite_busy_handler((sqlite *) h->sqlite, busyhandler, h);
   1337 #endif
   1338 #if HAVE_SQLITE3
   1339 	sqlite3_busy_handler((sqlite3 *) h->sqlite, busyhandler3, h);
   1340 #endif
   1341 #endif
   1342 	return;
   1343     }
   1344     throwclosed(env);
   1345 }
   1346 
   1347 JNIEXPORT void JNICALL
   1348 Java_SQLite_Database__1exec__Ljava_lang_String_2LSQLite_Callback_2
   1349     (JNIEnv *env, jobject obj, jstring sql, jobject cb)
   1350 {
   1351     handle *h = gethandle(env, obj);
   1352     freemem *freeproc;
   1353 
   1354     if (!sql) {
   1355 	throwex(env, "invalid SQL statement");
   1356 	return;
   1357     }
   1358     if (h) {
   1359 	if (h->sqlite) {
   1360 	    jthrowable exc;
   1361 	    int rc;
   1362 	    char *err = 0;
   1363 	    transstr sqlstr;
   1364 	    jobject oldcb = globrefpop(env, &h->cb);
   1365 
   1366 	    globrefset(env, cb, &h->cb);
   1367 	    h->env = env;
   1368 	    h->row1 = 1;
   1369 	    trans2iso(env, h->haveutf, h->enc, sql, &sqlstr);
   1370 	    exc = (*env)->ExceptionOccurred(env);
   1371 	    if (exc) {
   1372 		(*env)->DeleteLocalRef(env, exc);
   1373 		return;
   1374 	    }
   1375 #if HAVE_BOTH_SQLITE
   1376 	    if (h->is3) {
   1377 		rc = sqlite3_exec((sqlite3 *) h->sqlite, sqlstr.result,
   1378 				  callback, h, &err);
   1379 		freeproc = (freemem *) sqlite3_free;
   1380 	    } else {
   1381 		rc = sqlite_exec((sqlite *) h->sqlite, sqlstr.result,
   1382 				 callback, h, &err);
   1383 		freeproc = (freemem *) sqlite_freemem;
   1384 	    }
   1385 #else
   1386 #if HAVE_SQLITE2
   1387 	    rc = sqlite_exec((sqlite *) h->sqlite, sqlstr.result,
   1388 			     callback, h, &err);
   1389 	    freeproc = (freemem *) sqlite_freemem;
   1390 #endif
   1391 #if HAVE_SQLITE3
   1392 	    rc = sqlite3_exec((sqlite3 *) h->sqlite, sqlstr.result,
   1393 			      callback, h, &err);
   1394 	    freeproc = (freemem *) sqlite3_free;
   1395 #endif
   1396 #endif
   1397 	    transfree(&sqlstr);
   1398 	    exc = (*env)->ExceptionOccurred(env);
   1399 	    delglobrefp(env, &h->cb);
   1400 	    h->cb = oldcb;
   1401 	    if (exc) {
   1402 		(*env)->DeleteLocalRef(env, exc);
   1403 		if (err) {
   1404 		    freeproc(err);
   1405 		}
   1406 		return;
   1407 	    }
   1408 	    if (rc != SQLITE_OK) {
   1409 		char msg[128];
   1410 
   1411 		seterr(env, obj, rc);
   1412 		if (!err) {
   1413 		    sprintf(msg, "error %d in sqlite*_exec", rc);
   1414 		}
   1415 		throwex(env, err ? err : msg);
   1416 	    }
   1417 	    if (err) {
   1418 		freeproc(err);
   1419 	    }
   1420 	    return;
   1421 	}
   1422     }
   1423     throwclosed(env);
   1424 }
   1425 
   1426 JNIEXPORT void JNICALL
   1427 Java_SQLite_Database__1exec__Ljava_lang_String_2LSQLite_Callback_2_3Ljava_lang_String_2
   1428     (JNIEnv *env, jobject obj, jstring sql, jobject cb, jobjectArray args)
   1429 {
   1430     handle *h = gethandle(env, obj);
   1431     freemem *freeproc = 0;
   1432 
   1433     if (!sql) {
   1434 	throwex(env, "invalid SQL statement");
   1435 	return;
   1436     }
   1437     if (h) {
   1438 	if (h->sqlite) {
   1439 	    jthrowable exc;
   1440 	    int rc = SQLITE_ERROR, nargs, i;
   1441 	    char *err = 0, *p;
   1442 	    const char *str = (*env)->GetStringUTFChars(env, sql, 0);
   1443 	    transstr sqlstr;
   1444 	    struct args {
   1445 		char *arg;
   1446 		jobject obj;
   1447 		transstr trans;
   1448 	    } *argv = 0;
   1449 	    char **cargv = 0;
   1450 	    jobject oldcb = globrefpop(env, &h->cb);
   1451 
   1452 	    globrefset(env, cb, &h->cb);
   1453 	    p = (char *) str;
   1454 	    nargs = 0;
   1455 	    while (*p) {
   1456 		if (*p == '%') {
   1457 		    ++p;
   1458 		    if (*p == 'q' || *p == 's') {
   1459 			nargs++;
   1460 			if (nargs > MAX_PARAMS) {
   1461 			    (*env)->ReleaseStringUTFChars(env, sql, str);
   1462 			    delglobrefp(env, &h->cb);
   1463 			    h->cb = oldcb;
   1464 			    throwex(env, "too much SQL parameters");
   1465 			    return;
   1466 			}
   1467 		    } else if (h->ver >= 0x020500 && *p == 'Q') {
   1468 			nargs++;
   1469 			if (nargs > MAX_PARAMS) {
   1470 			    (*env)->ReleaseStringUTFChars(env, sql, str);
   1471 			    delglobrefp(env, &h->cb);
   1472 			    h->cb = oldcb;
   1473 			    throwex(env, "too much SQL parameters");
   1474 			    return;
   1475 			}
   1476 		    } else if (*p != '%') {
   1477 			(*env)->ReleaseStringUTFChars(env, sql, str);
   1478 			delglobrefp(env, &h->cb);
   1479 			h->cb = oldcb;
   1480 			throwex(env, "bad % specification in query");
   1481 			return;
   1482 		    }
   1483 		}
   1484 		++p;
   1485 	    }
   1486 	    cargv = malloc((sizeof (*argv) + sizeof (char *))
   1487 			   * MAX_PARAMS);
   1488 	    if (!cargv) {
   1489 		(*env)->ReleaseStringUTFChars(env, sql, str);
   1490 		delglobrefp(env, &h->cb);
   1491 		h->cb = oldcb;
   1492 		throwoom(env, "unable to allocate arg vector");
   1493 		return;
   1494 	    }
   1495 	    argv = (struct args *) (cargv + MAX_PARAMS);
   1496 	    for (i = 0; i < MAX_PARAMS; i++) {
   1497 		cargv[i] = 0;
   1498 		argv[i].arg = 0;
   1499 		argv[i].obj = 0;
   1500 		argv[i].trans.result = argv[i].trans.tofree = 0;
   1501 	    }
   1502 	    exc = 0;
   1503 	    for (i = 0; i < nargs; i++) {
   1504 		jobject so = (*env)->GetObjectArrayElement(env, args, i);
   1505 
   1506 		exc = (*env)->ExceptionOccurred(env);
   1507 		if (exc) {
   1508 		    (*env)->DeleteLocalRef(env, exc);
   1509 		    break;
   1510 		}
   1511 		if (so) {
   1512 		    argv[i].obj = so;
   1513 		    argv[i].arg = cargv[i] =
   1514 			trans2iso(env, h->haveutf, h->enc, argv[i].obj,
   1515 				  &argv[i].trans);
   1516 		}
   1517 	    }
   1518 	    if (exc) {
   1519 		for (i = 0; i < nargs; i++) {
   1520 		    if (argv[i].obj) {
   1521 			transfree(&argv[i].trans);
   1522 		    }
   1523 		}
   1524 		freep((char **) &cargv);
   1525 		(*env)->ReleaseStringUTFChars(env, sql, str);
   1526 		delglobrefp(env, &h->cb);
   1527 		h->cb = oldcb;
   1528 		return;
   1529 	    }
   1530 	    h->env = env;
   1531 	    h->row1 = 1;
   1532 	    trans2iso(env, h->haveutf, h->enc, sql, &sqlstr);
   1533 	    exc = (*env)->ExceptionOccurred(env);
   1534 	    if (!exc) {
   1535 #if HAVE_BOTH_SQLITE
   1536 		if (h->is3) {
   1537 #if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
   1538 		    char *s = sqlite3_vmprintf(sqlstr.result, (char *) cargv);
   1539 #else
   1540 		    char *s = sqlite3_mprintf(sqlstr.result,
   1541 					      cargv[0], cargv[1],
   1542 					      cargv[2], cargv[3],
   1543 					      cargv[4], cargv[5],
   1544 					      cargv[6], cargv[7],
   1545 					      cargv[8], cargv[9],
   1546 					      cargv[10], cargv[11],
   1547 					      cargv[12], cargv[13],
   1548 					      cargv[14], cargv[15],
   1549 					      cargv[16], cargv[17],
   1550 					      cargv[18], cargv[19],
   1551 					      cargv[20], cargv[21],
   1552 					      cargv[22], cargv[23],
   1553 					      cargv[24], cargv[25],
   1554 					      cargv[26], cargv[27],
   1555 					      cargv[28], cargv[29],
   1556 					      cargv[30], cargv[31]);
   1557 #endif
   1558 
   1559 		    if (s) {
   1560 			rc = sqlite3_exec((sqlite3 *) h->sqlite, s, callback,
   1561 					  h, &err);
   1562 			sqlite3_free(s);
   1563 		    } else {
   1564 			rc = SQLITE_NOMEM;
   1565 		    }
   1566 		    freeproc = (freemem *) sqlite3_free;
   1567 		} else {
   1568 #if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
   1569 		    rc = sqlite_exec_vprintf((sqlite *) h->sqlite,
   1570 					     sqlstr.result, callback, h, &err,
   1571 					     (char *) cargv);
   1572 #else
   1573 		    rc = sqlite_exec_printf((sqlite *) h->sqlite,
   1574 					    sqlstr.result, callback,
   1575 					    h, &err,
   1576 					    cargv[0], cargv[1],
   1577 					    cargv[2], cargv[3],
   1578 					    cargv[4], cargv[5],
   1579 					    cargv[6], cargv[7],
   1580 					    cargv[8], cargv[9],
   1581 					    cargv[10], cargv[11],
   1582 					    cargv[12], cargv[13],
   1583 					    cargv[14], cargv[15],
   1584 					    cargv[16], cargv[17],
   1585 					    cargv[18], cargv[19],
   1586 					    cargv[20], cargv[21],
   1587 					    cargv[22], cargv[23],
   1588 					    cargv[24], cargv[25],
   1589 					    cargv[26], cargv[27],
   1590 					    cargv[28], cargv[29],
   1591 					    cargv[30], cargv[31]);
   1592 #endif
   1593 		    freeproc = (freemem *) sqlite_freemem;
   1594 		}
   1595 #else
   1596 #if HAVE_SQLITE2
   1597 #if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
   1598 		rc = sqlite_exec_vprintf((sqlite *) h->sqlite, sqlstr.result,
   1599 					 callback, h, &err, (char *) cargv);
   1600 #else
   1601 		rc = sqlite_exec_printf((sqlite *) h->sqlite, sqlstr.result,
   1602 					callback, h, &err,
   1603 					cargv[0], cargv[1],
   1604 					cargv[2], cargv[3],
   1605 					cargv[4], cargv[5],
   1606 					cargv[6], cargv[7],
   1607 					cargv[8], cargv[9],
   1608 					cargv[10], cargv[11],
   1609 					cargv[12], cargv[13],
   1610 					cargv[14], cargv[15],
   1611 					cargv[16], cargv[17],
   1612 					cargv[18], cargv[19],
   1613 					cargv[20], cargv[21],
   1614 					cargv[22], cargv[23],
   1615 					cargv[24], cargv[25],
   1616 					cargv[26], cargv[27],
   1617 					cargv[28], cargv[29],
   1618 					cargv[30], cargv[31]);
   1619 #endif
   1620 		freeproc = (freemem *) sqlite_freemem;
   1621 #endif
   1622 #if HAVE_SQLITE3
   1623 #if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
   1624 		char *s = sqlite3_vmprintf(sqlstr.result, (char *) cargv);
   1625 #else
   1626 		char *s = sqlite3_mprintf(sqlstr.result,
   1627 					  cargv[0], cargv[1],
   1628 					  cargv[2], cargv[3],
   1629 					  cargv[4], cargv[5],
   1630 					  cargv[6], cargv[7],
   1631 					  cargv[8], cargv[9],
   1632 					  cargv[10], cargv[11],
   1633 					  cargv[12], cargv[13],
   1634 					  cargv[14], cargv[15],
   1635 					  cargv[16], cargv[17],
   1636 					  cargv[18], cargv[19],
   1637 					  cargv[20], cargv[21],
   1638 					  cargv[22], cargv[23],
   1639 					  cargv[24], cargv[25],
   1640 					  cargv[26], cargv[27],
   1641 					  cargv[28], cargv[29],
   1642 					  cargv[30], cargv[31]);
   1643 #endif
   1644 
   1645 		if (s) {
   1646 		    rc = sqlite3_exec((sqlite3 *) h->sqlite, s, callback,
   1647 				      h, &err);
   1648 		    sqlite3_free(s);
   1649 		} else {
   1650 		    rc = SQLITE_NOMEM;
   1651 		}
   1652 		freeproc = (freemem *) sqlite3_free;
   1653 #endif
   1654 #endif
   1655 		exc = (*env)->ExceptionOccurred(env);
   1656 	    }
   1657 	    for (i = 0; i < nargs; i++) {
   1658 		if (argv[i].obj) {
   1659 		    transfree(&argv[i].trans);
   1660 		}
   1661 	    }
   1662 	    transfree(&sqlstr);
   1663 	    (*env)->ReleaseStringUTFChars(env, sql, str);
   1664 	    freep((char **) &cargv);
   1665 	    delglobrefp(env, &h->cb);
   1666 	    h->cb = oldcb;
   1667 	    if (exc) {
   1668 		(*env)->DeleteLocalRef(env, exc);
   1669 		if (err && freeproc) {
   1670 		    freeproc(err);
   1671 		}
   1672 		return;
   1673 	    }
   1674 	    if (rc != SQLITE_OK) {
   1675 		char msg[128];
   1676 
   1677 		seterr(env, obj, rc);
   1678 		if (!err) {
   1679 		    sprintf(msg, "error %d in sqlite*_exec", rc);
   1680 		}
   1681 		throwex(env, err ? err : msg);
   1682 	    }
   1683 	    if (err && freeproc) {
   1684 		freeproc(err);
   1685 	    }
   1686 	    return;
   1687 	}
   1688     }
   1689     throwclosed(env);
   1690 }
   1691 
   1692 static hfunc *
   1693 getfunc(JNIEnv *env, jobject obj)
   1694 {
   1695     jvalue v;
   1696 
   1697     v.j = (*env)->GetLongField(env, obj, F_SQLite_FunctionContext_handle);
   1698     return (hfunc *) v.l;
   1699 }
   1700 
   1701 #if HAVE_SQLITE2
   1702 static void
   1703 call_common(sqlite_func *sf, int isstep, int nargs, const char **args)
   1704 {
   1705     hfunc *f = (hfunc *) sqlite_user_data(sf);
   1706 
   1707     if (f && f->env && f->fi) {
   1708 	JNIEnv *env = f->env;
   1709 	jclass cls = (*env)->GetObjectClass(env, f->fi);
   1710 	jmethodID mid =
   1711 	    (*env)->GetMethodID(env, cls,
   1712 				isstep ? "step" : "function",
   1713 				"(LSQLite/FunctionContext;[Ljava/lang/String;)V");
   1714 	jobjectArray arr;
   1715 	int i;
   1716 
   1717 	if (mid == 0) {
   1718 	    (*env)->DeleteLocalRef(env, cls);
   1719 	    return;
   1720 	}
   1721 	arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0);
   1722 	for (i = 0; i < nargs; i++) {
   1723 	    if (args[i]) {
   1724 		transstr arg;
   1725 		jthrowable exc;
   1726 
   1727 		trans2utf(env, f->h->haveutf, f->h->enc, args[i], &arg);
   1728 		(*env)->SetObjectArrayElement(env, arr, i, arg.jstr);
   1729 		exc = (*env)->ExceptionOccurred(env);
   1730 		if (exc) {
   1731 		    (*env)->DeleteLocalRef(env, exc);
   1732 		    return;
   1733 		}
   1734 		(*env)->DeleteLocalRef(env, arg.jstr);
   1735 	    }
   1736 	}
   1737 	f->sf = sf;
   1738 	(*env)->CallVoidMethod(env, f->fi, mid, f->fc, arr);
   1739 	(*env)->DeleteLocalRef(env, arr);
   1740 	(*env)->DeleteLocalRef(env, cls);
   1741     }
   1742 }
   1743 
   1744 static void
   1745 call_func(sqlite_func *sf, int nargs, const char **args)
   1746 {
   1747     call_common(sf, 0, nargs, args);
   1748 }
   1749 
   1750 static void
   1751 call_step(sqlite_func *sf, int nargs, const char **args)
   1752 {
   1753     call_common(sf, 1, nargs, args);
   1754 }
   1755 
   1756 static void
   1757 call_final(sqlite_func *sf)
   1758 {
   1759     hfunc *f = (hfunc *) sqlite_user_data(sf);
   1760 
   1761     if (f && f->env && f->fi) {
   1762 	JNIEnv *env = f->env;
   1763 	jclass cls = (*env)->GetObjectClass(env, f->fi);
   1764 	jmethodID mid = (*env)->GetMethodID(env, cls, "last_step",
   1765 					    "(LSQLite/FunctionContext;)V");
   1766 	if (mid == 0) {
   1767 	    (*env)->DeleteLocalRef(env, cls);
   1768 	    return;
   1769 	}
   1770 	f->sf = sf;
   1771 	(*env)->CallVoidMethod(env, f->fi, mid, f->fc);
   1772 	(*env)->DeleteLocalRef(env, cls);
   1773     }
   1774 }
   1775 #endif
   1776 
   1777 #if HAVE_SQLITE3
   1778 static void
   1779 call3_common(sqlite3_context *sf, int isstep, int nargs, sqlite3_value **args)
   1780 {
   1781     hfunc *f = (hfunc *) sqlite3_user_data(sf);
   1782 
   1783     if (f && f->env && f->fi) {
   1784 	JNIEnv *env = f->env;
   1785 	jclass cls = (*env)->GetObjectClass(env, f->fi);
   1786 	jmethodID mid =
   1787 	    (*env)->GetMethodID(env, cls,
   1788 				isstep ? "step" : "function",
   1789 				"(LSQLite/FunctionContext;[Ljava/lang/String;)V");
   1790 	jobjectArray arr;
   1791 	int i;
   1792 
   1793 	if (mid == 0) {
   1794 	    (*env)->DeleteLocalRef(env, cls);
   1795 	    return;
   1796 	}
   1797 	arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0);
   1798 	for (i = 0; i < nargs; i++) {
   1799 	    if (args[i]) {
   1800 		transstr arg;
   1801 		jthrowable exc;
   1802 
   1803 		trans2utf(env, 1, 0, (char *) sqlite3_value_text(args[i]),
   1804 			  &arg);
   1805 		(*env)->SetObjectArrayElement(env, arr, i, arg.jstr);
   1806 		exc = (*env)->ExceptionOccurred(env);
   1807 		if (exc) {
   1808 		    (*env)->DeleteLocalRef(env, exc);
   1809 		    return;
   1810 		}
   1811 		(*env)->DeleteLocalRef(env, arg.jstr);
   1812 	    }
   1813 	}
   1814 	f->sf = sf;
   1815 	(*env)->CallVoidMethod(env, f->fi, mid, f->fc, arr);
   1816 	(*env)->DeleteLocalRef(env, arr);
   1817 	(*env)->DeleteLocalRef(env, cls);
   1818     }
   1819 }
   1820 
   1821 static void
   1822 call3_func(sqlite3_context *sf, int nargs, sqlite3_value **args)
   1823 {
   1824     call3_common(sf, 0, nargs, args);
   1825 }
   1826 
   1827 static void
   1828 call3_step(sqlite3_context *sf, int nargs, sqlite3_value **args)
   1829 {
   1830     call3_common(sf, 1, nargs, args);
   1831 }
   1832 
   1833 static void
   1834 call3_final(sqlite3_context *sf)
   1835 {
   1836     hfunc *f = (hfunc *) sqlite3_user_data(sf);
   1837 
   1838     if (f && f->env && f->fi) {
   1839 	JNIEnv *env = f->env;
   1840 	jclass cls = (*env)->GetObjectClass(env, f->fi);
   1841 	jmethodID mid = (*env)->GetMethodID(env, cls, "last_step",
   1842 					    "(LSQLite/FunctionContext;)V");
   1843 	if (mid == 0) {
   1844 	    (*env)->DeleteLocalRef(env, cls);
   1845 	    return;
   1846 	}
   1847 	f->sf = sf;
   1848 	(*env)->CallVoidMethod(env, f->fi, mid, f->fc);
   1849 	(*env)->DeleteLocalRef(env, cls);
   1850     }
   1851 }
   1852 #endif
   1853 
   1854 static void
   1855 mkfunc_common(JNIEnv *env, int isagg, jobject obj, jstring name,
   1856 	      jint nargs, jobject fi)
   1857 {
   1858     handle *h = gethandle(env, obj);
   1859 
   1860     if (h && h->sqlite) {
   1861 	jclass cls = (*env)->FindClass(env, "SQLite/FunctionContext");
   1862 	jobject fc;
   1863 	hfunc *f;
   1864 	int ret;
   1865 	transstr namestr;
   1866 	jvalue v;
   1867 	jthrowable exc;
   1868 
   1869 	fc = (*env)->AllocObject(env, cls);
   1870 	if (!fi) {
   1871 	    throwex(env, "null SQLite.Function not allowed");
   1872 	    return;
   1873 	}
   1874 	f = malloc(sizeof (hfunc));
   1875 	if (!f) {
   1876 	    throwoom(env, "unable to get SQLite.FunctionContext handle");
   1877 	    return;
   1878 	}
   1879 	globrefset(env, fc, &f->fc);
   1880 	globrefset(env, fi, &f->fi);
   1881 	globrefset(env, obj, &f->db);
   1882 	f->h = h;
   1883 	f->next = h->funcs;
   1884 	h->funcs = f;
   1885 	f->sf = 0;
   1886 	f->env = env;
   1887 	v.j = 0;
   1888 	v.l = (jobject) f;
   1889 	(*env)->SetLongField(env, f->fc, F_SQLite_FunctionContext_handle, v.j);
   1890 	trans2iso(env, h->haveutf, h->enc, name, &namestr);
   1891 	exc = (*env)->ExceptionOccurred(env);
   1892 	if (exc) {
   1893 	    (*env)->DeleteLocalRef(env, exc);
   1894 	    return;
   1895 	}
   1896 #if HAVE_BOTH_SQLITE
   1897 	f->is3 = h->is3;
   1898 	if (h->is3) {
   1899 	    ret = sqlite3_create_function((sqlite3 *) h->sqlite,
   1900 					  namestr.result,
   1901 					  (int) nargs,
   1902 					  SQLITE_UTF8, f,
   1903 					  isagg ? NULL : call3_func,
   1904 					  isagg ? call3_step : NULL,
   1905 					  isagg ? call3_final : NULL);
   1906 
   1907 	} else {
   1908 	    if (isagg) {
   1909 		ret = sqlite_create_aggregate((sqlite *) h->sqlite,
   1910 					      namestr.result,
   1911 					      (int) nargs,
   1912 					      call_step, call_final, f);
   1913 	    } else {
   1914 		ret = sqlite_create_function((sqlite *) h->sqlite,
   1915 					     namestr.result,
   1916 					     (int) nargs,
   1917 					     call_func, f);
   1918 	    }
   1919 	}
   1920 #else
   1921 #if HAVE_SQLITE2
   1922 	if (isagg) {
   1923 	    ret = sqlite_create_aggregate((sqlite *) h->sqlite, namestr.result,
   1924 					  (int) nargs,
   1925 					  call_step, call_final, f);
   1926 	} else {
   1927 	    ret = sqlite_create_function((sqlite *) h->sqlite, namestr.result,
   1928 					 (int) nargs,
   1929 					 call_func, f);
   1930 	}
   1931 #endif
   1932 #if HAVE_SQLITE3
   1933 	ret = sqlite3_create_function((sqlite3 *) h->sqlite,
   1934 				      namestr.result,
   1935 				      (int) nargs,
   1936 				      SQLITE_UTF8, f,
   1937 				      isagg ? NULL : call3_func,
   1938 				      isagg ? call3_step : NULL,
   1939 				      isagg ? call3_final : NULL);
   1940 #endif
   1941 #endif
   1942 	transfree(&namestr);
   1943 	if (ret != SQLITE_OK) {
   1944 	    throwex(env, "error creating function/aggregate");
   1945 	}
   1946 	return;
   1947     }
   1948     throwclosed(env);
   1949 }
   1950 
   1951 JNIEXPORT void JNICALL
   1952 Java_SQLite_Database__1create_1aggregate(JNIEnv *env, jobject obj,
   1953 					 jstring name, jint nargs, jobject fi)
   1954 {
   1955     mkfunc_common(env, 1, obj, name, nargs, fi);
   1956 }
   1957 
   1958 JNIEXPORT void JNICALL
   1959 Java_SQLite_Database__1create_1function(JNIEnv *env, jobject obj,
   1960 					jstring name, jint nargs, jobject fi)
   1961 {
   1962     mkfunc_common(env, 0, obj, name, nargs, fi);
   1963 }
   1964 
   1965 JNIEXPORT void JNICALL
   1966 Java_SQLite_Database__1function_1type(JNIEnv *env, jobject obj,
   1967 				      jstring name, jint type)
   1968 {
   1969     handle *h = gethandle(env, obj);
   1970 
   1971     if (h && h->sqlite) {
   1972 #if HAVE_BOTH_SQLITE
   1973 	if (h->is3) {
   1974 	    return;
   1975 	}
   1976 #endif
   1977 #if HAVE_SQLITE2
   1978 #if HAVE_SQLITE_FUNCTION_TYPE
   1979 	{
   1980 	    int ret;
   1981 	    transstr namestr;
   1982 	    jthrowable exc;
   1983 
   1984 	    trans2iso(env, h->haveutf, h->enc, name, &namestr);
   1985 	    exc = (*env)->ExceptionOccurred(env);
   1986 	    if (exc) {
   1987 		(*env)->DeleteLocalRef(env, exc);
   1988 		return;
   1989 	    }
   1990 	    ret = sqlite_function_type(h->sqlite, namestr.result, (int) type);
   1991 	    transfree(&namestr);
   1992 	    if (ret != SQLITE_OK) {
   1993 		throwex(env, sqlite_error_string(ret));
   1994 	    }
   1995 	}
   1996 #endif
   1997 #endif
   1998 	return;
   1999     }
   2000     throwclosed(env);
   2001 }
   2002 
   2003 JNIEXPORT jint JNICALL
   2004 Java_SQLite_FunctionContext_count(JNIEnv *env, jobject obj)
   2005 {
   2006     hfunc *f = getfunc(env, obj);
   2007     jint r = 0;
   2008 
   2009     if (f && f->sf) {
   2010 #if HAVE_SQLITE_BOTH
   2011 	if (f->is3) {
   2012 	    r = (jint) sqlite3_aggregate_count((sqlite3_context *) f->sf);
   2013 	} else {
   2014 	    r = (jint) sqlite_aggregate_count((sqlite_func *) f->sf);
   2015 	}
   2016 #else
   2017 #if HAVE_SQLITE2
   2018 	r = (jint) sqlite_aggregate_count((sqlite_func *) f->sf);
   2019 #endif
   2020 #if HAVE_SQLITE3
   2021 	r = (jint) sqlite3_aggregate_count((sqlite3_context *) f->sf);
   2022 #endif
   2023 #endif
   2024     }
   2025     return r;
   2026 }
   2027 
   2028 JNIEXPORT void JNICALL
   2029 Java_SQLite_FunctionContext_set_1error(JNIEnv *env, jobject obj, jstring err)
   2030 {
   2031     hfunc *f = getfunc(env, obj);
   2032 
   2033     if (f && f->sf) {
   2034 #if HAVE_BOTH_SQLITE
   2035 	if (!f->is3) {
   2036 	    transstr errstr;
   2037 	    jthrowable exc;
   2038 
   2039 	    trans2iso(env, f->h->haveutf, f->h->enc, err, &errstr);
   2040 	    exc = (*env)->ExceptionOccurred(env);
   2041 	    if (exc) {
   2042 		(*env)->DeleteLocalRef(env, exc);
   2043 		return;
   2044 	    }
   2045 	    sqlite_set_result_error((sqlite_func *) f->sf,
   2046 				    errstr.result, -1);
   2047 	    transfree(&errstr);
   2048 	} else if (err) {
   2049 	    jsize len = (*env)->GetStringLength(env, err) * sizeof (jchar);
   2050 	    const jchar *str = (*env)->GetStringChars(env, err, 0);
   2051 
   2052 	    sqlite3_result_error16((sqlite3_context *) f->sf, str, len);
   2053 	    (*env)->ReleaseStringChars(env, err, str);
   2054 	} else {
   2055 	    sqlite3_result_error((sqlite3_context *) f->sf,
   2056 				 "null error text", -1);
   2057 	}
   2058 #else
   2059 #if HAVE_SQLITE2
   2060 	transstr errstr;
   2061 	jthrowable exc;
   2062 
   2063 	trans2iso(env, f->h->haveutf, f->h->enc, err, &errstr);
   2064 	exc = (*env)->ExceptionOccurred(env);
   2065 	if (exc) {
   2066 	    (*env)->DeleteLocalRef(env, exc);
   2067 	    return;
   2068 	}
   2069 	sqlite_set_result_error((sqlite_func *) f->sf, errstr.result, -1);
   2070 	transfree(&errstr);
   2071 #endif
   2072 #if HAVE_SQLITE3
   2073 	if (err) {
   2074 	    jsize len = (*env)->GetStringLength(env, err) * sizeof (jchar);
   2075 	    const jchar *str = (*env)->GetStringChars(env, err, 0);
   2076 
   2077 	    sqlite3_result_error16((sqlite3_context *) f->sf, str, len);
   2078 	    (*env)->ReleaseStringChars(env, err, str);
   2079 	} else {
   2080 	    sqlite3_result_error((sqlite3_context *) f->sf,
   2081 				 "null error text", -1);
   2082 	}
   2083 #endif
   2084 #endif
   2085     }
   2086 }
   2087 
   2088 JNIEXPORT void JNICALL
   2089 Java_SQLite_FunctionContext_set_1result__D(JNIEnv *env, jobject obj, jdouble d)
   2090 {
   2091     hfunc *f = getfunc(env, obj);
   2092 
   2093     if (f && f->sf) {
   2094 #if HAVE_BOTH_SQLITE
   2095 	if (f->is3) {
   2096 	    sqlite3_result_double((sqlite3_context *) f->sf, (double) d);
   2097 	} else {
   2098 	    sqlite_set_result_double((sqlite_func *) f->sf, (double) d);
   2099 	}
   2100 #else
   2101 #if HAVE_SQLITE2
   2102 	sqlite_set_result_double((sqlite_func *) f->sf, (double) d);
   2103 #endif
   2104 #if HAVE_SQLITE3
   2105 	sqlite3_result_double((sqlite3_context *) f->sf, (double) d);
   2106 #endif
   2107 #endif
   2108     }
   2109 }
   2110 
   2111 JNIEXPORT void JNICALL
   2112 Java_SQLite_FunctionContext_set_1result__I(JNIEnv *env, jobject obj, jint i)
   2113 {
   2114     hfunc *f = getfunc(env, obj);
   2115 
   2116     if (f && f->sf) {
   2117 #if HAVE_BOTH_SQLITE
   2118 	if (f->is3) {
   2119 	    sqlite3_result_int((sqlite3_context *) f->sf, (int) i);
   2120 	} else {
   2121 	    sqlite_set_result_int((sqlite_func *) f->sf, (int) i);
   2122 	}
   2123 #else
   2124 #if HAVE_SQLITE2
   2125 	sqlite_set_result_int((sqlite_func *) f->sf, (int) i);
   2126 #endif
   2127 #if HAVE_SQLITE3
   2128 	sqlite3_result_int((sqlite3_context *) f->sf, (int) i);
   2129 #endif
   2130 #endif
   2131     }
   2132 }
   2133 
   2134 JNIEXPORT void JNICALL
   2135 Java_SQLite_FunctionContext_set_1result__Ljava_lang_String_2(JNIEnv *env,
   2136 							     jobject obj,
   2137 							     jstring ret)
   2138 {
   2139     hfunc *f = getfunc(env, obj);
   2140 
   2141     if (f && f->sf) {
   2142 #if HAVE_BOTH_SQLITE
   2143 	if (!f->is3) {
   2144 	    transstr retstr;
   2145 	    jthrowable exc;
   2146 
   2147 	    trans2iso(env, f->h->haveutf, f->h->enc, ret, &retstr);
   2148 	    exc = (*env)->ExceptionOccurred(env);
   2149 	    if (exc) {
   2150 		(*env)->DeleteLocalRef(env, exc);
   2151 		return;
   2152 	    }
   2153 	    sqlite_set_result_string((sqlite_func *) f->sf,
   2154 				     retstr.result, -1);
   2155 	    transfree(&retstr);
   2156 	} else if (ret) {
   2157 	    jsize len = (*env)->GetStringLength(env, ret) * sizeof (jchar);
   2158 	    const jchar *str = (*env)->GetStringChars(env, ret, 0);
   2159 
   2160 	    sqlite3_result_text16((sqlite3_context *) f->sf, str, len,
   2161 				  SQLITE_TRANSIENT);
   2162 	    (*env)->ReleaseStringChars(env, ret, str);
   2163 	} else {
   2164 	    sqlite3_result_null((sqlite3_context *) f->sf);
   2165 	}
   2166 #else
   2167 #if HAVE_SQLITE2
   2168 	transstr retstr;
   2169 	jthrowable exc;
   2170 
   2171 	trans2iso(env, f->h->haveutf, f->h->enc, ret, &retstr);
   2172 	exc = (*env)->ExceptionOccurred(env);
   2173 	if (exc) {
   2174 	    (*env)->DeleteLocalRef(env, exc);
   2175 	    return;
   2176 	}
   2177 	sqlite_set_result_string((sqlite_func *) f->sf, retstr.result, -1);
   2178 	transfree(&retstr);
   2179 #endif
   2180 #if HAVE_SQLITE3
   2181 	if (ret) {
   2182 	    jsize len = (*env)->GetStringLength(env, ret) * sizeof (jchar);
   2183 	    const jchar *str = (*env)->GetStringChars(env, ret, 0);
   2184 
   2185 	    sqlite3_result_text16((sqlite3_context *) f->sf, str, len,
   2186 				  SQLITE_TRANSIENT);
   2187 	    (*env)->ReleaseStringChars(env, ret, str);
   2188 	} else {
   2189 	    sqlite3_result_null((sqlite3_context *) f->sf);
   2190 	}
   2191 #endif
   2192 #endif
   2193     }
   2194 }
   2195 
   2196 JNIEXPORT void JNICALL
   2197 Java_SQLite_FunctionContext_set_1result___3B(JNIEnv *env, jobject obj,
   2198 					     jbyteArray b)
   2199 {
   2200 #if HAVE_SQLITE3
   2201     hfunc *f = getfunc(env, obj);
   2202 
   2203     if (f && f->sf) {
   2204 #if HAVE_BOTH_SQLITE
   2205 	if (!f->is3) {
   2206 	    /* silently ignored */
   2207 	    return;
   2208 	}
   2209 #endif
   2210 	if (b) {
   2211 	    jsize len;
   2212 	    jbyte *data;
   2213 
   2214 	    len = (*env)->GetArrayLength(env, b);
   2215 	    data = (*env)->GetByteArrayElements(env, b, 0);
   2216 	    sqlite3_result_blob((sqlite3_context *) f->sf,
   2217 				data, len, SQLITE_TRANSIENT);
   2218 	    (*env)->ReleaseByteArrayElements(env, b, data, 0);
   2219 	} else {
   2220 	    sqlite3_result_null((sqlite3_context *) f->sf);
   2221 	}
   2222     }
   2223 #endif
   2224 }
   2225 
   2226 JNIEXPORT void JNICALL
   2227 Java_SQLite_FunctionContext_set_1result_1zeroblob(JNIEnv *env, jobject obj,
   2228 						  jint n)
   2229 {
   2230 #if HAVE_SQLITE3 && HAVE_SQLITE3_RESULT_ZEROBLOB
   2231     hfunc *f = getfunc(env, obj);
   2232 
   2233     if (f && f->sf) {
   2234 #if HAVE_BOTH_SQLITE
   2235 	if (!f->is3) {
   2236 	    /* silently ignored */
   2237 	    return;
   2238 	}
   2239 #endif
   2240 	sqlite3_result_zeroblob((sqlite3_context *) f->sf, n);
   2241     }
   2242 #endif
   2243 }
   2244 
   2245 JNIEXPORT jstring JNICALL
   2246 Java_SQLite_Database_error_1string(JNIEnv *env, jclass c, jint err)
   2247 {
   2248 #if HAVE_SQLITE2
   2249     return (*env)->NewStringUTF(env, sqlite_error_string((int) err));
   2250 #else
   2251     return (*env)->NewStringUTF(env, "unkown error");
   2252 #endif
   2253 }
   2254 
   2255 JNIEXPORT jstring JNICALL
   2256 Java_SQLite_Database__1errmsg(JNIEnv *env, jobject obj)
   2257 {
   2258 #if HAVE_SQLITE3
   2259     handle *h = gethandle(env, obj);
   2260 
   2261     if (h && h->sqlite) {
   2262 #if HAVE_BOTH_SQLITE
   2263 	if (!h->is3) {
   2264 	    return 0;
   2265 	}
   2266 #endif
   2267 	return (*env)->NewStringUTF(env,
   2268 				    sqlite3_errmsg((sqlite3 *) h->sqlite));
   2269     }
   2270 #endif
   2271     return 0;
   2272 }
   2273 
   2274 JNIEXPORT void JNICALL
   2275 Java_SQLite_Database__1set_1encoding(JNIEnv *env, jobject obj, jstring enc)
   2276 {
   2277     handle *h = gethandle(env, obj);
   2278 
   2279     if (h && !h->haveutf) {
   2280 #if HAVE_BOTH_SQLITE
   2281 	if (!h->is3) {
   2282 	    delglobrefp(env, &h->enc);
   2283 	    h->enc = enc;
   2284 	    globrefset(env, enc, &h->enc);
   2285 	}
   2286 #else
   2287 #if HAVE_SQLITE2
   2288 	delglobrefp(env, &h->enc);
   2289 	h->enc = enc;
   2290 	globrefset(env, enc, &h->enc);
   2291 #endif
   2292 #endif
   2293     }
   2294 }
   2295 
   2296 #if HAVE_SQLITE_SET_AUTHORIZER
   2297 static int
   2298 doauth(void *arg, int what, const char *arg1, const char *arg2,
   2299        const char *arg3, const char *arg4)
   2300 {
   2301     handle *h = (handle *) arg;
   2302     JNIEnv *env = h->env;
   2303 
   2304     if (env && h->ai) {
   2305 	jthrowable exc;
   2306 	jclass cls = (*env)->GetObjectClass(env, h->ai);
   2307 	jmethodID mid;
   2308 	jint i = what;
   2309 
   2310 	mid = (*env)->GetMethodID(env, cls, "authorize",
   2311 				  "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I");
   2312 	if (mid) {
   2313 	    jstring s1 = 0, s2 = 0, s3 = 0, s4 = 0;
   2314 	    transstr tr;
   2315 
   2316 	    if (arg1) {
   2317 		trans2utf(env, h->haveutf, h->enc, arg1, &tr);
   2318 		s1 = tr.jstr;
   2319 	    }
   2320 	    exc = (*env)->ExceptionOccurred(env);
   2321 	    if (exc) {
   2322 		(*env)->DeleteLocalRef(env, exc);
   2323 		return SQLITE_DENY;
   2324 	    }
   2325 	    if (arg2) {
   2326 		trans2utf(env, h->haveutf, h->enc, arg2, &tr);
   2327 		s2 = tr.jstr;
   2328 	    }
   2329 	    if (arg3) {
   2330 		trans2utf(env, h->haveutf, h->enc, arg3, &tr);
   2331 		s3 = tr.jstr;
   2332 	    }
   2333 	    if (arg4) {
   2334 		trans2utf(env, h->haveutf, h->enc, arg4, &tr);
   2335 		s4 = tr.jstr;
   2336 	    }
   2337 	    exc = (*env)->ExceptionOccurred(env);
   2338 	    if (exc) {
   2339 		(*env)->DeleteLocalRef(env, exc);
   2340 		return SQLITE_DENY;
   2341 	    }
   2342 	    i = (*env)->CallIntMethod(env, h->ai, mid, i, s1, s2, s3, s4);
   2343 	    exc = (*env)->ExceptionOccurred(env);
   2344 	    if (exc) {
   2345 		(*env)->DeleteLocalRef(env, exc);
   2346 		return SQLITE_DENY;
   2347 	    }
   2348 	    (*env)->DeleteLocalRef(env, s4);
   2349 	    (*env)->DeleteLocalRef(env, s3);
   2350 	    (*env)->DeleteLocalRef(env, s2);
   2351 	    (*env)->DeleteLocalRef(env, s1);
   2352 	    if (i != SQLITE_OK && i != SQLITE_IGNORE) {
   2353 		i = SQLITE_DENY;
   2354 	    }
   2355 	    return (int) i;
   2356 	}
   2357     }
   2358     return SQLITE_DENY;
   2359 }
   2360 #endif
   2361 
   2362 JNIEXPORT void JNICALL
   2363 Java_SQLite_Database__1set_1authorizer(JNIEnv *env, jobject obj, jobject auth)
   2364 {
   2365     handle *h = gethandle(env, obj);
   2366 
   2367     if (h && h->sqlite) {
   2368 	delglobrefp(env, &h->ai);
   2369 	globrefset(env, auth, &h->ai);
   2370 #if HAVE_SQLITE_SET_AUTHORIZER
   2371 	h->env = env;
   2372 #if HAVE_BOTH_SQLITE
   2373 	if (h->is3) {
   2374 	    sqlite3_set_authorizer((sqlite3 *) h->sqlite,
   2375 				   h->ai ? doauth : 0, h);
   2376 	} else {
   2377 	    sqlite_set_authorizer((sqlite *) h->sqlite,
   2378 				  h->ai ? doauth : 0, h);
   2379 	}
   2380 #else
   2381 #if HAVE_SQLITE2
   2382 	sqlite_set_authorizer((sqlite *) h->sqlite, h->ai ? doauth : 0, h);
   2383 #endif
   2384 #if HAVE_SQLITE3
   2385 	sqlite3_set_authorizer((sqlite3 *) h->sqlite, h->ai ? doauth : 0, h);
   2386 #endif
   2387 #endif
   2388 #endif
   2389 	return;
   2390     }
   2391     throwclosed(env);
   2392 }
   2393 
   2394 #if HAVE_SQLITE_TRACE
   2395 static void
   2396 dotrace(void *arg, const char *msg)
   2397 {
   2398     handle *h = (handle *) arg;
   2399     JNIEnv *env = h->env;
   2400 
   2401     if (env && h->tr && msg) {
   2402 	jthrowable exc;
   2403 	jclass cls = (*env)->GetObjectClass(env, h->tr);
   2404 	jmethodID mid;
   2405 
   2406 	mid = (*env)->GetMethodID(env, cls, "trace", "(Ljava/lang/String;)V");
   2407 	if (mid) {
   2408 	    transstr tr;
   2409 
   2410 	    trans2utf(env, h->haveutf, h->enc, msg, &tr);
   2411 	    exc = (*env)->ExceptionOccurred(env);
   2412 	    if (exc) {
   2413 		(*env)->DeleteLocalRef(env, exc);
   2414 		(*env)->ExceptionClear(env);
   2415 		return;
   2416 	    }
   2417 	    (*env)->CallVoidMethod(env, h->tr, mid, tr.jstr);
   2418 	    (*env)->ExceptionClear(env);
   2419 	    (*env)->DeleteLocalRef(env, tr.jstr);
   2420 	    return;
   2421 	}
   2422     }
   2423     return;
   2424 }
   2425 #endif
   2426 
   2427 JNIEXPORT void JNICALL
   2428 Java_SQLite_Database__1trace(JNIEnv *env, jobject obj, jobject tr)
   2429 {
   2430     handle *h = gethandle(env, obj);
   2431 
   2432     if (h && h->sqlite) {
   2433 	delglobrefp(env, &h->tr);
   2434 	globrefset(env, tr, &h->tr);
   2435 #if HAVE_BOTH_SQLITE
   2436 	if (h->is3) {
   2437 	    sqlite3_trace((sqlite3 *) h->sqlite, h->tr ? dotrace : 0, h);
   2438 	} else {
   2439 #if HAVE_SQLITE_TRACE
   2440 	    sqlite_trace((sqlite *) h->sqlite, h->tr ? dotrace : 0, h);
   2441 #endif
   2442 	}
   2443 #else
   2444 #if HAVE_SQLITE2
   2445 #if HAVE_SQLITE_TRACE
   2446 	sqlite_trace((sqlite *) h->sqlite, h->tr ? dotrace : 0, h);
   2447 #endif
   2448 #endif
   2449 #if HAVE_SQLITE3
   2450 	sqlite3_trace((sqlite3 *) h->sqlite, h->tr ? dotrace : 0, h);
   2451 #endif
   2452 #endif
   2453 	return;
   2454     }
   2455     throwclosed(env);
   2456 }
   2457 
   2458 #if HAVE_SQLITE_COMPILE
   2459 static void
   2460 dovmfinal(JNIEnv *env, jobject obj, int final)
   2461 {
   2462     hvm *v = gethvm(env, obj);
   2463 
   2464     if (v) {
   2465 	if (v->h) {
   2466 	    handle *h = v->h;
   2467 	    hvm *vv, **vvp;
   2468 
   2469 	    vvp = &h->vms;
   2470 	    vv = *vvp;
   2471 	    while (vv) {
   2472 		if (vv == v) {
   2473 		    *vvp = vv->next;
   2474 		    break;
   2475 		}
   2476 		vvp = &vv->next;
   2477 		vv = *vvp;
   2478 	    }
   2479 	}
   2480 	if (v->vm) {
   2481 #if HAVE_BOTH_SQLITE
   2482 	    if (v->is3) {
   2483 		sqlite3_finalize((sqlite3_stmt *) v->vm);
   2484 	    } else {
   2485 		sqlite_finalize((sqlite_vm *) v->vm, 0);
   2486 	    }
   2487 #else
   2488 #if HAVE_SQLITE2
   2489 	    sqlite_finalize((sqlite_vm *) v->vm, 0);
   2490 #endif
   2491 #if HAVE_SQLITE3
   2492 	    sqlite3_finalize((sqlite3_stmt *) v->vm);
   2493 #endif
   2494 #endif
   2495 	    v->vm = 0;
   2496 	}
   2497 	free(v);
   2498 	(*env)->SetLongField(env, obj, F_SQLite_Vm_handle, 0);
   2499 	return;
   2500     }
   2501     if (!final) {
   2502 	throwex(env, "vm already closed");
   2503     }
   2504 }
   2505 #endif
   2506 
   2507 #if HAVE_SQLITE3
   2508 static void
   2509 dostmtfinal(JNIEnv *env, jobject obj)
   2510 {
   2511     hvm *v = gethstmt(env, obj);
   2512 
   2513     if (v) {
   2514 	if (v->h) {
   2515 	    handle *h = v->h;
   2516 	    hvm *vv, **vvp;
   2517 
   2518 	    vvp = &h->vms;
   2519 	    vv = *vvp;
   2520 	    while (vv) {
   2521 		if (vv == v) {
   2522 		    *vvp = vv->next;
   2523 		    break;
   2524 		}
   2525 		vvp = &vv->next;
   2526 		vv = *vvp;
   2527 	    }
   2528 	}
   2529 	if (v->vm) {
   2530 	    sqlite3_finalize((sqlite3_stmt *) v->vm);
   2531 	}
   2532 	v->vm = 0;
   2533 	free(v);
   2534 	(*env)->SetLongField(env, obj, F_SQLite_Stmt_handle, 0);
   2535     }
   2536 }
   2537 #endif
   2538 
   2539 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
   2540 static void
   2541 doblobfinal(JNIEnv *env, jobject obj)
   2542 {
   2543     hbl *bl = gethbl(env, obj);
   2544 
   2545     if (bl) {
   2546 	if (bl->h) {
   2547 	    handle *h = bl->h;
   2548 	    hbl *blc, **blp;
   2549 
   2550 	    blp = &h->blobs;
   2551 	    blc = *blp;
   2552 	    while (blc) {
   2553 		if (blc == bl) {
   2554 		    *blp = blc->next;
   2555 		    break;
   2556 		}
   2557 		blp = &blc->next;
   2558 		blc = *blp;
   2559 	    }
   2560 	}
   2561 	if (bl->blob) {
   2562 	    sqlite3_blob_close(bl->blob);
   2563 	}
   2564 	bl->blob = 0;
   2565 	free(bl);
   2566 	(*env)->SetLongField(env, obj, F_SQLite_Blob_handle, 0);
   2567 	(*env)->SetIntField(env, obj, F_SQLite_Blob_size, 0);
   2568     }
   2569 }
   2570 #endif
   2571 
   2572 JNIEXPORT void JNICALL
   2573 Java_SQLite_Vm_stop(JNIEnv *env, jobject obj)
   2574 {
   2575 #if HAVE_SQLITE_COMPILE
   2576     dovmfinal(env, obj, 0);
   2577 #else
   2578     throwex(env, "unsupported");
   2579 #endif
   2580 }
   2581 
   2582 JNIEXPORT void JNICALL
   2583 Java_SQLite_Vm_finalize(JNIEnv *env, jobject obj)
   2584 {
   2585 #if HAVE_SQLITE_COMPILE
   2586     dovmfinal(env, obj, 1);
   2587 #endif
   2588 }
   2589 
   2590 #if HAVE_SQLITE_COMPILE
   2591 #if HAVE_SQLITE3
   2592 static void
   2593 free_tab(void *mem)
   2594 {
   2595     char **p = (char **) mem;
   2596     int i, n;
   2597 
   2598     if (!p) {
   2599 	return;
   2600     }
   2601     p -= 1;
   2602     mem = (void *) p;
   2603     n = ((int *) p)[0];
   2604     p += n * 2 + 2 + 1;
   2605     for (i = 0; i < n; i++) {
   2606 	if (p[i]) {
   2607 	    free(p[i]);
   2608 	}
   2609     }
   2610     free(mem);
   2611 }
   2612 #endif
   2613 #endif
   2614 
   2615 JNIEXPORT jboolean JNICALL
   2616 Java_SQLite_Vm_step(JNIEnv *env, jobject obj, jobject cb)
   2617 {
   2618 #if HAVE_SQLITE_COMPILE
   2619     hvm *v = gethvm(env, obj);
   2620 
   2621     if (v && v->vm && v->h) {
   2622 	jthrowable exc;
   2623 	int ret, tmp;
   2624 	long ncol = 0;
   2625 #if HAVE_SQLITE3
   2626 	freemem *freeproc = 0;
   2627 	const char **blob = 0;
   2628 #endif
   2629 	const char **data = 0, **cols = 0;
   2630 
   2631 	v->h->env = env;
   2632 #if HAVE_BOTH_SQLITE
   2633 	if (v->is3) {
   2634 	    ret = sqlite3_step((sqlite3_stmt *) v->vm);
   2635 	    if (ret == SQLITE_DONE && v->hh.row1) {
   2636 		ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
   2637 		if (ncol > 0) {
   2638 		    data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
   2639 		    if (data) {
   2640 			data[0] = (const char *) ncol;
   2641 			++data;
   2642 			cols = data + ncol + 1;
   2643 			blob = cols + ncol + 1;
   2644 			freeproc = free_tab;
   2645 		    } else {
   2646 			ret = SQLITE_NOMEM;
   2647 		    }
   2648 		}
   2649 		if (ret != SQLITE_NOMEM) {
   2650 		    int i;
   2651 
   2652 		    for (i = 0; i < ncol; i++) {
   2653 			cols[i] =
   2654 			    sqlite3_column_name((sqlite3_stmt *) v->vm, i);
   2655 		    }
   2656 		}
   2657 	    } else if (ret == SQLITE_ROW) {
   2658 		ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
   2659 		if (ncol > 0) {
   2660 		    data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
   2661 		    if (data) {
   2662 			data[0] = (const char *) ncol;
   2663 			++data;
   2664 			cols = data + ncol + 1;
   2665 			blob = cols + ncol + 1;
   2666 			freeproc = free_tab;
   2667 		    } else {
   2668 			ret = SQLITE_NOMEM;
   2669 		    }
   2670 		}
   2671 		if (ret != SQLITE_NOMEM) {
   2672 		    int i;
   2673 
   2674 		    for (i = 0; i < ncol; i++) {
   2675 			cols[i] =
   2676 			    sqlite3_column_name((sqlite3_stmt *) v->vm, i);
   2677 			if (sqlite3_column_type((sqlite3_stmt *) v->vm, i)
   2678 			    == SQLITE_BLOB) {
   2679 			    unsigned char *src = (unsigned char *)
   2680 				sqlite3_column_blob((sqlite3_stmt *) v->vm, i);
   2681 			    int n =
   2682 				sqlite3_column_bytes((sqlite3_stmt *) v->vm,
   2683 						     i);
   2684 
   2685 			    if (src) {
   2686 				data[i] = malloc(n * 2 + 4);
   2687 				if (data[i]) {
   2688 				    int k;
   2689 				    char *p = (char *) data[i];
   2690 
   2691 				    blob[i] = data[i];
   2692 				    *p++ = 'X';
   2693 				    *p++ = '\'';
   2694 				    for (k = 0; k < n; k++) {
   2695 					*p++ = xdigits[src[k] >> 4];
   2696 					*p++ = xdigits[src[k] & 0x0F];
   2697 				    }
   2698 				    *p++ = '\'';
   2699 				    *p++ = '\0';
   2700 				}
   2701 			    }
   2702 			} else {
   2703 			    data[i] = (const char *)
   2704 				sqlite3_column_text((sqlite3_stmt *) v->vm, i);
   2705 			}
   2706 		    }
   2707 		}
   2708 	    }
   2709 	} else {
   2710 	    tmp = 0;
   2711 	    ret = sqlite_step((sqlite_vm *) v->vm, &tmp, &data, &cols);
   2712 	    ncol = tmp;
   2713 	}
   2714 #else
   2715 #if HAVE_SQLITE2
   2716 	tmp = 0;
   2717 	ret = sqlite_step((sqlite_vm *) v->vm, &tmp, &data, &cols);
   2718 	ncol = tmp;
   2719 #endif
   2720 #if HAVE_SQLITE3
   2721 	ret = sqlite3_step((sqlite3_stmt *) v->vm);
   2722 	if (ret == SQLITE_DONE && v->hh.row1) {
   2723 	    ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
   2724 	    if (ncol > 0) {
   2725 		data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
   2726 		if (data) {
   2727 		    data[0] = (const char *) ncol;
   2728 		    ++data;
   2729 		    cols = data + ncol + 1;
   2730 		    blob = cols + ncol + 1;
   2731 		    freeproc = free_tab;
   2732 		} else {
   2733 		    ret = SQLITE_NOMEM;
   2734 		}
   2735 	    }
   2736 	    if (ret != SQLITE_NOMEM) {
   2737 		int i;
   2738 
   2739 		for (i = 0; i < ncol; i++) {
   2740 		    cols[i] =
   2741 			sqlite3_column_name((sqlite3_stmt *) v->vm, i);
   2742 		}
   2743 	    }
   2744 	} else if (ret == SQLITE_ROW) {
   2745 	    ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
   2746 	    if (ncol > 0) {
   2747 		data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
   2748 		if (data) {
   2749 		    data[0] = (const char *) ncol;
   2750 		    ++data;
   2751 		    cols = data + ncol + 1;
   2752 		    blob = cols + ncol + 1;
   2753 		    freeproc = free_tab;
   2754 		} else {
   2755 		    ret = SQLITE_NOMEM;
   2756 		}
   2757 	    }
   2758 	    if (ret != SQLITE_NOMEM) {
   2759 		int i;
   2760 
   2761 		for (i = 0; i < ncol; i++) {
   2762 		    cols[i] = sqlite3_column_name((sqlite3_stmt *) v->vm, i);
   2763 		    if (sqlite3_column_type((sqlite3_stmt *) v->vm, i)
   2764 			== SQLITE_BLOB) {
   2765 			unsigned char *src = (unsigned char *)
   2766 			    sqlite3_column_blob((sqlite3_stmt *) v->vm, i);
   2767 			int n =
   2768 			    sqlite3_column_bytes((sqlite3_stmt *) v->vm, i);
   2769 
   2770 			if (src) {
   2771 			    data[i] = malloc(n * 2 + 4);
   2772 			    if (data[i]) {
   2773 				int k;
   2774 				char *p = (char *) data[i];
   2775 
   2776 				blob[i] = data[i];
   2777 				*p++ = 'X';
   2778 				*p++ = '\'';
   2779 				for (k = 0; k < n; k++) {
   2780 				    *p++ = xdigits[src[k] >> 4];
   2781 				    *p++ = xdigits[src[k] & 0x0F];
   2782 				}
   2783 				*p++ = '\'';
   2784 				*p++ = '\0';
   2785 			    }
   2786 			}
   2787 		    } else {
   2788 			data[i] = (char *)
   2789 			    sqlite3_column_text((sqlite3_stmt *) v->vm, i);
   2790 		    }
   2791 		}
   2792 	    }
   2793 	}
   2794 #endif
   2795 #endif
   2796 	if (ret == SQLITE_ROW) {
   2797 	    v->hh.cb = cb;
   2798 	    v->hh.env = env;
   2799 #if HAVE_BOTH_SQLITE
   2800 	    if (v->is3) {
   2801 		v->hh.stmt = (sqlite3_stmt *) v->vm;
   2802 	    }
   2803 #else
   2804 #if HAVE_SQLITE3
   2805 	    v->hh.stmt = (sqlite3_stmt *) v->vm;
   2806 #endif
   2807 #endif
   2808 	    callback((void *) &v->hh, ncol, (char **) data, (char **) cols);
   2809 #if HAVE_SQLITE3
   2810 	    if (data && freeproc) {
   2811 		freeproc((void *) data);
   2812 	    }
   2813 #endif
   2814 	    exc = (*env)->ExceptionOccurred(env);
   2815 	    if (exc) {
   2816 		(*env)->DeleteLocalRef(env, exc);
   2817 		goto dofin;
   2818 	    }
   2819 	    return JNI_TRUE;
   2820 	} else if (ret == SQLITE_DONE) {
   2821 dofin:
   2822 	    if (v->hh.row1 && cols) {
   2823 		v->hh.cb = cb;
   2824 		v->hh.env = env;
   2825 #if HAVE_BOTH_SQLITE
   2826 		if (v->is3) {
   2827 		    v->hh.stmt = (sqlite3_stmt *) v->vm;
   2828 		}
   2829 #else
   2830 #if HAVE_SQLITE3
   2831 		v->hh.stmt = (sqlite3_stmt *) v->vm;
   2832 #endif
   2833 #endif
   2834 		callback((void *) &v->hh, ncol, (char **) 0, (char **) cols);
   2835 #if HAVE_SQLITE3
   2836 		if (data && freeproc) {
   2837 		    freeproc((void *) data);
   2838 		}
   2839 #endif
   2840 		exc = (*env)->ExceptionOccurred(env);
   2841 		if (exc) {
   2842 		    (*env)->DeleteLocalRef(env, exc);
   2843 		}
   2844 	    }
   2845 #if HAVE_BOTH_SQLITE
   2846 	    if (v->is3) {
   2847 		sqlite3_finalize((sqlite3_stmt *) v->vm);
   2848 	    } else {
   2849 		sqlite_finalize((sqlite_vm *) v->vm, 0);
   2850 	    }
   2851 #else
   2852 #if HAVE_SQLITE2
   2853 	    sqlite_finalize((sqlite_vm *) v->vm, 0);
   2854 #endif
   2855 #if HAVE_SQLITE3
   2856 	    sqlite3_finalize((sqlite3_stmt *) v->vm);
   2857 #endif
   2858 #endif
   2859 	    v->vm = 0;
   2860 	    return JNI_FALSE;
   2861 	}
   2862 #if HAVE_BOTH_SQLITE
   2863 	if (v->is3) {
   2864 	    sqlite3_finalize((sqlite3_stmt *) v->vm);
   2865 	} else {
   2866 	    sqlite_finalize((sqlite_vm *) v->vm, 0);
   2867 	}
   2868 #else
   2869 #if HAVE_SQLITE2
   2870 	sqlite_finalize((sqlite_vm *) v->vm, 0);
   2871 #endif
   2872 #if HAVE_SQLITE3
   2873 	sqlite3_finalize((sqlite3_stmt *) v->vm);
   2874 #endif
   2875 #endif
   2876 	setvmerr(env, obj, ret);
   2877 	v->vm = 0;
   2878 	throwex(env, "error in step");
   2879 	return JNI_FALSE;
   2880     }
   2881     throwex(env, "vm already closed");
   2882 #else
   2883     throwex(env, "unsupported");
   2884 #endif
   2885     return JNI_FALSE;
   2886 }
   2887 
   2888 JNIEXPORT jboolean JNICALL
   2889 Java_SQLite_Vm_compile(JNIEnv *env, jobject obj)
   2890 {
   2891 #if HAVE_SQLITE_COMPILE
   2892     hvm *v = gethvm(env, obj);
   2893     void *svm = 0;
   2894     char *err = 0;
   2895 #ifdef HAVE_SQLITE2
   2896     char *errfr = 0;
   2897 #endif
   2898     const char *tail;
   2899     int ret;
   2900 
   2901     if (v && v->vm) {
   2902 #if HAVE_BOTH_SQLITE
   2903 	if (v->is3) {
   2904 	    sqlite3_finalize((sqlite3_stmt *) v->vm);
   2905 	} else {
   2906 	    sqlite_finalize((sqlite_vm *) v->vm, 0);
   2907 	}
   2908 #else
   2909 #if HAVE_SQLITE2
   2910 	sqlite_finalize((sqlite_vm *) v->vm, 0);
   2911 #endif
   2912 #if HAVE_SQLITE3
   2913 	sqlite3_finalize((sqlite3_stmt *) v->vm);
   2914 #endif
   2915 #endif
   2916 	v->vm = 0;
   2917     }
   2918     if (v && v->h && v->h->sqlite) {
   2919 	if (!v->tail) {
   2920 	    return JNI_FALSE;
   2921 	}
   2922 	v->h->env = env;
   2923 #if HAVE_BOTH_SQLITE
   2924 	if (v->is3) {
   2925 #if HAVE_SQLITE3_PREPARE_V2
   2926 	    ret = sqlite3_prepare_v2((sqlite3 *) v->h->sqlite, v->tail, -1,
   2927 				     (sqlite3_stmt **) &svm, &tail);
   2928 #else
   2929 	    ret = sqlite3_prepare((sqlite3 *) v->h->sqlite, v->tail, -1,
   2930 				  (sqlite3_stmt **) &svm, &tail);
   2931 #endif
   2932 	    if (ret != SQLITE_OK) {
   2933 		if (svm) {
   2934 		    sqlite3_finalize((sqlite3_stmt *) svm);
   2935 		    svm = 0;
   2936 		}
   2937 		err = (char *) sqlite3_errmsg((sqlite3 *) v->h->sqlite);
   2938 	    }
   2939 	} else {
   2940 	    ret = sqlite_compile((sqlite *) v->h->sqlite, v->tail,
   2941 				 &tail, (sqlite_vm **) &svm, &errfr);
   2942 	    if (ret != SQLITE_OK) {
   2943 		err = errfr;
   2944 		if (svm) {
   2945 		    sqlite_finalize((sqlite_vm *) svm, 0);
   2946 		    svm = 0;
   2947 		}
   2948 	    }
   2949 	}
   2950 #else
   2951 #if HAVE_SQLITE2
   2952 	ret = sqlite_compile((sqlite *) v->h->sqlite, v->tail,
   2953 			     &tail, (sqlite_vm **) &svm, &errfr);
   2954 	if (ret != SQLITE_OK) {
   2955 	    err = errfr;
   2956 	    if (svm) {
   2957 		sqlite_finalize((sqlite_vm *) svm, 0);
   2958 		svm = 0;
   2959 	    }
   2960 	}
   2961 #endif
   2962 #if HAVE_SQLITE3
   2963 #if HAVE_SQLITE3_PREPARE_V2
   2964 	ret = sqlite3_prepare_v2((sqlite3 *) v->h->sqlite,
   2965 				 v->tail, -1, (sqlite3_stmt **) &svm, &tail);
   2966 #else
   2967 	ret = sqlite3_prepare((sqlite3 *) v->h->sqlite,
   2968 			      v->tail, -1, (sqlite3_stmt **) &svm, &tail);
   2969 #endif
   2970 	if (ret != SQLITE_OK) {
   2971 	    if (svm) {
   2972 		sqlite3_finalize((sqlite3_stmt *) svm);
   2973 		svm = 0;
   2974 	    }
   2975 	    err = (char *) sqlite3_errmsg((sqlite3 *) v->h->sqlite);
   2976 	}
   2977 #endif
   2978 #endif
   2979 	if (ret != SQLITE_OK) {
   2980 	    setvmerr(env, obj, ret);
   2981 	    v->tail = 0;
   2982 	    throwex(env, err ? err : "error in compile/prepare");
   2983 #if HAVE_SQLITE2
   2984 	    if (errfr) {
   2985 		sqlite_freemem(errfr);
   2986 	    }
   2987 #endif
   2988 	    return JNI_FALSE;
   2989 	}
   2990 #if HAVE_SQLITE2
   2991 	if (errfr) {
   2992 	    sqlite_freemem(errfr);
   2993 	}
   2994 #endif
   2995 	if (!svm) {
   2996 	    v->tail = 0;
   2997 	    return JNI_FALSE;
   2998 	}
   2999 	v->vm = svm;
   3000 	v->tail = (char *) tail;
   3001 	v->hh.row1 = 1;
   3002 	return JNI_TRUE;
   3003     }
   3004     throwex(env, "vm already closed");
   3005 #else
   3006     throwex(env, "unsupported");
   3007 #endif
   3008     return JNI_FALSE;
   3009 }
   3010 
   3011 JNIEXPORT void JNICALL
   3012 Java_SQLite_Database_vm_1compile(JNIEnv *env, jobject obj, jstring sql,
   3013 				 jobject vm)
   3014 {
   3015 #if HAVE_SQLITE_COMPILE
   3016     handle *h = gethandle(env, obj);
   3017     void *svm = 0;
   3018     hvm *v;
   3019     char *err = 0;
   3020 #if HAVE_SQLITE2
   3021     char *errfr = 0;
   3022 #endif
   3023     const char *tail;
   3024     transstr tr;
   3025     jvalue vv;
   3026     int ret;
   3027     jthrowable exc;
   3028 
   3029     if (!h) {
   3030 	throwclosed(env);
   3031 	return;
   3032     }
   3033     if (!vm) {
   3034 	throwex(env, "null vm");
   3035 	return;
   3036     }
   3037     if (!sql) {
   3038 	throwex(env, "null sql");
   3039 	return;
   3040     }
   3041     trans2iso(env, h->haveutf, h->enc, sql, &tr);
   3042     exc = (*env)->ExceptionOccurred(env);
   3043     if (exc) {
   3044 	(*env)->DeleteLocalRef(env, exc);
   3045 	return;
   3046     }
   3047     h->env = env;
   3048 #if HAVE_BOTH_SQLITE
   3049     if (h->is3) {
   3050 #if HAVE_SQLITE3_PREPARE_V2
   3051 	ret = sqlite3_prepare_v2((sqlite3 *) h->sqlite, tr.result, -1,
   3052 				 (sqlite3_stmt **) &svm, &tail);
   3053 #else
   3054 	ret = sqlite3_prepare((sqlite3 *) h->sqlite, tr.result, -1,
   3055 			      (sqlite3_stmt **) &svm, &tail);
   3056 #endif
   3057 	if (ret != SQLITE_OK) {
   3058 	    if (svm) {
   3059 		sqlite3_finalize((sqlite3_stmt *) svm);
   3060 		svm = 0;
   3061 	    }
   3062 	    err = (char *) sqlite3_errmsg((sqlite3 *) h->sqlite);
   3063 	}
   3064     } else {
   3065 	ret = sqlite_compile((sqlite *) h->sqlite, tr.result, &tail,
   3066 			     (sqlite_vm **) &svm, &errfr);
   3067 	if (ret != SQLITE_OK) {
   3068 	    err = errfr;
   3069 	    if (svm) {
   3070 		sqlite_finalize((sqlite_vm *) svm, 0);
   3071 	    }
   3072 	}
   3073     }
   3074 #else
   3075 #if HAVE_SQLITE2
   3076     ret = sqlite_compile((sqlite *) h->sqlite, tr.result, &tail,
   3077 			 (sqlite_vm **) &svm, &errfr);
   3078     if (ret != SQLITE_OK) {
   3079 	err = errfr;
   3080 	if (svm) {
   3081 	    sqlite_finalize((sqlite_vm *) svm, 0);
   3082 	    svm = 0;
   3083 	}
   3084     }
   3085 #endif
   3086 #if HAVE_SQLITE3
   3087 #if HAVE_SQLITE3_PREPARE_V2
   3088     ret = sqlite3_prepare_v2((sqlite3 *) h->sqlite, tr.result, -1,
   3089 			     (sqlite3_stmt **) &svm, &tail);
   3090 #else
   3091     ret = sqlite3_prepare((sqlite3 *) h->sqlite, tr.result, -1,
   3092 			  (sqlite3_stmt **) &svm, &tail);
   3093 #endif
   3094     if (ret != SQLITE_OK) {
   3095 	if (svm) {
   3096 	    sqlite3_finalize((sqlite3_stmt *) svm);
   3097 	    svm = 0;
   3098 	}
   3099 	err = (char *) sqlite3_errmsg((sqlite3 *) h->sqlite);
   3100     }
   3101 #endif
   3102 #endif
   3103     if (ret != SQLITE_OK) {
   3104 	transfree(&tr);
   3105 	setvmerr(env, vm, ret);
   3106 	throwex(env, err ? err : "error in prepare/compile");
   3107 #if HAVE_SQLITE2
   3108 	if (errfr) {
   3109 	    sqlite_freemem(errfr);
   3110 	}
   3111 #endif
   3112 	return;
   3113     }
   3114 #if HAVE_SQLITE2
   3115     if (errfr) {
   3116 	sqlite_freemem(errfr);
   3117     }
   3118 #endif
   3119     if (!svm) {
   3120 	transfree(&tr);
   3121 	return;
   3122     }
   3123     v = malloc(sizeof (hvm) + strlen(tail) + 1);
   3124     if (!v) {
   3125 	transfree(&tr);
   3126 #if HAVE_BOTH_SQLITE
   3127 	if (h->is3) {
   3128 	    sqlite3_finalize((sqlite3_stmt *) svm);
   3129 	} else {
   3130 	    sqlite_finalize((sqlite_vm *) svm, 0);
   3131 	}
   3132 #else
   3133 #if HAVE_SQLITE2
   3134 	sqlite_finalize((sqlite_vm *) svm, 0);
   3135 #endif
   3136 #if HAVE_SQLITE3
   3137 	sqlite3_finalize((sqlite3_stmt *) svm);
   3138 #endif
   3139 #endif
   3140 	throwoom(env, "unable to get SQLite handle");
   3141 	return;
   3142     }
   3143     v->next = h->vms;
   3144     h->vms = v;
   3145     v->vm = svm;
   3146     v->h = h;
   3147     v->tail = (char *) (v + 1);
   3148 #if HAVE_BOTH_SQLITE
   3149     v->is3 = v->hh.is3 = h->is3;
   3150 #endif
   3151     strcpy(v->tail, tail);
   3152     v->hh.sqlite = 0;
   3153     v->hh.haveutf = h->haveutf;
   3154     v->hh.ver = h->ver;
   3155     v->hh.bh = v->hh.cb = v->hh.ai = v->hh.tr = v->hh.ph = 0;
   3156     v->hh.row1 = 1;
   3157     v->hh.enc = h->enc;
   3158     v->hh.funcs = 0;
   3159     v->hh.vms = 0;
   3160     v->hh.env = 0;
   3161     vv.j = 0;
   3162     vv.l = (jobject) v;
   3163     (*env)->SetLongField(env, vm, F_SQLite_Vm_handle, vv.j);
   3164 #else
   3165     throwex(env, "unsupported");
   3166 #endif
   3167 }
   3168 
   3169 JNIEXPORT void JNICALL
   3170 Java_SQLite_Database_vm_1compile_1args(JNIEnv *env,
   3171 				       jobject obj, jstring sql,
   3172 				       jobject vm, jobjectArray args)
   3173 {
   3174 #if HAVE_SQLITE_COMPILE
   3175 #if HAVE_SQLITE3
   3176     handle *h = gethandle(env, obj);
   3177 #endif
   3178 
   3179 #if HAVE_BOTH_SQLITE
   3180     if (h && !h->is3) {
   3181 	throwex(env, "unsupported");
   3182 	return;
   3183     }
   3184 #else
   3185 #if HAVE_SQLITE2
   3186     throwex(env, "unsupported");
   3187 #endif
   3188 #endif
   3189 #if HAVE_SQLITE3
   3190     if (!h || !h->sqlite) {
   3191 	throwclosed(env);
   3192 	return;
   3193     }
   3194     if (!vm) {
   3195 	throwex(env, "null vm");
   3196 	return;
   3197     }
   3198     if (!sql) {
   3199 	throwex(env, "null sql");
   3200 	return;
   3201     } else {
   3202 	void *svm = 0;
   3203 	hvm *v;
   3204 	jvalue vv;
   3205 	jthrowable exc;
   3206 	int rc = SQLITE_ERROR, nargs, i;
   3207 	char *p;
   3208 	const char *str = (*env)->GetStringUTFChars(env, sql, 0);
   3209 	const char *tail;
   3210 	transstr sqlstr;
   3211 	struct args {
   3212 	    char *arg;
   3213 	    jobject obj;
   3214 	    transstr trans;
   3215 	} *argv = 0;
   3216 	char **cargv = 0;
   3217 
   3218 	p = (char *) str;
   3219 	nargs = 0;
   3220 	while (*p) {
   3221 	    if (*p == '%') {
   3222 		++p;
   3223 		if (*p == 'q' || *p == 'Q' || *p == 's') {
   3224 		    nargs++;
   3225 		    if (nargs > MAX_PARAMS) {
   3226 			(*env)->ReleaseStringUTFChars(env, sql, str);
   3227 			throwex(env, "too much SQL parameters");
   3228 			return;
   3229 		    }
   3230 		} else if (*p != '%') {
   3231 		    (*env)->ReleaseStringUTFChars(env, sql, str);
   3232 		    throwex(env, "bad % specification in query");
   3233 		    return;
   3234 		}
   3235 	    }
   3236 	    ++p;
   3237 	}
   3238 	cargv = malloc((sizeof (*argv) + sizeof (char *)) * MAX_PARAMS);
   3239 	if (!cargv) {
   3240 	    (*env)->ReleaseStringUTFChars(env, sql, str);
   3241 	    throwoom(env, "unable to allocate arg vector");
   3242 	    return;
   3243 	}
   3244 	argv = (struct args *) (cargv + MAX_PARAMS);
   3245 	for (i = 0; i < MAX_PARAMS; i++) {
   3246 	    cargv[i] = 0;
   3247 	    argv[i].arg = 0;
   3248 	    argv[i].obj = 0;
   3249 	    argv[i].trans.result = argv[i].trans.tofree = 0;
   3250 	}
   3251 	exc = 0;
   3252 	for (i = 0; i < nargs; i++) {
   3253 	    jobject so = (*env)->GetObjectArrayElement(env, args, i);
   3254 
   3255 	    exc = (*env)->ExceptionOccurred(env);
   3256 	    if (exc) {
   3257 		(*env)->DeleteLocalRef(env, exc);
   3258 		break;
   3259 	    }
   3260 	    if (so) {
   3261 		argv[i].obj = so;
   3262 		argv[i].arg = cargv[i] =
   3263 		    trans2iso(env, 1, 0, argv[i].obj, &argv[i].trans);
   3264 	    }
   3265 	}
   3266 	if (exc) {
   3267 	    for (i = 0; i < nargs; i++) {
   3268 		if (argv[i].obj) {
   3269 		    transfree(&argv[i].trans);
   3270 		}
   3271 	    }
   3272 	    freep((char **) &cargv);
   3273 	    (*env)->ReleaseStringUTFChars(env, sql, str);
   3274 	    return;
   3275 	}
   3276 	h->row1 = 1;
   3277 	trans2iso(env, 1, 0, sql, &sqlstr);
   3278 	exc = (*env)->ExceptionOccurred(env);
   3279 	if (!exc) {
   3280 #if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
   3281 	    char *s = sqlite3_vmprintf(sqlstr.result, (char *) cargv);
   3282 #else
   3283 	    char *s = sqlite3_mprintf(sqlstr.result,
   3284 				      cargv[0], cargv[1],
   3285 				      cargv[2], cargv[3],
   3286 				      cargv[4], cargv[5],
   3287 				      cargv[6], cargv[7],
   3288 				      cargv[8], cargv[9],
   3289 				      cargv[10], cargv[11],
   3290 				      cargv[12], cargv[13],
   3291 				      cargv[14], cargv[15],
   3292 				      cargv[16], cargv[17],
   3293 				      cargv[18], cargv[19],
   3294 				      cargv[20], cargv[21],
   3295 				      cargv[22], cargv[23],
   3296 				      cargv[24], cargv[25],
   3297 				      cargv[26], cargv[27],
   3298 				      cargv[28], cargv[29],
   3299 				      cargv[30], cargv[31]);
   3300 #endif
   3301 	    if (!s) {
   3302 		rc = SQLITE_NOMEM;
   3303 	    } else {
   3304 #if HAVE_SQLITE3_PREPARE_V2
   3305 		rc = sqlite3_prepare_v2((sqlite3 *) h->sqlite, s, -1,
   3306 					(sqlite3_stmt **) &svm, &tail);
   3307 #else
   3308 		rc = sqlite3_prepare((sqlite3 *) h->sqlite, s, -1,
   3309 				      (sqlite3_stmt **) &svm, &tail);
   3310 #endif
   3311 		if (rc != SQLITE_OK) {
   3312 		    if (svm) {
   3313 			sqlite3_finalize((sqlite3_stmt *) svm);
   3314 			svm = 0;
   3315 		    }
   3316 		}
   3317 	    }
   3318 	    if (rc != SQLITE_OK) {
   3319 		sqlite3_free(s);
   3320 		for (i = 0; i < nargs; i++) {
   3321 		    if (argv[i].obj) {
   3322 			transfree(&argv[i].trans);
   3323 		    }
   3324 		}
   3325 		freep((char **) &cargv);
   3326 		transfree(&sqlstr);
   3327 		(*env)->ReleaseStringUTFChars(env, sql, str);
   3328 		setvmerr(env, vm, rc);
   3329 		throwex(env, "error in prepare");
   3330 		return;
   3331 	    }
   3332 	    v = malloc(sizeof (hvm) + strlen(tail) + 1);
   3333 	    if (!v) {
   3334 		sqlite3_free(s);
   3335 		for (i = 0; i < nargs; i++) {
   3336 		    if (argv[i].obj) {
   3337 			transfree(&argv[i].trans);
   3338 		    }
   3339 		}
   3340 		freep((char **) &cargv);
   3341 		transfree(&sqlstr);
   3342 		(*env)->ReleaseStringUTFChars(env, sql, str);
   3343 		sqlite3_finalize((sqlite3_stmt *) svm);
   3344 		setvmerr(env, vm, SQLITE_NOMEM);
   3345 		throwoom(env, "unable to get SQLite handle");
   3346 		return;
   3347 	    }
   3348 	    v->next = h->vms;
   3349 	    h->vms = v;
   3350 	    v->vm = svm;
   3351 	    v->h = h;
   3352 	    v->tail = (char *) (v + 1);
   3353 #if HAVE_BOTH_SQLITE
   3354 	    v->is3 = v->hh.is3 = h->is3;
   3355 #endif
   3356 	    strcpy(v->tail, tail);
   3357 	    sqlite3_free(s);
   3358 	    v->hh.sqlite = 0;
   3359 	    v->hh.haveutf = h->haveutf;
   3360 	    v->hh.ver = h->ver;
   3361 	    v->hh.bh = v->hh.cb = v->hh.ai = v->hh.tr = v->hh.ph = 0;
   3362 	    v->hh.row1 = 1;
   3363 	    v->hh.enc = h->enc;
   3364 	    v->hh.funcs = 0;
   3365 	    v->hh.vms = 0;
   3366 	    v->hh.env = 0;
   3367 	    vv.j = 0;
   3368 	    vv.l = (jobject) v;
   3369 	    (*env)->SetLongField(env, vm, F_SQLite_Vm_handle, vv.j);
   3370 	}
   3371 	for (i = 0; i < nargs; i++) {
   3372 	    if (argv[i].obj) {
   3373 		transfree(&argv[i].trans);
   3374 	    }
   3375 	}
   3376 	freep((char **) &cargv);
   3377 	transfree(&sqlstr);
   3378 	(*env)->ReleaseStringUTFChars(env, sql, str);
   3379 	if (exc) {
   3380 	    (*env)->DeleteLocalRef(env, exc);
   3381 	}
   3382     }
   3383 #endif
   3384 #else
   3385     throwex(env, "unsupported");
   3386 #endif
   3387 }
   3388 
   3389 JNIEXPORT void JNICALL
   3390 Java_SQLite_FunctionContext_internal_1init(JNIEnv *env, jclass cls)
   3391 {
   3392     F_SQLite_FunctionContext_handle =
   3393 	(*env)->GetFieldID(env, cls, "handle", "J");
   3394 }
   3395 
   3396 JNIEXPORT void JNICALL
   3397 Java_SQLite_Database__1progress_1handler(JNIEnv *env, jobject obj, jint n,
   3398 					 jobject ph)
   3399 {
   3400     handle *h = gethandle(env, obj);
   3401 
   3402     if (h && h->sqlite) {
   3403 	/* CHECK THIS */
   3404 #if HAVE_SQLITE_PROGRESS_HANDLER
   3405 	delglobrefp(env, &h->ph);
   3406 #if HAVE_BOTH_SQLITE
   3407 	if (h->is3) {
   3408 	    if (ph) {
   3409 		globrefset(env, ph, &h->ph);
   3410 		sqlite3_progress_handler((sqlite3 *) h->sqlite,
   3411 					 n, progresshandler, h);
   3412 	    } else {
   3413 		sqlite3_progress_handler((sqlite3 *) h->sqlite,
   3414 					 0, 0, 0);
   3415 	    }
   3416 	} else {
   3417 	    if (ph) {
   3418 		globrefset(env, ph, &h->ph);
   3419 		sqlite_progress_handler((sqlite *) h->sqlite,
   3420 					n, progresshandler, h);
   3421 	    } else {
   3422 		sqlite_progress_handler((sqlite *) h->sqlite,
   3423 					0, 0, 0);
   3424 	    }
   3425 	}
   3426 #else
   3427 #if HAVE_SQLITE2
   3428 	if (ph) {
   3429 	    globrefset(env, ph, &h->ph);
   3430 	    sqlite_progress_handler((sqlite *) h->sqlite,
   3431 				    n, progresshandler, h);
   3432 	} else {
   3433 	    sqlite_progress_handler((sqlite *) h->sqlite,
   3434 				    0, 0, 0);
   3435 	}
   3436 #endif
   3437 #if HAVE_SQLITE3
   3438 	if (ph) {
   3439 	    globrefset(env, ph, &h->ph);
   3440 	    sqlite3_progress_handler((sqlite3 *) h->sqlite,
   3441 				     n, progresshandler, h);
   3442 	} else {
   3443 	    sqlite3_progress_handler((sqlite3 *) h->sqlite,
   3444 				     0, 0, 0);
   3445 	}
   3446 #endif
   3447 #endif
   3448 	return;
   3449 #else
   3450 	throwex(env, "unsupported");
   3451 	return;
   3452 #endif
   3453     }
   3454     throwclosed(env);
   3455 }
   3456 
   3457 JNIEXPORT jboolean JNICALL
   3458 Java_SQLite_Database_is3(JNIEnv *env, jobject obj)
   3459 {
   3460 #if HAVE_BOTH_SQLITE
   3461     handle *h = gethandle(env, obj);
   3462 
   3463     if (h) {
   3464 	return h->is3 ? JNI_TRUE : JNI_FALSE;
   3465     }
   3466     return JNI_FALSE;
   3467 #else
   3468 #if HAVE_SQLITE2
   3469     return JNI_FALSE;
   3470 #endif
   3471 #if HAVE_SQLITE3
   3472     return JNI_TRUE;
   3473 #endif
   3474 #endif
   3475 }
   3476 
   3477 JNIEXPORT jboolean JNICALL
   3478 Java_SQLite_Stmt_prepare(JNIEnv *env, jobject obj)
   3479 {
   3480 #if HAVE_SQLITE3
   3481     hvm *v = gethstmt(env, obj);
   3482     void *svm = 0;
   3483     char *tail;
   3484     int ret;
   3485 
   3486     if (v && v->vm) {
   3487 	sqlite3_finalize((sqlite3_stmt *) v->vm);
   3488 	v->vm = 0;
   3489     }
   3490     if (v && v->h && v->h->sqlite) {
   3491 	if (!v->tail) {
   3492 	    return JNI_FALSE;
   3493 	}
   3494 	v->h->env = env;
   3495 #if HAVE_SQLITE3_PREPARE16_V2
   3496 	ret = sqlite3_prepare16_v2((sqlite3 *) v->h->sqlite,
   3497 				   v->tail, -1, (sqlite3_stmt **) &svm,
   3498 				   (const void **) &tail);
   3499 #else
   3500 	ret = sqlite3_prepare16((sqlite3 *) v->h->sqlite,
   3501 				v->tail, -1, (sqlite3_stmt **) &svm,
   3502 				(const void **) &tail);
   3503 #endif
   3504 	if (ret != SQLITE_OK) {
   3505 	    if (svm) {
   3506 		sqlite3_finalize((sqlite3_stmt *) svm);
   3507 		svm = 0;
   3508 	    }
   3509 	}
   3510 	if (ret != SQLITE_OK) {
   3511 	    const char *err = sqlite3_errmsg(v->h->sqlite);
   3512 
   3513 	    setstmterr(env, obj, ret);
   3514 	    v->tail = 0;
   3515 	    throwex(env, err ? err : "error in compile/prepare");
   3516 	    return JNI_FALSE;
   3517 	}
   3518 	if (!svm) {
   3519 	    v->tail = 0;
   3520 	    return JNI_FALSE;
   3521 	}
   3522 	v->vm = svm;
   3523 	v->tail = (char *) tail;
   3524 	v->hh.row1 = 1;
   3525 	return JNI_TRUE;
   3526     }
   3527     throwex(env, "stmt already closed");
   3528 #else
   3529     throwex(env, "unsupported");
   3530 #endif
   3531     return JNI_FALSE;
   3532 }
   3533 
   3534 JNIEXPORT void JNICALL
   3535 Java_SQLite_Database_stmt_1prepare(JNIEnv *env, jobject obj, jstring sql,
   3536 				   jobject stmt)
   3537 {
   3538 #if HAVE_SQLITE3
   3539     handle *h = gethandle(env, obj);
   3540     void *svm = 0;
   3541     hvm *v;
   3542     jvalue vv;
   3543     jsize len16;
   3544     const jchar *sql16, *tail = 0;
   3545     int ret;
   3546 
   3547     if (!h) {
   3548 	throwclosed(env);
   3549 	return;
   3550     }
   3551     if (!stmt) {
   3552 	throwex(env, "null stmt");
   3553 	return;
   3554     }
   3555     if (!sql) {
   3556 	throwex(env, "null sql");
   3557 	return;
   3558     }
   3559 #ifdef HAVE_BOTH_SQLITE
   3560     if (!h->is3) {
   3561 	throwex(env, "only on SQLite3 database");
   3562 	return;
   3563     }
   3564 #endif
   3565     len16 = (*env)->GetStringLength(env, sql) * sizeof (jchar);
   3566     if (len16 < 1) {
   3567 	return;
   3568     }
   3569     h->env = env;
   3570     sql16 = (*env)->GetStringChars(env, sql, 0);
   3571 #if HAVE_SQLITE3_PREPARE16_V2
   3572     ret = sqlite3_prepare16_v2((sqlite3 *) h->sqlite, sql16, len16,
   3573 			       (sqlite3_stmt **) &svm, (const void **) &tail);
   3574 #else
   3575     ret = sqlite3_prepare16((sqlite3 *) h->sqlite, sql16, len16,
   3576 			    (sqlite3_stmt **) &svm, (const void **) &tail);
   3577 #endif
   3578     if (ret != SQLITE_OK) {
   3579 	if (svm) {
   3580 	    sqlite3_finalize((sqlite3_stmt *) svm);
   3581 	    svm = 0;
   3582 	}
   3583     }
   3584     if (ret != SQLITE_OK) {
   3585 	const char *err = sqlite3_errmsg(h->sqlite);
   3586 
   3587 	(*env)->ReleaseStringChars(env, sql, sql16);
   3588 	setstmterr(env, stmt, ret);
   3589 	throwex(env, err ? err : "error in prepare");
   3590 	return;
   3591     }
   3592     if (!svm) {
   3593 	(*env)->ReleaseStringChars(env, sql, sql16);
   3594 	return;
   3595     }
   3596     len16 = len16 + sizeof (jchar) - ((char *) tail - (char *) sql16);
   3597     if (len16 < sizeof (jchar)) {
   3598 	len16 = sizeof (jchar);
   3599     }
   3600     v = malloc(sizeof (hvm) + len16);
   3601     if (!v) {
   3602 	(*env)->ReleaseStringChars(env, sql, sql16);
   3603 	sqlite3_finalize((sqlite3_stmt *) svm);
   3604 	throwoom(env, "unable to get SQLite handle");
   3605 	return;
   3606     }
   3607     v->next = h->vms;
   3608     h->vms = v;
   3609     v->vm = svm;
   3610     v->h = h;
   3611     v->tail = (char *) (v + 1);
   3612 #if HAVE_BOTH_SQLITE
   3613     v->is3 = v->hh.is3 = 1;
   3614 #endif
   3615     memcpy(v->tail, tail, len16);
   3616     len16 /= sizeof (jchar);
   3617     ((jchar *) v->tail)[len16 - 1] = 0;
   3618     (*env)->ReleaseStringChars(env, sql, sql16);
   3619     v->hh.sqlite = 0;
   3620     v->hh.haveutf = h->haveutf;
   3621     v->hh.ver = h->ver;
   3622     v->hh.bh = v->hh.cb = v->hh.ai = v->hh.tr = v->hh.ph = 0;
   3623     v->hh.row1 = 1;
   3624     v->hh.enc = h->enc;
   3625     v->hh.funcs = 0;
   3626     v->hh.vms = 0;
   3627     v->hh.env = 0;
   3628     vv.j = 0;
   3629     vv.l = (jobject) v;
   3630     (*env)->SetLongField(env, stmt, F_SQLite_Stmt_handle, vv.j);
   3631 #else
   3632     throwex(env, "unsupported");
   3633 #endif
   3634 }
   3635 
   3636 JNIEXPORT jboolean JNICALL
   3637 Java_SQLite_Stmt_step(JNIEnv *env, jobject obj)
   3638 {
   3639 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   3640     hvm *v = gethstmt(env, obj);
   3641 
   3642     if (v && v->vm && v->h) {
   3643 	int ret;
   3644 
   3645 	ret = sqlite3_step((sqlite3_stmt *) v->vm);
   3646 	if (ret == SQLITE_ROW) {
   3647 	    return JNI_TRUE;
   3648 	}
   3649 	if (ret != SQLITE_DONE) {
   3650 	    const char *err = sqlite3_errmsg(v->h->sqlite);
   3651 
   3652 	    setstmterr(env, obj, ret);
   3653 	    throwex(env, err ? err : "error in step");
   3654 	}
   3655 	return JNI_FALSE;
   3656     }
   3657     throwex(env, "stmt already closed");
   3658 #else
   3659     throwex(env, "unsupported");
   3660 #endif
   3661     return JNI_FALSE;
   3662 }
   3663 
   3664 JNIEXPORT void JNICALL
   3665 Java_SQLite_Stmt_close(JNIEnv *env, jobject obj)
   3666 {
   3667 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   3668     hvm *v = gethstmt(env, obj);
   3669 
   3670     if (v && v->vm && v->h) {
   3671 	int ret;
   3672 
   3673 	ret = sqlite3_finalize((sqlite3_stmt *) v->vm);
   3674 	v->vm = 0;
   3675 	if (ret != SQLITE_OK) {
   3676 	    const char *err = sqlite3_errmsg(v->h->sqlite);
   3677 
   3678 	    setstmterr(env, obj, ret);
   3679 	    throwex(env, err ? err : "error in close");
   3680 	}
   3681 	return;
   3682     }
   3683     throwex(env, "stmt already closed");
   3684 #else
   3685     throwex(env, "unsupported");
   3686 #endif
   3687     return;
   3688 }
   3689 
   3690 JNIEXPORT void JNICALL
   3691 Java_SQLite_Stmt_reset(JNIEnv *env, jobject obj)
   3692 {
   3693 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   3694     hvm *v = gethstmt(env, obj);
   3695 
   3696     if (v && v->vm && v->h) {
   3697 	sqlite3_reset((sqlite3_stmt *) v->vm);
   3698     } else {
   3699 	throwex(env, "stmt already closed");
   3700     }
   3701 #else
   3702     throwex(env, "unsupported");
   3703 #endif
   3704 }
   3705 
   3706 JNIEXPORT void JNICALL
   3707 Java_SQLite_Stmt_clear_1bindings(JNIEnv *env, jobject obj)
   3708 {
   3709 #if HAVE_SQLITE3 && HAVE_SQLITE3_CLEAR_BINDINGS
   3710     hvm *v = gethstmt(env, obj);
   3711 
   3712     if (v && v->vm && v->h) {
   3713 	sqlite3_clear_bindings((sqlite3_stmt *) v->vm);
   3714     } else {
   3715 	throwex(env, "stmt already closed");
   3716     }
   3717 #else
   3718     throwex(env, "unsupported");
   3719 #endif
   3720 }
   3721 
   3722 JNIEXPORT void JNICALL
   3723 Java_SQLite_Stmt_bind__II(JNIEnv *env, jobject obj, jint pos, jint val)
   3724 {
   3725 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   3726     hvm *v = gethstmt(env, obj);
   3727 
   3728     if (v && v->vm && v->h) {
   3729 	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
   3730 	int ret;
   3731 
   3732 	if (pos < 1 || pos > npar) {
   3733 	    throwex(env, "parameter position out of bounds");
   3734 	    return;
   3735 	}
   3736 	ret = sqlite3_bind_int((sqlite3_stmt *) v->vm, pos, val);
   3737 	if (ret != SQLITE_OK) {
   3738 	    setstmterr(env, obj, ret);
   3739 	    throwex(env, "bind failed");
   3740 	}
   3741     } else {
   3742 	throwex(env, "stmt already closed");
   3743     }
   3744 #else
   3745     throwex(env, "unsupported");
   3746 #endif
   3747 }
   3748 
   3749 JNIEXPORT void JNICALL
   3750 Java_SQLite_Stmt_bind__IJ(JNIEnv *env, jobject obj, jint pos, jlong val)
   3751 {
   3752 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   3753     hvm *v = gethstmt(env, obj);
   3754 
   3755     if (v && v->vm && v->h) {
   3756 	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
   3757 	int ret;
   3758 
   3759 	if (pos < 1 || pos > npar) {
   3760 	    throwex(env, "parameter position out of bounds");
   3761 	    return;
   3762 	}
   3763 	ret = sqlite3_bind_int64((sqlite3_stmt *) v->vm, pos, val);
   3764 	if (ret != SQLITE_OK) {
   3765 	    setstmterr(env, obj, ret);
   3766 	    throwex(env, "bind failed");
   3767 	}
   3768     } else {
   3769 	throwex(env, "stmt already closed");
   3770     }
   3771 #else
   3772     throwex(env, "unsupported");
   3773 #endif
   3774 }
   3775 
   3776 JNIEXPORT void JNICALL
   3777 Java_SQLite_Stmt_bind__ID(JNIEnv *env, jobject obj, jint pos, jdouble val)
   3778 {
   3779 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   3780     hvm *v = gethstmt(env, obj);
   3781 
   3782     if (v && v->vm && v->h) {
   3783 	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
   3784 	int ret;
   3785 
   3786 	if (pos < 1 || pos > npar) {
   3787 	    throwex(env, "parameter position out of bounds");
   3788 	    return;
   3789 	}
   3790 	ret = sqlite3_bind_double((sqlite3_stmt *) v->vm, pos, val);
   3791 	if (ret != SQLITE_OK) {
   3792 	    setstmterr(env, obj, ret);
   3793 	    throwex(env, "bind failed");
   3794 	}
   3795     } else {
   3796 	throwex(env, "stmt already closed");
   3797     }
   3798 #else
   3799     throwex(env, "unsupported");
   3800 #endif
   3801 }
   3802 
   3803 JNIEXPORT void JNICALL
   3804 Java_SQLite_Stmt_bind__I_3B(JNIEnv *env, jobject obj, jint pos, jbyteArray val)
   3805 {
   3806 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   3807     hvm *v = gethstmt(env, obj);
   3808 
   3809     if (v && v->vm && v->h) {
   3810 	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
   3811 	int ret;
   3812 	jint len;
   3813 	char *data = 0;
   3814 
   3815 	if (pos < 1 || pos > npar) {
   3816 	    throwex(env, "parameter position out of bounds");
   3817 	    return;
   3818 	}
   3819 	if (val) {
   3820 	    len = (*env)->GetArrayLength(env, val);
   3821 	    if (len > 0) {
   3822 		data = sqlite3_malloc(len);
   3823 		if (!data) {
   3824 		    throwoom(env, "unable to get blob parameter");
   3825 		    return;
   3826 		}
   3827 		(*env)->GetByteArrayRegion(env, val, 0, len, (jbyte *) data);
   3828 		ret = sqlite3_bind_blob((sqlite3_stmt *) v->vm,
   3829 					pos, data, len, sqlite3_free);
   3830 	    } else {
   3831 		ret = sqlite3_bind_blob((sqlite3_stmt *) v->vm,
   3832 					pos, "", 0, SQLITE_STATIC);
   3833 	    }
   3834 	} else {
   3835 	    ret = sqlite3_bind_null((sqlite3_stmt *) v->vm, pos);
   3836 	}
   3837 	if (ret != SQLITE_OK) {
   3838 	    if (data) {
   3839 		sqlite3_free(data);
   3840 	    }
   3841 	    setstmterr(env, obj, ret);
   3842 	    throwex(env, "bind failed");
   3843 	}
   3844     } else {
   3845 	throwex(env, "stmt already closed");
   3846     }
   3847 #else
   3848     throwex(env, "unsupported");
   3849 #endif
   3850 }
   3851 
   3852 JNIEXPORT void JNICALL
   3853 Java_SQLite_Stmt_bind__ILjava_lang_String_2(JNIEnv *env, jobject obj,
   3854 					    jint pos, jstring val)
   3855 {
   3856 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   3857     hvm *v = gethstmt(env, obj);
   3858 
   3859     if (v && v->vm && v->h) {
   3860 	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
   3861 	int ret;
   3862 	jsize len, count;
   3863 	char *data = 0;
   3864 
   3865 	if (pos < 1 || pos > npar) {
   3866 	    throwex(env, "parameter position out of bounds");
   3867 	    return;
   3868 	}
   3869 	if (val) {
   3870 	    count = (*env)->GetStringLength(env, val);
   3871 	    len = count * sizeof (jchar);
   3872 	    if (len > 0) {
   3873 #ifndef JNI_VERSION_1_2
   3874 		const jchar *ch;
   3875 #endif
   3876 		data = sqlite3_malloc(len);
   3877 		if (!data) {
   3878 		    throwoom(env, "unable to get blob parameter");
   3879 		    return;
   3880 		}
   3881 #ifndef JNI_VERSION_1_2
   3882 		ch = (*env)->GetStringChars(env, val, 0);
   3883 		memcpy(data, ch, len);
   3884 		(*env)->ReleaseStringChars(env, val, ch);
   3885 #else
   3886 		(*env)->GetStringRegion(env, val, 0, count, (jchar *) data);
   3887 #endif
   3888 		ret = sqlite3_bind_text16((sqlite3_stmt *) v->vm,
   3889 					  pos, data, len, sqlite3_free);
   3890 	    } else {
   3891 		ret = sqlite3_bind_text16((sqlite3_stmt *) v->vm, pos, "", 0,
   3892 					  SQLITE_STATIC);
   3893 	    }
   3894 	} else {
   3895 	    ret = sqlite3_bind_null((sqlite3_stmt *) v->vm, pos);
   3896 	}
   3897 	if (ret != SQLITE_OK) {
   3898 	    if (data) {
   3899 		sqlite3_free(data);
   3900 	    }
   3901 	    setstmterr(env, obj, ret);
   3902 	    throwex(env, "bind failed");
   3903 	}
   3904     } else {
   3905 	throwex(env, "stmt already closed");
   3906     }
   3907 #else
   3908     throwex(env, "unsupported");
   3909 #endif
   3910 }
   3911 
   3912 JNIEXPORT void JNICALL
   3913 Java_SQLite_Stmt_bind__I(JNIEnv *env, jobject obj, jint pos)
   3914 {
   3915 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   3916     hvm *v = gethstmt(env, obj);
   3917 
   3918     if (v && v->vm && v->h) {
   3919 	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
   3920 	int ret;
   3921 
   3922 	if (pos < 1 || pos > npar) {
   3923 	    throwex(env, "parameter position out of bounds");
   3924 	    return;
   3925 	}
   3926 	ret = sqlite3_bind_null((sqlite3_stmt *) v->vm, pos);
   3927 	if (ret != SQLITE_OK) {
   3928 	    setstmterr(env, obj, ret);
   3929 	    throwex(env, "bind failed");
   3930 	}
   3931     } else {
   3932 	throwex(env, "stmt already closed");
   3933     }
   3934 #else
   3935     throwex(env, "unsupported");
   3936 #endif
   3937 }
   3938 
   3939 JNIEXPORT void JNICALL
   3940 Java_SQLite_Stmt_bind_1zeroblob(JNIEnv *env, jobject obj, jint pos, jint len)
   3941 {
   3942 #if HAVE_SQLITE3 && HAVE_SQLITE3_BIND_ZEROBLOB
   3943     hvm *v = gethstmt(env, obj);
   3944 
   3945     if (v && v->vm && v->h) {
   3946 	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
   3947 	int ret;
   3948 
   3949 	if (pos < 1 || pos > npar) {
   3950 	    throwex(env, "parameter position out of bounds");
   3951 	    return;
   3952 	}
   3953 	ret = sqlite3_bind_zeroblob((sqlite3_stmt *) v->vm, pos, len);
   3954 	if (ret != SQLITE_OK) {
   3955 	    setstmterr(env, obj, ret);
   3956 	    throwex(env, "bind failed");
   3957 	}
   3958     } else {
   3959 	throwex(env, "stmt already closed");
   3960     }
   3961 #else
   3962     throwex(env, "unsupported");
   3963 #endif
   3964 }
   3965 
   3966 JNIEXPORT jint JNICALL
   3967 Java_SQLite_Stmt_bind_1parameter_1count(JNIEnv *env, jobject obj)
   3968 {
   3969 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   3970     hvm *v = gethstmt(env, obj);
   3971 
   3972     if (v && v->vm && v->h) {
   3973 	return sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
   3974     }
   3975     throwex(env, "stmt already closed");
   3976 #else
   3977     throwex(env, "unsupported");
   3978 #endif
   3979     return 0;
   3980 }
   3981 
   3982 JNIEXPORT jstring JNICALL
   3983 Java_SQLite_Stmt_bind_1parameter_1name(JNIEnv *env, jobject obj, jint pos)
   3984 {
   3985 #if HAVE_SQLITE3 && HAVE_SQLITE3_BIND_PARAMETER_NAME
   3986     hvm *v = gethstmt(env, obj);
   3987 
   3988     if (v && v->vm && v->h) {
   3989 	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
   3990 	const char *name;
   3991 
   3992 	if (pos < 1 || pos > npar) {
   3993 	    throwex(env, "parameter position out of bounds");
   3994 	    return 0;
   3995 	}
   3996 	name = sqlite3_bind_parameter_name((sqlite3_stmt *) v->vm, pos);
   3997 	if (name) {
   3998 	    return (*env)->NewStringUTF(env, name);
   3999 	}
   4000     } else {
   4001 	throwex(env, "stmt already closed");
   4002     }
   4003 #else
   4004     throwex(env, "unsupported");
   4005 #endif
   4006     return 0;
   4007 }
   4008 
   4009 JNIEXPORT jint JNICALL
   4010 Java_SQLite_Stmt_bind_1parameter_1index(JNIEnv *env, jobject obj,
   4011 					jstring name)
   4012 {
   4013 #if HAVE_SQLITE3 && HAVE_SQLITE3_BIND_PARAMETER_INDEX
   4014     hvm *v = gethstmt(env, obj);
   4015 
   4016     if (v && v->vm && v->h) {
   4017 	int pos;
   4018 	const char *n;
   4019 	transstr namestr;
   4020 	jthrowable exc;
   4021 
   4022 	n = trans2iso(env, 1, 0, name, &namestr);
   4023 	exc = (*env)->ExceptionOccurred(env);
   4024 	if (exc) {
   4025 	    (*env)->DeleteLocalRef(env, exc);
   4026 	    return -1;
   4027 	}
   4028 	pos = sqlite3_bind_parameter_index((sqlite3_stmt *) v->vm, n);
   4029 	transfree(&namestr);
   4030 	return pos;
   4031     } else {
   4032 	throwex(env, "stmt already closed");
   4033     }
   4034 #else
   4035     throwex(env, "unsupported");
   4036 #endif
   4037     return -1;
   4038 }
   4039 
   4040 JNIEXPORT jint JNICALL
   4041 Java_SQLite_Stmt_column_1int(JNIEnv *env, jobject obj, jint col)
   4042 {
   4043 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   4044     hvm *v = gethstmt(env, obj);
   4045 
   4046     if (v && v->vm && v->h) {
   4047 	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
   4048 
   4049 	if (col < 0 || col >= ncol) {
   4050 	    throwex(env, "column out of bounds");
   4051 	    return 0;
   4052 	}
   4053 	return sqlite3_column_int((sqlite3_stmt *) v->vm, col);
   4054     }
   4055     throwex(env, "stmt already closed");
   4056 #else
   4057     throwex(env, "unsupported");
   4058 #endif
   4059     return 0;
   4060 }
   4061 
   4062 JNIEXPORT jlong JNICALL
   4063 Java_SQLite_Stmt_column_1long(JNIEnv *env, jobject obj, jint col)
   4064 {
   4065 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   4066     hvm *v = gethstmt(env, obj);
   4067 
   4068     if (v && v->vm && v->h) {
   4069 	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
   4070 
   4071 	if (col < 0 || col >= ncol) {
   4072 	    throwex(env, "column out of bounds");
   4073 	    return 0;
   4074 	}
   4075 	return sqlite3_column_int64((sqlite3_stmt *) v->vm, col);
   4076     }
   4077     throwex(env, "stmt already closed");
   4078 #else
   4079     throwex(env, "unsupported");
   4080 #endif
   4081     return 0;
   4082 }
   4083 
   4084 JNIEXPORT jdouble JNICALL
   4085 Java_SQLite_Stmt_column_1double(JNIEnv *env, jobject obj, jint col)
   4086 {
   4087 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   4088     hvm *v = gethstmt(env, obj);
   4089 
   4090     if (v && v->vm && v->h) {
   4091 	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
   4092 
   4093 	if (col < 0 || col >= ncol) {
   4094 	    throwex(env, "column out of bounds");
   4095 	    return 0;
   4096 	}
   4097 	return sqlite3_column_double((sqlite3_stmt *) v->vm, col);
   4098     }
   4099     throwex(env, "stmt already closed");
   4100 #else
   4101     throwex(env, "unsupported");
   4102 #endif
   4103     return 0;
   4104 }
   4105 
   4106 JNIEXPORT jbyteArray JNICALL
   4107 Java_SQLite_Stmt_column_1bytes(JNIEnv *env, jobject obj, jint col)
   4108 {
   4109 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   4110     hvm *v = gethstmt(env, obj);
   4111 
   4112     if (v && v->vm && v->h) {
   4113 	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
   4114 	int nbytes;
   4115 	const jbyte *data;
   4116 	jbyteArray b = 0;
   4117 
   4118 	if (col < 0 || col >= ncol) {
   4119 	    throwex(env, "column out of bounds");
   4120 	    return 0;
   4121 	}
   4122 	data = sqlite3_column_blob((sqlite3_stmt *) v->vm, col);
   4123 	if (data) {
   4124 	    nbytes = sqlite3_column_bytes((sqlite3_stmt *) v->vm, col);
   4125 	} else {
   4126 	    return 0;
   4127 	}
   4128 	b = (*env)->NewByteArray(env, nbytes);
   4129 	if (!b) {
   4130 	    throwoom(env, "unable to get blob column data");
   4131 	    return 0;
   4132 	}
   4133 	(*env)->SetByteArrayRegion(env, b, 0, nbytes, data);
   4134 	return b;
   4135     }
   4136     throwex(env, "stmt already closed");
   4137 #else
   4138     throwex(env, "unsupported");
   4139 #endif
   4140     return 0;
   4141 }
   4142 
   4143 JNIEXPORT jstring JNICALL
   4144 Java_SQLite_Stmt_column_1string(JNIEnv *env, jobject obj, jint col)
   4145 {
   4146 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   4147     hvm *v = gethstmt(env, obj);
   4148 
   4149     if (v && v->vm && v->h) {
   4150 	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
   4151 	int nbytes;
   4152 	const jchar *data;
   4153 	jstring b = 0;
   4154 
   4155 	if (col < 0 || col >= ncol) {
   4156 	    throwex(env, "column out of bounds");
   4157 	    return 0;
   4158 	}
   4159 	data = sqlite3_column_text16((sqlite3_stmt *) v->vm, col);
   4160 	if (data) {
   4161 	    nbytes = sqlite3_column_bytes16((sqlite3_stmt *) v->vm, col);
   4162 	} else {
   4163 	    return 0;
   4164 	}
   4165 	nbytes /= sizeof (jchar);
   4166 	b = (*env)->NewString(env, data, nbytes);
   4167 	if (!b) {
   4168 	    throwoom(env, "unable to get string column data");
   4169 	    return 0;
   4170 	}
   4171 	return b;
   4172     }
   4173     throwex(env, "stmt already closed");
   4174 #else
   4175     throwex(env, "unsupported");
   4176 #endif
   4177     return 0;
   4178 }
   4179 
   4180 JNIEXPORT jint JNICALL
   4181 Java_SQLite_Stmt_column_1type(JNIEnv *env, jobject obj, jint col)
   4182 {
   4183 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   4184     hvm *v = gethstmt(env, obj);
   4185 
   4186     if (v && v->vm && v->h) {
   4187 	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
   4188 
   4189 	if (col < 0 || col >= ncol) {
   4190 	    throwex(env, "column out of bounds");
   4191 	    return 0;
   4192 	}
   4193 	return sqlite3_column_type((sqlite3_stmt *) v->vm, col);
   4194     }
   4195     throwex(env, "stmt already closed");
   4196 #else
   4197     throwex(env, "unsupported");
   4198 #endif
   4199     return 0;
   4200 }
   4201 
   4202 JNIEXPORT jint JNICALL
   4203 Java_SQLite_Stmt_column_1count(JNIEnv *env, jobject obj)
   4204 {
   4205 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   4206     hvm *v = gethstmt(env, obj);
   4207 
   4208     if (v && v->vm && v->h) {
   4209 	return sqlite3_column_count((sqlite3_stmt *) v->vm);
   4210     }
   4211     throwex(env, "stmt already closed");
   4212 #else
   4213     throwex(env, "unsupported");
   4214 #endif
   4215     return 0;
   4216 }
   4217 
   4218 JNIEXPORT jstring JNICALL
   4219 Java_SQLite_Stmt_column_1table_1name(JNIEnv *env, jobject obj, jint col)
   4220 {
   4221 #if HAVE_SQLITE3 && HAVE_SQLITE3_COLUMN_TABLE_NAME16
   4222     hvm *v = gethstmt(env, obj);
   4223 
   4224     if (v && v->vm && v->h) {
   4225 	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
   4226 	const jchar *str;
   4227 
   4228 	if (col < 0 || col >= ncol) {
   4229 	    throwex(env, "column out of bounds");
   4230 	    return 0;
   4231 	}
   4232 	str = sqlite3_column_table_name16((sqlite3_stmt *) v->vm, col);
   4233 	if (str) {
   4234 	    return (*env)->NewString(env, str, jstrlen(str));
   4235 	}
   4236 	return 0;
   4237     }
   4238     throwex(env, "stmt already closed");
   4239 #else
   4240     throwex(env, "unsupported");
   4241 #endif
   4242     return 0;
   4243 }
   4244 
   4245 JNIEXPORT jstring JNICALL
   4246 Java_SQLite_Stmt_column_1database_1name(JNIEnv *env, jobject obj, jint col)
   4247 {
   4248 #if HAVE_SQLITE3 && HAVE_SQLITE3_COLUMN_DATABASE_NAME16
   4249     hvm *v = gethstmt(env, obj);
   4250 
   4251     if (v && v->vm && v->h) {
   4252 	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
   4253 	const jchar *str;
   4254 
   4255 	if (col < 0 || col >= ncol) {
   4256 	    throwex(env, "column out of bounds");
   4257 	    return 0;
   4258 	}
   4259 	str = sqlite3_column_database_name16((sqlite3_stmt *) v->vm, col);
   4260 	if (str) {
   4261 	    return (*env)->NewString(env, str, jstrlen(str));
   4262 	}
   4263 	return 0;
   4264     }
   4265     throwex(env, "stmt already closed");
   4266 #else
   4267     throwex(env, "unsupported");
   4268 #endif
   4269     return 0;
   4270 }
   4271 
   4272 JNIEXPORT jstring JNICALL
   4273 Java_SQLite_Stmt_column_1decltype(JNIEnv *env, jobject obj, jint col)
   4274 {
   4275 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   4276     hvm *v = gethstmt(env, obj);
   4277 
   4278     if (v && v->vm && v->h) {
   4279 	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
   4280 	const jchar *str;
   4281 
   4282 	if (col < 0 || col >= ncol) {
   4283 	    throwex(env, "column out of bounds");
   4284 	    return 0;
   4285 	}
   4286 	str = sqlite3_column_decltype16((sqlite3_stmt *) v->vm, col);
   4287 	if (str) {
   4288 	    return (*env)->NewString(env, str, jstrlen(str));
   4289 	}
   4290 	return 0;
   4291     }
   4292     throwex(env, "stmt already closed");
   4293 #else
   4294     throwex(env, "unsupported");
   4295 #endif
   4296     return 0;
   4297 }
   4298 
   4299 JNIEXPORT jstring JNICALL
   4300 Java_SQLite_Stmt_column_1origin_1name(JNIEnv *env, jobject obj, jint col)
   4301 {
   4302 #if HAVE_SQLITE3 && HAVE_SQLITE3_COLUMN_ORIGIN_NAME16
   4303     hvm *v = gethstmt(env, obj);
   4304 
   4305     if (v && v->vm && v->h) {
   4306 	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
   4307 	const jchar *str;
   4308 
   4309 	if (col < 0 || col >= ncol) {
   4310 	    throwex(env, "column out of bounds");
   4311 	    return 0;
   4312 	}
   4313 	str = sqlite3_column_origin_name16((sqlite3_stmt *) v->vm, col);
   4314 	if (str) {
   4315 	    return (*env)->NewString(env, str, jstrlen(str));
   4316 	}
   4317 	return 0;
   4318     }
   4319     throwex(env, "stmt already closed");
   4320 #else
   4321     throwex(env, "unsupported");
   4322 #endif
   4323     return 0;
   4324 }
   4325 
   4326 JNIEXPORT jint JNICALL
   4327 Java_SQLite_Stmt_status(JNIEnv *env, jobject obj, jint op, jboolean flg)
   4328 {
   4329     jint count = 0;
   4330 #if HAVE_SQLITE3 && HAVE_SQLITE3_STMT_STATUS
   4331     hvm *v = gethstmt(env, obj);
   4332 
   4333     if (v && v->vm && v->h) {
   4334 	count = sqlite3_stmt_status((sqlite3_stmt *) v->vm, op,
   4335 				    flg == JNI_TRUE);
   4336     }
   4337 #endif
   4338     return count;
   4339 }
   4340 
   4341 JNIEXPORT void JNICALL
   4342 Java_SQLite_Stmt_finalize(JNIEnv *env, jobject obj)
   4343 {
   4344 #if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
   4345     dostmtfinal(env, obj);
   4346 #endif
   4347 }
   4348 
   4349 JNIEXPORT void JNICALL
   4350 Java_SQLite_Database__1open_1blob(JNIEnv *env, jobject obj,
   4351 				  jstring dbname, jstring table,
   4352 				  jstring column, jlong row,
   4353 				  jboolean rw, jobject blobj)
   4354 {
   4355 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
   4356     handle *h = gethandle(env, obj);
   4357     hbl *bl;
   4358     jthrowable exc;
   4359     transstr dbn, tbl, col;
   4360     sqlite3_blob *blob;
   4361     jvalue vv;
   4362     int ret;
   4363 
   4364     if (!blobj) {
   4365 	throwex(env, "null blob");
   4366 	return;
   4367     }
   4368 #if HAVE_BOTH_SQLITE
   4369     if (!h->is3) {
   4370 	throwex(env, "not a SQLite 3 database");
   4371 	return;
   4372     }
   4373 #endif
   4374     if (h && h->sqlite) {
   4375 	trans2iso(env, h->haveutf, h->enc, dbname, &dbn);
   4376 	exc = (*env)->ExceptionOccurred(env);
   4377 	if (exc) {
   4378 	    (*env)->DeleteLocalRef(env, exc);
   4379 	    return;
   4380 	}
   4381 	trans2iso(env, h->haveutf, h->enc, table, &tbl);
   4382 	exc = (*env)->ExceptionOccurred(env);
   4383 	if (exc) {
   4384 	    transfree(&dbn);
   4385 	    (*env)->DeleteLocalRef(env, exc);
   4386 	    return;
   4387 	}
   4388 	trans2iso(env, h->haveutf, h->enc, column, &col);
   4389 	exc = (*env)->ExceptionOccurred(env);
   4390 	if (exc) {
   4391 	    transfree(&tbl);
   4392 	    transfree(&dbn);
   4393 	    (*env)->DeleteLocalRef(env, exc);
   4394 	    return;
   4395 	}
   4396 	ret = sqlite3_blob_open(h->sqlite,
   4397 				dbn.result, tbl.result, col.result,
   4398 				row, rw, &blob);
   4399 	transfree(&col);
   4400 	transfree(&tbl);
   4401 	transfree(&dbn);
   4402 	if (ret != SQLITE_OK) {
   4403 	    const char *err = sqlite3_errmsg(h->sqlite);
   4404 
   4405 	    seterr(env, obj, ret);
   4406 	    throwex(env, err ? err : "error in blob open");
   4407 	    return;
   4408 	}
   4409 	bl = malloc(sizeof (hbl));
   4410 	if (!bl) {
   4411 	    sqlite3_blob_close(blob);
   4412 	    throwoom(env, "unable to get SQLite blob handle");
   4413 	    return;
   4414 	}
   4415 	bl->next = h->blobs;
   4416 	h->blobs = bl;
   4417 	bl->blob = blob;
   4418 	bl->h = h;
   4419 	vv.j = 0;
   4420 	vv.l = (jobject) bl;
   4421 	(*env)->SetLongField(env, blobj, F_SQLite_Blob_handle, vv.j);
   4422 	(*env)->SetIntField(env, blobj, F_SQLite_Blob_size,
   4423 			    sqlite3_blob_bytes(blob));
   4424 	return;
   4425     }
   4426     throwex(env, "not an open database");
   4427 #else
   4428     throwex(env, "unsupported");
   4429 #endif
   4430 }
   4431 
   4432 JNIEXPORT jint JNICALL
   4433 Java_SQLite_Blob_write(JNIEnv *env , jobject obj, jbyteArray b, jint off,
   4434 		       jint pos, jint len)
   4435 {
   4436 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
   4437     hbl *bl = gethbl(env, obj);
   4438 
   4439     if (bl && bl->h && bl->blob) {
   4440 	jbyte *buf;
   4441 	jthrowable exc;
   4442 	int ret;
   4443 
   4444 	if (len <= 0) {
   4445 	    return 0;
   4446 	}
   4447 	buf = malloc(len);
   4448 	if (!buf) {
   4449 	    throwoom(env, "out of buffer space for blob");
   4450 	    return 0;
   4451 	}
   4452 	(*env)->GetByteArrayRegion(env, b, off, len, buf);
   4453 	exc = (*env)->ExceptionOccurred(env);
   4454 	if (exc) {
   4455 	    free(buf);
   4456 	    return 0;
   4457 	}
   4458 	ret = sqlite3_blob_write(bl->blob, buf, len, pos);
   4459 	free(buf);
   4460 	if (ret != SQLITE_OK) {
   4461 	    throwioex(env, "blob write error");
   4462 	    return 0;
   4463 	}
   4464 	return len;
   4465     }
   4466     throwex(env, "blob already closed");
   4467 #else
   4468     throwex(env, "unsupported");
   4469 #endif
   4470     return 0;
   4471 }
   4472 
   4473 JNIEXPORT jint JNICALL
   4474 Java_SQLite_Blob_read(JNIEnv *env , jobject obj, jbyteArray b, jint off,
   4475 		      jint pos, jint len)
   4476 {
   4477 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
   4478     hbl *bl = gethbl(env, obj);
   4479 
   4480     if (bl && bl->h && bl->blob) {
   4481 	jbyte *buf;
   4482 	jthrowable exc;
   4483 	int ret;
   4484 
   4485 	if (len <= 0) {
   4486 	    return 0;
   4487 	}
   4488 	buf = malloc(len);
   4489 	if (!buf) {
   4490 	    throwoom(env, "out of buffer space for blob");
   4491 	    return 0;
   4492 	}
   4493 	ret = sqlite3_blob_read(bl->blob, buf, len, pos);
   4494 	if (ret != SQLITE_OK) {
   4495 	    free(buf);
   4496 	    throwioex(env, "blob read error");
   4497 	    return 0;
   4498 	}
   4499 	(*env)->SetByteArrayRegion(env, b, off, len, buf);
   4500 	free(buf);
   4501 	exc = (*env)->ExceptionOccurred(env);
   4502 	if (exc) {
   4503 	    return 0;
   4504 	}
   4505 	return len;
   4506     }
   4507     throwex(env, "blob already closed");
   4508 #else
   4509     throwex(env, "unsupported");
   4510 #endif
   4511     return 0;
   4512 }
   4513 
   4514 JNIEXPORT void JNICALL
   4515 Java_SQLite_Blob_close(JNIEnv *env, jobject obj)
   4516 {
   4517 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
   4518     doblobfinal(env, obj);
   4519 #endif
   4520 }
   4521 
   4522 JNIEXPORT void JNICALL
   4523 Java_SQLite_Blob_finalize(JNIEnv *env, jobject obj)
   4524 {
   4525 #if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
   4526     doblobfinal(env, obj);
   4527 #endif
   4528 }
   4529 
   4530 JNIEXPORT void
   4531 JNICALL Java_SQLite_Database__1key(JNIEnv *env, jobject obj, jbyteArray key)
   4532 {
   4533     jsize len;
   4534     jbyte *data;
   4535 #if HAVE_SQLITE3_KEY
   4536     handle *h = gethandle(env, obj);
   4537 #endif
   4538 
   4539     len = (*env)->GetArrayLength(env, key);
   4540     data = (*env)->GetByteArrayElements(env, key, 0);
   4541     if (len == 0) {
   4542 	data = 0;
   4543     }
   4544     if (!data) {
   4545 	len = 0;
   4546     }
   4547 #if HAVE_SQLITE3_KEY
   4548     if (h && h->sqlite) {
   4549 #if HAVE_BOTH_SQLITE
   4550 	if (!h->is3) {
   4551 	    if (data) {
   4552 		memset(data, 0, len);
   4553 	    }
   4554 	    throwex(env, "unsupported");
   4555 	}
   4556 #endif
   4557 	sqlite3_key((sqlite3 *) h->sqlite, data, len);
   4558 	if (data) {
   4559 	    memset(data, 0, len);
   4560 	}
   4561     } else {
   4562 	if (data) {
   4563 	    memset(data, 0, len);
   4564 	}
   4565 	throwclosed(env);
   4566     }
   4567 #else
   4568     if (data) {
   4569 	memset(data, 0, len);
   4570     }
   4571     /* no error */
   4572 #endif
   4573 }
   4574 
   4575 JNIEXPORT void JNICALL
   4576 Java_SQLite_Database__1rekey(JNIEnv *env, jobject obj, jbyteArray key)
   4577 {
   4578     jsize len;
   4579     jbyte *data;
   4580 #if HAVE_SQLITE3_KEY
   4581     handle *h = gethandle(env, obj);
   4582 #endif
   4583 
   4584     len = (*env)->GetArrayLength(env, key);
   4585     data = (*env)->GetByteArrayElements(env, key, 0);
   4586     if (len == 0) {
   4587 	data = 0;
   4588     }
   4589     if (!data) {
   4590 	len = 0;
   4591     }
   4592 #if HAVE_SQLITE3_KEY
   4593     if (h && h->sqlite) {
   4594 #if HAVE_BOTH_SQLITE
   4595 	if (!h->is3) {
   4596 	    if (data) {
   4597 		memset(data, 0, len);
   4598 	    }
   4599 	    throwex(env, "unsupported");
   4600 	}
   4601 #endif
   4602 	sqlite3_rekey((sqlite3 *) h->sqlite, data, len);
   4603 	if (data) {
   4604 	    memset(data, 0, len);
   4605 	}
   4606     } else {
   4607 	if (data) {
   4608 	    memset(data, 0, len);
   4609 	}
   4610 	throwclosed(env);
   4611     }
   4612 #else
   4613     if (data) {
   4614 	memset(data, 0, len);
   4615     }
   4616     throwex(env, "unsupported");
   4617 #endif
   4618 }
   4619 
   4620 JNIEXPORT jboolean JNICALL
   4621 Java_SQLite_Database__1enable_1shared_1cache(JNIEnv *env, jclass cls,
   4622 					     jboolean onoff)
   4623 {
   4624 #if HAVE_SQLITE3_SHARED_CACHE
   4625     return (sqlite3_enable_shared_cache(onoff == JNI_TRUE) == SQLITE_OK) ?
   4626 	   JNI_TRUE : JNI_FALSE;
   4627 #else
   4628     return JNI_FALSE;
   4629 #endif
   4630 }
   4631 
   4632 
   4633 JNIEXPORT void JNICALL
   4634 Java_SQLite_Database__1backup(JNIEnv *env, jclass cls, jobject bkupj,
   4635 			      jobject dest, jstring destName,
   4636 			      jobject src, jstring srcName)
   4637 {
   4638 #if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
   4639     handle *hsrc = gethandle(env, src);
   4640     handle *hdest = gethandle(env, dest);
   4641     hbk *bk;
   4642     jthrowable exc;
   4643     transstr dbns, dbnd;
   4644     sqlite3_backup *bkup;
   4645     jvalue vv;
   4646 
   4647     if (!bkupj) {
   4648 	throwex(env, "null backup");
   4649 	return;
   4650     }
   4651     if (!hsrc) {
   4652 	throwex(env, "no source database");
   4653 	return;
   4654     }
   4655     if (!hdest) {
   4656 	throwex(env, "no destination database");
   4657 	return;
   4658     }
   4659 #if HAVE_BOTH_SQLITE
   4660     if (!hsrc->is3 || !hdest->is3) {
   4661 	throwex(env, "not a SQLite 3 database");
   4662 	return;
   4663     }
   4664 #endif
   4665     if (!hsrc->sqlite) {
   4666 	throwex(env, "source database not open");
   4667 	return;
   4668     }
   4669     if (!hdest->sqlite) {
   4670 	throwex(env, "destination database not open");
   4671 	return;
   4672     }
   4673     trans2iso(env, hdest->haveutf, hdest->enc, destName, &dbnd);
   4674     exc = (*env)->ExceptionOccurred(env);
   4675     if (exc) {
   4676 	(*env)->DeleteLocalRef(env, exc);
   4677 	return;
   4678     }
   4679     trans2iso(env, hsrc->haveutf, hsrc->enc, srcName, &dbns);
   4680     exc = (*env)->ExceptionOccurred(env);
   4681     if (exc) {
   4682 	transfree(&dbnd);
   4683 	(*env)->DeleteLocalRef(env, exc);
   4684 	return;
   4685     }
   4686     bkup = sqlite3_backup_init((sqlite3 *) hdest->sqlite, dbnd.result,
   4687 			       (sqlite3 *) hsrc->sqlite, dbns.result);
   4688     transfree(&dbnd);
   4689     transfree(&dbns);
   4690     if (!bkup) {
   4691 	const char *err = sqlite3_errmsg((sqlite3 *) hdest->sqlite);
   4692 
   4693 	seterr(env, src, sqlite3_errcode((sqlite3 *) hdest->sqlite));
   4694 	throwex(env, err ? err : "error in backup init");
   4695 	return;
   4696     }
   4697     bk = malloc(sizeof (hbk));
   4698     if (!bk) {
   4699 	sqlite3_backup_finish(bkup);
   4700 	throwoom(env, "unable to get SQLite backup handle");
   4701 	return;
   4702     }
   4703     bk->next = hsrc->backups;
   4704     hsrc->backups = bk;
   4705     bk->bkup = bkup;
   4706     bk->h = hsrc;
   4707     vv.j = 0;
   4708     vv.l = (jobject) bk;
   4709     (*env)->SetLongField(env, bkupj, F_SQLite_Backup_handle, vv.j);
   4710     return;
   4711 #else
   4712     throwex(env, "unsupported");
   4713 #endif
   4714 }
   4715 
   4716 JNIEXPORT void JNICALL
   4717 Java_SQLite_Backup__1finalize(JNIEnv *env, jobject obj)
   4718 {
   4719 #if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
   4720     hbk *bk = gethbk(env, obj);
   4721     int ret = SQLITE_OK;
   4722     char *err = 0;
   4723 
   4724     if (bk) {
   4725 	if (bk->h) {
   4726 	    handle *h = bk->h;
   4727 	    hbk *bkc, **bkp;
   4728 
   4729 	    bkp = &h->backups;
   4730 	    bkc = *bkp;
   4731 	    while (bkc) {
   4732 		if (bkc == bk) {
   4733 		    *bkp = bkc->next;
   4734 		    break;
   4735 		}
   4736 		bkp = &bkc->next;
   4737 		bkc = *bkp;
   4738 	    }
   4739 	}
   4740 	if (bk->bkup) {
   4741 	    ret = sqlite3_backup_finish(bk->bkup);
   4742 	    if (ret != SQLITE_OK && bk->h) {
   4743 		err = (char *) sqlite3_errmsg((sqlite3 *) bk->h->sqlite);
   4744 	    }
   4745 	}
   4746 	bk->bkup = 0;
   4747 	free(bk);
   4748 	(*env)->SetLongField(env, obj, F_SQLite_Backup_handle, 0);
   4749 	if (ret != SQLITE_OK) {
   4750 	    throwex(env, err ? err : "unknown error");
   4751 	}
   4752     }
   4753 #endif
   4754 }
   4755 
   4756 JNIEXPORT jboolean JNICALL
   4757 Java_SQLite_Backup__1step(JNIEnv *env, jobject obj, jint n)
   4758 {
   4759     jboolean result = JNI_TRUE;
   4760 #if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
   4761     hbk *bk = gethbk(env, obj);
   4762     int ret;
   4763 
   4764     if (bk) {
   4765 	if (bk->bkup) {
   4766 	    ret = sqlite3_backup_step(bk->bkup, (int) n);
   4767 	    switch (ret) {
   4768 	    case SQLITE_DONE:
   4769 		break;
   4770 	    case SQLITE_LOCKED:
   4771 	    case SQLITE_BUSY:
   4772 	    case SQLITE_OK:
   4773 		result = JNI_FALSE;
   4774 		break;
   4775 	    default:
   4776 		result = JNI_FALSE;
   4777 		throwex(env, "backup step failed");
   4778 		break;
   4779 	    }
   4780 	}
   4781     } else {
   4782 	throwex(env, "stale backup object");
   4783     }
   4784 #else
   4785     throwex(env, "unsupported");
   4786 #endif
   4787     return result;
   4788 }
   4789 
   4790 JNIEXPORT jint JNICALL
   4791 Java_SQLite_Backup__1remaining(JNIEnv *env, jobject obj)
   4792 {
   4793     jint result = 0;
   4794 #if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
   4795     hbk *bk = gethbk(env, obj);
   4796 
   4797     if (bk) {
   4798 	if (bk->bkup) {
   4799 	    result = sqlite3_backup_remaining(bk->bkup);
   4800 	}
   4801     }
   4802 #else
   4803     throwex(env, "unsupported");
   4804 #endif
   4805     return result;
   4806 }
   4807 
   4808 JNIEXPORT jint JNICALL
   4809 Java_SQLite_Backup__1pagecount(JNIEnv *env, jobject obj)
   4810 {
   4811     jint result = 0;
   4812 #if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
   4813     hbk *bk = gethbk(env, obj);
   4814 
   4815     if (bk) {
   4816 	if (bk->bkup) {
   4817 	    result = sqlite3_backup_pagecount(bk->bkup);
   4818 	}
   4819     }
   4820 #else
   4821     throwex(env, "unsupported");
   4822 #endif
   4823     return result;
   4824 }
   4825 
   4826 #if HAVE_SQLITE3_PROFILE
   4827 static void
   4828 doprofile(void *arg, const char *msg, sqlite_uint64 est)
   4829 {
   4830     handle *h = (handle *) arg;
   4831     JNIEnv *env = h->env;
   4832 
   4833     if (env && h->pr && msg) {
   4834 	jthrowable exc;
   4835 	jclass cls = (*env)->GetObjectClass(env, h->pr);
   4836 	jmethodID mid;
   4837 
   4838 	mid = (*env)->GetMethodID(env, cls, "profile",
   4839 				  "(Ljava/lang/String;J)V");
   4840 	if (mid) {
   4841 	    transstr tr;
   4842 #if _MSC_VER && (_MSC_VER < 1300)
   4843 	    jlong ms = est / (3600i64 * 24i64 * 1000i64);
   4844 #else
   4845 	    jlong ms = est / (3600LL * 24LL * 1000LL);
   4846 #endif
   4847 
   4848 	    trans2utf(env, h->haveutf, h->enc, msg, &tr);
   4849 	    exc = (*env)->ExceptionOccurred(env);
   4850 	    if (exc) {
   4851 		(*env)->DeleteLocalRef(env, exc);
   4852 		(*env)->ExceptionClear(env);
   4853 		return;
   4854 	    }
   4855 	    (*env)->CallVoidMethod(env, h->pr, mid, tr.jstr, ms);
   4856 	    (*env)->ExceptionClear(env);
   4857 	    (*env)->DeleteLocalRef(env, tr.jstr);
   4858 	    return;
   4859 	}
   4860     }
   4861     return;
   4862 }
   4863 #endif
   4864 
   4865 JNIEXPORT void JNICALL
   4866 Java_SQLite_Database__1profile(JNIEnv *env, jobject obj, jobject tr)
   4867 {
   4868 #if HAVE_SQLITE3_PROFILE
   4869     handle *h = gethandle(env, obj);
   4870 
   4871     if (h && h->sqlite) {
   4872 	delglobrefp(env, &h->pr);
   4873 	globrefset(env, tr, &h->pr);
   4874 #if HAVE_BOTH_SQLITE
   4875 	if (h->is3) {
   4876 	    sqlite3_profile((sqlite3 *) h->sqlite, h->pr ? doprofile : 0, h);
   4877 	}
   4878 #else
   4879 #if HAVE_SQLITE3
   4880 	sqlite3_profile((sqlite3 *) h->sqlite, h->pr ? doprofile : 0, h);
   4881 #endif
   4882 #endif
   4883     }
   4884 #endif
   4885 }
   4886 
   4887 JNIEXPORT jint JNICALL
   4888 Java_SQLite_Database__1status(JNIEnv *env, jclass cls, jint op,
   4889 			      jintArray info, jboolean flag)
   4890 {
   4891     jint ret = SQLITE_ERROR;
   4892 #if HAVE_SQLITE3_STATUS
   4893     int data[2] = { 0, 0 };
   4894     jint jdata[2];
   4895 #if HAVE_SQLITE3
   4896     ret = sqlite3_status(op, &data[0], &data[2], flag);
   4897     if (ret == SQLITE_OK) {
   4898 	jdata[0] = data[0];
   4899 	jdata[1] = data[1];
   4900 	(*env)->SetIntArrayRegion(env, info, 0, 2, jdata);
   4901     }
   4902 #endif
   4903 #endif
   4904     return ret;
   4905 }
   4906 
   4907 JNIEXPORT jint JNICALL
   4908 Java_SQLite_Database__1db_1status(JNIEnv *env, jobject obj, jint op,
   4909 				  jintArray info, jboolean flag)
   4910 {
   4911     jint ret = SQLITE_ERROR;
   4912 #if HAVE_SQLITE3_DB_STATUS
   4913     handle *h = gethandle(env, obj);
   4914     int data[2] = { 0, 0 };
   4915     jint jdata[2];
   4916 
   4917     if (h && h->sqlite) {
   4918 #if HAVE_BOTH_SQLITE
   4919 	if (h->is3) {
   4920 	    ret = sqlite3_db_status((sqlite3 *) h->sqlite, op, &data[0],
   4921 				    &data[1], flag);
   4922 	}
   4923 #else
   4924 #if HAVE_SQLITE3
   4925 	ret = sqlite3_db_status((sqlite3 *) h->sqlite, op, &data[0],
   4926 				&data[2], flag);
   4927 #endif
   4928 #endif
   4929 	if (ret == SQLITE_OK) {
   4930 	    jdata[0] = data[0];
   4931 	    jdata[1] = data[1];
   4932 	    (*env)->SetIntArrayRegion(env, info, 0, 2, jdata);
   4933 	}
   4934     }
   4935 #endif
   4936     return ret;
   4937 }
   4938 
   4939 JNIEXPORT void JNICALL
   4940 Java_SQLite_Stmt_internal_1init(JNIEnv *env, jclass cls)
   4941 {
   4942     F_SQLite_Stmt_handle =
   4943 	(*env)->GetFieldID(env, cls, "handle", "J");
   4944     F_SQLite_Stmt_error_code =
   4945 	(*env)->GetFieldID(env, cls, "error_code", "I");
   4946 }
   4947 
   4948 JNIEXPORT void JNICALL
   4949 Java_SQLite_Vm_internal_1init(JNIEnv *env, jclass cls)
   4950 {
   4951     F_SQLite_Vm_handle =
   4952 	(*env)->GetFieldID(env, cls, "handle", "J");
   4953     F_SQLite_Vm_error_code =
   4954 	(*env)->GetFieldID(env, cls, "error_code", "I");
   4955 }
   4956 
   4957 JNIEXPORT void JNICALL
   4958 Java_SQLite_Blob_internal_1init(JNIEnv *env, jclass cls)
   4959 {
   4960     F_SQLite_Blob_handle =
   4961 	(*env)->GetFieldID(env, cls, "handle", "J");
   4962     F_SQLite_Blob_size =
   4963 	(*env)->GetFieldID(env, cls, "size", "I");
   4964 }
   4965 
   4966 JNIEXPORT void JNICALL
   4967 Java_SQLite_Backup_internal_1init(JNIEnv *env, jclass cls)
   4968 {
   4969     F_SQLite_Backup_handle =
   4970 	(*env)->GetFieldID(env, cls, "handle", "J");
   4971 }
   4972 
   4973 JNIEXPORT void JNICALL
   4974 Java_SQLite_Database_internal_1init(JNIEnv *env, jclass cls)
   4975 {
   4976 #if defined(DONT_USE_JNI_ONLOAD) || !defined(JNI_VERSION_1_2)
   4977     while (C_java_lang_String == 0) {
   4978 	jclass jls = (*env)->FindClass(env, "java/lang/String");
   4979 
   4980 	C_java_lang_String = (*env)->NewGlobalRef(env, jls);
   4981     }
   4982 #endif
   4983     F_SQLite_Database_handle =
   4984 	(*env)->GetFieldID(env, cls, "handle", "J");
   4985     F_SQLite_Database_error_code =
   4986 	(*env)->GetFieldID(env, cls, "error_code", "I");
   4987     M_java_lang_String_getBytes =
   4988 	(*env)->GetMethodID(env, C_java_lang_String, "getBytes", "()[B");
   4989     M_java_lang_String_getBytes2 =
   4990 	(*env)->GetMethodID(env, C_java_lang_String, "getBytes",
   4991 			    "(Ljava/lang/String;)[B");
   4992     M_java_lang_String_initBytes =
   4993 	(*env)->GetMethodID(env, C_java_lang_String, "<init>", "([B)V");
   4994     M_java_lang_String_initBytes2 =
   4995 	(*env)->GetMethodID(env, C_java_lang_String, "<init>",
   4996 			    "([BLjava/lang/String;)V");
   4997 }
   4998 
   4999 #if !defined(DONT_USE_JNI_ONLOAD) && defined(JNI_VERSION_1_2)
   5000 JNIEXPORT jint JNICALL
   5001 JNI_OnLoad(JavaVM *vm, void *reserved)
   5002 {
   5003     JNIEnv *env;
   5004     jclass cls;
   5005 
   5006 #ifndef _WIN32
   5007 #if HAVE_SQLITE2
   5008     if (strcmp(sqlite_libencoding(), "UTF-8") != 0) {
   5009 	fprintf(stderr, "WARNING: using non-UTF SQLite2 engine\n");
   5010     }
   5011 #endif
   5012 #endif
   5013     if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_2)) {
   5014 	return JNI_ERR;
   5015     }
   5016     cls = (*env)->FindClass(env, "java/lang/String");
   5017     if (!cls) {
   5018 	return JNI_ERR;
   5019     }
   5020     C_java_lang_String = (*env)->NewGlobalRef(env, cls);
   5021     return JNI_VERSION_1_2;
   5022 }
   5023 
   5024 JNIEXPORT void JNICALL
   5025 JNI_OnUnload(JavaVM *vm, void *reserved)
   5026 {
   5027     JNIEnv *env;
   5028 
   5029     if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_2)) {
   5030 	return;
   5031     }
   5032     if (C_java_lang_String) {
   5033 	(*env)->DeleteGlobalRef(env, C_java_lang_String);
   5034 	C_java_lang_String = 0;
   5035     }
   5036 }
   5037 #endif
   5038