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