sqlite_jni.c revision 417deb1db112103aff04231b6ca79772ff7d3a21
1417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#include "JNIHelp.h"
2417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#include "sqlite_jni_defs.h"
3417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#include <stdlib.h>
5417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#include <stdio.h>
6417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#include <string.h>
7417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
8417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
9417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#include "sqlite.h"
10417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
11417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
12417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
13417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#include "sqlite3.h"
14417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#undef  HAVE_SQLITE_COMPILE
15417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define HAVE_SQLITE_COMPILE 1
16417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#undef  HAVE_SQLITE_PROGRESS_HANDLER
17417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define HAVE_SQLITE_PROGRESS_HANDLER 1
18417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#undef  HAVE_SQLITE_TRACE
19417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define HAVE_SQLITE_TRACE 1
20417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if !HAVE_SQLITE3_MALLOC
21417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define sqlite3_malloc malloc
22417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define sqlite3_free   free
23417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
24417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if !HAVE_SQLITE3_BIND_PARAMETER_COUNT
25417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define sqlite3_bind_parameter_count(dummy) (1000)
26417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
27417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
28417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
29417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2 && HAVE_SQLITE3
30417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define HAVE_BOTH_SQLITE 1
31417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
32417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
33417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define CANT_PASS_VALIST_AS_CHARPTR
34417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
35417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#include "sqlite_jni.h"
36417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
37417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
38417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define MAX_PARAMS 256
39417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
40417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define MAX_PARAMS 32
41417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
42417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
43417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* free memory proc */
44417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
45417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef void (freemem)(void *);
46417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
47417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* internal handle for SQLite database */
48417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
49417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef struct {
50417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *sqlite;		/* SQLite handle */
51417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
52417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int is3;			/* True for SQLITE3 handle */
53417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
54417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ver;			/* version code */
55417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject bh;			/* BusyHandler object */
56417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject cb;			/* Callback object */
57417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject ai;			/* Authorizer object */
58417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject tr;			/* Trace object */
59417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject ph;			/* ProgressHandler object */
60417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env;		/* Java environment for callbacks */
61417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int row1;			/* true while processing first row */
62417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int haveutf;		/* true for SQLite UTF-8 support */
63417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jstring enc;		/* encoding or 0 */
64417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    struct hfunc *funcs;	/* SQLite user defined function handles */
65417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
66417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    struct hvm *vms;		/* Compiled SQLite VMs */
67417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
68417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
69417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    sqlite3_stmt *stmt;		/* For callback() */
70417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
71417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
72417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes  struct hbl *blobs;		/* SQLite3 blob handles */
73417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
74417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes} handle;
75417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
76417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* internal handle for SQLite user defined function */
77417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
78417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef struct hfunc {
79417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    struct hfunc *next;		/* next function */
80417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
81417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int is3;			/* True for SQLITE3 handle */
82417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
83417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject fc;			/* FunctionContext object */
84417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject fi;			/* Function object */
85417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject db;			/* Database object */
86417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h;			/* SQLite database handle */
87417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *sf;			/* SQLite function handle */
88417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env;		/* Java environment for callbacks */
89417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes} hfunc;
90417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
91417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
92417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* internal handle for SQLite VM (sqlite_compile()) */
93417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
94417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef struct hvm {
95417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    struct hvm *next;		/* next vm handle */
96417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
97417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int is3;			/* True for SQLITE3 handle */
98417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
99417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *vm;			/* SQLite 2/3 VM/statement */
100417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *tail;			/* tail SQL string */
101417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int tail_len;		/* only for SQLite3/prepare */
102417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h;			/* SQLite database handle */
103417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle hh;			/* fake SQLite database handle */
104417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes} hvm;
105417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
106417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
107417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
108417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* internal handle for sqlite3_blob */
109417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
110417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef struct hbl {
111417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    struct hbl *next;		/* next blob handle */
112417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    sqlite3_blob *blob;		/* SQLite3 blob */
113417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h;			/* SQLite database handle */
114417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes} hbl;
115417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
116417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
117417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* ISO to/from UTF-8 translation */
118417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
119417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef struct {
120417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *result;		/* translated C string result */
121417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *tofree;		/* memory to be free'd, or 0 */
122417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jstring jstr;		/* resulting Java string or 0 */
123417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes} transstr;
124417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
125417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* static cached weak class refs, field and method ids */
126417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
127417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jclass C_java_lang_String = 0;
128417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
129417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Database_handle = 0;
130417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Database_error_code = 0;
131417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_FunctionContext_handle = 0;
132417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Vm_handle = 0;
133417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Vm_error_code = 0;
134417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Stmt_handle = 0;
135417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Stmt_error_code = 0;
136417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Blob_handle = 0;
137417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Blob_size = 0;
138417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
139417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jmethodID M_java_lang_String_getBytes = 0;
140417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jmethodID M_java_lang_String_getBytes2 = 0;
141417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jmethodID M_java_lang_String_initBytes = 0;
142417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jmethodID M_java_lang_String_initBytes2 = 0;
143417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
144417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic const char xdigits[] = "0123456789ABCDEF";
145417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
146417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
147417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesseterr(JNIEnv *env, jobject obj, int err)
148417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
149417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
150417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
151417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = 0;
152417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.i = (jint) err;
153417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->SetIntField(env, obj, F_SQLite_Database_error_code, v.i);
154417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
155417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
156417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
157417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
158417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughessetvmerr(JNIEnv *env, jobject obj, int err)
159417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
160417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
161417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
162417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = 0;
163417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.i = (jint) err;
164417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->SetIntField(env, obj, F_SQLite_Vm_error_code, v.i);
165417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
166417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
167417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
168417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
169417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughessetstmterr(JNIEnv *env, jobject obj, int err)
170417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
171417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
172417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
173417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = 0;
174417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.i = (jint) err;
175417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->SetIntField(env, obj, F_SQLite_Stmt_error_code, v.i);
176417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
177417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
178417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
179417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesjstrlen(const jchar *jstr)
180417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
181417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int len = 0;
182417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
183417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (jstr) {
184417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        while (*jstr++) {
185417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    len++;
186417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
187417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
188417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return len;
189417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
190417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
191417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
192417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
193417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void *
194417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesgethandle(JNIEnv *env, jobject obj)
195417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
196417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
197417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
198417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = (*env)->GetLongField(env, obj, F_SQLite_Database_handle);
199417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (void *) v.l;
200417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
201417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
202417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
203417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void *
204417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesgethvm(JNIEnv *env, jobject obj)
205417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
206417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
207417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
208417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = (*env)->GetLongField(env, obj, F_SQLite_Vm_handle);
209417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (void *) v.l;
210417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
211417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
212417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
213417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void *
214417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesgethstmt(JNIEnv *env, jobject obj)
215417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
216417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
217417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
218417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = (*env)->GetLongField(env, obj, F_SQLite_Stmt_handle);
219417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (void *) v.l;
220417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
221417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
222417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
223417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
224417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
225417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void *
226417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesgethbl(JNIEnv *env, jobject obj)
227417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
228417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
229417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
230417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = (*env)->GetLongField(env, obj, F_SQLite_Blob_handle);
231417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (void *) v.l;
232417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
233417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
234417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
235417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
236417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdelglobrefp(JNIEnv *env, jobject *obj)
237417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
238417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (*obj) {
239417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteGlobalRef(env, *obj);
240417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	*obj = 0;
241417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
242417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
243417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
244417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jobject
245417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesglobrefpop(JNIEnv *env, jobject *obj)
246417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
247417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject ret = 0;
248417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
249417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (*obj) {
250417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = *obj;
251417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	*obj = 0;
252417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
253417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return ret;
254417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
255417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
256417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
257417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesglobrefset(JNIEnv *env, jobject obj, jobject *ref)
258417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
259417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ref) {
260417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (obj) {
261417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    *ref = (*env)->NewGlobalRef(env, obj);
262417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
263417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    *ref = 0;
264417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
265417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
266417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
267417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
268417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
269417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesfreep(char **strp)
270417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
271417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (strp && *strp) {
272417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(*strp);
273417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	*strp = 0;
274417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
275417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
276417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
277417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
278417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesthrowex(JNIEnv *env, const char *msg)
279417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
280417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jclass except = (*env)->FindClass(env, "SQLite/Exception");
281417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
282417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->ExceptionClear(env);
283417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (except) {
284417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->ThrowNew(env, except, msg);
285417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
286417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
287417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
288417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
289417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesthrowoom(JNIEnv *env, const char *msg)
290417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
291417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jclass except = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
292417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
293417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->ExceptionClear(env);
294417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (except) {
295417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->ThrowNew(env, except, msg);
296417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
297417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
298417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
299417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
300417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesthrowclosed(JNIEnv *env)
301417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
302417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "database already closed");
303417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
304417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
305417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
306417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
307417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesthrowioex(JNIEnv *env, const char *msg)
308417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
309417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jclass except = (*env)->FindClass(env, "java/io/IOException");
310417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
311417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->ExceptionClear(env);
312417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (except) {
313417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->ThrowNew(env, except, msg);
314417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
315417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
316417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
317417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
318417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
319417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestransfree(transstr *dest)
320417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
321417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->result = 0;
322417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    freep(&dest->tofree);
323417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
324417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
325417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic char *
326417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestrans2iso(JNIEnv *env, int haveutf, jstring enc, jstring src,
327417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	  transstr *dest)
328417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
329417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jbyteArray bytes = 0;
330417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jthrowable exc;
331417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
332417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->result = 0;
333417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->tofree = 0;
334417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (haveutf) {
335417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        const jsize utfLength = (*env)->GetStringUTFLength(env, src);
336417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        dest->result = dest->tofree = malloc(utfLength + 1);
337417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        if (!dest->tofree) {
338417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes            throwoom(env, "string translation failed");
339417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes            return dest->result;
340417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        }
341417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        (*env)->GetStringUTFRegion(env, src, 0, utfLength, dest->result);
342417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        return dest->result;
343417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
344417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (enc) {
345417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bytes = (*env)->CallObjectMethod(env, src,
346417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 M_java_lang_String_getBytes2, enc);
347417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
348417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bytes = (*env)->CallObjectMethod(env, src,
349417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 M_java_lang_String_getBytes);
350417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
351417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    exc = (*env)->ExceptionOccurred(env);
352417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!exc) {
353417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jint len = (*env)->GetArrayLength(env, bytes);
354417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	dest->tofree = malloc(len + 1);
355417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!dest->tofree) {
356417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "string translation failed");
357417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return dest->result;
358417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
359417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	dest->result = dest->tofree;
360417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetByteArrayRegion(env, bytes, 0, len, (jbyte *) dest->result);
361417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	dest->result[len] = '\0';
362417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
363417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, exc);
364417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
365417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return dest->result;
366417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
367417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
368417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jstring
369417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestrans2utf(JNIEnv *env, int haveutf, jstring enc, const char *src,
370417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	  transstr *dest)
371417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
372417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jbyteArray bytes = 0;
373417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int len;
374417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
375417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->result = 0;
376417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->tofree = 0;
377417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->jstr = 0;
378417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!src) {
379417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return dest->jstr;
380417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
381417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (haveutf) {
382417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	dest->jstr = (*env)->NewStringUTF(env, src);
383417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return dest->jstr;
384417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
385417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    len = strlen(src);
386417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    bytes = (*env)->NewByteArray(env, len);
387417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (bytes) {
388417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *) src);
389417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (enc) {
390417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    dest->jstr =
391417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->NewObject(env, C_java_lang_String,
392417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  M_java_lang_String_initBytes2, bytes, enc);
393417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
394417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    dest->jstr =
395417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->NewObject(env, C_java_lang_String,
396417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  M_java_lang_String_initBytes, bytes);
397417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
398417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, bytes);
399417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return dest->jstr;
400417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
401417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwoom(env, "string translation failed");
402417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return dest->jstr;
403417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
404417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
405417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
406417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
407417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesbusyhandler(void *udata, const char *table, int count)
408417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
409417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) udata;
410417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
411417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret = 0;
412417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
413417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->bh) {
414417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr tabstr;
415417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->bh);
416417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid = (*env)->GetMethodID(env, cls, "busy",
417417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    "(Ljava/lang/String;I)Z");
418417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
419417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
420417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, cls);
421417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return ret;
422417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
423417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2utf(env, h->haveutf, h->enc, table, &tabstr);
424417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = (*env)->CallBooleanMethod(env, h->bh, mid, tabstr.jstr,
425417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					(jint) count)
426417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	      != JNI_FALSE;
427417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, tabstr.jstr);
428417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, cls);
429417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
430417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return ret;
431417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
432417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
433417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
434417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
435417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
436417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesbusyhandler3(void *udata, int count)
437417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
438417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) udata;
439417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
440417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret = 0;
441417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
442417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->bh) {
443417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->bh);
444417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid = (*env)->GetMethodID(env, cls, "busy",
445417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    "(Ljava/lang/String;I)Z");
446417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
447417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
448417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, cls);
449417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return ret;
450417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
451417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = (*env)->CallBooleanMethod(env, h->bh, mid, 0, (jint) count)
452417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    != JNI_FALSE;
453417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, cls);
454417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
455417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return ret;
456417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
457417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
458417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
459417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
460417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesprogresshandler(void *udata)
461417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
462417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) udata;
463417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
464417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret = 0;
465417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
466417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->ph) {
467417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->ph);
468417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid = (*env)->GetMethodID(env, cls, "progress", "()Z");
469417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
470417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
471417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, cls);
472417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return ret;
473417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
474417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = (*env)->CallBooleanMethod(env, h->ph, mid) != JNI_TRUE;
475417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, cls);
476417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
477417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return ret;
478417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
479417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
480417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
481417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescallback(void *udata, int ncol, char **data, char **cols)
482417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
483417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) udata;
484417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
485417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
486417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->cb) {
487417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
488417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->cb);
489417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid;
490417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jobjectArray arr = 0;
491417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jint i;
492417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
493417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->row1) {
494417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    mid = (*env)->GetMethodID(env, cls, "columns",
495417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      "([Ljava/lang/String;)V");
496417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
497417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (mid) {
498417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		arr = (*env)->NewObjectArray(env, ncol, C_java_lang_String, 0);
499417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < ncol; i++) {
500417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (cols[i]) {
501417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			transstr col;
502417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
503417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			trans2utf(env, h->haveutf, h->enc, cols[i], &col);
504417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->SetObjectArrayElement(env, arr, i, col.jstr);
505417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			exc = (*env)->ExceptionOccurred(env);
506417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (exc) {
507417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->DeleteLocalRef(env, exc);
508417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    return 1;
509417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
510417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->DeleteLocalRef(env, col.jstr);
511417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
512417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
513417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->row1 = 0;
514417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->CallVoidMethod(env, h->cb, mid, arr);
515417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		exc = (*env)->ExceptionOccurred(env);
516417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (exc) {
517417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, exc);
518417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return 1;
519417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
520417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, arr);
521417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
522417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
523417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->is3) {
524417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		mid = (*env)->GetMethodID(env, cls, "types",
525417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  "([Ljava/lang/String;)V");
526417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
527417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (mid && h->stmt) {
528417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    arr = (*env)->NewObjectArray(env, ncol,
529417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						 C_java_lang_String, 0);
530417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    for (i = 0; i < ncol; i++) {
531417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			const char *ctype =
532417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_column_decltype(h->stmt, i);
533417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
534417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (!ctype) {
535417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    switch (sqlite3_column_type(h->stmt, i)) {
536417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE_INTEGER: ctype = "integer"; break;
537417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE_FLOAT:   ctype = "double";  break;
538417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    default:
539417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(SQLITE_TEXT) && defined(SQLITE3_TEXT) && (SQLITE_TEXT != SQLITE3_TEXT)
540417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE_TEXT:
541417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
542417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#ifdef SQLITE3_TEXT
543417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE3_TEXT:
544417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
545417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
546417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						 ctype = "text";    break;
547417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE_BLOB:    ctype = "blob";    break;
548417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE_NULL:    ctype = "null";    break;
549417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
550417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
551417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (ctype) {
552417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    transstr ty;
553417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
554417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    trans2utf(env, 1, 0, ctype, &ty);
555417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->SetObjectArrayElement(env, arr, i,
556417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes							  ty.jstr);
557417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    exc = (*env)->ExceptionOccurred(env);
558417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    if (exc) {
559417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				(*env)->DeleteLocalRef(env, exc);
560417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				return 1;
561417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
562417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->DeleteLocalRef(env, ty.jstr);
563417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
564417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
565417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->CallVoidMethod(env, h->cb, mid, arr);
566417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    exc = (*env)->ExceptionOccurred(env);
567417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (exc) {
568417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->DeleteLocalRef(env, exc);
569417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			return 1;
570417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
571417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, arr);
572417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
573417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
574417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (h->ver >= 0x020506 && cols[ncol]) {
575417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    mid = (*env)->GetMethodID(env, cls, "types",
576417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      "([Ljava/lang/String;)V");
577417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
578417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (mid) {
579417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			arr = (*env)->NewObjectArray(env, ncol,
580417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						     C_java_lang_String, 0);
581417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			for (i = 0; i < ncol; i++) {
582417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    if (cols[i + ncol]) {
583417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				transstr ty;
584417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
585417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				trans2utf(env, h->haveutf, h->enc,
586417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cols[i + ncol], &ty);
587417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				(*env)->SetObjectArrayElement(env, arr, i,
588417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes							      ty.jstr);
589417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				exc = (*env)->ExceptionOccurred(env);
590417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				if (exc) {
591417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    (*env)->DeleteLocalRef(env, exc);
592417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    return 1;
593417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				}
594417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				(*env)->DeleteLocalRef(env, ty.jstr);
595417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
596417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
597417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->CallVoidMethod(env, h->cb, mid, arr);
598417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			exc = (*env)->ExceptionOccurred(env);
599417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (exc) {
600417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->DeleteLocalRef(env, exc);
601417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    return 1;
602417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
603417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->DeleteLocalRef(env, arr);
604417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
605417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
606417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
607417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
608417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
609417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->ver >= 0x020506 && cols[ncol]) {
610417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		mid = (*env)->GetMethodID(env, cls, "types",
611417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  "([Ljava/lang/String;)V");
612417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
613417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (mid) {
614417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    arr = (*env)->NewObjectArray(env, ncol,
615417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						 C_java_lang_String, 0);
616417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    for (i = 0; i < ncol; i++) {
617417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (cols[i + ncol]) {
618417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    transstr ty;
619417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
620417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    trans2utf(env, h->haveutf, h->enc,
621417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cols[i + ncol], &ty);
622417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->SetObjectArrayElement(env, arr, i,
623417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes							  ty.jstr);
624417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    exc = (*env)->ExceptionOccurred(env);
625417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    if (exc) {
626417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				(*env)->DeleteLocalRef(env, exc);
627417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				return 1;
628417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
629417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->DeleteLocalRef(env, ty.jstr);
630417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
631417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
632417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->CallVoidMethod(env, h->cb, mid, arr);
633417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    exc = (*env)->ExceptionOccurred(env);
634417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (exc) {
635417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->DeleteLocalRef(env, exc);
636417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			return 1;
637417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
638417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, arr);
639417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
640417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
641417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
642417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
643417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    mid = (*env)->GetMethodID(env, cls, "types",
644417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      "([Ljava/lang/String;)V");
645417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
646417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (mid && h->stmt) {
647417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		arr = (*env)->NewObjectArray(env, ncol,
648417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     C_java_lang_String, 0);
649417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < ncol; i++) {
650417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    const char *ctype = sqlite3_column_decltype(h->stmt, i);
651417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
652417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (!ctype) {
653417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			switch (sqlite3_column_type(h->stmt, i)) {
654417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE_INTEGER: ctype = "integer"; break;
655417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE_FLOAT:   ctype = "double";  break;
656417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			default:
657417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(SQLITE_TEXT) && defined(SQLITE3_TEXT) && (SQLITE_TEXT != SQLITE3_TEXT)
658417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE_TEXT:
659417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
660417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#ifdef SQLITE3_TEXT
661417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE3_TEXT:
662417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
663417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
664417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     ctype = "text";    break;
665417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE_BLOB:    ctype = "blob";    break;
666417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE_NULL:    ctype = "null";    break;
667417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
668417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
669417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (ctype) {
670417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			transstr ty;
671417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
672417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			trans2utf(env, 1, 0, ctype, &ty);
673417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->SetObjectArrayElement(env, arr, i, ty.jstr);
674417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			exc = (*env)->ExceptionOccurred(env);
675417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (exc) {
676417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->DeleteLocalRef(env, exc);
677417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    return 1;
678417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
679417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->DeleteLocalRef(env, ty.jstr);
680417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
681417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
682417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->CallVoidMethod(env, h->cb, mid, arr);
683417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		exc = (*env)->ExceptionOccurred(env);
684417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (exc) {
685417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, exc);
686417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return 1;
687417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
688417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, arr);
689417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
690417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
691417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
692417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
693417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	mid = (*env)->GetMethodID(env, cls, "newrow",
694417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  "([Ljava/lang/String;)Z");
695417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid) {
696417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jboolean rc;
697417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
698417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (data) {
699417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		arr = (*env)->NewObjectArray(env, ncol, C_java_lang_String, 0);
700417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
701417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		arr = 0;
702417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
703417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    for (i = 0; arr && i < ncol; i++) {
704417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (data[i]) {
705417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    transstr dats;
706417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
707417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    trans2utf(env, h->haveutf, h->enc, data[i], &dats);
708417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->SetObjectArrayElement(env, arr, i, dats.jstr);
709417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    exc = (*env)->ExceptionOccurred(env);
710417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (exc) {
711417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->DeleteLocalRef(env, exc);
712417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			return 1;
713417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
714417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, dats.jstr);
715417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
716417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
717417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    rc = (*env)->CallBooleanMethod(env, h->cb, mid, arr);
718417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
719417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
720417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
721417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return 1;
722417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
723417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (arr) {
724417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, arr);
725417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
726417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, cls);
727417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return rc != JNI_FALSE;
728417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
729417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
730417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
731417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
732417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
733417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
734417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdoclose(JNIEnv *env, jobject obj, int final)
735417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
736417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
737417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
738417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h) {
739417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	hfunc *f;
740417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
741417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	hbl *bl;
742417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
743417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
744417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	hvm *v;
745417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
746417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	while ((v = h->vms)) {
747417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->vms = v->next;
748417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->next = 0;
749417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->h = 0;
750417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (v->vm) {
751417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
752417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (h->is3) {
753417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sqlite3_finalize((sqlite3_stmt *) v->vm);
754417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		} else {
755417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sqlite_finalize((sqlite_vm *) v->vm, 0);
756417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
757417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
758417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
759417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_finalize((sqlite_vm *) v->vm, 0);
760417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
761417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
762417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) v->vm);
763417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
764417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
765417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		v->vm = 0;
766417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
767417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
768417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
769417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->sqlite) {
770417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
771417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->is3) {
772417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_close((sqlite3 *) h->sqlite);
773417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
774417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_close((sqlite *) h->sqlite);
775417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
776417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
777417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
778417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_close((sqlite *) h->sqlite);
779417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
780417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
781417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_close((sqlite3 *) h->sqlite);
782417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
783417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
784417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->sqlite = 0;
785417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
786417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	while ((f = h->funcs)) {
787417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->funcs = f->next;
788417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    f->h = 0;
789417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    f->sf = 0;
790417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    f->env = 0;
791417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (f->fc) {
792417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->SetLongField(env, f->fc,
793417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				     F_SQLite_FunctionContext_handle, 0);
794417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
795417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &f->db);
796417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &f->fi);
797417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &f->fc);
798417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    free(f);
799417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
800417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
801417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	while ((bl = h->blobs)) {
802417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->blobs = bl->next;
803417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    bl->next = 0;
804417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    bl->h = 0;
805417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (bl->blob) {
806417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	        sqlite3_blob_close(bl->blob);
807417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
808417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    bl->blob = 0;
809417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
810417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
811417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->bh);
812417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->cb);
813417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->ai);
814417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->tr);
815417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->ph);
816417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->enc);
817417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(h);
818417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, obj, F_SQLite_Database_handle, 0);
819417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
820417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
821417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!final) {
822417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwclosed(env);
823417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
824417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
825417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
826417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
827417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1close(JNIEnv *env, jobject obj)
828417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
829417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    doclose(env, obj, 0);
830417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
831417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
832417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
833417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1finalize(JNIEnv *env, jobject obj)
834417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
835417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    doclose(env, obj, 1);
836417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
837417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
838417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
839417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1busy_1timeout(JNIEnv *env, jobject obj, jint ms)
840417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
841417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
842417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
843417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
844417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
845417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
846417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_busy_timeout((sqlite3 * ) h->sqlite, ms);
847417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
848417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_busy_timeout((sqlite *) h->sqlite, ms);
849417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
850417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
851417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
852417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_busy_timeout((sqlite *) h->sqlite, ms);
853417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
854417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
855417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_busy_timeout((sqlite3 * ) h->sqlite, ms);
856417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
857417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
858417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
859417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
860417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
861417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
862417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
863417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
864417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_version(JNIEnv *env, jclass cls)
865417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
866417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    /* CHECK THIS */
867417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
868417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, sqlite_libversion());
869417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
870417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
871417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, sqlite_libversion());
872417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
873417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, sqlite3_libversion());
874417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
875417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
876417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
877417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
878417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
879417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_dbversion(JNIEnv *env, jobject obj)
880417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
881417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
882417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
883417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
884417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
885417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
886417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewStringUTF(env, sqlite3_libversion());
887417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
888417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewStringUTF(env, sqlite_libversion());
889417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
890417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
891417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
892417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (*env)->NewStringUTF(env, sqlite_libversion());
893417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
894417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (*env)->NewStringUTF(env, sqlite3_libversion());
895417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
896417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
897417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
898417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, "unknown");
899417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
900417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
901417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jlong JNICALL
902417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1last_1insert_1rowid(JNIEnv *env, jobject obj)
903417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
904417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
905417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
906417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
907417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
908417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
909417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (jlong) sqlite3_last_insert_rowid((sqlite3 *) h->sqlite);
910417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
911417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (jlong) sqlite_last_insert_rowid((sqlite *) h->sqlite);
912417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
913417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
914417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
915417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (jlong) sqlite_last_insert_rowid((sqlite *) h->sqlite);
916417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
917417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
918417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (jlong) sqlite3_last_insert_rowid((sqlite3 *) h->sqlite);
919417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
920417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
921417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
922417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
923417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (jlong) 0;
924417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
925417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
926417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jlong JNICALL
927417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1changes(JNIEnv *env, jobject obj)
928417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
929417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
930417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
931417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
932417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
933417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
934417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (jlong) sqlite3_changes((sqlite3 *) h->sqlite);
935417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
936417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (jlong) sqlite_changes((sqlite *) h->sqlite);
937417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
938417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
939417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
940417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (jlong) sqlite_changes((sqlite *) h->sqlite);
941417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
942417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
943417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (jlong) sqlite3_changes((sqlite3 *) h->sqlite);
944417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
945417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
946417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
947417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
948417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (jlong) 0;
949417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
950417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
951417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
952417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1complete(JNIEnv *env, jclass cls, jstring sql)
953417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
954417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transstr sqlstr;
955417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jboolean result;
956417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
957417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
958417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_FALSE;
959417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
960417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE || HAVE_SQLITE3
961417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    /* CHECK THIS */
962417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    trans2iso(env, 1, 0, sql, &sqlstr);
963417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    result = sqlite3_complete(sqlstr.result) ? JNI_TRUE : JNI_FALSE;
964417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
965417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    trans2iso(env, strcmp(sqlite_libencoding(), "UTF-8") == 0, 0,
966417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	      sql, &sqlstr);
967417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    result = sqlite_complete(sqlstr.result) ? JNI_TRUE : JNI_FALSE;
968417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
969417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transfree(&sqlstr);
970417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return result;
971417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
972417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
973417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
974417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1interrupt(JNIEnv *env, jobject obj)
975417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
976417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
977417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
978417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
979417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
980417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
981417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_interrupt((sqlite3 *) h->sqlite);
982417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
983417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_interrupt((sqlite *) h->sqlite);
984417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
985417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
986417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
987417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_interrupt((sqlite *) h->sqlite);
988417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
989417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
990417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_interrupt((sqlite3 *) h->sqlite);
991417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
992417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
993417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
994417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
995417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
996417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
997417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
998417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
999417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode)
1000417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1001417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1002417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jthrowable exc;
1003417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *err = 0;
1004417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transstr filename;
1005417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int maj, min, lev;
1006417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1007417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h) {
1008417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->sqlite) {
1009417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1010417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->is3) {
1011417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_close((sqlite3 *) h->sqlite);
1012417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
1013417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_close((sqlite *) h->sqlite);
1014417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1015417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->is3 = 0;
1016417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1017417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1018417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_close((sqlite *) h->sqlite);
1019417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1020417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1021417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_close((sqlite3 *) h->sqlite);
1022417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1023417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1024417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->sqlite = 0;
1025417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1026417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
1027417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h = malloc(sizeof (handle));
1028417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!h) {
1029417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to get SQLite handle");
1030417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1031417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1032417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->sqlite = 0;
1033417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->bh = h->cb = h->ai = h->tr = h->ph = 0;
1034417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	/* CHECK THIS */
1035417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1036417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->is3 = 0;
1037417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->stmt = 0;
1038417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->haveutf = 1;
1039417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1040417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1041417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->haveutf = strcmp(sqlite_libencoding(), "UTF-8") == 0;
1042417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1043417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1044417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->stmt = 0;
1045417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->haveutf = 1;
1046417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1047417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1048417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->enc = 0;
1049417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->funcs = 0;
1050417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->ver = 0;
1051417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
1052417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->vms = 0;
1053417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1054417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
1055417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->blobs = 0;
1056417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1057417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1058417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->env = 0;
1059417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!file) {
1060417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, err ? err : "invalid file name");
1061417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1062417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1063417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    trans2iso(env, h->haveutf, h->enc, file, &filename);
1064417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    exc = (*env)->ExceptionOccurred(env);
1065417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (exc) {
1066417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, exc);
1067417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1068417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1069417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1070417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    {
1071417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	FILE *f = fopen(filename.result, "rb");
1072417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int c_0 = EOF;
1073417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1074417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (f) {
1075417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    c_0 = fgetc(f);
1076417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    fclose(f);
1077417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1078417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (c_0 != '*') {
1079417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    int rc = sqlite3_open(filename.result, (sqlite3 **) &h->sqlite);
1080417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1081417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (rc == SQLITE_OK) {
1082417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->is3 = 1;
1083417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else if (h->sqlite) {
1084417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	        sqlite3_close((sqlite3 *) h->sqlite);
1085417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->sqlite = 0;
1086417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1087417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1088417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->sqlite = (void *) sqlite_open(filename.result,
1089417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     (int) mode, &err);
1090417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1091417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1092417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1093417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1094417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->sqlite = (void *) sqlite_open(filename.result, (int) mode, &err);
1095417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1096417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1097417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (sqlite3_open(filename.result, (sqlite3 **) &h->sqlite) != SQLITE_OK) {
1098417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        if (h->sqlite) {
1099417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_close((sqlite3 *) h->sqlite);
1100417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->sqlite = 0;
1101417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1102417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1103417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1104417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1105417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transfree(&filename);
1106417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    exc = (*env)->ExceptionOccurred(env);
1107417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (exc) {
1108417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, exc);
1109417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1110417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (err) {
1111417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_freemem(err);
1112417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1113417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1114417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->sqlite) {
1115417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1116417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->is3) {
1117417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_close((sqlite3 *) h->sqlite);
1118417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->is3 = 0;
1119417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
1120417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_close((sqlite *) h->sqlite);
1121417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1122417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1123417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1124417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_close((sqlite *) h->sqlite);
1125417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1126417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1127417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_close((sqlite3 *) h->sqlite);
1128417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1129417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1130417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1131417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->sqlite = 0;
1132417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1133417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1134417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h->sqlite) {
1135417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jvalue v;
1136417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1137417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v.j = 0;
1138417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v.l = (jobject) h;
1139417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, obj, F_SQLite_Database_handle, v.j);
1140417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1141417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (err) {
1142417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_freemem(err);
1143417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1144417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1145417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1146417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
1147417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sscanf(sqlite3_libversion(), "%d.%d.%d", &maj, &min, &lev);
1148417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1149417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sscanf(sqlite_libversion(), "%d.%d.%d", &maj, &min, &lev);
1150417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1151417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1152417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1153417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sscanf(sqlite_libversion(), "%d.%d.%d", &maj, &min, &lev);
1154417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1155417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1156417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sscanf(sqlite3_libversion(), "%d.%d.%d", &maj, &min, &lev);
1157417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1158417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1159417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->ver = ((maj & 0xFF) << 16) | ((min & 0xFF) << 8) | (lev & 0xFF);
1160417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1161417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1162417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, err ? err : "unknown error in open");
1163417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1164417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (err) {
1165417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_freemem(err);
1166417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1167417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1168417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1169417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1170417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1171417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1open_1aux_1file(JNIEnv *env, jobject obj, jstring file)
1172417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1173417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1174417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_OPEN_AUX_FILE
1175417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jboolean b;
1176417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jthrowable exc;
1177417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *err = 0;
1178417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transstr filename;
1179417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
1180417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1181417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1182417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
1183417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_OPEN_AUX_FILE
1184417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1185417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
1186417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "unsupported");
1187417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1188417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1189417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2iso(env, h->haveutf, h->enc, file, &filename);
1190417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
1191417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
1192417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
1193417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1194417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1195417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite_open_aux_file((sqlite *) h->sqlite,
1196417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				   filename.result, &err);
1197417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&filename);
1198417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
1199417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
1200417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
1201417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (err) {
1202417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_freemem(err);
1203417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1204417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1205417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1206417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
1207417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : sqlite_error_string(ret));
1208417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1209417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (err) {
1210417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_freemem(err);
1211417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1212417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1213417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "unsupported");
1214417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1215417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1216417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1217417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1218417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1219417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1220417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1221417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1busy_1handler(JNIEnv *env, jobject obj, jobject bh)
1222417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1223417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1224417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1225417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
1226417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->bh);
1227417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, bh, &h->bh);
1228417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1229417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
1230417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_busy_handler((sqlite3 *) h->sqlite, busyhandler3, h);
1231417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1232417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_busy_handler((sqlite *) h->sqlite, busyhandler, h);
1233417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1234417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1235417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1236417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_busy_handler((sqlite *) h->sqlite, busyhandler, h);
1237417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1238417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1239417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_busy_handler((sqlite3 *) h->sqlite, busyhandler3, h);
1240417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1241417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1242417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1243417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1244417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1245417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1246417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1247417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1248417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1exec__Ljava_lang_String_2LSQLite_Callback_2
1249417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (JNIEnv *env, jobject obj, jstring sql, jobject cb)
1250417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1251417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1252417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    freemem *freeproc;
1253417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1254417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
1255417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "invalid SQL statement");
1256417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1257417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1258417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h) {
1259417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->sqlite) {
1260417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jthrowable exc;
1261417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    int rc;
1262417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char *err = 0;
1263417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr sqlstr;
1264417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jobject oldcb = globrefpop(env, &h->cb);
1265417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1266417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    globrefset(env, cb, &h->cb);
1267417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->env = env;
1268417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->row1 = 1;
1269417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2iso(env, h->haveutf, h->enc, sql, &sqlstr);
1270417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
1271417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
1272417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
1273417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1274417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1275417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1276417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->is3) {
1277417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite3_exec((sqlite3 *) h->sqlite, sqlstr.result,
1278417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  callback, h, &err);
1279417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc = (freemem *) sqlite3_free;
1280417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
1281417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite_exec((sqlite *) h->sqlite, sqlstr.result,
1282417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 callback, h, &err);
1283417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc = (freemem *) sqlite_freemem;
1284417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1285417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1286417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1287417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    rc = sqlite_exec((sqlite *) h->sqlite, sqlstr.result,
1288417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			     callback, h, &err);
1289417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    freeproc = (freemem *) sqlite_freemem;
1290417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1291417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1292417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    rc = sqlite3_exec((sqlite3 *) h->sqlite, sqlstr.result,
1293417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			      callback, h, &err);
1294417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    freeproc = (freemem *) sqlite3_free;
1295417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1296417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1297417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&sqlstr);
1298417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
1299417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &h->cb);
1300417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->cb = oldcb;
1301417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
1302417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
1303417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (err) {
1304417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    freeproc(err);
1305417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1306417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1307417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1308417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (rc != SQLITE_OK) {
1309417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		char msg[128];
1310417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1311417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		seterr(env, obj, rc);
1312417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (!err) {
1313417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sprintf(msg, "error %d in sqlite*_exec", rc);
1314417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1315417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwex(env, err ? err : msg);
1316417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1317417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (err) {
1318417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc(err);
1319417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1320417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1321417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1322417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1323417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1324417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1325417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1326417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1327417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1exec__Ljava_lang_String_2LSQLite_Callback_2_3Ljava_lang_String_2
1328417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (JNIEnv *env, jobject obj, jstring sql, jobject cb, jobjectArray args)
1329417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1330417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1331417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    freemem *freeproc = 0;
1332417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1333417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
1334417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "invalid SQL statement");
1335417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1336417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1337417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h) {
1338417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->sqlite) {
1339417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jthrowable exc;
1340417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    int rc = SQLITE_ERROR, nargs, i;
1341417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char *err = 0, *p;
1342417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const char *str = (*env)->GetStringUTFChars(env, sql, NULL);
1343417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr sqlstr;
1344417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    struct args {
1345417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		char *arg;
1346417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		jobject obj;
1347417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transstr trans;
1348417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } *argv = 0;
1349417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char **cargv = 0;
1350417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jobject oldcb = globrefpop(env, &h->cb);
1351417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1352417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    globrefset(env, cb, &h->cb);
1353417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    p = (char *) str;
1354417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    nargs = 0;
1355417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    while (*p) {
1356417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (*p == '%') {
1357417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    ++p;
1358417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (*p == 'q' || *p == 's') {
1359417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			nargs++;
1360417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (nargs > MAX_PARAMS) {
1361417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->ReleaseStringUTFChars(env, sql, str);
1362417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    delglobrefp(env, &h->cb);
1363417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    h->cb = oldcb;
1364417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    throwex(env, "too much SQL parameters");
1365417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    return;
1366417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
1367417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    } else if (h->ver >= 0x020500 && *p == 'Q') {
1368417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			nargs++;
1369417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (nargs > MAX_PARAMS) {
1370417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->ReleaseStringUTFChars(env, sql, str);
1371417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    delglobrefp(env, &h->cb);
1372417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    h->cb = oldcb;
1373417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    throwex(env, "too much SQL parameters");
1374417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    return;
1375417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
1376417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    } else if (*p != '%') {
1377417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->ReleaseStringUTFChars(env, sql, str);
1378417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			delglobrefp(env, &h->cb);
1379417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			h->cb = oldcb;
1380417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			throwex(env, "bad % specification in query");
1381417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			return;
1382417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
1383417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1384417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		++p;
1385417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1386417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    cargv = malloc((sizeof (*argv) + sizeof (char *))
1387417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			   * MAX_PARAMS);
1388417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (!cargv) {
1389417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->ReleaseStringUTFChars(env, sql, str);
1390417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		delglobrefp(env, &h->cb);
1391417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->cb = oldcb;
1392417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwoom(env, "unable to allocate arg vector");
1393417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1394417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1395417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    argv = (struct args *) (cargv + MAX_PARAMS);
1396417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    for (i = 0; i < MAX_PARAMS; i++) {
1397417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		cargv[i] = 0;
1398417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		argv[i].arg = 0;
1399417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		argv[i].obj = 0;
1400417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		argv[i].trans.result = argv[i].trans.tofree = 0;
1401417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1402417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = 0;
1403417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    for (i = 0; i < nargs; i++) {
1404417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		jobject so = (*env)->GetObjectArrayElement(env, args, i);
1405417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1406417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		exc = (*env)->ExceptionOccurred(env);
1407417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (exc) {
1408417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, exc);
1409417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    break;
1410417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1411417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (so) {
1412417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    argv[i].obj = so;
1413417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    argv[i].arg = cargv[i] =
1414417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			trans2iso(env, h->haveutf, h->enc, argv[i].obj,
1415417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  &argv[i].trans);
1416417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1417417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1418417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
1419417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < nargs; i++) {
1420417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (argv[i].obj) {
1421417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			transfree(&argv[i].trans);
1422417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
1423417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1424417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freep((char **) &cargv);
1425417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->ReleaseStringUTFChars(env, sql, str);
1426417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		delglobrefp(env, &h->cb);
1427417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->cb = oldcb;
1428417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1429417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1430417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->env = env;
1431417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->row1 = 1;
1432417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2iso(env, h->haveutf, h->enc, sql, &sqlstr);
1433417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
1434417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (!exc) {
1435417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1436417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (h->is3) {
1437417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
1438417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    char *s = sqlite3_vmprintf(sqlstr.result, (char *) cargv);
1439417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1440417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    char *s = sqlite3_mprintf(sqlstr.result,
1441417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[0], cargv[1],
1442417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[2], cargv[3],
1443417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[4], cargv[5],
1444417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[6], cargv[7],
1445417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[8], cargv[9],
1446417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[10], cargv[11],
1447417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[12], cargv[13],
1448417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[14], cargv[15],
1449417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[16], cargv[17],
1450417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[18], cargv[19],
1451417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[20], cargv[21],
1452417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[22], cargv[23],
1453417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[24], cargv[25],
1454417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[26], cargv[27],
1455417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[28], cargv[29],
1456417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[30], cargv[31]);
1457417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1458417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1459417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (s) {
1460417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			rc = sqlite3_exec((sqlite3 *) h->sqlite, s, callback,
1461417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  h, &err);
1462417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			sqlite3_free(s);
1463417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    } else {
1464417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			rc = SQLITE_NOMEM;
1465417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
1466417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    freeproc = (freemem *) sqlite3_free;
1467417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		} else {
1468417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
1469417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    rc = sqlite_exec_vprintf((sqlite *) h->sqlite,
1470417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     sqlstr.result, callback, h, &err,
1471417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     (char *) cargv);
1472417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1473417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    rc = sqlite_exec_printf((sqlite *) h->sqlite,
1474417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    sqlstr.result, callback,
1475417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    h, &err,
1476417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[0], cargv[1],
1477417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[2], cargv[3],
1478417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[4], cargv[5],
1479417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[6], cargv[7],
1480417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[8], cargv[9],
1481417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[10], cargv[11],
1482417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[12], cargv[13],
1483417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[14], cargv[15],
1484417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[16], cargv[17],
1485417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[18], cargv[19],
1486417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[20], cargv[21],
1487417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[22], cargv[23],
1488417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[24], cargv[25],
1489417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[26], cargv[27],
1490417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[28], cargv[29],
1491417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[30], cargv[31]);
1492417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1493417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    freeproc = (freemem *) sqlite_freemem;
1494417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1495417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1496417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1497417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
1498417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite_exec_vprintf((sqlite *) h->sqlite, sqlstr.result,
1499417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 callback, h, &err, (char *) cargv);
1500417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1501417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite_exec_printf((sqlite *) h->sqlite, sqlstr.result,
1502417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					callback, h, &err,
1503417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[0], cargv[1],
1504417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[2], cargv[3],
1505417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[4], cargv[5],
1506417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[6], cargv[7],
1507417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[8], cargv[9],
1508417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[10], cargv[11],
1509417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[12], cargv[13],
1510417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[14], cargv[15],
1511417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[16], cargv[17],
1512417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[18], cargv[19],
1513417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[20], cargv[21],
1514417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[22], cargv[23],
1515417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[24], cargv[25],
1516417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[26], cargv[27],
1517417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[28], cargv[29],
1518417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[30], cargv[31]);
1519417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1520417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc = (freemem *) sqlite_freemem;
1521417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1522417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1523417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
1524417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		char *s = sqlite3_vmprintf(sqlstr.result, (char *) cargv);
1525417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1526417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		char *s = sqlite3_mprintf(sqlstr.result,
1527417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[0], cargv[1],
1528417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[2], cargv[3],
1529417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[4], cargv[5],
1530417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[6], cargv[7],
1531417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[8], cargv[9],
1532417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[10], cargv[11],
1533417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[12], cargv[13],
1534417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[14], cargv[15],
1535417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[16], cargv[17],
1536417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[18], cargv[19],
1537417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[20], cargv[21],
1538417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[22], cargv[23],
1539417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[24], cargv[25],
1540417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[26], cargv[27],
1541417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[28], cargv[29],
1542417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[30], cargv[31]);
1543417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1544417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1545417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (s) {
1546417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    rc = sqlite3_exec((sqlite3 *) h->sqlite, s, callback,
1547417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      h, &err);
1548417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sqlite3_free(s);
1549417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		} else {
1550417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    rc = SQLITE_NOMEM;
1551417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1552417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc = (freemem *) sqlite3_free;
1553417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1554417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1555417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		exc = (*env)->ExceptionOccurred(env);
1556417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1557417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    for (i = 0; i < nargs; i++) {
1558417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (argv[i].obj) {
1559417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    transfree(&argv[i].trans);
1560417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1561417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1562417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&sqlstr);
1563417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringUTFChars(env, sql, str);
1564417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    freep((char **) &cargv);
1565417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &h->cb);
1566417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->cb = oldcb;
1567417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
1568417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
1569417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (err && freeproc) {
1570417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    freeproc(err);
1571417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1572417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1573417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1574417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (rc != SQLITE_OK) {
1575417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		char msg[128];
1576417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1577417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		seterr(env, obj, rc);
1578417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (!err) {
1579417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sprintf(msg, "error %d in sqlite*_exec", rc);
1580417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1581417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwex(env, err ? err : msg);
1582417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1583417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (err && freeproc) {
1584417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc(err);
1585417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1586417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1587417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1588417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1589417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1590417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1591417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1592417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic hfunc *
1593417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesgetfunc(JNIEnv *env, jobject obj)
1594417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1595417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
1596417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1597417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = (*env)->GetLongField(env, obj, F_SQLite_FunctionContext_handle);
1598417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (hfunc *) v.l;
1599417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1600417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1601417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1602417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1603417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall_common(sqlite_func *sf, int isstep, int nargs, const char **args)
1604417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1605417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = (hfunc *) sqlite_user_data(sf);
1606417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1607417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->env && f->fi) {
1608417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	JNIEnv *env = f->env;
1609417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, f->fi);
1610417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid =
1611417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->GetMethodID(env, cls,
1612417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				isstep ? "step" : "function",
1613417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				"(LSQLite/FunctionContext;[Ljava/lang/String;)V");
1614417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jobjectArray arr;
1615417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int i;
1616417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1617417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
1618417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, cls);
1619417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1620417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1621417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0);
1622417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	for (i = 0; i < nargs; i++) {
1623417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (args[i]) {
1624417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transstr arg;
1625417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		jthrowable exc;
1626417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1627417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, f->h->haveutf, f->h->enc, args[i], &arg);
1628417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->SetObjectArrayElement(env, arr, i, arg.jstr);
1629417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		exc = (*env)->ExceptionOccurred(env);
1630417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (exc) {
1631417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, exc);
1632417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return;
1633417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1634417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, arg.jstr);
1635417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1636417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1637417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->sf = sf;
1638417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->CallVoidMethod(env, f->fi, mid, f->fc, arr);
1639417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, arr);
1640417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, cls);
1641417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1642417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1643417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1644417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1645417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall_func(sqlite_func *sf, int nargs, const char **args)
1646417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1647417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    call_common(sf, 0, nargs, args);
1648417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1649417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1650417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1651417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall_step(sqlite_func *sf, int nargs, const char **args)
1652417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1653417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    call_common(sf, 1, nargs, args);
1654417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1655417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1656417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1657417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall_final(sqlite_func *sf)
1658417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1659417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = (hfunc *) sqlite_user_data(sf);
1660417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1661417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->env && f->fi) {
1662417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	JNIEnv *env = f->env;
1663417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, f->fi);
1664417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid = (*env)->GetMethodID(env, cls, "last_step",
1665417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    "(LSQLite/FunctionContext;)V");
1666417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
1667417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, cls);
1668417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1669417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1670417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->sf = sf;
1671417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->CallVoidMethod(env, f->fi, mid, f->fc);
1672417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, cls);
1673417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1674417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1675417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1676417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1677417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1678417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1679417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall3_common(sqlite3_context *sf, int isstep, int nargs, sqlite3_value **args)
1680417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1681417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = (hfunc *) sqlite3_user_data(sf);
1682417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1683417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->env && f->fi) {
1684417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	JNIEnv *env = f->env;
1685417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, f->fi);
1686417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid =
1687417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->GetMethodID(env, cls,
1688417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				isstep ? "step" : "function",
1689417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				"(LSQLite/FunctionContext;[Ljava/lang/String;)V");
1690417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jobjectArray arr;
1691417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int i;
1692417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1693417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
1694417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, cls);
1695417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1696417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1697417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0);
1698417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	for (i = 0; i < nargs; i++) {
1699417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (args[i]) {
1700417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transstr arg;
1701417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		jthrowable exc;
1702417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1703417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, 1, 0, (char *) sqlite3_value_text(args[i]),
1704417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			  &arg);
1705417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->SetObjectArrayElement(env, arr, i, arg.jstr);
1706417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		exc = (*env)->ExceptionOccurred(env);
1707417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (exc) {
1708417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, exc);
1709417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return;
1710417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1711417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, arg.jstr);
1712417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1713417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1714417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->sf = sf;
1715417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->CallVoidMethod(env, f->fi, mid, f->fc, arr);
1716417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, arr);
1717417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, cls);
1718417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1719417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1720417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1721417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1722417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall3_func(sqlite3_context *sf, int nargs, sqlite3_value **args)
1723417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1724417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    call3_common(sf, 0, nargs, args);
1725417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1726417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1727417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1728417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall3_step(sqlite3_context *sf, int nargs, sqlite3_value **args)
1729417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1730417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    call3_common(sf, 1, nargs, args);
1731417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1732417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1733417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1734417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall3_final(sqlite3_context *sf)
1735417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1736417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = (hfunc *) sqlite3_user_data(sf);
1737417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1738417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->env && f->fi) {
1739417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	JNIEnv *env = f->env;
1740417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, f->fi);
1741417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid = (*env)->GetMethodID(env, cls, "last_step",
1742417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    "(LSQLite/FunctionContext;)V");
1743417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
1744417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, cls);
1745417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1746417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1747417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->sf = sf;
1748417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->CallVoidMethod(env, f->fi, mid, f->fc);
1749417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, cls);
1750417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1751417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1752417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1753417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1754417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1755417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesmkfunc_common(JNIEnv *env, int isagg, jobject obj, jstring name,
1756417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	      jint nargs, jobject fi)
1757417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1758417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1759417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1760417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
1761417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->FindClass(env, "SQLite/FunctionContext");
1762417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jobject fc;
1763417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	hfunc *f;
1764417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
1765417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr namestr;
1766417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jvalue v;
1767417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
1768417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1769417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	fc = (*env)->AllocObject(env, cls);
1770417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!fi) {
1771417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "null SQLite.Function not allowed");
1772417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1773417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1774417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f = malloc(sizeof (hfunc));
1775417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!f) {
1776417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to get SQLite.FunctionContext handle");
1777417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1778417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1779417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, fc, &f->fc);
1780417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, fi, &f->fi);
1781417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, obj, &f->db);
1782417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->h = h;
1783417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->next = h->funcs;
1784417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->funcs = f;
1785417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->sf = 0;
1786417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->env = env;
1787417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v.j = 0;
1788417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v.l = (jobject) f;
1789417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, f->fc, F_SQLite_FunctionContext_handle, v.j);
1790417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2iso(env, h->haveutf, h->enc, name, &namestr);
1791417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
1792417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
1793417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
1794417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1795417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1796417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1797417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->is3 = h->is3;
1798417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
1799417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_create_function((sqlite3 *) h->sqlite,
1800417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  namestr.result,
1801417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  (int) nargs,
1802417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  SQLITE_UTF8, f,
1803417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  isagg ? NULL : call3_func,
1804417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  isagg ? call3_step : NULL,
1805417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  isagg ? call3_final : NULL);
1806417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1807417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1808417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (isagg) {
1809417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ret = sqlite_create_aggregate((sqlite *) h->sqlite,
1810417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      namestr.result,
1811417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      (int) nargs,
1812417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      call_step, call_final, f);
1813417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
1814417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ret = sqlite_create_function((sqlite *) h->sqlite,
1815417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     namestr.result,
1816417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     (int) nargs,
1817417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     call_func, f);
1818417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1819417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1820417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1821417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1822417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (isagg) {
1823417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite_create_aggregate((sqlite *) h->sqlite, namestr.result,
1824417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  (int) nargs,
1825417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  call_step, call_final, f);
1826417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1827417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite_create_function((sqlite *) h->sqlite, namestr.result,
1828417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 (int) nargs,
1829417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 call_func, f);
1830417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1831417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1832417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1833417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_create_function((sqlite3 *) h->sqlite,
1834417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      namestr.result,
1835417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      (int) nargs,
1836417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      SQLITE_UTF8, f,
1837417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      isagg ? NULL : call3_func,
1838417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      isagg ? call3_step : NULL,
1839417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      isagg ? call3_final : NULL);
1840417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1841417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1842417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&namestr);
1843417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
1844417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "error creating function/aggregate");
1845417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1846417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1847417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1848417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1849417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1850417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1851417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1852417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1create_1aggregate(JNIEnv *env, jobject obj,
1853417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 jstring name, jint nargs, jobject fi)
1854417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1855417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    mkfunc_common(env, 1, obj, name, nargs, fi);
1856417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1857417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1858417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1859417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1create_1function(JNIEnv *env, jobject obj,
1860417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					jstring name, jint nargs, jobject fi)
1861417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1862417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    mkfunc_common(env, 0, obj, name, nargs, fi);
1863417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1864417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1865417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1866417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1function_1type(JNIEnv *env, jobject obj,
1867417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      jstring name, jint type)
1868417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1869417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1870417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1871417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
1872417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1873417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
1874417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1875417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1876417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1877417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1878417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_FUNCTION_TYPE
1879417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	{
1880417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    int ret;
1881417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr namestr;
1882417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jthrowable exc;
1883417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1884417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2iso(env, h->haveutf, h->enc, name, &namestr);
1885417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
1886417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
1887417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
1888417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1889417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1890417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite_function_type(h->sqlite, namestr.result, (int) type);
1891417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&namestr);
1892417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ret != SQLITE_OK) {
1893417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwex(env, sqlite_error_string(ret));
1894417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1895417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1896417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1897417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1898417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1899417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1900417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1901417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1902417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1903417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
1904417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_count(JNIEnv *env, jobject obj)
1905417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1906417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
1907417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jint r = 0;
1908417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1909417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
1910417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_BOTH
1911417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (f->is3) {
1912417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    r = (jint) sqlite3_aggregate_count((sqlite3_context *) f->sf);
1913417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1914417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    r = (jint) sqlite_aggregate_count((sqlite_func *) f->sf);
1915417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1916417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1917417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1918417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	r = (jint) sqlite_aggregate_count((sqlite_func *) f->sf);
1919417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1920417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1921417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	r = (jint) sqlite3_aggregate_count((sqlite3_context *) f->sf);
1922417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1923417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1924417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1925417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return r;
1926417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1927417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1928417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1929417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1error(JNIEnv *env, jobject obj, jstring err)
1930417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1931417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
1932417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1933417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
1934417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1935417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!f->is3) {
1936417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr errstr;
1937417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jthrowable exc;
1938417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1939417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2iso(env, f->h->haveutf, f->h->enc, err, &errstr);
1940417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
1941417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
1942417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	        (*env)->DeleteLocalRef(env, exc);
1943417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1944417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1945417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_set_result_error((sqlite_func *) f->sf,
1946417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    errstr.result, -1);
1947417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&errstr);
1948417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else if (err) {
1949417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jsize len = (*env)->GetStringLength(env, err) * sizeof (jchar);
1950417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const jchar *str = (*env)->GetStringChars(env, err, 0);
1951417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1952417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_error16((sqlite3_context *) f->sf, str, len);
1953417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringChars(env, err, str);
1954417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1955417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_error((sqlite3_context *) f->sf,
1956417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 "null error text", -1);
1957417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1958417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1959417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1960417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr errstr;
1961417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
1962417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1963417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2iso(env, f->h->haveutf, f->h->enc, err, &errstr);
1964417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
1965417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
1966417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
1967417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1968417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1969417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_set_result_error((sqlite_func *) f->sf, errstr.result, -1);
1970417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&errstr);
1971417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1972417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1973417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (err) {
1974417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jsize len = (*env)->GetStringLength(env, err) * sizeof (jchar);
1975417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const jchar *str = (*env)->GetStringChars(env, err, 0);
1976417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1977417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_error16((sqlite3_context *) f->sf, str, len);
1978417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringChars(env, err, str);
1979417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1980417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_error((sqlite3_context *) f->sf,
1981417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 "null error text", -1);
1982417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1983417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1984417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1985417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1986417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1987417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1988417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1989417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1result__D(JNIEnv *env, jobject obj, jdouble d)
1990417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1991417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
1992417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1993417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
1994417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1995417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (f->is3) {
1996417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_double((sqlite3_context *) f->sf, (double) d);
1997417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1998417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_set_result_double((sqlite_func *) f->sf, (double) d);
1999417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2000417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2001417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2002417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_set_result_double((sqlite_func *) f->sf, (double) d);
2003417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2004417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2005417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_result_double((sqlite3_context *) f->sf, (double) d);
2006417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2007417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2008417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2009417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2010417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2011417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2012417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1result__I(JNIEnv *env, jobject obj, jint i)
2013417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2014417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
2015417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2016417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
2017417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2018417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (f->is3) {
2019417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_int((sqlite3_context *) f->sf, (int) i);
2020417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2021417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_set_result_int((sqlite_func *) f->sf, (int) i);
2022417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2023417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2024417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2025417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_set_result_int((sqlite_func *) f->sf, (int) i);
2026417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2027417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2028417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_result_int((sqlite3_context *) f->sf, (int) i);
2029417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2030417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2031417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2032417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2033417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2034417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2035417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1result__Ljava_lang_String_2(JNIEnv *env,
2036417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes							     jobject obj,
2037417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes							     jstring ret)
2038417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2039417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
2040417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2041417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
2042417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2043417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!f->is3) {
2044417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr retstr;
2045417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jthrowable exc;
2046417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2047417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2iso(env, f->h->haveutf, f->h->enc, ret, &retstr);
2048417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2049417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
2050417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	        (*env)->DeleteLocalRef(env, exc);
2051417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
2052417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2053417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_set_result_string((sqlite_func *) f->sf,
2054417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				     retstr.result, -1);
2055417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&retstr);
2056417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else if (ret) {
2057417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jsize len = (*env)->GetStringLength(env, ret) * sizeof (jchar);
2058417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const jchar *str = (*env)->GetStringChars(env, ret, 0);
2059417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2060417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_text16((sqlite3_context *) f->sf, str, len,
2061417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  SQLITE_TRANSIENT);
2062417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringChars(env, ret, str);
2063417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2064417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_null((sqlite3_context *) f->sf);
2065417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2066417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2067417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2068417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr retstr;
2069417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
2070417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2071417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2iso(env, f->h->haveutf, f->h->enc, ret, &retstr);
2072417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
2073417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
2074417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
2075417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
2076417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2077417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_set_result_string((sqlite_func *) f->sf, retstr.result, -1);
2078417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&retstr);
2079417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2080417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2081417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret) {
2082417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jsize len = (*env)->GetStringLength(env, ret) * sizeof (jchar);
2083417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const jchar *str = (*env)->GetStringChars(env, ret, 0);
2084417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2085417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_text16((sqlite3_context *) f->sf, str, len,
2086417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  SQLITE_TRANSIENT);
2087417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringChars(env, ret, str);
2088417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2089417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_null((sqlite3_context *) f->sf);
2090417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2091417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2092417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2093417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2094417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2095417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2096417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2097417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1result___3B(JNIEnv *env, jobject obj,
2098417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     jbyteArray b)
2099417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2100417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2101417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
2102417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2103417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
2104417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2105417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!f->is3) {
2106417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    /* silently ignored */
2107417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
2108417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2109417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2110417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (b) {
2111417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jsize len;
2112417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jbyte *data;
2113417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2114417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    len = (*env)->GetArrayLength(env, b);
2115417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    data = (*env)->GetByteArrayElements(env, b, 0);
2116417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_blob((sqlite3_context *) f->sf,
2117417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				data, len, SQLITE_TRANSIENT);
2118417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseByteArrayElements(env, b, data, 0);
2119417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2120417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_null((sqlite3_context *) f->sf);
2121417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2122417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2123417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2124417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2125417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2126417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2127417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1result_1zeroblob(JNIEnv *env, jobject obj,
2128417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						  jint n)
2129417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2130417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_RESULT_ZEROBLOB
2131417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
2132417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2133417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
2134417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2135417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!f->is3) {
2136417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    /* silently ignored */
2137417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
2138417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2139417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2140417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_result_zeroblob((sqlite3_context *) f->sf, n);
2141417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2142417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2143417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2144417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2145417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
2146417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_error_1string(JNIEnv *env, jclass c, jint err)
2147417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2148417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2149417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, sqlite_error_string((int) err));
2150417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2151417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, "unkown error");
2152417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2153417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2154417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2155417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
2156417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1errmsg(JNIEnv *env, jobject obj)
2157417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2158417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2159417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
2160417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2161417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
2162417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2163417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!h->is3) {
2164417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
2165417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2166417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2167417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (*env)->NewStringUTF(env,
2168417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    sqlite3_errmsg((sqlite3 *) h->sqlite));
2169417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2170417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2171417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
2172417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2173417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2174417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2175417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1set_1encoding(JNIEnv *env, jobject obj, jstring enc)
2176417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2177417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
2178417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2179417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && !h->haveutf) {
2180417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2181417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!h->is3) {
2182417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &h->enc);
2183417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->enc = enc;
2184417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    globrefset(env, enc, &h->enc);
2185417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2186417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2187417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2188417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->enc);
2189417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->enc = enc;
2190417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, enc, &h->enc);
2191417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2192417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2193417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2194417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2195417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2196417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_SET_AUTHORIZER
2197417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
2198417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdoauth(void *arg, int what, const char *arg1, const char *arg2,
2199417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes       const char *arg3, const char *arg4)
2200417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2201417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) arg;
2202417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
2203417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2204417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->ai) {
2205417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
2206417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->ai);
2207417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid;
2208417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jint i = what;
2209417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2210417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	mid = (*env)->GetMethodID(env, cls, "authorize",
2211417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I");
2212417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid) {
2213417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jstring s1 = 0, s2 = 0, s3 = 0, s4 = 0;
2214417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr tr;
2215417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2216417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (arg1) {
2217417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, h->haveutf, h->enc, arg1, &tr);
2218417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		s1 = tr.jstr;
2219417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2220417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2221417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
2222417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
2223417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return SQLITE_DENY;
2224417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2225417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (arg2) {
2226417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, h->haveutf, h->enc, arg2, &tr);
2227417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		s2 = tr.jstr;
2228417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2229417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (arg3) {
2230417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, h->haveutf, h->enc, arg3, &tr);
2231417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		s3 = tr.jstr;
2232417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2233417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (arg4) {
2234417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, h->haveutf, h->enc, arg4, &tr);
2235417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		s4 = tr.jstr;
2236417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2237417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2238417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
2239417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
2240417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return SQLITE_DENY;
2241417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2242417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    i = (*env)->CallIntMethod(env, h->ai, mid, i, s1, s2, s3, s4);
2243417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2244417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
2245417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
2246417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return SQLITE_DENY;
2247417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2248417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, s4);
2249417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, s3);
2250417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, s2);
2251417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, s1);
2252417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (i != SQLITE_OK && i != SQLITE_IGNORE) {
2253417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		i = SQLITE_DENY;
2254417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2255417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (int) i;
2256417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2257417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2258417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return SQLITE_DENY;
2259417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2260417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2261417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2262417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2263417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1set_1authorizer(JNIEnv *env, jobject obj, jobject auth)
2264417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2265417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
2266417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2267417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
2268417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->ai);
2269417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, auth, &h->ai);
2270417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_SET_AUTHORIZER
2271417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->env = env;
2272417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2273417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
2274417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_set_authorizer((sqlite3 *) h->sqlite,
2275417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				   h->ai ? doauth : 0, h);
2276417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2277417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_set_authorizer((sqlite *) h->sqlite,
2278417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  h->ai ? doauth : 0, h);
2279417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2280417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2281417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2282417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_set_authorizer((sqlite *) h->sqlite, h->ai ? doauth : 0, h);
2283417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2284417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2285417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_set_authorizer((sqlite3 *) h->sqlite, h->ai ? doauth : 0, h);
2286417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2287417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2288417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2289417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2290417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2291417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
2292417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2293417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2294417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_TRACE
2295417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
2296417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdotrace(void *arg, const char *msg)
2297417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2298417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) arg;
2299417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
2300417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2301417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->tr && msg) {
2302417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
2303417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->tr);
2304417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid;
2305417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2306417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	mid = (*env)->GetMethodID(env, cls, "trace", "(Ljava/lang/String;)V");
2307417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid) {
2308417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr tr;
2309417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2310417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2utf(env, h->haveutf, h->enc, msg, &tr);
2311417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2312417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
2313417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
2314417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->ExceptionClear(env);
2315417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
2316417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2317417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->CallVoidMethod(env, h->tr, mid, tr.jstr);
2318417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ExceptionClear(env);
2319417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, tr.jstr);
2320417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
2321417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2322417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2323417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return;
2324417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2325417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2326417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2327417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2328417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1trace(JNIEnv *env, jobject obj, jobject tr)
2329417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2330417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
2331417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2332417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
2333417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->tr);
2334417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, tr, &h->tr);
2335417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2336417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
2337417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_trace((sqlite3 *) h->sqlite, h->tr ? dotrace : 0, h);
2338417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2339417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_TRACE
2340417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_trace((sqlite *) h->sqlite, h->tr ? dotrace : 0, h);
2341417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2342417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2343417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2344417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2345417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_TRACE
2346417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_trace((sqlite *) h->sqlite, h->tr ? dotrace : 0, h);
2347417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2348417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2349417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2350417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_trace((sqlite3 *) h->sqlite, h->tr ? dotrace : 0, h);
2351417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2352417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2353417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2354417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2355417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
2356417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2357417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2358417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2359417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
2360417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdovmfinal(JNIEnv *env, jobject obj, int final)
2361417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2362417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethvm(env, obj);
2363417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2364417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v) {
2365417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->h) {
2366417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    handle *h = v->h;
2367417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    hvm *vv, **vvp;
2368417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2369417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vvp = &h->vms;
2370417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vv = *vvp;
2371417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    while (vv) {
2372417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (vv == v) {
2373417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    *vvp = vv->next;
2374417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    break;
2375417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2376417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		vvp = &vv->next;
2377417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		vv = *vvp;
2378417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2379417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2380417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->vm) {
2381417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2382417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (v->is3) {
2383417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) v->vm);
2384417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
2385417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_finalize((sqlite_vm *) v->vm, 0);
2386417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2387417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2388417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2389417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) v->vm, 0);
2390417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2391417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2392417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) v->vm);
2393417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2394417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2395417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->vm = 0;
2396417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2397417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(v);
2398417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, obj, F_SQLite_Vm_handle, 0);
2399417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2400417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2401417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!final) {
2402417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "vm already closed");
2403417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2404417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2405417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2406417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2407417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2408417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
2409417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdostmtfinal(JNIEnv *env, jobject obj)
2410417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2411417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
2412417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2413417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v) {
2414417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->h) {
2415417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    handle *h = v->h;
2416417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    hvm *vv, **vvp;
2417417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2418417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vvp = &h->vms;
2419417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vv = *vvp;
2420417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    while (vv) {
2421417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (vv == v) {
2422417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    *vvp = vv->next;
2423417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    break;
2424417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2425417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		vvp = &vv->next;
2426417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		vv = *vvp;
2427417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2428417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2429417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->vm) {
2430417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) v->vm);
2431417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2432417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = 0;
2433417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(v);
2434417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, obj, F_SQLite_Stmt_handle, 0);
2435417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2436417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2437417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2438417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2439417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
2440417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
2441417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdoblobfinal(JNIEnv *env, jobject obj)
2442417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2443417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hbl *bl = gethbl(env, obj);
2444417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2445417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (bl) {
2446417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (bl->h) {
2447417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    handle *h = bl->h;
2448417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    hbl *blc, **blp;
2449417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2450417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    blp = &h->blobs;
2451417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    blc = *blp;
2452417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    while (blc) {
2453417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (blc == bl) {
2454417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    *blp = blc->next;
2455417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    break;
2456417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2457417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		blp = &blc->next;
2458417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		blc = *blp;
2459417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2460417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2461417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (bl->blob) {
2462417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_blob_close(bl->blob);
2463417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2464417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bl->blob = 0;
2465417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(bl);
2466417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, obj, F_SQLite_Blob_handle, 0);
2467417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetIntField(env, obj, F_SQLite_Blob_size, 0);
2468417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2469417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2470417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2471417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2472417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2473417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Vm_stop(JNIEnv *env, jobject obj)
2474417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2475417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2476417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dovmfinal(env, obj, 0);
2477417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2478417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
2479417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2480417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2481417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2482417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2483417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Vm_finalize(JNIEnv *env, jobject obj)
2484417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2485417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2486417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dovmfinal(env, obj, 1);
2487417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2488417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2489417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2490417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2491417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2492417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
2493417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesfree_tab(void *mem)
2494417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2495417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char **p = (char **) mem;
2496417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int i, n;
2497417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2498417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!p) {
2499417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2500417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2501417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    p -= 1;
2502417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    mem = (void *) p;
2503417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    n = ((int *) p)[0];
2504417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    p += n * 2 + 2 + 1;
2505417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    for (i = 0; i < n; i++) {
2506417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (p[i]) {
2507417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    free(p[i]);
2508417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2509417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2510417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    free(mem);
2511417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2512417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2513417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2514417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2515417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
2516417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Vm_step(JNIEnv *env, jobject obj, jobject cb)
2517417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2518417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2519417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethvm(env, obj);
2520417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2521417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
2522417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
2523417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret, ncol = 0;
2524417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2525417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	freemem *freeproc = 0;
2526417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char **blob = 0;
2527417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2528417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char **data = 0, **cols = 0;
2529417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2530417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->h->env = env;
2531417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2532417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->is3) {
2533417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_step((sqlite3_stmt *) v->vm);
2534417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ret == SQLITE_ROW) {
2535417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
2536417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (ncol > 0) {
2537417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
2538417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (data) {
2539417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			data[0] = (const char *) ncol;
2540417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			++data;
2541417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			cols = data + ncol + 1;
2542417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			blob = cols + ncol + 1;
2543417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			freeproc = free_tab;
2544417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    } else {
2545417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			ret = SQLITE_NOMEM;
2546417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
2547417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2548417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (ret != SQLITE_NOMEM) {
2549417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    int i;
2550417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2551417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    for (i = 0; i < ncol; i++) {
2552417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			cols[i] =
2553417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_column_name((sqlite3_stmt *) v->vm, i);
2554417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (sqlite3_column_type((sqlite3_stmt *) v->vm, i)
2555417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    == SQLITE_BLOB) {
2556417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    unsigned char *src = (unsigned char *)
2557417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				sqlite3_column_blob((sqlite3_stmt *) v->vm, i);
2558417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    int n =
2559417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				sqlite3_column_bytes((sqlite3_stmt *) v->vm,
2560417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						     i);
2561417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2562417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    if (src) {
2563417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				data[i] = malloc(n * 2 + 4);
2564417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				if (data[i]) {
2565417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    int k;
2566417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    char *p = (char *) data[i];
2567417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2568417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    blob[i] = data[i];
2569417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = 'X';
2570417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = '\'';
2571417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    for (k = 0; k < n; k++) {
2572417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					*p++ = xdigits[src[k] >> 4];
2573417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					*p++ = xdigits[src[k] & 0x0F];
2574417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    }
2575417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = '\'';
2576417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = '\0';
2577417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				}
2578417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
2579417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			} else {
2580417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    data[i] = (const char *)
2581417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				sqlite3_column_text((sqlite3_stmt *) v->vm, i);
2582417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
2583417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
2584417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2585417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2586417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2587417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite_step((sqlite_vm *) v->vm, &ncol, &data, &cols);
2588417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2589417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2590417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2591417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite_step((sqlite_vm *) v->vm, &ncol, &data, &cols);
2592417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2593417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2594417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_step((sqlite3_stmt *) v->vm);
2595417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret == SQLITE_ROW) {
2596417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
2597417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ncol > 0) {
2598417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
2599417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (data) {
2600417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    data[0] = (const char *) ncol;
2601417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    ++data;
2602417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    cols = data + ncol + 1;
2603417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    blob = cols + ncol + 1;
2604417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    freeproc = free_tab;
2605417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		} else {
2606417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    ret = SQLITE_NOMEM;
2607417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2608417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2609417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ret != SQLITE_NOMEM) {
2610417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		int i;
2611417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2612417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < ncol; i++) {
2613417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    cols[i] = sqlite3_column_name((sqlite3_stmt *) v->vm, i);
2614417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (sqlite3_column_type((sqlite3_stmt *) v->vm, i)
2615417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			== SQLITE_BLOB) {
2616417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			unsigned char *src = (unsigned char *)
2617417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_column_blob((sqlite3_stmt *) v->vm, i);
2618417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			int n =
2619417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_column_bytes((sqlite3_stmt *) v->vm, i);
2620417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2621417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (src) {
2622417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    data[i] = malloc(n * 2 + 4);
2623417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    if (data[i]) {
2624417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				int k;
2625417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				char *p = (char *) data[i];
2626417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2627417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				blob[i] = data[i];
2628417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				*p++ = 'X';
2629417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				*p++ = '\'';
2630417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				for (k = 0; k < n; k++) {
2631417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = xdigits[src[k] >> 4];
2632417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = xdigits[src[k] & 0x0F];
2633417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				}
2634417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				*p++ = '\'';
2635417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				*p++ = '\0';
2636417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
2637417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
2638417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    } else {
2639417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			data[i] = (char *)
2640417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_column_text((sqlite3_stmt *) v->vm, i);
2641417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
2642417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2643417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2644417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2645417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2646417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2647417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret == SQLITE_ROW) {
2648417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.cb = cb;
2649417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.env = env;
2650417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2651417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (v->is3) {
2652417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		v->hh.stmt = (sqlite3_stmt *) v->vm;
2653417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2654417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2655417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2656417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.stmt = (sqlite3_stmt *) v->vm;
2657417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2658417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2659417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    callback((void *) &v->hh, ncol, (char **) data, (char **) cols);
2660417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2661417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (data && freeproc) {
2662417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc((void *) data);
2663417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2664417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2665417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2666417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
2667417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
2668417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		goto dofin;
2669417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2670417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_TRUE;
2671417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else if (ret == SQLITE_DONE) {
2672417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdofin:
2673417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2674417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (v->is3) {
2675417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) v->vm);
2676417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
2677417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_finalize((sqlite_vm *) v->vm, 0);
2678417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2679417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2680417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2681417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) v->vm, 0);
2682417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2683417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2684417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) v->vm);
2685417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2686417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2687417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->vm = 0;
2688417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
2689417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2690417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2691417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->is3) {
2692417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) v->vm);
2693417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2694417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) v->vm, 0);
2695417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2696417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2697417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2698417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_finalize((sqlite_vm *) v->vm, 0);
2699417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2700417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2701417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_finalize((sqlite3_stmt *) v->vm);
2702417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2703417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2704417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	setvmerr(env, obj, ret);
2705417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = 0;
2706417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "error in step");
2707417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_FALSE;
2708417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2709417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "vm already closed");
2710417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2711417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
2712417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2713417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
2714417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2715417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2716417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
2717417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Vm_compile(JNIEnv *env, jobject obj)
2718417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2719417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2720417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethvm(env, obj);
2721417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *svm = 0;
2722417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *err = 0;
2723417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    const char *tail;
2724417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
2725417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2726417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm) {
2727417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2728417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->is3) {
2729417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) v->vm);
2730417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2731417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) v->vm, 0);
2732417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2733417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2734417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2735417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_finalize((sqlite_vm *) v->vm, 0);
2736417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2737417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2738417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_finalize((sqlite3_stmt *) v->vm);
2739417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2740417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2741417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = 0;
2742417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2743417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->h && v->h->sqlite) {
2744417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!v->tail) {
2745417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
2746417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2747417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->h->env = env;
2748417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2749417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->is3) {
2750417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE_V2
2751417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_prepare_v2((sqlite3 *) v->h->sqlite, v->tail, -1,
2752417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				     (sqlite3_stmt **) &svm, &tail);
2753417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2754417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_prepare((sqlite3 *) v->h->sqlite, v->tail, -1,
2755417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  (sqlite3_stmt **) &svm, &tail);
2756417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2757417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ret != SQLITE_OK) {
2758417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (svm) {
2759417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sqlite3_finalize((sqlite3_stmt *) svm);
2760417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    svm = 0;
2761417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2762417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2763417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2764417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite_compile((sqlite *) v->h->sqlite, v->tail,
2765417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 &tail, (sqlite_vm **) &svm, &err);
2766417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ret != SQLITE_OK) {
2767417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (svm) {
2768417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sqlite_finalize((sqlite_vm *) svm, 0);
2769417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    svm = 0;
2770417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2771417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2772417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2773417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2774417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2775417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite_compile((sqlite *) v->h->sqlite, v->tail,
2776417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			     &tail, (sqlite_vm **) &svm, &err);
2777417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
2778417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (svm) {
2779417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_finalize((sqlite_vm *) svm, 0);
2780417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		svm = 0;
2781417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2782417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2783417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2784417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2785417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE_V2
2786417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare_v2((sqlite3 *) v->h->sqlite,
2787417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 v->tail, -1, (sqlite3_stmt **) &svm, &tail);
2788417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2789417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare((sqlite3 *) v->h->sqlite,
2790417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			      v->tail, -1, (sqlite3_stmt **) &svm, &tail);
2791417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2792417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
2793417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (svm) {
2794417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) svm);
2795417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		svm = 0;
2796417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2797417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2798417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2799417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2800417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
2801417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setvmerr(env, obj, ret);
2802417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->tail = 0;
2803417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : "error in compile/prepare");
2804417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2805417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (err) {
2806417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_freemem(err);
2807417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2808417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2809417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
2810417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2811417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2812417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (err) {
2813417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_freemem(err);
2814417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2815417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2816417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!svm) {
2817417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->tail = 0;
2818417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
2819417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2820417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = svm;
2821417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->tail = (char *) tail;
2822417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->hh.row1 = 1;
2823417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_TRUE;
2824417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2825417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "vm already closed");
2826417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2827417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
2828417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2829417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
2830417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2831417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2832417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2833417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_vm_1compile(JNIEnv *env, jobject obj, jstring sql,
2834417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 jobject vm)
2835417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2836417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2837417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
2838417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *svm = 0;
2839417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v;
2840417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *err = 0;
2841417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    const char *tail;
2842417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transstr tr;
2843417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue vv;
2844417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
2845417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jthrowable exc;
2846417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2847417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!h) {
2848417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwclosed(env);
2849417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2850417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2851417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!vm) {
2852417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null vm");
2853417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2854417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2855417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
2856417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null sql");
2857417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2858417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2859417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    trans2iso(env, h->haveutf, h->enc, sql, &tr);
2860417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    exc = (*env)->ExceptionOccurred(env);
2861417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (exc) {
2862417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, exc);
2863417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2864417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2865417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->env = env;
2866417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2867417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h->is3) {
2868417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE_V2
2869417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare_v2((sqlite3 *) h->sqlite, tr.result, -1,
2870417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 (sqlite3_stmt **) &svm, &tail);
2871417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2872417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare((sqlite3 *) h->sqlite, tr.result, -1,
2873417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			      (sqlite3_stmt **) &svm, &tail);
2874417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2875417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
2876417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (svm) {
2877417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) svm);
2878417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		svm = 0;
2879417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2880417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2881417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
2882417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite_compile((sqlite *) h->sqlite, tr.result, &tail,
2883417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			     (sqlite_vm **) &svm, &err);
2884417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
2885417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (svm) {
2886417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_finalize((sqlite_vm *) svm, 0);
2887417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2888417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2889417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2890417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2891417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2892417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ret = sqlite_compile((sqlite *) h->sqlite, tr.result, &tail,
2893417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			 (sqlite_vm **) &svm, &err);
2894417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ret != SQLITE_OK) {
2895417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (svm) {
2896417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) svm, 0);
2897417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    svm = 0;
2898417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2899417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2900417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2901417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2902417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE_V2
2903417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ret = sqlite3_prepare_v2((sqlite3 *) h->sqlite, tr.result, -1,
2904417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			     (sqlite3_stmt **) &svm, &tail);
2905417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2906417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ret = sqlite3_prepare((sqlite3 *) h->sqlite, tr.result, -1,
2907417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			  (sqlite3_stmt **) &svm, &tail);
2908417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2909417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ret != SQLITE_OK) {
2910417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (svm) {
2911417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) svm);
2912417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    svm = 0;
2913417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2914417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2915417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2916417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2917417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ret != SQLITE_OK) {
2918417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&tr);
2919417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	setvmerr(env, vm, ret);
2920417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, err ? err : "error in prepare/compile");
2921417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2922417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (err) {
2923417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_freemem(err);
2924417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2925417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2926417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2927417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2928417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2929417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (err) {
2930417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_freemem(err);
2931417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2932417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2933417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!svm) {
2934417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&tr);
2935417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2936417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2937417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v = malloc(sizeof (hvm) + strlen(tail) + 1);
2938417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!v) {
2939417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&tr);
2940417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2941417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
2942417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) svm);
2943417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2944417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) svm, 0);
2945417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2946417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2947417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2948417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_finalize((sqlite_vm *) svm, 0);
2949417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2950417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2951417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_finalize((sqlite3_stmt *) svm);
2952417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2953417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2954417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwoom(env, "unable to get SQLite handle");
2955417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2956417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2957417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->next = h->vms;
2958417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->vms = v;
2959417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->vm = svm;
2960417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->h = h;
2961417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->tail = (char *) (v + 1);
2962417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2963417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->is3 = v->hh.is3 = h->is3;
2964417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2965417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    strcpy(v->tail, tail);
2966417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.sqlite = 0;
2967417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.haveutf = h->haveutf;
2968417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.ver = h->ver;
2969417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.bh = v->hh.cb = v->hh.ai = v->hh.tr = v->hh.ph = 0;
2970417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.row1 = 1;
2971417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.enc = h->enc;
2972417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.funcs = 0;
2973417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.vms = 0;
2974417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.env = 0;
2975417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    vv.j = 0;
2976417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    vv.l = (jobject) v;
2977417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->SetLongField(env, vm, F_SQLite_Vm_handle, vv.j);
2978417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2979417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
2980417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2981417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2982417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2983417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2984417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_vm_1compile_1args(JNIEnv *env,
2985417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				       jobject obj, jstring sql,
2986417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				       jobject vm, jobjectArray args)
2987417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2988417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2989417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2990417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
2991417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2992417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2993417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2994417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && !h->is3) {
2995417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "unsupported");
2996417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2997417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2998417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2999417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
3000417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3001417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3002417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3003417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3004417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!h || !h->sqlite) {
3005417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwclosed(env);
3006417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3007417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3008417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!vm) {
3009417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null vm");
3010417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3011417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3012417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
3013417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null sql");
3014417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3015417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3016417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	void *svm = 0;
3017417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	hvm *v;
3018417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jvalue vv;
3019417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
3020417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int rc = SQLITE_ERROR, nargs, i;
3021417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	char *p;
3022417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char *str = (*env)->GetStringUTFChars(env, sql, NULL);
3023417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char *tail;
3024417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr sqlstr;
3025417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	struct args {
3026417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char *arg;
3027417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jobject obj;
3028417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr trans;
3029417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} *argv = 0;
3030417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	char **cargv = 0;
3031417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3032417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	p = (char *) str;
3033417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	nargs = 0;
3034417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	while (*p) {
3035417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (*p == '%') {
3036417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		++p;
3037417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (*p == 'q' || *p == 'Q' || *p == 's') {
3038417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    nargs++;
3039417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (nargs > MAX_PARAMS) {
3040417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->ReleaseStringUTFChars(env, sql, str);
3041417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			throwex(env, "too much SQL parameters");
3042417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			return;
3043417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
3044417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		} else if (*p != '%') {
3045417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->ReleaseStringUTFChars(env, sql, str);
3046417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    throwex(env, "bad % specification in query");
3047417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return;
3048417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3049417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3050417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ++p;
3051417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3052417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	cargv = malloc((sizeof (*argv) + sizeof (char *)) * MAX_PARAMS);
3053417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!cargv) {
3054417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringUTFChars(env, sql, str);
3055417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to allocate arg vector");
3056417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3057417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3058417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	argv = (struct args *) (cargv + MAX_PARAMS);
3059417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	for (i = 0; i < MAX_PARAMS; i++) {
3060417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    cargv[i] = 0;
3061417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    argv[i].arg = 0;
3062417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    argv[i].obj = 0;
3063417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    argv[i].trans.result = argv[i].trans.tofree = 0;
3064417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3065417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = 0;
3066417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	for (i = 0; i < nargs; i++) {
3067417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jobject so = (*env)->GetObjectArrayElement(env, args, i);
3068417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3069417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
3070417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
3071417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
3072417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		break;
3073417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3074417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (so) {
3075417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		argv[i].obj = so;
3076417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		argv[i].arg = cargv[i] =
3077417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    trans2iso(env, 1, 0, argv[i].obj, &argv[i].trans);
3078417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3079417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3080417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
3081417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    for (i = 0; i < nargs; i++) {
3082417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (argv[i].obj) {
3083417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    transfree(&argv[i].trans);
3084417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3085417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3086417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    freep((char **) &cargv);
3087417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringUTFChars(env, sql, str);
3088417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3089417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3090417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->row1 = 1;
3091417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2iso(env, 1, 0, sql, &sqlstr);
3092417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
3093417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!exc) {
3094417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
3095417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char *s = sqlite3_vmprintf(sqlstr.result, (char *) cargv);
3096417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3097417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char *s = sqlite3_mprintf(sqlstr.result,
3098417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[0], cargv[1],
3099417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[2], cargv[3],
3100417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[4], cargv[5],
3101417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[6], cargv[7],
3102417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[8], cargv[9],
3103417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[10], cargv[11],
3104417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[12], cargv[13],
3105417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[14], cargv[15],
3106417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[16], cargv[17],
3107417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[18], cargv[19],
3108417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[20], cargv[21],
3109417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[22], cargv[23],
3110417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[24], cargv[25],
3111417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[26], cargv[27],
3112417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[28], cargv[29],
3113417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[30], cargv[31]);
3114417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3115417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (!s) {
3116417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = SQLITE_NOMEM;
3117417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
3118417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE_V2
3119417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite3_prepare_v2((sqlite3 *) h->sqlite, s, -1,
3120417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					(sqlite3_stmt **) &svm, &tail);
3121417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3122417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite3_prepare((sqlite3 *) h->sqlite, s, -1,
3123417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      (sqlite3_stmt **) &svm, &tail);
3124417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3125417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (rc != SQLITE_OK) {
3126417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (svm) {
3127417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			sqlite3_finalize((sqlite3_stmt *) svm);
3128417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			svm = 0;
3129417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
3130417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3131417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3132417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (rc != SQLITE_OK) {
3133417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_free(s);
3134417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < nargs; i++) {
3135417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (argv[i].obj) {
3136417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			transfree(&argv[i].trans);
3137417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
3138417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3139417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freep((char **) &cargv);
3140417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transfree(&sqlstr);
3141417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->ReleaseStringUTFChars(env, sql, str);
3142417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		setvmerr(env, vm, rc);
3143417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwex(env, "error in prepare");
3144417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
3145417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3146417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v = malloc(sizeof (hvm) + strlen(tail) + 1);
3147417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (!v) {
3148417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_free(s);
3149417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < nargs; i++) {
3150417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (argv[i].obj) {
3151417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			transfree(&argv[i].trans);
3152417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
3153417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3154417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freep((char **) &cargv);
3155417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transfree(&sqlstr);
3156417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->ReleaseStringUTFChars(env, sql, str);
3157417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) svm);
3158417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		setvmerr(env, vm, SQLITE_NOMEM);
3159417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwoom(env, "unable to get SQLite handle");
3160417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
3161417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3162417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->next = h->vms;
3163417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->vms = v;
3164417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->vm = svm;
3165417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->h = h;
3166417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->tail = (char *) (v + 1);
3167417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3168417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->is3 = v->hh.is3 = h->is3;
3169417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3170417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    strcpy(v->tail, tail);
3171417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_free(s);
3172417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.sqlite = 0;
3173417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.haveutf = h->haveutf;
3174417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.ver = h->ver;
3175417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.bh = v->hh.cb = v->hh.ai = v->hh.tr = v->hh.ph = 0;
3176417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.row1 = 1;
3177417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.enc = h->enc;
3178417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.funcs = 0;
3179417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.vms = 0;
3180417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.env = 0;
3181417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vv.j = 0;
3182417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vv.l = (jobject) v;
3183417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->SetLongField(env, vm, F_SQLite_Vm_handle, vv.j);
3184417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3185417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	for (i = 0; i < nargs; i++) {
3186417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (argv[i].obj) {
3187417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transfree(&argv[i].trans);
3188417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3189417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3190417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	freep((char **) &cargv);
3191417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&sqlstr);
3192417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->ReleaseStringUTFChars(env, sql, str);
3193417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
3194417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
3195417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3196417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3197417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3198417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3199417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3200417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3201417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3202417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3203417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3204417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_internal_1init(JNIEnv *env, jclass cls)
3205417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3206417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_FunctionContext_handle =
3207417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "handle", "J");
3208417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3209417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3210417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3211417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1progress_1handler(JNIEnv *env, jobject obj, jint n,
3212417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 jobject ph)
3213417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3214417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
3215417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3216417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
3217417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	/* CHECK THIS */
3218417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_PROGRESS_HANDLER
3219417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->ph);
3220417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3221417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
3222417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ph) {
3223417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		globrefset(env, ph, &h->ph);
3224417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_progress_handler((sqlite3 *) h->sqlite,
3225417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 n, progresshandler, h);
3226417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
3227417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_progress_handler((sqlite3 *) h->sqlite,
3228417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 0, 0, 0);
3229417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3230417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3231417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ph) {
3232417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		globrefset(env, ph, &h->ph);
3233417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_progress_handler((sqlite *) h->sqlite,
3234417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					n, progresshandler, h);
3235417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
3236417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_progress_handler((sqlite *) h->sqlite,
3237417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					0, 0, 0);
3238417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3239417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3240417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3241417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
3242417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ph) {
3243417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    globrefset(env, ph, &h->ph);
3244417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_progress_handler((sqlite *) h->sqlite,
3245417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    n, progresshandler, h);
3246417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3247417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_progress_handler((sqlite *) h->sqlite,
3248417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    0, 0, 0);
3249417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3250417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3251417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3252417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ph) {
3253417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    globrefset(env, ph, &h->ph);
3254417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_progress_handler((sqlite3 *) h->sqlite,
3255417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				     n, progresshandler, h);
3256417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3257417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_progress_handler((sqlite3 *) h->sqlite,
3258417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				     0, 0, 0);
3259417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3260417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3261417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3262417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3263417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3264417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "unsupported");
3265417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3266417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3267417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3268417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
3269417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3270417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3271417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
3272417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_is3(JNIEnv *env, jobject obj)
3273417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3274417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3275417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
3276417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3277417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h) {
3278417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return h->is3 ? JNI_TRUE : JNI_FALSE;
3279417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3280417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
3281417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3282417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
3283417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
3284417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3285417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3286417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_TRUE;
3287417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3288417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3289417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3290417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3291417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
3292417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_prepare(JNIEnv *env, jobject obj)
3293417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3294417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3295417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3296417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *svm = 0;
3297417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *tail;
3298417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
3299417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3300417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm) {
3301417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_finalize((sqlite3_stmt *) v->vm);
3302417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = 0;
3303417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3304417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->h && v->h->sqlite) {
3305417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!v->tail) {
3306417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
3307417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3308417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->h->env = env;
3309417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE16_V2
3310417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare16_v2((sqlite3 *) v->h->sqlite,
3311417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				   v->tail, -1, (sqlite3_stmt **) &svm,
3312417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				   (const void **) &tail);
3313417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3314417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare16((sqlite3 *) v->h->sqlite,
3315417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				v->tail, -1, (sqlite3_stmt **) &svm,
3316417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				(const void **) &tail);
3317417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3318417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3319417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (svm) {
3320417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) svm);
3321417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		svm = 0;
3322417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3323417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3324417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3325417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const char *err = sqlite3_errmsg(v->h->sqlite);
3326417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3327417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3328417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->tail = 0;
3329417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : "error in compile/prepare");
3330417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
3331417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3332417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!svm) {
3333417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->tail = 0;
3334417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
3335417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3336417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = svm;
3337417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->tail = (char *) tail;
3338417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->hh.row1 = 1;
3339417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_TRUE;
3340417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3341417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3342417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3343417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3344417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3345417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
3346417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3347417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3348417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3349417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_stmt_1prepare(JNIEnv *env, jobject obj, jstring sql,
3350417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				   jobject stmt)
3351417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3352417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3353417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
3354417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *svm = 0;
3355417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v;
3356417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue vv;
3357417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jsize len16;
3358417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    const jchar *sql16, *tail = 0;
3359417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
3360417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3361417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!h) {
3362417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwclosed(env);
3363417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3364417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3365417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!stmt) {
3366417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null stmt");
3367417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3368417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3369417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
3370417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null sql");
3371417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3372417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3373417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#ifdef HAVE_BOTH_SQLITE
3374417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!h->is3) {
3375417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "only on SQLite3 database");
3376417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3377417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3378417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3379417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    len16 = (*env)->GetStringLength(env, sql) * sizeof (jchar);
3380417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (len16 < 1) {
3381417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        return;
3382417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3383417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->env = env;
3384417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    sql16 = (*env)->GetStringChars(env, sql, 0);
3385417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE16_V2
3386417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ret = sqlite3_prepare16_v2((sqlite3 *) h->sqlite, sql16, len16,
3387417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			       (sqlite3_stmt **) &svm, (const void **) &tail);
3388417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3389417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ret = sqlite3_prepare16((sqlite3 *) h->sqlite, sql16, len16,
3390417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (sqlite3_stmt **) &svm, (const void **) &tail);
3391417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3392417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ret != SQLITE_OK) {
3393417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (svm) {
3394417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) svm);
3395417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    svm = 0;
3396417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3397417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3398417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ret != SQLITE_OK) {
3399417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char *err = sqlite3_errmsg(h->sqlite);
3400417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3401417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        (*env)->ReleaseStringChars(env, sql, sql16);
3402417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	setstmterr(env, stmt, ret);
3403417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, err ? err : "error in prepare");
3404417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3405417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3406417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!svm) {
3407417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        (*env)->ReleaseStringChars(env, sql, sql16);
3408417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3409417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3410417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    len16 = len16 + sizeof (jchar) - ((char *) tail - (char *) sql16);
3411417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (len16 < (jsize) sizeof (jchar)) {
3412417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        len16 = sizeof (jchar);
3413417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3414417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v = malloc(sizeof (hvm) + len16);
3415417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!v) {
3416417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        (*env)->ReleaseStringChars(env, sql, sql16);
3417417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_finalize((sqlite3_stmt *) svm);
3418417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwoom(env, "unable to get SQLite handle");
3419417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3420417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3421417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->next = h->vms;
3422417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->vms = v;
3423417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->vm = svm;
3424417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->h = h;
3425417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->tail = (char *) (v + 1);
3426417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3427417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->is3 = v->hh.is3 = 1;
3428417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3429417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    memcpy(v->tail, tail, len16);
3430417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    len16 /= sizeof (jchar);
3431417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ((jchar *) v->tail)[len16 - 1] = 0;
3432417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->ReleaseStringChars(env, sql, sql16);
3433417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.sqlite = 0;
3434417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.haveutf = h->haveutf;
3435417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.ver = h->ver;
3436417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.bh = v->hh.cb = v->hh.ai = v->hh.tr = v->hh.ph = 0;
3437417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.row1 = 1;
3438417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.enc = h->enc;
3439417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.funcs = 0;
3440417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.vms = 0;
3441417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.env = 0;
3442417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    vv.j = 0;
3443417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    vv.l = (jobject) v;
3444417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->SetLongField(env, stmt, F_SQLite_Stmt_handle, vv.j);
3445417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3446417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3447417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3448417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3449417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3450417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
3451417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_step(JNIEnv *env, jobject obj)
3452417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3453417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3454417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3455417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3456417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3457417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3458417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3459417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_step((sqlite3_stmt *) v->vm);
3460417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret == SQLITE_ROW) {
3461417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_TRUE;
3462417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3463417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_DONE) {
3464417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const char *err = sqlite3_errmsg(v->h->sqlite);
3465417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3466417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3467417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : "error in step");
3468417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3469417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_FALSE;
3470417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3471417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3472417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3473417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3474417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3475417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
3476417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3477417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3478417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3479417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_close(JNIEnv *env, jobject obj)
3480417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3481417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3482417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3483417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3484417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3485417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3486417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3487417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_finalize((sqlite3_stmt *) v->vm);
3488417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = 0;
3489417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3490417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const char *err = sqlite3_errmsg(v->h->sqlite);
3491417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3492417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3493417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : "error in close");
3494417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3495417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3496417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3497417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3498417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3499417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3500417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3501417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return;
3502417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3503417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3504417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3505417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_reset(JNIEnv *env, jobject obj)
3506417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3507417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3508417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3509417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3510417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3511417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_reset((sqlite3_stmt *) v->vm);
3512417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3513417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "stmt already closed");
3514417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3515417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3516417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3517417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3518417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3519417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3520417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3521417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_clear_1bindings(JNIEnv *env, jobject obj)
3522417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3523417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_CLEAR_BINDINGS
3524417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3525417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3526417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3527417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_clear_bindings((sqlite3_stmt *) v->vm);
3528417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3529417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "stmt already closed");
3530417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3531417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3532417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3533417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3534417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3535417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3536417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3537417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__II(JNIEnv *env, jobject obj, jint pos, jint val)
3538417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3539417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3540417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3541417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3542417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3543417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3544417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3545417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3546417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3547417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3548417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3549417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3550417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_bind_int((sqlite3_stmt *) v->vm, pos, val);
3551417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3552417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3553417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3554417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3555417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3556417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        throwex(env, "stmt already closed");
3557417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3558417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3559417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3560417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3561417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3562417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3563417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3564417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__IJ(JNIEnv *env, jobject obj, jint pos, jlong val)
3565417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3566417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3567417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3568417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3569417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3570417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3571417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3572417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3573417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3574417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3575417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3576417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3577417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_bind_int64((sqlite3_stmt *) v->vm, pos, val);
3578417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3579417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3580417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3581417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3582417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3583417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        throwex(env, "stmt already closed");
3584417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3585417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3586417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3587417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3588417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3589417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3590417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3591417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__ID(JNIEnv *env, jobject obj, jint pos, jdouble val)
3592417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3593417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3594417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3595417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3596417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3597417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3598417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3599417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3600417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3601417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3602417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3603417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3604417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_bind_double((sqlite3_stmt *) v->vm, pos, val);
3605417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3606417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3607417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3608417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3609417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3610417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        throwex(env, "stmt already closed");
3611417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3612417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3613417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3614417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3615417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3616417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3617417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3618417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__I_3B(JNIEnv *env, jobject obj, jint pos, jbyteArray val)
3619417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3620417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3621417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3622417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3623417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3624417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3625417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3626417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jint len;
3627417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	char *data = 0;
3628417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3629417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3630417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3631417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3632417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3633417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (val) {
3634417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    len = (*env)->GetArrayLength(env, val);
3635417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (len > 0) {
3636417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	        data = sqlite3_malloc(len);
3637417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (!data) {
3638417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    throwoom(env, "unable to get blob parameter");
3639417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return;
3640417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3641417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->GetByteArrayRegion(env, val, 0, len, (jbyte *) data);
3642417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ret = sqlite3_bind_blob((sqlite3_stmt *) v->vm,
3643417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					pos, data, len, sqlite3_free);
3644417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
3645417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ret = sqlite3_bind_blob((sqlite3_stmt *) v->vm,
3646417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					pos, "", 0, SQLITE_STATIC);
3647417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3648417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3649417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_bind_null((sqlite3_stmt *) v->vm, pos);
3650417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3651417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3652417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (data) {
3653417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	        sqlite3_free(data);
3654417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3655417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3656417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3657417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3658417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3659417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        throwex(env, "stmt already closed");
3660417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3661417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3662417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3663417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3664417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3665417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3666417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3667417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__ILjava_lang_String_2(JNIEnv *env, jobject obj,
3668417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    jint pos, jstring val)
3669417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3670417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3671417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3672417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3673417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3674417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3675417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3676417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jsize len;
3677417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	char *data = 0;
3678417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3679417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3680417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3681417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3682417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3683417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (val) {
3684417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const jsize charCount = (*env)->GetStringLength(env, val);
3685417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    len = charCount * sizeof(jchar);
3686417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (len > 0) {
3687417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		data = sqlite3_malloc(len);
3688417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (!data) {
3689417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    throwoom(env, "unable to get blob parameter");
3690417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return;
3691417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3692417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3693417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->GetStringRegion(env, val, 0, charCount, (jchar*) data);
3694417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ret = sqlite3_bind_text16((sqlite3_stmt *) v->vm,
3695417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  pos, data, len, sqlite3_free);
3696417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
3697417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	        ret = sqlite3_bind_text16((sqlite3_stmt *) v->vm, pos, "", 0,
3698417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  SQLITE_STATIC);
3699417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3700417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3701417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_bind_null((sqlite3_stmt *) v->vm, pos);
3702417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3703417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3704417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (data) {
3705417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	        sqlite3_free(data);
3706417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3707417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3708417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3709417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3710417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3711417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        throwex(env, "stmt already closed");
3712417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3713417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3714417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3715417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3716417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3717417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3718417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3719417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__I(JNIEnv *env, jobject obj, jint pos)
3720417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3721417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3722417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3723417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3724417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3725417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3726417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3727417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3728417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3729417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3730417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3731417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3732417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_bind_null((sqlite3_stmt *) v->vm, pos);
3733417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3734417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3735417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3736417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3737417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3738417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        throwex(env, "stmt already closed");
3739417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3740417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3741417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3742417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3743417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3744417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3745417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3746417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind_1zeroblob(JNIEnv *env, jobject obj, jint pos, jint len)
3747417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3748417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BIND_ZEROBLOB
3749417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3750417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3751417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3752417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3753417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3754417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3755417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3756417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3757417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3758417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3759417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_bind_zeroblob((sqlite3_stmt *) v->vm, pos, len);
3760417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3761417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3762417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3763417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3764417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3765417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        throwex(env, "stmt already closed");
3766417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3767417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3768417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3769417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3770417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3771417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3772417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
3773417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind_1parameter_1count(JNIEnv *env, jobject obj)
3774417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3775417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3776417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3777417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3778417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3779417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3780417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3781417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3782417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3783417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3784417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3785417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
3786417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3787417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3788417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
3789417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind_1parameter_1name(JNIEnv *env, jobject obj, jint pos)
3790417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3791417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BIND_PARAMETER_NAME
3792417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3793417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3794417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3795417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3796417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char *name;
3797417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3798417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3799417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3800417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3801417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3802417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	name = sqlite3_bind_parameter_name((sqlite3_stmt *) v->vm, pos);
3803417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (name) {
3804417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewStringUTF(env, name);
3805417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3806417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3807417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        throwex(env, "stmt already closed");
3808417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3809417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3810417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3811417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3812417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
3813417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3814417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3815417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
3816417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind_1parameter_1index(JNIEnv *env, jobject obj,
3817417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					jstring name)
3818417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3819417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BIND_PARAMETER_INDEX
3820417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3821417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3822417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3823417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        int pos;
3824417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char *n;
3825417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr namestr;
3826417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
3827417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3828417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	n = trans2iso(env, 1, 0, name, &namestr);
3829417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
3830417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
3831417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
3832417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return -1;
3833417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3834417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        pos = sqlite3_bind_parameter_index((sqlite3_stmt *) v->vm, n);
3835417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&namestr);
3836417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return pos;
3837417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3838417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        throwex(env, "stmt already closed");
3839417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3840417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3841417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3842417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3843417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return -1;
3844417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3845417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3846417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
3847417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1int(JNIEnv *env, jobject obj, jint col)
3848417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3849417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3850417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3851417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3852417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3853417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
3854417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3855417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
3856417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
3857417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3858417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3859417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_column_int((sqlite3_stmt *) v->vm, col);
3860417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3861417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3862417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3863417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3864417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3865417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
3866417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3867417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3868417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jlong JNICALL
3869417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1long(JNIEnv *env, jobject obj, jint col)
3870417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3871417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3872417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3873417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3874417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3875417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
3876417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3877417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
3878417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
3879417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3880417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3881417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_column_int64((sqlite3_stmt *) v->vm, col);
3882417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3883417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3884417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3885417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3886417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3887417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
3888417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3889417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3890417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jdouble JNICALL
3891417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1double(JNIEnv *env, jobject obj, jint col)
3892417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3893417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3894417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3895417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3896417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3897417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
3898417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3899417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
3900417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
3901417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3902417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3903417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_column_double((sqlite3_stmt *) v->vm, col);
3904417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3905417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3906417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3907417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3908417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3909417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
3910417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3911417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3912417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jbyteArray JNICALL
3913417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1bytes(JNIEnv *env, jobject obj, jint col)
3914417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3915417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3916417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3917417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3918417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3919417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
3920417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int nbytes;
3921417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const jbyte *data;
3922417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jbyteArray b = 0;
3923417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3924417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
3925417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
3926417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3927417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3928417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	data = sqlite3_column_blob((sqlite3_stmt *) v->vm, col);
3929417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (data) {
3930417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    nbytes = sqlite3_column_bytes((sqlite3_stmt *) v->vm, col);
3931417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3932417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3933417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3934417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	b = (*env)->NewByteArray(env, nbytes);
3935417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!b) {
3936417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to get blob column data");
3937417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3938417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3939417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetByteArrayRegion(env, b, 0, nbytes, data);
3940417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return b;
3941417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3942417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3943417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3944417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3945417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3946417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
3947417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3948417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3949417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
3950417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1string(JNIEnv *env, jobject obj, jint col)
3951417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3952417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3953417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3954417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3955417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3956417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
3957417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int nbytes;
3958417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const jchar *data;
3959417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jstring b = 0;
3960417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3961417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
3962417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
3963417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3964417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3965417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	data = sqlite3_column_text16((sqlite3_stmt *) v->vm, col);
3966417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (data) {
3967417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    nbytes = sqlite3_column_bytes16((sqlite3_stmt *) v->vm, col);
3968417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3969417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3970417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3971417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	nbytes /= sizeof (jchar);
3972417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	b = (*env)->NewString(env, data, nbytes);
3973417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!b) {
3974417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to get string column data");
3975417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3976417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3977417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return b;
3978417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3979417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3980417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3981417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3982417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3983417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
3984417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3985417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3986417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
3987417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1type(JNIEnv *env, jobject obj, jint col)
3988417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3989417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3990417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3991417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3992417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3993417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
3994417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3995417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
3996417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
3997417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3998417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3999417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_column_type((sqlite3_stmt *) v->vm, col);
4000417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4001417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4002417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4003417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4004417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4005417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4006417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4007417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4008417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
4009417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1count(JNIEnv *env, jobject obj)
4010417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4011417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4012417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4013417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4014417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4015417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_column_count((sqlite3_stmt *) v->vm);
4016417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4017417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4018417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4019417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4020417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4021417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4022417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4023417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4024417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
4025417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1table_1name(JNIEnv *env, jobject obj, jint col)
4026417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4027417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_COLUMN_TABLE_NAME16
4028417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4029417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4030417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4031417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
4032417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        const jchar *str;
4033417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4034417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4035417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4036417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4037417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4038417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	str = sqlite3_column_table_name16((sqlite3_stmt *) v->vm, col);
4039417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (str) {
4040417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewString(env, str, jstrlen(str));
4041417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4042417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return 0;
4043417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4044417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4045417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4046417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4047417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4048417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4049417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4050417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4051417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
4052417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1database_1name(JNIEnv *env, jobject obj, jint col)
4053417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4054417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_COLUMN_DATABASE_NAME16
4055417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4056417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4057417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4058417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
4059417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        const jchar *str;
4060417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4061417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4062417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4063417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4064417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4065417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	str = sqlite3_column_database_name16((sqlite3_stmt *) v->vm, col);
4066417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (str) {
4067417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewString(env, str, jstrlen(str));
4068417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4069417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return 0;
4070417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4071417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4072417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4073417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4074417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4075417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4076417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4077417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4078417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
4079417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1decltype(JNIEnv *env, jobject obj, jint col)
4080417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4081417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4082417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4083417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4084417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4085417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
4086417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        const jchar *str;
4087417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4088417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4089417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4090417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4091417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4092417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	str = sqlite3_column_decltype16((sqlite3_stmt *) v->vm, col);
4093417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (str) {
4094417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewString(env, str, jstrlen(str));
4095417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4096417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return 0;
4097417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4098417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4099417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4100417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4101417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4102417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4103417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4104417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4105417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
4106417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1origin_1name(JNIEnv *env, jobject obj, jint col)
4107417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4108417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_COLUMN_ORIGIN_NAME16
4109417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4110417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4111417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4112417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
4113417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        const jchar *str;
4114417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4115417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4116417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4117417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4118417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4119417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	str = sqlite3_column_origin_name16((sqlite3_stmt *) v->vm, col);
4120417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (str) {
4121417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewString(env, str, jstrlen(str));
4122417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4123417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return 0;
4124417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4125417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4126417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4127417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4128417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4129417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4130417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4131417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4132417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4133417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_finalize(JNIEnv *env, jobject obj)
4134417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4135417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4136417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dostmtfinal(env, obj);
4137417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4138417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4139417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4140417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4141417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1open_1blob(JNIEnv *env, jobject obj,
4142417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  jstring dbname, jstring table,
4143417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  jstring column, jlong row,
4144417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  jboolean rw, jobject blobj)
4145417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4146417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
4147417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
4148417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hbl *bl;
4149417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jthrowable exc;
4150417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transstr dbn, tbl, col;
4151417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    sqlite3_blob *blob;
4152417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue vv;
4153417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
4154417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4155417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!blobj) {
4156417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null blob");
4157417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
4158417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4159417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
4160417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        trans2iso(env, h->haveutf, h->enc, dbname, &dbn);
4161417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
4162417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
4163417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
4164417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
4165417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4166417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        trans2iso(env, h->haveutf, h->enc, table, &tbl);
4167417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
4168417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
4169417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&dbn);
4170417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
4171417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
4172417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4173417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        trans2iso(env, h->haveutf, h->enc, column, &col);
4174417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
4175417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
4176417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&tbl);
4177417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&dbn);
4178417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
4179417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
4180417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4181417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_blob_open(h->sqlite,
4182417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				dbn.result, tbl.result, col.result,
4183417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				row, rw, &blob);
4184417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&col);
4185417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&tbl);
4186417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&dbn);
4187417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
4188417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const char *err = sqlite3_errmsg(h->sqlite);
4189417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4190417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    seterr(env, obj, ret);
4191417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : "error in blob open");
4192417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
4193417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4194417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bl = malloc(sizeof (hbl));
4195417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!bl) {
4196417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_blob_close(blob);
4197417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to get SQLite blob handle");
4198417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
4199417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4200417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bl->next = h->blobs;
4201417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->blobs = bl;
4202417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bl->blob = blob;
4203417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bl->h = h;
4204417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	vv.j = 0;
4205417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	vv.l = (jobject) bl;
4206417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, blobj, F_SQLite_Blob_handle, vv.j);
4207417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetIntField(env, blobj, F_SQLite_Blob_size,
4208417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_blob_bytes(blob));
4209417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
4210417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4211417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "not an open database");
4212417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4213417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4214417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4215417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4216417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4217417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
4218417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Blob_write(JNIEnv *env , jobject obj, jbyteArray b, jint off,
4219417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		       jint pos, jint len)
4220417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4221417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
4222417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hbl *bl = gethbl(env, obj);
4223417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4224417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (bl && bl->h && bl->blob) {
4225417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        jbyte *buf;
4226417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
4227417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
4228417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4229417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (len <= 0) {
4230417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4231417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4232417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	buf = malloc(len);
4233417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!buf) {
4234417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "out of buffer space for blob");
4235417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4236417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4237417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetByteArrayRegion(env, b, off, len, buf);
4238417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
4239417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
4240417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    free(buf);
4241417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4242417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4243417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_blob_write(bl->blob, buf, len, pos);
4244417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(buf);
4245417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
4246417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwioex(env, "blob write error");
4247417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4248417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4249417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return len;
4250417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4251417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "blob already closed");
4252417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4253417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4254417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4255417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4256417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4257417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4258417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
4259417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Blob_read(JNIEnv *env , jobject obj, jbyteArray b, jint off,
4260417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		      jint pos, jint len)
4261417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4262417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
4263417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hbl *bl = gethbl(env, obj);
4264417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4265417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (bl && bl->h && bl->blob) {
4266417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes        jbyte *buf;
4267417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
4268417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
4269417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4270417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (len <= 0) {
4271417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4272417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4273417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	buf = malloc(len);
4274417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!buf) {
4275417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "out of buffer space for blob");
4276417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4277417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4278417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_blob_read(bl->blob, buf, len, pos);
4279417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
4280417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    free(buf);
4281417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwioex(env, "blob read error");
4282417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4283417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4284417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetByteArrayRegion(env, b, off, len, buf);
4285417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(buf);
4286417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
4287417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
4288417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4289417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4290417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return len;
4291417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4292417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "blob already closed");
4293417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4294417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4295417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4296417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4297417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4298417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4299417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4300417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Blob_close(JNIEnv *env, jobject obj)
4301417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4302417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
4303417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    doblobfinal(env, obj);
4304417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4305417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4306417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4307417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4308417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Blob_finalize(JNIEnv *env, jobject obj)
4309417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4310417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
4311417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    doblobfinal(env, obj);
4312417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4313417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4314417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4315417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4316417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_internal_1init(JNIEnv *env, jclass cls)
4317417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4318417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Stmt_handle =
4319417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "handle", "J");
4320417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Stmt_error_code =
4321417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "error_code", "I");
4322417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4323417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4324417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4325417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Vm_internal_1init(JNIEnv *env, jclass cls)
4326417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4327417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Vm_handle =
4328417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "handle", "J");
4329417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Vm_error_code =
4330417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "error_code", "I");
4331417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4332417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4333417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4334417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Blob_internal_1init(JNIEnv *env, jclass cls)
4335417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4336417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Blob_handle =
4337417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "handle", "J");
4338417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Blob_size =
4339417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "size", "I");
4340417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4341417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4342417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4343417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_internal_1init(JNIEnv *env, jclass cls)
4344417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4345417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes//#ifndef JNI_VERSION_1_2
4346417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jclass jls = (*env)->FindClass(env, "java/lang/String");
4347417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4348417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    C_java_lang_String = (*env)->NewGlobalRef(env, jls);
4349417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes//#endif
4350417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Database_handle =
4351417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "handle", "J");
4352417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Database_error_code =
4353417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "error_code", "I");
4354417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    M_java_lang_String_getBytes =
4355417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetMethodID(env, C_java_lang_String, "getBytes", "()[B");
4356417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    M_java_lang_String_getBytes2 =
4357417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetMethodID(env, C_java_lang_String, "getBytes",
4358417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    "(Ljava/lang/String;)[B");
4359417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    M_java_lang_String_initBytes =
4360417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetMethodID(env, C_java_lang_String, "<init>", "([B)V");
4361417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    M_java_lang_String_initBytes2 =
4362417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetMethodID(env, C_java_lang_String, "<init>",
4363417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    "([BLjava/lang/String;)V");
4364417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4365417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4366417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#ifdef JNI_VERSION_1_2
4367417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
4368417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNI_OnLoad(JavaVM *vm, void *reserved)
4369417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4370417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env;
4371417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jclass cls;
4372417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4373417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#ifndef _WIN32
4374417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
4375417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (strcmp(sqlite_libencoding(), "UTF-8") != 0) {
4376417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	fprintf(stderr, "WARNING: using non-UTF SQLite2 engine\n");
4377417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4378417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4379417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4380417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_2)) {
4381417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_ERR;
4382417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4383417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    cls = (*env)->FindClass(env, "java/lang/String");
4384417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!cls) {
4385417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_ERR;
4386417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4387417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    C_java_lang_String = (*env)->NewWeakGlobalRef(env, cls);
4388417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_VERSION_1_2;
4389417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4390417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4391417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4392417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNI_OnUnload(JavaVM *vm, void *reserved)
4393417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4394417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env;
4395417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4396417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_2)) {
4397417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
4398417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4399417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (C_java_lang_String) {
4400417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteWeakGlobalRef(env, C_java_lang_String);
4401417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	C_java_lang_String = 0;
4402417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4403417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4404417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4405