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