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