Home | History | Annotate | Download | only in SQLite
      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 
     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