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