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