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