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