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