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