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