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