xref: /aosp_15_r20/external/javasqlite/src/main/java/SQLite/Database.java (revision fd76c71b147b98c03334ec0945352cee0b39aab1)
1*fd76c71bSTreehugger Robot package SQLite;
2*fd76c71bSTreehugger Robot 
3*fd76c71bSTreehugger Robot /**
4*fd76c71bSTreehugger Robot  * Main class wrapping an SQLite database.
5*fd76c71bSTreehugger Robot  */
6*fd76c71bSTreehugger Robot 
7*fd76c71bSTreehugger Robot public class Database {
8*fd76c71bSTreehugger Robot 
9*fd76c71bSTreehugger Robot     /**
10*fd76c71bSTreehugger Robot      * Internal handle for the native SQLite API.
11*fd76c71bSTreehugger Robot      */
12*fd76c71bSTreehugger Robot 
13*fd76c71bSTreehugger Robot     protected long handle = 0;
14*fd76c71bSTreehugger Robot 
15*fd76c71bSTreehugger Robot     /**
16*fd76c71bSTreehugger Robot      * Internal last error code for exec() methods.
17*fd76c71bSTreehugger Robot      */
18*fd76c71bSTreehugger Robot 
19*fd76c71bSTreehugger Robot     protected int error_code = 0;
20*fd76c71bSTreehugger Robot 
21*fd76c71bSTreehugger Robot     /**
22*fd76c71bSTreehugger Robot      * Open an SQLite database file.
23*fd76c71bSTreehugger Robot      *
24*fd76c71bSTreehugger Robot      * @param filename the name of the database file
25*fd76c71bSTreehugger Robot      * @param mode open mode (e.g. SQLITE_OPEN_READONLY)
26*fd76c71bSTreehugger Robot      */
27*fd76c71bSTreehugger Robot 
open(String filename, int mode)28*fd76c71bSTreehugger Robot     public void open(String filename, int mode) throws SQLite.Exception {
29*fd76c71bSTreehugger Robot 	if ((mode & 0200) != 0) {
30*fd76c71bSTreehugger Robot 	    mode = SQLite.Constants.SQLITE_OPEN_READWRITE |
31*fd76c71bSTreehugger Robot 		   SQLite.Constants.SQLITE_OPEN_CREATE;
32*fd76c71bSTreehugger Robot 	} else if ((mode & 0400) != 0) {
33*fd76c71bSTreehugger Robot 	    mode = SQLite.Constants.SQLITE_OPEN_READONLY;
34*fd76c71bSTreehugger Robot 	}
35*fd76c71bSTreehugger Robot 	synchronized(this) {
36*fd76c71bSTreehugger Robot 	    try {
37*fd76c71bSTreehugger Robot 		_open4(filename, mode, null, false);
38*fd76c71bSTreehugger Robot 	    } catch (SQLite.Exception se) {
39*fd76c71bSTreehugger Robot 		throw se;
40*fd76c71bSTreehugger Robot 	    } catch (java.lang.OutOfMemoryError me) {
41*fd76c71bSTreehugger Robot 		throw me;
42*fd76c71bSTreehugger Robot 	    } catch (Throwable t) {
43*fd76c71bSTreehugger Robot 		_open(filename, mode);
44*fd76c71bSTreehugger Robot 	    }
45*fd76c71bSTreehugger Robot 	}
46*fd76c71bSTreehugger Robot     }
47*fd76c71bSTreehugger Robot 
48*fd76c71bSTreehugger Robot     /**
49*fd76c71bSTreehugger Robot      * Open an SQLite database file.
50*fd76c71bSTreehugger Robot      *
51*fd76c71bSTreehugger Robot      * @param filename the name of the database file
52*fd76c71bSTreehugger Robot      * @param mode open mode (e.g. SQLITE_OPEN_READONLY)
53*fd76c71bSTreehugger Robot      * @param vfs VFS name (for SQLite >= 3.5)
54*fd76c71bSTreehugger Robot      */
55*fd76c71bSTreehugger Robot 
open(String filename, int mode, String vfs)56*fd76c71bSTreehugger Robot     public void open(String filename, int mode, String vfs)
57*fd76c71bSTreehugger Robot 	throws SQLite.Exception {
58*fd76c71bSTreehugger Robot 	if ((mode & 0200) != 0) {
59*fd76c71bSTreehugger Robot 	    mode = SQLite.Constants.SQLITE_OPEN_READWRITE |
60*fd76c71bSTreehugger Robot 		   SQLite.Constants.SQLITE_OPEN_CREATE;
61*fd76c71bSTreehugger Robot 	} else if ((mode & 0400) != 0) {
62*fd76c71bSTreehugger Robot 	    mode = SQLite.Constants.SQLITE_OPEN_READONLY;
63*fd76c71bSTreehugger Robot 	}
64*fd76c71bSTreehugger Robot 	synchronized(this) {
65*fd76c71bSTreehugger Robot 	    try {
66*fd76c71bSTreehugger Robot 		_open4(filename, mode, vfs, false);
67*fd76c71bSTreehugger Robot 	    } catch (SQLite.Exception se) {
68*fd76c71bSTreehugger Robot 		throw se;
69*fd76c71bSTreehugger Robot 	    } catch (java.lang.OutOfMemoryError me) {
70*fd76c71bSTreehugger Robot 		throw me;
71*fd76c71bSTreehugger Robot 	    } catch (Throwable t) {
72*fd76c71bSTreehugger Robot 		_open(filename, mode);
73*fd76c71bSTreehugger Robot 	    }
74*fd76c71bSTreehugger Robot 	}
75*fd76c71bSTreehugger Robot     }
76*fd76c71bSTreehugger Robot 
77*fd76c71bSTreehugger Robot     /**
78*fd76c71bSTreehugger Robot      * Open an SQLite database file.
79*fd76c71bSTreehugger Robot      *
80*fd76c71bSTreehugger Robot      * @param filename the name of the database file
81*fd76c71bSTreehugger Robot      * @param mode open mode (e.g. SQLITE_OPEN_READONLY)
82*fd76c71bSTreehugger Robot      * @param vfs VFS name (for SQLite >= 3.5)
83*fd76c71bSTreehugger Robot      * @param ver2 flag to force version on create (false = SQLite3, true = SQLite2)
84*fd76c71bSTreehugger Robot      */
85*fd76c71bSTreehugger Robot 
open(String filename, int mode, String vfs, boolean ver2)86*fd76c71bSTreehugger Robot     public void open(String filename, int mode, String vfs, boolean ver2)
87*fd76c71bSTreehugger Robot 	throws SQLite.Exception {
88*fd76c71bSTreehugger Robot 	if ((mode & 0200) != 0) {
89*fd76c71bSTreehugger Robot 	    mode = SQLite.Constants.SQLITE_OPEN_READWRITE |
90*fd76c71bSTreehugger Robot 		   SQLite.Constants.SQLITE_OPEN_CREATE;
91*fd76c71bSTreehugger Robot 	} else if ((mode & 0400) != 0) {
92*fd76c71bSTreehugger Robot 	    mode = SQLite.Constants.SQLITE_OPEN_READONLY;
93*fd76c71bSTreehugger Robot 	}
94*fd76c71bSTreehugger Robot 	synchronized(this) {
95*fd76c71bSTreehugger Robot 	    try {
96*fd76c71bSTreehugger Robot 		_open4(filename, mode, vfs, ver2);
97*fd76c71bSTreehugger Robot 	    } catch (SQLite.Exception se) {
98*fd76c71bSTreehugger Robot 		throw se;
99*fd76c71bSTreehugger Robot 	    } catch (java.lang.OutOfMemoryError me) {
100*fd76c71bSTreehugger Robot 		throw me;
101*fd76c71bSTreehugger Robot 	    } catch (Throwable t) {
102*fd76c71bSTreehugger Robot 		_open(filename, mode);
103*fd76c71bSTreehugger Robot 	    }
104*fd76c71bSTreehugger Robot 	}
105*fd76c71bSTreehugger Robot     }
106*fd76c71bSTreehugger Robot 
107*fd76c71bSTreehugger Robot     /*
108*fd76c71bSTreehugger Robot      * For backward compatibility to older sqlite.jar, sqlite_jni
109*fd76c71bSTreehugger Robot      */
110*fd76c71bSTreehugger Robot 
_open(String filename, int mode)111*fd76c71bSTreehugger Robot     private native void _open(String filename, int mode)
112*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
113*fd76c71bSTreehugger Robot 
114*fd76c71bSTreehugger Robot     /*
115*fd76c71bSTreehugger Robot      * Newer full interface
116*fd76c71bSTreehugger Robot      */
117*fd76c71bSTreehugger Robot 
_open4(String filename, int mode, String vfs, boolean ver2)118*fd76c71bSTreehugger Robot     private native void _open4(String filename, int mode, String vfs,
119*fd76c71bSTreehugger Robot 			       boolean ver2)
120*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
121*fd76c71bSTreehugger Robot 
122*fd76c71bSTreehugger Robot     /**
123*fd76c71bSTreehugger Robot      * Open SQLite auxiliary database file for temporary
124*fd76c71bSTreehugger Robot      * tables.
125*fd76c71bSTreehugger Robot      *
126*fd76c71bSTreehugger Robot      * @param filename the name of the auxiliary file or null
127*fd76c71bSTreehugger Robot      */
128*fd76c71bSTreehugger Robot 
open_aux_file(String filename)129*fd76c71bSTreehugger Robot     public void open_aux_file(String filename) throws SQLite.Exception {
130*fd76c71bSTreehugger Robot 	synchronized(this) {
131*fd76c71bSTreehugger Robot 	    _open_aux_file(filename);
132*fd76c71bSTreehugger Robot 	}
133*fd76c71bSTreehugger Robot     }
134*fd76c71bSTreehugger Robot 
_open_aux_file(String filename)135*fd76c71bSTreehugger Robot     private native void _open_aux_file(String filename)
136*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
137*fd76c71bSTreehugger Robot 
138*fd76c71bSTreehugger Robot     /**
139*fd76c71bSTreehugger Robot      * Destructor for object.
140*fd76c71bSTreehugger Robot      */
141*fd76c71bSTreehugger Robot 
finalize()142*fd76c71bSTreehugger Robot     protected void finalize() {
143*fd76c71bSTreehugger Robot 	synchronized(this) {
144*fd76c71bSTreehugger Robot 	    _finalize();
145*fd76c71bSTreehugger Robot 	}
146*fd76c71bSTreehugger Robot     }
147*fd76c71bSTreehugger Robot 
_finalize()148*fd76c71bSTreehugger Robot     private native void _finalize();
149*fd76c71bSTreehugger Robot 
150*fd76c71bSTreehugger Robot     /**
151*fd76c71bSTreehugger Robot      * Close the underlying SQLite database file.
152*fd76c71bSTreehugger Robot      */
153*fd76c71bSTreehugger Robot 
close()154*fd76c71bSTreehugger Robot     public void close()	throws SQLite.Exception {
155*fd76c71bSTreehugger Robot 	synchronized(this) {
156*fd76c71bSTreehugger Robot 	    _close();
157*fd76c71bSTreehugger Robot 	}
158*fd76c71bSTreehugger Robot     }
159*fd76c71bSTreehugger Robot 
_close()160*fd76c71bSTreehugger Robot     private native void _close()
161*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
162*fd76c71bSTreehugger Robot 
163*fd76c71bSTreehugger Robot     /**
164*fd76c71bSTreehugger Robot      * Execute an SQL statement and invoke callback methods
165*fd76c71bSTreehugger Robot      * for each row of the result set.<P>
166*fd76c71bSTreehugger Robot      *
167*fd76c71bSTreehugger Robot      * It the method fails, an SQLite.Exception is thrown and
168*fd76c71bSTreehugger Robot      * an error code is set, which later can be retrieved by
169*fd76c71bSTreehugger Robot      * the last_error() method.
170*fd76c71bSTreehugger Robot      *
171*fd76c71bSTreehugger Robot      * @param sql the SQL statement to be executed
172*fd76c71bSTreehugger Robot      * @param cb the object implementing the callback methods
173*fd76c71bSTreehugger Robot      */
174*fd76c71bSTreehugger Robot 
exec(String sql, SQLite.Callback cb)175*fd76c71bSTreehugger Robot     public void exec(String sql, SQLite.Callback cb) throws SQLite.Exception {
176*fd76c71bSTreehugger Robot 	synchronized(this) {
177*fd76c71bSTreehugger Robot 	    _exec(sql, cb);
178*fd76c71bSTreehugger Robot 	}
179*fd76c71bSTreehugger Robot     }
180*fd76c71bSTreehugger Robot 
_exec(String sql, SQLite.Callback cb)181*fd76c71bSTreehugger Robot     private native void _exec(String sql, SQLite.Callback cb)
182*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
183*fd76c71bSTreehugger Robot 
184*fd76c71bSTreehugger Robot     /**
185*fd76c71bSTreehugger Robot      * Execute an SQL statement and invoke callback methods
186*fd76c71bSTreehugger Robot      * for each row of the result set. Each '%q' or %Q in the
187*fd76c71bSTreehugger Robot      * statement string is substituted by its corresponding
188*fd76c71bSTreehugger Robot      * element in the argument vector.
189*fd76c71bSTreehugger Robot      * <BR><BR>
190*fd76c71bSTreehugger Robot      * Example:<BR>
191*fd76c71bSTreehugger Robot      * <PRE>
192*fd76c71bSTreehugger Robot      *   String args[] = new String[1];
193*fd76c71bSTreehugger Robot      *   args[0] = "tab%";
194*fd76c71bSTreehugger Robot      *   db.exec("select * from sqlite_master where type like '%q'",
195*fd76c71bSTreehugger Robot      *           null, args);
196*fd76c71bSTreehugger Robot      * </PRE>
197*fd76c71bSTreehugger Robot      *
198*fd76c71bSTreehugger Robot      * It the method fails, an SQLite.Exception is thrown and
199*fd76c71bSTreehugger Robot      * an error code is set, which later can be retrieved by
200*fd76c71bSTreehugger Robot      * the last_error() method.
201*fd76c71bSTreehugger Robot      *
202*fd76c71bSTreehugger Robot      * @param sql the SQL statement to be executed
203*fd76c71bSTreehugger Robot      * @param cb the object implementing the callback methods
204*fd76c71bSTreehugger Robot      * @param args arguments for the SQL statement, '%q' substitution
205*fd76c71bSTreehugger Robot      */
206*fd76c71bSTreehugger Robot 
exec(String sql, SQLite.Callback cb, String args[])207*fd76c71bSTreehugger Robot     public void exec(String sql, SQLite.Callback cb,
208*fd76c71bSTreehugger Robot 		     String args[]) throws SQLite.Exception {
209*fd76c71bSTreehugger Robot 	synchronized(this) {
210*fd76c71bSTreehugger Robot 	    _exec(sql, cb, args);
211*fd76c71bSTreehugger Robot 	}
212*fd76c71bSTreehugger Robot     }
213*fd76c71bSTreehugger Robot 
_exec(String sql, SQLite.Callback cb, String args[])214*fd76c71bSTreehugger Robot     private native void _exec(String sql, SQLite.Callback cb, String args[])
215*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
216*fd76c71bSTreehugger Robot 
217*fd76c71bSTreehugger Robot     /**
218*fd76c71bSTreehugger Robot      * Return the row identifier of the last inserted
219*fd76c71bSTreehugger Robot      * row.
220*fd76c71bSTreehugger Robot      */
221*fd76c71bSTreehugger Robot 
last_insert_rowid()222*fd76c71bSTreehugger Robot     public long last_insert_rowid() {
223*fd76c71bSTreehugger Robot 	synchronized(this) {
224*fd76c71bSTreehugger Robot 	    return _last_insert_rowid();
225*fd76c71bSTreehugger Robot 	}
226*fd76c71bSTreehugger Robot     }
227*fd76c71bSTreehugger Robot 
_last_insert_rowid()228*fd76c71bSTreehugger Robot     private native long _last_insert_rowid();
229*fd76c71bSTreehugger Robot 
230*fd76c71bSTreehugger Robot     /**
231*fd76c71bSTreehugger Robot      * Abort the current SQLite operation.
232*fd76c71bSTreehugger Robot      */
233*fd76c71bSTreehugger Robot 
interrupt()234*fd76c71bSTreehugger Robot     public void interrupt() {
235*fd76c71bSTreehugger Robot 	synchronized(this) {
236*fd76c71bSTreehugger Robot 	    _interrupt();
237*fd76c71bSTreehugger Robot 	}
238*fd76c71bSTreehugger Robot     }
239*fd76c71bSTreehugger Robot 
_interrupt()240*fd76c71bSTreehugger Robot     private native void _interrupt();
241*fd76c71bSTreehugger Robot 
242*fd76c71bSTreehugger Robot     /**
243*fd76c71bSTreehugger Robot      * Return the number of changed rows for the last statement.
244*fd76c71bSTreehugger Robot      */
245*fd76c71bSTreehugger Robot 
changes()246*fd76c71bSTreehugger Robot     public long changes() {
247*fd76c71bSTreehugger Robot 	synchronized(this) {
248*fd76c71bSTreehugger Robot 	    return _changes();
249*fd76c71bSTreehugger Robot 	}
250*fd76c71bSTreehugger Robot     }
251*fd76c71bSTreehugger Robot 
_changes()252*fd76c71bSTreehugger Robot     private native long _changes();
253*fd76c71bSTreehugger Robot 
254*fd76c71bSTreehugger Robot     /**
255*fd76c71bSTreehugger Robot      * Establish a busy callback method which gets called when
256*fd76c71bSTreehugger Robot      * an SQLite table is locked.
257*fd76c71bSTreehugger Robot      *
258*fd76c71bSTreehugger Robot      * @param bh the object implementing the busy callback method
259*fd76c71bSTreehugger Robot      */
260*fd76c71bSTreehugger Robot 
busy_handler(SQLite.BusyHandler bh)261*fd76c71bSTreehugger Robot     public void busy_handler(SQLite.BusyHandler bh) {
262*fd76c71bSTreehugger Robot 	synchronized(this) {
263*fd76c71bSTreehugger Robot 	    _busy_handler(bh);
264*fd76c71bSTreehugger Robot 	}
265*fd76c71bSTreehugger Robot     }
266*fd76c71bSTreehugger Robot 
_busy_handler(SQLite.BusyHandler bh)267*fd76c71bSTreehugger Robot     private native void _busy_handler(SQLite.BusyHandler bh);
268*fd76c71bSTreehugger Robot 
269*fd76c71bSTreehugger Robot     /**
270*fd76c71bSTreehugger Robot      * Set the timeout for waiting for an SQLite table to become
271*fd76c71bSTreehugger Robot      * unlocked.
272*fd76c71bSTreehugger Robot      *
273*fd76c71bSTreehugger Robot      * @param ms number of millisecond to wait
274*fd76c71bSTreehugger Robot      */
275*fd76c71bSTreehugger Robot 
busy_timeout(int ms)276*fd76c71bSTreehugger Robot     public void busy_timeout(int ms) {
277*fd76c71bSTreehugger Robot 	synchronized(this) {
278*fd76c71bSTreehugger Robot 	    _busy_timeout(ms);
279*fd76c71bSTreehugger Robot 	}
280*fd76c71bSTreehugger Robot     }
281*fd76c71bSTreehugger Robot 
_busy_timeout(int ms)282*fd76c71bSTreehugger Robot     private native void _busy_timeout(int ms);
283*fd76c71bSTreehugger Robot 
284*fd76c71bSTreehugger Robot     /**
285*fd76c71bSTreehugger Robot      * Convenience method to retrieve an entire result
286*fd76c71bSTreehugger Robot      * set into memory.
287*fd76c71bSTreehugger Robot      *
288*fd76c71bSTreehugger Robot      * @param sql the SQL statement to be executed
289*fd76c71bSTreehugger Robot      * @param maxrows the max. number of rows to retrieve
290*fd76c71bSTreehugger Robot      * @return result set
291*fd76c71bSTreehugger Robot      */
292*fd76c71bSTreehugger Robot 
get_table(String sql, int maxrows)293*fd76c71bSTreehugger Robot     public TableResult get_table(String sql, int maxrows)
294*fd76c71bSTreehugger Robot 	throws SQLite.Exception {
295*fd76c71bSTreehugger Robot 	TableResult ret = new TableResult(maxrows);
296*fd76c71bSTreehugger Robot 	if (!is3()) {
297*fd76c71bSTreehugger Robot 	    try {
298*fd76c71bSTreehugger Robot 		exec(sql, ret);
299*fd76c71bSTreehugger Robot 	    } catch (SQLite.Exception e) {
300*fd76c71bSTreehugger Robot 		if (maxrows <= 0 || !ret.atmaxrows) {
301*fd76c71bSTreehugger Robot 		    throw e;
302*fd76c71bSTreehugger Robot 		}
303*fd76c71bSTreehugger Robot 	    }
304*fd76c71bSTreehugger Robot 	} else {
305*fd76c71bSTreehugger Robot 	    synchronized(this) {
306*fd76c71bSTreehugger Robot 		/* only one statement !!! */
307*fd76c71bSTreehugger Robot 		Vm vm = compile(sql);
308*fd76c71bSTreehugger Robot 		set_last_error(vm.error_code);
309*fd76c71bSTreehugger Robot 		if (ret.maxrows > 0) {
310*fd76c71bSTreehugger Robot 		    while (ret.nrows < ret.maxrows && vm.step(ret)) {
311*fd76c71bSTreehugger Robot 			set_last_error(vm.error_code);
312*fd76c71bSTreehugger Robot 		    }
313*fd76c71bSTreehugger Robot 		} else {
314*fd76c71bSTreehugger Robot 		    while (vm.step(ret)) {
315*fd76c71bSTreehugger Robot 			set_last_error(vm.error_code);
316*fd76c71bSTreehugger Robot 		    }
317*fd76c71bSTreehugger Robot 		}
318*fd76c71bSTreehugger Robot 		vm.finalize();
319*fd76c71bSTreehugger Robot 	    }
320*fd76c71bSTreehugger Robot 	}
321*fd76c71bSTreehugger Robot 	return ret;
322*fd76c71bSTreehugger Robot     }
323*fd76c71bSTreehugger Robot 
324*fd76c71bSTreehugger Robot     /**
325*fd76c71bSTreehugger Robot      * Convenience method to retrieve an entire result
326*fd76c71bSTreehugger Robot      * set into memory.
327*fd76c71bSTreehugger Robot      *
328*fd76c71bSTreehugger Robot      * @param sql the SQL statement to be executed
329*fd76c71bSTreehugger Robot      * @return result set
330*fd76c71bSTreehugger Robot      */
331*fd76c71bSTreehugger Robot 
get_table(String sql)332*fd76c71bSTreehugger Robot     public TableResult get_table(String sql) throws SQLite.Exception {
333*fd76c71bSTreehugger Robot 	return get_table(sql, 0);
334*fd76c71bSTreehugger Robot     }
335*fd76c71bSTreehugger Robot 
336*fd76c71bSTreehugger Robot     /**
337*fd76c71bSTreehugger Robot      * Convenience method to retrieve an entire result
338*fd76c71bSTreehugger Robot      * set into memory.
339*fd76c71bSTreehugger Robot      *
340*fd76c71bSTreehugger Robot      * @param sql the SQL statement to be executed
341*fd76c71bSTreehugger Robot      * @param maxrows the max. number of rows to retrieve
342*fd76c71bSTreehugger Robot      * @param args arguments for the SQL statement, '%q' substitution
343*fd76c71bSTreehugger Robot      * @return result set
344*fd76c71bSTreehugger Robot      */
345*fd76c71bSTreehugger Robot 
get_table(String sql, int maxrows, String args[])346*fd76c71bSTreehugger Robot     public TableResult get_table(String sql, int maxrows, String args[])
347*fd76c71bSTreehugger Robot 	throws SQLite.Exception {
348*fd76c71bSTreehugger Robot 	TableResult ret = new TableResult(maxrows);
349*fd76c71bSTreehugger Robot 	if (!is3()) {
350*fd76c71bSTreehugger Robot 	    try {
351*fd76c71bSTreehugger Robot 		exec(sql, ret, args);
352*fd76c71bSTreehugger Robot 	    } catch (SQLite.Exception e) {
353*fd76c71bSTreehugger Robot 		if (maxrows <= 0 || !ret.atmaxrows) {
354*fd76c71bSTreehugger Robot 		    throw e;
355*fd76c71bSTreehugger Robot 		}
356*fd76c71bSTreehugger Robot 	    }
357*fd76c71bSTreehugger Robot 	} else {
358*fd76c71bSTreehugger Robot 	    synchronized(this) {
359*fd76c71bSTreehugger Robot 		/* only one statement !!! */
360*fd76c71bSTreehugger Robot 		Vm vm = compile(sql, args);
361*fd76c71bSTreehugger Robot 		set_last_error(vm.error_code);
362*fd76c71bSTreehugger Robot 		if (ret.maxrows > 0) {
363*fd76c71bSTreehugger Robot 		    while (ret.nrows < ret.maxrows && vm.step(ret)) {
364*fd76c71bSTreehugger Robot 			set_last_error(vm.error_code);
365*fd76c71bSTreehugger Robot 		    }
366*fd76c71bSTreehugger Robot 		} else {
367*fd76c71bSTreehugger Robot 		    while (vm.step(ret)) {
368*fd76c71bSTreehugger Robot 			set_last_error(vm.error_code);
369*fd76c71bSTreehugger Robot 		    }
370*fd76c71bSTreehugger Robot 		}
371*fd76c71bSTreehugger Robot 		vm.finalize();
372*fd76c71bSTreehugger Robot 	    }
373*fd76c71bSTreehugger Robot 	}
374*fd76c71bSTreehugger Robot 	return ret;
375*fd76c71bSTreehugger Robot     }
376*fd76c71bSTreehugger Robot 
377*fd76c71bSTreehugger Robot     /**
378*fd76c71bSTreehugger Robot      * Convenience method to retrieve an entire result
379*fd76c71bSTreehugger Robot      * set into memory.
380*fd76c71bSTreehugger Robot      *
381*fd76c71bSTreehugger Robot      * @param sql the SQL statement to be executed
382*fd76c71bSTreehugger Robot      * @param args arguments for the SQL statement, '%q' substitution
383*fd76c71bSTreehugger Robot      * @return result set
384*fd76c71bSTreehugger Robot      */
385*fd76c71bSTreehugger Robot 
get_table(String sql, String args[])386*fd76c71bSTreehugger Robot     public TableResult get_table(String sql, String args[])
387*fd76c71bSTreehugger Robot 	throws SQLite.Exception {
388*fd76c71bSTreehugger Robot 	return get_table(sql, 0, args);
389*fd76c71bSTreehugger Robot     }
390*fd76c71bSTreehugger Robot 
391*fd76c71bSTreehugger Robot     /**
392*fd76c71bSTreehugger Robot      * Convenience method to retrieve an entire result
393*fd76c71bSTreehugger Robot      * set into memory.
394*fd76c71bSTreehugger Robot      *
395*fd76c71bSTreehugger Robot      * @param sql the SQL statement to be executed
396*fd76c71bSTreehugger Robot      * @param args arguments for the SQL statement, '%q' substitution
397*fd76c71bSTreehugger Robot      * @param tbl TableResult to receive result set
398*fd76c71bSTreehugger Robot      */
399*fd76c71bSTreehugger Robot 
get_table(String sql, String args[], TableResult tbl)400*fd76c71bSTreehugger Robot     public void get_table(String sql, String args[], TableResult tbl)
401*fd76c71bSTreehugger Robot 	throws SQLite.Exception {
402*fd76c71bSTreehugger Robot 	tbl.clear();
403*fd76c71bSTreehugger Robot 	if (!is3()) {
404*fd76c71bSTreehugger Robot 	    try {
405*fd76c71bSTreehugger Robot 		exec(sql, tbl, args);
406*fd76c71bSTreehugger Robot 	    } catch (SQLite.Exception e) {
407*fd76c71bSTreehugger Robot 		if (tbl.maxrows <= 0 || !tbl.atmaxrows) {
408*fd76c71bSTreehugger Robot 		    throw e;
409*fd76c71bSTreehugger Robot 		}
410*fd76c71bSTreehugger Robot 	    }
411*fd76c71bSTreehugger Robot 	} else {
412*fd76c71bSTreehugger Robot 	    synchronized(this) {
413*fd76c71bSTreehugger Robot 		/* only one statement !!! */
414*fd76c71bSTreehugger Robot 		Vm vm = compile(sql, args);
415*fd76c71bSTreehugger Robot 		if (tbl.maxrows > 0) {
416*fd76c71bSTreehugger Robot 		    while (tbl.nrows < tbl.maxrows && vm.step(tbl)) {
417*fd76c71bSTreehugger Robot 			set_last_error(vm.error_code);
418*fd76c71bSTreehugger Robot 		    }
419*fd76c71bSTreehugger Robot 		} else {
420*fd76c71bSTreehugger Robot 		    while (vm.step(tbl)) {
421*fd76c71bSTreehugger Robot 			set_last_error(vm.error_code);
422*fd76c71bSTreehugger Robot 		    }
423*fd76c71bSTreehugger Robot 		}
424*fd76c71bSTreehugger Robot 		vm.finalize();
425*fd76c71bSTreehugger Robot 	    }
426*fd76c71bSTreehugger Robot 	}
427*fd76c71bSTreehugger Robot     }
428*fd76c71bSTreehugger Robot 
429*fd76c71bSTreehugger Robot     /**
430*fd76c71bSTreehugger Robot      * See if an SQL statement is complete.
431*fd76c71bSTreehugger Robot      * Returns true if the input string comprises
432*fd76c71bSTreehugger Robot      * one or more complete SQL statements.
433*fd76c71bSTreehugger Robot      *
434*fd76c71bSTreehugger Robot      * @param sql the SQL statement to be checked
435*fd76c71bSTreehugger Robot      */
436*fd76c71bSTreehugger Robot 
complete(String sql)437*fd76c71bSTreehugger Robot     public synchronized static boolean complete(String sql) {
438*fd76c71bSTreehugger Robot 	return _complete(sql);
439*fd76c71bSTreehugger Robot     }
440*fd76c71bSTreehugger Robot 
_complete(String sql)441*fd76c71bSTreehugger Robot     private native static boolean _complete(String sql);
442*fd76c71bSTreehugger Robot 
443*fd76c71bSTreehugger Robot     /**
444*fd76c71bSTreehugger Robot      * Return SQLite version number as string.
445*fd76c71bSTreehugger Robot      * Don't rely on this when both SQLite 2 and 3 are compiled
446*fd76c71bSTreehugger Robot      * into the native part. Use the class method in this case.
447*fd76c71bSTreehugger Robot      */
448*fd76c71bSTreehugger Robot 
version()449*fd76c71bSTreehugger Robot     public native static String version();
450*fd76c71bSTreehugger Robot 
451*fd76c71bSTreehugger Robot     /**
452*fd76c71bSTreehugger Robot      * Return SQLite version number as string.
453*fd76c71bSTreehugger Robot      * If the database is not open, <tt>unknown</tt> is returned.
454*fd76c71bSTreehugger Robot      */
455*fd76c71bSTreehugger Robot 
dbversion()456*fd76c71bSTreehugger Robot     public native String dbversion();
457*fd76c71bSTreehugger Robot 
458*fd76c71bSTreehugger Robot     /**
459*fd76c71bSTreehugger Robot      * Create regular function.
460*fd76c71bSTreehugger Robot      *
461*fd76c71bSTreehugger Robot      * @param name the name of the new function
462*fd76c71bSTreehugger Robot      * @param nargs number of arguments to function
463*fd76c71bSTreehugger Robot      * @param f interface of function
464*fd76c71bSTreehugger Robot      */
465*fd76c71bSTreehugger Robot 
create_function(String name, int nargs, Function f)466*fd76c71bSTreehugger Robot     public void create_function(String name, int nargs, Function f) {
467*fd76c71bSTreehugger Robot 	synchronized(this) {
468*fd76c71bSTreehugger Robot 	    _create_function(name, nargs, f);
469*fd76c71bSTreehugger Robot 	}
470*fd76c71bSTreehugger Robot     }
471*fd76c71bSTreehugger Robot 
_create_function(String name, int nargs, Function f)472*fd76c71bSTreehugger Robot     private native void _create_function(String name, int nargs, Function f);
473*fd76c71bSTreehugger Robot 
474*fd76c71bSTreehugger Robot     /**
475*fd76c71bSTreehugger Robot      * Create aggregate function.
476*fd76c71bSTreehugger Robot      *
477*fd76c71bSTreehugger Robot      * @param name the name of the new function
478*fd76c71bSTreehugger Robot      * @param nargs number of arguments to function
479*fd76c71bSTreehugger Robot      * @param f interface of function
480*fd76c71bSTreehugger Robot      */
481*fd76c71bSTreehugger Robot 
create_aggregate(String name, int nargs, Function f)482*fd76c71bSTreehugger Robot     public void create_aggregate(String name, int nargs, Function f) {
483*fd76c71bSTreehugger Robot 	synchronized(this) {
484*fd76c71bSTreehugger Robot 	    _create_aggregate(name, nargs, f);
485*fd76c71bSTreehugger Robot 	}
486*fd76c71bSTreehugger Robot     }
487*fd76c71bSTreehugger Robot 
_create_aggregate(String name, int nargs, Function f)488*fd76c71bSTreehugger Robot     private native void _create_aggregate(String name, int nargs, Function f);
489*fd76c71bSTreehugger Robot 
490*fd76c71bSTreehugger Robot     /**
491*fd76c71bSTreehugger Robot      * Set function return type. Only available in SQLite 2.6.0 and
492*fd76c71bSTreehugger Robot      * above, otherwise a no-op.
493*fd76c71bSTreehugger Robot      *
494*fd76c71bSTreehugger Robot      * @param name the name of the function whose return type is to be set
495*fd76c71bSTreehugger Robot      * @param type return type code, e.g. SQLite.Constants.SQLITE_NUMERIC
496*fd76c71bSTreehugger Robot      */
497*fd76c71bSTreehugger Robot 
function_type(String name, int type)498*fd76c71bSTreehugger Robot     public void function_type(String name, int type) {
499*fd76c71bSTreehugger Robot 	synchronized(this) {
500*fd76c71bSTreehugger Robot 	    _function_type(name, type);
501*fd76c71bSTreehugger Robot 	}
502*fd76c71bSTreehugger Robot     }
503*fd76c71bSTreehugger Robot 
_function_type(String name, int type)504*fd76c71bSTreehugger Robot     private native void _function_type(String name, int type);
505*fd76c71bSTreehugger Robot 
506*fd76c71bSTreehugger Robot     /**
507*fd76c71bSTreehugger Robot      * Return the code of the last error occured in
508*fd76c71bSTreehugger Robot      * any of the exec() methods. The value is valid
509*fd76c71bSTreehugger Robot      * after an Exception has been reported by one of
510*fd76c71bSTreehugger Robot      * these methods. See the <A HREF="Constants.html">Constants</A>
511*fd76c71bSTreehugger Robot      * class for possible values.
512*fd76c71bSTreehugger Robot      *
513*fd76c71bSTreehugger Robot      * @return SQLite error code
514*fd76c71bSTreehugger Robot      */
515*fd76c71bSTreehugger Robot 
last_error()516*fd76c71bSTreehugger Robot     public int last_error() {
517*fd76c71bSTreehugger Robot 	return error_code;
518*fd76c71bSTreehugger Robot     }
519*fd76c71bSTreehugger Robot 
520*fd76c71bSTreehugger Robot     /**
521*fd76c71bSTreehugger Robot      * Internal: set error code.
522*fd76c71bSTreehugger Robot      * @param error_code new error code
523*fd76c71bSTreehugger Robot      */
524*fd76c71bSTreehugger Robot 
set_last_error(int error_code)525*fd76c71bSTreehugger Robot     protected void set_last_error(int error_code) {
526*fd76c71bSTreehugger Robot 	this.error_code = error_code;
527*fd76c71bSTreehugger Robot     }
528*fd76c71bSTreehugger Robot 
529*fd76c71bSTreehugger Robot     /**
530*fd76c71bSTreehugger Robot      * Return last error message of SQLite3 engine.
531*fd76c71bSTreehugger Robot      *
532*fd76c71bSTreehugger Robot      * @return error string or null
533*fd76c71bSTreehugger Robot      */
534*fd76c71bSTreehugger Robot 
error_message()535*fd76c71bSTreehugger Robot     public String error_message() {
536*fd76c71bSTreehugger Robot 	synchronized(this) {
537*fd76c71bSTreehugger Robot 	    return _errmsg();
538*fd76c71bSTreehugger Robot 	}
539*fd76c71bSTreehugger Robot     }
540*fd76c71bSTreehugger Robot 
_errmsg()541*fd76c71bSTreehugger Robot     private native String _errmsg();
542*fd76c71bSTreehugger Robot 
543*fd76c71bSTreehugger Robot     /**
544*fd76c71bSTreehugger Robot      * Return error string given SQLite error code (SQLite2).
545*fd76c71bSTreehugger Robot      *
546*fd76c71bSTreehugger Robot      * @param error_code the error code
547*fd76c71bSTreehugger Robot      * @return error string
548*fd76c71bSTreehugger Robot      */
549*fd76c71bSTreehugger Robot 
error_string(int error_code)550*fd76c71bSTreehugger Robot     public static native String error_string(int error_code);
551*fd76c71bSTreehugger Robot 
552*fd76c71bSTreehugger Robot     /**
553*fd76c71bSTreehugger Robot      * Set character encoding.
554*fd76c71bSTreehugger Robot      * @param enc name of encoding
555*fd76c71bSTreehugger Robot      */
556*fd76c71bSTreehugger Robot 
set_encoding(String enc)557*fd76c71bSTreehugger Robot     public void set_encoding(String enc) throws SQLite.Exception {
558*fd76c71bSTreehugger Robot 	synchronized(this) {
559*fd76c71bSTreehugger Robot 	    _set_encoding(enc);
560*fd76c71bSTreehugger Robot 	}
561*fd76c71bSTreehugger Robot     }
562*fd76c71bSTreehugger Robot 
_set_encoding(String enc)563*fd76c71bSTreehugger Robot     private native void _set_encoding(String enc)
564*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
565*fd76c71bSTreehugger Robot 
566*fd76c71bSTreehugger Robot     /**
567*fd76c71bSTreehugger Robot      * Set authorizer function. Only available in SQLite 2.7.6 and
568*fd76c71bSTreehugger Robot      * above, otherwise a no-op.
569*fd76c71bSTreehugger Robot      *
570*fd76c71bSTreehugger Robot      * @param auth the authorizer function
571*fd76c71bSTreehugger Robot      */
572*fd76c71bSTreehugger Robot 
set_authorizer(Authorizer auth)573*fd76c71bSTreehugger Robot     public void set_authorizer(Authorizer auth) {
574*fd76c71bSTreehugger Robot 	synchronized(this) {
575*fd76c71bSTreehugger Robot 	    _set_authorizer(auth);
576*fd76c71bSTreehugger Robot 	}
577*fd76c71bSTreehugger Robot     }
578*fd76c71bSTreehugger Robot 
_set_authorizer(Authorizer auth)579*fd76c71bSTreehugger Robot     private native void _set_authorizer(Authorizer auth);
580*fd76c71bSTreehugger Robot 
581*fd76c71bSTreehugger Robot     /**
582*fd76c71bSTreehugger Robot      * Set trace function. Only available in SQLite 2.7.6 and above,
583*fd76c71bSTreehugger Robot      * otherwise a no-op.
584*fd76c71bSTreehugger Robot      *
585*fd76c71bSTreehugger Robot      * @param tr the trace function
586*fd76c71bSTreehugger Robot      */
587*fd76c71bSTreehugger Robot 
trace(Trace tr)588*fd76c71bSTreehugger Robot     public void trace(Trace tr) {
589*fd76c71bSTreehugger Robot 	synchronized(this) {
590*fd76c71bSTreehugger Robot 	    _trace(tr);
591*fd76c71bSTreehugger Robot 	}
592*fd76c71bSTreehugger Robot     }
593*fd76c71bSTreehugger Robot 
_trace(Trace tr)594*fd76c71bSTreehugger Robot     private native void _trace(Trace tr);
595*fd76c71bSTreehugger Robot 
596*fd76c71bSTreehugger Robot     /**
597*fd76c71bSTreehugger Robot      * Initiate a database backup, SQLite 3.x only.
598*fd76c71bSTreehugger Robot      *
599*fd76c71bSTreehugger Robot      * @param dest destination database
600*fd76c71bSTreehugger Robot      * @param destName schema of destination database to be backed up
601*fd76c71bSTreehugger Robot      * @param srcName schema of source database
602*fd76c71bSTreehugger Robot      * @return Backup object to perform the backup operation
603*fd76c71bSTreehugger Robot      */
604*fd76c71bSTreehugger Robot 
backup(Database dest, String destName, String srcName)605*fd76c71bSTreehugger Robot     public Backup backup(Database dest, String destName, String srcName)
606*fd76c71bSTreehugger Robot 	throws SQLite.Exception {
607*fd76c71bSTreehugger Robot 	synchronized(this) {
608*fd76c71bSTreehugger Robot 	    Backup b = new Backup();
609*fd76c71bSTreehugger Robot 	    _backup(b, dest, destName, this, srcName);
610*fd76c71bSTreehugger Robot 	    return b;
611*fd76c71bSTreehugger Robot 	}
612*fd76c71bSTreehugger Robot     }
613*fd76c71bSTreehugger Robot 
_backup(Backup b, Database dest, String destName, Database src, String srcName)614*fd76c71bSTreehugger Robot     private static native void _backup(Backup b, Database dest,
615*fd76c71bSTreehugger Robot 				       String destName, Database src,
616*fd76c71bSTreehugger Robot 				       String srcName)
617*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
618*fd76c71bSTreehugger Robot 
619*fd76c71bSTreehugger Robot     /**
620*fd76c71bSTreehugger Robot      * Set profile function. Only available in SQLite 3.6 and above,
621*fd76c71bSTreehugger Robot      * otherwise a no-op.
622*fd76c71bSTreehugger Robot      *
623*fd76c71bSTreehugger Robot      * @param pr the trace function
624*fd76c71bSTreehugger Robot      */
625*fd76c71bSTreehugger Robot 
profile(Profile pr)626*fd76c71bSTreehugger Robot     public void profile(Profile pr) {
627*fd76c71bSTreehugger Robot 	synchronized(this) {
628*fd76c71bSTreehugger Robot 	    _profile(pr);
629*fd76c71bSTreehugger Robot 	}
630*fd76c71bSTreehugger Robot     }
631*fd76c71bSTreehugger Robot 
_profile(Profile pr)632*fd76c71bSTreehugger Robot     private native void _profile(Profile pr);
633*fd76c71bSTreehugger Robot 
634*fd76c71bSTreehugger Robot     /**
635*fd76c71bSTreehugger Robot      * Return information on SQLite runtime status.
636*fd76c71bSTreehugger Robot      * Only available in SQLite 3.6 and above,
637*fd76c71bSTreehugger Robot      * otherwise a no-op.
638*fd76c71bSTreehugger Robot      *
639*fd76c71bSTreehugger Robot      * @param op   operation code
640*fd76c71bSTreehugger Robot      * @param info output buffer, must be able to hold two
641*fd76c71bSTreehugger Robot      *             values (current/highwater)
642*fd76c71bSTreehugger Robot      * @param flag reset flag
643*fd76c71bSTreehugger Robot      * @return SQLite error code
644*fd76c71bSTreehugger Robot      */
645*fd76c71bSTreehugger Robot 
status(int op, int info[], boolean flag)646*fd76c71bSTreehugger Robot     public synchronized static int status(int op, int info[], boolean flag) {
647*fd76c71bSTreehugger Robot 	return _status(op, info, flag);
648*fd76c71bSTreehugger Robot     }
649*fd76c71bSTreehugger Robot 
_status(int op, int info[], boolean flag)650*fd76c71bSTreehugger Robot     private native static int _status(int op, int info[], boolean flag);
651*fd76c71bSTreehugger Robot 
652*fd76c71bSTreehugger Robot     /**
653*fd76c71bSTreehugger Robot      * Return information on SQLite connection status.
654*fd76c71bSTreehugger Robot      * Only available in SQLite 3.6 and above,
655*fd76c71bSTreehugger Robot      * otherwise a no-op.
656*fd76c71bSTreehugger Robot      *
657*fd76c71bSTreehugger Robot      * @param op operation code
658*fd76c71bSTreehugger Robot      * @param info output buffer, must be able to hold two
659*fd76c71bSTreehugger Robot      *             values (current/highwater)
660*fd76c71bSTreehugger Robot      * @param flag reset flag
661*fd76c71bSTreehugger Robot      * @return SQLite error code
662*fd76c71bSTreehugger Robot      */
663*fd76c71bSTreehugger Robot 
db_status(int op, int info[], boolean flag)664*fd76c71bSTreehugger Robot     public int db_status(int op, int info[], boolean flag) {
665*fd76c71bSTreehugger Robot 	synchronized(this) {
666*fd76c71bSTreehugger Robot 	    return _db_status(op, info, flag);
667*fd76c71bSTreehugger Robot 	}
668*fd76c71bSTreehugger Robot     }
669*fd76c71bSTreehugger Robot 
_db_status(int op, int info[], boolean flag)670*fd76c71bSTreehugger Robot     private native int _db_status(int op, int info[], boolean flag);
671*fd76c71bSTreehugger Robot 
672*fd76c71bSTreehugger Robot     /**
673*fd76c71bSTreehugger Robot      * Compile and return SQLite VM for SQL statement. Only available
674*fd76c71bSTreehugger Robot      * in SQLite 2.8.0 and above, otherwise a no-op.
675*fd76c71bSTreehugger Robot      *
676*fd76c71bSTreehugger Robot      * @param sql SQL statement to be compiled
677*fd76c71bSTreehugger Robot      * @return a Vm object
678*fd76c71bSTreehugger Robot      */
679*fd76c71bSTreehugger Robot 
compile(String sql)680*fd76c71bSTreehugger Robot     public Vm compile(String sql) throws SQLite.Exception {
681*fd76c71bSTreehugger Robot 	synchronized(this) {
682*fd76c71bSTreehugger Robot 	    Vm vm = new Vm();
683*fd76c71bSTreehugger Robot 	    vm_compile(sql, vm);
684*fd76c71bSTreehugger Robot 	    return vm;
685*fd76c71bSTreehugger Robot 	}
686*fd76c71bSTreehugger Robot     }
687*fd76c71bSTreehugger Robot 
688*fd76c71bSTreehugger Robot     /**
689*fd76c71bSTreehugger Robot      * Compile and return SQLite VM for SQL statement. Only available
690*fd76c71bSTreehugger Robot      * in SQLite 3.0 and above, otherwise a no-op.
691*fd76c71bSTreehugger Robot      *
692*fd76c71bSTreehugger Robot      * @param sql SQL statement to be compiled
693*fd76c71bSTreehugger Robot      * @param args arguments for the SQL statement, '%q' substitution
694*fd76c71bSTreehugger Robot      * @return a Vm object
695*fd76c71bSTreehugger Robot      */
696*fd76c71bSTreehugger Robot 
compile(String sql, String args[])697*fd76c71bSTreehugger Robot     public Vm compile(String sql, String args[]) throws SQLite.Exception {
698*fd76c71bSTreehugger Robot 	synchronized(this) {
699*fd76c71bSTreehugger Robot 	    Vm vm = new Vm();
700*fd76c71bSTreehugger Robot 	    vm_compile_args(sql, vm, args);
701*fd76c71bSTreehugger Robot 	    return vm;
702*fd76c71bSTreehugger Robot 	}
703*fd76c71bSTreehugger Robot     }
704*fd76c71bSTreehugger Robot 
705*fd76c71bSTreehugger Robot     /**
706*fd76c71bSTreehugger Robot      * Prepare and return SQLite3 statement for SQL. Only available
707*fd76c71bSTreehugger Robot      * in SQLite 3.0 and above, otherwise a no-op.
708*fd76c71bSTreehugger Robot      *
709*fd76c71bSTreehugger Robot      * @param sql SQL statement to be prepared
710*fd76c71bSTreehugger Robot      * @return a Stmt object
711*fd76c71bSTreehugger Robot      */
712*fd76c71bSTreehugger Robot 
prepare(String sql)713*fd76c71bSTreehugger Robot     public Stmt prepare(String sql) throws SQLite.Exception {
714*fd76c71bSTreehugger Robot 	synchronized(this) {
715*fd76c71bSTreehugger Robot 	    Stmt stmt = new Stmt();
716*fd76c71bSTreehugger Robot 	    stmt_prepare(sql, stmt);
717*fd76c71bSTreehugger Robot 	    return stmt;
718*fd76c71bSTreehugger Robot 	}
719*fd76c71bSTreehugger Robot     }
720*fd76c71bSTreehugger Robot 
721*fd76c71bSTreehugger Robot     /**
722*fd76c71bSTreehugger Robot      * Open an SQLite3 blob. Only available in SQLite 3.4.0 and above.
723*fd76c71bSTreehugger Robot      * @param db database name
724*fd76c71bSTreehugger Robot      * @param table table name
725*fd76c71bSTreehugger Robot      * @param column column name
726*fd76c71bSTreehugger Robot      * @param row row identifier
727*fd76c71bSTreehugger Robot      * @param rw if true, open for read-write, else read-only
728*fd76c71bSTreehugger Robot      * @return a Blob object
729*fd76c71bSTreehugger Robot      */
730*fd76c71bSTreehugger Robot 
open_blob(String db, String table, String column, long row, boolean rw)731*fd76c71bSTreehugger Robot     public Blob open_blob(String db, String table, String column,
732*fd76c71bSTreehugger Robot 			  long row, boolean rw) throws SQLite.Exception {
733*fd76c71bSTreehugger Robot 	synchronized(this) {
734*fd76c71bSTreehugger Robot 	    Blob blob = new Blob();
735*fd76c71bSTreehugger Robot 	    _open_blob(db, table, column, row, rw, blob);
736*fd76c71bSTreehugger Robot 	    return blob;
737*fd76c71bSTreehugger Robot 	}
738*fd76c71bSTreehugger Robot     }
739*fd76c71bSTreehugger Robot 
740*fd76c71bSTreehugger Robot     /**
741*fd76c71bSTreehugger Robot      * Check type of open database.
742*fd76c71bSTreehugger Robot      * @return true if SQLite3 database
743*fd76c71bSTreehugger Robot      */
744*fd76c71bSTreehugger Robot 
is3()745*fd76c71bSTreehugger Robot     public native boolean is3();
746*fd76c71bSTreehugger Robot 
747*fd76c71bSTreehugger Robot     /**
748*fd76c71bSTreehugger Robot      * Internal compile method.
749*fd76c71bSTreehugger Robot      * @param sql SQL statement
750*fd76c71bSTreehugger Robot      * @param vm Vm object
751*fd76c71bSTreehugger Robot      */
752*fd76c71bSTreehugger Robot 
vm_compile(String sql, Vm vm)753*fd76c71bSTreehugger Robot     private native void vm_compile(String sql, Vm vm)
754*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
755*fd76c71bSTreehugger Robot 
756*fd76c71bSTreehugger Robot     /**
757*fd76c71bSTreehugger Robot      * Internal compile method, SQLite 3.0 only.
758*fd76c71bSTreehugger Robot      * @param sql SQL statement
759*fd76c71bSTreehugger Robot      * @param args arguments for the SQL statement, '%q' substitution
760*fd76c71bSTreehugger Robot      * @param vm Vm object
761*fd76c71bSTreehugger Robot      */
762*fd76c71bSTreehugger Robot 
vm_compile_args(String sql, Vm vm, String args[])763*fd76c71bSTreehugger Robot     private native void vm_compile_args(String sql, Vm vm, String args[])
764*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
765*fd76c71bSTreehugger Robot 
766*fd76c71bSTreehugger Robot     /**
767*fd76c71bSTreehugger Robot      * Internal SQLite3 prepare method.
768*fd76c71bSTreehugger Robot      * @param sql SQL statement
769*fd76c71bSTreehugger Robot      * @param stmt Stmt object
770*fd76c71bSTreehugger Robot      */
771*fd76c71bSTreehugger Robot 
stmt_prepare(String sql, Stmt stmt)772*fd76c71bSTreehugger Robot     private native void stmt_prepare(String sql, Stmt stmt)
773*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
774*fd76c71bSTreehugger Robot 
775*fd76c71bSTreehugger Robot     /**
776*fd76c71bSTreehugger Robot      * Internal SQLite open blob method.
777*fd76c71bSTreehugger Robot      * @param db database name
778*fd76c71bSTreehugger Robot      * @param table table name
779*fd76c71bSTreehugger Robot      * @param column column name
780*fd76c71bSTreehugger Robot      * @param row row identifier
781*fd76c71bSTreehugger Robot      * @param rw if true, open for read-write, else read-only
782*fd76c71bSTreehugger Robot      * @param blob Blob object
783*fd76c71bSTreehugger Robot      */
784*fd76c71bSTreehugger Robot 
_open_blob(String db, String table, String column, long row, boolean rw, Blob blob)785*fd76c71bSTreehugger Robot     private native void _open_blob(String db, String table, String column,
786*fd76c71bSTreehugger Robot 				   long row, boolean rw, Blob blob)
787*fd76c71bSTreehugger Robot 	throws SQLite.Exception;
788*fd76c71bSTreehugger Robot 
789*fd76c71bSTreehugger Robot     /**
790*fd76c71bSTreehugger Robot      * Establish a progress callback method which gets called after
791*fd76c71bSTreehugger Robot      * N SQLite VM opcodes.
792*fd76c71bSTreehugger Robot      *
793*fd76c71bSTreehugger Robot      * @param n number of SQLite VM opcodes until callback is invoked
794*fd76c71bSTreehugger Robot      * @param p the object implementing the progress callback method
795*fd76c71bSTreehugger Robot      */
796*fd76c71bSTreehugger Robot 
progress_handler(int n, SQLite.ProgressHandler p)797*fd76c71bSTreehugger Robot     public void progress_handler(int n, SQLite.ProgressHandler p) {
798*fd76c71bSTreehugger Robot 	synchronized(this) {
799*fd76c71bSTreehugger Robot 	    _progress_handler(n, p);
800*fd76c71bSTreehugger Robot 	}
801*fd76c71bSTreehugger Robot     }
802*fd76c71bSTreehugger Robot 
_progress_handler(int n, SQLite.ProgressHandler p)803*fd76c71bSTreehugger Robot     private native void _progress_handler(int n, SQLite.ProgressHandler p);
804*fd76c71bSTreehugger Robot 
805*fd76c71bSTreehugger Robot     /**
806*fd76c71bSTreehugger Robot      * Specify key for encrypted database. To be called
807*fd76c71bSTreehugger Robot      * right after open() on SQLite3 databases.
808*fd76c71bSTreehugger Robot      * Not available in public releases of SQLite.
809*fd76c71bSTreehugger Robot      *
810*fd76c71bSTreehugger Robot      * @param ekey the key as byte array
811*fd76c71bSTreehugger Robot      */
812*fd76c71bSTreehugger Robot 
key(byte[] ekey)813*fd76c71bSTreehugger Robot     public void key(byte[] ekey) throws SQLite.Exception {
814*fd76c71bSTreehugger Robot 	synchronized(this) {
815*fd76c71bSTreehugger Robot 	    _key(ekey);
816*fd76c71bSTreehugger Robot 	}
817*fd76c71bSTreehugger Robot     }
818*fd76c71bSTreehugger Robot 
819*fd76c71bSTreehugger Robot     /**
820*fd76c71bSTreehugger Robot      * Specify key for encrypted database. To be called
821*fd76c71bSTreehugger Robot      * right after open() on SQLite3 databases.
822*fd76c71bSTreehugger Robot      * Not available in public releases of SQLite.
823*fd76c71bSTreehugger Robot      *
824*fd76c71bSTreehugger Robot      * @param skey the key as String
825*fd76c71bSTreehugger Robot      */
826*fd76c71bSTreehugger Robot 
key(String skey)827*fd76c71bSTreehugger Robot     public void key(String skey) throws SQLite.Exception {
828*fd76c71bSTreehugger Robot 	synchronized(this) {
829*fd76c71bSTreehugger Robot 	    byte ekey[] = null;
830*fd76c71bSTreehugger Robot 	    if (skey != null && skey.length() > 0) {
831*fd76c71bSTreehugger Robot 		ekey = new byte[skey.length()];
832*fd76c71bSTreehugger Robot 		for (int i = 0; i< skey.length(); i++) {
833*fd76c71bSTreehugger Robot 		    char c = skey.charAt(i);
834*fd76c71bSTreehugger Robot 		    ekey[i] = (byte) ((c & 0xff) ^ (c >> 8));
835*fd76c71bSTreehugger Robot 		}
836*fd76c71bSTreehugger Robot 	    }
837*fd76c71bSTreehugger Robot 	    _key(ekey);
838*fd76c71bSTreehugger Robot 	}
839*fd76c71bSTreehugger Robot     }
840*fd76c71bSTreehugger Robot 
_key(byte[] ekey)841*fd76c71bSTreehugger Robot     private native void _key(byte[] ekey);
842*fd76c71bSTreehugger Robot 
843*fd76c71bSTreehugger Robot     /**
844*fd76c71bSTreehugger Robot      * Change the key of a encrypted database. The
845*fd76c71bSTreehugger Robot      * SQLite3 database must have been open()ed.
846*fd76c71bSTreehugger Robot      * Not available in public releases of SQLite.
847*fd76c71bSTreehugger Robot      *
848*fd76c71bSTreehugger Robot      * @param ekey the key as byte array
849*fd76c71bSTreehugger Robot      */
850*fd76c71bSTreehugger Robot 
rekey(byte[] ekey)851*fd76c71bSTreehugger Robot     public void rekey(byte[] ekey) throws SQLite.Exception {
852*fd76c71bSTreehugger Robot 	synchronized(this) {
853*fd76c71bSTreehugger Robot 	    _rekey(ekey);
854*fd76c71bSTreehugger Robot 	}
855*fd76c71bSTreehugger Robot     }
856*fd76c71bSTreehugger Robot 
857*fd76c71bSTreehugger Robot     /**
858*fd76c71bSTreehugger Robot      * Change the key of a encrypted database. The
859*fd76c71bSTreehugger Robot      * SQLite3 database must have been open()ed.
860*fd76c71bSTreehugger Robot      * Not available in public releases of SQLite.
861*fd76c71bSTreehugger Robot      *
862*fd76c71bSTreehugger Robot      * @param skey the key as String
863*fd76c71bSTreehugger Robot      */
864*fd76c71bSTreehugger Robot 
rekey(String skey)865*fd76c71bSTreehugger Robot     public void rekey(String skey) throws SQLite.Exception {
866*fd76c71bSTreehugger Robot 	synchronized(this) {
867*fd76c71bSTreehugger Robot 	    byte ekey[] = null;
868*fd76c71bSTreehugger Robot 	    if (skey != null && skey.length() > 0) {
869*fd76c71bSTreehugger Robot 		ekey = new byte[skey.length()];
870*fd76c71bSTreehugger Robot 		for (int i = 0; i< skey.length(); i++) {
871*fd76c71bSTreehugger Robot 		    char c = skey.charAt(i);
872*fd76c71bSTreehugger Robot 		    ekey[i] = (byte) ((c & 0xff) ^ (c >> 8));
873*fd76c71bSTreehugger Robot 		}
874*fd76c71bSTreehugger Robot 	    }
875*fd76c71bSTreehugger Robot 	    _rekey(ekey);
876*fd76c71bSTreehugger Robot 	}
877*fd76c71bSTreehugger Robot     }
878*fd76c71bSTreehugger Robot 
_rekey(byte[] ekey)879*fd76c71bSTreehugger Robot     private native void _rekey(byte[] ekey);
880*fd76c71bSTreehugger Robot 
881*fd76c71bSTreehugger Robot     /**
882*fd76c71bSTreehugger Robot      * Enable/disable shared cache mode (SQLite 3.x only).
883*fd76c71bSTreehugger Robot      *
884*fd76c71bSTreehugger Robot      * @param onoff boolean to enable or disable shared cache
885*fd76c71bSTreehugger Robot      * @return boolean when true, function supported/succeeded
886*fd76c71bSTreehugger Robot      */
887*fd76c71bSTreehugger Robot 
_enable_shared_cache(boolean onoff)888*fd76c71bSTreehugger Robot     protected static native boolean _enable_shared_cache(boolean onoff);
889*fd76c71bSTreehugger Robot 
890*fd76c71bSTreehugger Robot     /**
891*fd76c71bSTreehugger Robot      * Internal native initializer.
892*fd76c71bSTreehugger Robot      */
893*fd76c71bSTreehugger Robot 
internal_init()894*fd76c71bSTreehugger Robot     private static native void internal_init();
895*fd76c71bSTreehugger Robot 
896*fd76c71bSTreehugger Robot     /**
897*fd76c71bSTreehugger Robot      * Make long value from julian date for java.lang.Date
898*fd76c71bSTreehugger Robot      *
899*fd76c71bSTreehugger Robot      * @param d double value (julian date in SQLite3 format)
900*fd76c71bSTreehugger Robot      * @return long
901*fd76c71bSTreehugger Robot      */
902*fd76c71bSTreehugger Robot 
long_from_julian(double d)903*fd76c71bSTreehugger Robot     public static long long_from_julian(double d) {
904*fd76c71bSTreehugger Robot 	d -= 2440587.5;
905*fd76c71bSTreehugger Robot 	d *= 86400000.0;
906*fd76c71bSTreehugger Robot 	return (long) d;
907*fd76c71bSTreehugger Robot     }
908*fd76c71bSTreehugger Robot 
909*fd76c71bSTreehugger Robot     /**
910*fd76c71bSTreehugger Robot      * Make long value from julian date for java.lang.Date
911*fd76c71bSTreehugger Robot      *
912*fd76c71bSTreehugger Robot      * @param s string (double value) (julian date in SQLite3 format)
913*fd76c71bSTreehugger Robot      * @return long
914*fd76c71bSTreehugger Robot      */
915*fd76c71bSTreehugger Robot 
long_from_julian(String s)916*fd76c71bSTreehugger Robot     public static long long_from_julian(String s) throws SQLite.Exception {
917*fd76c71bSTreehugger Robot 	try {
918*fd76c71bSTreehugger Robot 	    double d = Double.parseDouble(s); // android-changed: performance
919*fd76c71bSTreehugger Robot 	    return long_from_julian(d);
920*fd76c71bSTreehugger Robot 	} catch (java.lang.Exception ee) {
921*fd76c71bSTreehugger Robot 	    throw new SQLite.Exception("not a julian date");
922*fd76c71bSTreehugger Robot 	}
923*fd76c71bSTreehugger Robot     }
924*fd76c71bSTreehugger Robot 
925*fd76c71bSTreehugger Robot     /**
926*fd76c71bSTreehugger Robot      * Make julian date value from java.lang.Date
927*fd76c71bSTreehugger Robot      *
928*fd76c71bSTreehugger Robot      * @param ms millisecond value of java.lang.Date
929*fd76c71bSTreehugger Robot      * @return double
930*fd76c71bSTreehugger Robot      */
931*fd76c71bSTreehugger Robot 
julian_from_long(long ms)932*fd76c71bSTreehugger Robot     public static double julian_from_long(long ms) {
933*fd76c71bSTreehugger Robot 	double adj = (ms < 0) ? 0 : 0.5;
934*fd76c71bSTreehugger Robot 	double d = (ms + adj) / 86400000.0 + 2440587.5;
935*fd76c71bSTreehugger Robot 	return d;
936*fd76c71bSTreehugger Robot     }
937*fd76c71bSTreehugger Robot 
938*fd76c71bSTreehugger Robot     /**
939*fd76c71bSTreehugger Robot      * Static initializer to load the native part.
940*fd76c71bSTreehugger Robot      */
941*fd76c71bSTreehugger Robot 
942*fd76c71bSTreehugger Robot     static {
943*fd76c71bSTreehugger Robot 	try {
944*fd76c71bSTreehugger Robot 	    String path = System.getProperty("SQLite.library.path");
945*fd76c71bSTreehugger Robot 	    if (path == null || path.length() == 0) {
946*fd76c71bSTreehugger Robot 		System.loadLibrary("sqlite_jni");
947*fd76c71bSTreehugger Robot 	    } else {
948*fd76c71bSTreehugger Robot 		try {
949*fd76c71bSTreehugger Robot 		    java.lang.reflect.Method mapLibraryName;
950*fd76c71bSTreehugger Robot 		    Class param[] = new Class[1];
951*fd76c71bSTreehugger Robot 		    param[0] = String.class;
952*fd76c71bSTreehugger Robot 		    mapLibraryName = System.class.getMethod("mapLibraryName",
953*fd76c71bSTreehugger Robot 							    param);
954*fd76c71bSTreehugger Robot 		    Object args[] = new Object[1];
955*fd76c71bSTreehugger Robot 		    args[0] = "sqlite_jni";
956*fd76c71bSTreehugger Robot 		    String mapped = (String) mapLibraryName.invoke(null, args);
957*fd76c71bSTreehugger Robot 		    System.load(path + java.io.File.separator + mapped);
958*fd76c71bSTreehugger Robot 		} catch (Throwable t) {
959*fd76c71bSTreehugger Robot 		    System.err.println("Unable to load sqlite_jni from" +
960*fd76c71bSTreehugger Robot 				       "SQLite.library.path=" + path +
961*fd76c71bSTreehugger Robot 				       ", trying system default: " + t);
962*fd76c71bSTreehugger Robot 		    System.loadLibrary("sqlite_jni");
963*fd76c71bSTreehugger Robot 		}
964*fd76c71bSTreehugger Robot 	    }
965*fd76c71bSTreehugger Robot 	} catch (Throwable t) {
966*fd76c71bSTreehugger Robot 	    System.err.println("Unable to load sqlite_jni: " + t);
967*fd76c71bSTreehugger Robot 	}
968*fd76c71bSTreehugger Robot 	/*
969*fd76c71bSTreehugger Robot 	 * Call native initializer functions now, since the
970*fd76c71bSTreehugger Robot 	 * native part could have been linked statically, i.e.
971*fd76c71bSTreehugger Robot 	 * the try/catch above would have failed in that case.
972*fd76c71bSTreehugger Robot 	 */
973*fd76c71bSTreehugger Robot 	try {
internal_init()974*fd76c71bSTreehugger Robot 	    internal_init();
FunctionContext()975*fd76c71bSTreehugger Robot 	    new FunctionContext();
976*fd76c71bSTreehugger Robot 	} catch (java.lang.Exception e) {
977*fd76c71bSTreehugger Robot 	}
978*fd76c71bSTreehugger Robot     }
979*fd76c71bSTreehugger Robot }
980*fd76c71bSTreehugger Robot 
981