1package SQLite;
2
3/**
4 * Main class wrapping an SQLite database.
5 */
6
7public 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
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
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
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
111    private native void _open(String filename, int mode)
112	throws SQLite.Exception;
113
114    /*
115     * Newer full interface
116     */
117
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
129    public void open_aux_file(String filename) throws SQLite.Exception {
130	synchronized(this) {
131	    _open_aux_file(filename);
132	}
133    }
134
135    private native void _open_aux_file(String filename)
136	throws SQLite.Exception;
137
138    /**
139     * Destructor for object.
140     */
141
142    protected void finalize() {
143	synchronized(this) {
144	    _finalize();
145	}
146    }
147
148    private native void _finalize();
149
150    /**
151     * Close the underlying SQLite database file.
152     */
153
154    public void close()	throws SQLite.Exception {
155	synchronized(this) {
156	    _close();
157	}
158    }
159
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
175    public void exec(String sql, SQLite.Callback cb) throws SQLite.Exception {
176	synchronized(this) {
177	    _exec(sql, cb);
178	}
179    }
180
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
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
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
222    public long last_insert_rowid() {
223	synchronized(this) {
224	    return _last_insert_rowid();
225	}
226    }
227
228    private native long _last_insert_rowid();
229
230    /**
231     * Abort the current SQLite operation.
232     */
233
234    public void interrupt() {
235	synchronized(this) {
236	    _interrupt();
237	}
238    }
239
240    private native void _interrupt();
241
242    /**
243     * Return the number of changed rows for the last statement.
244     */
245
246    public long changes() {
247	synchronized(this) {
248	    return _changes();
249	}
250    }
251
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
261    public void busy_handler(SQLite.BusyHandler bh) {
262	synchronized(this) {
263	    _busy_handler(bh);
264	}
265    }
266
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
276    public void busy_timeout(int ms) {
277	synchronized(this) {
278	    _busy_timeout(ms);
279	}
280    }
281
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
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
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
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
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
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
437    public synchronized static boolean complete(String sql) {
438	return _complete(sql);
439    }
440
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
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
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
466    public void create_function(String name, int nargs, Function f) {
467	synchronized(this) {
468	    _create_function(name, nargs, f);
469	}
470    }
471
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
482    public void create_aggregate(String name, int nargs, Function f) {
483	synchronized(this) {
484	    _create_aggregate(name, nargs, f);
485	}
486    }
487
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
498    public void function_type(String name, int type) {
499	synchronized(this) {
500	    _function_type(name, type);
501	}
502    }
503
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
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
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
535    public String error_message() {
536	synchronized(this) {
537	    return _errmsg();
538	}
539    }
540
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
550    public static native String error_string(int error_code);
551
552    /**
553     * Set character encoding.
554     * @param enc name of encoding
555     */
556
557    public void set_encoding(String enc) throws SQLite.Exception {
558	synchronized(this) {
559	    _set_encoding(enc);
560	}
561    }
562
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
573    public void set_authorizer(Authorizer auth) {
574	synchronized(this) {
575	    _set_authorizer(auth);
576	}
577    }
578
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
588    public void trace(Trace tr) {
589	synchronized(this) {
590	    _trace(tr);
591	}
592    }
593
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
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
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
626    public void profile(Profile pr) {
627	synchronized(this) {
628	    _profile(pr);
629	}
630    }
631
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
646    public synchronized static int status(int op, int info[], boolean flag) {
647	return _status(op, info, flag);
648    }
649
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
664    public int db_status(int op, int info[], boolean flag) {
665	synchronized(this) {
666	    return _db_status(op, info, flag);
667	}
668    }
669
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
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
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
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
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
745    public native boolean is3();
746
747    /**
748     * Internal compile method.
749     * @param sql SQL statement
750     * @param vm Vm object
751     */
752
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
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
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
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
797    public void progress_handler(int n, SQLite.ProgressHandler p) {
798	synchronized(this) {
799	    _progress_handler(n, p);
800	}
801    }
802
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
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
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
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
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
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
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
888    protected static native boolean _enable_shared_cache(boolean onoff);
889
890    /**
891     * Internal native initializer.
892     */
893
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
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
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
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 {
974	    internal_init();
975	    new FunctionContext();
976	} catch (java.lang.Exception e) {
977	}
978    }
979}
980
981