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
337a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#ifndef HAVE_SQLITE3_SHARED_CACHE
347a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#define HAVE_SQLITE3_SHARED_CACHE 0
357a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
36417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
37417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#include "sqlite_jni.h"
38417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
39417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
40417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define MAX_PARAMS 256
41417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
42417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#define MAX_PARAMS 32
43417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
44417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
45417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* free memory proc */
46417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
47417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef void (freemem)(void *);
48417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
49417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* internal handle for SQLite database */
50417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
51417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef struct {
52417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *sqlite;		/* SQLite handle */
53417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
54417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int is3;			/* True for SQLITE3 handle */
55417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
56417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ver;			/* version code */
57417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject bh;			/* BusyHandler object */
58417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject cb;			/* Callback object */
59417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject ai;			/* Authorizer object */
60417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject tr;			/* Trace object */
615cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jobject pr;			/* Profile object */
62417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject ph;			/* ProgressHandler object */
63417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env;		/* Java environment for callbacks */
64417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int row1;			/* true while processing first row */
65417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int haveutf;		/* true for SQLite UTF-8 support */
66417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jstring enc;		/* encoding or 0 */
67417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    struct hfunc *funcs;	/* SQLite user defined function handles */
68417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
69417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    struct hvm *vms;		/* Compiled SQLite VMs */
70417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
71417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
72417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    sqlite3_stmt *stmt;		/* For callback() */
73417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
74417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
755cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    struct hbl *blobs;		/* SQLite3 blob handles */
765cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
775cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
785cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes  struct hbk *backups;		/* SQLite3 backup handles */
79417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
80417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes} handle;
81417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
82417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* internal handle for SQLite user defined function */
83417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
84417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef struct hfunc {
85417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    struct hfunc *next;		/* next function */
86417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
87417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int is3;			/* True for SQLITE3 handle */
88417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
89417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject fc;			/* FunctionContext object */
90417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject fi;			/* Function object */
91417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject db;			/* Database object */
92417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h;			/* SQLite database handle */
93417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *sf;			/* SQLite function handle */
94417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env;		/* Java environment for callbacks */
95417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes} hfunc;
96417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
97417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
98417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* internal handle for SQLite VM (sqlite_compile()) */
99417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
100417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef struct hvm {
101417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    struct hvm *next;		/* next vm handle */
102417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
103417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int is3;			/* True for SQLITE3 handle */
104417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
105417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *vm;			/* SQLite 2/3 VM/statement */
106417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *tail;			/* tail SQL string */
107417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int tail_len;		/* only for SQLite3/prepare */
108417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h;			/* SQLite database handle */
109417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle hh;			/* fake SQLite database handle */
110417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes} hvm;
111417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
112417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
113417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
114417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* internal handle for sqlite3_blob */
115417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
116417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef struct hbl {
117417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    struct hbl *next;		/* next blob handle */
118417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    sqlite3_blob *blob;		/* SQLite3 blob */
119417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h;			/* SQLite database handle */
120417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes} hbl;
121417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
122417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1235cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
1245cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes/* internal handle for sqlite3_backup */
1255cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
1265cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughestypedef struct hbk {
1275cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    struct hbk *next;		/* next blob handle */
1285cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    sqlite3_backup *bkup;	/* SQLite3 backup handle */
1295cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    handle *h;			/* SQLite database handle (source) */
1305cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes} hbk;
1315cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
1325cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
133417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* ISO to/from UTF-8 translation */
134417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
135417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestypedef struct {
136417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *result;		/* translated C string result */
137417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *tofree;		/* memory to be free'd, or 0 */
138417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jstring jstr;		/* resulting Java string or 0 */
139417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes} transstr;
140417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
141417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes/* static cached weak class refs, field and method ids */
142417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
143417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jclass C_java_lang_String = 0;
144417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
145417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Database_handle = 0;
146417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Database_error_code = 0;
147417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_FunctionContext_handle = 0;
148417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Vm_handle = 0;
149417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Vm_error_code = 0;
150417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Stmt_handle = 0;
151417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Stmt_error_code = 0;
152417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Blob_handle = 0;
153417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jfieldID F_SQLite_Blob_size = 0;
1545cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughesstatic jfieldID F_SQLite_Backup_handle = 0;
155417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
156417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jmethodID M_java_lang_String_getBytes = 0;
157417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jmethodID M_java_lang_String_getBytes2 = 0;
158417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jmethodID M_java_lang_String_initBytes = 0;
159417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jmethodID M_java_lang_String_initBytes2 = 0;
160417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
161417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic const char xdigits[] = "0123456789ABCDEF";
162417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
163417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
164417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesseterr(JNIEnv *env, jobject obj, int err)
165417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
166417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
167417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
168417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = 0;
169417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.i = (jint) err;
170417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->SetIntField(env, obj, F_SQLite_Database_error_code, v.i);
171417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
172417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
173417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
174417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
175417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughessetvmerr(JNIEnv *env, jobject obj, int err)
176417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
177417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
178417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
179417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = 0;
180417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.i = (jint) err;
181417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->SetIntField(env, obj, F_SQLite_Vm_error_code, v.i);
182417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
183417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
184417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
185417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
186417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughessetstmterr(JNIEnv *env, jobject obj, int err)
187417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
188417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
189417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
190417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = 0;
191417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.i = (jint) err;
192417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->SetIntField(env, obj, F_SQLite_Stmt_error_code, v.i);
193417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
194417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
195417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
196417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesjstrlen(const jchar *jstr)
197417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
198417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int len = 0;
199417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
200417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (jstr) {
2017a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	while (*jstr++) {
202417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    len++;
203417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
204417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
205417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return len;
206417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
207417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
208417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
209417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
210417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void *
211417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesgethandle(JNIEnv *env, jobject obj)
212417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
213417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
214417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
215417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = (*env)->GetLongField(env, obj, F_SQLite_Database_handle);
216417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (void *) v.l;
217417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
218417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
219417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
220417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void *
221417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesgethvm(JNIEnv *env, jobject obj)
222417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
223417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
224417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
225417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = (*env)->GetLongField(env, obj, F_SQLite_Vm_handle);
226417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (void *) v.l;
227417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
228417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
229417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
230417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void *
231417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesgethstmt(JNIEnv *env, jobject obj)
232417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
233417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
234417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
235417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = (*env)->GetLongField(env, obj, F_SQLite_Stmt_handle);
236417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (void *) v.l;
237417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
238417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
239417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
240417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
241417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
242417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void *
243417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesgethbl(JNIEnv *env, jobject obj)
244417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
245417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
246417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
247417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = (*env)->GetLongField(env, obj, F_SQLite_Blob_handle);
248417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (void *) v.l;
249417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
250417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
251417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2525cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
2535cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughesstatic void *
2545cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughesgethbk(JNIEnv *env, jobject obj)
2555cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
2565cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jvalue v;
2575cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
2585cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    v.j = (*env)->GetLongField(env, obj, F_SQLite_Backup_handle);
2595cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    return (void *) v.l;
2605cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
2615cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
2625cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
263417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
264417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdelglobrefp(JNIEnv *env, jobject *obj)
265417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
266417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (*obj) {
267417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteGlobalRef(env, *obj);
268417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	*obj = 0;
269417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
270417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
271417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
272417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jobject
273417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesglobrefpop(JNIEnv *env, jobject *obj)
274417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
275417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jobject ret = 0;
276417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
277417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (*obj) {
278417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = *obj;
279417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	*obj = 0;
280417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
281417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return ret;
282417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
283417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
284417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
285417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesglobrefset(JNIEnv *env, jobject obj, jobject *ref)
286417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
287417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ref) {
288417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (obj) {
289417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    *ref = (*env)->NewGlobalRef(env, obj);
290417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
291417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    *ref = 0;
292417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
293417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
294417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
295417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
296417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
297417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesfreep(char **strp)
298417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
299417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (strp && *strp) {
300417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(*strp);
301417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	*strp = 0;
302417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
303417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
304417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
305417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
306417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesthrowex(JNIEnv *env, const char *msg)
307417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
308417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jclass except = (*env)->FindClass(env, "SQLite/Exception");
309417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
310417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->ExceptionClear(env);
311417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (except) {
312417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->ThrowNew(env, except, msg);
313417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
314417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
315417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
316417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
317417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesthrowoom(JNIEnv *env, const char *msg)
318417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
319417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jclass except = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
320417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
321417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->ExceptionClear(env);
322417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (except) {
323417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->ThrowNew(env, except, msg);
324417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
325417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
326417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
327417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
328417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesthrowclosed(JNIEnv *env)
329417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
330417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "database already closed");
331417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
332417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
333417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
334417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
335417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesthrowioex(JNIEnv *env, const char *msg)
336417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
337417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jclass except = (*env)->FindClass(env, "java/io/IOException");
338417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
339417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->ExceptionClear(env);
340417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (except) {
341417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->ThrowNew(env, except, msg);
342417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
343417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
344417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
345417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
346417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
347417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestransfree(transstr *dest)
348417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
349417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->result = 0;
350417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    freep(&dest->tofree);
351417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
352417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
353417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic char *
354417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestrans2iso(JNIEnv *env, int haveutf, jstring enc, jstring src,
355417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	  transstr *dest)
356417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
357417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jbyteArray bytes = 0;
358417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jthrowable exc;
359417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
360417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->result = 0;
361417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->tofree = 0;
362417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (haveutf) {
3634538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe#ifndef JNI_VERSION_1_2
3644538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	const char *utf = (*env)->GetStringUTFChars(env, src, 0);
3654538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe
3664538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	dest->result = dest->tofree = malloc(strlen(utf) + 1);
3674538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe#else
3684538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	jsize utflen = (*env)->GetStringUTFLength(env, src);
3695cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	jsize uclen = (*env)->GetStringLength(env, src);
3704538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe
3714538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	dest->result = dest->tofree = malloc(utflen + 1);
3724538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe#endif
3734538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	if (!dest->tofree) {
3744538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    throwoom(env, "string translation failed");
3754538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    return dest->result;
3764538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	}
3774538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe#ifndef JNI_VERSION_1_2
3784538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	strcpy(dest->result, utf);
3794538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	(*env)->ReleaseStringUTFChars(env, src, utf);
3804538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe#else
3815cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	(*env)->GetStringUTFRegion(env, src, 0, uclen, dest->result);
3825cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	dest->result[utflen] = '\0';
3834538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe#endif
3844538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	return dest->result;
385417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
386417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (enc) {
387417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bytes = (*env)->CallObjectMethod(env, src,
388417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 M_java_lang_String_getBytes2, enc);
389417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
390417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bytes = (*env)->CallObjectMethod(env, src,
391417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 M_java_lang_String_getBytes);
392417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
393417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    exc = (*env)->ExceptionOccurred(env);
394417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!exc) {
395417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jint len = (*env)->GetArrayLength(env, bytes);
396417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	dest->tofree = malloc(len + 1);
397417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!dest->tofree) {
398417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "string translation failed");
399417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return dest->result;
400417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
401417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	dest->result = dest->tofree;
402417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetByteArrayRegion(env, bytes, 0, len, (jbyte *) dest->result);
403417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	dest->result[len] = '\0';
404417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
405417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, exc);
406417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
407417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return dest->result;
408417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
409417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
410417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic jstring
411417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughestrans2utf(JNIEnv *env, int haveutf, jstring enc, const char *src,
412417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	  transstr *dest)
413417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
414417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jbyteArray bytes = 0;
415417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int len;
416417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
417417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->result = 0;
418417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->tofree = 0;
419417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dest->jstr = 0;
420417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!src) {
421417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return dest->jstr;
422417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
423417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (haveutf) {
424417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	dest->jstr = (*env)->NewStringUTF(env, src);
425417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return dest->jstr;
426417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
427417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    len = strlen(src);
428417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    bytes = (*env)->NewByteArray(env, len);
429417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (bytes) {
430417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *) src);
431417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (enc) {
432417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    dest->jstr =
433417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->NewObject(env, C_java_lang_String,
434417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  M_java_lang_String_initBytes2, bytes, enc);
435417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
436417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    dest->jstr =
437417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->NewObject(env, C_java_lang_String,
438417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  M_java_lang_String_initBytes, bytes);
439417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
440417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, bytes);
441417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return dest->jstr;
442417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
443417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwoom(env, "string translation failed");
444417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return dest->jstr;
445417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
446417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
447417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
448417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
449417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesbusyhandler(void *udata, const char *table, int count)
450417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
451417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) udata;
452417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
453417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret = 0;
454417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
455417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->bh) {
456417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr tabstr;
457417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->bh);
458417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid = (*env)->GetMethodID(env, cls, "busy",
459417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    "(Ljava/lang/String;I)Z");
460417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
461417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
4624538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    (*env)->DeleteLocalRef(env, cls);
463417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return ret;
464417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
465417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2utf(env, h->haveutf, h->enc, table, &tabstr);
466417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = (*env)->CallBooleanMethod(env, h->bh, mid, tabstr.jstr,
467417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					(jint) count)
468417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	      != JNI_FALSE;
469417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, tabstr.jstr);
4704538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	(*env)->DeleteLocalRef(env, cls);
471417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
472417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return ret;
473417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
474417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
475417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
476417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
477417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
478417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesbusyhandler3(void *udata, int count)
479417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
480417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) udata;
481417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
482417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret = 0;
483417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
484417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->bh) {
485417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->bh);
486417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid = (*env)->GetMethodID(env, cls, "busy",
487417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    "(Ljava/lang/String;I)Z");
488417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
489417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
4904538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    (*env)->DeleteLocalRef(env, cls);
491417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return ret;
492417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
493417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = (*env)->CallBooleanMethod(env, h->bh, mid, 0, (jint) count)
494417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    != JNI_FALSE;
4954538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	(*env)->DeleteLocalRef(env, cls);
496417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
497417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return ret;
498417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
499417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
500417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
501417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
502417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesprogresshandler(void *udata)
503417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
504417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) udata;
505417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
506417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret = 0;
507417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
508417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->ph) {
509417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->ph);
510417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid = (*env)->GetMethodID(env, cls, "progress", "()Z");
511417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
512417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
5134538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    (*env)->DeleteLocalRef(env, cls);
514417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return ret;
515417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
516417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = (*env)->CallBooleanMethod(env, h->ph, mid) != JNI_TRUE;
5174538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	(*env)->DeleteLocalRef(env, cls);
518417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
519417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return ret;
520417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
521417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
522417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
523417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescallback(void *udata, int ncol, char **data, char **cols)
524417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
525417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) udata;
526417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
527417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
528417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->cb) {
529417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
530417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->cb);
531417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid;
532417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jobjectArray arr = 0;
533417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jint i;
534417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
535417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->row1) {
536417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    mid = (*env)->GetMethodID(env, cls, "columns",
537417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      "([Ljava/lang/String;)V");
538417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
539417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (mid) {
540417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		arr = (*env)->NewObjectArray(env, ncol, C_java_lang_String, 0);
541417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < ncol; i++) {
542417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (cols[i]) {
543417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			transstr col;
544417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
545417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			trans2utf(env, h->haveutf, h->enc, cols[i], &col);
546417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->SetObjectArrayElement(env, arr, i, col.jstr);
547417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			exc = (*env)->ExceptionOccurred(env);
548417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (exc) {
549417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->DeleteLocalRef(env, exc);
550417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    return 1;
551417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
552417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->DeleteLocalRef(env, col.jstr);
553417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
554417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
555417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->row1 = 0;
556417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->CallVoidMethod(env, h->cb, mid, arr);
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, arr);
563417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
564417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
565417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->is3) {
566417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		mid = (*env)->GetMethodID(env, cls, "types",
567417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  "([Ljava/lang/String;)V");
568417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
569417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (mid && h->stmt) {
570417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    arr = (*env)->NewObjectArray(env, ncol,
571417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						 C_java_lang_String, 0);
572417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    for (i = 0; i < ncol; i++) {
573417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			const char *ctype =
574417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_column_decltype(h->stmt, i);
575417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
576417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (!ctype) {
577417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    switch (sqlite3_column_type(h->stmt, i)) {
578417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE_INTEGER: ctype = "integer"; break;
579417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE_FLOAT:   ctype = "double";  break;
580417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    default:
581417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(SQLITE_TEXT) && defined(SQLITE3_TEXT) && (SQLITE_TEXT != SQLITE3_TEXT)
582417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE_TEXT:
583417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
584417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#ifdef SQLITE3_TEXT
585417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE3_TEXT:
586417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
587417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
588417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						 ctype = "text";    break;
589417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE_BLOB:    ctype = "blob";    break;
590417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    case SQLITE_NULL:    ctype = "null";    break;
591417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
592417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
593417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (ctype) {
594417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    transstr ty;
595417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
596417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    trans2utf(env, 1, 0, ctype, &ty);
597417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->SetObjectArrayElement(env, arr, i,
598417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes							  ty.jstr);
599417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    exc = (*env)->ExceptionOccurred(env);
600417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    if (exc) {
601417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				(*env)->DeleteLocalRef(env, exc);
602417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				return 1;
603417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
604417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->DeleteLocalRef(env, ty.jstr);
605417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
606417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
607417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->CallVoidMethod(env, h->cb, mid, arr);
608417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    exc = (*env)->ExceptionOccurred(env);
609417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (exc) {
610417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->DeleteLocalRef(env, exc);
611417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			return 1;
612417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
613417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, arr);
614417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
615417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
616417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (h->ver >= 0x020506 && cols[ncol]) {
617417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    mid = (*env)->GetMethodID(env, cls, "types",
618417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      "([Ljava/lang/String;)V");
619417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
620417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (mid) {
621417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			arr = (*env)->NewObjectArray(env, ncol,
622417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						     C_java_lang_String, 0);
623417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			for (i = 0; i < ncol; i++) {
624417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    if (cols[i + ncol]) {
625417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				transstr ty;
626417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
627417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				trans2utf(env, h->haveutf, h->enc,
628417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cols[i + ncol], &ty);
629417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				(*env)->SetObjectArrayElement(env, arr, i,
630417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes							      ty.jstr);
631417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				exc = (*env)->ExceptionOccurred(env);
632417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				if (exc) {
633417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    (*env)->DeleteLocalRef(env, exc);
634417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    return 1;
635417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				}
636417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				(*env)->DeleteLocalRef(env, ty.jstr);
637417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
638417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
639417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->CallVoidMethod(env, h->cb, mid, arr);
640417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			exc = (*env)->ExceptionOccurred(env);
641417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (exc) {
642417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->DeleteLocalRef(env, exc);
643417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    return 1;
644417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
645417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->DeleteLocalRef(env, arr);
646417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
647417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
648417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
649417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
650417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
651417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->ver >= 0x020506 && cols[ncol]) {
652417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		mid = (*env)->GetMethodID(env, cls, "types",
653417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  "([Ljava/lang/String;)V");
654417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
655417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (mid) {
656417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    arr = (*env)->NewObjectArray(env, ncol,
657417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						 C_java_lang_String, 0);
658417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    for (i = 0; i < ncol; i++) {
659417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (cols[i + ncol]) {
660417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    transstr ty;
661417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
662417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    trans2utf(env, h->haveutf, h->enc,
663417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cols[i + ncol], &ty);
664417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->SetObjectArrayElement(env, arr, i,
665417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes							  ty.jstr);
666417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    exc = (*env)->ExceptionOccurred(env);
667417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    if (exc) {
668417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				(*env)->DeleteLocalRef(env, exc);
669417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				return 1;
670417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
671417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->DeleteLocalRef(env, ty.jstr);
672417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
673417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
674417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->CallVoidMethod(env, h->cb, mid, arr);
675417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    exc = (*env)->ExceptionOccurred(env);
676417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (exc) {
677417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->DeleteLocalRef(env, exc);
678417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			return 1;
679417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
680417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, arr);
681417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
682417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
683417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
684417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
685417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    mid = (*env)->GetMethodID(env, cls, "types",
686417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      "([Ljava/lang/String;)V");
687417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
688417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (mid && h->stmt) {
689417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		arr = (*env)->NewObjectArray(env, ncol,
690417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     C_java_lang_String, 0);
691417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < ncol; i++) {
692417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    const char *ctype = sqlite3_column_decltype(h->stmt, i);
693417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
694417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (!ctype) {
695417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			switch (sqlite3_column_type(h->stmt, i)) {
696417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE_INTEGER: ctype = "integer"; break;
697417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE_FLOAT:   ctype = "double";  break;
698417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			default:
699417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(SQLITE_TEXT) && defined(SQLITE3_TEXT) && (SQLITE_TEXT != SQLITE3_TEXT)
700417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE_TEXT:
701417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
702417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#ifdef SQLITE3_TEXT
703417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE3_TEXT:
704417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
705417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
706417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     ctype = "text";    break;
707417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE_BLOB:    ctype = "blob";    break;
708417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			case SQLITE_NULL:    ctype = "null";    break;
709417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
710417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
711417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (ctype) {
712417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			transstr ty;
713417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
714417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			trans2utf(env, 1, 0, ctype, &ty);
715417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->SetObjectArrayElement(env, arr, i, ty.jstr);
716417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			exc = (*env)->ExceptionOccurred(env);
717417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (exc) {
718417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->DeleteLocalRef(env, exc);
719417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    return 1;
720417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
721417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->DeleteLocalRef(env, ty.jstr);
722417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
723417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
724417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->CallVoidMethod(env, h->cb, mid, arr);
725417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		exc = (*env)->ExceptionOccurred(env);
726417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (exc) {
727417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, exc);
728417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return 1;
729417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
730417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, arr);
731417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
732417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
733417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
734417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
7357a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (data) {
7367a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    mid = (*env)->GetMethodID(env, cls, "newrow",
7377a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes				      "([Ljava/lang/String;)Z");
7387a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    if (mid) {
7397a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		jboolean rc;
740417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
741417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		arr = (*env)->NewObjectArray(env, ncol, C_java_lang_String, 0);
7427a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		for (i = 0; arr && i < ncol; i++) {
7437a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    if (data[i]) {
7447a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			transstr dats;
745417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
7467a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			trans2utf(env, h->haveutf, h->enc, data[i], &dats);
7477a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			(*env)->SetObjectArrayElement(env, arr, i, dats.jstr);
7487a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			exc = (*env)->ExceptionOccurred(env);
7497a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			if (exc) {
7507a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			    (*env)->DeleteLocalRef(env, exc);
7517a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			    return 1;
7527a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			}
7537a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			(*env)->DeleteLocalRef(env, dats.jstr);
754417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
755417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
7567a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		rc = (*env)->CallBooleanMethod(env, h->cb, mid, arr);
7577a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		exc = (*env)->ExceptionOccurred(env);
7587a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		if (exc) {
7597a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    (*env)->DeleteLocalRef(env, exc);
7607a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    return 1;
7617a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		}
7627a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		if (arr) {
7637a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    (*env)->DeleteLocalRef(env, arr);
7647a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		}
7657a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		(*env)->DeleteLocalRef(env, cls);
7667a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		return rc != JNI_FALSE;
767417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
768417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
769417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
770417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
771417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
772417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
773417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
774417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdoclose(JNIEnv *env, jobject obj, int final)
775417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
776417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
777417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
778417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h) {
779417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	hfunc *f;
780417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
781417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	hbl *bl;
782417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
7835cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
7845cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	hbk *bk;
7855cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
786417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
787417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	hvm *v;
788417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
789417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	while ((v = h->vms)) {
790417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->vms = v->next;
791417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->next = 0;
792417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->h = 0;
793417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (v->vm) {
794417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
795417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (h->is3) {
796417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sqlite3_finalize((sqlite3_stmt *) v->vm);
797417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		} else {
798417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sqlite_finalize((sqlite_vm *) v->vm, 0);
799417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
800417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
801417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
802417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_finalize((sqlite_vm *) v->vm, 0);
803417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
804417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
805417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) v->vm);
806417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
807417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
808417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		v->vm = 0;
809417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
810417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
811417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
812417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->sqlite) {
813417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
814417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->is3) {
815417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_close((sqlite3 *) h->sqlite);
816417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
817417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_close((sqlite *) h->sqlite);
818417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
819417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
820417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
821417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_close((sqlite *) h->sqlite);
822417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
823417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
824417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_close((sqlite3 *) h->sqlite);
825417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
826417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
827417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->sqlite = 0;
828417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
829417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	while ((f = h->funcs)) {
830417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->funcs = f->next;
831417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    f->h = 0;
832417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    f->sf = 0;
833417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    f->env = 0;
834417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (f->fc) {
835417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->SetLongField(env, f->fc,
836417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				     F_SQLite_FunctionContext_handle, 0);
837417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
838417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &f->db);
839417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &f->fi);
840417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &f->fc);
841417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    free(f);
842417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
843417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
844417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	while ((bl = h->blobs)) {
845417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->blobs = bl->next;
846417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    bl->next = 0;
847417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    bl->h = 0;
848417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (bl->blob) {
8497a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		sqlite3_blob_close(bl->blob);
850417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
851417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    bl->blob = 0;
852417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
853417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
8545cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
8555cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	while ((bk = h->backups)) {
8565cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    h->backups = bk->next;
8575cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    bk->next = 0;
8585cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    bk->h = 0;
8595cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    if (bk->bkup) {
8605cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		sqlite3_backup_finish(bk->bkup);
8615cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    }
8625cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    bk->bkup = 0;
8635cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	}
8645cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
865417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->bh);
866417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->cb);
867417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->ai);
868417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->tr);
869417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->ph);
870417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->enc);
871417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(h);
872417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, obj, F_SQLite_Database_handle, 0);
873417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
874417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
875417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!final) {
876417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwclosed(env);
877417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
878417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
879417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
880417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
881417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1close(JNIEnv *env, jobject obj)
882417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
883417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    doclose(env, obj, 0);
884417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
885417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
886417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
887417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1finalize(JNIEnv *env, jobject obj)
888417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
889417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    doclose(env, obj, 1);
890417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
891417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
892417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
893417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1busy_1timeout(JNIEnv *env, jobject obj, jint ms)
894417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
895417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
896417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
897417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
898417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
899417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
900417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_busy_timeout((sqlite3 * ) h->sqlite, ms);
901417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
902417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_busy_timeout((sqlite *) h->sqlite, ms);
903417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
904417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
905417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
906417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_busy_timeout((sqlite *) h->sqlite, ms);
907417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
908417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
909417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_busy_timeout((sqlite3 * ) h->sqlite, ms);
910417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
911417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
912417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
913417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
914417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
915417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
916417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
917417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
918417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_version(JNIEnv *env, jclass cls)
919417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
920417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    /* CHECK THIS */
921417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
922417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, sqlite_libversion());
923417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
924417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
925417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, sqlite_libversion());
926417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
927417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, sqlite3_libversion());
928417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
929417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
930417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
931417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
932417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
933417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_dbversion(JNIEnv *env, jobject obj)
934417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
935417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
936417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
937417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
938417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
939417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
940417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewStringUTF(env, sqlite3_libversion());
941417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
942417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewStringUTF(env, sqlite_libversion());
943417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
944417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
945417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
946417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (*env)->NewStringUTF(env, sqlite_libversion());
947417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
948417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (*env)->NewStringUTF(env, sqlite3_libversion());
949417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
950417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
951417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
952417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, "unknown");
953417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
954417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
955417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jlong JNICALL
956417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1last_1insert_1rowid(JNIEnv *env, jobject obj)
957417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
958417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
959417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
960417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
961417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
962417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
963417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (jlong) sqlite3_last_insert_rowid((sqlite3 *) h->sqlite);
964417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
965417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (jlong) sqlite_last_insert_rowid((sqlite *) h->sqlite);
966417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
967417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
968417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
969417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (jlong) sqlite_last_insert_rowid((sqlite *) h->sqlite);
970417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
971417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
972417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (jlong) sqlite3_last_insert_rowid((sqlite3 *) h->sqlite);
973417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
974417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
975417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
976417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
977417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (jlong) 0;
978417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
979417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
980417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jlong JNICALL
981417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1changes(JNIEnv *env, jobject obj)
982417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
983417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
984417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
985417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
986417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
987417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
988417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (jlong) sqlite3_changes((sqlite3 *) h->sqlite);
989417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
990417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (jlong) sqlite_changes((sqlite *) h->sqlite);
991417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
992417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
993417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
994417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (jlong) sqlite_changes((sqlite *) h->sqlite);
995417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
996417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
997417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (jlong) sqlite3_changes((sqlite3 *) h->sqlite);
998417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
999417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1000417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1001417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1002417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (jlong) 0;
1003417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1004417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1005417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
1006417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1complete(JNIEnv *env, jclass cls, jstring sql)
1007417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1008417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transstr sqlstr;
1009417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jboolean result;
1010417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1011417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
1012417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_FALSE;
1013417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1014417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE || HAVE_SQLITE3
1015417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    /* CHECK THIS */
1016417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    trans2iso(env, 1, 0, sql, &sqlstr);
1017417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    result = sqlite3_complete(sqlstr.result) ? JNI_TRUE : JNI_FALSE;
1018417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1019417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    trans2iso(env, strcmp(sqlite_libencoding(), "UTF-8") == 0, 0,
1020417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	      sql, &sqlstr);
1021417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    result = sqlite_complete(sqlstr.result) ? JNI_TRUE : JNI_FALSE;
1022417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1023417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transfree(&sqlstr);
1024417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return result;
1025417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1026417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1027417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1028417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1interrupt(JNIEnv *env, jobject obj)
1029417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1030417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1031417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1032417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
1033417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1034417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
1035417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_interrupt((sqlite3 *) h->sqlite);
1036417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1037417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_interrupt((sqlite *) h->sqlite);
1038417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1039417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1040417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1041417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_interrupt((sqlite *) h->sqlite);
1042417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1043417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1044417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_interrupt((sqlite3 *) h->sqlite);
1045417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1046417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1047417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1048417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1049417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1050417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1051417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1052417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
10537a647e8547e57ca573541be55b3728ef7ce376feElliott HughesJava_SQLite_Database__1open4(JNIEnv *env, jobject obj, jstring file, jint mode,
10547a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			     jstring vfs, jboolean ver2)
1055417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1056417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1057417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jthrowable exc;
1058417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *err = 0;
1059417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transstr filename;
1060417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int maj, min, lev;
10617a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_OPEN_V2
10627a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    transstr vfsname;
10637a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes
10647a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    vfsname.result = 0;
10657a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    vfsname.tofree = 0;
10667a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    vfsname.jstr = 0;
10677a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
1068417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1069417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h) {
1070417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->sqlite) {
1071417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1072417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->is3) {
1073417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_close((sqlite3 *) h->sqlite);
1074417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
1075417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_close((sqlite *) h->sqlite);
1076417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1077417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->is3 = 0;
1078417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1079417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1080417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_close((sqlite *) h->sqlite);
1081417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1082417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1083417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_close((sqlite3 *) h->sqlite);
1084417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1085417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1086417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->sqlite = 0;
1087417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1088417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
1089417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h = malloc(sizeof (handle));
1090417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!h) {
1091417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to get SQLite handle");
1092417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1093417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1094417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->sqlite = 0;
10955cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	h->bh = h->cb = h->ai = h->tr = h->pr = h->ph = 0;
1096417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	/* CHECK THIS */
1097417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1098417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->is3 = 0;
1099417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->stmt = 0;
1100417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->haveutf = 1;
1101417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1102417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1103417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->haveutf = strcmp(sqlite_libencoding(), "UTF-8") == 0;
1104417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1105417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1106417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->stmt = 0;
1107417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->haveutf = 1;
1108417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1109417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1110417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->enc = 0;
1111417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->funcs = 0;
1112417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->ver = 0;
1113417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
1114417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->vms = 0;
1115417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1116417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
1117417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->blobs = 0;
1118417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
11195cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
11205cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	h->backups = 0;
11215cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
1122417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1123417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->env = 0;
1124417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!file) {
1125417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, err ? err : "invalid file name");
1126417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1127417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1128417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    trans2iso(env, h->haveutf, h->enc, file, &filename);
1129417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    exc = (*env)->ExceptionOccurred(env);
1130417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (exc) {
1131417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, exc);
1132417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1133417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
11347a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_OPEN_V2
11357a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (vfs) {
11367a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	trans2iso(env, 1, h->enc, vfs, &vfsname);
11377a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	exc = (*env)->ExceptionOccurred(env);
11387a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (exc) {
11397a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    transfree(&filename);
11407a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    (*env)->DeleteLocalRef(env, exc);
11417a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    return;
11427a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	}
11437a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    }
11447a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
1145417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1146417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    {
1147417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	FILE *f = fopen(filename.result, "rb");
1148417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int c_0 = EOF;
1149417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1150417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (f) {
1151417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    c_0 = fgetc(f);
1152417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    fclose(f);
1153417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
11547a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (c_0 != '*' && ver2 == JNI_FALSE) {
11557a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_OPEN_V2
11567a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    int rc = sqlite3_open_v2(filename.result, (sqlite3 **) &h->sqlite,
11577a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes				     (int) mode, vfsname.result);
11587a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#else
1159417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    int rc = sqlite3_open(filename.result, (sqlite3 **) &h->sqlite);
11607a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
1161417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1162417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (rc == SQLITE_OK) {
1163417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->is3 = 1;
1164417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else if (h->sqlite) {
11654538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		sqlite3_close((sqlite3 *) h->sqlite);
1166417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->sqlite = 0;
1167417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1168417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1169417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->sqlite = (void *) sqlite_open(filename.result,
1170417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     (int) mode, &err);
1171417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1172417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1173417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1174417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1175417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->sqlite = (void *) sqlite_open(filename.result, (int) mode, &err);
1176417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1177417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
11787a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_OPEN_V2
11797a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (sqlite3_open_v2(filename.result, (sqlite3 **) &h->sqlite,
11807a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			(int) mode, vfsname.result) != SQLITE_OK)
11817a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#else
11827a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (sqlite3_open(filename.result, (sqlite3 **) &h->sqlite) != SQLITE_OK)
11837a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
11847a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    {
11854538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	if (h->sqlite) {
1186417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_close((sqlite3 *) h->sqlite);
1187417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->sqlite = 0;
1188417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1189417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1190417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1191417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1192417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transfree(&filename);
11937a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_OPEN_V2
11947a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    transfree(&vfsname);
11957a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
1196417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    exc = (*env)->ExceptionOccurred(env);
1197417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (exc) {
1198417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, exc);
1199417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1200417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (err) {
1201417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_freemem(err);
1202417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1203417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1204417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->sqlite) {
1205417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1206417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->is3) {
1207417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_close((sqlite3 *) h->sqlite);
1208417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->is3 = 0;
1209417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
1210417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_close((sqlite *) h->sqlite);
1211417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1212417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1213417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1214417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_close((sqlite *) h->sqlite);
1215417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1216417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1217417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_close((sqlite3 *) h->sqlite);
1218417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1219417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1220417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1221417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->sqlite = 0;
1222417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1223417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1224417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h->sqlite) {
1225417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jvalue v;
1226417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1227417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v.j = 0;
1228417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v.l = (jobject) h;
1229417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, obj, F_SQLite_Database_handle, v.j);
1230417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1231417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (err) {
1232417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_freemem(err);
1233417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1234417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1235417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1236417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
1237417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sscanf(sqlite3_libversion(), "%d.%d.%d", &maj, &min, &lev);
12387a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_LOAD_EXTENSION
12397a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    sqlite3_enable_load_extension((sqlite3 *) h->sqlite, 1);
12407a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
1241417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1242417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sscanf(sqlite_libversion(), "%d.%d.%d", &maj, &min, &lev);
1243417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1244417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1245417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1246417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sscanf(sqlite_libversion(), "%d.%d.%d", &maj, &min, &lev);
1247417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1248417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1249417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sscanf(sqlite3_libversion(), "%d.%d.%d", &maj, &min, &lev);
12507a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_LOAD_EXTENSION
12517a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	sqlite3_enable_load_extension((sqlite3 *) h->sqlite, 1);
12527a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
1253417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1254417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1255417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->ver = ((maj & 0xFF) << 16) | ((min & 0xFF) << 8) | (lev & 0xFF);
1256417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1257417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1258417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, err ? err : "unknown error in open");
1259417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1260417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (err) {
1261417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_freemem(err);
1262417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1263417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1264417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1265417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1266417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
12677a647e8547e57ca573541be55b3728ef7ce376feElliott HughesJava_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode)
12687a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes{
12697a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    Java_SQLite_Database__1open4(env, obj, file, mode, 0, 0);
12707a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes}
12717a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes
12727a647e8547e57ca573541be55b3728ef7ce376feElliott HughesJNIEXPORT void JNICALL
1273417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1open_1aux_1file(JNIEnv *env, jobject obj, jstring file)
1274417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1275417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1276417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_OPEN_AUX_FILE
1277417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jthrowable exc;
1278417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *err = 0;
1279417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transstr filename;
1280417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
1281417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1282417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1283417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
1284417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_OPEN_AUX_FILE
1285417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1286417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
1287417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "unsupported");
1288417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1289417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1290417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2iso(env, h->haveutf, h->enc, file, &filename);
1291417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
1292417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
1293417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
1294417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1295417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1296417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite_open_aux_file((sqlite *) h->sqlite,
1297417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				   filename.result, &err);
1298417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&filename);
1299417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
1300417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
1301417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
1302417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (err) {
1303417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_freemem(err);
1304417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1305417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1306417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1307417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
1308417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : sqlite_error_string(ret));
1309417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1310417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (err) {
1311417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_freemem(err);
1312417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1313417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1314417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "unsupported");
1315417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1316417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1317417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1318417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1319417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1320417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1321417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1322417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1busy_1handler(JNIEnv *env, jobject obj, jobject bh)
1323417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1324417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1325417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1326417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
1327417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->bh);
1328417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, bh, &h->bh);
1329417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1330417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
1331417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_busy_handler((sqlite3 *) h->sqlite, busyhandler3, h);
1332417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1333417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_busy_handler((sqlite *) h->sqlite, busyhandler, h);
1334417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1335417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1336417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1337417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_busy_handler((sqlite *) h->sqlite, busyhandler, h);
1338417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1339417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1340417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_busy_handler((sqlite3 *) h->sqlite, busyhandler3, h);
1341417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1342417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1343417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1344417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1345417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1346417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1347417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1348417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1349417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1exec__Ljava_lang_String_2LSQLite_Callback_2
1350417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (JNIEnv *env, jobject obj, jstring sql, jobject cb)
1351417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1352417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1353417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    freemem *freeproc;
1354417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1355417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
1356417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "invalid SQL statement");
1357417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1358417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1359417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h) {
1360417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->sqlite) {
1361417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jthrowable exc;
1362417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    int rc;
1363417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char *err = 0;
1364417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr sqlstr;
1365417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jobject oldcb = globrefpop(env, &h->cb);
1366417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1367417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    globrefset(env, cb, &h->cb);
1368417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->env = env;
1369417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->row1 = 1;
1370417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2iso(env, h->haveutf, h->enc, sql, &sqlstr);
1371417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
1372417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
1373417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
1374417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1375417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1376417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1377417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (h->is3) {
1378417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite3_exec((sqlite3 *) h->sqlite, sqlstr.result,
1379417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  callback, h, &err);
1380417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc = (freemem *) sqlite3_free;
1381417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
1382417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite_exec((sqlite *) h->sqlite, sqlstr.result,
1383417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 callback, h, &err);
1384417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc = (freemem *) sqlite_freemem;
1385417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1386417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1387417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1388417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    rc = sqlite_exec((sqlite *) h->sqlite, sqlstr.result,
1389417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			     callback, h, &err);
1390417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    freeproc = (freemem *) sqlite_freemem;
1391417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1392417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1393417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    rc = sqlite3_exec((sqlite3 *) h->sqlite, sqlstr.result,
1394417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			      callback, h, &err);
1395417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    freeproc = (freemem *) sqlite3_free;
1396417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1397417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1398417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&sqlstr);
1399417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
1400417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &h->cb);
1401417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->cb = oldcb;
1402417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
1403417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
1404417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (err) {
1405417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    freeproc(err);
1406417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1407417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1408417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1409417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (rc != SQLITE_OK) {
1410417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		char msg[128];
1411417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1412417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		seterr(env, obj, rc);
1413417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (!err) {
1414417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sprintf(msg, "error %d in sqlite*_exec", rc);
1415417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1416417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwex(env, err ? err : msg);
1417417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1418417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (err) {
1419417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc(err);
1420417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1421417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1422417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1423417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1424417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1425417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1426417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1427417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1428417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1exec__Ljava_lang_String_2LSQLite_Callback_2_3Ljava_lang_String_2
1429417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (JNIEnv *env, jobject obj, jstring sql, jobject cb, jobjectArray args)
1430417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1431417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1432417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    freemem *freeproc = 0;
1433417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1434417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
1435417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "invalid SQL statement");
1436417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1437417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1438417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h) {
1439417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->sqlite) {
1440417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jthrowable exc;
1441417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    int rc = SQLITE_ERROR, nargs, i;
1442417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char *err = 0, *p;
14434538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    const char *str = (*env)->GetStringUTFChars(env, sql, 0);
1444417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr sqlstr;
1445417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    struct args {
1446417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		char *arg;
1447417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		jobject obj;
1448417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transstr trans;
1449417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } *argv = 0;
1450417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char **cargv = 0;
1451417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jobject oldcb = globrefpop(env, &h->cb);
1452417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1453417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    globrefset(env, cb, &h->cb);
1454417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    p = (char *) str;
1455417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    nargs = 0;
1456417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    while (*p) {
1457417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (*p == '%') {
1458417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    ++p;
1459417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (*p == 'q' || *p == 's') {
1460417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			nargs++;
1461417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (nargs > MAX_PARAMS) {
1462417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->ReleaseStringUTFChars(env, sql, str);
1463417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    delglobrefp(env, &h->cb);
1464417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    h->cb = oldcb;
1465417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    throwex(env, "too much SQL parameters");
1466417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    return;
1467417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
1468417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    } else if (h->ver >= 0x020500 && *p == 'Q') {
1469417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			nargs++;
1470417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (nargs > MAX_PARAMS) {
1471417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (*env)->ReleaseStringUTFChars(env, sql, str);
1472417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    delglobrefp(env, &h->cb);
1473417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    h->cb = oldcb;
1474417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    throwex(env, "too much SQL parameters");
1475417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    return;
1476417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
1477417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    } else if (*p != '%') {
1478417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->ReleaseStringUTFChars(env, sql, str);
1479417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			delglobrefp(env, &h->cb);
1480417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			h->cb = oldcb;
1481417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			throwex(env, "bad % specification in query");
1482417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			return;
1483417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
1484417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1485417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		++p;
1486417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1487417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    cargv = malloc((sizeof (*argv) + sizeof (char *))
1488417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			   * MAX_PARAMS);
1489417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (!cargv) {
1490417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->ReleaseStringUTFChars(env, sql, str);
1491417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		delglobrefp(env, &h->cb);
1492417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->cb = oldcb;
1493417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwoom(env, "unable to allocate arg vector");
1494417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1495417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1496417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    argv = (struct args *) (cargv + MAX_PARAMS);
1497417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    for (i = 0; i < MAX_PARAMS; i++) {
1498417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		cargv[i] = 0;
1499417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		argv[i].arg = 0;
1500417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		argv[i].obj = 0;
1501417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		argv[i].trans.result = argv[i].trans.tofree = 0;
1502417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1503417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = 0;
1504417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    for (i = 0; i < nargs; i++) {
1505417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		jobject so = (*env)->GetObjectArrayElement(env, args, i);
1506417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1507417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		exc = (*env)->ExceptionOccurred(env);
1508417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (exc) {
1509417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, exc);
1510417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    break;
1511417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1512417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (so) {
1513417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    argv[i].obj = so;
1514417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    argv[i].arg = cargv[i] =
1515417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			trans2iso(env, h->haveutf, h->enc, argv[i].obj,
1516417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  &argv[i].trans);
1517417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1518417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1519417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
1520417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < nargs; i++) {
1521417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (argv[i].obj) {
1522417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			transfree(&argv[i].trans);
1523417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
1524417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1525417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freep((char **) &cargv);
1526417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->ReleaseStringUTFChars(env, sql, str);
1527417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		delglobrefp(env, &h->cb);
1528417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		h->cb = oldcb;
1529417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1530417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1531417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->env = env;
1532417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->row1 = 1;
1533417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2iso(env, h->haveutf, h->enc, sql, &sqlstr);
1534417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
1535417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (!exc) {
1536417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1537417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (h->is3) {
1538417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
1539417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    char *s = sqlite3_vmprintf(sqlstr.result, (char *) cargv);
1540417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1541417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    char *s = sqlite3_mprintf(sqlstr.result,
1542417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[0], cargv[1],
1543417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[2], cargv[3],
1544417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[4], cargv[5],
1545417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[6], cargv[7],
1546417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[8], cargv[9],
1547417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[10], cargv[11],
1548417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[12], cargv[13],
1549417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[14], cargv[15],
1550417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[16], cargv[17],
1551417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[18], cargv[19],
1552417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[20], cargv[21],
1553417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[22], cargv[23],
1554417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[24], cargv[25],
1555417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[26], cargv[27],
1556417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[28], cargv[29],
1557417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      cargv[30], cargv[31]);
1558417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1559417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1560417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (s) {
1561417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			rc = sqlite3_exec((sqlite3 *) h->sqlite, s, callback,
1562417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  h, &err);
1563417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			sqlite3_free(s);
1564417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    } else {
1565417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			rc = SQLITE_NOMEM;
1566417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
1567417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    freeproc = (freemem *) sqlite3_free;
1568417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		} else {
1569417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
1570417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    rc = sqlite_exec_vprintf((sqlite *) h->sqlite,
1571417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     sqlstr.result, callback, h, &err,
1572417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     (char *) cargv);
1573417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1574417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    rc = sqlite_exec_printf((sqlite *) h->sqlite,
1575417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    sqlstr.result, callback,
1576417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    h, &err,
1577417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[0], cargv[1],
1578417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[2], cargv[3],
1579417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[4], cargv[5],
1580417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[6], cargv[7],
1581417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[8], cargv[9],
1582417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[10], cargv[11],
1583417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[12], cargv[13],
1584417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[14], cargv[15],
1585417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[16], cargv[17],
1586417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[18], cargv[19],
1587417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[20], cargv[21],
1588417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[22], cargv[23],
1589417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[24], cargv[25],
1590417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[26], cargv[27],
1591417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[28], cargv[29],
1592417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    cargv[30], cargv[31]);
1593417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1594417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    freeproc = (freemem *) sqlite_freemem;
1595417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1596417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1597417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1598417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
1599417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite_exec_vprintf((sqlite *) h->sqlite, sqlstr.result,
1600417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 callback, h, &err, (char *) cargv);
1601417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1602417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite_exec_printf((sqlite *) h->sqlite, sqlstr.result,
1603417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					callback, h, &err,
1604417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[0], cargv[1],
1605417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[2], cargv[3],
1606417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[4], cargv[5],
1607417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[6], cargv[7],
1608417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[8], cargv[9],
1609417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[10], cargv[11],
1610417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[12], cargv[13],
1611417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[14], cargv[15],
1612417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[16], cargv[17],
1613417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[18], cargv[19],
1614417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[20], cargv[21],
1615417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[22], cargv[23],
1616417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[24], cargv[25],
1617417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[26], cargv[27],
1618417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[28], cargv[29],
1619417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					cargv[30], cargv[31]);
1620417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1621417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc = (freemem *) sqlite_freemem;
1622417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1623417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1624417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
1625417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		char *s = sqlite3_vmprintf(sqlstr.result, (char *) cargv);
1626417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1627417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		char *s = sqlite3_mprintf(sqlstr.result,
1628417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[0], cargv[1],
1629417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[2], cargv[3],
1630417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[4], cargv[5],
1631417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[6], cargv[7],
1632417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[8], cargv[9],
1633417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[10], cargv[11],
1634417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[12], cargv[13],
1635417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[14], cargv[15],
1636417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[16], cargv[17],
1637417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[18], cargv[19],
1638417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[20], cargv[21],
1639417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[22], cargv[23],
1640417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[24], cargv[25],
1641417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[26], cargv[27],
1642417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[28], cargv[29],
1643417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  cargv[30], cargv[31]);
1644417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1645417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1646417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (s) {
1647417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    rc = sqlite3_exec((sqlite3 *) h->sqlite, s, callback,
1648417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      h, &err);
1649417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sqlite3_free(s);
1650417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		} else {
1651417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    rc = SQLITE_NOMEM;
1652417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1653417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc = (freemem *) sqlite3_free;
1654417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1655417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1656417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		exc = (*env)->ExceptionOccurred(env);
1657417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1658417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    for (i = 0; i < nargs; i++) {
1659417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (argv[i].obj) {
1660417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    transfree(&argv[i].trans);
1661417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1662417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1663417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&sqlstr);
1664417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringUTFChars(env, sql, str);
1665417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    freep((char **) &cargv);
1666417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &h->cb);
1667417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->cb = oldcb;
1668417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
1669417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
1670417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (err && freeproc) {
1671417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    freeproc(err);
1672417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1673417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1674417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1675417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (rc != SQLITE_OK) {
1676417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		char msg[128];
1677417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1678417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		seterr(env, obj, rc);
1679417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (!err) {
1680417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sprintf(msg, "error %d in sqlite*_exec", rc);
1681417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1682417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwex(env, err ? err : msg);
1683417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1684417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (err && freeproc) {
1685417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc(err);
1686417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1687417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1688417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1689417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1690417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1691417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1692417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1693417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic hfunc *
1694417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesgetfunc(JNIEnv *env, jobject obj)
1695417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1696417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue v;
1697417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1698417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v.j = (*env)->GetLongField(env, obj, F_SQLite_FunctionContext_handle);
1699417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (hfunc *) v.l;
1700417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1701417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1702417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1703417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1704417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall_common(sqlite_func *sf, int isstep, int nargs, const char **args)
1705417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1706417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = (hfunc *) sqlite_user_data(sf);
1707417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1708417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->env && f->fi) {
1709417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	JNIEnv *env = f->env;
1710417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, f->fi);
1711417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid =
1712417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->GetMethodID(env, cls,
1713417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				isstep ? "step" : "function",
1714417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				"(LSQLite/FunctionContext;[Ljava/lang/String;)V");
1715417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jobjectArray arr;
1716417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int i;
1717417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1718417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
17194538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    (*env)->DeleteLocalRef(env, cls);
1720417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1721417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1722417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0);
1723417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	for (i = 0; i < nargs; i++) {
1724417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (args[i]) {
1725417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transstr arg;
1726417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		jthrowable exc;
1727417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1728417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, f->h->haveutf, f->h->enc, args[i], &arg);
1729417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->SetObjectArrayElement(env, arr, i, arg.jstr);
1730417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		exc = (*env)->ExceptionOccurred(env);
1731417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (exc) {
1732417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, exc);
1733417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return;
1734417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1735417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, arg.jstr);
1736417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1737417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1738417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->sf = sf;
1739417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->CallVoidMethod(env, f->fi, mid, f->fc, arr);
1740417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, arr);
1741417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, cls);
1742417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1743417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1744417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1745417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1746417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall_func(sqlite_func *sf, int nargs, const char **args)
1747417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1748417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    call_common(sf, 0, nargs, args);
1749417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1750417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1751417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1752417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall_step(sqlite_func *sf, int nargs, const char **args)
1753417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1754417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    call_common(sf, 1, nargs, args);
1755417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1756417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1757417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1758417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall_final(sqlite_func *sf)
1759417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1760417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = (hfunc *) sqlite_user_data(sf);
1761417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1762417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->env && f->fi) {
1763417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	JNIEnv *env = f->env;
1764417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, f->fi);
1765417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid = (*env)->GetMethodID(env, cls, "last_step",
1766417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    "(LSQLite/FunctionContext;)V");
1767417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
17684538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    (*env)->DeleteLocalRef(env, cls);
1769417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1770417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1771417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->sf = sf;
1772417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->CallVoidMethod(env, f->fi, mid, f->fc);
1773417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, cls);
1774417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1775417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1776417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1777417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1778417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1779417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1780417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall3_common(sqlite3_context *sf, int isstep, int nargs, sqlite3_value **args)
1781417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1782417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = (hfunc *) sqlite3_user_data(sf);
1783417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1784417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->env && f->fi) {
1785417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	JNIEnv *env = f->env;
1786417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, f->fi);
1787417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid =
1788417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->GetMethodID(env, cls,
1789417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				isstep ? "step" : "function",
1790417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				"(LSQLite/FunctionContext;[Ljava/lang/String;)V");
1791417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jobjectArray arr;
1792417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int i;
1793417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1794417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
17954538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    (*env)->DeleteLocalRef(env, cls);
1796417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1797417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1798417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0);
1799417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	for (i = 0; i < nargs; i++) {
1800417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (args[i]) {
1801417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transstr arg;
1802417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		jthrowable exc;
1803417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1804417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, 1, 0, (char *) sqlite3_value_text(args[i]),
1805417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			  &arg);
1806417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->SetObjectArrayElement(env, arr, i, arg.jstr);
1807417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		exc = (*env)->ExceptionOccurred(env);
1808417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (exc) {
1809417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->DeleteLocalRef(env, exc);
1810417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return;
1811417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
1812417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, arg.jstr);
1813417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1814417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1815417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->sf = sf;
1816417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->CallVoidMethod(env, f->fi, mid, f->fc, arr);
1817417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, arr);
1818417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, cls);
1819417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1820417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1821417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1822417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1823417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall3_func(sqlite3_context *sf, int nargs, sqlite3_value **args)
1824417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1825417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    call3_common(sf, 0, nargs, args);
1826417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1827417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1828417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1829417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall3_step(sqlite3_context *sf, int nargs, sqlite3_value **args)
1830417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1831417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    call3_common(sf, 1, nargs, args);
1832417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1833417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1834417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1835417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughescall3_final(sqlite3_context *sf)
1836417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1837417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = (hfunc *) sqlite3_user_data(sf);
1838417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1839417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->env && f->fi) {
1840417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	JNIEnv *env = f->env;
1841417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, f->fi);
1842417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid = (*env)->GetMethodID(env, cls, "last_step",
1843417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    "(LSQLite/FunctionContext;)V");
1844417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid == 0) {
18454538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    (*env)->DeleteLocalRef(env, cls);
1846417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1847417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1848417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->sf = sf;
1849417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->CallVoidMethod(env, f->fi, mid, f->fc);
1850417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, cls);
1851417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1852417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1853417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1854417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1855417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
1856417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesmkfunc_common(JNIEnv *env, int isagg, jobject obj, jstring name,
1857417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	      jint nargs, jobject fi)
1858417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1859417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1860417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1861417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
1862417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->FindClass(env, "SQLite/FunctionContext");
1863417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jobject fc;
1864417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	hfunc *f;
1865417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
1866417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr namestr;
1867417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jvalue v;
1868417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
1869417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1870417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	fc = (*env)->AllocObject(env, cls);
1871417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!fi) {
1872417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "null SQLite.Function not allowed");
1873417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1874417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1875417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f = malloc(sizeof (hfunc));
1876417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!f) {
1877417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to get SQLite.FunctionContext handle");
1878417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1879417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1880417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, fc, &f->fc);
1881417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, fi, &f->fi);
1882417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, obj, &f->db);
1883417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->h = h;
1884417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->next = h->funcs;
1885417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->funcs = f;
1886417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->sf = 0;
1887417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->env = env;
1888417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v.j = 0;
1889417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v.l = (jobject) f;
1890417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, f->fc, F_SQLite_FunctionContext_handle, v.j);
1891417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2iso(env, h->haveutf, h->enc, name, &namestr);
1892417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
1893417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
1894417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
1895417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1896417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1897417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1898417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	f->is3 = h->is3;
1899417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
1900417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_create_function((sqlite3 *) h->sqlite,
1901417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  namestr.result,
1902417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  (int) nargs,
1903417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  SQLITE_UTF8, f,
1904417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  isagg ? NULL : call3_func,
1905417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  isagg ? call3_step : NULL,
1906417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  isagg ? call3_final : NULL);
1907417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1908417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1909417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (isagg) {
1910417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ret = sqlite_create_aggregate((sqlite *) h->sqlite,
1911417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      namestr.result,
1912417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      (int) nargs,
1913417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					      call_step, call_final, f);
1914417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
1915417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ret = sqlite_create_function((sqlite *) h->sqlite,
1916417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     namestr.result,
1917417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     (int) nargs,
1918417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     call_func, f);
1919417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1920417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1921417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
1922417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1923417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (isagg) {
1924417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite_create_aggregate((sqlite *) h->sqlite, namestr.result,
1925417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  (int) nargs,
1926417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  call_step, call_final, f);
1927417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
1928417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite_create_function((sqlite *) h->sqlite, namestr.result,
1929417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 (int) nargs,
1930417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 call_func, f);
1931417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1932417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1933417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
1934417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_create_function((sqlite3 *) h->sqlite,
1935417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      namestr.result,
1936417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      (int) nargs,
1937417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      SQLITE_UTF8, f,
1938417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      isagg ? NULL : call3_func,
1939417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      isagg ? call3_step : NULL,
1940417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      isagg ? call3_final : NULL);
1941417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1942417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1943417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&namestr);
1944417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
1945417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "error creating function/aggregate");
1946417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1947417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
1948417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
1949417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
1950417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1951417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1952417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1953417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1create_1aggregate(JNIEnv *env, jobject obj,
1954417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 jstring name, jint nargs, jobject fi)
1955417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1956417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    mkfunc_common(env, 1, obj, name, nargs, fi);
1957417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1958417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1959417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1960417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1create_1function(JNIEnv *env, jobject obj,
1961417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					jstring name, jint nargs, jobject fi)
1962417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1963417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    mkfunc_common(env, 0, obj, name, nargs, fi);
1964417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
1965417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1966417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
1967417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1function_1type(JNIEnv *env, jobject obj,
1968417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      jstring name, jint type)
1969417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
1970417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
1971417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1972417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
1973417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
1974417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
1975417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
1976417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1977417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1978417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
1979417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_FUNCTION_TYPE
1980417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	{
1981417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    int ret;
1982417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr namestr;
1983417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jthrowable exc;
1984417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
1985417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2iso(env, h->haveutf, h->enc, name, &namestr);
1986417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
1987417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
1988417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
1989417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
1990417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1991417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite_function_type(h->sqlite, namestr.result, (int) type);
1992417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&namestr);
1993417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ret != SQLITE_OK) {
1994417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwex(env, sqlite_error_string(ret));
1995417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
1996417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
1997417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1998417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
1999417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2000417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2001417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
2002417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2003417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2004417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
2005417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_count(JNIEnv *env, jobject obj)
2006417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2007417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
2008417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jint r = 0;
2009417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2010417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
2011417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_BOTH
2012417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (f->is3) {
2013417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    r = (jint) sqlite3_aggregate_count((sqlite3_context *) f->sf);
2014417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2015417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    r = (jint) sqlite_aggregate_count((sqlite_func *) f->sf);
2016417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2017417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2018417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2019417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	r = (jint) sqlite_aggregate_count((sqlite_func *) f->sf);
2020417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2021417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2022417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	r = (jint) sqlite3_aggregate_count((sqlite3_context *) f->sf);
2023417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2024417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2025417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2026417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return r;
2027417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2028417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2029417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2030417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1error(JNIEnv *env, jobject obj, jstring err)
2031417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2032417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
2033417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2034417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
2035417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2036417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!f->is3) {
2037417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr errstr;
2038417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jthrowable exc;
2039417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2040417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2iso(env, f->h->haveutf, f->h->enc, err, &errstr);
2041417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2042417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
20434538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		(*env)->DeleteLocalRef(env, exc);
2044417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
2045417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2046417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_set_result_error((sqlite_func *) f->sf,
2047417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    errstr.result, -1);
2048417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&errstr);
2049417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else if (err) {
2050417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jsize len = (*env)->GetStringLength(env, err) * sizeof (jchar);
2051417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const jchar *str = (*env)->GetStringChars(env, err, 0);
2052417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2053417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_error16((sqlite3_context *) f->sf, str, len);
2054417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringChars(env, err, str);
2055417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2056417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_error((sqlite3_context *) f->sf,
2057417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 "null error text", -1);
2058417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2059417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2060417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2061417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr errstr;
2062417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
2063417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2064417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2iso(env, f->h->haveutf, f->h->enc, err, &errstr);
2065417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
2066417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
2067417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
2068417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
2069417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2070417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_set_result_error((sqlite_func *) f->sf, errstr.result, -1);
2071417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&errstr);
2072417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2073417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2074417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (err) {
2075417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jsize len = (*env)->GetStringLength(env, err) * sizeof (jchar);
2076417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const jchar *str = (*env)->GetStringChars(env, err, 0);
2077417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2078417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_error16((sqlite3_context *) f->sf, str, len);
2079417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringChars(env, err, str);
2080417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2081417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_error((sqlite3_context *) f->sf,
2082417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 "null error text", -1);
2083417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2084417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2085417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2086417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2087417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2088417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2089417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2090417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1result__D(JNIEnv *env, jobject obj, jdouble d)
2091417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2092417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
2093417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2094417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
2095417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2096417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (f->is3) {
2097417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_double((sqlite3_context *) f->sf, (double) d);
2098417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2099417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_set_result_double((sqlite_func *) f->sf, (double) d);
2100417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2101417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2102417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2103417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_set_result_double((sqlite_func *) f->sf, (double) d);
2104417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2105417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2106417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_result_double((sqlite3_context *) f->sf, (double) d);
2107417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2108417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2109417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2110417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2111417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2112417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2113417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1result__I(JNIEnv *env, jobject obj, jint i)
2114417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2115417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
2116417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2117417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
2118417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2119417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (f->is3) {
2120417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_int((sqlite3_context *) f->sf, (int) i);
2121417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2122417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_set_result_int((sqlite_func *) f->sf, (int) i);
2123417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2124417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2125417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2126417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_set_result_int((sqlite_func *) f->sf, (int) i);
2127417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2128417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2129417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_result_int((sqlite3_context *) f->sf, (int) i);
2130417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2131417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2132417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2133417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2134417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2135417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2136417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1result__Ljava_lang_String_2(JNIEnv *env,
2137417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes							     jobject obj,
2138417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes							     jstring ret)
2139417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2140417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
2141417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2142417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
2143417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2144417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!f->is3) {
2145417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr retstr;
2146417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jthrowable exc;
2147417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2148417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2iso(env, f->h->haveutf, f->h->enc, ret, &retstr);
2149417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2150417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
21514538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		(*env)->DeleteLocalRef(env, exc);
2152417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
2153417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2154417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_set_result_string((sqlite_func *) f->sf,
2155417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				     retstr.result, -1);
2156417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&retstr);
2157417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else if (ret) {
2158417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jsize len = (*env)->GetStringLength(env, ret) * sizeof (jchar);
2159417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const jchar *str = (*env)->GetStringChars(env, ret, 0);
2160417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2161417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_text16((sqlite3_context *) f->sf, str, len,
2162417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  SQLITE_TRANSIENT);
2163417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringChars(env, ret, str);
2164417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2165417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_null((sqlite3_context *) f->sf);
2166417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2167417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2168417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2169417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr retstr;
2170417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
2171417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2172417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2iso(env, f->h->haveutf, f->h->enc, ret, &retstr);
2173417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
2174417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
2175417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
2176417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
2177417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2178417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_set_result_string((sqlite_func *) f->sf, retstr.result, -1);
2179417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&retstr);
2180417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2181417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2182417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret) {
2183417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jsize len = (*env)->GetStringLength(env, ret) * sizeof (jchar);
2184417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const jchar *str = (*env)->GetStringChars(env, ret, 0);
2185417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2186417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_text16((sqlite3_context *) f->sf, str, len,
2187417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  SQLITE_TRANSIENT);
2188417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringChars(env, ret, str);
2189417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2190417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_null((sqlite3_context *) f->sf);
2191417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2192417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2193417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2194417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2195417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2196417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2197417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2198417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1result___3B(JNIEnv *env, jobject obj,
2199417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					     jbyteArray b)
2200417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2201417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2202417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
2203417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2204417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
2205417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2206417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!f->is3) {
2207417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    /* silently ignored */
2208417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
2209417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2210417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2211417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (b) {
2212417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jsize len;
2213417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jbyte *data;
2214417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2215417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    len = (*env)->GetArrayLength(env, b);
2216417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    data = (*env)->GetByteArrayElements(env, b, 0);
2217417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_blob((sqlite3_context *) f->sf,
2218417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				data, len, SQLITE_TRANSIENT);
2219417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseByteArrayElements(env, b, data, 0);
2220417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2221417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_result_null((sqlite3_context *) f->sf);
2222417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2223417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2224417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2225417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2226417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2227417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2228417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_set_1result_1zeroblob(JNIEnv *env, jobject obj,
2229417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						  jint n)
2230417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2231417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_RESULT_ZEROBLOB
2232417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hfunc *f = getfunc(env, obj);
2233417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2234417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (f && f->sf) {
2235417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2236417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!f->is3) {
2237417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    /* silently ignored */
2238417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
2239417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2240417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2241417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_result_zeroblob((sqlite3_context *) f->sf, n);
2242417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2243417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2244417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2245417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2246417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
2247417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_error_1string(JNIEnv *env, jclass c, jint err)
2248417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2249417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2250417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, sqlite_error_string((int) err));
2251417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2252417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return (*env)->NewStringUTF(env, "unkown error");
2253417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2254417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2255417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2256417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
2257417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1errmsg(JNIEnv *env, jobject obj)
2258417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2259417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2260417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
2261417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2262417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
2263417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2264417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!h->is3) {
2265417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
2266417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2267417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2268417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return (*env)->NewStringUTF(env,
2269417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    sqlite3_errmsg((sqlite3 *) h->sqlite));
2270417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2271417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2272417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
2273417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2274417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2275417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2276417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1set_1encoding(JNIEnv *env, jobject obj, jstring enc)
2277417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2278417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
2279417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2280417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && !h->haveutf) {
2281417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2282417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!h->is3) {
2283417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    delglobrefp(env, &h->enc);
2284417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->enc = enc;
2285417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    globrefset(env, enc, &h->enc);
2286417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2287417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2288417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2289417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->enc);
2290417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->enc = enc;
2291417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, enc, &h->enc);
2292417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2293417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2294417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2295417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2296417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2297417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_SET_AUTHORIZER
2298417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic int
2299417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdoauth(void *arg, int what, const char *arg1, const char *arg2,
2300417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes       const char *arg3, const char *arg4)
2301417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2302417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) arg;
2303417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
2304417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2305417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->ai) {
2306417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
2307417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->ai);
2308417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid;
2309417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jint i = what;
2310417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2311417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	mid = (*env)->GetMethodID(env, cls, "authorize",
2312417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I");
2313417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid) {
2314417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jstring s1 = 0, s2 = 0, s3 = 0, s4 = 0;
2315417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr tr;
2316417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2317417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (arg1) {
2318417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, h->haveutf, h->enc, arg1, &tr);
2319417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		s1 = tr.jstr;
2320417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2321417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2322417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
2323417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
2324417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return SQLITE_DENY;
2325417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2326417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (arg2) {
2327417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, h->haveutf, h->enc, arg2, &tr);
2328417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		s2 = tr.jstr;
2329417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2330417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (arg3) {
2331417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, h->haveutf, h->enc, arg3, &tr);
2332417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		s3 = tr.jstr;
2333417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2334417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (arg4) {
2335417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		trans2utf(env, h->haveutf, h->enc, arg4, &tr);
2336417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		s4 = tr.jstr;
2337417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2338417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2339417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
2340417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
2341417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return SQLITE_DENY;
2342417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2343417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    i = (*env)->CallIntMethod(env, h->ai, mid, i, s1, s2, s3, s4);
2344417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2345417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
2346417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
2347417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return SQLITE_DENY;
2348417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2349417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, s4);
2350417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, s3);
2351417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, s2);
2352417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, s1);
2353417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (i != SQLITE_OK && i != SQLITE_IGNORE) {
2354417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		i = SQLITE_DENY;
2355417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2356417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (int) i;
2357417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2358417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2359417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return SQLITE_DENY;
2360417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2361417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2362417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2363417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2364417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1set_1authorizer(JNIEnv *env, jobject obj, jobject auth)
2365417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2366417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
2367417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2368417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
2369417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->ai);
2370417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, auth, &h->ai);
2371417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_SET_AUTHORIZER
2372417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->env = env;
2373417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2374417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
2375417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_set_authorizer((sqlite3 *) h->sqlite,
2376417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				   h->ai ? doauth : 0, h);
2377417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2378417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_set_authorizer((sqlite *) h->sqlite,
2379417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  h->ai ? doauth : 0, h);
2380417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2381417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2382417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2383417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_set_authorizer((sqlite *) h->sqlite, h->ai ? doauth : 0, h);
2384417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2385417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2386417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_set_authorizer((sqlite3 *) h->sqlite, h->ai ? doauth : 0, h);
2387417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2388417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2389417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2390417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2391417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2392417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
2393417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2394417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2395417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_TRACE
2396417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
2397417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdotrace(void *arg, const char *msg)
2398417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2399417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = (handle *) arg;
2400417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env = h->env;
2401417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2402417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (env && h->tr && msg) {
2403417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
2404417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->tr);
2405417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jmethodID mid;
2406417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2407417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	mid = (*env)->GetMethodID(env, cls, "trace", "(Ljava/lang/String;)V");
2408417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (mid) {
2409417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr tr;
2410417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2411417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    trans2utf(env, h->haveutf, h->enc, msg, &tr);
2412417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2413417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
2414417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
2415417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->ExceptionClear(env);
2416417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
2417417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2418417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->CallVoidMethod(env, h->tr, mid, tr.jstr);
2419417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ExceptionClear(env);
2420417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, tr.jstr);
2421417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
2422417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2423417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2424417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return;
2425417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2426417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2427417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2428417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2429417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1trace(JNIEnv *env, jobject obj, jobject tr)
2430417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2431417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
2432417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2433417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
2434417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->tr);
2435417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	globrefset(env, tr, &h->tr);
2436417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2437417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
2438417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_trace((sqlite3 *) h->sqlite, h->tr ? dotrace : 0, h);
2439417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2440417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_TRACE
2441417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_trace((sqlite *) h->sqlite, h->tr ? dotrace : 0, h);
2442417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2443417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2444417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2445417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2446417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_TRACE
2447417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_trace((sqlite *) h->sqlite, h->tr ? dotrace : 0, h);
2448417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2449417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2450417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2451417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_trace((sqlite3 *) h->sqlite, h->tr ? dotrace : 0, h);
2452417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2453417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2454417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2455417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2456417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
2457417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2458417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2459417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2460417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
2461417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdovmfinal(JNIEnv *env, jobject obj, int final)
2462417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2463417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethvm(env, obj);
2464417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2465417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v) {
2466417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->h) {
2467417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    handle *h = v->h;
2468417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    hvm *vv, **vvp;
2469417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2470417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vvp = &h->vms;
2471417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vv = *vvp;
2472417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    while (vv) {
2473417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (vv == v) {
2474417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    *vvp = vv->next;
2475417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    break;
2476417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2477417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		vvp = &vv->next;
2478417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		vv = *vvp;
2479417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2480417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2481417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->vm) {
2482417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2483417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (v->is3) {
2484417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) v->vm);
2485417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
2486417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_finalize((sqlite_vm *) v->vm, 0);
2487417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2488417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2489417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2490417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) v->vm, 0);
2491417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2492417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2493417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) v->vm);
2494417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2495417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2496417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->vm = 0;
2497417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2498417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(v);
2499417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, obj, F_SQLite_Vm_handle, 0);
2500417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2501417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2502417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!final) {
2503417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "vm already closed");
2504417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2505417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2506417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2507417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2508417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2509417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
2510417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdostmtfinal(JNIEnv *env, jobject obj)
2511417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2512417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
2513417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2514417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v) {
2515417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->h) {
2516417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    handle *h = v->h;
2517417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    hvm *vv, **vvp;
2518417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2519417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vvp = &h->vms;
2520417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vv = *vvp;
2521417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    while (vv) {
2522417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (vv == v) {
2523417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    *vvp = vv->next;
2524417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    break;
2525417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2526417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		vvp = &vv->next;
2527417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		vv = *vvp;
2528417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2529417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2530417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->vm) {
2531417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) v->vm);
2532417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2533417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = 0;
2534417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(v);
2535417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, obj, F_SQLite_Stmt_handle, 0);
2536417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2537417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2538417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2539417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2540417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
2541417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
2542417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdoblobfinal(JNIEnv *env, jobject obj)
2543417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2544417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hbl *bl = gethbl(env, obj);
2545417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2546417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (bl) {
2547417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (bl->h) {
2548417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    handle *h = bl->h;
2549417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    hbl *blc, **blp;
2550417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2551417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    blp = &h->blobs;
2552417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    blc = *blp;
2553417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    while (blc) {
2554417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (blc == bl) {
2555417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    *blp = blc->next;
2556417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    break;
2557417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2558417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		blp = &blc->next;
2559417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		blc = *blp;
2560417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2561417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2562417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (bl->blob) {
2563417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_blob_close(bl->blob);
2564417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2565417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bl->blob = 0;
2566417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(bl);
2567417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, obj, F_SQLite_Blob_handle, 0);
2568417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetIntField(env, obj, F_SQLite_Blob_size, 0);
2569417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2570417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2571417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2572417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2573417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2574417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Vm_stop(JNIEnv *env, jobject obj)
2575417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2576417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2577417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dovmfinal(env, obj, 0);
2578417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2579417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
2580417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2581417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2582417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2583417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
2584417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Vm_finalize(JNIEnv *env, jobject obj)
2585417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2586417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2587417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dovmfinal(env, obj, 1);
2588417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2589417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2590417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2591417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2592417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2593417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesstatic void
2594417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesfree_tab(void *mem)
2595417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2596417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char **p = (char **) mem;
2597417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int i, n;
2598417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2599417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!p) {
2600417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
2601417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2602417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    p -= 1;
2603417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    mem = (void *) p;
2604417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    n = ((int *) p)[0];
2605417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    p += n * 2 + 2 + 1;
2606417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    for (i = 0; i < n; i++) {
2607417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (p[i]) {
2608417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    free(p[i]);
2609417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2610417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2611417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    free(mem);
2612417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2613417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2614417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2615417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2616417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
2617417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Vm_step(JNIEnv *env, jobject obj, jobject cb)
2618417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2619417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2620417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethvm(env, obj);
2621417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2622417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
2623417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
26247a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	int ret, tmp;
26257a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	long ncol = 0;
2626417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2627417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	freemem *freeproc = 0;
2628417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char **blob = 0;
2629417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2630417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char **data = 0, **cols = 0;
2631417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2632417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->h->env = env;
2633417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2634417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->is3) {
2635417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_step((sqlite3_stmt *) v->vm);
26367a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    if (ret == SQLITE_DONE && v->hh.row1) {
26377a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
26387a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		if (ncol > 0) {
26397a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
26407a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    if (data) {
26417a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			data[0] = (const char *) ncol;
26427a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			++data;
26437a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			cols = data + ncol + 1;
26447a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			blob = cols + ncol + 1;
26457a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			freeproc = free_tab;
26467a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    } else {
26477a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			ret = SQLITE_NOMEM;
26487a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    }
26497a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		}
26507a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		if (ret != SQLITE_NOMEM) {
26517a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    int i;
26527a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes
26537a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    for (i = 0; i < ncol; i++) {
26547a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			cols[i] =
26557a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			    sqlite3_column_name((sqlite3_stmt *) v->vm, i);
26567a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    }
26577a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		}
26587a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    } else if (ret == SQLITE_ROW) {
2659417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
2660417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (ncol > 0) {
2661417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
2662417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (data) {
2663417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			data[0] = (const char *) ncol;
2664417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			++data;
2665417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			cols = data + ncol + 1;
2666417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			blob = cols + ncol + 1;
2667417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			freeproc = free_tab;
2668417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    } else {
2669417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			ret = SQLITE_NOMEM;
2670417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
2671417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2672417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (ret != SQLITE_NOMEM) {
2673417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    int i;
2674417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2675417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    for (i = 0; i < ncol; i++) {
2676417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			cols[i] =
2677417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_column_name((sqlite3_stmt *) v->vm, i);
2678417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (sqlite3_column_type((sqlite3_stmt *) v->vm, i)
2679417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    == SQLITE_BLOB) {
2680417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    unsigned char *src = (unsigned char *)
2681417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				sqlite3_column_blob((sqlite3_stmt *) v->vm, i);
2682417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    int n =
2683417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				sqlite3_column_bytes((sqlite3_stmt *) v->vm,
2684417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes						     i);
2685417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2686417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    if (src) {
2687417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				data[i] = malloc(n * 2 + 4);
2688417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				if (data[i]) {
2689417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    int k;
2690417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    char *p = (char *) data[i];
2691417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2692417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    blob[i] = data[i];
2693417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = 'X';
2694417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = '\'';
2695417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    for (k = 0; k < n; k++) {
2696417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					*p++ = xdigits[src[k] >> 4];
2697417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					*p++ = xdigits[src[k] & 0x0F];
2698417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    }
2699417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = '\'';
2700417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = '\0';
2701417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				}
2702417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
2703417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			} else {
2704417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    data[i] = (const char *)
2705417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				sqlite3_column_text((sqlite3_stmt *) v->vm, i);
2706417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
2707417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
2708417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2709417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2710417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
27117a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    tmp = 0;
27127a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    ret = sqlite_step((sqlite_vm *) v->vm, &tmp, &data, &cols);
27137a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    ncol = tmp;
2714417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2715417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2716417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
27177a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	tmp = 0;
27187a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	ret = sqlite_step((sqlite_vm *) v->vm, &tmp, &data, &cols);
27197a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	ncol = tmp;
2720417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2721417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2722417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_step((sqlite3_stmt *) v->vm);
27237a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (ret == SQLITE_DONE && v->hh.row1) {
27247a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
27257a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    if (ncol > 0) {
27267a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
27277a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		if (data) {
27287a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    data[0] = (const char *) ncol;
27297a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    ++data;
27307a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    cols = data + ncol + 1;
27317a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    blob = cols + ncol + 1;
27327a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    freeproc = free_tab;
27337a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		} else {
27347a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    ret = SQLITE_NOMEM;
27357a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		}
27367a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    }
27377a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    if (ret != SQLITE_NOMEM) {
27387a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		int i;
27397a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes
27407a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		for (i = 0; i < ncol; i++) {
27417a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    cols[i] =
27427a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			sqlite3_column_name((sqlite3_stmt *) v->vm, i);
27437a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		}
27447a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    }
27457a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	} else if (ret == SQLITE_ROW) {
2746417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
2747417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ncol > 0) {
2748417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
2749417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (data) {
2750417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    data[0] = (const char *) ncol;
2751417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    ++data;
2752417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    cols = data + ncol + 1;
2753417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    blob = cols + ncol + 1;
2754417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    freeproc = free_tab;
2755417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		} else {
2756417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    ret = SQLITE_NOMEM;
2757417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2758417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2759417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ret != SQLITE_NOMEM) {
2760417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		int i;
2761417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2762417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < ncol; i++) {
2763417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    cols[i] = sqlite3_column_name((sqlite3_stmt *) v->vm, i);
2764417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (sqlite3_column_type((sqlite3_stmt *) v->vm, i)
2765417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			== SQLITE_BLOB) {
2766417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			unsigned char *src = (unsigned char *)
2767417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_column_blob((sqlite3_stmt *) v->vm, i);
2768417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			int n =
2769417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_column_bytes((sqlite3_stmt *) v->vm, i);
2770417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2771417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			if (src) {
2772417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    data[i] = malloc(n * 2 + 4);
2773417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    if (data[i]) {
2774417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				int k;
2775417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				char *p = (char *) data[i];
2776417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2777417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				blob[i] = data[i];
2778417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				*p++ = 'X';
2779417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				*p++ = '\'';
2780417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				for (k = 0; k < n; k++) {
2781417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = xdigits[src[k] >> 4];
2782417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    *p++ = xdigits[src[k] & 0x0F];
2783417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				}
2784417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				*p++ = '\'';
2785417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				*p++ = '\0';
2786417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    }
2787417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			}
2788417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    } else {
2789417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			data[i] = (char *)
2790417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_column_text((sqlite3_stmt *) v->vm, i);
2791417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
2792417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2793417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2794417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2795417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2796417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2797417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret == SQLITE_ROW) {
2798417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.cb = cb;
2799417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.env = env;
2800417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2801417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (v->is3) {
2802417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		v->hh.stmt = (sqlite3_stmt *) v->vm;
2803417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2804417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2805417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2806417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.stmt = (sqlite3_stmt *) v->vm;
2807417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2808417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2809417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    callback((void *) &v->hh, ncol, (char **) data, (char **) cols);
2810417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2811417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (data && freeproc) {
2812417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freeproc((void *) data);
2813417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2814417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2815417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
2816417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
2817417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
2818417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		goto dofin;
2819417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2820417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_TRUE;
2821417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else if (ret == SQLITE_DONE) {
2822417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughesdofin:
28237a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    if (v->hh.row1 && cols) {
28247a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		v->hh.cb = cb;
28257a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		v->hh.env = env;
28267a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_BOTH_SQLITE
28277a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		if (v->is3) {
28287a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    v->hh.stmt = (sqlite3_stmt *) v->vm;
28297a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		}
28307a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#else
28317a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3
28327a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		v->hh.stmt = (sqlite3_stmt *) v->vm;
28337a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
28347a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
28357a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		callback((void *) &v->hh, ncol, (char **) 0, (char **) cols);
28367a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3
28377a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		if (data && freeproc) {
28387a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    freeproc((void *) data);
28397a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		}
28407a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
28417a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		exc = (*env)->ExceptionOccurred(env);
28427a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		if (exc) {
28437a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		    (*env)->DeleteLocalRef(env, exc);
28447a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		}
28457a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    }
2846417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2847417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (v->is3) {
2848417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) v->vm);
2849417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
2850417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_finalize((sqlite_vm *) v->vm, 0);
2851417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2852417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2853417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2854417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) v->vm, 0);
2855417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2856417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2857417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) v->vm);
2858417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2859417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2860417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->vm = 0;
2861417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
2862417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2863417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2864417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->is3) {
2865417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) v->vm);
2866417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2867417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) v->vm, 0);
2868417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2869417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2870417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2871417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_finalize((sqlite_vm *) v->vm, 0);
2872417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2873417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2874417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_finalize((sqlite3_stmt *) v->vm);
2875417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2876417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2877417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	setvmerr(env, obj, ret);
2878417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = 0;
2879417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "error in step");
2880417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_FALSE;
2881417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2882417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "vm already closed");
2883417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2884417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
2885417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2886417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
2887417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
2888417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2889417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
2890417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Vm_compile(JNIEnv *env, jobject obj)
2891417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
2892417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
2893417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethvm(env, obj);
2894417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *svm = 0;
2895417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *err = 0;
28967a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#ifdef HAVE_SQLITE2
28977a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    char *errfr = 0;
28987a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
2899417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    const char *tail;
2900417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
2901417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
2902417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm) {
2903417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2904417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->is3) {
2905417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) v->vm);
2906417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2907417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) v->vm, 0);
2908417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2909417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2910417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2911417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_finalize((sqlite_vm *) v->vm, 0);
2912417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2913417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2914417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_finalize((sqlite3_stmt *) v->vm);
2915417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2916417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2917417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = 0;
2918417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
2919417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->h && v->h->sqlite) {
2920417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!v->tail) {
2921417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
2922417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2923417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->h->env = env;
2924417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
2925417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (v->is3) {
2926417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE_V2
2927417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_prepare_v2((sqlite3 *) v->h->sqlite, v->tail, -1,
2928417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				     (sqlite3_stmt **) &svm, &tail);
2929417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2930417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_prepare((sqlite3 *) v->h->sqlite, v->tail, -1,
2931417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  (sqlite3_stmt **) &svm, &tail);
2932417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2933417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ret != SQLITE_OK) {
2934417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (svm) {
2935417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sqlite3_finalize((sqlite3_stmt *) svm);
2936417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    svm = 0;
2937417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
29387a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		err = (char *) sqlite3_errmsg((sqlite3 *) v->h->sqlite);
2939417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2940417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
2941417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite_compile((sqlite *) v->h->sqlite, v->tail,
29427a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes				 &tail, (sqlite_vm **) &svm, &errfr);
2943417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ret != SQLITE_OK) {
29447a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		err = errfr;
2945417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (svm) {
2946417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    sqlite_finalize((sqlite_vm *) svm, 0);
2947417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    svm = 0;
2948417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
2949417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2950417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2951417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2952417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
2953417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite_compile((sqlite *) v->h->sqlite, v->tail,
29547a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			     &tail, (sqlite_vm **) &svm, &errfr);
2955417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
29567a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    err = errfr;
2957417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (svm) {
2958417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_finalize((sqlite_vm *) svm, 0);
2959417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		svm = 0;
2960417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2961417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2962417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2963417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
2964417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE_V2
2965417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare_v2((sqlite3 *) v->h->sqlite,
2966417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 v->tail, -1, (sqlite3_stmt **) &svm, &tail);
2967417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
2968417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare((sqlite3 *) v->h->sqlite,
2969417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			      v->tail, -1, (sqlite3_stmt **) &svm, &tail);
2970417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2971417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
2972417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (svm) {
2973417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) svm);
2974417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		svm = 0;
2975417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
29767a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    err = (char *) sqlite3_errmsg((sqlite3 *) v->h->sqlite);
2977417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2978417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2979417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2980417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
2981417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setvmerr(env, obj, ret);
2982417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->tail = 0;
2983417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : "error in compile/prepare");
2984417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
29857a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    if (errfr) {
29867a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		sqlite_freemem(errfr);
2987417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
2988417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2989417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
2990417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2991417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
29927a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (errfr) {
29937a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    sqlite_freemem(errfr);
2994417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
2995417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
2996417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!svm) {
2997417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->tail = 0;
2998417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
2999417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3000417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = svm;
3001417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->tail = (char *) tail;
3002417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->hh.row1 = 1;
3003417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_TRUE;
3004417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3005417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "vm already closed");
3006417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3007417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3008417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3009417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
3010417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3011417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3012417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3013417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_vm_1compile(JNIEnv *env, jobject obj, jstring sql,
3014417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 jobject vm)
3015417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3016417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
3017417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
3018417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *svm = 0;
3019417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v;
3020417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *err = 0;
30217a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE2
30227a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    char *errfr = 0;
30237a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
3024417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    const char *tail;
3025417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transstr tr;
3026417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue vv;
3027417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
3028417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jthrowable exc;
3029417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3030417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!h) {
3031417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwclosed(env);
3032417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3033417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3034417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!vm) {
3035417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null vm");
3036417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3037417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3038417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
3039417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null sql");
3040417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3041417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3042417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    trans2iso(env, h->haveutf, h->enc, sql, &tr);
3043417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    exc = (*env)->ExceptionOccurred(env);
3044417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (exc) {
3045417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->DeleteLocalRef(env, exc);
3046417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3047417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3048417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->env = env;
3049417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3050417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h->is3) {
3051417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE_V2
3052417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare_v2((sqlite3 *) h->sqlite, tr.result, -1,
3053417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				 (sqlite3_stmt **) &svm, &tail);
3054417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3055417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare((sqlite3 *) h->sqlite, tr.result, -1,
3056417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			      (sqlite3_stmt **) &svm, &tail);
3057417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3058417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3059417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (svm) {
3060417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) svm);
3061417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		svm = 0;
3062417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
30637a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    err = (char *) sqlite3_errmsg((sqlite3 *) h->sqlite);
3064417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3065417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3066417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite_compile((sqlite *) h->sqlite, tr.result, &tail,
30677a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			     (sqlite_vm **) &svm, &errfr);
3068417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
30697a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    err = errfr;
3070417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (svm) {
3071417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_finalize((sqlite_vm *) svm, 0);
3072417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3073417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3074417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3075417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3076417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
3077417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ret = sqlite_compile((sqlite *) h->sqlite, tr.result, &tail,
30787a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes			 (sqlite_vm **) &svm, &errfr);
3079417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ret != SQLITE_OK) {
30807a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	err = errfr;
3081417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (svm) {
3082417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) svm, 0);
3083417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    svm = 0;
3084417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3085417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3086417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3087417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3088417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE_V2
3089417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ret = sqlite3_prepare_v2((sqlite3 *) h->sqlite, tr.result, -1,
3090417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			     (sqlite3_stmt **) &svm, &tail);
3091417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3092417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ret = sqlite3_prepare((sqlite3 *) h->sqlite, tr.result, -1,
3093417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			  (sqlite3_stmt **) &svm, &tail);
3094417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3095417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ret != SQLITE_OK) {
3096417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (svm) {
3097417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) svm);
3098417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    svm = 0;
3099417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
31007a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	err = (char *) sqlite3_errmsg((sqlite3 *) h->sqlite);
3101417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3102417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3103417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3104417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ret != SQLITE_OK) {
3105417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&tr);
3106417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	setvmerr(env, vm, ret);
3107417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, err ? err : "error in prepare/compile");
3108417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
31097a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (errfr) {
31107a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    sqlite_freemem(errfr);
3111417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3112417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3113417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3114417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3115417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
31167a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (errfr) {
31177a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	sqlite_freemem(errfr);
3118417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3119417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3120417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!svm) {
3121417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&tr);
3122417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3123417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3124417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v = malloc(sizeof (hvm) + strlen(tail) + 1);
3125417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!v) {
3126417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&tr);
3127417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3128417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
3129417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) svm);
3130417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3131417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_finalize((sqlite_vm *) svm, 0);
3132417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3133417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3134417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
3135417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite_finalize((sqlite_vm *) svm, 0);
3136417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3137417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3138417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_finalize((sqlite3_stmt *) svm);
3139417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3140417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3141417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwoom(env, "unable to get SQLite handle");
3142417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3143417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3144417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->next = h->vms;
3145417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->vms = v;
3146417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->vm = svm;
3147417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->h = h;
3148417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->tail = (char *) (v + 1);
3149417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3150417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->is3 = v->hh.is3 = h->is3;
3151417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3152417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    strcpy(v->tail, tail);
3153417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.sqlite = 0;
3154417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.haveutf = h->haveutf;
3155417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.ver = h->ver;
3156417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.bh = v->hh.cb = v->hh.ai = v->hh.tr = v->hh.ph = 0;
3157417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.row1 = 1;
3158417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.enc = h->enc;
3159417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.funcs = 0;
3160417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.vms = 0;
3161417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.env = 0;
3162417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    vv.j = 0;
3163417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    vv.l = (jobject) v;
3164417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->SetLongField(env, vm, F_SQLite_Vm_handle, vv.j);
3165417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3166417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3167417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3168417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3169417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3170417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3171417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_vm_1compile_1args(JNIEnv *env,
3172417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				       jobject obj, jstring sql,
3173417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				       jobject vm, jobjectArray args)
3174417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3175417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_COMPILE
3176417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3177417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
3178417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3179417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3180417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3181417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && !h->is3) {
3182417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "unsupported");
3183417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3184417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3185417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3186417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
3187417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3188417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3189417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3190417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3191417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!h || !h->sqlite) {
3192417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwclosed(env);
3193417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3194417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3195417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!vm) {
3196417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null vm");
3197417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3198417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3199417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
3200417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null sql");
3201417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3202417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3203417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	void *svm = 0;
3204417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	hvm *v;
3205417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jvalue vv;
3206417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
3207417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int rc = SQLITE_ERROR, nargs, i;
3208417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	char *p;
32094538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	const char *str = (*env)->GetStringUTFChars(env, sql, 0);
3210417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char *tail;
3211417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr sqlstr;
3212417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	struct args {
3213417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char *arg;
3214417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jobject obj;
3215417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transstr trans;
3216417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} *argv = 0;
3217417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	char **cargv = 0;
3218417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3219417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	p = (char *) str;
3220417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	nargs = 0;
3221417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	while (*p) {
3222417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (*p == '%') {
3223417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		++p;
3224417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (*p == 'q' || *p == 'Q' || *p == 's') {
3225417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    nargs++;
3226417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (nargs > MAX_PARAMS) {
3227417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			(*env)->ReleaseStringUTFChars(env, sql, str);
3228417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			throwex(env, "too much SQL parameters");
3229417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			return;
3230417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
3231417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		} else if (*p != '%') {
3232417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    (*env)->ReleaseStringUTFChars(env, sql, str);
3233417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    throwex(env, "bad % specification in query");
3234417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return;
3235417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3236417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3237417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ++p;
3238417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3239417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	cargv = malloc((sizeof (*argv) + sizeof (char *)) * MAX_PARAMS);
3240417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!cargv) {
3241417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringUTFChars(env, sql, str);
3242417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to allocate arg vector");
3243417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3244417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3245417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	argv = (struct args *) (cargv + MAX_PARAMS);
3246417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	for (i = 0; i < MAX_PARAMS; i++) {
3247417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    cargv[i] = 0;
3248417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    argv[i].arg = 0;
3249417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    argv[i].obj = 0;
3250417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    argv[i].trans.result = argv[i].trans.tofree = 0;
3251417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3252417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = 0;
3253417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	for (i = 0; i < nargs; i++) {
3254417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    jobject so = (*env)->GetObjectArrayElement(env, args, i);
3255417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3256417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    exc = (*env)->ExceptionOccurred(env);
3257417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (exc) {
3258417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->DeleteLocalRef(env, exc);
3259417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		break;
3260417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3261417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (so) {
3262417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		argv[i].obj = so;
3263417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		argv[i].arg = cargv[i] =
3264417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    trans2iso(env, 1, 0, argv[i].obj, &argv[i].trans);
3265417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3266417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3267417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
3268417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    for (i = 0; i < nargs; i++) {
3269417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (argv[i].obj) {
3270417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    transfree(&argv[i].trans);
3271417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3272417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3273417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    freep((char **) &cargv);
3274417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->ReleaseStringUTFChars(env, sql, str);
3275417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3276417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3277417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->row1 = 1;
3278417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	trans2iso(env, 1, 0, sql, &sqlstr);
3279417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
3280417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!exc) {
3281417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if defined(_WIN32) || !defined(CANT_PASS_VALIST_AS_CHARPTR)
3282417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char *s = sqlite3_vmprintf(sqlstr.result, (char *) cargv);
3283417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3284417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    char *s = sqlite3_mprintf(sqlstr.result,
3285417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[0], cargv[1],
3286417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[2], cargv[3],
3287417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[4], cargv[5],
3288417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[6], cargv[7],
3289417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[8], cargv[9],
3290417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[10], cargv[11],
3291417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[12], cargv[13],
3292417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[14], cargv[15],
3293417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[16], cargv[17],
3294417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[18], cargv[19],
3295417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[20], cargv[21],
3296417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[22], cargv[23],
3297417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[24], cargv[25],
3298417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[26], cargv[27],
3299417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[28], cargv[29],
3300417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      cargv[30], cargv[31]);
3301417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3302417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (!s) {
3303417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = SQLITE_NOMEM;
3304417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
3305417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE_V2
3306417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite3_prepare_v2((sqlite3 *) h->sqlite, s, -1,
3307417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					(sqlite3_stmt **) &svm, &tail);
3308417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3309417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		rc = sqlite3_prepare((sqlite3 *) h->sqlite, s, -1,
3310417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				      (sqlite3_stmt **) &svm, &tail);
3311417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3312417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (rc != SQLITE_OK) {
3313417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (svm) {
3314417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			sqlite3_finalize((sqlite3_stmt *) svm);
3315417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			svm = 0;
3316417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
3317417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3318417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3319417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (rc != SQLITE_OK) {
3320417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_free(s);
3321417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < nargs; i++) {
3322417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (argv[i].obj) {
3323417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			transfree(&argv[i].trans);
3324417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
3325417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3326417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freep((char **) &cargv);
3327417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transfree(&sqlstr);
3328417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->ReleaseStringUTFChars(env, sql, str);
3329417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		setvmerr(env, vm, rc);
3330417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwex(env, "error in prepare");
3331417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
3332417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3333417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v = malloc(sizeof (hvm) + strlen(tail) + 1);
3334417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (!v) {
3335417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_free(s);
3336417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		for (i = 0; i < nargs; i++) {
3337417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    if (argv[i].obj) {
3338417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			transfree(&argv[i].trans);
3339417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    }
3340417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3341417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		freep((char **) &cargv);
3342417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transfree(&sqlstr);
3343417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->ReleaseStringUTFChars(env, sql, str);
3344417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) svm);
3345417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		setvmerr(env, vm, SQLITE_NOMEM);
3346417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		throwoom(env, "unable to get SQLite handle");
3347417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		return;
3348417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3349417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->next = h->vms;
3350417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    h->vms = v;
3351417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->vm = svm;
3352417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->h = h;
3353417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->tail = (char *) (v + 1);
3354417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3355417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->is3 = v->hh.is3 = h->is3;
3356417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3357417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    strcpy(v->tail, tail);
3358417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_free(s);
3359417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.sqlite = 0;
3360417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.haveutf = h->haveutf;
3361417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.ver = h->ver;
3362417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.bh = v->hh.cb = v->hh.ai = v->hh.tr = v->hh.ph = 0;
3363417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.row1 = 1;
3364417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.enc = h->enc;
3365417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.funcs = 0;
3366417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.vms = 0;
3367417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->hh.env = 0;
3368417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vv.j = 0;
3369417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    vv.l = (jobject) v;
3370417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->SetLongField(env, vm, F_SQLite_Vm_handle, vv.j);
3371417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3372417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	for (i = 0; i < nargs; i++) {
3373417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (argv[i].obj) {
3374417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		transfree(&argv[i].trans);
3375417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3376417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3377417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	freep((char **) &cargv);
3378417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&sqlstr);
3379417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->ReleaseStringUTFChars(env, sql, str);
3380417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
3381417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
3382417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3383417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3384417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3385417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3386417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3387417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3388417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3389417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3390417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3391417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_FunctionContext_internal_1init(JNIEnv *env, jclass cls)
3392417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3393417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_FunctionContext_handle =
3394417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "handle", "J");
3395417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3396417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3397417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3398417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1progress_1handler(JNIEnv *env, jobject obj, jint n,
3399417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 jobject ph)
3400417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3401417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
3402417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3403417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
3404417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	/* CHECK THIS */
3405417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE_PROGRESS_HANDLER
3406417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	delglobrefp(env, &h->ph);
3407417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3408417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (h->is3) {
3409417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ph) {
3410417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		globrefset(env, ph, &h->ph);
3411417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_progress_handler((sqlite3 *) h->sqlite,
3412417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 n, progresshandler, h);
3413417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
3414417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_progress_handler((sqlite3 *) h->sqlite,
3415417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					 0, 0, 0);
3416417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3417417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3418417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (ph) {
3419417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		globrefset(env, ph, &h->ph);
3420417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_progress_handler((sqlite *) h->sqlite,
3421417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					n, progresshandler, h);
3422417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
3423417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite_progress_handler((sqlite *) h->sqlite,
3424417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					0, 0, 0);
3425417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3426417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3427417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3428417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
3429417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ph) {
3430417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    globrefset(env, ph, &h->ph);
3431417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_progress_handler((sqlite *) h->sqlite,
3432417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    n, progresshandler, h);
3433417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3434417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite_progress_handler((sqlite *) h->sqlite,
3435417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				    0, 0, 0);
3436417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3437417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3438417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3439417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ph) {
3440417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    globrefset(env, ph, &h->ph);
3441417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_progress_handler((sqlite3 *) h->sqlite,
3442417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				     n, progresshandler, h);
3443417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3444417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_progress_handler((sqlite3 *) h->sqlite,
3445417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				     0, 0, 0);
3446417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3447417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3448417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3449417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3450417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3451417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "unsupported");
3452417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3453417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3454417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3455417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwclosed(env);
3456417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3457417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3458417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
3459417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_is3(JNIEnv *env, jobject obj)
3460417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3461417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3462417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
3463417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3464417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h) {
3465417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return h->is3 ? JNI_TRUE : JNI_FALSE;
3466417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3467417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
3468417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3469417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
3470417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
3471417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3472417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3473417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_TRUE;
3474417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3475417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3476417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3477417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3478417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
3479417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_prepare(JNIEnv *env, jobject obj)
3480417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3481417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3482417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3483417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *svm = 0;
3484417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    char *tail;
3485417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
3486417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3487417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm) {
3488417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_finalize((sqlite3_stmt *) v->vm);
3489417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = 0;
3490417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3491417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->h && v->h->sqlite) {
3492417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!v->tail) {
3493417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
3494417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3495417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->h->env = env;
3496417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE16_V2
3497417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare16_v2((sqlite3 *) v->h->sqlite,
3498417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				   v->tail, -1, (sqlite3_stmt **) &svm,
3499417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				   (const void **) &tail);
3500417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3501417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_prepare16((sqlite3 *) v->h->sqlite,
3502417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				v->tail, -1, (sqlite3_stmt **) &svm,
3503417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				(const void **) &tail);
3504417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3505417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3506417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (svm) {
3507417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		sqlite3_finalize((sqlite3_stmt *) svm);
3508417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		svm = 0;
3509417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3510417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3511417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3512417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const char *err = sqlite3_errmsg(v->h->sqlite);
3513417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3514417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3515417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->tail = 0;
3516417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : "error in compile/prepare");
3517417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
3518417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3519417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!svm) {
3520417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    v->tail = 0;
3521417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_FALSE;
3522417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3523417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = svm;
3524417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->tail = (char *) tail;
3525417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->hh.row1 = 1;
3526417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_TRUE;
3527417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3528417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3529417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3530417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3531417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3532417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
3533417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3534417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3535417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3536417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_stmt_1prepare(JNIEnv *env, jobject obj, jstring sql,
3537417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				   jobject stmt)
3538417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3539417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3
3540417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
3541417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    void *svm = 0;
3542417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v;
3543417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue vv;
3544417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jsize len16;
3545417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    const jchar *sql16, *tail = 0;
3546417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
3547417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3548417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!h) {
3549417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwclosed(env);
3550417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3551417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3552417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!stmt) {
3553417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null stmt");
3554417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3555417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3556417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!sql) {
3557417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null sql");
3558417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3559417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3560417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#ifdef HAVE_BOTH_SQLITE
3561417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!h->is3) {
3562417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "only on SQLite3 database");
3563417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3564417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3565417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3566417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    len16 = (*env)->GetStringLength(env, sql) * sizeof (jchar);
3567417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (len16 < 1) {
35684538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	return;
3569417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3570417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->env = env;
3571417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    sql16 = (*env)->GetStringChars(env, sql, 0);
3572417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3_PREPARE16_V2
3573417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ret = sqlite3_prepare16_v2((sqlite3 *) h->sqlite, sql16, len16,
3574417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			       (sqlite3_stmt **) &svm, (const void **) &tail);
3575417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3576417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ret = sqlite3_prepare16((sqlite3 *) h->sqlite, sql16, len16,
3577417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    (sqlite3_stmt **) &svm, (const void **) &tail);
3578417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3579417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ret != SQLITE_OK) {
3580417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (svm) {
3581417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_finalize((sqlite3_stmt *) svm);
3582417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    svm = 0;
3583417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3584417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3585417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (ret != SQLITE_OK) {
3586417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char *err = sqlite3_errmsg(h->sqlite);
3587417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
35884538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	(*env)->ReleaseStringChars(env, sql, sql16);
3589417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	setstmterr(env, stmt, ret);
3590417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, err ? err : "error in prepare");
3591417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3592417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3593417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!svm) {
35944538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	(*env)->ReleaseStringChars(env, sql, sql16);
3595417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3596417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3597417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    len16 = len16 + sizeof (jchar) - ((char *) tail - (char *) sql16);
35985cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (len16 < sizeof (jchar)) {
35994538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	len16 = sizeof (jchar);
3600417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3601417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v = malloc(sizeof (hvm) + len16);
3602417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!v) {
36034538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	(*env)->ReleaseStringChars(env, sql, sql16);
3604417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_finalize((sqlite3_stmt *) svm);
3605417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwoom(env, "unable to get SQLite handle");
3606417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3607417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3608417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->next = h->vms;
3609417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    h->vms = v;
3610417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->vm = svm;
3611417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->h = h;
3612417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->tail = (char *) (v + 1);
3613417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_BOTH_SQLITE
3614417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->is3 = v->hh.is3 = 1;
3615417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3616417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    memcpy(v->tail, tail, len16);
3617417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    len16 /= sizeof (jchar);
3618417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    ((jchar *) v->tail)[len16 - 1] = 0;
3619417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->ReleaseStringChars(env, sql, sql16);
3620417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.sqlite = 0;
3621417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.haveutf = h->haveutf;
3622417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.ver = h->ver;
3623417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.bh = v->hh.cb = v->hh.ai = v->hh.tr = v->hh.ph = 0;
3624417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.row1 = 1;
3625417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.enc = h->enc;
3626417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.funcs = 0;
3627417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.vms = 0;
3628417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    v->hh.env = 0;
3629417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    vv.j = 0;
3630417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    vv.l = (jobject) v;
3631417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    (*env)->SetLongField(env, stmt, F_SQLite_Stmt_handle, vv.j);
3632417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3633417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3634417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3635417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3636417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3637417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jboolean JNICALL
3638417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_step(JNIEnv *env, jobject obj)
3639417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3640417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3641417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3642417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3643417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3644417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3645417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3646417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_step((sqlite3_stmt *) v->vm);
3647417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret == SQLITE_ROW) {
3648417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return JNI_TRUE;
3649417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3650417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_DONE) {
3651417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const char *err = sqlite3_errmsg(v->h->sqlite);
3652417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3653417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3654417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : "error in step");
3655417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3656417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_FALSE;
3657417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3658417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3659417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3660417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3661417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3662417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_FALSE;
3663417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3664417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3665417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3666417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_close(JNIEnv *env, jobject obj)
3667417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3668417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3669417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3670417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3671417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3672417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3673417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3674417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_finalize((sqlite3_stmt *) v->vm);
3675417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	v->vm = 0;
3676417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3677417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const char *err = sqlite3_errmsg(v->h->sqlite);
3678417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3679417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3680417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : "error in close");
3681417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3682417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
3683417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3684417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3685417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3686417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3687417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3688417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return;
3689417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3690417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3691417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3692417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_reset(JNIEnv *env, jobject obj)
3693417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3694417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3695417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3696417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3697417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3698417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_reset((sqlite3_stmt *) v->vm);
3699417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3700417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "stmt already closed");
3701417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3702417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3703417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3704417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3705417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3706417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3707417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3708417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_clear_1bindings(JNIEnv *env, jobject obj)
3709417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3710417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_CLEAR_BINDINGS
3711417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3712417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3713417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3714417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	sqlite3_clear_bindings((sqlite3_stmt *) v->vm);
3715417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
3716417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "stmt already closed");
3717417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3718417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3719417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3720417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3721417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3722417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3723417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3724417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__II(JNIEnv *env, jobject obj, jint pos, jint val)
3725417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3726417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3727417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3728417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3729417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3730417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3731417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3732417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3733417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3734417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3735417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3736417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3737417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_bind_int((sqlite3_stmt *) v->vm, pos, val);
3738417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3739417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3740417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3741417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3742417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
37434538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	throwex(env, "stmt already closed");
3744417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3745417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3746417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3747417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3748417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3749417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3750417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3751417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__IJ(JNIEnv *env, jobject obj, jint pos, jlong val)
3752417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3753417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3754417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3755417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3756417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3757417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3758417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3759417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3760417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3761417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3762417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3763417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3764417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_bind_int64((sqlite3_stmt *) v->vm, pos, val);
3765417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3766417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3767417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3768417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3769417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
37704538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	throwex(env, "stmt already closed");
3771417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3772417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3773417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3774417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3775417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3776417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3777417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3778417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__ID(JNIEnv *env, jobject obj, jint pos, jdouble val)
3779417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3780417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3781417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3782417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3783417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3784417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3785417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3786417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3787417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3788417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3789417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3790417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3791417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_bind_double((sqlite3_stmt *) v->vm, pos, val);
3792417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3793417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3794417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3795417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3796417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
37974538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	throwex(env, "stmt already closed");
3798417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3799417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3800417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3801417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3802417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3803417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3804417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3805417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__I_3B(JNIEnv *env, jobject obj, jint pos, jbyteArray val)
3806417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3807417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3808417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3809417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3810417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3811417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3812417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3813417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jint len;
3814417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	char *data = 0;
3815417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3816417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3817417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3818417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3819417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3820417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (val) {
3821417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    len = (*env)->GetArrayLength(env, val);
3822417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (len > 0) {
38234538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		data = sqlite3_malloc(len);
3824417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (!data) {
3825417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    throwoom(env, "unable to get blob parameter");
3826417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return;
3827417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
3828417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		(*env)->GetByteArrayRegion(env, val, 0, len, (jbyte *) data);
3829417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ret = sqlite3_bind_blob((sqlite3_stmt *) v->vm,
3830417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					pos, data, len, sqlite3_free);
3831417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
3832417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ret = sqlite3_bind_blob((sqlite3_stmt *) v->vm,
3833417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					pos, "", 0, SQLITE_STATIC);
3834417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3835417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3836417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_bind_null((sqlite3_stmt *) v->vm, pos);
3837417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3838417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3839417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (data) {
38404538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		sqlite3_free(data);
3841417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3842417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3843417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3844417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3845417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
38464538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	throwex(env, "stmt already closed");
3847417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3848417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3849417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3850417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3851417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3852417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3853417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3854417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__ILjava_lang_String_2(JNIEnv *env, jobject obj,
3855417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					    jint pos, jstring val)
3856417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3857417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3858417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3859417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3860417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3861417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3862417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
38634538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	jsize len, count;
3864417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	char *data = 0;
3865417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3866417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3867417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3868417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3869417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3870417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (val) {
38714538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    count = (*env)->GetStringLength(env, val);
38724538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	    len = count * sizeof (jchar);
3873417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (len > 0) {
38744538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe#ifndef JNI_VERSION_1_2
38754538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		const jchar *ch;
38764538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe#endif
3877417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		data = sqlite3_malloc(len);
3878417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		if (!data) {
3879417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    throwoom(env, "unable to get blob parameter");
3880417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		    return;
3881417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		}
38824538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe#ifndef JNI_VERSION_1_2
38834538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		ch = (*env)->GetStringChars(env, val, 0);
38844538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		memcpy(data, ch, len);
38854538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		(*env)->ReleaseStringChars(env, val, ch);
38864538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe#else
38874538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		(*env)->GetStringRegion(env, val, 0, count, (jchar *) data);
38884538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe#endif
3889417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		ret = sqlite3_bind_text16((sqlite3_stmt *) v->vm,
3890417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  pos, data, len, sqlite3_free);
3891417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    } else {
38924538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		ret = sqlite3_bind_text16((sqlite3_stmt *) v->vm, pos, "", 0,
3893417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					  SQLITE_STATIC);
3894417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3895417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
3896417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    ret = sqlite3_bind_null((sqlite3_stmt *) v->vm, pos);
3897417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3898417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3899417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    if (data) {
39004538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe		sqlite3_free(data);
3901417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    }
3902417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3903417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3904417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3905417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
39064538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	throwex(env, "stmt already closed");
3907417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3908417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3909417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3910417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3911417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3912417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3913417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3914417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind__I(JNIEnv *env, jobject obj, jint pos)
3915417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3916417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3917417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3918417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3919417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3920417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3921417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3922417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3923417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3924417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3925417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3926417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3927417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_bind_null((sqlite3_stmt *) v->vm, pos);
3928417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3929417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3930417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3931417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3932417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
39334538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	throwex(env, "stmt already closed");
3934417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3935417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3936417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3937417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3938417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3939417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3940417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
3941417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind_1zeroblob(JNIEnv *env, jobject obj, jint pos, jint len)
3942417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3943417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BIND_ZEROBLOB
3944417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3945417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3946417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3947417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3948417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
3949417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3950417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3951417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3952417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
3953417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3954417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_bind_zeroblob((sqlite3_stmt *) v->vm, pos, len);
3955417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
3956417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    setstmterr(env, obj, ret);
3957417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "bind failed");
3958417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3959417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
39604538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	throwex(env, "stmt already closed");
3961417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3962417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3963417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3964417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3965417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3966417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3967417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
3968417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind_1parameter_1count(JNIEnv *env, jobject obj)
3969417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3970417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
3971417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3972417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3973417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3974417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3975417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
3976417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
3977417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
3978417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
3979417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
3980417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
3981417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
3982417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3983417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
3984417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind_1parameter_1name(JNIEnv *env, jobject obj, jint pos)
3985417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
3986417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BIND_PARAMETER_NAME
3987417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
3988417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3989417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
3990417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int npar = sqlite3_bind_parameter_count((sqlite3_stmt *) v->vm);
3991417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char *name;
3992417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
3993417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (pos < 1 || pos > npar) {
3994417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "parameter position out of bounds");
3995417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
3996417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
3997417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	name = sqlite3_bind_parameter_name((sqlite3_stmt *) v->vm, pos);
3998417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (name) {
3999417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewStringUTF(env, name);
4000417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4001417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
40024538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	throwex(env, "stmt already closed");
4003417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4004417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4005417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4006417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4007417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4008417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4009417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4010417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
4011417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_bind_1parameter_1index(JNIEnv *env, jobject obj,
4012417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes					jstring name)
4013417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4014417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BIND_PARAMETER_INDEX
4015417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4016417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4017417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
40184538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	int pos;
4019417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const char *n;
4020417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transstr namestr;
4021417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
4022417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4023417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	n = trans2iso(env, 1, 0, name, &namestr);
4024417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
4025417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
4026417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
4027417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return -1;
4028417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
40294538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	pos = sqlite3_bind_parameter_index((sqlite3_stmt *) v->vm, n);
4030417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&namestr);
4031417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return pos;
4032417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    } else {
40334538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	throwex(env, "stmt already closed");
4034417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4035417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4036417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4037417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4038417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return -1;
4039417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4040417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4041417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
4042417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1int(JNIEnv *env, jobject obj, jint col)
4043417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4044417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4045417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4046417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4047417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4048417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
4049417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4050417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4051417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4052417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4053417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4054417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_column_int((sqlite3_stmt *) v->vm, col);
4055417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4056417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4057417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4058417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4059417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4060417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4061417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4062417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4063417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jlong JNICALL
4064417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1long(JNIEnv *env, jobject obj, jint col)
4065417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4066417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4067417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4068417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4069417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4070417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
4071417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4072417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4073417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4074417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4075417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4076417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_column_int64((sqlite3_stmt *) v->vm, col);
4077417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4078417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4079417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4080417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4081417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4082417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4083417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4084417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4085417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jdouble JNICALL
4086417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1double(JNIEnv *env, jobject obj, jint col)
4087417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4088417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4089417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4090417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4091417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4092417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
4093417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4094417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4095417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4096417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4097417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4098417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_column_double((sqlite3_stmt *) v->vm, col);
4099417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4100417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4101417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4102417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4103417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4104417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4105417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4106417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4107417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jbyteArray JNICALL
4108417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1bytes(JNIEnv *env, jobject obj, jint col)
4109417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4110417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4111417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4112417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4113417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4114417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
4115417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int nbytes;
4116417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const jbyte *data;
4117417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jbyteArray b = 0;
4118417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4119417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4120417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4121417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4122417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4123417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	data = sqlite3_column_blob((sqlite3_stmt *) v->vm, col);
4124417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (data) {
4125417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    nbytes = sqlite3_column_bytes((sqlite3_stmt *) v->vm, col);
4126417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
4127417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4128417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4129417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	b = (*env)->NewByteArray(env, nbytes);
4130417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!b) {
4131417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to get blob column data");
4132417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4133417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4134417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetByteArrayRegion(env, b, 0, nbytes, data);
4135417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return b;
4136417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4137417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4138417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4139417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4140417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4141417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4142417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4143417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4144417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
4145417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1string(JNIEnv *env, jobject obj, jint col)
4146417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4147417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4148417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4149417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4150417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4151417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
4152417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int nbytes;
4153417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	const jchar *data;
4154417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jstring b = 0;
4155417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4156417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4157417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4158417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4159417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4160417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	data = sqlite3_column_text16((sqlite3_stmt *) v->vm, col);
4161417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (data) {
4162417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    nbytes = sqlite3_column_bytes16((sqlite3_stmt *) v->vm, col);
4163417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	} else {
4164417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4165417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4166417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	nbytes /= sizeof (jchar);
4167417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	b = (*env)->NewString(env, data, nbytes);
4168417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!b) {
4169417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to get string column data");
4170417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4171417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4172417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return b;
4173417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4174417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4175417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4176417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4177417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4178417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4179417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4180417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4181417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
4182417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1type(JNIEnv *env, jobject obj, jint col)
4183417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4184417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4185417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4186417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4187417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4188417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
4189417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4190417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4191417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4192417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4193417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4194417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_column_type((sqlite3_stmt *) v->vm, col);
4195417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4196417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4197417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4198417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4199417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4200417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4201417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4202417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4203417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
4204417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1count(JNIEnv *env, jobject obj)
4205417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4206417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4207417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4208417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4209417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4210417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return sqlite3_column_count((sqlite3_stmt *) v->vm);
4211417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4212417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4213417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4214417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4215417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4216417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4217417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4218417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4219417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
4220417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1table_1name(JNIEnv *env, jobject obj, jint col)
4221417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4222417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_COLUMN_TABLE_NAME16
4223417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4224417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4225417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4226417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
42274538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	const jchar *str;
4228417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4229417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4230417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4231417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4232417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4233417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	str = sqlite3_column_table_name16((sqlite3_stmt *) v->vm, col);
4234417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (str) {
4235417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewString(env, str, jstrlen(str));
4236417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4237417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return 0;
4238417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4239417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4240417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4241417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4242417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4243417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4244417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4245417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4246417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
4247417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1database_1name(JNIEnv *env, jobject obj, jint col)
4248417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4249417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_COLUMN_DATABASE_NAME16
4250417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4251417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4252417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4253417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
42544538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	const jchar *str;
4255417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4256417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4257417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4258417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4259417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4260417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	str = sqlite3_column_database_name16((sqlite3_stmt *) v->vm, col);
4261417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (str) {
4262417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewString(env, str, jstrlen(str));
4263417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4264417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return 0;
4265417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4266417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4267417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4268417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4269417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4270417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4271417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4272417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4273417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
4274417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1decltype(JNIEnv *env, jobject obj, jint col)
4275417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4276417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4277417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4278417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4279417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4280417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
42814538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	const jchar *str;
4282417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4283417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4284417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4285417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4286417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4287417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	str = sqlite3_column_decltype16((sqlite3_stmt *) v->vm, col);
4288417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (str) {
4289417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewString(env, str, jstrlen(str));
4290417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4291417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return 0;
4292417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4293417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4294417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4295417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4296417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4297417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4298417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4299417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4300417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jstring JNICALL
4301417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_column_1origin_1name(JNIEnv *env, jobject obj, jint col)
4302417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4303417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_COLUMN_ORIGIN_NAME16
4304417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hvm *v = gethstmt(env, obj);
4305417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4306417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (v && v->vm && v->h) {
4307417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
43084538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	const jchar *str;
4309417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4310417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (col < 0 || col >= ncol) {
4311417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, "column out of bounds");
4312417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4313417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4314417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	str = sqlite3_column_origin_name16((sqlite3_stmt *) v->vm, col);
4315417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (str) {
4316417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return (*env)->NewString(env, str, jstrlen(str));
4317417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4318417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return 0;
4319417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4320417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "stmt already closed");
4321417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4322417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4323417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4324417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4325417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4326417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
43275cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJNIEXPORT jint JNICALL
43285cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJava_SQLite_Stmt_status(JNIEnv *env, jobject obj, jint op, jboolean flg)
43295cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
43305cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jint count = 0;
43315cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_STMT_STATUS
43325cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    hvm *v = gethstmt(env, obj);
43335cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
43345cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (v && v->vm && v->h) {
43355cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	count = sqlite3_stmt_status((sqlite3_stmt *) v->vm, op,
43365cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes				    flg == JNI_TRUE);
43375cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
43385cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
43395cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    return count;
43405cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
43415cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
4342417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4343417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_finalize(JNIEnv *env, jobject obj)
4344417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4345417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE_COMPILE
4346417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    dostmtfinal(env, obj);
4347417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4348417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4349417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4350417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4351417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database__1open_1blob(JNIEnv *env, jobject obj,
4352417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  jstring dbname, jstring table,
4353417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  jstring column, jlong row,
4354417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				  jboolean rw, jobject blobj)
4355417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4356417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
4357417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    handle *h = gethandle(env, obj);
4358417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hbl *bl;
4359417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jthrowable exc;
4360417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    transstr dbn, tbl, col;
4361417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    sqlite3_blob *blob;
4362417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jvalue vv;
4363417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    int ret;
4364417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4365417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!blobj) {
4366417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	throwex(env, "null blob");
4367417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
4368417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
43695cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_BOTH_SQLITE
43705cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (!h->is3) {
43715cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	throwex(env, "not a SQLite 3 database");
43725cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	return;
43735cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
43745cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
4375417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (h && h->sqlite) {
43764538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	trans2iso(env, h->haveutf, h->enc, dbname, &dbn);
4377417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
4378417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
4379417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
4380417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
4381417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
43824538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	trans2iso(env, h->haveutf, h->enc, table, &tbl);
4383417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
4384417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
4385417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&dbn);
4386417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
4387417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
4388417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
43894538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	trans2iso(env, h->haveutf, h->enc, column, &col);
4390417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
4391417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
4392417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&tbl);
4393417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    transfree(&dbn);
4394417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    (*env)->DeleteLocalRef(env, exc);
4395417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
4396417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4397417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_blob_open(h->sqlite,
4398417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				dbn.result, tbl.result, col.result,
4399417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes				row, rw, &blob);
4400417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&col);
4401417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&tbl);
4402417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	transfree(&dbn);
4403417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
4404417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    const char *err = sqlite3_errmsg(h->sqlite);
4405417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4406417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    seterr(env, obj, ret);
4407417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwex(env, err ? err : "error in blob open");
4408417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
4409417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4410417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bl = malloc(sizeof (hbl));
4411417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!bl) {
4412417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    sqlite3_blob_close(blob);
4413417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "unable to get SQLite blob handle");
4414417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return;
4415417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4416417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bl->next = h->blobs;
4417417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	h->blobs = bl;
4418417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bl->blob = blob;
4419417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	bl->h = h;
4420417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	vv.j = 0;
4421417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	vv.l = (jobject) bl;
4422417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetLongField(env, blobj, F_SQLite_Blob_handle, vv.j);
4423417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetIntField(env, blobj, F_SQLite_Blob_size,
4424417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    sqlite3_blob_bytes(blob));
4425417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
4426417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4427417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "not an open database");
4428417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4429417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4430417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4431417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4432417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4433417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
4434417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Blob_write(JNIEnv *env , jobject obj, jbyteArray b, jint off,
4435417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		       jint pos, jint len)
4436417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4437417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
4438417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hbl *bl = gethbl(env, obj);
4439417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4440417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (bl && bl->h && bl->blob) {
44414538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	jbyte *buf;
4442417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
4443417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
4444417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4445417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (len <= 0) {
4446417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4447417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4448417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	buf = malloc(len);
4449417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!buf) {
4450417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "out of buffer space for blob");
4451417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4452417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4453417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetByteArrayRegion(env, b, off, len, buf);
4454417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
4455417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
4456417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    free(buf);
4457417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4458417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4459417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_blob_write(bl->blob, buf, len, pos);
4460417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(buf);
4461417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
4462417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwioex(env, "blob write error");
4463417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4464417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4465417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return len;
4466417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4467417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "blob already closed");
4468417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4469417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4470417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4471417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4472417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4473417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4474417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
4475417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Blob_read(JNIEnv *env , jobject obj, jbyteArray b, jint off,
4476417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes		      jint pos, jint len)
4477417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4478417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
4479417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    hbl *bl = gethbl(env, obj);
4480417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4481417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (bl && bl->h && bl->blob) {
44824538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	jbyte *buf;
4483417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	jthrowable exc;
4484417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	int ret;
4485417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4486417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (len <= 0) {
4487417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4488417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4489417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	buf = malloc(len);
4490417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (!buf) {
4491417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwoom(env, "out of buffer space for blob");
4492417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4493417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4494417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	ret = sqlite3_blob_read(bl->blob, buf, len, pos);
4495417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (ret != SQLITE_OK) {
4496417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    free(buf);
4497417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    throwioex(env, "blob read error");
4498417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4499417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4500417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->SetByteArrayRegion(env, b, off, len, buf);
4501417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	free(buf);
4502417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	exc = (*env)->ExceptionOccurred(env);
4503417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	if (exc) {
4504417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	    return 0;
4505417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	}
4506417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return len;
4507417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
4508417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "blob already closed");
4509417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#else
4510417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    throwex(env, "unsupported");
4511417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4512417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return 0;
4513417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4514417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4515417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4516417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Blob_close(JNIEnv *env, jobject obj)
4517417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4518417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
4519417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    doblobfinal(env, obj);
4520417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4521417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4522417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4523417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4524417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Blob_finalize(JNIEnv *env, jobject obj)
4525417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4526417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_INCRBLOBIO
4527417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    doblobfinal(env, obj);
4528417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
4529417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4530417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
45317a647e8547e57ca573541be55b3728ef7ce376feElliott HughesJNIEXPORT void
45327a647e8547e57ca573541be55b3728ef7ce376feElliott HughesJNICALL Java_SQLite_Database__1key(JNIEnv *env, jobject obj, jbyteArray key)
45337a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes{
45347a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    jsize len;
45357a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    jbyte *data;
45367a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_KEY
45377a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    handle *h = gethandle(env, obj);
45387a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
45397a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes
45407a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    len = (*env)->GetArrayLength(env, key);
45417a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    data = (*env)->GetByteArrayElements(env, key, 0);
45427a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (len == 0) {
45437a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	data = 0;
45447a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    }
45457a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (!data) {
45467a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	len = 0;
45477a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    }
45487a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_KEY
45497a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (h && h->sqlite) {
45507a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_BOTH_SQLITE
45517a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (!h->is3) {
45527a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    if (data) {
45537a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		memset(data, 0, len);
45547a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    }
45557a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    throwex(env, "unsupported");
45567a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	}
45577a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
45587a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	sqlite3_key((sqlite3 *) h->sqlite, data, len);
45597a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (data) {
45607a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    memset(data, 0, len);
45617a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	}
45627a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    } else {
45637a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (data) {
45647a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    memset(data, 0, len);
45657a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	}
45667a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	throwclosed(env);
45677a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    }
45687a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#else
45697a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (data) {
45707a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	memset(data, 0, len);
45717a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    }
45727a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    /* no error */
45737a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
45747a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes}
45757a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes
45767a647e8547e57ca573541be55b3728ef7ce376feElliott HughesJNIEXPORT void JNICALL
45777a647e8547e57ca573541be55b3728ef7ce376feElliott HughesJava_SQLite_Database__1rekey(JNIEnv *env, jobject obj, jbyteArray key)
45787a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes{
45797a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    jsize len;
45807a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    jbyte *data;
45817a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_KEY
45827a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    handle *h = gethandle(env, obj);
45837a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
45847a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes
45857a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    len = (*env)->GetArrayLength(env, key);
45867a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    data = (*env)->GetByteArrayElements(env, key, 0);
45877a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (len == 0) {
45887a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	data = 0;
45897a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    }
45907a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (!data) {
45917a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	len = 0;
45927a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    }
45937a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_KEY
45947a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (h && h->sqlite) {
45957a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_BOTH_SQLITE
45967a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (!h->is3) {
45977a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    if (data) {
45987a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes		memset(data, 0, len);
45997a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    }
46007a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    throwex(env, "unsupported");
46017a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	}
46027a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
46037a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	sqlite3_rekey((sqlite3 *) h->sqlite, data, len);
46047a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (data) {
46057a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    memset(data, 0, len);
46067a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	}
46077a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    } else {
46087a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	if (data) {
46097a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	    memset(data, 0, len);
46107a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	}
46117a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	throwclosed(env);
46127a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    }
46137a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#else
46147a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    if (data) {
46157a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	memset(data, 0, len);
46167a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    }
46177a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    throwex(env, "unsupported");
46187a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
46197a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes}
46207a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes
46217a647e8547e57ca573541be55b3728ef7ce376feElliott HughesJNIEXPORT jboolean JNICALL
46227a647e8547e57ca573541be55b3728ef7ce376feElliott HughesJava_SQLite_Database__1enable_1shared_1cache(JNIEnv *env, jclass cls,
46237a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes					     jboolean onoff)
46247a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes{
46257a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if HAVE_SQLITE3_SHARED_CACHE
46267a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    return (sqlite3_enable_shared_cache(onoff == JNI_TRUE) == SQLITE_OK) ?
46277a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	   JNI_TRUE : JNI_FALSE;
46287a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#else
46297a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    return JNI_FALSE;
46307a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
46317a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes}
46327a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes
46335cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
46345cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJNIEXPORT void JNICALL
46355cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJava_SQLite_Database__1backup(JNIEnv *env, jclass cls, jobject bkupj,
46365cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes			      jobject dest, jstring destName,
46375cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes			      jobject src, jstring srcName)
46385cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
46395cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
46405cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    handle *hsrc = gethandle(env, src);
46415cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    handle *hdest = gethandle(env, dest);
46425cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    hbk *bk;
46435cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jthrowable exc;
46445cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    transstr dbns, dbnd;
46455cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    sqlite3_backup *bkup;
46465cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jvalue vv;
46475cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
46485cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (!bkupj) {
46495cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	throwex(env, "null backup");
46505cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	return;
46515cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
46525cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (!hsrc) {
46535cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	throwex(env, "no source database");
46545cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	return;
46555cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
46565cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (!hdest) {
46575cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	throwex(env, "no destination database");
46585cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	return;
46595cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
46605cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_BOTH_SQLITE
46615cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (!hsrc->is3 || !hdest->is3) {
46625cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	throwex(env, "not a SQLite 3 database");
46635cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	return;
46645cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
46655cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
46665cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (!hsrc->sqlite) {
46675cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	throwex(env, "source database not open");
46685cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	return;
46695cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
46705cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (!hdest->sqlite) {
46715cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	throwex(env, "destination database not open");
46725cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	return;
46735cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
46745cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    trans2iso(env, hdest->haveutf, hdest->enc, destName, &dbnd);
46755cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    exc = (*env)->ExceptionOccurred(env);
46765cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (exc) {
46775cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	(*env)->DeleteLocalRef(env, exc);
46785cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	return;
46795cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
46805cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    trans2iso(env, hsrc->haveutf, hsrc->enc, srcName, &dbns);
46815cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    exc = (*env)->ExceptionOccurred(env);
46825cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (exc) {
46835cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	transfree(&dbnd);
46845cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	(*env)->DeleteLocalRef(env, exc);
46855cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	return;
46865cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
46875cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    bkup = sqlite3_backup_init((sqlite3 *) hdest->sqlite, dbnd.result,
46885cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes			       (sqlite3 *) hsrc->sqlite, dbns.result);
46895cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    transfree(&dbnd);
46905cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    transfree(&dbns);
46915cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (!bkup) {
46925cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	const char *err = sqlite3_errmsg((sqlite3 *) hdest->sqlite);
46935cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
46945cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	seterr(env, src, sqlite3_errcode((sqlite3 *) hdest->sqlite));
46955cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	throwex(env, err ? err : "error in backup init");
46965cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	return;
46975cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
46985cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    bk = malloc(sizeof (hbk));
46995cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (!bk) {
47005cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	sqlite3_backup_finish(bkup);
47015cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	throwoom(env, "unable to get SQLite backup handle");
47025cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	return;
47035cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
47045cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    bk->next = hsrc->backups;
47055cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    hsrc->backups = bk;
47065cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    bk->bkup = bkup;
47075cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    bk->h = hsrc;
47085cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    vv.j = 0;
47095cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    vv.l = (jobject) bk;
47105cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    (*env)->SetLongField(env, bkupj, F_SQLite_Backup_handle, vv.j);
47115cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    return;
47125cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#else
47135cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    throwex(env, "unsupported");
47145cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
47155cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
47165cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
47175cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJNIEXPORT void JNICALL
47185cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJava_SQLite_Backup__1finalize(JNIEnv *env, jobject obj)
47195cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
47205cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
47215cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    hbk *bk = gethbk(env, obj);
47225cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    int ret = SQLITE_OK;
47235cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    char *err = 0;
47245cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
47255cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (bk) {
47265cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	if (bk->h) {
47275cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    handle *h = bk->h;
47285cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    hbk *bkc, **bkp;
47295cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
47305cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    bkp = &h->backups;
47315cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    bkc = *bkp;
47325cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    while (bkc) {
47335cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		if (bkc == bk) {
47345cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		    *bkp = bkc->next;
47355cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		    break;
47365cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		}
47375cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		bkp = &bkc->next;
47385cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		bkc = *bkp;
47395cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    }
47405cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	}
47415cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	if (bk->bkup) {
47425cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    ret = sqlite3_backup_finish(bk->bkup);
47435cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    if (ret != SQLITE_OK && bk->h) {
47445cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		err = (char *) sqlite3_errmsg((sqlite3 *) bk->h->sqlite);
47455cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    }
47465cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	}
47475cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	bk->bkup = 0;
47485cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	free(bk);
47495cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	(*env)->SetLongField(env, obj, F_SQLite_Backup_handle, 0);
47505cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	if (ret != SQLITE_OK) {
47515cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    throwex(env, err ? err : "unknown error");
47525cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	}
47535cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
47545cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
47555cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
47565cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
47575cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJNIEXPORT jboolean JNICALL
47585cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJava_SQLite_Backup__1step(JNIEnv *env, jobject obj, jint n)
47595cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
47605cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jboolean result = JNI_TRUE;
47615cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
47625cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    hbk *bk = gethbk(env, obj);
47635cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    int ret;
47645cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
47655cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (bk) {
47665cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	if (bk->bkup) {
47675cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    ret = sqlite3_backup_step(bk->bkup, (int) n);
47685cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    switch (ret) {
47695cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    case SQLITE_DONE:
47705cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		break;
47715cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    case SQLITE_LOCKED:
47725cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    case SQLITE_BUSY:
47735cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    case SQLITE_OK:
47745cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		result = JNI_FALSE;
47755cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		break;
47765cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    default:
47775cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		result = JNI_FALSE;
47785cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		throwex(env, "backup step failed");
47795cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		break;
47805cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    }
47815cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	}
47825cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    } else {
47835cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	throwex(env, "stale backup object");
47845cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
47855cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#else
47865cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    throwex(env, "unsupported");
47875cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
47885cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    return result;
47895cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
47905cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
47915cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJNIEXPORT jint JNICALL
47925cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJava_SQLite_Backup__1remaining(JNIEnv *env, jobject obj)
47935cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
47945cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jint result = 0;
47955cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
47965cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    hbk *bk = gethbk(env, obj);
47975cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
47985cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (bk) {
47995cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	if (bk->bkup) {
48005cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    result = sqlite3_backup_remaining(bk->bkup);
48015cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	}
48025cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
48035cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#else
48045cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    throwex(env, "unsupported");
48055cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
48065cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    return result;
48075cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
48085cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
48095cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJNIEXPORT jint JNICALL
48105cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJava_SQLite_Backup__1pagecount(JNIEnv *env, jobject obj)
48115cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
48125cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jint result = 0;
48135cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3 && HAVE_SQLITE3_BACKUPAPI
48145cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    hbk *bk = gethbk(env, obj);
48155cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
48165cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (bk) {
48175cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	if (bk->bkup) {
48185cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    result = sqlite3_backup_pagecount(bk->bkup);
48195cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	}
48205cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
48215cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#else
48225cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    throwex(env, "unsupported");
48235cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
48245cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    return result;
48255cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
48265cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
48275cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3_PROFILE
48285cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughesstatic void
48295cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughesdoprofile(void *arg, const char *msg, sqlite_uint64 est)
48305cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
48315cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    handle *h = (handle *) arg;
48325cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    JNIEnv *env = h->env;
48335cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
48345cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (env && h->pr && msg) {
48355cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	jthrowable exc;
48365cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	jclass cls = (*env)->GetObjectClass(env, h->pr);
48375cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	jmethodID mid;
48385cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
48395cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	mid = (*env)->GetMethodID(env, cls, "profile",
48405cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes				  "(Ljava/lang/String;J)V");
48415cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	if (mid) {
48425cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    transstr tr;
48435cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if _MSC_VER && (_MSC_VER < 1300)
48445cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    jlong ms = est / (3600i64 * 24i64 * 1000i64);
48455cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#else
48465cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    jlong ms = est / (3600LL * 24LL * 1000LL);
48475cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
48485cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
48495cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    trans2utf(env, h->haveutf, h->enc, msg, &tr);
48505cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    exc = (*env)->ExceptionOccurred(env);
48515cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    if (exc) {
48525cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		(*env)->DeleteLocalRef(env, exc);
48535cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		(*env)->ExceptionClear(env);
48545cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes		return;
48555cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    }
48565cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    (*env)->CallVoidMethod(env, h->pr, mid, tr.jstr, ms);
48575cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    (*env)->ExceptionClear(env);
48585cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    (*env)->DeleteLocalRef(env, tr.jstr);
48595cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    return;
48605cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	}
48615cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
48625cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    return;
48635cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
48645cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
48655cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
48665cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJNIEXPORT void JNICALL
48675cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJava_SQLite_Database__1profile(JNIEnv *env, jobject obj, jobject tr)
48685cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
48695cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3_PROFILE
48705cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    handle *h = gethandle(env, obj);
48715cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
48725cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (h && h->sqlite) {
48735cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	delglobrefp(env, &h->pr);
48745cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	globrefset(env, tr, &h->pr);
48755cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_BOTH_SQLITE
48765cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	if (h->is3) {
48775cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    sqlite3_profile((sqlite3 *) h->sqlite, h->pr ? doprofile : 0, h);
48785cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	}
48795cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#else
48805cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3
48815cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	sqlite3_profile((sqlite3 *) h->sqlite, h->pr ? doprofile : 0, h);
48825cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
48835cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
48845cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
48855cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
48865cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
48875cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
48885cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJNIEXPORT jint JNICALL
48895cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJava_SQLite_Database__1status(JNIEnv *env, jclass cls, jint op,
48905cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes			      jintArray info, jboolean flag)
48915cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
48925cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jint ret = SQLITE_ERROR;
48935cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3_STATUS
48945cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    int data[2] = { 0, 0 };
48955cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jint jdata[2];
48965cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3
48975cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    ret = sqlite3_status(op, &data[0], &data[2], flag);
48985cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (ret == SQLITE_OK) {
48995cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	jdata[0] = data[0];
49005cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	jdata[1] = data[1];
49015cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	(*env)->SetIntArrayRegion(env, info, 0, 2, jdata);
49025cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
49035cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
49045cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
49055cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    return ret;
49065cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
49075cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
49085cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJNIEXPORT jint JNICALL
49095cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJava_SQLite_Database__1db_1status(JNIEnv *env, jobject obj, jint op,
49105cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes				  jintArray info, jboolean flag)
49115cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
49125cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jint ret = SQLITE_ERROR;
49135cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3_DB_STATUS
49145cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    handle *h = gethandle(env, obj);
49155cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    int data[2] = { 0, 0 };
49165cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    jint jdata[2];
49175cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
49185cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    if (h && h->sqlite) {
49195cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_BOTH_SQLITE
49205cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	if (h->is3) {
49215cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    ret = sqlite3_db_status((sqlite3 *) h->sqlite, op, &data[0],
49225cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes				    &data[1], flag);
49235cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	}
49245cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#else
49255cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#if HAVE_SQLITE3
49265cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	ret = sqlite3_db_status((sqlite3 *) h->sqlite, op, &data[0],
49275cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes				&data[2], flag);
49285cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
49295cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
49305cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	if (ret == SQLITE_OK) {
49315cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    jdata[0] = data[0];
49325cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    jdata[1] = data[1];
49335cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	    (*env)->SetIntArrayRegion(env, info, 0, 2, jdata);
49345cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	}
49355cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    }
49365cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes#endif
49375cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    return ret;
49385cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
49395cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
4940417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4941417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Stmt_internal_1init(JNIEnv *env, jclass cls)
4942417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4943417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Stmt_handle =
4944417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "handle", "J");
4945417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Stmt_error_code =
4946417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "error_code", "I");
4947417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4948417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4949417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4950417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Vm_internal_1init(JNIEnv *env, jclass cls)
4951417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4952417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Vm_handle =
4953417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "handle", "J");
4954417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Vm_error_code =
4955417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "error_code", "I");
4956417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4957417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4958417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
4959417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Blob_internal_1init(JNIEnv *env, jclass cls)
4960417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
4961417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Blob_handle =
4962417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "handle", "J");
4963417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Blob_size =
4964417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "size", "I");
4965417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4966417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
4967417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
49685cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJava_SQLite_Backup_internal_1init(JNIEnv *env, jclass cls)
49695cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes{
49705cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes    F_SQLite_Backup_handle =
49715cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes	(*env)->GetFieldID(env, cls, "handle", "J");
49725cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes}
49735cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott Hughes
49745cd52ed8fd9244cbbb9c2553e58b511344f75d8bElliott HughesJNIEXPORT void JNICALL
4975417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJava_SQLite_Database_internal_1init(JNIEnv *env, jclass cls)
4976417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
49777a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if defined(DONT_USE_JNI_ONLOAD) || !defined(JNI_VERSION_1_2)
49787a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    while (C_java_lang_String == 0) {
49797a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	jclass jls = (*env)->FindClass(env, "java/lang/String");
4980417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
49817a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes	C_java_lang_String = (*env)->NewGlobalRef(env, jls);
49827a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes    }
49837a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#endif
4984417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Database_handle =
4985417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "handle", "J");
4986417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    F_SQLite_Database_error_code =
4987417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetFieldID(env, cls, "error_code", "I");
4988417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    M_java_lang_String_getBytes =
4989417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetMethodID(env, C_java_lang_String, "getBytes", "()[B");
4990417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    M_java_lang_String_getBytes2 =
4991417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetMethodID(env, C_java_lang_String, "getBytes",
4992417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    "(Ljava/lang/String;)[B");
4993417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    M_java_lang_String_initBytes =
4994417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetMethodID(env, C_java_lang_String, "<init>", "([B)V");
4995417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    M_java_lang_String_initBytes2 =
4996417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	(*env)->GetMethodID(env, C_java_lang_String, "<init>",
4997417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes			    "([BLjava/lang/String;)V");
4998417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
4999417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
50007a647e8547e57ca573541be55b3728ef7ce376feElliott Hughes#if !defined(DONT_USE_JNI_ONLOAD) && defined(JNI_VERSION_1_2)
5001417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT jint JNICALL
5002417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNI_OnLoad(JavaVM *vm, void *reserved)
5003417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
5004417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env;
5005417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    jclass cls;
5006417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
5007417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#ifndef _WIN32
5008417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#if HAVE_SQLITE2
5009417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (strcmp(sqlite_libencoding(), "UTF-8") != 0) {
5010417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	fprintf(stderr, "WARNING: using non-UTF SQLite2 engine\n");
5011417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
5012417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
5013417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
5014417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_2)) {
5015417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_ERR;
5016417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
5017417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    cls = (*env)->FindClass(env, "java/lang/String");
5018417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (!cls) {
5019417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return JNI_ERR;
5020417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
50214538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe    C_java_lang_String = (*env)->NewGlobalRef(env, cls);
5022417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    return JNI_VERSION_1_2;
5023417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
5024417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
5025417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNIEXPORT void JNICALL
5026417deb1db112103aff04231b6ca79772ff7d3a21Elliott HughesJNI_OnUnload(JavaVM *vm, void *reserved)
5027417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes{
5028417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    JNIEnv *env;
5029417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes
5030417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_2)) {
5031417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	return;
5032417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
5033417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    if (C_java_lang_String) {
50344538aff6d563d32cd1c5d2f7b349809384a0a540Jeremy Sharpe	(*env)->DeleteGlobalRef(env, C_java_lang_String);
5035417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes	C_java_lang_String = 0;
5036417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes    }
5037417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes}
5038417deb1db112103aff04231b6ca79772ff7d3a21Elliott Hughes#endif
5039