diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:28:47 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:28:47 -0800 |
commit | adc854b798c1cfe3bfd4c27d68d5cee38ca617da (patch) | |
tree | 6aed8b4923ca428942cbaa7e848d50237a3d31e0 /sql/src/main/java | |
parent | 1c0fed63c71ddb230f3b304aac12caffbedf2f21 (diff) | |
download | libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.zip libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.tar.gz libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'sql/src/main/java')
69 files changed, 23448 insertions, 0 deletions
diff --git a/sql/src/main/java/SQLite/Authorizer.java b/sql/src/main/java/SQLite/Authorizer.java new file mode 100644 index 0000000..cdc321d --- /dev/null +++ b/sql/src/main/java/SQLite/Authorizer.java @@ -0,0 +1,25 @@ +package SQLite; + +/** + * Callback interface for SQLite's authorizer function. + */ + +public interface Authorizer { + + /** + * Callback to authorize access. + * + * @param what integer indicating type of access + * @param arg1 first argument (table, view, index, or trigger name) + * @param arg2 second argument (file, table, or column name) + * @param arg3 third argument (database name) + * @param arg4 third argument (trigger name) + * @return Constants.SQLITE_OK for success, Constants.SQLITE_IGNORE + * for don't allow access but don't raise an error, Constants.SQLITE_DENY + * for abort SQL statement with error. + */ + + public int authorize(int what, String arg1, String arg2, String arg3, + String arg4); +} + diff --git a/sql/src/main/java/SQLite/Blob.java b/sql/src/main/java/SQLite/Blob.java new file mode 100644 index 0000000..3de9f8a --- /dev/null +++ b/sql/src/main/java/SQLite/Blob.java @@ -0,0 +1,323 @@ +package SQLite; + +import java.io.*; + +/** + * Internal class implementing java.io.InputStream on + * SQLite 3.4.0 incremental blob I/O interface. + */ + +class BlobR extends InputStream { + + /** + * Blob instance + */ + + private Blob blob; + + /** + * Read position, file pointer. + */ + + private int pos; + + /** + * Contruct InputStream from blob instance. + */ + + BlobR(Blob blob) { + this.blob = blob; + this.pos = 0; + } + + /** + * Return number of available bytes for reading. + * @return available input bytes + */ + + public int available() throws IOException { + int ret = blob.size - pos; + return (ret < 0) ? 0 : ret; + } + + /** + * Mark method; dummy to satisfy InputStream class. + */ + + public void mark(int limit) { + } + + /** + * Reset method; dummy to satisfy InputStream class. + */ + + public void reset() throws IOException { + } + + /** + * Mark support; not for this class. + * @return always false + */ + + public boolean markSupported() { + return false; + } + + /** + * Close this blob InputStream. + */ + + public void close() throws IOException { + blob.close(); + blob = null; + pos = 0; + } + + /** + * Skip over blob data. + */ + + public long skip(long n) throws IOException { + long ret = pos + n; + if (ret < 0) { + ret = 0; + pos = 0; + } else if (ret > blob.size) { + ret = blob.size; + pos = blob.size; + } else { + pos = (int) ret; + } + return ret; + } + + /** + * Read single byte from blob. + * @return byte read + */ + + public int read() throws IOException { + byte b[] = new byte[1]; + int n = blob.read(b, 0, pos, b.length); + if (n > 0) { + pos += n; + return b[0]; + } + return -1; + } + + /** + * Read byte array from blob. + * @param b byte array to be filled + * @return number of bytes read + */ + + public int read(byte b[]) throws IOException { + int n = blob.read(b, 0, pos, b.length); + if (n > 0) { + pos += n; + return n; + } + return -1; + } + + /** + * Read slice of byte array from blob. + * @param b byte array to be filled + * @param off offset into byte array + * @param len length to be read + * @return number of bytes read + */ + + public int read(byte b[], int off, int len) throws IOException { + if (off + len > b.length) { + len = b.length - off; + } + if (len < 0) { + return -1; + } + if (len == 0) { + return 0; + } + int n = blob.read(b, off, pos, len); + if (n > 0) { + pos += n; + return n; + } + return -1; + } +} + +/** + * Internal class implementing java.io.OutputStream on + * SQLite 3.4.0 incremental blob I/O interface. + */ + +class BlobW extends OutputStream { + + /** + * Blob instance + */ + + private Blob blob; + + /** + * Read position, file pointer. + */ + + private int pos; + + /** + * Contruct OutputStream from blob instance. + */ + + BlobW(Blob blob) { + this.blob = blob; + this.pos = 0; + } + + /** + * Flush blob; dummy to satisfy OutputStream class. + */ + + public void flush() throws IOException { + } + + /** + * Close this blob OutputStream. + */ + + public void close() throws IOException { + blob.close(); + blob = null; + pos = 0; + } + + /** + * Write blob data. + * @param v byte to be written at current position. + */ + + public void write(int v) throws IOException { + byte b[] = new byte[1]; + b[0] = (byte) v; + pos += blob.write(b, 0, pos, 1); + } + + /** + * Write blob data. + * @param b byte array to be written at current position. + */ + + public void write(byte[] b) throws IOException { + if (b != null && b.length > 0) { + pos += blob.write(b, 0, pos, b.length); + } + } + + /** + * Write blob data. + * @param b byte array to be written. + * @param off offset within byte array + * @param len length of data to be written + */ + + public void write(byte[] b, int off, int len) throws IOException { + if (b != null) { + if (off + len > b.length) { + len = b.length - off; + } + if (len <= 0) { + return; + } + pos += blob.write(b, off, pos, len); + } + } +} + +/** + * Class to represent SQLite3 3.4.0 incremental blob I/O interface. + * + * Note, that all native methods of this class are + * not synchronized, i.e. it is up to the caller + * to ensure that only one thread is in these + * methods at any one time. + */ + +public class Blob { + + /** + * Internal handle for the SQLite3 blob. + */ + + private long handle = 0; + + /** + * Cached size of blob, setup right after blob + * has been opened. + */ + + protected int size = 0; + + /** + * Return InputStream for this blob + * @return InputStream + */ + + public InputStream getInputStream() { + return (InputStream) new BlobR(this); + } + + /** + * Return OutputStream for this blob + * @return OutputStream + */ + + public OutputStream getOutputStream() { + return (OutputStream) new BlobW(this); + } + + /** + * Close blob. + */ + + public native void close(); + + /** + * Internal blob write method. + * @param b byte array to be written + * @param off offset into byte array + * @param pos offset into blob + * @param len length to be written + * @return number of bytes written to blob + */ + + native int write(byte[] b, int off, int pos, int len) throws IOException; + + /** + * Internal blob read method. + * @param b byte array to be written + * @param off offset into byte array + * @param pos offset into blob + * @param len length to be written + * @return number of bytes written to blob + */ + + native int read(byte[] b, int off, int pos, int len) throws IOException; + + /** + * Destructor for object. + */ + + protected native void finalize(); + + /** + * Internal native initializer. + */ + + private static native void internal_init(); + + static { + internal_init(); + } +} diff --git a/sql/src/main/java/SQLite/BusyHandler.java b/sql/src/main/java/SQLite/BusyHandler.java new file mode 100644 index 0000000..c39b39d --- /dev/null +++ b/sql/src/main/java/SQLite/BusyHandler.java @@ -0,0 +1,20 @@ +package SQLite; + +/** + * Callback interface for SQLite's user defined busy handler. + */ + +public interface BusyHandler { + + /** + * Invoked when a table is locked by another process + * or thread. The method should return true for waiting + * until the table becomes unlocked, or false in order + * to abandon the action.<BR><BR> + * + * @param table the name of the locked table + * @param count number of times the table was locked + */ + + public boolean busy(String table, int count); +} diff --git a/sql/src/main/java/SQLite/Callback.java b/sql/src/main/java/SQLite/Callback.java new file mode 100644 index 0000000..3eeb605 --- /dev/null +++ b/sql/src/main/java/SQLite/Callback.java @@ -0,0 +1,68 @@ +package SQLite; + +/** + * Callback interface for SQLite's query results. + * <BR><BR> + * Example:<BR> + * + * <PRE> + * class TableFmt implements SQLite.Callback { + * public void columns(String cols[]) { + * System.out.println("<TH><TR>"); + * for (int i = 0; i < cols.length; i++) { + * System.out.println("<TD>" + cols[i] + "</TD>"); + * } + * System.out.println("</TR></TH>"); + * } + * public boolean newrow(String cols[]) { + * System.out.println("<TR>"); + * for (int i = 0; i < cols.length; i++) { + * System.out.println("<TD>" + cols[i] + "</TD>"); + * } + * System.out.println("</TR>"); + * return false; + * } + * } + * ... + * SQLite.Database db = new SQLite.Database(); + * db.open("db", 0); + * System.out.println("<TABLE>"); + * db.exec("select * from TEST", new TableFmt()); + * System.out.println("</TABLE>"); + * ... + * </PRE> + */ + +public interface Callback { + + /** + * Reports column names of the query result. + * This method is invoked first (and once) when + * the SQLite engine returns the result set.<BR><BR> + * + * @param coldata string array holding the column names + */ + + public void columns(String coldata[]); + + /** + * Reports type names of the columns of the query result. + * This is available from SQLite 2.6.0 on and needs + * the PRAGMA show_datatypes to be turned on.<BR><BR> + * + * @param types string array holding column types + */ + + public void types(String types[]); + + /** + * Reports row data of the query result. + * This method is invoked for each row of the + * result set. If true is returned the running + * SQLite query is aborted.<BR><BR> + * + * @param rowdata string array holding the column values of the row + */ + + public boolean newrow(String rowdata[]); +} diff --git a/sql/src/main/java/SQLite/Constants.java b/sql/src/main/java/SQLite/Constants.java new file mode 100644 index 0000000..4e636b9 --- /dev/null +++ b/sql/src/main/java/SQLite/Constants.java @@ -0,0 +1,157 @@ +/* DO NOT EDIT */ + +package SQLite; + +/** + * Container for SQLite constants. + */ + +public final class Constants { + /* + * Error code: 0 + */ + public static final int SQLITE_OK = 0; + /* + * Error code: 1 + */ + public static final int SQLITE_ERROR = 1; + /* + * Error code: 2 + */ + public static final int SQLITE_INTERNAL = 2; + /* + * Error code: 3 + */ + public static final int SQLITE_PERM = 3; + /* + * Error code: 4 + */ + public static final int SQLITE_ABORT = 4; + /* + * Error code: 5 + */ + public static final int SQLITE_BUSY = 5; + /* + * Error code: 6 + */ + public static final int SQLITE_LOCKED = 6; + /* + * Error code: 7 + */ + public static final int SQLITE_NOMEM = 7; + /* + * Error code: 8 + */ + public static final int SQLITE_READONLY = 8; + /* + * Error code: 9 + */ + public static final int SQLITE_INTERRUPT = 9; + /* + * Error code: 10 + */ + public static final int SQLITE_IOERR = 10; + /* + * Error code: 11 + */ + public static final int SQLITE_CORRUPT = 11; + /* + * Error code: 12 + */ + public static final int SQLITE_NOTFOUND = 12; + /* + * Error code: 13 + */ + public static final int SQLITE_FULL = 13; + /* + * Error code: 14 + */ + public static final int SQLITE_CANTOPEN = 14; + /* + * Error code: 15 + */ + public static final int SQLITE_PROTOCOL = 15; + /* + * Error code: 16 + */ + public static final int SQLITE_EMPTY = 16; + /* + * Error code: 17 + */ + public static final int SQLITE_SCHEMA = 17; + /* + * Error code: 18 + */ + public static final int SQLITE_TOOBIG = 18; + /* + * Error code: 19 + */ + public static final int SQLITE_CONSTRAINT = 19; + /* + * Error code: 20 + */ + public static final int SQLITE_MISMATCH = 20; + /* + * Error code: 21 + */ + public static final int SQLITE_MISUSE = 21; + /* + * Error code: 22 + */ + public static final int SQLITE_NOLFS = 22; + /* + * Error code: 23 + */ + public static final int SQLITE_AUTH = 23; + /* + * Error code: 24 + */ + public static final int SQLITE_FORMAT = 24; + /* + * Error code: 25 + */ + public static final int SQLITE_RANGE = 25; + /* + * Error code: 26 + */ + public static final int SQLITE_NOTADB = 26; + public static final int SQLITE_ROW = 100; + public static final int SQLITE_DONE = 101; + public static final int SQLITE_INTEGER = 1; + public static final int SQLITE_FLOAT = 2; + public static final int SQLITE_BLOB = 4; + public static final int SQLITE_NULL = 5; + public static final int SQLITE3_TEXT = 3; + public static final int SQLITE_NUMERIC = -1; + public static final int SQLITE_TEXT = 3; + public static final int SQLITE2_TEXT = -2; + public static final int SQLITE_ARGS = -3; + public static final int SQLITE_COPY = 0; + public static final int SQLITE_CREATE_INDEX = 1; + public static final int SQLITE_CREATE_TABLE = 2; + public static final int SQLITE_CREATE_TEMP_INDEX = 3; + public static final int SQLITE_CREATE_TEMP_TABLE = 4; + public static final int SQLITE_CREATE_TEMP_TRIGGER = 5; + public static final int SQLITE_CREATE_TEMP_VIEW = 6; + public static final int SQLITE_CREATE_TRIGGER = 7; + public static final int SQLITE_CREATE_VIEW = 8; + public static final int SQLITE_DELETE = 9; + public static final int SQLITE_DROP_INDEX = 10; + public static final int SQLITE_DROP_TABLE = 11; + public static final int SQLITE_DROP_TEMP_INDEX = 12; + public static final int SQLITE_DROP_TEMP_TABLE = 13; + public static final int SQLITE_DROP_TEMP_TRIGGER = 14; + public static final int SQLITE_DROP_TEMP_VIEW = 15; + public static final int SQLITE_DROP_TRIGGER = 16; + public static final int SQLITE_DROP_VIEW = 17; + public static final int SQLITE_INSERT = 18; + public static final int SQLITE_PRAGMA = 19; + public static final int SQLITE_READ = 20; + public static final int SQLITE_SELECT = 21; + public static final int SQLITE_TRANSACTION = 22; + public static final int SQLITE_UPDATE = 23; + public static final int SQLITE_ATTACH = 24; + public static final int SQLITE_DETACH = 25; + public static final int SQLITE_DENY = 1; + public static final int SQLITE_IGNORE = 2; +} diff --git a/sql/src/main/java/SQLite/Database.java b/sql/src/main/java/SQLite/Database.java new file mode 100644 index 0000000..dcaaf9d --- /dev/null +++ b/sql/src/main/java/SQLite/Database.java @@ -0,0 +1,615 @@ +package SQLite; + +/** + * Main class wrapping an SQLite database. + */ + +public class Database { + + /** + * Internal handle for the native SQLite API. + */ + + protected long handle = 0; + + /** + * Internal last error code for exec() methods. + */ + + protected int error_code = 0; + + /** + * Open an SQLite database file. + * + * @param filename the name of the database file + * @param mode open mode, currently ignored + */ + + public void open(String filename, int mode) throws SQLite.Exception { + synchronized(this) { + _open(filename, mode); + } + } + + private native void _open(String filename, int mode) + throws SQLite.Exception; + + /** + * Open SQLite auxiliary database file for temporary + * tables. + * + * @param filename the name of the auxiliary file or null + */ + + public void open_aux_file(String filename) throws SQLite.Exception { + synchronized(this) { + _open_aux_file(filename); + } + } + + private native void _open_aux_file(String filename) + throws SQLite.Exception; + + /** + * Destructor for object. + */ + + protected void finalize() { + synchronized(this) { + _finalize(); + } + } + + private native void _finalize(); + + /** + * Close the underlying SQLite database file. + */ + + public void close() throws SQLite.Exception { + synchronized(this) { + _close(); + } + } + + private native void _close() + throws SQLite.Exception; + + /** + * Execute an SQL statement and invoke callback methods + * for each row of the result set.<P> + * + * It the method fails, an SQLite.Exception is thrown and + * an error code is set, which later can be retrieved by + * the last_error() method. + * + * @param sql the SQL statement to be executed + * @param cb the object implementing the callback methods + */ + + public void exec(String sql, SQLite.Callback cb) throws SQLite.Exception { + synchronized(this) { + _exec(sql, cb); + } + } + + private native void _exec(String sql, SQLite.Callback cb) + throws SQLite.Exception; + + /** + * Execute an SQL statement and invoke callback methods + * for each row of the result set. Each '%q' or %Q in the + * statement string is substituted by its corresponding + * element in the argument vector. + * <BR><BR> + * Example:<BR> + * <PRE> + * String args[] = new String[1]; + * args[0] = "tab%"; + * db.exec("select * from sqlite_master where type like '%q'", + * null, args); + * </PRE> + * + * It the method fails, an SQLite.Exception is thrown and + * an error code is set, which later can be retrieved by + * the last_error() method. + * + * @param sql the SQL statement to be executed + * @param cb the object implementing the callback methods + * @param args arguments for the SQL statement, '%q' substitution + */ + + public void exec(String sql, SQLite.Callback cb, + String args[]) throws SQLite.Exception { + synchronized(this) { + _exec(sql, cb, args); + } + } + + private native void _exec(String sql, SQLite.Callback cb, String args[]) + throws SQLite.Exception; + + /** + * Return the row identifier of the last inserted + * row. + */ + + public long last_insert_rowid() { + synchronized(this) { + return _last_insert_rowid(); + } + } + + private native long _last_insert_rowid(); + + /** + * Abort the current SQLite operation. + */ + + public void interrupt() { + synchronized(this) { + _interrupt(); + } + } + + private native void _interrupt(); + + /** + * Return the number of changed rows for the last statement. + */ + + public long changes() { + synchronized(this) { + return _changes(); + } + } + + private native long _changes(); + + /** + * Establish a busy callback method which gets called when + * an SQLite table is locked. + * + * @param bh the object implementing the busy callback method + */ + + public void busy_handler(SQLite.BusyHandler bh) { + synchronized(this) { + _busy_handler(bh); + } + } + + private native void _busy_handler(SQLite.BusyHandler bh); + + /** + * Set the timeout for waiting for an SQLite table to become + * unlocked. + * + * @param ms number of millisecond to wait + */ + + public void busy_timeout(int ms) { + synchronized(this) { + _busy_timeout(ms); + } + } + + private native void _busy_timeout(int ms); + + /** + * Convenience method to retrieve an entire result + * set into memory. + * + * @param sql the SQL statement to be executed + * @return result set + */ + + public TableResult get_table(String sql) throws SQLite.Exception { + TableResult ret = new TableResult(); + if (!is3()) { + exec(sql, ret); + } else { + synchronized(this) { + /* only one statement !!! */ + Vm vm = compile(sql); + set_last_error(vm.error_code); + while (vm.step(ret)) { + set_last_error(vm.error_code); + } + vm.finalize(); + } + } + return ret; + } + + /** + * Convenience method to retrieve an entire result + * set into memory. + * + * @param sql the SQL statement to be executed + * @param args arguments for the SQL statement, '%q' substitution + * @return result set + */ + + public TableResult get_table(String sql, String args[]) + throws SQLite.Exception { + TableResult ret = new TableResult(); + if (!is3()) { + exec(sql, ret, args); + } else { + synchronized(this) { + /* only one statement !!! */ + Vm vm = compile(sql, args); + set_last_error(vm.error_code); + while (vm.step(ret)) { + set_last_error(vm.error_code); + } + vm.finalize(); + } + } + return ret; + } + + /** + * Convenience method to retrieve an entire result + * set into memory. + * + * @param sql the SQL statement to be executed + * @param args arguments for the SQL statement, '%q' substitution + * @param tbl TableResult to receive result set + * @return result set + */ + + public void get_table(String sql, String args[], TableResult tbl) + throws SQLite.Exception { + tbl.clear(); + if (!is3()) { + exec(sql, tbl, args); + } else { + synchronized(this) { + /* only one statement !!! */ + Vm vm = compile(sql, args); + while (vm.step(tbl)) { + } + vm.finalize(); + } + } + } + + /** + * See if an SQL statement is complete. + * Returns true if the input string comprises + * one or more complete SQL statements. + * + * @param sql the SQL statement to be checked + */ + + public synchronized static boolean complete(String sql) { + return _complete(sql); + } + + private native static boolean _complete(String sql); + + /** + * Return SQLite version number as string. + * Don't rely on this when both SQLite 2 and 3 are compiled + * into the native part. Use the class method in this case. + */ + + public native static String version(); + + /** + * Return SQLite version number as string. + * If the database is not open, <tt>unknown</tt> is returned. + */ + + public native String dbversion(); + + /** + * Create regular function. + * + * @param name the name of the new function + * @param nargs number of arguments to function + * @param f interface of function + */ + + public void create_function(String name, int nargs, Function f) { + synchronized(this) { + _create_function(name, nargs, f); + } + } + + private native void _create_function(String name, int nargs, Function f); + + /** + * Create aggregate function. + * + * @param name the name of the new function + * @param nargs number of arguments to function + * @param f interface of function + */ + + public void create_aggregate(String name, int nargs, Function f) { + synchronized(this) { + _create_aggregate(name, nargs, f); + } + } + + private native void _create_aggregate(String name, int nargs, Function f); + + /** + * Set function return type. Only available in SQLite 2.6.0 and + * above, otherwise a no-op. + * + * @param name the name of the function whose return type is to be set + * @param type return type code, e.g. SQLite.Constants.SQLITE_NUMERIC + */ + + public void function_type(String name, int type) { + synchronized(this) { + _function_type(name, type); + } + } + + private native void _function_type(String name, int type); + + /** + * Return the code of the last error occured in + * any of the exec() methods. The value is valid + * after an Exception has been reported by one of + * these methods. See the <A HREF="Constants.html">Constants</A> + * class for possible values. + * + * @return SQLite error code + */ + + public int last_error() { + return error_code; + } + + /** + * Internal: set error code. + * @param error_code new error code + */ + + protected void set_last_error(int error_code) { + this.error_code = error_code; + } + + /** + * Return last error message of SQLite3 engine. + * + * @return error string or null + */ + + public String error_message() { + synchronized(this) { + return _errmsg(); + } + } + + private native String _errmsg(); + + /** + * Return error string given SQLite error code (SQLite2). + * + * @param error_code the error code + * @return error string + */ + + public static native String error_string(int error_code); + + /** + * Set character encoding. + * @param enc name of encoding + */ + + public void set_encoding(String enc) throws SQLite.Exception { + synchronized(this) { + _set_encoding(enc); + } + } + + private native void _set_encoding(String enc) + throws SQLite.Exception; + + /** + * Set authorizer function. Only available in SQLite 2.7.6 and + * above, otherwise a no-op. + * + * @param auth the authorizer function + */ + + public void set_authorizer(Authorizer auth) { + synchronized(this) { + _set_authorizer(auth); + } + } + + private native void _set_authorizer(Authorizer auth); + + /** + * Set trace function. Only available in SQLite 2.7.6 and above, + * otherwise a no-op. + * + * @param tr the trace function + */ + + public void trace(Trace tr) { + synchronized(this) { + _trace(tr); + } + } + + private native void _trace(Trace tr); + + /** + * Compile and return SQLite VM for SQL statement. Only available + * in SQLite 2.8.0 and above, otherwise a no-op. + * + * @param sql SQL statement to be compiled + * @return a Vm object + */ + + public Vm compile(String sql) throws SQLite.Exception { + synchronized(this) { + Vm vm = new Vm(); + vm_compile(sql, vm); + return vm; + } + } + + /** + * Compile and return SQLite VM for SQL statement. Only available + * in SQLite 3.0 and above, otherwise a no-op. + * + * @param sql SQL statement to be compiled + * @param args arguments for the SQL statement, '%q' substitution + * @return a Vm object + */ + + public Vm compile(String sql, String args[]) throws SQLite.Exception { + synchronized(this) { + Vm vm = new Vm(); + vm_compile_args(sql, vm, args); + return vm; + } + } + + /** + * Prepare and return SQLite3 statement for SQL. Only available + * in SQLite 3.0 and above, otherwise a no-op. + * + * @param sql SQL statement to be prepared + * @return a Stmt object + */ + + public Stmt prepare(String sql) throws SQLite.Exception { + synchronized(this) { + Stmt stmt = new Stmt(); + stmt_prepare(sql, stmt); + return stmt; + } + } + + /** + * Open an SQLite3 blob. Only available in SQLite 3.4.0 and above. + * @param db database name + * @param table table name + * @param column column name + * @param row row identifier + * @param rw if true, open for read-write, else read-only + * @return a Blob object + */ + + public Blob open_blob(String db, String table, String column, + long row, boolean rw) throws SQLite.Exception { + synchronized(this) { + Blob blob = new Blob(); + _open_blob(db, table, column, row, rw, blob); + return blob; + } + } + + /** + * Check type of open database. + * @return true if SQLite3 database + */ + + public native boolean is3(); + + /** + * Internal compile method. + * @param sql SQL statement + * @param vm Vm object + */ + + private native void vm_compile(String sql, Vm vm) + throws SQLite.Exception; + + /** + * Internal compile method, SQLite 3.0 only. + * @param sql SQL statement + * @param args arguments for the SQL statement, '%q' substitution + * @param vm Vm object + */ + + private native void vm_compile_args(String sql, Vm vm, String args[]) + throws SQLite.Exception; + + /** + * Internal SQLite3 prepare method. + * @param sql SQL statement + * @param stmt Stmt object + */ + + private native void stmt_prepare(String sql, Stmt stmt) + throws SQLite.Exception; + + /** + * Internal SQLite open blob method. + * @param db database name + * @param table table name + * @param column column name + * @param row row identifier + * @param rw if true, open for read-write, else read-only + * @param blob Blob object + */ + + private native void _open_blob(String db, String table, String column, + long row, boolean rw, Blob blob) + throws SQLite.Exception; + + /** + * Establish a progress callback method which gets called after + * N SQLite VM opcodes. + * + * @param n number of SQLite VM opcodes until callback is invoked + * @param p the object implementing the progress callback method + */ + + public void progress_handler(int n, SQLite.ProgressHandler p) { + synchronized(this) { + _progress_handler(n, p); + } + } + + private native void _progress_handler(int n, SQLite.ProgressHandler p); + + /** + * Internal native initializer. + */ + + private static native void internal_init(); + + /** + * Static initializer to load the native part. + */ + + static { + try { +// String path = System.getProperty("SQLite.library.path"); +// if (path == null || path.length() == 0){ +// System.loadLibrary("sqlite_jni"); +// } else { +// try { +// java.lang.reflect.Method mapLibraryName; +// Class param[] = new Class[1]; +// param[0] = String.class; +// mapLibraryName = System.class.getMethod("mapLibraryName", +// param); +// Object args[] = new Object[1]; +// args[0] = "sqlite_jni"; +// String mapped = (String) mapLibraryName.invoke(null, args); +// System.load(path + java.io.File.separator + mapped); +// } catch (Throwable t) { +// System.loadLibrary("sqlite_jni"); +// } +// } + internal_init(); + } catch (Throwable t) { + System.err.println("Unable to load sqlite: " + t); + } + } +} + diff --git a/sql/src/main/java/SQLite/Exception.java b/sql/src/main/java/SQLite/Exception.java new file mode 100644 index 0000000..cc26b99 --- /dev/null +++ b/sql/src/main/java/SQLite/Exception.java @@ -0,0 +1,18 @@ +package SQLite; + +/** + * Class for SQLite related exceptions. + */ + +public class Exception extends java.lang.Exception { + + /** + * Construct a new SQLite exception. + * + * @param string error message + */ + + public Exception(String string) { + super(string); + } +} diff --git a/sql/src/main/java/SQLite/Function.java b/sql/src/main/java/SQLite/Function.java new file mode 100644 index 0000000..5aa5e33 --- /dev/null +++ b/sql/src/main/java/SQLite/Function.java @@ -0,0 +1,59 @@ +package SQLite; + +/** + * Callback interface for SQLite's user defined functions. + * Each callback method receives a + * <A HREF="FunctionContext.html">FunctionContext</A> object + * which is used to set the function result or error code. + * <BR><BR> + * Example:<BR> + * + * <PRE> + * class SinFunc implements SQLite.Function { + * public void function(SQLite.FunctionContext fc, String args[]) { + * try { + * Double d = new Double(args[0]); + * fc.set_result(Math.sin(d.doubleValue())); + * } catch (Exception e) { + * fc.set_error("sin(" + args[0] + "):" + e); + * } + * } + * ... + * } + * SQLite.Database db = new SQLite.Database(); + * db.open("db", 0); + * db.create_function("sin", 1, SinFunc); + * ... + * db.exec("select sin(1.0) from test", null); + * </PRE> + */ + +public interface Function { + + /** + * Callback for regular function. + * + * @param fc function's context for reporting result + * @param args String array of arguments + */ + + public void function(FunctionContext fc, String args[]); + + /** + * Callback for one step in aggregate function. + * + * @param fc function's context for reporting result + * @param args String array of arguments + */ + + public void step(FunctionContext fc, String args[]); + + /** + * Callback for final step in aggregate function. + * + * @param fc function's context for reporting result + */ + + public void last_step(FunctionContext fc); + +} diff --git a/sql/src/main/java/SQLite/FunctionContext.java b/sql/src/main/java/SQLite/FunctionContext.java new file mode 100644 index 0000000..d0b5182 --- /dev/null +++ b/sql/src/main/java/SQLite/FunctionContext.java @@ -0,0 +1,82 @@ +package SQLite; + +/** + * Context for execution of SQLite's user defined functions. + * A reference to an instance of this class is passed to + * user defined functions. + */ + +public class FunctionContext { + + /** + * Internal handle for the native SQLite API. + */ + + private long handle = 0; + + /** + * Set function result from string. + * + * @param r result string + */ + + public native void set_result(String r); + + /** + * Set function result from integer. + * + * @param r result integer + */ + + public native void set_result(int r); + + /** + * Set function result from double. + * + * @param r result double + */ + + public native void set_result(double r); + + /** + * Set function result from error message. + * + * @param r result string (error message) + */ + + public native void set_error(String r); + + /** + * Set function result from byte array. + * Only provided by SQLite3 databases. + * + * @param r result byte array + */ + + public native void set_result(byte[] r); + + /** + * Set function result as empty blob given size. + * Only provided by SQLite3 databases. + * + * @param n size for empty blob + */ + + public native void set_result_zeroblob(int n); + + /** + * Retrieve number of rows for aggregate function. + */ + + public native int count(); + + /** + * Internal native initializer. + */ + + private static native void internal_init(); + + static { + internal_init(); + } +} diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCConnection.java b/sql/src/main/java/SQLite/JDBC2y/JDBCConnection.java new file mode 100644 index 0000000..20c98e3 --- /dev/null +++ b/sql/src/main/java/SQLite/JDBC2y/JDBCConnection.java @@ -0,0 +1,452 @@ +package SQLite.JDBC2y; + +import java.sql.*; +import java.util.*; + +public class JDBCConnection + implements java.sql.Connection, SQLite.BusyHandler { + + /** + * Open database. + */ + protected DatabaseX db; + + /** + * Database URL. + */ + protected String url; + + /** + * Character encoding. + */ + protected String enc; + + /** + * Autocommit flag, true means autocommit. + */ + protected boolean autocommit = true; + + /** + * In-transaction flag. + * Can be true only when autocommit false. + */ + protected boolean intrans = false; + + /** + * Timeout for Database.exec() + */ + protected int timeout = 1000000; + + /** + * File name of database. + */ + private String dbfile = null; + + /** + * Reference to meta data or null. + */ + private JDBCDatabaseMetaData meta = null; + + /** + * Base time value for timeout handling. + */ + private long t0; + + /** + * Database in readonly mode. + */ + private boolean readonly = false; + + + private boolean busy0(DatabaseX db, int count) { + if (count <= 1) { + t0 = System.currentTimeMillis(); + } + if (db != null) { + long t1 = System.currentTimeMillis(); + if (t1 - t0 > timeout) { + return false; + } + db.wait(100); + return true; + } + return false; + } + + public boolean busy(String table, int count) { + return busy0(db, count); + } + + protected boolean busy3(DatabaseX db, int count) { + if (count <= 1) { + t0 = System.currentTimeMillis(); + } + if (db != null) { + long t1 = System.currentTimeMillis(); + if (t1 - t0 > timeout) { + return false; + } + return true; + } + return false; + } + + private DatabaseX open(boolean readonly) throws SQLException { + DatabaseX db = null; + try { + db = new DatabaseX(); + db.open(dbfile, readonly ? 0444 : 0644); + db.set_encoding(enc); + } catch (SQLite.Exception e) { + throw new SQLException(e.toString()); + } + int loop = 0; + while (true) { + try { + db.exec("PRAGMA short_column_names = off;", null); + db.exec("PRAGMA full_column_names = on;", null); + db.exec("PRAGMA empty_result_callbacks = on;", null); + if (SQLite.Database.version().compareTo("2.6.0") >= 0) { + db.exec("PRAGMA show_datatypes = on;", null); + } + } catch (SQLite.Exception e) { + if (db.last_error() != SQLite.Constants.SQLITE_BUSY || + !busy0(db, ++loop)) { + try { + db.close(); + } catch (SQLite.Exception ee) { + } + throw new SQLException(e.toString()); + } + continue; + } + break; + } + return db; + } + + public JDBCConnection(String url, String enc) throws SQLException { + if (url.startsWith("sqlite:/")) { + dbfile = url.substring(8); + } else if (url.startsWith("jdbc:sqlite:/")) { + dbfile = url.substring(13); + } else { + throw new SQLException("unsupported url"); + } + this.url = url; + this.enc = enc; + try { + db = open(readonly); + db.busy_handler(this); + } catch (SQLException e) { + if (db != null) { + try { + db.close(); + } catch (SQLite.Exception ee) { + } + } + throw e; + } + } + + /* non-standard */ + public SQLite.Database getSQLiteDatabase() { + return (SQLite.Database) db; + } + + public Statement createStatement() { + JDBCStatement s = new JDBCStatement(this); + return s; + } + + public Statement createStatement(int resultSetType, + int resultSetConcurrency) + throws SQLException { + JDBCStatement s = new JDBCStatement(this); + return s; + } + + public DatabaseMetaData getMetaData() throws SQLException { + if (meta == null) { + meta = new JDBCDatabaseMetaData(this); + } + return meta; + } + + public void close() throws SQLException { + try { + rollback(); + } catch (SQLException e) { + /* ignored */ + } + intrans = false; + if (db != null) { + try { + db.close(); + db = null; + } catch (SQLite.Exception e) { + throw new SQLException(e.toString()); + } + } + } + + public boolean isClosed() throws SQLException { + return db == null; + } + + public boolean isReadOnly() throws SQLException { + return readonly; + } + + public void clearWarnings() throws SQLException { + } + + public void commit() throws SQLException { + if (db == null) { + throw new SQLException("stale connection"); + } + if (!intrans) { + return; + } + try { + db.exec("COMMIT", null); + intrans = false; + } catch (SQLite.Exception e) { + throw new SQLException(e.toString()); + } + } + + public boolean getAutoCommit() throws SQLException { + return autocommit; + } + + public String getCatalog() throws SQLException { + return null; + } + + public int getTransactionIsolation() throws SQLException { + return TRANSACTION_SERIALIZABLE; + } + + public SQLWarning getWarnings() throws SQLException { + return null; + } + + public String nativeSQL(String sql) throws SQLException { + throw new SQLException("not supported"); + } + + public CallableStatement prepareCall(String sql) throws SQLException { + throw new SQLException("not supported"); + } + + public CallableStatement prepareCall(String sql, int x, int y) + throws SQLException { + throw new SQLException("not supported"); + } + + public PreparedStatement prepareStatement(String sql) throws SQLException { + JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql); + return s; + } + + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency) + throws SQLException { + JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql); + return s; + } + + public void rollback() throws SQLException { + if (db == null) { + throw new SQLException("stale connection"); + } + if (!intrans) { + return; + } + try { + db.exec("ROLLBACK", null); + intrans = false; + } catch (SQLite.Exception e) { + throw new SQLException(e.toString()); + } + } + + public void setAutoCommit(boolean ac) throws SQLException { + if (ac && intrans && db != null) { + try { + db.exec("ROLLBACK", null); + } catch (SQLite.Exception e) { + throw new SQLException(e.toString()); + } + } + intrans = false; + autocommit = ac; + } + + public void setCatalog(String catalog) throws SQLException { + } + + public void setReadOnly(boolean ro) throws SQLException { + if (intrans) { + throw new SQLException("incomplete transaction"); + } + if (ro != readonly) { + DatabaseX db = null; + try { + db = open(ro); + this.db.close(); + this.db = db; + db = null; + readonly = ro; + } catch (SQLException e) { + throw e; + } catch (SQLite.Exception ee) { + if (db != null) { + try { + db.close(); + } catch (SQLite.Exception eee) { + } + } + throw new SQLException(ee.toString()); + } + } + } + + public void setTransactionIsolation(int level) throws SQLException { + if (level != TRANSACTION_SERIALIZABLE) { + throw new SQLException("not supported"); + } + } + + public java.util.Map<String, Class<?>> getTypeMap() throws SQLException { + throw new SQLException("not supported"); + } + + public void setTypeMap(java.util.Map map) throws SQLException { + throw new SQLException("not supported"); + } + + public int getHoldability() throws SQLException { + return ResultSet.HOLD_CURSORS_OVER_COMMIT; + } + + public void setHoldability(int holdability) throws SQLException { + if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT) { + return; + } + throw new SQLException("not supported"); + } + + public Savepoint setSavepoint() throws SQLException { + throw new SQLException("not supported"); + } + + public Savepoint setSavepoint(String name) throws SQLException { + throw new SQLException("not supported"); + } + + public void rollback(Savepoint x) throws SQLException { + throw new SQLException("not supported"); + } + + public void releaseSavepoint(Savepoint x) throws SQLException { + throw new SQLException("not supported"); + } + + public Statement createStatement(int resultSetType, + int resultSetConcurrency, + int resultSetHoldability) + throws SQLException { + if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) { + throw new SQLException("not supported"); + } + return createStatement(resultSetType, resultSetConcurrency); + } + + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency, + int resultSetHoldability) + throws SQLException { + if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) { + throw new SQLException("not supported"); + } + return prepareStatement(sql, resultSetType, resultSetConcurrency); + } + + public CallableStatement prepareCall(String sql, int x, int y, int z) + throws SQLException { + throw new SQLException("not supported"); + } + + public PreparedStatement prepareStatement(String sql, int autokeys) + throws SQLException { + if (autokeys != Statement.NO_GENERATED_KEYS) { + throw new SQLException("not supported"); + } + return prepareStatement(sql); + } + + public PreparedStatement prepareStatement(String sql, int colIndexes[]) + throws SQLException { + throw new SQLException("not supported"); + } + + public PreparedStatement prepareStatement(String sql, String columns[]) + throws SQLException { + throw new SQLException("not supported"); + } + +} + +class DatabaseX extends SQLite.Database { + + static Object lock = new Object(); + + public DatabaseX() { + super(); + } + + void wait(int ms) { + try { + synchronized (lock) { + lock.wait(ms); + } + } catch (java.lang.Exception e) { + } + } + + public void exec(String sql, SQLite.Callback cb) + throws SQLite.Exception { + super.exec(sql, cb); + synchronized (lock) { + lock.notifyAll(); + } + } + + public void exec(String sql, SQLite.Callback cb, String args[]) + throws SQLite.Exception { + super.exec(sql, cb, args); + synchronized (lock) { + lock.notifyAll(); + } + } + + public SQLite.TableResult get_table(String sql, String args[]) + throws SQLite.Exception { + SQLite.TableResult ret = super.get_table(sql, args); + synchronized (lock) { + lock.notifyAll(); + } + return ret; + } + + public void get_table(String sql, String args[], SQLite.TableResult tbl) + throws SQLite.Exception { + super.get_table(sql, args, tbl); + synchronized (lock) { + lock.notifyAll(); + } + } + +} diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java b/sql/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java new file mode 100644 index 0000000..8c14d1d --- /dev/null +++ b/sql/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java @@ -0,0 +1,1578 @@ +package SQLite.JDBC2y; + +import java.sql.*; +import java.util.Hashtable; + +public class JDBCDatabaseMetaData implements DatabaseMetaData { + + private JDBCConnection conn; + + public JDBCDatabaseMetaData(JDBCConnection conn) { + this.conn = conn; + } + + public boolean allProceduresAreCallable() throws SQLException { + return false; + } + + public boolean allTablesAreSelectable() throws SQLException { + return true; + } + + public String getURL() throws SQLException { + return conn.url; + } + + public String getUserName() throws SQLException { + return ""; + } + + public boolean isReadOnly() throws SQLException { + return false; + } + + public boolean nullsAreSortedHigh() throws SQLException { + return false; + } + + public boolean nullsAreSortedLow() throws SQLException { + return false; + } + + public boolean nullsAreSortedAtStart() throws SQLException { + return false; + } + + public boolean nullsAreSortedAtEnd() throws SQLException { + return false; + } + + public String getDatabaseProductName() throws SQLException { + return "SQLite"; + } + + public String getDatabaseProductVersion() throws SQLException { + return SQLite.Database.version(); + } + + public String getDriverName() throws SQLException { + return "SQLite/JDBC"; + } + + public String getDriverVersion() throws SQLException { + return "" + SQLite.JDBCDriver.MAJORVERSION + "." + + SQLite.JDBCDriver.MINORVERSION; + } + + public int getDriverMajorVersion() { + return SQLite.JDBCDriver.MAJORVERSION; + } + + public int getDriverMinorVersion() { + return SQLite.JDBCDriver.MINORVERSION; + } + + public boolean usesLocalFiles() throws SQLException { + return true; + } + + public boolean usesLocalFilePerTable() throws SQLException { + return false; + } + + public boolean supportsMixedCaseIdentifiers() throws SQLException { + return false; + } + + public boolean storesUpperCaseIdentifiers() throws SQLException { + return false; + } + + public boolean storesLowerCaseIdentifiers() throws SQLException { + return false; + } + + public boolean storesMixedCaseIdentifiers() throws SQLException { + return true; + } + + public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { + return false; + } + + public boolean storesUpperCaseQuotedIdentifiers() throws SQLException { + return false; + } + + public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { + return false; + } + + public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { + return true; + } + + public String getIdentifierQuoteString() throws SQLException { + return "\""; + } + + public String getSQLKeywords() throws SQLException { + return "SELECT,UPDATE,CREATE,TABLE,VIEW,DELETE,FROM,WHERE" + + ",COMMIT,ROLLBACK,TRIGGER"; + } + + public String getNumericFunctions() throws SQLException { + return ""; + } + + public String getStringFunctions() throws SQLException { + return ""; + } + + public String getSystemFunctions() throws SQLException { + return ""; + } + + public String getTimeDateFunctions() throws SQLException { + return ""; + } + + public String getSearchStringEscape() throws SQLException { + return "\\"; + } + + public String getExtraNameCharacters() throws SQLException { + return ""; + } + + public boolean supportsAlterTableWithAddColumn() throws SQLException { + return false; + } + + public boolean supportsAlterTableWithDropColumn() throws SQLException { + return false; + } + + public boolean supportsColumnAliasing() throws SQLException { + return true; + } + + public boolean nullPlusNonNullIsNull() throws SQLException { + return false; + } + + public boolean supportsConvert() throws SQLException { + return false; + } + + public boolean supportsConvert(int fromType, int toType) + throws SQLException { + return false; + } + + public boolean supportsTableCorrelationNames() throws SQLException { + return true; + } + + public boolean supportsDifferentTableCorrelationNames() + throws SQLException { + return false; + } + + public boolean supportsExpressionsInOrderBy() throws SQLException { + return true; + } + + public boolean supportsOrderByUnrelated() throws SQLException { + return true; + } + + public boolean supportsGroupBy() throws SQLException { + return true; + } + + public boolean supportsGroupByUnrelated() throws SQLException { + return true; + } + + public boolean supportsGroupByBeyondSelect() throws SQLException { + return false; + } + + public boolean supportsLikeEscapeClause() throws SQLException { + return false; + } + + public boolean supportsMultipleResultSets() throws SQLException { + return false; + } + + public boolean supportsMultipleTransactions() throws SQLException { + return false; + } + + public boolean supportsNonNullableColumns() throws SQLException { + return true; + } + + public boolean supportsMinimumSQLGrammar() throws SQLException { + return true; + } + + public boolean supportsCoreSQLGrammar() throws SQLException { + return false; + } + + public boolean supportsExtendedSQLGrammar() throws SQLException { + return false; + } + + public boolean supportsANSI92EntryLevelSQL() throws SQLException { + return true; + } + + public boolean supportsANSI92IntermediateSQL() throws SQLException { + return false; + } + + public boolean supportsANSI92FullSQL() throws SQLException { + return false; + } + + public boolean supportsIntegrityEnhancementFacility() + throws SQLException { + return false; + } + + public boolean supportsOuterJoins() throws SQLException { + return false; + } + + public boolean supportsFullOuterJoins() throws SQLException { + return false; + } + + public boolean supportsLimitedOuterJoins() throws SQLException { + return false; + } + + public String getSchemaTerm() throws SQLException { + return ""; + } + + public String getProcedureTerm() throws SQLException { + return ""; + } + + public String getCatalogTerm() throws SQLException { + return ""; + } + + public boolean isCatalogAtStart() throws SQLException { + return false; + } + + public String getCatalogSeparator() throws SQLException { + return ""; + } + + public boolean supportsSchemasInDataManipulation() throws SQLException { + return false; + } + + public boolean supportsSchemasInProcedureCalls() throws SQLException { + return false; + } + + public boolean supportsSchemasInTableDefinitions() throws SQLException { + return false; + } + + public boolean supportsSchemasInIndexDefinitions() throws SQLException { + return false; + } + + public boolean supportsSchemasInPrivilegeDefinitions() + throws SQLException { + return false; + } + + public boolean supportsCatalogsInDataManipulation() throws SQLException { + return false; + } + + public boolean supportsCatalogsInProcedureCalls() throws SQLException { + return false; + } + + public boolean supportsCatalogsInTableDefinitions() throws SQLException { + return false; + } + + public boolean supportsCatalogsInIndexDefinitions() throws SQLException { + return false; + } + + public boolean supportsCatalogsInPrivilegeDefinitions() + throws SQLException { + return false; + } + + public boolean supportsPositionedDelete() throws SQLException { + return false; + } + + public boolean supportsPositionedUpdate() throws SQLException { + return false; + } + + public boolean supportsSelectForUpdate() throws SQLException { + return true; + } + + public boolean supportsStoredProcedures() throws SQLException { + return false; + } + + public boolean supportsSubqueriesInComparisons() throws SQLException { + return true; + } + + public boolean supportsSubqueriesInExists() throws SQLException { + return true; + } + + public boolean supportsSubqueriesInIns() throws SQLException { + return true; + } + + public boolean supportsSubqueriesInQuantifieds() throws SQLException { + return false; + } + + public boolean supportsCorrelatedSubqueries() throws SQLException { + return false; + } + + public boolean supportsUnion() throws SQLException { + return false; + } + + public boolean supportsUnionAll() throws SQLException { + return false; + } + + public boolean supportsOpenCursorsAcrossCommit() throws SQLException { + return false; + } + + public boolean supportsOpenCursorsAcrossRollback() throws SQLException { + return false; + } + + public boolean supportsOpenStatementsAcrossCommit() throws SQLException { + return false; + } + + public boolean supportsOpenStatementsAcrossRollback() throws SQLException { + return false; + } + + public int getMaxBinaryLiteralLength() throws SQLException { + return 0; + } + + public int getMaxCharLiteralLength() throws SQLException { + return 0; + } + + public int getMaxColumnNameLength() throws SQLException { + return 0; + } + + public int getMaxColumnsInGroupBy() throws SQLException { + return 0; + } + + public int getMaxColumnsInIndex() throws SQLException { + return 0; + } + + public int getMaxColumnsInOrderBy() throws SQLException { + return 0; + } + + public int getMaxColumnsInSelect() throws SQLException { + return 0; + } + + public int getMaxColumnsInTable() throws SQLException { + return 0; + } + + public int getMaxConnections() throws SQLException { + return 0; + } + + public int getMaxCursorNameLength() throws SQLException { + return 8; + } + + public int getMaxIndexLength() throws SQLException { + return 0; + } + + public int getMaxSchemaNameLength() throws SQLException { + return 0; + } + + public int getMaxProcedureNameLength() throws SQLException { + return 0; + } + + public int getMaxCatalogNameLength() throws SQLException { + return 0; + } + + public int getMaxRowSize() throws SQLException { + return 0; + } + + public boolean doesMaxRowSizeIncludeBlobs() throws SQLException { + return true; + } + + public int getMaxStatementLength() throws SQLException { + return 0; + } + + public int getMaxStatements() throws SQLException { + return 0; + } + + public int getMaxTableNameLength() throws SQLException { + return 0; + } + + public int getMaxTablesInSelect() throws SQLException { + return 0; + } + + public int getMaxUserNameLength() throws SQLException { + return 0; + } + + public int getDefaultTransactionIsolation() throws SQLException { + return Connection.TRANSACTION_SERIALIZABLE; + } + + public boolean supportsTransactions() throws SQLException { + return true; + } + + public boolean supportsTransactionIsolationLevel(int level) + throws SQLException { + return level == Connection.TRANSACTION_SERIALIZABLE; + } + + public boolean supportsDataDefinitionAndDataManipulationTransactions() + throws SQLException { + return true; + } + + public boolean supportsDataManipulationTransactionsOnly() + throws SQLException { + return false; + } + + public boolean dataDefinitionCausesTransactionCommit() + throws SQLException { + return false; + } + + public boolean dataDefinitionIgnoredInTransactions() throws SQLException { + return false; + } + + public ResultSet getProcedures(String catalog, String schemaPattern, + String procedureNamePattern) + throws SQLException { + return null; + } + + public ResultSet getProcedureColumns(String catalog, + String schemaPattern, + String procedureNamePattern, + String columnNamePattern) + throws SQLException { + return null; + } + + public ResultSet getTables(String catalog, String schemaPattern, + String tableNamePattern, String types[]) + throws SQLException { + JDBCStatement s = new JDBCStatement(conn); + StringBuffer sb = new StringBuffer(); + sb.append("SELECT '' AS 'TABLE_CAT', " + + "'' AS 'TABLE_SCHEM', " + + "tbl_name AS 'TABLE_NAME', " + + "upper(type) AS 'TABLE_TYPE', " + + "'' AS REMARKS FROM sqlite_master " + + "WHERE tbl_name like "); + if (tableNamePattern != null) { + sb.append(SQLite.Shell.sql_quote(tableNamePattern)); + } else { + sb.append("'%'"); + } + sb.append(" AND "); + if (types == null || types.length == 0) { + sb.append("(type = 'table' or type = 'view')"); + } else { + sb.append("("); + String sep = ""; + for (int i = 0; i < types.length; i++) { + sb.append(sep); + sb.append("type = "); + sb.append(SQLite.Shell.sql_quote(types[i].toLowerCase())); + sep = " or "; + } + sb.append(")"); + } + ResultSet rs = null; + try { + rs = s.executeQuery(sb.toString()); + s.close(); + } catch (SQLException e) { + throw e; + } finally { + s.close(); + } + return rs; + } + + public ResultSet getSchemas() throws SQLException { + String cols[] = { "TABLE_SCHEM" }; + SQLite.TableResult tr = new SQLite.TableResult(); + tr.columns(cols); + String row[] = { "" }; + tr.newrow(row); + JDBCResultSet rs = new JDBCResultSet(tr, null); + return (ResultSet) rs; + } + + public ResultSet getCatalogs() throws SQLException { + String cols[] = { "TABLE_CAT" }; + SQLite.TableResult tr = new SQLite.TableResult(); + tr.columns(cols); + String row[] = { "" }; + tr.newrow(row); + JDBCResultSet rs = new JDBCResultSet(tr, null); + return (ResultSet) rs; + } + + public ResultSet getTableTypes() throws SQLException { + String cols[] = { "TABLE_TYPE" }; + SQLite.TableResult tr = new SQLite.TableResult(); + tr.columns(cols); + String row[] = new String[1]; + row[0] = "TABLE"; + tr.newrow(row); + row = new String[1]; + row[0] = "VIEW"; + tr.newrow(row); + JDBCResultSet rs = new JDBCResultSet(tr, null); + return (ResultSet) rs; + } + + public ResultSet getColumns(String catalog, String schemaPattern, + String tableNamePattern, + String columnNamePattern) + throws SQLException { + JDBCStatement s = new JDBCStatement(conn); + JDBCResultSet rs0 = null; + try { + rs0 = (JDBCResultSet) + (s.executeQuery("PRAGMA table_info(" + + SQLite.Shell.sql_quote(tableNamePattern) + + ")")); + s.close(); + } catch (SQLException e) { + throw e; + } finally { + s.close(); + } + String cols[] = { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", + "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME", + "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_POINTS", + "NUM_PREC_RADIX", "NULLABLE", "REMARKS", + "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", + "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.SMALLINT, Types.VARCHAR, + Types.INTEGER, Types.INTEGER, Types.INTEGER, + Types.INTEGER, Types.INTEGER, Types.VARCHAR, + Types.VARCHAR, Types.INTEGER, Types.INTEGER, + Types.INTEGER, Types.INTEGER, Types.VARCHAR + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + Hashtable<String, Integer> h = new Hashtable<String, Integer>(); + for (int i = 0; i < rs0.tr.ncolumns; i++) { + h.put(rs0.tr.column[i], new Integer(i)); + } + if (columnNamePattern != null && + columnNamePattern.charAt(0) == '%') { + columnNamePattern = null; + } + for (int i = 0; i < rs0.tr.nrows; i++) { + String r0[] = (String [])(rs0.tr.rows.elementAt(i)); + int col = ((Integer) h.get("name")).intValue(); + if (columnNamePattern != null) { + if (r0[col].compareTo(columnNamePattern) != 0) { + continue; + } + } + String row[] = new String[cols.length]; + row[0] = ""; + row[1] = ""; + row[2] = tableNamePattern; + row[3] = r0[col]; + col = ((Integer) h.get("type")).intValue(); + String typeStr = r0[col]; + int type = mapSqlType(typeStr); + row[4] = "" + type; + row[5] = mapTypeName(type); + row[6] = "" + getD(typeStr, type); + row[7] = "" + getM(typeStr, type); + row[8] = "10"; + row[9] = "0"; + row[11] = null; + col = ((Integer) h.get("dflt_value")).intValue(); + row[12] = r0[col]; + row[13] = "0"; + row[14] = "0"; + row[15] = "65536"; + col = ((Integer) h.get("cid")).intValue(); + Integer cid = new Integer(r0[col]); + row[16] = "" + (cid.intValue() + 1); + col = ((Integer) h.get("notnull")).intValue(); + row[17] = (r0[col].charAt(0) == '0') ? "YES" : "NO"; + row[10] = (r0[col].charAt(0) == '0') ? "" + columnNullable : + "" + columnNoNulls; + tr.newrow(row); + } + } + return rs; + } + + public ResultSet getColumnPrivileges(String catalog, String schema, + String table, + String columnNamePattern) + throws SQLException { + String cols[] = { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", + "COLUMN_NAME", "GRANTOR", "GRANTEE", + "PRIVILEGE", "IS_GRANTABLE" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + return rs; + } + + public ResultSet getTablePrivileges(String catalog, String schemaPattern, + String tableNamePattern) + throws SQLException { + String cols[] = { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", + "COLUMN_NAME", "GRANTOR", "GRANTEE", + "PRIVILEGE", "IS_GRANTABLE" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + return rs; + } + + public ResultSet getBestRowIdentifier(String catalog, String schema, + String table, int scope, + boolean nullable) + throws SQLException { + JDBCStatement s0 = new JDBCStatement(conn); + JDBCResultSet rs0 = null; + JDBCStatement s1 = new JDBCStatement(conn); + JDBCResultSet rs1 = null; + try { + rs0 = (JDBCResultSet) + (s0.executeQuery("PRAGMA index_list(" + + SQLite.Shell.sql_quote(table) + ")")); + rs1 = (JDBCResultSet) + (s1.executeQuery("PRAGMA table_info(" + + SQLite.Shell.sql_quote(table) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s0.close(); + s1.close(); + } + String cols[] = { + "SCOPE", "COLUMN_NAME", "DATA_TYPE", + "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", + "DECIMAL_DIGITS", "PSEUDO_COLUMN" + }; + int types[] = { + Types.SMALLINT, Types.VARCHAR, Types.SMALLINT, + Types.VARCHAR, Types.INTEGER, Types.INTEGER, + Types.SMALLINT, Types.SMALLINT + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0 && + rs1 != null && rs1.tr != null && rs1.tr.nrows > 0) { + Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); + for (int i = 0; i < rs0.tr.ncolumns; i++) { + h0.put(rs0.tr.column[i], new Integer(i)); + } + Hashtable<String, Integer> h1 = new Hashtable<String, Integer>(); + for (int i = 0; i < rs1.tr.ncolumns; i++) { + h1.put(rs1.tr.column[i], new Integer(i)); + } + for (int i = 0; i < rs0.tr.nrows; i++) { + String r0[] = (String [])(rs0.tr.rows.elementAt(i)); + int col = ((Integer) h0.get("unique")).intValue(); + String uniq = r0[col]; + col = ((Integer) h0.get("name")).intValue(); + String iname = r0[col]; + if (uniq.charAt(0) == '0') { + continue; + } + JDBCStatement s2 = new JDBCStatement(conn); + JDBCResultSet rs2 = null; + try { + rs2 = (JDBCResultSet) + (s2.executeQuery("PRAGMA index_info(" + + SQLite.Shell.sql_quote(iname) + ")")); + } catch (SQLException e) { + } finally { + s2.close(); + } + if (rs2 == null || rs2.tr == null || rs2.tr.nrows <= 0) { + continue; + } + Hashtable<String, Integer> h2 = + new Hashtable<String, Integer>(); + for (int k = 0; k < rs2.tr.ncolumns; k++) { + h2.put(rs2.tr.column[k], new Integer(k)); + } + for (int k = 0; k < rs2.tr.nrows; k++) { + String r2[] = (String [])(rs2.tr.rows.elementAt(k)); + col = ((Integer) h2.get("name")).intValue(); + String cname = r2[col]; + for (int m = 0; m < rs1.tr.nrows; m++) { + String r1[] = (String [])(rs1.tr.rows.elementAt(m)); + col = ((Integer) h1.get("name")).intValue(); + if (cname.compareTo(r1[col]) == 0) { + String row[] = new String[cols.length]; + row[0] = "" + scope; + row[1] = cname; + row[2] = "" + Types.VARCHAR; + row[3] = "VARCHAR"; + row[4] = "65536"; + row[5] = "0"; + row[6] = "0"; + row[7] = "" + bestRowNotPseudo; + tr.newrow(row); + } + } + } + } + } + if (tr.nrows <= 0) { + String row[] = new String[cols.length]; + row[0] = "" + scope; + row[1] = "_ROWID_"; + row[2] = "" + Types.INTEGER; + row[3] = "INTEGER"; + row[4] = "10"; + row[5] = "0"; + row[6] = "0"; + row[7] = "" + bestRowPseudo; + tr.newrow(row); + } + return rs; + } + + public ResultSet getVersionColumns(String catalog, String schema, + String table) throws SQLException { + String cols[] = { + "SCOPE", "COLUMN_NAME", "DATA_TYPE", + "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", + "DECIMAL_DIGITS", "PSEUDO_COLUMN" + }; + int types[] = { + Types.SMALLINT, Types.VARCHAR, Types.SMALLINT, + Types.VARCHAR, Types.INTEGER, Types.INTEGER, + Types.SMALLINT, Types.SMALLINT + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + return rs; + } + + public ResultSet getPrimaryKeys(String catalog, String schema, + String table) throws SQLException { + JDBCStatement s0 = new JDBCStatement(conn); + JDBCResultSet rs0 = null; + try { + rs0 = (JDBCResultSet) + (s0.executeQuery("PRAGMA index_list(" + + SQLite.Shell.sql_quote(table) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s0.close(); + } + String cols[] = { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", + "COLUMN_NAME", "KEY_SEQ", "PK_NAME" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.SMALLINT, Types.VARCHAR + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); + for (int i = 0; i < rs0.tr.ncolumns; i++) { + h0.put(rs0.tr.column[i], new Integer(i)); + } + for (int i = 0; i < rs0.tr.nrows; i++) { + String r0[] = (String [])(rs0.tr.rows.elementAt(i)); + int col = ((Integer) h0.get("unique")).intValue(); + String uniq = r0[col]; + col = ((Integer) h0.get("name")).intValue(); + String iname = r0[col]; + if (uniq.charAt(0) == '0') { + continue; + } + JDBCStatement s1 = new JDBCStatement(conn); + JDBCResultSet rs1 = null; + try { + rs1 = (JDBCResultSet) + (s1.executeQuery("PRAGMA index_info(" + + SQLite.Shell.sql_quote(iname) + ")")); + } catch (SQLException e) { + } finally { + s1.close(); + } + if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) { + continue; + } + Hashtable<String, Integer> h1 = + new Hashtable<String, Integer>(); + for (int k = 0; k < rs1.tr.ncolumns; k++) { + h1.put(rs1.tr.column[k], new Integer(k)); + } + for (int k = 0; k < rs1.tr.nrows; k++) { + String r1[] = (String [])(rs1.tr.rows.elementAt(k)); + String row[] = new String[cols.length]; + row[0] = ""; + row[1] = ""; + row[2] = table; + col = ((Integer) h1.get("name")).intValue(); + row[3] = r1[col]; + col = ((Integer) h1.get("seqno")).intValue(); +// BEGIN android-changed + row[4] = "" + (Integer.parseInt(r1[col]) + 1); +// END android-changed + row[5] = iname; + tr.newrow(row); + } + } + } + JDBCStatement s1 = new JDBCStatement(conn); + try { + rs0 = (JDBCResultSet) + (s1.executeQuery("PRAGMA table_info(" + + SQLite.Shell.sql_quote(table) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s1.close(); + } + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); + for (int i = 0; i < rs0.tr.ncolumns; i++) { + h0.put(rs0.tr.column[i], new Integer(i)); + } + for (int i = 0; i < rs0.tr.nrows; i++) { + String r0[] = (String [])(rs0.tr.rows.elementAt(i)); + int col = ((Integer) h0.get("type")).intValue(); + String type = r0[col]; + if (!type.equalsIgnoreCase("integer")) { + continue; + } + col = ((Integer) h0.get("pk")).intValue(); + String pk = r0[col]; + if (pk.charAt(0) == '0') { + continue; + } + String row[] = new String[cols.length]; + row[0] = ""; + row[1] = ""; + row[2] = table; + col = ((Integer) h0.get("name")).intValue(); + row[3] = r0[col]; + col = ((Integer) h0.get("cid")).intValue(); +// BEGIN android-changed + row[4] = "" + (Integer.parseInt(r0[col]) + 1); +// END android-changed + row[5] = ""; + tr.newrow(row); + } + } + return rs; + } + + private void internalImportedKeys(String table, String pktable, + JDBCResultSet in, TableResultX out) { + Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); + for (int i = 0; i < in.tr.ncolumns; i++) { + h0.put(in.tr.column[i], new Integer(i)); + } + for (int i = 0; i < in.tr.nrows; i++) { + String r0[] = (String [])(in.tr.rows.elementAt(i)); + int col = ((Integer) h0.get("table")).intValue(); + String pktab = r0[col]; + if (pktable != null && !pktable.equalsIgnoreCase(pktab)) { + continue; + } + col = ((Integer) h0.get("from")).intValue(); + String pkcol = r0[col]; + col = ((Integer) h0.get("to")).intValue(); + String fkcol = r0[col]; + col = ((Integer) h0.get("seq")).intValue(); + String seq = r0[col]; + String row[] = new String[out.ncolumns]; + row[0] = ""; + row[1] = ""; + row[2] = pktab; + row[3] = pkcol; + row[4] = ""; + row[5] = ""; + row[6] = table; + row[7] = fkcol == null ? pkcol : fkcol; +// BEGIN android-changed + row[8] = "" + ((Integer.parseInt(seq)) + 1); +// END android-changed + row[9] = + "" + java.sql.DatabaseMetaData.importedKeyNoAction; + row[10] = + "" + java.sql.DatabaseMetaData.importedKeyNoAction; + row[11] = null; + row[12] = null; + row[13] = + "" + java.sql.DatabaseMetaData.importedKeyNotDeferrable; + out.newrow(row); + } + } + + public ResultSet getImportedKeys(String catalog, String schema, + String table) throws SQLException { + JDBCStatement s0 = new JDBCStatement(conn); + JDBCResultSet rs0 = null; + try { + rs0 = (JDBCResultSet) + (s0.executeQuery("PRAGMA foreign_key_list(" + + SQLite.Shell.sql_quote(table) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s0.close(); + } + String cols[] = { + "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", + "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", + "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", + "UPDATE_RULE", "DELETE_RULE", "FK_NAME", + "PK_NAME", "DEFERRABILITY" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, + Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, + Types.VARCHAR, Types.SMALLINT + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + internalImportedKeys(table, null, rs0, tr); + } + return rs; + } + + public ResultSet getExportedKeys(String catalog, String schema, + String table) throws SQLException { + String cols[] = { + "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", + "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", + "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", + "UPDATE_RULE", "DELETE_RULE", "FK_NAME", + "PK_NAME", "DEFERRABILITY" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, + Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, + Types.VARCHAR, Types.SMALLINT + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet(tr, null); + return rs; + } + + public ResultSet getCrossReference(String primaryCatalog, + String primarySchema, + String primaryTable, + String foreignCatalog, + String foreignSchema, + String foreignTable) + throws SQLException { + JDBCResultSet rs0 = null; + if (foreignTable != null && foreignTable.charAt(0) != '%') { + JDBCStatement s0 = new JDBCStatement(conn); + try { + rs0 = (JDBCResultSet) + (s0.executeQuery("PRAGMA foreign_key_list(" + + SQLite.Shell.sql_quote(foreignTable) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s0.close(); + } + } + String cols[] = { + "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", + "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", + "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", + "UPDATE_RULE", "DELETE_RULE", "FK_NAME", + "PK_NAME", "DEFERRABILITY" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, + Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, + Types.VARCHAR, Types.SMALLINT + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet(tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + String pktable = null; + if (primaryTable != null && primaryTable.charAt(0) != '%') { + pktable = primaryTable; + } + internalImportedKeys(foreignTable, pktable, rs0, tr); + } + return rs; + } + + public ResultSet getTypeInfo() throws SQLException { + String cols[] = { + "TYPE_NAME", "DATA_TYPE", "PRECISION", + "LITERAL_PREFIX", "LITERAL_SUFFIX", "CREATE_PARAMS", + "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE", + "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", "AUTO_INCREMENT", + "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE", + "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX" + }; + int types[] = { + Types.VARCHAR, Types.SMALLINT, Types.INTEGER, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.SMALLINT, Types.BIT, Types.SMALLINT, + Types.BIT, Types.BIT, Types.BIT, + Types.VARCHAR, Types.SMALLINT, Types.SMALLINT, + Types.INTEGER, Types.INTEGER, Types.INTEGER + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet(tr, null); + String row1[] = { + "VARCHAR", "" + Types.VARCHAR, "65536", + "'", "'", null, + "" + typeNullable, "1", "" + typeSearchable, + "0", "0", "0", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row1); + String row2[] = { + "INTEGER", "" + Types.INTEGER, "32", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "2" + }; + tr.newrow(row2); + String row3[] = { + "DOUBLE", "" + Types.DOUBLE, "16", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "10" + }; + tr.newrow(row3); + String row4[] = { + "FLOAT", "" + Types.FLOAT, "7", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "10" + }; + tr.newrow(row4); + String row5[] = { + "SMALLINT", "" + Types.SMALLINT, "16", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "2" + }; + tr.newrow(row5); + String row6[] = { + "BIT", "" + Types.BIT, "1", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "2" + }; + tr.newrow(row6); + String row7[] = { + "TIMESTAMP", "" + Types.TIMESTAMP, "30", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row7); + String row8[] = { + "DATE", "" + Types.DATE, "10", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row8); + String row9[] = { + "TIME", "" + Types.TIME, "8", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row9); + String row10[] = { + "BINARY", "" + Types.BINARY, "65536", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row10); + String row11[] = { + "VARBINARY", "" + Types.VARBINARY, "65536", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row11); + return rs; + } + + public ResultSet getIndexInfo(String catalog, String schema, String table, + boolean unique, boolean approximate) + throws SQLException { + JDBCStatement s0 = new JDBCStatement(conn); + JDBCResultSet rs0 = null; + try { + rs0 = (JDBCResultSet) + (s0.executeQuery("PRAGMA index_list(" + + SQLite.Shell.sql_quote(table) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s0.close(); + } + String cols[] = { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", + "NON_UNIQUE", "INDEX_QUALIFIER", "INDEX_NAME", + "TYPE", "ORDINAL_POSITION", "COLUMN_NAME", + "ASC_OR_DESC", "CARDINALITY", "PAGES", + "FILTER_CONDITION" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.BIT, Types.VARCHAR, Types.VARCHAR, + Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, + Types.VARCHAR, Types.INTEGER, Types.INTEGER, + Types.VARCHAR + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet(tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); + for (int i = 0; i < rs0.tr.ncolumns; i++) { + h0.put(rs0.tr.column[i], new Integer(i)); + } + for (int i = 0; i < rs0.tr.nrows; i++) { + String r0[] = (String [])(rs0.tr.rows.elementAt(i)); + int col = ((Integer) h0.get("unique")).intValue(); + String uniq = r0[col]; + col = ((Integer) h0.get("name")).intValue(); + String iname = r0[col]; + if (unique && uniq.charAt(0) == '0') { + continue; + } + JDBCStatement s1 = new JDBCStatement(conn); + JDBCResultSet rs1 = null; + try { + rs1 = (JDBCResultSet) + (s1.executeQuery("PRAGMA index_info(" + + SQLite.Shell.sql_quote(iname) + ")")); + } catch (SQLException e) { + } finally { + s1.close(); + } + if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) { + continue; + } + Hashtable<String, Integer> h1 = + new Hashtable<String, Integer>(); + for (int k = 0; k < rs1.tr.ncolumns; k++) { + h1.put(rs1.tr.column[k], new Integer(k)); + } + for (int k = 0; k < rs1.tr.nrows; k++) { + String r1[] = (String [])(rs1.tr.rows.elementAt(k)); + String row[] = new String[cols.length]; + row[0] = ""; + row[1] = ""; + row[2] = table; + row[3] = (uniq.charAt(0) != '0' || + (iname.charAt(0) == '(' && + iname.indexOf(" autoindex ") > 0)) ? "0" : "1"; + row[4] = ""; + row[5] = iname; + row[6] = "" + tableIndexOther; + col = ((Integer) h1.get("seqno")).intValue(); +// BEGIN android-changed + row[7] = "" + (Integer.parseInt(r1[col]) + 1); +// END android-changed + col = ((Integer) h1.get("name")).intValue(); + row[8] = r1[col]; + row[9] = "A"; + row[10] = "0"; + row[11] = "0"; + row[12] = null; + tr.newrow(row); + } + } + } + return rs; + } + + public boolean supportsResultSetType(int type) throws SQLException { + return type == ResultSet.CONCUR_READ_ONLY; + } + + public boolean supportsResultSetConcurrency(int type, int concurrency) + throws SQLException { + return false; + } + + public boolean ownUpdatesAreVisible(int type) throws SQLException { + return false; + } + + public boolean ownDeletesAreVisible(int type) throws SQLException { + return false; + } + + public boolean ownInsertsAreVisible(int type) throws SQLException { + return false; + } + + public boolean othersUpdatesAreVisible(int type) throws SQLException { + return false; + } + + public boolean othersDeletesAreVisible(int type) throws SQLException { + return false; + } + + public boolean othersInsertsAreVisible(int type) throws SQLException { + return false; + } + + public boolean updatesAreDetected(int type) throws SQLException { + return false; + } + + public boolean deletesAreDetected(int type) throws SQLException { + return false; + } + + public boolean insertsAreDetected(int type) throws SQLException { + return false; + } + + public boolean supportsBatchUpdates() throws SQLException { + return false; + } + + public ResultSet getUDTs(String catalog, String schemaPattern, + String typeNamePattern, int[] types) + throws SQLException { + return null; + } + + public Connection getConnection() throws SQLException { + return conn; + } + + static String mapTypeName(int type) { + switch (type) { + case Types.INTEGER: return "integer"; + case Types.SMALLINT: return "smallint"; + case Types.FLOAT: return "float"; + case Types.DOUBLE: return "double"; + case Types.TIMESTAMP: return "timestamp"; + case Types.DATE: return "date"; + case Types.TIME: return "time"; + case Types.BINARY: return "binary"; + case Types.VARBINARY: return "varbinary"; + } + return "varchar"; + } + + static int mapSqlType(String type) { + if (type == null) { + return Types.VARCHAR; + } + type = type.toLowerCase(); + if (type.startsWith("inter")) { + return Types.VARCHAR; + } + if (type.startsWith("numeric") || + type.startsWith("int")) { + return Types.INTEGER; + } + if (type.startsWith("tinyint") || + type.startsWith("smallint")) { + return Types.SMALLINT; + } + if (type.startsWith("float")) { + return Types.FLOAT; + } + if (type.startsWith("double")) { + return Types.DOUBLE; + } + if (type.startsWith("datetime") || + type.startsWith("timestamp")) { + return Types.TIMESTAMP; + } + if (type.startsWith("date")) { + return Types.DATE; + } + if (type.startsWith("time")) { + return Types.TIME; + } + if (type.startsWith("blob")) { + return Types.BINARY; + } + if (type.startsWith("binary")) { + return Types.BINARY; + } + if (type.startsWith("varbinary")) { + return Types.VARBINARY; + } + return Types.VARCHAR; + } + + static int getM(String typeStr, int type) { + int m = 65536; + switch (type) { + case Types.INTEGER: m = 11; break; + case Types.SMALLINT: m = 6; break; + case Types.FLOAT: m = 25; break; + case Types.DOUBLE: m = 54; break; + case Types.TIMESTAMP: return 30; + case Types.DATE: return 10; + case Types.TIME: return 8; + } + typeStr = typeStr.toLowerCase(); + int i1 = typeStr.indexOf('('); + if (i1 > 0) { + ++i1; + int i2 = typeStr.indexOf(',', i1); + if (i2 < 0) { + i2 = typeStr.indexOf(')', i1); + } + if (i2 - i1 > 0) { + String num = typeStr.substring(i1, i2); + try { + m = java.lang.Integer.parseInt(num, 10); + } catch (NumberFormatException e) { + } + } + } + return m; + } + + static int getD(String typeStr, int type) { + int d = 0; + switch (type) { + case Types.INTEGER: d = 10; break; + case Types.SMALLINT: d = 5; break; + case Types.FLOAT: d = 24; break; + case Types.DOUBLE: d = 53; break; + default: return getM(typeStr, type); + } + typeStr = typeStr.toLowerCase(); + int i1 = typeStr.indexOf('('); + if (i1 > 0) { + ++i1; + int i2 = typeStr.indexOf(',', i1); + if (i2 < 0) { + return getM(typeStr, type); + } + i1 = i2; + i2 = typeStr.indexOf(')', i1); + if (i2 - i1 > 0) { + String num = typeStr.substring(i1, i2); + try { + d = java.lang.Integer.parseInt(num, 10); + } catch (NumberFormatException e) { + } + } + } + return d; + } + + public boolean supportsSavepoints() { + return false; + } + + public boolean supportsNamedParameters() { + return false; + } + + public boolean supportsMultipleOpenResults() { + return false; + } + + public boolean supportsGetGeneratedKeys() { + return false; + } + + public boolean supportsResultSetHoldability(int x) { + return false; + } + + public boolean supportsStatementPooling() { + return false; + } + + public boolean locatorsUpdateCopy() throws SQLException { + throw new SQLException("not supported"); + } + + public ResultSet getSuperTypes(String catalog, String schemaPattern, + String typeNamePattern) + throws SQLException { + throw new SQLException("not supported"); + } + + public ResultSet getSuperTables(String catalog, String schemaPattern, + String tableNamePattern) + throws SQLException { + throw new SQLException("not supported"); + } + + public ResultSet getAttributes(String catalog, String schemaPattern, + String typeNamePattern, + String attributeNamePattern) + throws SQLException { + throw new SQLException("not supported"); + } + + public int getResultSetHoldability() throws SQLException { + return ResultSet.HOLD_CURSORS_OVER_COMMIT; + } + + public int getDatabaseMajorVersion() { + return SQLite.JDBCDriver.MAJORVERSION; + } + + public int getDatabaseMinorVersion() { + return SQLite.JDBCDriver.MINORVERSION; + } + + public int getJDBCMajorVersion() { + return 1; + } + + public int getJDBCMinorVersion() { + return 0; + } + + public int getSQLStateType() throws SQLException { + return sqlStateXOpen; + } + +} diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java b/sql/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java new file mode 100644 index 0000000..ab81867 --- /dev/null +++ b/sql/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java @@ -0,0 +1,752 @@ +package SQLite.JDBC2y; + +import java.sql.*; +import java.math.BigDecimal; +import java.util.*; + +class BatchArg { + String arg; + boolean blob; + + BatchArg(String arg, boolean blob) { + if (arg == null) { + this.arg = null; + } else { + this.arg = new String(arg); + } + this.blob = blob; + } +} + +public class JDBCPreparedStatement extends JDBCStatement + implements java.sql.PreparedStatement { + + private String sql; + private String args[]; + private boolean blobs[]; + private ArrayList<BatchArg> batch; + private static final boolean nullrepl = + SQLite.Database.version().compareTo("2.5.0") < 0; + + public JDBCPreparedStatement(JDBCConnection conn, String sql) { + super(conn); + this.args = null; + this.blobs = null; + this.batch = null; + this.sql = fixup(sql); + } + + private String fixup(String sql) { + StringBuffer sb = new StringBuffer(); + boolean inq = false; + int nparm = 0; + for (int i = 0; i < sql.length(); i++) { + char c = sql.charAt(i); + if (c == '\'') { + if (inq) { + char nextChar = 0; + if(i + 1 < sql.length()) { + nextChar = sql.charAt(i + 1); + } + if (nextChar == '\'') { + sb.append(c); + sb.append(nextChar); + i++; + } else { + inq = false; + sb.append(c); + } + } else { + inq = true; + sb.append(c); + } + } else if (c == '?') { + if (inq) { + sb.append(c); + } else { + ++nparm; + sb.append(nullrepl ? "'%q'" : "%Q"); + } + } else if (c == ';') { + if (!inq) { + break; + } + sb.append(c); + } else if (c == '%') { + sb.append("%%"); + } else { + sb.append(c); + } + } + args = new String[nparm]; + blobs = new boolean[nparm]; + try { + clearParameters(); + } catch (SQLException e) { + } + return sb.toString(); + } + + private String fixup2(String sql) { + if (!conn.db.is3()) { + return sql; + } + StringBuffer sb = new StringBuffer(); + int parm = -1; + for (int i = 0; i < sql.length(); i++) { + char c = sql.charAt(i); + if (c == '%') { + sb.append(c); + ++i; + c = sql.charAt(i); + if (c == 'Q') { + parm++; + if (blobs[parm]) { + c = 's'; + } + } + } + sb.append(c); + } + return sb.toString(); + } + + public ResultSet executeQuery() throws SQLException { + return executeQuery(fixup2(sql), args, false); + } + + public int executeUpdate() throws SQLException { + executeQuery(fixup2(sql), args, true); + return updcnt; + } + + public void setNull(int parameterIndex, int sqlType) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = nullrepl ? "" : null; + blobs[parameterIndex - 1] = false; + } + + public void setBoolean(int parameterIndex, boolean x) + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = x ? "1" : "0"; + blobs[parameterIndex - 1] = false; + } + + public void setByte(int parameterIndex, byte x) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; + } + + public void setShort(int parameterIndex, short x) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; + } + + public void setInt(int parameterIndex, int x) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; + } + + public void setLong(int parameterIndex, long x) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; + } + + public void setFloat(int parameterIndex, float x) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; + } + + public void setDouble(int parameterIndex, double x) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; + } + + public void setBigDecimal(int parameterIndex, BigDecimal x) + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + args[parameterIndex - 1] = "" + x; + } + blobs[parameterIndex - 1] = false; + } + + public void setString(int parameterIndex, String x) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + args[parameterIndex - 1] = x; + } + blobs[parameterIndex - 1] = false; + } + + public void setBytes(int parameterIndex, byte x[]) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + blobs[parameterIndex - 1] = false; + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + if (conn.db.is3()) { + args[parameterIndex - 1] = SQLite.StringEncoder.encodeX(x); + blobs[parameterIndex - 1] = true; + } else { + args[parameterIndex - 1] = SQLite.StringEncoder.encode(x); + } + } + } + + public void setDate(int parameterIndex, java.sql.Date x) + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + args[parameterIndex - 1] = x.toString(); + } + blobs[parameterIndex - 1] = false; + } + + public void setTime(int parameterIndex, java.sql.Time x) + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + args[parameterIndex - 1] = x.toString(); + } + blobs[parameterIndex - 1] = false; + } + + public void setTimestamp(int parameterIndex, java.sql.Timestamp x) + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + args[parameterIndex - 1] = x.toString(); + } + blobs[parameterIndex - 1] = false; + } + + public void setAsciiStream(int parameterIndex, java.io.InputStream x, + int length) throws SQLException { + throw new SQLException("not supported"); + } + + @Deprecated + public void setUnicodeStream(int parameterIndex, java.io.InputStream x, + int length) throws SQLException { + throw new SQLException("not supported"); + } + + public void setBinaryStream(int parameterIndex, java.io.InputStream x, + int length) throws SQLException { + throw new SQLException("not supported"); + } + + public void clearParameters() throws SQLException { + for (int i = 0; i < args.length; i++) { + args[i] = nullrepl ? "" : null; + blobs[i] = false; + } + } + + public void setObject(int parameterIndex, Object x, int targetSqlType, + int scale) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + if (x instanceof byte[]) { + byte[] bx = (byte[]) x; + if (conn.db.is3()) { + args[parameterIndex - 1] = + SQLite.StringEncoder.encodeX(bx); + blobs[parameterIndex - 1] = true; + return; + } + args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx); + } else { + args[parameterIndex - 1] = x.toString(); + } + } + blobs[parameterIndex - 1] = false; + } + + public void setObject(int parameterIndex, Object x, int targetSqlType) + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + if (x instanceof byte[]) { + byte[] bx = (byte[]) x; + if (conn.db.is3()) { + args[parameterIndex - 1] = + SQLite.StringEncoder.encodeX(bx); + blobs[parameterIndex - 1] = true; + return; + } + args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx); + } else { + args[parameterIndex - 1] = x.toString(); + } + } + blobs[parameterIndex - 1] = false; + } + + public void setObject(int parameterIndex, Object x) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + if (x instanceof byte[]) { + byte[] bx = (byte[]) x; + if (conn.db.is3()) { + args[parameterIndex - 1] = + SQLite.StringEncoder.encodeX(bx); + blobs[parameterIndex - 1] = true; + return; + } + args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx); + } else { + args[parameterIndex - 1] = x.toString(); + } + } + blobs[parameterIndex - 1] = false; + } + + public boolean execute() throws SQLException { + return executeQuery(fixup2(sql), args, false) != null; + } + + public void addBatch() throws SQLException { + if (batch == null) { + batch = new ArrayList<BatchArg>(args.length); + } + for (int i = 0; i < args.length; i++) { + batch.add(new BatchArg(args[i], blobs[i])); + } + } + + public int[] executeBatch() throws SQLException { + if (batch == null) { + return new int[0]; + } + int[] ret = new int[batch.size() / args.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = EXECUTE_FAILED; + } + int errs = 0; + int index = 0; + for (int i = 0; i < ret.length; i++) { + for (int k = 0; k < args.length; k++) { + BatchArg b = (BatchArg) batch.get(index++); + + args[i] = b.arg; + blobs[i] = b.blob; + } + try { + ret[i] = executeUpdate(); + } catch (SQLException e) { + ++errs; + } + } + if (errs > 0) { + throw new BatchUpdateException("batch failed", ret); + } + return ret; + } + + public void clearBatch() throws SQLException { + if (batch != null) { + batch.clear(); + batch = null; + } + } + + public void setCharacterStream(int parameterIndex, + java.io.Reader reader, + int length) throws SQLException { + throw new SQLException("not supported"); + } + + public void setRef(int i, Ref x) throws SQLException { + throw new SQLException("not supported"); + } + + public void setBlob(int i, Blob x) throws SQLException { + throw new SQLException("not supported"); + } + + public void setClob(int i, Clob x) throws SQLException { + throw new SQLException("not supported"); + } + + public void setArray(int i, Array x) throws SQLException { + throw new SQLException("not supported"); + } + + public ResultSetMetaData getMetaData() throws SQLException { + return rs.getMetaData(); + } + + public void setDate(int parameterIndex, java.sql.Date x, Calendar cal) + throws SQLException { + setDate(parameterIndex, x); + } + + public void setTime(int parameterIndex, java.sql.Time x, Calendar cal) + throws SQLException { + setTime(parameterIndex, x); + } + + public void setTimestamp(int parameterIndex, java.sql.Timestamp x, + Calendar cal) throws SQLException { + setTimestamp(parameterIndex, x); + } + + public void setNull(int parameterIndex, int sqlType, String typeName) + throws SQLException { + setNull(parameterIndex, sqlType); + } + + public ParameterMetaData getParameterMetaData() throws SQLException { + throw new SQLException("not supported"); + } + + public void registerOutputParameter(String parameterName, int sqlType) + throws SQLException { + throw new SQLException("not supported"); + } + + public void registerOutputParameter(String parameterName, int sqlType, + int scale) + throws SQLException { + throw new SQLException("not supported"); + } + + public void registerOutputParameter(String parameterName, int sqlType, + String typeName) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.net.URL getURL(int parameterIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public void setURL(int parameterIndex, java.net.URL url) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setNull(String parameterName, int sqlType) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setBoolean(String parameterName, boolean val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setByte(String parameterName, byte val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setShort(String parameterName, short val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setInt(String parameterName, int val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setLong(String parameterName, long val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setFloat(String parameterName, float val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setDouble(String parameterName, double val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setBigDecimal(String parameterName, BigDecimal val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setString(String parameterName, String val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setBytes(String parameterName, byte val[]) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setDate(String parameterName, java.sql.Date val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setTime(String parameterName, java.sql.Time val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setTimestamp(String parameterName, java.sql.Timestamp val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setAsciiStream(String parameterName, + java.io.InputStream s, int length) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setBinaryStream(String parameterName, + java.io.InputStream s, int length) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setObject(String parameterName, Object val, int targetSqlType, + int scale) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setObject(String parameterName, Object val, int targetSqlType) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setObject(String parameterName, Object val) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setCharacterStream(String parameterName, + java.io.Reader r, int length) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setDate(String parameterName, java.sql.Date val, + Calendar cal) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setTime(String parameterName, java.sql.Time val, + Calendar cal) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setTimestamp(String parameterName, java.sql.Timestamp val, + Calendar cal) + throws SQLException { + throw new SQLException("not supported"); + } + + public void setNull(String parameterName, int sqlType, String typeName) + throws SQLException { + throw new SQLException("not supported"); + } + + public String getString(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public boolean getBoolean(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public byte getByte(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public short getShort(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public int getInt(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public long getLong(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public float getFloat(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public double getDouble(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public byte[] getBytes(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Date getDate(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Time getTime(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Timestamp getTimestamp(String parameterName) + throws SQLException { + throw new SQLException("not supported"); + } + + public Object getObject(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public Object getObject(int parameterIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public BigDecimal getBigDecimal(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public Object getObject(String parameterName, Map map) + throws SQLException { + throw new SQLException("not supported"); + } + + public Object getObject(int parameterIndex, Map map) + throws SQLException { + throw new SQLException("not supported"); + } + + public Ref getRef(int parameterIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public Ref getRef(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public Blob getBlob(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public Blob getBlob(int parameterIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public Clob getClob(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public Clob getClob(int parameterIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public Array getArray(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + + public Array getArray(int parameterIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Date getDate(String parameterName, Calendar cal) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Date getDate(int parameterIndex, Calendar cal) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Time getTime(String parameterName, Calendar cal) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Time getTime(int parameterIndex, Calendar cal) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Timestamp getTimestamp(String parameterName, Calendar cal) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Timestamp getTimestamp(int parameterIndex, Calendar cal) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.net.URL getURL(String parameterName) throws SQLException { + throw new SQLException("not supported"); + } + +} diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCResultSet.java b/sql/src/main/java/SQLite/JDBC2y/JDBCResultSet.java new file mode 100644 index 0000000..06384eb --- /dev/null +++ b/sql/src/main/java/SQLite/JDBC2y/JDBCResultSet.java @@ -0,0 +1,932 @@ +package SQLite.JDBC2y; + +import java.sql.*; +import java.math.BigDecimal; + +public class JDBCResultSet implements java.sql.ResultSet { + + /** + * Current row to be retrieved. + */ + private int row; + + /** + * Table returned by Database.get_table() + */ + protected SQLite.TableResult tr; + + /** + * Statement from which result set was produced. + */ + private JDBCStatement s; + + /** + * Meta data for result set or null. + */ + private JDBCResultSetMetaData m; + + /** + * Last result cell retrieved or null. + */ + private String lastg; + + + public JDBCResultSet(SQLite.TableResult tr, JDBCStatement s) { + this.tr = tr; + this.s = s; + this.m = null; + this.lastg = null; + this.row = -1; + } + + public boolean next() throws SQLException { + if (tr == null) { + return false; + } + row++; + return row < tr.nrows; + } + + public int findColumn(String columnName) throws SQLException { + JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData(); + return m.findColByName(columnName); + } + + public int getRow() throws SQLException { + if (tr == null) { + throw new SQLException("no rows"); + } + return row + 1; + } + + public boolean previous() throws SQLException { + if (tr == null) { + return false; + } + if (row >= 0) { + row--; + } + return row >= 0; + } + + public boolean absolute(int row) throws SQLException { + if (tr == null) { + return false; + } + if (row < 0) { + row = tr.nrows + 1 + row; + } + row--; + if (row < 0 || row > tr.nrows) { + return false; + } + this.row = row; + return true; + } + + public boolean relative(int row) throws SQLException { + if (tr == null) { + return false; + } + if (this.row + row < 0 || this.row + row >= tr.nrows) { + return false; + } + this.row += row; + return true; + } + + public void setFetchDirection(int dir) throws SQLException { + throw new SQLException("not supported"); + } + + public int getFetchDirection() throws SQLException { + throw new SQLException("not supported"); + } + + public void setFetchSize(int fsize) throws SQLException { + throw new SQLException("not supported"); + } + + public int getFetchSize() throws SQLException { + throw new SQLException("not supported"); + } + + public String getString(int columnIndex) throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + return lastg; + } + + public String getString(String columnName) throws SQLException { + int col = findColumn(columnName); + return getString(col); + } + + public int getInt(int columnIndex) throws SQLException { + Integer i = internalGetInt(columnIndex); + if (i != null) { + return i.intValue(); + } + return 0; + } + + private Integer internalGetInt(int columnIndex) throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return Integer.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; + } + + public int getInt(String columnName) throws SQLException { + int col = findColumn(columnName); + return getInt(col); + } + + public boolean getBoolean(int columnIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public boolean getBoolean(String columnName) throws SQLException { + throw new SQLException("not supported"); + } + + public ResultSetMetaData getMetaData() throws SQLException { + if (m == null) { + m = new JDBCResultSetMetaData(this); + } + return m; + } + + public short getShort(int columnIndex) throws SQLException { + Short s = internalGetShort(columnIndex); + if (s != null) { + return s.shortValue(); + } + return 0; + } + + private Short internalGetShort(int columnIndex) throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return Short.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; + } + + public short getShort(String columnName) throws SQLException { + int col = findColumn(columnName); + return getShort(col); + } + + public java.sql.Time getTime(int columnIndex) throws SQLException { + return internalGetTime(columnIndex, null); + } + + private java.sql.Time internalGetTime(int columnIndex, + java.util.Calendar cal) + throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return java.sql.Time.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; + } + + public java.sql.Time getTime(String columnName) throws SQLException { + int col = findColumn(columnName); + return getTime(col); + } + + public java.sql.Time getTime(int columnIndex, java.util.Calendar cal) + throws SQLException { + return internalGetTime(columnIndex, cal); + } + + public java.sql.Time getTime(String columnName, java.util.Calendar cal) + throws SQLException{ + int col = findColumn(columnName); + return getTime(col, cal); + } + + public java.sql.Timestamp getTimestamp(int columnIndex) + throws SQLException{ + return internalGetTimestamp(columnIndex, null); + } + + private java.sql.Timestamp internalGetTimestamp(int columnIndex, + java.util.Calendar cal) + throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return java.sql.Timestamp.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; + } + + public java.sql.Timestamp getTimestamp(String columnName) + throws SQLException{ + int col = findColumn(columnName); + return getTimestamp(col); + } + + public java.sql.Timestamp getTimestamp(int columnIndex, + java.util.Calendar cal) + throws SQLException { + return internalGetTimestamp(columnIndex, cal); + } + + public java.sql.Timestamp getTimestamp(String columnName, + java.util.Calendar cal) + throws SQLException { + int col = findColumn(columnName); + return getTimestamp(col, cal); + } + + public java.sql.Date getDate(int columnIndex) throws SQLException { + return internalGetDate(columnIndex, null); + } + + private java.sql.Date internalGetDate(int columnIndex, + java.util.Calendar cal) + throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return java.sql.Date.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; + } + + public java.sql.Date getDate(String columnName) throws SQLException { + int col = findColumn(columnName); + return getDate(col); + } + + public java.sql.Date getDate(int columnIndex, java.util.Calendar cal) + throws SQLException{ + return internalGetDate(columnIndex, cal); + } + + public java.sql.Date getDate(String columnName, java.util.Calendar cal) + throws SQLException{ + int col = findColumn(columnName); + return getDate(col, cal); + } + + public double getDouble(int columnIndex) throws SQLException { + Double d = internalGetDouble(columnIndex); + if (d != null) { + return d.doubleValue(); + } + return 0; + } + + private Double internalGetDouble(int columnIndex) throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return Double.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; + } + + public double getDouble(String columnName) throws SQLException { + int col = findColumn(columnName); + return getDouble(col); + } + + public float getFloat(int columnIndex) throws SQLException { + Float f = internalGetFloat(columnIndex); + if (f != null) { + return f.floatValue(); + } + return 0; + } + + private Float internalGetFloat(int columnIndex) throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return Float.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; + } + + public float getFloat(String columnName) throws SQLException { + int col = findColumn(columnName); + return getFloat(col); + } + + public long getLong(int columnIndex) throws SQLException { + Long l = internalGetLong(columnIndex); + if (l != null) { + return l.longValue(); + } + return 0; + } + + private Long internalGetLong(int columnIndex) throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return Long.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; + } + + public long getLong(String columnName) throws SQLException { + int col = findColumn(columnName); + return getLong(col); + } + + @Deprecated + public java.io.InputStream getUnicodeStream(int columnIndex) + throws SQLException { + throw new SQLException("not supported"); + } + + @Deprecated + public java.io.InputStream getUnicodeStream(String columnName) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.io.InputStream getAsciiStream(String columnName) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.io.InputStream getAsciiStream(int columnIndex) + throws SQLException { + throw new SQLException("not supported"); + } + + public BigDecimal getBigDecimal(String columnName) + throws SQLException { + throw new SQLException("not supported"); + } + + @Deprecated + public BigDecimal getBigDecimal(String columnName, int scale) + throws SQLException { + throw new SQLException("not supported"); + } + + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + throw new SQLException("not supported"); + } + + @Deprecated + public BigDecimal getBigDecimal(int columnIndex, int scale) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.io.InputStream getBinaryStream(int columnIndex) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.io.InputStream getBinaryStream(String columnName) + throws SQLException { + throw new SQLException("not supported"); + } + + public byte getByte(int columnIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public byte getByte(String columnName) throws SQLException { + throw new SQLException("not supported"); + } + + public byte[] getBytes(int columnIndex) throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + byte ret[] = null; + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + if (lastg != null) { + ret = SQLite.StringEncoder.decode(lastg); + } + return ret; + } + + public byte[] getBytes(String columnName) throws SQLException { + int col = findColumn(columnName); + return getBytes(col); + } + + public String getCursorName() throws SQLException { + return null; + } + + public Object getObject(int columnIndex) throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + Object ret = lastg; + if (tr instanceof TableResultX) { + switch (((TableResultX) tr).sql_type[columnIndex - 1]) { + case Types.SMALLINT: + ret = internalGetShort(columnIndex); + break; + case Types.INTEGER: + ret = internalGetInt(columnIndex); + break; + case Types.DOUBLE: + ret = internalGetDouble(columnIndex); + break; + case Types.FLOAT: + ret = internalGetFloat(columnIndex); + break; + case Types.BIGINT: + ret = internalGetLong(columnIndex); + break; + case Types.BINARY: + case Types.VARBINARY: + case Types.LONGVARBINARY: + ret = getBytes(columnIndex); + break; + case Types.NULL: + ret = null; + break; + /* defaults to String below */ + } + } + return ret; + } + + public Object getObject(String columnName) throws SQLException { + int col = findColumn(columnName); + return getObject(col); + } + + public Object getObject(int columnIndex, java.util.Map map) + throws SQLException { + throw new SQLException("not supported"); + } + + public Object getObject(String columnIndex, java.util.Map map) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Ref getRef(int columnIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Ref getRef(String columnIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Blob getBlob(int columnIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Blob getBlob(String columnIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Clob getClob(int columnIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Clob getClob(String columnIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Array getArray(int columnIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public java.sql.Array getArray(String columnIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public java.io.Reader getCharacterStream(int columnIndex) + throws SQLException { + throw new SQLException("not supported"); + } + + public java.io.Reader getCharacterStream(String columnName) + throws SQLException { + throw new SQLException("not supported"); + } + + public SQLWarning getWarnings() throws SQLException { + throw new SQLException("not supported"); + } + + public boolean wasNull() throws SQLException { + return lastg == null; + } + + public void clearWarnings() throws SQLException { + throw new SQLException("not supported"); + } + + public boolean isFirst() throws SQLException { + if (tr == null) { + return true; + } + return row == 0; + } + + public boolean isBeforeFirst() throws SQLException { + if (tr == null || tr.nrows <= 0) { + return false; + } + return row < 0; + } + + public void beforeFirst() throws SQLException { + if (tr == null) { + return; + } + row = -1; + } + + public boolean first() throws SQLException { + if (tr == null || tr.nrows <= 0) { + return false; + } + row = 0; + return true; + } + + public boolean isAfterLast() throws SQLException { + if (tr == null || tr.nrows <= 0) { + return false; + } + return row >= tr.nrows; + } + + public void afterLast() throws SQLException { + if (tr == null) { + return; + } + row = tr.nrows; + } + + public boolean isLast() throws SQLException { + if (tr == null) { + return true; + } + return row == tr.nrows - 1; + } + + public boolean last() throws SQLException { + if (tr == null || tr.nrows <= 0) { + return false; + } + row = tr.nrows -1; + return true; + } + + public int getType() throws SQLException { + return TYPE_SCROLL_INSENSITIVE; + } + + public int getConcurrency() throws SQLException { + return CONCUR_READ_ONLY; + } + + public boolean rowUpdated() throws SQLException { + throw new SQLException("not supported"); + } + + public boolean rowInserted() throws SQLException { + throw new SQLException("not supported"); + } + + public boolean rowDeleted() throws SQLException { + throw new SQLException("not supported"); + } + + public void insertRow() throws SQLException { + throw new SQLException("not supported"); + } + + public void updateRow() throws SQLException { + throw new SQLException("not supported"); + } + + public void deleteRow() throws SQLException { + throw new SQLException("not supported"); + } + + public void refreshRow() throws SQLException { + throw new SQLException("not supported"); + } + + public void cancelRowUpdates() throws SQLException { + throw new SQLException("not supported"); + } + + public void moveToInsertRow() throws SQLException { + throw new SQLException("not supported"); + } + + public void moveToCurrentRow() throws SQLException { + throw new SQLException("not supported"); + } + + public void updateNull(int colIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateBoolean(int colIndex, boolean b) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateByte(int colIndex, byte b) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateShort(int colIndex, short b) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateInt(int colIndex, int b) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateLong(int colIndex, long b) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateFloat(int colIndex, float f) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateDouble(int colIndex, double f) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateBigDecimal(int colIndex, BigDecimal f) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateString(int colIndex, String s) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateBytes(int colIndex, byte[] s) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateDate(int colIndex, java.sql.Date d) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateTime(int colIndex, java.sql.Time t) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateTimestamp(int colIndex, java.sql.Timestamp t) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateAsciiStream(int colIndex, java.io.InputStream in, int s) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateBinaryStream(int colIndex, java.io.InputStream in, int s) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateCharacterStream(int colIndex, java.io.Reader in, int s) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateObject(int colIndex, Object obj) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateObject(int colIndex, Object obj, int s) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateNull(String colIndex) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateBoolean(String colIndex, boolean b) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateByte(String colIndex, byte b) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateShort(String colIndex, short b) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateInt(String colIndex, int b) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateLong(String colIndex, long b) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateFloat(String colIndex, float f) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateDouble(String colIndex, double f) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateBigDecimal(String colIndex, BigDecimal f) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateString(String colIndex, String s) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateBytes(String colIndex, byte[] s) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateDate(String colIndex, java.sql.Date d) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateTime(String colIndex, java.sql.Time t) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateTimestamp(String colIndex, java.sql.Timestamp t) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateAsciiStream(String colIndex, java.io.InputStream in, + int s) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateBinaryStream(String colIndex, java.io.InputStream in, + int s) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateCharacterStream(String colIndex, java.io.Reader in, + int s) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateObject(String colIndex, Object obj) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateObject(String colIndex, Object obj, int s) + throws SQLException { + throw new SQLException("not supported"); + } + + public Statement getStatement() throws SQLException { + if (s == null) { + throw new SQLException("stale result set"); + } + return s; + } + + public void close() throws SQLException { + s = null; + tr = null; + lastg = null; + row = -1; + } + + public java.net.URL getURL(int colIndex) throws SQLException { + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[colIndex - 1]; + java.net.URL url = null; + if (lastg == null) { + return url; + } + try { + url = new java.net.URL(lastg); + } catch (java.lang.Exception e) { + url = null; + } + return url; + } + + public java.net.URL getURL(String colIndex) throws SQLException { + int col = findColumn(colIndex); + return getURL(col); + } + + public void updateRef(int colIndex, java.sql.Ref x) throws SQLException { + throw new SQLException("not supported"); + } + + public void updateRef(String colIndex, java.sql.Ref x) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateBlob(int colIndex, java.sql.Blob x) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateBlob(String colIndex, java.sql.Blob x) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateClob(int colIndex, java.sql.Clob x) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateClob(String colIndex, java.sql.Clob x) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateArray(int colIndex, java.sql.Array x) + throws SQLException { + throw new SQLException("not supported"); + } + + public void updateArray(String colIndex, java.sql.Array x) + throws SQLException { + throw new SQLException("not supported"); + } + +} diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java b/sql/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java new file mode 100644 index 0000000..934ca78 --- /dev/null +++ b/sql/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java @@ -0,0 +1,212 @@ +package SQLite.JDBC2y; + +import java.sql.*; + +public class JDBCResultSetMetaData implements java.sql.ResultSetMetaData { + + private JDBCResultSet r; + + public JDBCResultSetMetaData(JDBCResultSet r) { + this.r = r; + } + + public String getCatalogName(int column) throws java.sql.SQLException { + return null; + } + + public String getColumnClassName(int column) throws java.sql.SQLException { + column--; + if (r != null && r.tr != null) { + if (column < 0 || column >= r.tr.ncolumns) { + return null; + } + if (r.tr instanceof TableResultX) { + switch (((TableResultX) r.tr).sql_type[column]) { + case Types.SMALLINT: return "java.lang.Short"; + case Types.INTEGER: return "java.lang.Integer"; + case Types.DOUBLE: return "java.lang.Double"; + case Types.FLOAT: return "java.lang.Float"; + case Types.BIGINT: return "java.lang.Long"; + case Types.DATE: return "java.sql.Date"; + case Types.TIME: return "java.sql.Time"; + case Types.TIMESTAMP: return "java.sql.Timestamp"; + case Types.BINARY: + case Types.VARBINARY: return "[B"; + /* defaults to varchar below */ + } + } + return "java.lang.String"; + } + return null; + } + + public int getColumnCount() throws java.sql.SQLException { + if (r != null && r.tr != null) { + return r.tr.ncolumns; + } + return 0; + } + + public int getColumnDisplaySize(int column) throws java.sql.SQLException { + return 0; + } + + public String getColumnLabel(int column) throws java.sql.SQLException { + column--; + String c = null; + if (r != null && r.tr != null) { + if (column < 0 || column >= r.tr.ncolumns) { + return c; + } + c = r.tr.column[column]; + } + return c; + } + + public String getColumnName(int column) throws java.sql.SQLException { + column--; + String c = null; + if (r != null && r.tr != null) { + if (column < 0 || column >= r.tr.ncolumns) { + return c; + } + c = r.tr.column[column]; + if (c != null) { + int i = c.indexOf('.'); + if (i > 0) { + return c.substring(i + 1); + } + } + } + return c; + } + + public int getColumnType(int column) throws java.sql.SQLException { + column--; + if (r != null && r.tr != null) { + if (column >= 0 && column < r.tr.ncolumns) { + if (r.tr instanceof TableResultX) { + return ((TableResultX) r.tr).sql_type[column]; + } + return Types.VARCHAR; + } + } + throw new SQLException("bad column index"); + } + + public String getColumnTypeName(int column) throws java.sql.SQLException { + column--; + if (r != null && r.tr != null) { + if (column >= 0 && column < r.tr.ncolumns) { + if (r.tr instanceof TableResultX) { + switch (((TableResultX) r.tr).sql_type[column]) { + case Types.SMALLINT: return "smallint"; + case Types.INTEGER: return "integer"; + case Types.DOUBLE: return "double"; + case Types.FLOAT: return "float"; + case Types.BIGINT: return "bigint"; + case Types.DATE: return "date"; + case Types.TIME: return "time"; + case Types.TIMESTAMP: return "timestamp"; + case Types.BINARY: return "binary"; + case Types.VARBINARY: return "varbinary"; + /* defaults to varchar below */ + } + } + return "varchar"; + } + } + throw new SQLException("bad column index"); + } + + public int getPrecision(int column) throws java.sql.SQLException { + return 0; + } + + public int getScale(int column) throws java.sql.SQLException { + return 0; + } + + public String getSchemaName(int column) throws java.sql.SQLException { + return null; + } + + public String getTableName(int column) throws java.sql.SQLException { + column--; + String c = null; + if (r != null && r.tr != null) { + if (column < 0 || column >= r.tr.ncolumns) { + return c; + } + c = r.tr.column[column]; + if (c != null) { + int i = c.indexOf('.'); + if (i > 0) { + return c.substring(0, i); + } + c = null; + } + } + return c; + } + + public boolean isAutoIncrement(int column) throws java.sql.SQLException { + return false; + } + + public boolean isCaseSensitive(int column) throws java.sql.SQLException { + return false; + } + + public boolean isCurrency(int column) throws java.sql.SQLException { + return false; + } + + public boolean isDefinitelyWritable(int column) + throws java.sql.SQLException { + return true; + } + + public int isNullable(int column) throws java.sql.SQLException { + return columnNullableUnknown; + } + + public boolean isReadOnly(int column) throws java.sql.SQLException { + return false; + } + + public boolean isSearchable(int column) throws java.sql.SQLException { + return true; + } + + public boolean isSigned(int column) throws java.sql.SQLException { + return false; + } + + public boolean isWritable(int column) throws java.sql.SQLException { + return true; + } + + int findColByName(String columnName) throws java.sql.SQLException { + String c = null; + if (r != null && r.tr != null) { + for (int i = 0; i < r.tr.ncolumns; i++) { + c = r.tr.column[i]; + if (c != null) { + if (c.compareToIgnoreCase(columnName) == 0) { + return i + 1; + } + int k = c.indexOf('.'); + if (k > 0) { + c = c.substring(k + 1); + if (c.compareToIgnoreCase(columnName) == 0) { + return i + 1; + } + } + } + c = null; + } + } + throw new SQLException("column " + columnName + " not found"); + } +} diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCStatement.java b/sql/src/main/java/SQLite/JDBC2y/JDBCStatement.java new file mode 100644 index 0000000..99d12d3 --- /dev/null +++ b/sql/src/main/java/SQLite/JDBC2y/JDBCStatement.java @@ -0,0 +1,287 @@ +package SQLite.JDBC2y; + +import java.sql.*; +import java.util.*; + +public class JDBCStatement implements java.sql.Statement { + + protected JDBCConnection conn; + protected JDBCResultSet rs; + protected int updcnt; + private ArrayList<String> batch; + + public JDBCStatement(JDBCConnection conn) { + this.conn = conn; + this.updcnt = 0; + this.rs = null; + this.batch = null; + } + + public void setFetchSize(int fetchSize) throws SQLException { + throw new SQLException("not supported"); + } + + public int getFetchSize() throws SQLException { + return 1; + } + + public int getMaxRows() throws SQLException { + return 0; + } + + public void setMaxRows(int max) throws SQLException { + throw new SQLException("not supported"); + } + + public void setFetchDirection(int fetchDirection) throws SQLException { + throw new SQLException("not supported"); + } + + public int getFetchDirection() throws SQLException { + return ResultSet.FETCH_UNKNOWN; + } + + public int getResultSetConcurrency() throws SQLException { + return ResultSet.CONCUR_READ_ONLY; + } + + public int getResultSetType() throws SQLException { + return ResultSet.TYPE_SCROLL_INSENSITIVE; + } + + public void setQueryTimeout(int seconds) throws SQLException { + conn.timeout = seconds * 1000; + if (conn.timeout < 0) { + conn.timeout = 120000; + } else if (conn.timeout < 1000) { + conn.timeout = 5000; + } + } + + public int getQueryTimeout() throws SQLException { + return conn.timeout; + } + + public ResultSet getResultSet() throws SQLException { + return rs; + } + + ResultSet executeQuery(String sql, String args[], boolean updonly) + throws SQLException { + SQLite.TableResult tr = null; + if (rs != null) { + rs.close(); + rs = null; + } + updcnt = -1; + if (conn == null || conn.db == null) { + throw new SQLException("stale connection"); + } + int busy = 0; + boolean starttrans = !conn.autocommit && !conn.intrans; + while (true) { + try { + if (starttrans) { + conn.db.exec("BEGIN TRANSACTION", null); + conn.intrans = true; + } + if (args == null) { + if (updonly) { + conn.db.exec(sql, null); + } else { + tr = conn.db.get_table(sql); + } + } else { + if (updonly) { + conn.db.exec(sql, null, args); + } else { + tr = conn.db.get_table(sql, args); + } + } + updcnt = (int) conn.db.changes(); + } catch (SQLite.Exception e) { + if (conn.db.is3() && + conn.db.last_error() == SQLite.Constants.SQLITE_BUSY && + conn.busy3(conn.db, ++busy)) { + try { + if (starttrans && conn.intrans) { + conn.db.exec("ROLLBACK", null); + conn.intrans = false; + } + } catch (SQLite.Exception ee) { + } + try { + int ms = 20 + busy * 10; + if (ms > 1000) { + ms = 1000; + } + synchronized (this) { + this.wait(ms); + } + } catch (java.lang.Exception eee) { + } + continue; + } + throw new SQLException(e.toString()); + } + break; + } + if (!updonly && tr == null) { + throw new SQLException("no result set produced"); + } + if (!updonly && tr != null) { + rs = new JDBCResultSet(new TableResultX(tr), this); + } + return rs; + } + + public ResultSet executeQuery(String sql) throws SQLException { + return executeQuery(sql, null, false); + } + + public boolean execute(String sql) throws SQLException { + return executeQuery(sql) != null; + } + + public void cancel() throws SQLException { + if (conn == null || conn.db == null) { + throw new SQLException("stale connection"); + } + conn.db.interrupt(); + } + + public void clearWarnings() throws SQLException { + } + + public Connection getConnection() throws SQLException { + return conn; + } + + public void addBatch(String sql) throws SQLException { + if (batch == null) { + batch = new ArrayList<String>(1); + } + batch.add(sql); + } + + public int[] executeBatch() throws SQLException { + if (batch == null) { + return new int[0]; + } + int[] ret = new int[batch.size()]; + for (int i = 0; i < ret.length; i++) { + ret[i] = EXECUTE_FAILED; + } + int errs = 0; + for (int i = 0; i < ret.length; i++) { + try { + execute((String) batch.get(i)); + ret[i] = updcnt; + } catch (SQLException e) { + ++errs; + } + } + if (errs > 0) { + throw new BatchUpdateException("batch failed", ret); + } + return ret; + } + + public void clearBatch() throws SQLException { + if (batch != null) { + batch.clear(); + batch = null; + } + } + + public void close() throws SQLException { + clearBatch(); + conn = null; + } + + public int executeUpdate(String sql) throws SQLException { + executeQuery(sql, null, true); + return updcnt; + } + + public int getMaxFieldSize() throws SQLException { + return 0; + } + + public boolean getMoreResults() throws SQLException { + if (rs != null) { + rs.close(); + rs = null; + } + return false; + } + + public int getUpdateCount() throws SQLException { + return updcnt; + } + + public SQLWarning getWarnings() throws SQLException { + return null; + } + + public void setCursorName(String name) throws SQLException { + throw new SQLException("not supported"); + } + + public void setEscapeProcessing(boolean enable) throws SQLException { + throw new SQLException("not supported"); + } + + public void setMaxFieldSize(int max) throws SQLException { + throw new SQLException("not supported"); + } + + public boolean getMoreResults(int x) throws SQLException { + throw new SQLException("not supported"); + } + + public ResultSet getGeneratedKeys() throws SQLException { + throw new SQLException("not supported"); + } + + public int executeUpdate(String sql, int autokeys) + throws SQLException { + if (autokeys != Statement.NO_GENERATED_KEYS) { + throw new SQLException("not supported"); + } + return executeUpdate(sql); + } + + public int executeUpdate(String sql, int colIndexes[]) + throws SQLException { + throw new SQLException("not supported"); + } + + public int executeUpdate(String sql, String colIndexes[]) + throws SQLException { + throw new SQLException("not supported"); + } + + public boolean execute(String sql, int autokeys) + throws SQLException { + if (autokeys != Statement.NO_GENERATED_KEYS) { + throw new SQLException("not supported"); + } + return execute(sql); + } + + public boolean execute(String sql, int colIndexes[]) + throws SQLException { + throw new SQLException("not supported"); + } + + public boolean execute(String sql, String colIndexes[]) + throws SQLException { + throw new SQLException("not supported"); + } + + public int getResultSetHoldability() throws SQLException { + return ResultSet.HOLD_CURSORS_OVER_COMMIT; + } + +} diff --git a/sql/src/main/java/SQLite/JDBC2y/TableResultX.java b/sql/src/main/java/SQLite/JDBC2y/TableResultX.java new file mode 100644 index 0000000..205372f --- /dev/null +++ b/sql/src/main/java/SQLite/JDBC2y/TableResultX.java @@ -0,0 +1,37 @@ +package SQLite.JDBC2y; + +import java.sql.Types; +import java.util.Vector; + +public class TableResultX extends SQLite.TableResult { + public int sql_type[]; + + public TableResultX() { + super(); + sql_type = new int[this.ncolumns]; + for (int i = 0; i < this.ncolumns; i++) { + sql_type[i] = Types.VARCHAR; + } + } + + public TableResultX(SQLite.TableResult tr) { + this.column = tr.column; + this.rows = tr.rows; + this.ncolumns = tr.ncolumns; + this.nrows = tr.nrows; + this.types = tr.types; + sql_type = new int[tr.ncolumns]; + for (int i = 0; i < this.ncolumns; i++) { + sql_type[i] = Types.VARCHAR; + } + if (tr.types != null) { + for (int i = 0; i < tr.types.length; i++) { + sql_type[i] = JDBCDatabaseMetaData.mapSqlType(tr.types[i]); + } + } + } + + void sql_types(int types[]) { + sql_type = types; + } +} diff --git a/sql/src/main/java/SQLite/JDBCDriver.java b/sql/src/main/java/SQLite/JDBCDriver.java new file mode 100644 index 0000000..63b95ee --- /dev/null +++ b/sql/src/main/java/SQLite/JDBCDriver.java @@ -0,0 +1,109 @@ +package SQLite; + +import java.sql.*; +import java.util.Properties; + +public class JDBCDriver implements java.sql.Driver { + + public static final int MAJORVERSION = 1; + public static final int MINORVERSION = 2; + + private static java.lang.reflect.Constructor makeConn = null; + + protected Connection conn; + + static { + try { + Class connClass = null; + Class args[] = new Class[2]; + args[0] = Class.forName("java.lang.String"); + args[1] = args[0]; + String jvers = java.lang.System.getProperty("java.version"); + String cvers; + if (jvers == null || jvers.startsWith("1.0")) { + throw new java.lang.Exception("unsupported java version"); + } else if (jvers.startsWith("1.1")) { + cvers = "SQLite.JDBC1.JDBCConnection"; + } else if (jvers.startsWith("1.2") || jvers.startsWith("1.3")) { + cvers = "SQLite.JDBC2.JDBCConnection"; + } else if (jvers.startsWith("1.4")) { + cvers = "SQLite.JDBC2x.JDBCConnection"; + } else if (jvers.startsWith("1.5")) { + cvers = "SQLite.JDBC2y.JDBCConnection"; + try { + Class.forName(cvers); + } catch (java.lang.Exception e) { + cvers = "SQLite.JDBC2x.JDBCConnection"; + } + } else { + cvers = "SQLite.JDBC2z.JDBCConnection"; + try { + Class.forName(cvers); + } catch (java.lang.Exception e) { + cvers = "SQLite.JDBC2y.JDBCConnection"; + try { + Class.forName(cvers); + } catch (java.lang.Exception ee) { + cvers = "SQLite.JDBC2x.JDBCConnection"; + } + } + } + connClass = Class.forName(cvers); + makeConn = connClass.getConstructor(args); + java.sql.DriverManager.registerDriver(new JDBCDriver()); + } catch (java.lang.Exception e) { + System.err.println(e); + } + } + + public JDBCDriver() { + } + + public boolean acceptsURL(String url) throws SQLException { + return url.startsWith("sqlite:/") || + url.startsWith("jdbc:sqlite:/"); + } + + public Connection connect(String url, Properties info) + throws SQLException { + if (!acceptsURL(url)) { + return null; + } + Object args[] = new Object[2]; + args[0] = url; + if (info != null) { + args[1] = info.getProperty("encoding"); + } + if (args[1] == null) { + args[1] = java.lang.System.getProperty("SQLite.encoding"); + } + try { + conn = (Connection) makeConn.newInstance(args); + } catch (java.lang.reflect.InvocationTargetException ie) { + throw new SQLException(ie.getTargetException().toString()); + } catch (java.lang.Exception e) { + throw new SQLException(e.toString()); + } + return conn; + } + + public int getMajorVersion() { + return MAJORVERSION; + } + + public int getMinorVersion() { + return MINORVERSION; + } + + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) + throws SQLException { + DriverPropertyInfo p[] = new DriverPropertyInfo[1]; + DriverPropertyInfo pp = new DriverPropertyInfo("encoding", ""); + p[0] = pp; + return p; + } + + public boolean jdbcCompliant() { + return false; + } +} diff --git a/sql/src/main/java/SQLite/ProgressHandler.java b/sql/src/main/java/SQLite/ProgressHandler.java new file mode 100644 index 0000000..b2ec7c0 --- /dev/null +++ b/sql/src/main/java/SQLite/ProgressHandler.java @@ -0,0 +1,17 @@ +package SQLite; + +/** + * Callback interface for SQLite's user defined progress handler. + */ + +public interface ProgressHandler { + + /** + * Invoked for N SQLite VM opcodes. + * The method should return true to continue the + * current query, or false in order + * to abandon the action.<BR><BR> + */ + + public boolean progress(); +} diff --git a/sql/src/main/java/SQLite/Shell.java b/sql/src/main/java/SQLite/Shell.java new file mode 100644 index 0000000..78d37a1 --- /dev/null +++ b/sql/src/main/java/SQLite/Shell.java @@ -0,0 +1,669 @@ +package SQLite; + +import SQLite.*; +import java.io.*; +import java.util.*; + +/** + * SQLite command line shell. This is a partial reimplementaion + * of sqlite/src/shell.c and can be invoked by:<P> + * + * <verb> + * java SQLite.Shell [OPTIONS] database [SHELLCMD] + * or + * java -jar sqlite.jar [OPTIONS] database [SHELLCMD] + * </verb> + */ + +public class Shell implements Callback { + Database db; + boolean echo; + int count; + int mode; + boolean showHeader; + String tableName; + String sep; + String cols[]; + int colwidth[]; + String destTable; + PrintWriter pw; + PrintWriter err; + + static final int MODE_Line = 0; + static final int MODE_Column = 1; + static final int MODE_List = 2; + static final int MODE_Semi = 3; + static final int MODE_Html = 4; + static final int MODE_Insert = 5; + static final int MODE_Insert2 = 6; + + public Shell(PrintWriter pw, PrintWriter err) { + this.pw = pw; + this.err = err; + } + + public Shell(PrintStream ps, PrintStream errs) { + pw = new PrintWriter(ps); + err = new PrintWriter(errs); + } + + protected Object clone() { + Shell s = new Shell(this.pw, this.err); + s.db = db; + s.echo = echo; + s.mode = mode; + s.count = 0; + s.showHeader = showHeader; + s.tableName = tableName; + s.sep = sep; + s.colwidth = colwidth; + return s; + } + + static public String sql_quote_dbl(String str) { + if (str == null) { + return "NULL"; + } + int i, single = 0, dbl = 0; + for (i = 0; i < str.length(); i++) { + if (str.charAt(i) == '\'') { + single++; + } else if (str.charAt(i) == '"') { + dbl++; + } + } + if (dbl == 0) { + return "\"" + str + "\""; + } + StringBuffer sb = new StringBuffer("\""); + for (i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (c == '"') { + sb.append("\"\""); + } else { + sb.append(c); + } + } + return sb.toString(); + } + + static public String sql_quote(String str) { + if (str == null) { + return "NULL"; + } + int i, single = 0, dbl = 0; + for (i = 0; i < str.length(); i++) { + if (str.charAt(i) == '\'') { + single++; + } else if (str.charAt(i) == '"') { + dbl++; + } + } + if (single == 0) { + return "'" + str + "'"; + } + if (dbl == 0) { + return "\"" + str + "\""; + } + StringBuffer sb = new StringBuffer("'"); + for (i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (c == '\'') { + sb.append("''"); + } else { + sb.append(c); + } + } + return sb.toString(); + } + + static String html_quote(String str) { + if (str == null) { + return "NULL"; + } + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (c == '<') { + sb.append("<"); + } else if (c == '>') { + sb.append(">"); + } else if (c == '&') { + sb.append("&"); + } else { + int x = c; + if (x < 32 || x > 127) { + sb.append("&#" + x + ";"); + } else { + sb.append(c); + } + } + } + return sb.toString(); + } + + static boolean is_numeric(String str) { + try { + Double d = Double.valueOf(str); + } catch (java.lang.Exception e) { + return false; + } + return true; + } + + void set_table_name(String str) { + if (str == null) { + tableName = ""; + return; + } + tableName = Shell.sql_quote(str); + } + + public void columns(String args[]) { + cols = args; + } + + public void types(String args[]) { + /* Empty body to satisfy SQLite.Callback interface. */ + } + + public boolean newrow(String args[]) { + int i; + String tname; + switch (mode) { + case Shell.MODE_Line: + if (args.length == 0) { + break; + } + if (count++ > 0) { + pw.println(""); + } + for (i = 0; i < args.length; i++) { + pw.println(cols[i] + " = " + + args[i] == null ? "NULL" : args[i]); + } + break; + case Shell.MODE_Column: + String csep = ""; + if (count++ == 0) { + colwidth = new int[args.length]; + for (i = 0; i < args.length; i++) { + int w, n; + w = cols[i].length(); + if (w < 10) { + w = 10; + } + colwidth[i] = w; + if (showHeader) { + pw.print(csep + cols[i]); + csep = " "; + } + } + if (showHeader) { + pw.println(""); + } + } + if (args.length == 0) { + break; + } + csep = ""; + for (i = 0; i < args.length; i++) { + pw.print(csep + (args[i] == null ? "NULL" : args[i])); + csep = " "; + } + pw.println(""); + break; + case Shell.MODE_Semi: + case Shell.MODE_List: + if (count++ == 0 && showHeader) { + for (i = 0; i < args.length; i++) { + pw.print(cols[i] + + (i == args.length - 1 ? "\n" : sep)); + } + } + if (args.length == 0) { + break; + } + for (i = 0; i < args.length; i++) { + pw.print(args[i] == null ? "NULL" : args[i]); + if (mode == Shell.MODE_Semi) { + pw.print(";"); + } else if (i < args.length - 1) { + pw.print(sep); + } + } + pw.println(""); + break; + case MODE_Html: + if (count++ == 0 && showHeader) { + pw.print("<TR>"); + for (i = 0; i < args.length; i++) { + pw.print("<TH>" + html_quote(cols[i]) + "</TH>"); + } + pw.println("</TR>"); + } + if (args.length == 0) { + break; + } + pw.print("<TR>"); + for (i = 0; i < args.length; i++) { + pw.print("<TD>" + html_quote(args[i]) + "</TD>"); + } + pw.println("</TR>"); + break; + case MODE_Insert: + if (args.length == 0) { + break; + } + tname = tableName; + if (destTable != null) { + tname = destTable; + } + pw.print("INSERT INTO " + tname + " VALUES("); + for (i = 0; i < args.length; i++) { + String tsep = i > 0 ? "," : ""; + if (args[i] == null) { + pw.print(tsep + "NULL"); + } else if (is_numeric(args[i])) { + pw.print(tsep + args[i]); + } else { + pw.print(tsep + sql_quote(args[i])); + } + } + pw.println(");"); + break; + case MODE_Insert2: + if (args.length == 0) { + break; + } + tname = tableName; + if (destTable != null) { + tname = destTable; + } + pw.print("INSERT INTO " + tname + " VALUES("); + for (i = 0; i < args.length; i++) { + String tsep = i > 0 ? "," : ""; + pw.print(tsep + args[i]); + } + pw.println(");"); + break; + } + return false; + } + + void do_meta(String line) { + StringTokenizer st = new StringTokenizer(line.toLowerCase()); + int n = st.countTokens(); + if (n <= 0) { + return; + } + String cmd = st.nextToken(); + String args[] = new String[n - 1]; + int i = 0; + while (st.hasMoreTokens()) { + args[i] = st.nextToken(); + ++i; + } + if (cmd.compareTo(".dump") == 0) { + new DBDump(this, args); + return; + } + if (cmd.compareTo(".echo") == 0) { + if (args.length > 0 && + (args[0].startsWith("y") || args[0].startsWith("on"))) { + echo = true; + } + return; + } + if (cmd.compareTo(".exit") == 0) { + try { + db.close(); + } catch (Exception e) { + } + System.exit(0); + } + if (cmd.compareTo(".header") == 0) { + if (args.length > 0 && + (args[0].startsWith("y") || args[0].startsWith("on"))) { + showHeader = true; + } + return; + } + if (cmd.compareTo(".help") == 0) { + pw.println(".dump ?TABLE? ... Dump database in text fmt"); + pw.println(".echo ON|OFF Command echo on or off"); + pw.println(".enc ?NAME? Change encoding"); + pw.println(".exit Exit program"); + pw.println(".header ON|OFF Display headers on or off"); + pw.println(".help This message"); + pw.println(".mode MODE Set output mode to\n" + + " line, column, insert\n" + + " list, or html"); + pw.println(".mode insert TABLE Generate SQL insert stmts"); + pw.println(".schema ?PATTERN? List table schema"); + pw.println(".separator STRING Set separator string"); + pw.println(".tables ?PATTERN? List table names"); + return; + } + if (cmd.compareTo(".mode") == 0) { + if (args.length > 0) { + if (args[0].compareTo("line") == 0) { + mode = Shell.MODE_Line; + } else if (args[0].compareTo("column") == 0) { + mode = Shell.MODE_Column; + } else if (args[0].compareTo("list") == 0) { + mode = Shell.MODE_List; + } else if (args[0].compareTo("html") == 0) { + mode = Shell.MODE_Html; + } else if (args[0].compareTo("insert") == 0) { + mode = Shell.MODE_Insert; + if (args.length > 1) { + destTable = args[1]; + } + } + } + return; + } + if (cmd.compareTo(".separator") == 0) { + if (args.length > 0) { + sep = args[0]; + } + return; + } + if (cmd.compareTo(".tables") == 0) { + TableResult t = null; + if (args.length > 0) { + try { + String qarg[] = new String[1]; + qarg[0] = args[0]; + t = db.get_table("SELECT name FROM sqlite_master " + + "WHERE type='table' AND " + + "name LIKE '%%%q%%' " + + "ORDER BY name", qarg); + } catch (Exception e) { + err.println("SQL Error: " + e); + err.flush(); + } + } else { + try { + t = db.get_table("SELECT name FROM sqlite_master " + + "WHERE type='table' ORDER BY name"); + } catch (Exception e) { + err.println("SQL Error: " + e); + err.flush(); + } + } + if (t != null) { + for (i = 0; i < t.nrows; i++) { + String tab = ((String[]) t.rows.elementAt(i))[0]; + if (tab != null) { + pw.println(tab); + } + } + } + return; + } + if (cmd.compareTo(".schema") == 0) { + if (args.length > 0) { + try { + String qarg[] = new String[1]; + qarg[0] = args[0]; + db.exec("SELECT sql FROM sqlite_master " + + "WHERE type!='meta' AND " + + "name LIKE '%%%q%%' AND " + + "sql NOTNULL " + + "ORDER BY type DESC, name", + this, qarg); + } catch (Exception e) { + err.println("SQL Error: " + e); + err.flush(); + } + } else { + try { + db.exec("SELECT sql FROM sqlite_master " + + "WHERE type!='meta' AND " + + "sql NOTNULL " + + "ORDER BY tbl_name, type DESC, name", + this); + } catch (Exception e) { + err.println("SQL Error: " + e); + err.flush(); + } + } + return; + } + if (cmd.compareTo(".enc") == 0) { + try { + db.set_encoding(args.length > 0 ? args[0] : null); + } catch (Exception e) { + err.println("" + e); + err.flush(); + } + return; + } + err.println("Unknown command '" + cmd + "'"); + err.flush(); + } + + String read_line(BufferedReader is, String prompt) { + try { + if (prompt != null) { + pw.print(prompt); + pw.flush(); + } + String line = is.readLine(); + return line; + } catch (IOException e) { + return null; + } + } + + void do_input(BufferedReader is) { + String line, sql = null; + String prompt = "SQLITE> "; + while ((line = read_line(is, prompt)) != null) { + if (echo) { + pw.println(line); + } + if (line.length() > 0 && line.charAt(0) == '.') { + do_meta(line); + } else { + if (sql == null) { + sql = line; + } else { + sql = sql + " " + line; + } + if (Database.complete(sql)) { + try { + db.exec(sql, this); + } catch (Exception e) { + if (!echo) { + err.println(sql); + } + err.println("SQL Error: " + e); + err.flush(); + } + sql = null; + prompt = "SQLITE> "; + } else { + prompt = "SQLITE? "; + } + } + pw.flush(); + } + if (sql != null) { + err.println("Incomplete SQL: " + sql); + err.flush(); + } + } + + void do_cmd(String sql) { + if (db == null) { + return; + } + if (sql.length() > 0 && sql.charAt(0) == '.') { + do_meta(sql); + } else { + try { + db.exec(sql, this); + } catch (Exception e) { + err.println("SQL Error: " + e); + err.flush(); + } + } + } + + public static void main(String args[]) { + Shell s = new Shell(System.out, System.err); + s.mode = Shell.MODE_List; + s.sep = "|"; + s.showHeader = false; + s.db = new Database(); + String dbname = null, sql = null; + for (int i = 0; i < args.length; i++) { + if(args[i].compareTo("-html") ==0) { + s.mode = Shell.MODE_Html; + } else if (args[i].compareTo("-list") == 0) { + s.mode = Shell.MODE_List; + } else if (args[i].compareTo("-line") == 0) { + s.mode = Shell.MODE_Line; + } else if (i < args.length - 1 && + args[i].compareTo("-separator") == 0) { + ++i; + s.sep = args[i]; + } else if (args[i].compareTo("-header") == 0) { + s.showHeader = true; + } else if (args[i].compareTo("-noheader") == 0) { + s.showHeader = false; + } else if (args[i].compareTo("-echo") == 0) { + s.echo = true; + } else if (dbname == null) { + dbname = args[i]; + } else if (sql == null) { + sql = args[i]; + } else { + System.err.println("Arguments: ?OPTIONS? FILENAME ?SQL?"); + System.exit(1); + } + } + if (dbname == null) { + System.err.println("No database file given"); + System.exit(1); + } + try { + s.db.open(dbname, 0); + } catch (Exception e) { + System.err.println("Unable to open database: " + e); + System.exit(1); + } + if (sql != null) { + s.do_cmd(sql); + } else { + // BEGIN android-modified + BufferedReader is = + new BufferedReader(new InputStreamReader(System.in), 8192); + // END android-modified + s.do_input(is); + } + try { + s.db.close(); + } catch (Exception ee) { + } + } +} + +/** + * Internal class for dumping an entire database. + * It contains a special callback interface to traverse the + * tables of the current database and output create SQL statements + * and for the data insert SQL statements. + */ + +class DBDump implements Callback { + Shell s; + + DBDump(Shell s, String tables[]) { + this.s = s; + s.pw.println("BEGIN TRANSACTION;"); + if (tables == null || tables.length == 0) { + try { + s.db.exec("SELECT name, type, sql FROM sqlite_master " + + "WHERE type!='meta' AND sql NOT NULL " + + "ORDER BY substr(type,2,1), name", this); + } catch (Exception e) { + s.err.println("SQL Error: " + e); + s.err.flush(); + } + } else { + String arg[] = new String[1]; + for (int i = 0; i < tables.length; i++) { + arg[0] = tables[i]; + try { + s.db.exec("SELECT name, type, sql FROM sqlite_master " + + "WHERE tbl_name LIKE '%q' AND type!='meta' " + + " AND sql NOT NULL " + + " ORDER BY substr(type,2,1), name", + this, arg); + } catch (Exception e) { + s.err.println("SQL Error: " + e); + s.err.flush(); + } + } + } + s.pw.println("COMMIT;"); + } + + public void columns(String col[]) { + /* Empty body to satisfy SQLite.Callback interface. */ + } + + public void types(String args[]) { + /* Empty body to satisfy SQLite.Callback interface. */ + } + + public boolean newrow(String args[]) { + if (args.length != 3) { + return true; + } + s.pw.println(args[2] + ";"); + if (args[1].compareTo("table") == 0) { + Shell s2 = (Shell) s.clone(); + s2.mode = Shell.MODE_Insert; + s2.set_table_name(args[0]); + String qargs[] = new String[1]; + qargs[0] = args[0]; + try { + if (s2.db.is3()) { + TableResult t = null; + t = s2.db.get_table("PRAGMA table_info('%q')", qargs); + String query; + if (t != null) { + StringBuffer sb = new StringBuffer(); + String sep = ""; + + sb.append("SELECT "); + for (int i = 0; i < t.nrows; i++) { + String col = ((String[]) t.rows.elementAt(i))[1]; + sb.append(sep + "quote(" + + Shell.sql_quote_dbl(col) + ")"); + sep = ","; + } + sb.append(" from '%q'"); + query = sb.toString(); + s2.mode = Shell.MODE_Insert2; + } else { + query = "SELECT * from '%q'"; + } + s2.db.exec(query, s2, qargs); + } else { + s2.db.exec("SELECT * from '%q'", s2, qargs); + } + } catch (Exception e) { + s.err.println("SQL Error: " + e); + s.err.flush(); + return true; + } + } + return false; + } +} diff --git a/sql/src/main/java/SQLite/Stmt.java b/sql/src/main/java/SQLite/Stmt.java new file mode 100644 index 0000000..c4f72ed --- /dev/null +++ b/sql/src/main/java/SQLite/Stmt.java @@ -0,0 +1,288 @@ +package SQLite; + +/** + * Class to represent compiled SQLite3 statement. + * + * Note, that all native methods of this class are + * not synchronized, i.e. it is up to the caller + * to ensure that only one thread is in these + * methods at any one time. + */ + +public class Stmt { + + /** + * Internal handle for the SQLite3 statement. + */ + + private long handle = 0; + + /** + * Internal last error code for prepare()/step() methods. + */ + + protected int error_code = 0; + + /** + * Prepare the next SQL statement for the Stmt instance. + * @return true when the next piece of the SQL statement sequence + * has been prepared, false on end of statement sequence. + */ + + public native boolean prepare() throws SQLite.Exception; + + /** + * Perform one step of compiled SQLite3 statement. + * + * Example:<BR> + * <PRE> + * ... + * try { + * Stmt s = db.prepare("select * from x; select * from y;"); + * s.bind(...); + * ... + * s.bind(...); + * while (s.step(cb)) { + * Object o = s.value(...); + * ... + * } + * // s.reset() for re-execution or + * // s.prepare() for the next piece of SQL + * while (s.prepare()) { + * s.bind(...); + * ... + * s.bind(...); + * while (s.step(cb)) { + * Object o = s.value(...); + * ... + * } + * } + * } catch (SQLite.Exception e) { + * s.close(); + * } + * </PRE> + * + * @return true when row data is available, false on end + * of result set. + */ + + public native boolean step() throws SQLite.Exception; + + /** + * Close the compiled SQLite3 statement. + */ + + public native void close() throws SQLite.Exception; + + /** + * Reset the compiled SQLite3 statement without + * clearing parameter bindings. + */ + + public native void reset() throws SQLite.Exception; + + /** + * Clear all bound parameters of the compiled SQLite3 statement. + */ + + public native void clear_bindings() throws SQLite.Exception; + + /** + * Bind positional integer value to compiled SQLite3 statement. + * @param pos parameter index, 1-based + * @param value value of parameter + */ + + public native void bind(int pos, int value) throws SQLite.Exception; + + /** + * Bind positional long value to compiled SQLite3 statement. + * @param pos parameter index, 1-based + * @param value value of parameter + */ + + public native void bind(int pos, long value) throws SQLite.Exception; + + /** + * Bind positional double value to compiled SQLite3 statement. + * @param pos parameter index, 1-based + * @param value value of parameter + */ + + public native void bind(int pos, double value) throws SQLite.Exception; + + /** + * Bind positional byte array to compiled SQLite3 statement. + * @param pos parameter index, 1-based + * @param value value of parameter, may be null + */ + + public native void bind(int pos, byte[] value) throws SQLite.Exception; + + /** + * Bind positional String to compiled SQLite3 statement. + * @param pos parameter index, 1-based + * @param value value of parameter, may be null + */ + + public native void bind(int pos, String value) throws SQLite.Exception; + + /** + * Bind positional SQL null to compiled SQLite3 statement. + * @param pos parameter index, 1-based + */ + + public native void bind(int pos) throws SQLite.Exception; + + /** + * Bind positional zero'ed blob to compiled SQLite3 statement. + * @param pos parameter index, 1-based + * @param length byte size of zero blob + */ + + public native void bind_zeroblob(int pos, int length) + throws SQLite.Exception; + + /** + * Return number of parameters in compiled SQLite3 statement. + * @return int number of parameters + */ + + public native int bind_parameter_count() throws SQLite.Exception; + + /** + * Return name of parameter in compiled SQLite3 statement. + * @param pos parameter index, 1-based + * @return String parameter name + */ + + public native String bind_parameter_name(int pos) throws SQLite.Exception; + + /** + * Return index of named parameter in compiled SQLite3 statement. + * @param name of parameter + * @return int index of parameter, 1-based + */ + + public native int bind_parameter_index(String name) + throws SQLite.Exception; + + + /** + * Retrieve integer column from exec'ed SQLite3 statement. + * @param col column number, 0-based + * @return int column value + */ + + public native int column_int(int col) throws SQLite.Exception; + + /** + * Retrieve long column from exec'ed SQLite3 statement. + * @param col column number, 0-based + * @return long column value + */ + public native long column_long(int col) throws SQLite.Exception; + + /** + * Retrieve double column from exec'ed SQLite3 statement. + * @param col column number, 0-based + * @return double column value + */ + public native double column_double(int col) throws SQLite.Exception; + + /** + * Retrieve blob column from exec'ed SQLite3 statement. + * @param col column number, 0-based + * @return byte[] column value + */ + public native byte[] column_bytes(int col) throws SQLite.Exception; + + /** + * Retrieve string column from exec'ed SQLite3 statement. + * @param col column number, 0-based + * @return String column value + */ + public native String column_string(int col) throws SQLite.Exception; + + /** + * Retrieve column type from exec'ed SQLite3 statement. + * @param col column number, 0-based + * @return column type code, e.g. SQLite.Constants.SQLITE_INTEGER + */ + public native int column_type(int col) throws SQLite.Exception; + + /** + * Retrieve number of columns of exec'ed SQLite3 statement. + * @return int number of columns + */ + + public native int column_count() throws SQLite.Exception; + + /** + * Retrieve column data as object from exec'ed SQLite3 statement. + * @param col column number, 0-based + * @return Object or null + */ + + public Object column(int col) throws SQLite.Exception { + switch (column_type(col)) { + case Constants.SQLITE_INTEGER: + return new Long(column_long(col)); + case Constants.SQLITE_FLOAT: + return new Double(column_double(col)); + case Constants.SQLITE_BLOB: + return column_bytes(col); + case Constants.SQLITE3_TEXT: + return column_string(col); + } + return null; + } + + /** + * Return table name of column of SQLite3 statement. + * @param col column number, 0-based + * @return String or null + */ + + public native String column_table_name(int col) throws SQLite.Exception; + + /** + * Return database name of column of SQLite3 statement. + * @param col column number, 0-based + * @return String or null + */ + + public native String column_database_name(int col) throws SQLite.Exception; + + /** + * Return declared column type of SQLite3 statement. + * @param col column number, 0-based + * @return String or null + */ + + public native String column_decltype(int col) throws SQLite.Exception; + + /** + * Return origin column name of column of SQLite3 statement. + * @param col column number, 0-based + * @return String or null + */ + + public native String column_origin_name(int col) throws SQLite.Exception; + + /** + * Destructor for object. + */ + + protected native void finalize(); + + /** + * Internal native initializer. + */ + + private static native void internal_init(); + + static { + internal_init(); + } +} diff --git a/sql/src/main/java/SQLite/StringEncoder.java b/sql/src/main/java/SQLite/StringEncoder.java new file mode 100644 index 0000000..c2f20ad --- /dev/null +++ b/sql/src/main/java/SQLite/StringEncoder.java @@ -0,0 +1,201 @@ +package SQLite; + +/** + * String encoder/decoder for SQLite. + * + * This module was kindly donated by Eric van der Maarel of Nedap N.V. + * + * This encoder was implemented based on an original idea from an anonymous + * author in the source code of the SQLite distribution. + * I feel obliged to provide a quote from the original C-source code: + * + * "The author disclaims copyright to this source code. In place of + * a legal notice, here is a blessing: + * + * May you do good and not evil. + * May you find forgiveness for yourself and forgive others. + * May you share freely, never taking more than you give." + * + */ + +public class StringEncoder { + + /** + * Encodes the given byte array into a string that can be used by + * the SQLite database. The database cannot handle null (0x00) and + * the character '\'' (0x27). The encoding consists of escaping + * these characters with a reserved character (0x01). The escaping + * is applied after determining and applying a shift that minimizes + * the number of escapes required. + * With this encoding the data of original size n is increased to a + * maximum of 1+(n*257)/254. + * For sufficiently large n the overhead is thus less than 1.2%. + * @param a the byte array to be encoded. A null reference is handled as + * an empty array. + * @return the encoded bytes as a string. When an empty array is + * provided a string of length 1 is returned, the value of + * which is bogus. + * When decoded with this class' <code>decode</code> method + * a string of size 1 will return an empty byte array. + */ + + public static String encode(byte[] a) { + // check input + if (a == null || a.length == 0) { + // bogus shift, no data + return "x"; + } + // determine count + int[] cnt = new int[256]; + for (int i = 0 ; i < a.length; i++) { + cnt[a[i] & 0xff]++; + } + // determine shift for minimum number of escapes + int shift = 1; + int nEscapes = a.length; + for (int i = 1; i < 256; i++) { + if (i == '\'') { + continue; + } + int sum = cnt[i] + cnt[(i + 1) & 0xff] + cnt[(i + '\'') & 0xff]; + if (sum < nEscapes) { + nEscapes = sum; + shift = i; + if (nEscapes == 0) { + // cannot become smaller + break; + } + } + } + // construct encoded output + int outLen = a.length + nEscapes + 1; + StringBuffer out = new StringBuffer(outLen); + out.append((char)shift); + for (int i = 0; i < a.length; i++) { + // apply shift + char c = (char)((a[i] - shift)&0xff); + // insert escapes + if (c == 0) { // forbidden + out.append((char)1); + out.append((char)1); + } else if (c == 1) { // escape character + out.append((char)1); + out.append((char)2); + } else if (c == '\'') { // forbidden + out.append((char)1); + out.append((char)3); + } else { + out.append(c); + } + } + return out.toString(); + } + + /** + * Decodes the given string that is assumed to be a valid encoding + * of a byte array. Typically the given string is generated by + * this class' <code>encode</code> method. + * @param s the given string encoding. + * @return the byte array obtained from the decoding. + * @throws IllegalArgumentException when the string given is not + * a valid encoded string for this encoder. + */ + + public static byte[] decode(String s) { + char[] a = s.toCharArray(); + if (a.length > 2 && a[0] == 'X' && + a[1] == '\'' && a[a.length-1] == '\'') { + // SQLite3 BLOB syntax + byte[] result = new byte[(a.length-3)/2]; + for (int i = 2, k = 0; i < a.length - 1; i += 2, k++) { + byte tmp = (byte) (a[i] - '0'); + if (tmp > 15) { + tmp -= 0x20; + } + result[k] = (byte) (tmp << 4); + tmp = (byte) (a[i+1] - '0'); + if (tmp > 15) { + tmp -= 0x20; + } + result[k] |= tmp; + } + return result; + } + // first element is the shift + byte[] result = new byte[a.length-1]; + int i = 0; + int shift = s.charAt(i++); + int j = 0; + while (i < s.length()) { + int c; + if ((c = s.charAt(i++)) == 1) { // escape character found + if ((c = s.charAt(i++)) == 1) { + c = 0; + } else if (c == 2) { + c = 1; + } else if (c == 3) { + c = '\''; + } else { + throw new IllegalArgumentException( + "invalid string passed to decoder: " + j); + } + } + // do shift + result[j++] = (byte)((c + shift) & 0xff); + } + int outLen = j; + // provide array of correct length + if (result.length != outLen) { + result = byteCopy(result, 0, outLen, new byte[outLen]); + } + return result; + } + + /** + * Copies count elements from source, starting at element with + * index offset, to the given target. + * @param source the source. + * @param offset the offset. + * @param count the number of elements to be copied. + * @param target the target to be returned. + * @return the target being copied to. + */ + + private static byte[] byteCopy(byte[] source, int offset, + int count, byte[] target) { + for (int i = offset, j = 0; i < offset + count; i++, j++) { + target[j] = source[i]; + } + return target; + } + + + static final char[] xdigits = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + + /** + * Encodes the given byte array into SQLite3 blob notation, ie X'..' + * @param a the byte array to be encoded. A null reference is handled as + * an empty array. + * @return the encoded bytes as a string. + */ + + public static String encodeX(byte[] a) { + // check input + if (a == null || a.length == 0) { + return "X''"; + } + int outLen = a.length + 3; + StringBuffer out = new StringBuffer(outLen); + out.append('X'); + out.append('\''); + for (int i = 0; i < a.length; i++) { + out.append(xdigits[a[i] >> 4]); + out.append(xdigits[a[i] & 0x0F]); + } + out.append('\''); + return out.toString(); + } +} diff --git a/sql/src/main/java/SQLite/TableResult.java b/sql/src/main/java/SQLite/TableResult.java new file mode 100644 index 0000000..1a7fb57 --- /dev/null +++ b/sql/src/main/java/SQLite/TableResult.java @@ -0,0 +1,133 @@ +package SQLite; + +import java.util.Vector; + +/** + * Class representing an SQLite result set as + * returned by the + * <A HREF="Database.html#get_table(java.lang.String)">Database.get_table</A> + * convenience method. + * <BR><BR> + * Example:<BR> + * + * <PRE> + * ... + * SQLite.Database db = new SQLite.Database(); + * db.open("db", 0); + * System.out.print(db.get_table("select * from TEST")); + * ... + * </PRE> + * Example output:<BR> + * + * <PRE> + * id|firstname|lastname| + * 0|John|Doe| + * 1|Speedy|Gonzales| + * ... + * </PRE> + */ + +public class TableResult implements Callback { + + /** + * Number of columns in the result set. + */ + + public int ncolumns; + + /** + * Number of rows in the result set. + */ + + public int nrows; + + /** + * Column names of the result set. + */ + + public String column[]; + + /** + * Types of columns of the result set or null. + */ + + public String types[]; + + /** + * Rows of the result set. Each row is stored as a String array. + */ + + public Vector rows; + + /** + * Create an empty result set. + */ + + public TableResult() { + clear(); + } + + /** + * Clear result set. + */ + + public void clear() { + column = new String[0]; + types = null; + rows = new Vector(); + ncolumns = nrows = 0; + } + + /** + * Callback method used while the query is executed. + */ + + public void columns(String coldata[]) { + column = coldata; + ncolumns = column.length; + } + + /** + * Callback method used while the query is executed. + */ + + public void types(String types[]) { + this.types = types; + } + + /** + * Callback method used while the query is executed. + */ + + public boolean newrow(String rowdata[]) { + if (rowdata != null) { + rows.addElement(rowdata); + nrows++; + } + return false; + } + + /** + * Make String representation of result set. + */ + + public String toString() { + StringBuffer sb = new StringBuffer(); + int i; + for (i = 0; i < ncolumns; i++) { + sb.append(column[i] == null ? "NULL" : column[i]); + sb.append('|'); + } + sb.append('\n'); + for (i = 0; i < nrows; i++) { + int k; + String row[] = (String[]) rows.elementAt(i); + for (k = 0; k < ncolumns; k++) { + sb.append(row[k] == null ? "NULL" : row[k]); + sb.append('|'); + } + sb.append('\n'); + } + return sb.toString(); + } +} diff --git a/sql/src/main/java/SQLite/Trace.java b/sql/src/main/java/SQLite/Trace.java new file mode 100644 index 0000000..19ed2a1 --- /dev/null +++ b/sql/src/main/java/SQLite/Trace.java @@ -0,0 +1,17 @@ +package SQLite; + +/** + * Callback interface for SQLite's trace function. + */ + +public interface Trace { + + /** + * Callback to trace (ie log) one SQL statement. + * + * @param stmt SQL statement string + */ + + public void trace(String stmt); +} + diff --git a/sql/src/main/java/SQLite/Vm.java b/sql/src/main/java/SQLite/Vm.java new file mode 100644 index 0000000..9856ed0 --- /dev/null +++ b/sql/src/main/java/SQLite/Vm.java @@ -0,0 +1,78 @@ +package SQLite; + +/** + * Class to represent compiled SQLite VM. + */ + +public class Vm { + + /** + * Internal handle for the compiled SQLite VM. + */ + + private long handle = 0; + + /** + * Internal last error code for compile()/step() methods. + */ + + protected int error_code = 0; + + /** + * Perform one step on compiled SQLite VM. + * The result row is passed to the given callback interface.<BR><BR> + * + * Example:<BR> + * <PRE> + * ... + * try { + * Vm vm = db.compile("select * from x; select * from y;"); + * while (vm.step(cb)) { + * ... + * } + * while (vm.compile()) { + * while (vm.step(cb)) { + * ... + * } + * } + * } catch (SQLite.Exception e) { + * } + * </PRE> + * + * @param cb the object implementing the callback methods. + * @return true as long as more row data can be retrieved, + * false, otherwise. + */ + + public native boolean step(Callback cb) throws SQLite.Exception; + + /** + * Compile the next SQL statement for the SQLite VM instance. + * @return true when SQL statement has been compiled, false + * on end of statement sequence. + */ + + public native boolean compile() throws SQLite.Exception; + + /** + * Abort the compiled SQLite VM. + */ + + public native void stop() throws SQLite.Exception; + + /** + * Destructor for object. + */ + + protected native void finalize(); + + /** + * Internal native initializer. + */ + + private static native void internal_init(); + + static { + internal_init(); + } +} diff --git a/sql/src/main/java/java/sql/Array.java b/sql/src/main/java/java/sql/Array.java new file mode 100644 index 0000000..6113c46 --- /dev/null +++ b/sql/src/main/java/java/sql/Array.java @@ -0,0 +1,178 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.util.Map; + +/** + * A Java representation of the SQL {@code ARRAY} type. + * + * @since Android 1.0 + */ +public interface Array { + + /** + * Retrieves the contents of the SQL {@code ARRAY} value as a Java array + * object. + * + * @return A Java array containing the elements of this Array + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public Object getArray() throws SQLException; + + /** + * Returns part of the SQL {@code ARRAY} associated with this array, + * starting at a particular {@code index} and comprising up to {@code count} + * successive elements of the SQL array. + * + * @param index + * the start position in the array where the values are + * retrieved. + * @param count + * the number of elements to retrieve. + * @return A Java array containing the desired set of elements from this Array + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public Object getArray(long index, int count) throws SQLException; + + /** + * Returns part of the SQL {@code ARRAY} associated with this array, + * starting at a particular {@code index} and comprising up to {@code count} + * successive elements of the SQL array. + * + * @param index + * the start position in the array where the values are + * retrieved. + * @param count + * the number of elements to retrieve. + * @param map + * the map defining the correspondence between SQL type names + * and Java types. + * @return A Java array containing the desired set of elements from this Array + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public Object getArray(long index, int count, Map<String, Class<?>> map) + throws SQLException; + + /** + * Returns the data from the underlying SQL {@code ARRAY} as a Java array. + * + * @param map + * the map defining the correspondence between SQL type names + * and Java types. + * @return A Java array containing the elements of this array + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public Object getArray(Map<String, Class<?>> map) throws SQLException; + + /** + * Returns the JDBC type of the entries in this array's underlying + * SQL array. + * + * @return An integer constant from the {@code java.sql.Types} class + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public int getBaseType() throws SQLException; + + /** + * Returns the SQL type name of the entries in this array's underlying + * SQL array. + * + * @return The database specific name or a fully-qualified SQL type name. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public String getBaseTypeName() throws SQLException; + + /** + * Returns a ResultSet object which holds the entries of the SQL {@code + * ARRAY} associated with this array. + * + * @return the elements of the array as a {@code ResultSet}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public ResultSet getResultSet() throws SQLException; + + /** + * Returns a {@code ResultSet} object that holds the entries of a subarray, + * beginning at a particular index and comprising up to {@code count} + * successive entries. + * + * @param index + * the start position in the array where the values are + * retrieved. + * @param count + * the number of elements to retrieve. + * @return the elements of the array as a {@code ResultSet}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public ResultSet getResultSet(long index, int count) throws SQLException; + + /** + * Returns a {@code ResultSet} object that holds the entries of a subarray, + * beginning at a particular index and comprising up to {@code count} + * successive entries. + * + * @param index + * the start position in the array where the values are + * retrieved. + * @param count + * the number of elements to retrieve. + * @param map + * the map defining the correspondence between SQL type names + * and Java types. + * @return the {@code ResultSet} the array's custom type values. if a + * database error has occurred. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public ResultSet getResultSet(long index, int count, + Map<String, Class<?>> map) throws SQLException; + + /** + * Returns a {@code ResultSet} object which holds the entries of the SQL + * {@code ARRAY} associated with this array. + * + * @param map + * the map defining the correspondence between SQL type names + * and Java types. + * @return the array as a {@code ResultSet}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public ResultSet getResultSet(Map<String, Class<?>> map) + throws SQLException; + +} diff --git a/sql/src/main/java/java/sql/BatchUpdateException.java b/sql/src/main/java/java/sql/BatchUpdateException.java new file mode 100644 index 0000000..36a7ef9 --- /dev/null +++ b/sql/src/main/java/java/sql/BatchUpdateException.java @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.io.Serializable; + +/** + * This exception is thrown if a problem occurs during a batch update operation. + * <p> + * A {@code BatchUpdateException} provides additional information about the + * problem that occurred, compared with a standard {@code SQLException}. It + * supplies update counts for successful commands which were executed before the + * exception was encountered. + * </p> + * The element order in the array of update counts matches the order that the + * commands were added to the batch operation. + * <p> + * Once a batch update command fails and a {@code BatchUpdateException} is + * thrown, the JDBC driver may continue processing the remaining commands in the + * batch. If the driver does process more commands after the problem occurs, the + * array returned by {@code BatchUpdateException.getUpdateCounts} has an element + * for every command in the batch, not only those that executed successfully. In + * this case, the array element for any command which encountered a problem is + * set to {@code Statement.EXECUTE_FAILED}. + * </p> + * + * @since Android 1.0 + */ +public class BatchUpdateException extends SQLException implements Serializable { + + private static final long serialVersionUID = 5977529877145521757L; + + private int[] updateCounts = null; + + /** + * Creates a default {@code BatchUpdateException} with the parameters + * <i>reason</i>, <i>SQLState</i>, and <i>update counts</i> set to {@code + * null} and the <i>vendor code</i> set to 0. + * + * @since Android 1.0 + */ + public BatchUpdateException() { + super(); + } + + /** + * Creates a {@code BatchUpdateException} with the {@code updateCounts} set + * to the supplied value. All other fields are set to their + * default values. + * + * @param updateCounts + * the array of {@code updateCounts} giving the number of + * successful updates (or another status code) for each command + * in the batch that was attempted. + * @since Android 1.0 + */ + public BatchUpdateException(int[] updateCounts) { + super(); + this.updateCounts = updateCounts; + } + + /** + * Creates a {@code BatchUpdateException} with the {@code updateCounts} and + * {@code reason} set to the supplied values. All other fields are set to their + * default values. + * + * @param reason + * the message providing information about the source of this + * exception. + * @param updateCounts + * the array of {@code updateCounts} giving the number of + * successful updates (or another status code) for each command + * in the batch that was attempted. + * @since Android 1.0 + */ + public BatchUpdateException(String reason, int[] updateCounts) { + super(reason); + this.updateCounts = updateCounts; + } + + /** + * Creates a {@code BatchUpdateException} with the {@code reason}, {@code + * SQLState} and {@code updateCounts} set to the supplied values. All other + * fields are set to their default values. + * + * @param reason + * the message providing information about the source of this + * exception. + * @param SQLState + * the X/OPEN value to use for the {@code SQLState} + * @param updateCounts + * the array of {@code updateCounts} giving the number of + * successful updates (or another status code) for each command + * in the batch that was attempted. + * @since Android 1.0 + */ + public BatchUpdateException(String reason, String SQLState, + int[] updateCounts) { + super(reason, SQLState); + this.updateCounts = updateCounts; + } + + /** + * Creates a {@code BatchUpdateException} for the case where all relevant + * information is provided. + * + * @param reason + * the message providing information about the source of this + * exception. + * @param SQLState + * the X/OPEN value to use for the {@code SQLState}. + * @param vendorCode + * the value to use for the vendor error code. + * @param updateCounts + * the array of {@code updateCounts} giving the number of + * successful updates (or another status code) for each command + * in the batch that was attempted. + * @since Android 1.0 + */ + public BatchUpdateException(String reason, String SQLState, int vendorCode, + int[] updateCounts) { + super(reason, SQLState, vendorCode); + this.updateCounts = updateCounts; + } + + /** + * Gets the <i>update count</i> array giving status information for every + * command that was attempted in the batch. + * <p> + * If a batch update command fails and a {@code BatchUpdateException} is + * thrown, the JDBC driver may continue processing the remaining commands in + * the batch. If the driver does so, the array returned by {@code + * BatchUpdateException.getUpdateCounts} has an element for every command in + * the batch, not only those that executed successfully. In this case, the + * array element for any command which encountered a problem is set to + * {@code Statement.EXECUTE_FAILED}. + * + * @return an array that contains the successful update counts, before this + * exception was thrown. Alternatively, if the driver continues to + * process commands following an error, for each successive command + * there is a corresponding element in the array giving one of the + * following status values: + * <ol> + * <li>the number of successful updates</li> <li>{@code + * Statement.SUCCESS_NO_INFO} indicating that the command completed + * successfully, but the amount of altered rows is unknown.</li> + * <li>{@code Statement.EXECUTE_FAILED} indicating that the command + * was unsuccessful.</li> + * </ol> + * @since Android 1.0 + */ + public int[] getUpdateCounts() { + return updateCounts; + } +} diff --git a/sql/src/main/java/java/sql/Blob.java b/sql/src/main/java/java/sql/Blob.java new file mode 100644 index 0000000..e6d9b19 --- /dev/null +++ b/sql/src/main/java/java/sql/Blob.java @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.io.OutputStream; +import java.io.InputStream; + +/** + * A Java interface representing the SQL {@code BLOB} type. + * <p> + * An SQL {@code BLOB} type stores a large array of binary data (bytes) as the + * value in a column of a database. + * </p> + * The {@code java.sql.Blob} interface provides methods for setting and + * retrieving data in the {@code Blob}, for querying {@code Blob} data length, + * and for searching for data within the {@code Blob}. + * + * @since Android 1.0 + */ +public interface Blob { + + /** + * Retrieves this {@code Blob} object as a binary stream. + * + * @return a binary {@code InputStream} giving access to the {@code Blob} + * data. + * @throws SQLException + * if an error occurs accessing the {@code Blob}. + * @since Android 1.0 + */ + public InputStream getBinaryStream() throws SQLException; + + /** + * Gets a portion of the value of this {@code Blob} as an array of bytes. + * + * @param pos + * the position of the first byte in the {@code Blob} to get, + * where the first byte in the {@code Blob} has position 1. + * @param length + * the number of bytes to get. + * @return a byte array containing the data from the {@code Blob}, starting + * at {@code pos} and is up to {@code length} bytes long. + * @throws SQLException + * if an error occurs accessing the {@code Blob}. + * @since Android 1.0 + */ + public byte[] getBytes(long pos, int length) throws SQLException; + + /** + * Gets the number of bytes in this {@code Blob} object. + * + * @return a {@code long} value with the length of the {@code Blob} in + * bytes. + * @throws SQLException + * if an error occurs accessing the {@code Blob}. + * @since Android 1.0 + */ + public long length() throws SQLException; + + /** + * Search for the position in this {@code Blob} at which a specified pattern + * begins, starting at a specified position within the {@code Blob}. + * + * @param pattern + * a {@code Blob} containing the pattern of data to search for in + * this {@code Blob}. + * @param start + * the position within this {@code Blob} to start the search, + * where the first position in the {@code Blob} is {@code 1}. + * @return a {@code long} value with the position at which the pattern + * begins. Returns {@code -1} if the pattern is not found in this + * {@code Blob}. + * @throws SQLException + * if an error occurs accessing the {@code Blob}. + * @since Android 1.0 + */ + public long position(Blob pattern, long start) throws SQLException; + + /** + * Search for the position in this {@code Blob} at which the specified + * pattern begins, starting at a specified position within the {@code Blob}. + * + * @param pattern + * a byte array containing the pattern of data to search for in + * this {@code Blob}. + * @param start + * the position within this {@code Blob} to start the search, + * where the first position in the {@code Blob} is {@code 1}. + * @return a {@code long} value with the position at which the pattern + * begins. Returns {@code -1} if the pattern is not found in this + * {@code Blob}. + * @throws SQLException + * if an error occurs accessing the {@code Blob}. + * @since Android 1.0 + */ + public long position(byte[] pattern, long start) throws SQLException; + + /** + * Gets a stream that can be used to write binary data to this {@code Blob}. + * + * @param pos + * the position within this {@code Blob} at which to start + * writing, where the first position in the {@code Blob} is + * {@code 1}. + * @return a binary {@code InputStream} which can be used to write data into + * the {@code Blob} starting at the specified position. + * @throws SQLException + * if an error occurs accessing the {@code Blob}. + * @since Android 1.0 + */ + public OutputStream setBinaryStream(long pos) throws SQLException; + + /** + * Writes a specified array of bytes to this {@code Blob} object, starting + * at a specified position. Returns the number of bytes written. + * + * @param pos + * the position within this {@code Blob} at which to start + * writing, where the first position in the {@code Blob} is + * {@code 1}. + * @param theBytes + * an array of bytes to write into the {@code Blob}. + * @return an integer containing the number of bytes written to the {@code + * Blob}. + * @throws SQLException + * if an error occurs accessing the {@code Blob}. + * @since Android 1.0 + */ + public int setBytes(long pos, byte[] theBytes) throws SQLException; + + /** + * Writes a portion of a specified byte array to this {@code Blob}. Returns + * the number of bytes written. + * + * @param pos + * the position within this {@code Blob} at which to start + * writing, where the first position in the {@code Blob} is + * {@code 1}. + * @param theBytes + * an array of bytes to write into the {@code Blob}. + * @param offset + * the offset into the byte array from which to start writing + * data - the first byte in the array has offset {@code 0}. + * @param len + * the length of data to write in number of bytes. + * @return an integer containing the number of bytes written to the {@code + * Blob}. + * @throws SQLException + * if an error occurs accessing the {@code Blob}. + * @since Android 1.0 + */ + public int setBytes(long pos, byte[] theBytes, int offset, int len) + throws SQLException; + + /** + * Truncate the value of this {@code Blob} object to a specified length in + * bytes. + * + * @param len + * the length of data in bytes after which this {@code Blob} + * is to be truncated. + * @throws SQLException + * if an error occurs accessing the {@code Blob}. + * @since Android 1.0 + */ + public void truncate(long len) throws SQLException; +} diff --git a/sql/src/main/java/java/sql/CallableStatement.java b/sql/src/main/java/java/sql/CallableStatement.java new file mode 100644 index 0000000..7a90041 --- /dev/null +++ b/sql/src/main/java/java/sql/CallableStatement.java @@ -0,0 +1,1483 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.math.BigDecimal; +import java.util.Calendar; +import java.util.Map; +import java.net.URL; +import java.io.InputStream; +import java.io.Reader; + +/** + * An interface used to call <i>Stored Procedures</i>. + * <p> + * The JDBC API provides an SQL escape syntax allowing <i>Stored Procedures</i> + * to be called in a standard way for all databases. The JDBC escape syntax has + * two forms. One form includes a result parameter. The second form does not + * include a result parameter. Where the result parameter is used, it must be + * declared as an {@code OUT} parameter. Other parameters can be declared as + * {@code IN}, {@code OUT}, or {@code INOUT}. Parameters are referenced either by + * name or by a numerical index starting at 1. + * <p> + * The correct syntax is: + * </p> + * <dd> + * <dl> + * { ?= call <procedurename> [( [parameter1,parameter2,...] )] } + * </dl> + * <dl> + * { call <procedurename> [( [parameter1,parameter2,...] )] } + * </dl> + * </code></dd> </p> {@code IN} parameters are set before calling the procedure, + * using the setter methods which are inherited from {@code PreparedStatement}. + * For {@code OUT} parameters, their type must be registered before executing + * the stored procedure. The values are retrieved using the getter methods + * defined in the {@code CallableStatement} interface. + * <p> + * {@code CallableStatement}s can return one or more {@code ResultSets}. In the + * event that multiple {@code ResultSets} are returned, they are accessed using + * the methods inherited from the {@code Statement} interface. + * </p> + * + * @since Android 1.0 + */ +public interface CallableStatement extends PreparedStatement { + + /** + * Gets the value of a specified JDBC {@code ARRAY} parameter as a + * {@code java.sql.Array}. + * + * @param parameterIndex + * the parameter index, where the first parameter has + * index 1. + * @return a {@code java.sql.Array} containing the parameter value. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public Array getArray(int parameterIndex) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code ARRAY} parameter as a {@code + * java.sql.Array}. + * + * @param parameterName + * the desired parameter's name. + * @return a {@code java.sql.Array} containing the parameter's value. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public Array getArray(String parameterName) throws SQLException; + + /** + * Returns a new {@link BigDecimal} representation of the JDBC {@code + * NUMERIC} parameter specified by the input index. + * + * @param parameterIndex + * the parameter number index where the first parameter has index + * 1. + * @return a {@code java.math.BigDecimal} representing the value of the + * specified parameter. The value {@code null} is returned if + * the parameter in question is an SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public BigDecimal getBigDecimal(int parameterIndex) throws SQLException; + + /** + * Returns a new {@link BigDecimal} representation of the JDBC {@code + * NUMERIC} parameter specified by the input index. The number of digits + * after the decimal point is specified by {@code scale}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param scale + * the number of digits after the decimal point to get. + * @return a {@code java.math.BigDecimal} representing the value of the + * specified parameter. The value {@code null} is returned if + * the parameter in question is an SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @deprecated Use {@link #getBigDecimal(int)} or + * {@link #getBigDecimal(String)} + * @since Android 1.0 + */ + @Deprecated + public BigDecimal getBigDecimal(int parameterIndex, int scale) + throws SQLException; + + /** + * Returns a new {@link BigDecimal} representation of the JDBC {@code + * NUMERIC} parameter specified by the input name. + * + * @param parameterName + * the desired parameter's name. + * @return a {@code java.math.BigDecimal} representing the value of the + * specified parameter. The value {@code null} is returned if + * the parameter in question is an SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public BigDecimal getBigDecimal(String parameterName) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code BLOB} parameter as a {@code + * java.sql.Blob}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return a {@code java.sql.Blob} representing the value of the + * specified parameter. The value {@code null} is returned if + * the parameter in question is an SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public Blob getBlob(int parameterIndex) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code BLOB} parameter as a {@code + * java.sql.Blob}. + * + * @param parameterName + * the desired parameter's name. + * @return a {@code java.sql.Blob} representing the value of the + * specified parameter. The value {@code null} is returned if + * the parameter in question is an SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public Blob getBlob(String parameterName) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code BIT} parameter as a boolean. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return a {@code boolean} representing the parameter value. {@code false} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public boolean getBoolean(int parameterIndex) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code BIT} parameter as a {@code + * boolean}. + * + * @param parameterName + * the desired parameter's name. + * @return a {@code boolean} representation of the value of the parameter. + * {@code false} is returned if the SQL value is {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public boolean getBoolean(String parameterName) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code TINYINT} parameter as a {@code + * byte}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return a {@code byte} representation of the value of the parameter. + * {@code 0} is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public byte getByte(int parameterIndex) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code TINYINT} parameter as a Java + * {@code byte}. + * + * @param parameterName + * the desired parameter's name. + * @return a {@code byte} representation of the value of the parameter. + * {@code 0} is returned if the SQL value is {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public byte getByte(String parameterName) throws SQLException; + + /** + * Returns a byte array representation of the indexed JDBC {@code BINARY} or + * {@code VARBINARY} parameter. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return an array of bytes giving the value of the parameter. {@code null} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public byte[] getBytes(int parameterIndex) throws SQLException; + + /** + * Returns a byte array representation of the named JDBC {@code BINARY} or + * {@code VARBINARY} parameter. + * + * @param parameterName + * the name of the parameter. + * @return an array of bytes giving the value of the parameter. {@code null} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public byte[] getBytes(String parameterName) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code CLOB} parameter as a {@code + * java.sql.Clob}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return a {@code java.sql.Clob} representing the value of the + * parameter. {@code null} is returned if the value is SQL + * {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @see Clob + * @since Android 1.0 + */ + public Clob getClob(int parameterIndex) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code CLOB} parameter as a {@code + * java.sql.Clob}. + * + * @param parameterName + * the name of the parameter. + * @return a {@code java.sql.Clob} with the value of the parameter. {@code + * null} is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @see Clob + * @since Android 1.0 + */ + public Clob getClob(String parameterName) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code DATE} parameter as a {@code + * java.sql.Date}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return the {@code java.sql.Date} representing the parameter's value. + * {@code null} is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @see Date + * @since Android 1.0 + */ + public Date getDate(int parameterIndex) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code DATE} parameter as a {@code + * java.sql.Date}, using the specified {@code Calendar} to construct the date. + * <p> + * The JDBC driver uses the calendar to create the Date using a particular + * timezone and locale. The default behavior of the driver is to use the Java + * virtual machine default settings. + * </p> + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param cal + * the {@code Calendar} to use to construct the date + * @return the {@code java.sql.Date} giving the parameter's value. {@code null} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @see Date + * @since Android 1.0 + */ + public Date getDate(int parameterIndex, Calendar cal) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code DATE} parameter as a {@code + * java.sql.Date}. + * + * @param parameterName + * the name of the desired parameter. + * @return the {@code java.sql.Date} giving the parameter's value. {@code null} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @see Date + * @since Android 1.0 + */ + public Date getDate(String parameterName) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code DATE} parameter as a {@code + * java.sql.Date}, using the specified {@code Calendar} to construct the date. + * <p> + * The JDBC driver uses the calendar to create the date using a particular + * timezone and locale. The default behavior of the driver is to use the Java + * virtual machine default settings. + * </p> + * + * @param parameterName + * the name of the desired parameter. + * @param cal + * used for creating the returned {@code Date}. + * @return the {@code java.sql.Date} giving the parameter's value. {@code null} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @see Date + * @since Android 1.0 + */ + public Date getDate(String parameterName, Calendar cal) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code DOUBLE} parameter as a + * {@code double}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return the parameter's value as a {@code double}. {@code 0.0} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public double getDouble(int parameterIndex) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code DOUBLE} parameter as a + * {@code double}. + * + * @param parameterName + * the name of the desired parameter. + * @return the parameter's value as a {@code double}. {@code 0.0} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public double getDouble(String parameterName) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code FLOAT} parameter as a {@code + * float}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return the parameter's value as a {@code float}. {@code 0.0} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public float getFloat(int parameterIndex) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code FLOAT} parameter as a Java + * {@code float}. + * + * @param parameterName + * the name of the desired parameter. + * @return the parameter's value as a {@code float}. {@code 0.0} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public float getFloat(String parameterName) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code INTEGER} parameter as an + * {@code int}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return the {@code int} giving the parameter's value. {@code 0} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public int getInt(int parameterIndex) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code INTEGER} parameter as an + * {@code int}. + * + * @param parameterName + * the name of the desired parameter. + * @return the {@code int} giving the parameter's value. {@code 0} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public int getInt(String parameterName) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code BIGINT} parameter as a + * {@code long}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return the {@code long} giving the parameter's value. {@code 0} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public long getLong(int parameterIndex) throws SQLException; + + /** + * Gets the value of the specified JDBC {@code BIGINT} parameter as a + * {@code long}. + * + * @param parameterName + * the name of the desired parameter. + * @return the {@code long} giving the parameter's value. {@code 0} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public long getLong(String parameterName) throws SQLException; + + /** + * Gets the value of the specified parameter as a Java {@code Object}. + * <p> + * The object type returned is the JDBC type registered for the parameter + * with a {@code registerOutParameter} call. If a parameter was registered + * as a {@code java.sql.Types.OTHER} then it may hold abstract types that + * are particular to the connected database. + * </p> + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return an Object holding the value of the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public Object getObject(int parameterIndex) throws SQLException; + + /** + * Gets the value of the specified parameter as an {@code Object}. The + * {@code Map} gives the correspondence between SQL types and Java classes. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param map + * the {@code Map} giving the correspondence between SQL + * types and Java classes. + * @return an Object holding the value of the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public Object getObject(int parameterIndex, Map<String, Class<?>> map) + throws SQLException; + + /** + * Gets the value of the specified parameter as an {@code Object}. + * <p> + * The object type returned is the JDBC type that was registered for + * the parameter by an earlier call to {@link #registerOutParameter}. + * If a parameter was registered as a {@code java.sql.Types.OTHER} + * then it may hold abstract types that are particular to the + * connected database. + * </p> + * + * @param parameterName + * the parameter name. + * @return the Java {@code Object} representation of the value of the + * parameter. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public Object getObject(String parameterName) throws SQLException; + + /** + * Gets the value of a specified parameter as an {@code Object}. The + * actual return type is determined by the {@code Map} parameter which + * gives the correspondence between SQL types and Java classes. + * + * @param parameterName + * the parameter name. + * @param map + * the {@code Map} of SQL types to their Java counterparts + * @return an {@code Object} holding the value of the parameter. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public Object getObject(String parameterName, Map<String, Class<?>> map) + throws SQLException; + + /** + * Gets the value of a specified SQL {@code REF(<structured type>)} + * parameter as a {@code java.sql.Ref}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return a {@code java.sql.Ref} with the parameter value. {@code null} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public Ref getRef(int parameterIndex) throws SQLException; + + /** + * Gets the value of a specified SQL {@code REF(<structured type>)} + * parameter as a {@code java.sql.Ref}. + * + * @param parameterName + * the desired parameter's name. + * @return the parameter's value in the form of a {@code + * java.sql.Ref}. A {@code null} reference is returned if the + * parameter's value is SQL {@code NULL}. + * @throws SQLException + * if there is a problem accessing the database. + * @see Ref + * @since Android 1.0 + */ + public Ref getRef(String parameterName) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code SMALLINT} parameter as a + * {@code short}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return the parameter's value as a {@code short}. 0 is returned + * if the parameter's value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public short getShort(int parameterIndex) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code SMALLINT} parameter as a + * {@code short}. + * + * @param parameterName + * the desired parameter's name. + * @return the parameter's value as a {@code short}. 0 is returned + * if the parameter's value is SQL {@code NULL}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public short getShort(String parameterName) throws SQLException; + + /** + * Returns the indexed parameter's value as a {@code String}. The + * parameter value must be one of the JDBC types {@code CHAR}, + * {@code VARCHAR} or {@code LONGVARCHAR}. + * <p> + * The {@code String} corresponding to a {@code CHAR} of fixed length + * will be of identical length to the value in the database inclusive + * of padding characters. + * </p> + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return the parameter's value as a {@code String}. {@code null} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public String getString(int parameterIndex) throws SQLException; + + /** + * Returns the named parameter's value as a string. The parameter value must + * be one of the JDBC types {@code CHAR}, {@code VARCHAR} or {@code + * LONGVARCHAR}. + * <p> + * The string corresponding to a {@code CHAR} of fixed length will be of + * identical length to the value in the database inclusive of padding + * characters. + * </p> + * + * @param parameterName + * the desired parameter's name. + * @return the parameter's value as a {@code String}. {@code null} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public String getString(String parameterName) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code TIME} parameter as a {@code + * java.sql.Time}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return the parameter's value as a {@code java.sql.Time}. + * {@code null} is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @see Time + * @since Android 1.0 + */ + public Time getTime(int parameterIndex) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code TIME} parameter as a {@code + * java.sql.Time}, using the supplied {@code Calendar} to construct the + * time. The JDBC driver uses the calendar to handle specific timezones + * and locales in order to determine {@code Time}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param cal + * the calendar to use in constructing {@code Time}. + * @return the parameter's value as a {@code java.sql.Time}. + * {@code null} is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @see Time + * @see java.util.Calendar + * @since Android 1.0 + */ + public Time getTime(int parameterIndex, Calendar cal) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code TIME} parameter as a {@code + * java.sql.Time}. + * + * @param parameterName + * the name of the desired parameter. + * @return a new {@code java.sql.Time} with the parameter's value. A {@code + * null} reference is returned for an SQL value of {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @see Time + * @since Android 1.0 + */ + public Time getTime(String parameterName) throws SQLException; + + /** + * Gets the value of a specified JDBC {@code TIME} parameter as a {@code + * java.sql.Time}, using the supplied {@code Calendar} to construct + * the time. The JDBC driver uses the calendar to handle specific + * timezones and locales when creating {@code Time}. + * + * @param parameterName + * the name of the desired parameter. + * @param cal + * used for creating the returned {@code Time} + * @return a new {@code java.sql.Time} with the parameter's value. A {@code + * null} reference is returned for an SQL value of {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @see Time + * @see java.util.Calendar + * @since Android 1.0 + */ + public Time getTime(String parameterName, Calendar cal) throws SQLException; + + /** + * Returns the indexed parameter's {@code TIMESTAMP} value as a {@code + * java.sql.Timestamp}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1 + * @return the parameter's value as a {@code java.sql.Timestamp}. A + * {@code null} reference is returned for an SQL value of {@code + * NULL}. + * @throws SQLException + * if a database error occurs. + * @see Timestamp + * @since Android 1.0 + */ + public Timestamp getTimestamp(int parameterIndex) throws SQLException; + + /** + * Returns the indexed parameter's {@code TIMESTAMP} value as a {@code + * java.sql.Timestamp}. The JDBC driver uses the supplied {@code Calendar} + * to handle specific timezones and locales when creating the result. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1 + * @param cal + * used for creating the returned {@code Timestamp} + * @return the parameter's value as a {@code java.sql.Timestamp}. A + * {@code null} reference is returned for an SQL value of {@code + * NULL}. + * @throws SQLException + * if a database error occurs. + * @see Timestamp + * @since Android 1.0 + */ + public Timestamp getTimestamp(int parameterIndex, Calendar cal) + throws SQLException; + + /** + * Returns the named parameter's {@code TIMESTAMP} value as a {@code + * java.sql.Timestamp}. + * + * @param parameterName + * the name of the desired parameter. + * @return the parameter's value as a {@code java.sql.Timestamp}. A + * {@code null} reference is returned for an SQL value of {@code + * NULL}. + * @throws SQLException + * if a database error occurs. + * @see Timestamp + * @since Android 1.0 + */ + public Timestamp getTimestamp(String parameterName) throws SQLException; + + /** + * Returns the indexed parameter's {@code TIMESTAMP} value as a {@code + * java.sql.Timestamp}. The JDBC driver uses the supplied {@code Calendar} + * to handle specific timezones and locales when creating the result. + * + * @param parameterName + * the name of the desired parameter. + * @param cal + * used for creating the returned {@code Timestamp} + * @return the parameter's value as a {@code java.sql.Timestamp}. A + * {@code null} reference is returned for an SQL value of {@code + * NULL}. + * @throws SQLException + * if a database error occurs. + * @see Timestamp + * @since Android 1.0 + */ + public Timestamp getTimestamp(String parameterName, Calendar cal) + throws SQLException; + + /** + * Gets the value of a specified JDBC {@code DATALINK} parameter as a + * {@code java.net.URL}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @return a {@code URL} giving the parameter's value. {@code null} + * is returned if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error occurs. + * @see java.net.URL + * @since Android 1.0 + */ + public URL getURL(int parameterIndex) throws SQLException; + + /** + * Returns the named parameter's JDBC {@code DATALINK} value in a new Java + * {@code java.net.URL}. + * + * @param parameterName + * the name of the desired parameter. + * @return a new {@code java.net.URL} encapsulating the parameter value. A + * {@code null} reference is returned for an SQL value of {@code + * NULL}. + * @throws SQLException + * if a database error occurs. + * @see java.net.URL + * @since Android 1.0 + */ + public URL getURL(String parameterName) throws SQLException; + + /** + * Defines the type of a specified {@code OUT} parameter. All {@code OUT} + * parameters must have their type defined before a stored procedure is + * executed. + * <p> + * The type supplied in the {@code sqlType} parameter fixes the + * type that will be returned by the getter methods of + * {@code CallableStatement}. + * If a database specific type is expected for a parameter, the Type {@code + * java.sql.Types.OTHER} should be used. Note that there is another variant + * of this method for User Defined Types or a {@code REF} type. + * </p> + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1 + * @param sqlType + * the JDBC type as defined by {@code java.sql.Types}. The JDBC + * types {@code NUMERIC} and {@code DECIMAL} should be defined + * using {@link #registerOutParameter(int, int, int)}. + * @throws SQLException + * if a database error occurs. + * @see Types + * @since Android 1.0 + */ + public void registerOutParameter(int parameterIndex, int sqlType) + throws SQLException; + + /** + * Defines the Type of a specified {@code OUT} parameter. All {@code OUT} + * parameters must have their type defined before a stored procedure is + * executed. This version of the {@code registerOutParameter} method, which + * has a scale parameter, should be used for the JDBC types {@code NUMERIC} + * and {@code DECIMAL}, where there is a need to specify the number of + * digits expected after the decimal point. + * <p> + * The type supplied in the {@code sqlType} parameter fixes the + * type that will be returned by the getter methods of + * {@code CallableStatement}. + * </p> + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1 + * @param sqlType + * the JDBC type as defined by {@code java.sql.Types}. + * @param scale + * the number of digits after the decimal point. Must be greater + * than or equal to 0. + * @throws SQLException + * if a database error occurs. + * @see Types + * @since Android 1.0 + */ + public void registerOutParameter(int parameterIndex, int sqlType, int scale) + throws SQLException; + + /** + * Defines the Type of a specified {@code OUT} parameter. This variant + * of the method is designed for use with parameters that are + * <i>User Defined Types</i> (UDT) or a {@code REF} type, although it + * can be used for any type. + * + * @param paramIndex + * the parameter number index, where the first parameter has + * index 1. + * @param sqlType + * a JDBC type expressed as a constant from {@link Types}. + * @param typeName + * an SQL type name. For a {@code REF} type, this name should be + * the fully qualified name of the referenced type. + * @throws SQLException + * if a database error occurs. + * @see Ref + * @since Android 1.0 + */ + public void registerOutParameter(int paramIndex, int sqlType, + String typeName) throws SQLException; + + /** + * Defines the Type of a specified {@code OUT} parameter. All OUT parameters + * must have their Type defined before a stored procedure is executed. + * <p> + * The type supplied in the {@code sqlType} parameter fixes the + * type that will be returned by the getter methods of + * {@code CallableStatement}. + * If a database-specific type is expected for a parameter, the Type {@code + * java.sql.Types.OTHER} should be used. Note that there is another variant + * of this method for User Defined Types or a {@code REF} type. + * </p> + * + * @param parameterName + * the parameter name. + * @param sqlType + * a JDBC type expressed as a constant from {@link Types}. Types + * {@code NUMERIC} and {@code DECIMAL} should be defined using + * the variant of this method that takes a {@code scale} + * parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void registerOutParameter(String parameterName, int sqlType) + throws SQLException; + + /** + * Defines the Type of a specified {@code OUT} parameter. All {@code OUT} + * parameters must have their Type defined before a stored procedure is + * executed. This version of the {@code registerOutParameter} method, which + * has a scale parameter, should be used for the JDBC types {@code NUMERIC} + * and {@code DECIMAL}, where there is a need to specify the number of + * digits expected after the decimal point. + * <p> + * The type supplied in the {@code sqlType} parameter fixes the + * type that will be returned by the getter methods of + * {@code CallableStatement}. + * </p> + * + * @param parameterName + * the parameter name. + * @param sqlType + * a JDBC type expressed as a constant from {@link Types}. + * @param scale + * the number of digits after the decimal point. Must be greater + * than or equal to 0. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void registerOutParameter(String parameterName, int sqlType, + int scale) throws SQLException; + + /** + * Defines the Type of a specified {@code OUT} parameter. This variant of + * the method is designed for use with parameters that are <i>User Defined + * Types</i> (UDT) or a {@code REF} type, although it can be used for any + * type. + * + * @param parameterName + * the parameter name + * @param sqlType + * a JDBC type expressed as a constant from {@link Types} + * @param typeName + * the fully qualified name of an SQL structured type. For a + * {@code REF} type, this name should be the fully qualified name + * of the referenced type. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void registerOutParameter(String parameterName, int sqlType, + String typeName) throws SQLException; + + /** + * Sets the value of a specified parameter to the content of a supplied + * {@code InputStream}, which has a specified number of bytes. + * <p> + * This is a good method for setting an SQL {@code LONVARCHAR} parameter + * where the length of the data is large. Data is read from the {@code + * InputStream} until end-of-file is reached or the specified number of + * bytes is copied. + * </p> + * + * @param parameterName + * the parameter name + * @param theInputStream + * the ASCII input stream carrying the data to update the + * parameter with. + * @param length + * the number of bytes in the {@code InputStream} to copy to the + * parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setAsciiStream(String parameterName, + InputStream theInputStream, int length) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.math.BigDecimal} value. + * + * @param parameterName + * the name of the parameter. + * @param theBigDecimal + * the {@code java.math.BigInteger} value to set. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setBigDecimal(String parameterName, BigDecimal theBigDecimal) + throws SQLException; + + /** + * Sets the value of a specified parameter to the content of a supplied + * binary {@code InputStream}, which has a specified number of bytes. + * <p> + * Use this method when a large amount of data needs to be set into a + * {@code LONGVARBINARY} parameter. + * </p> + * + * @param parameterName + * the name of the parameter. + * @param theInputStream + * the binary {@code InputStream} carrying the data to update the + * parameter. + * @param length + * the number of bytes in the {@code InputStream} to copy to the + * parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setBinaryStream(String parameterName, + InputStream theInputStream, int length) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code boolean} + * value. + * + * @param parameterName + * the parameter name. + * @param theBoolean + * the new value with which to update the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setBoolean(String parameterName, boolean theBoolean) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code byte} value. + * + * @param parameterName + * the parameter name. + * @param theByte + * the new value with which to update the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setByte(String parameterName, byte theByte) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied array of bytes. The + * array is mapped to {@code VARBINARY} or else {@code LONGVARBINARY} in the + * connected database. + * + * @param parameterName + * the parameter name. + * @param theBytes + * the new value with which to update the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setBytes(String parameterName, byte[] theBytes) + throws SQLException; + + /** + * Sets the value of a specified parameter to the character content of a + * {@code Reader} object, with the specified length of character data. + * + * @param parameterName + * the parameter name. + * @param reader + * the new value with which to update the parameter. + * @param length + * a count of the characters contained in {@code reader}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setCharacterStream(String parameterName, Reader reader, + int length) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.sql.Date} value. + * + * @param parameterName + * the parameter name. + * @param theDate + * the new value with which to update the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setDate(String parameterName, Date theDate) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.sql.Date} value, using a supplied calendar to map the date. The + * calendar allows the application to control the timezone used to compute + * the SQL {@code DATE} in the database. In case that no calendar is + * supplied, the driver uses the default timezone of the Java virtual + * machine. + * + * @param parameterName + * the parameter name. + * @param theDate + * the new value with which to update the parameter. + * @param cal + * a {@code Calendar} to use to construct the SQL {@code DATE} + * value. + * @throws SQLException + * if a database error occurs. + * @see java.util.Calendar + * @see Date + * @since Android 1.0 + */ + public void setDate(String parameterName, Date theDate, Calendar cal) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code double} + * value. + * + * @param parameterName + * the parameter name. + * @param theDouble + * the new value with which to update the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setDouble(String parameterName, double theDouble) + throws SQLException; + + /** + * Sets the value of a specified parameter to to a supplied {@code float} + * value. + * + * @param parameterName + * the parameter name. + * @param theFloat + * the new value with which to update the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setFloat(String parameterName, float theFloat) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code int} value. + * + * @param parameterName + * the parameter name. + * @param theInt + * the new value with which to update the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setInt(String parameterName, int theInt) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code long} value. + * + * @param parameterName + * the parameter name. + * @param theLong + * the new value with which to update the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setLong(String parameterName, long theLong) throws SQLException; + + /** + * Sets the value of a specified parameter to SQL {@code NULL}. Don't use + * this version of {@code setNull} for <i>User Defined Types</i> (UDT) or + * for {@code REF} type parameters. + * + * @param parameterName + * the parameter name. + * @param sqlType + * a JDBC type expressed as a constant from {@link Types}. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setNull(String parameterName, int sqlType) throws SQLException; + + /** + * Sets the value of a specified parameter to be SQL {@code NULL} where the + * parameter type is either {@code REF} or user defined (e.g. {@code STRUCT} + * , {@code JAVA_OBJECT} etc). + * <p> + * For reasons of portability, the caller is expected to supply both the SQL + * type code and type name (which is just the parameter name if the type is + * user defined, referred to as a {@code UDT}, or the name of the referenced + * type in case of a {@code REF} type). + * </p> + * + * @param parameterName + * the parameter name. + * @param sqlType + * a JDBC type expressed as a constant from {@link Types}. + * @param typeName + * if the target parameter is a user defined type then this + * should contain the full type name. The fully qualified name of + * a {@code UDT} or {@code REF} type is ignored if the parameter + * is not a {@code UDT}. + * @throws SQLException + * if a database error occurs. + * @see Types + * @since Android 1.0 + */ + public void setNull(String parameterName, int sqlType, String typeName) + throws SQLException; + + /** + * Sets the value of a specified parameter using a supplied object. Prior to + * issuing this request to the connected database {@code theObject} is + * transformed to the corresponding SQL type according to the standard Java + * to SQL mapping rules. + * <p> + * If the object's class implements the interface {@code SQLData}, the JDBC + * driver calls {@code SQLData.writeSQL} to write it to the SQL data stream. + * If {@code theObject} implements any of the following interfaces then the + * driver is in charge of mapping the value to the appropriate SQL type. + * <ul><li>{@link Ref}</li> + * <li>{@link Struct}</li> + * <li>{@link Array}</li> + * <li>{@link Clob}</li> + * <li>{@link Blob}</li> </ul> + * </p> + * + * @param parameterName + * the parameter name + * @param theObject + * the new value with which to update the parameter + * @throws SQLException + * if a database error occurs. + * @see SQLData + * @since Android 1.0 + */ + public void setObject(String parameterName, Object theObject) + throws SQLException; + + /** + * Sets the value of a specified parameter using a supplied object. + * <p> + * The parameter {@code theObject} is converted to the given {@code + * targetSqlType} before it is sent to the database. If the object has a + * custom mapping (its class implements the interface {@code SQLData}), the + * JDBC driver calls the method {@code SQLData.writeSQL} to write it to the + * SQL data stream. If {@code theObject} is an instance of one of the + * following types + * <ul> + * <li>{@link Ref}</li> + * <li>{@link Struct}</li> + * <li>{@link Array}</li> + * <li>{@link Clob}</li> + * <li>{@link Blob}</li> + * </ul> + * then the driver is in charge of mapping the value to the appropriate + * SQL type and deliver it to the database. + * </p> + * + * @param parameterName + * the parameter name. + * @param theObject + * the new value with which to update the parameter. + * @param targetSqlType + * a JDBC type expressed as a constant from {@link Types}. + * @throws SQLException + * if a database error occurs. + * @see SQLData + * @since Android 1.0 + */ + public void setObject(String parameterName, Object theObject, + int targetSqlType) throws SQLException; + + /** + * Sets the value of a specified parameter using a supplied object. + * <p> + * The object is converted to the given {@code targetSqlType} before it is + * sent to the database. If the object has a custom mapping (its class + * implements the interface {@code SQLData}), the JDBC driver calls the + * method {@code SQLData.writeSQL} to write it to the SQL data stream. If + * {@code theObject} implements any of the following interfaces + * <ul> + * <li>{@link Ref}</li> + * <li>{@link Struct}</li> + * <li>{@link Array}</li> + * <li>{@link Clob}</li> + * <li>{@link Blob}</li> + * </ul> + * then the driver is charge of mapping the value to the appropriate + * SQL type. + * </p> + * + * @param parameterName + * the parameter name. + * @param theObject + * the new value with which to update the parameter. + * @param targetSqlType + * a JDBC type expressed as a constant from {@link Types}. + * @param scale + * where applicable, the number of digits after the decimal. + * point. + * @throws SQLException + * if a database error occurs. + * @see SQLData + * @since Android 1.0 + */ + public void setObject(String parameterName, Object theObject, + int targetSqlType, int scale) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code short} + * value. + * + * @param parameterName + * the name of the parameter. + * @param theShort + * a short value to update the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setShort(String parameterName, short theShort) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code String}. + * + * @param parameterName + * the name of the parameter. + * @param theString + * a {@code String} value to update the parameter. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void setString(String parameterName, String theString) + throws SQLException; + + /** + * Sets the value of the parameter named {@code parameterName} to the value + * of the supplied {@code java.sql.Time}. + * + * @param parameterName + * the parameter name. + * @param theTime + * the new value with which to update the parameter. + * @throws SQLException + * if a database error occurs. + * @see Time + * @since Android 1.0 + */ + public void setTime(String parameterName, Time theTime) throws SQLException; + + /** + * Sets the value of the parameter named {@code parameterName} to the value + * of the supplied {@code java.sql.Time} using the supplied calendar. + * <p> + * The driver uses the supplied {@code Calendar} to create the SQL + * {@code TIME} value, which allows it to use a custom timezone - + * otherwise the driver uses the default timezone of the Java + * virtual machine. + * + * @param parameterName + * the parameter name. + * @param theTime + * the new value with which to update the parameter. + * @param cal + * used for creating the new SQL {@code TIME} value. + * @throws SQLException + * if a database error occurs. + * @see Time + * @since Android 1.0 + */ + public void setTime(String parameterName, Time theTime, Calendar cal) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.sql.Timestamp} value. + * + * @param parameterName + * the parameter name. + * @param theTimestamp + * the new value with which to update the parameter. + * @throws SQLException + * if a database error occurs. + * @see Timestamp + * @since Android 1.0 + */ + public void setTimestamp(String parameterName, Timestamp theTimestamp) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.sql.Timestamp} value, using the supplied calendar. + * <p> + * The driver uses the supplied calendar to create the SQL {@code TIMESTAMP} + * value, which allows it to use a custom timezone - otherwise the driver + * uses the default timezone of the Java virtual machine. + * </p> + * + * @param parameterName + * the parameter name. + * @param theTimestamp + * the new value with which to update the parameter. + * @param cal + * used for creating the new SQL {@code TIME} value. + * @throws SQLException + * if a database error occurs. + * @see Timestamp + * @see java.util.Calendar + * @since Android 1.0 + */ + public void setTimestamp(String parameterName, Timestamp theTimestamp, + Calendar cal) throws SQLException; + + /** + * Sets the value of a specified parameter to the supplied {@code + * java.net.URL}. + * + * @param parameterName + * the parameter name. + * @param theURL + * the new value with which to update the parameter. + * @throws SQLException + * if a database error occurs. + * @see java.net.URL + * @since Android 1.0 + */ + public void setURL(String parameterName, URL theURL) throws SQLException; + + /** + * Gets whether the value of the last {@code OUT} parameter read was SQL + * {@code NULL}. + * + * @return true if the last parameter was SQL {@code NULL}, {@code false} + * otherwise. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public boolean wasNull() throws SQLException; +} diff --git a/sql/src/main/java/java/sql/Clob.java b/sql/src/main/java/java/sql/Clob.java new file mode 100644 index 0000000..339d4e5 --- /dev/null +++ b/sql/src/main/java/java/sql/Clob.java @@ -0,0 +1,192 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.io.InputStream; +import java.io.Reader; +import java.io.OutputStream; +import java.io.Writer; + +/** + * A Java interface mapping for the SQL CLOB type. + * <p> + * An SQL {@code CLOB} type stores a large array of characters as the value in a + * column of a database. + * <p> + * The {@code java.sql.Clob} interface provides methods for setting and + * retrieving data in the {@code Clob}, for querying {@code Clob} data length, + * for searching for data within the {@code Clob}. + * + * @since Android 1.0 + */ +public interface Clob { + + /** + * Gets the value of this {@code Clob} object as an ASCII stream. + * + * @return an ASCII {@code InputStream} giving access to the + * {@code Clob} data. + * @throws SQLException + * if an error occurs accessing the {@code Clob}. + * @since Android 1.0 + */ + public InputStream getAsciiStream() throws SQLException; + + /** + * Gets the data of this {@code Clob} object in a {@code java.io.Reader}. + * + * @return a character stream Reader object giving access to the {@code + * Clob} data. + * @throws SQLException + * if an error occurs accessing the {@code Clob}. + * @since Android 1.0 + */ + public Reader getCharacterStream() throws SQLException; + + /** + * Gets a copy of a specified substring in this {@code Clob}. + * + * @param pos + * the index of the start of the substring in the {@code Clob}. + * @param length + * the length of the data to retrieve. + * @return A string containing the requested data. + * @throws SQLException + * if an error occurs accessing the {@code Clob}. + * @since Android 1.0 + */ + public String getSubString(long pos, int length) throws SQLException; + + /** + * Retrieves the number of characters in this {@code Clob} object. + * + * @return a long value with the number of character in this {@code Clob}. + * @throws SQLException + * if an error occurs accessing the {@code Clob}. + * @since Android 1.0 + */ + public long length() throws SQLException; + + /** + * Retrieves the character position at which a specified {@code Clob} object + * appears in this {@code Clob} object. + * + * @param searchstr + * the specified {@code Clob} to search for. + * @param start + * the position within this {@code Clob} to start the search + * @return a long value with the position at which the specified {@code + * Clob} occurs within this {@code Clob}. + * @throws SQLException + * if an error occurs accessing the {@code Clob}. + * @since Android 1.0 + */ + public long position(Clob searchstr, long start) throws SQLException; + + /** + * Retrieves the character position at which a specified substring appears + * in this {@code Clob} object. + * + * @param searchstr + * the string to search for. + * @param start + * the position at which to start the search within this {@code + * Clob}. + * @return a long value with the position at which the specified string + * occurs within this {@code Clob}. + * @throws SQLException + * if an error occurs accessing the {@code Clob}. + * @since Android 1.0 + */ + public long position(String searchstr, long start) throws SQLException; + + /** + * Retrieves a stream which can be used to write Ascii characters to this + * {@code Clob} object, starting at specified position. + * + * @param pos + * the position at which to start the writing. + * @return an OutputStream which can be used to write ASCII characters to + * this {@code Clob}. + * @throws SQLException + * if an error occurs accessing the {@code Clob}. + * @since Android 1.0 + */ + public OutputStream setAsciiStream(long pos) throws SQLException; + + /** + * Retrieves a stream which can be used to write a stream of unicode + * characters to this {@code Clob} object, at a specified position. + * + * @param pos + * the position at which to start the writing. + * @return a Writer which can be used to write unicode characters to this + * {@code Clob}. + * @throws SQLException + * if an error occurs accessing the {@code Clob}. + * @since Android 1.0 + */ + public Writer setCharacterStream(long pos) throws SQLException; + + /** + * Writes a given Java String to this {@code Clob} object at a specified + * position. + * + * @param pos + * the position at which to start the writing. + * @param str + * the string to write. + * @return the number of characters written. + * @throws SQLException + * if an error occurs accessing the {@code Clob}. + * @since Android 1.0 + */ + public int setString(long pos, String str) throws SQLException; + + /** + * Writes {@code len} characters of a string, starting at a specified + * character offset, to this {@code Clob}. + * + * @param pos + * the position at which to start the writing. + * @param str + * the String to write. + * @param offset + * the offset within {@code str} to start writing from. + * @param len + * the number of characters to write. + * @return the number of characters written. + * @throws SQLException + * if an error occurs accessing the {@code Clob}. + * @since Android 1.0 + */ + public int setString(long pos, String str, int offset, int len) + throws SQLException; + + /** + * Truncates this {@code Clob} after the specified number of characters. + * + * @param len + * the length in characters giving the place to + * truncate this {@code Clob}. + * @throws SQLException + * if an error occurs accessing the {@code Clob}. + * @since Android 1.0 + */ + public void truncate(long len) throws SQLException; +} diff --git a/sql/src/main/java/java/sql/Connection.java b/sql/src/main/java/java/sql/Connection.java new file mode 100644 index 0000000..523071c --- /dev/null +++ b/sql/src/main/java/java/sql/Connection.java @@ -0,0 +1,809 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.util.Map; + +/** + * A connection represents a link from a Java application to a database. All SQL + * statements and results are returned within the context of a connection. + * Database statements that are executed within this context form a + * database session which forms one or more closed transactions. Especially In distributed applications, multiple concurrent connections may exist accessing the same values of the database. + * which may lead to the following phenomena (referred to as <i>transaction isolation levels</i>): + * <ul> + * <li><i>dirty reads</i>:<br> + * reading values from table rows that are not committed.</br></li> + * <li><i>non-repeatable reads</i>:<br> + * reading table rows more than once in a transaction but getting back different + * data because other transactions have altered the rows between the reads.</br></li> + * <li><i>phantom reads</i>:<br> + * retrieving additional "phantom" rows in the course of repeated table reads + * because other transactions have inserted additional rows that satisfy an + * SQL {@code WHERE} clause</br></li> + * </ul> + * + * @since Android 1.0 + */ +public interface Connection { + + /** + * A constant indicating that transactions are not supported. + * + * @since Android 1.0 + */ + public static final int TRANSACTION_NONE = 0; + + /** + * No <i>dirty reads</i> are permitted, therefore transactions may not read + * a row containing uncommitted values - but does not prevent an application + * from <i>non-repeatable reads</i> and <i>phantom reads</i>. + * + * @since Android 1.0 + */ + public static final int TRANSACTION_READ_COMMITTED = 2; + + /** + * In the case that reading uncommitted values is allowed, the following + * incidents may happen which may lead to an invalid results: + * <ul> + * <li><i>dirty reads</i></li> + * <li><i>non-repeatable reads</i></li> + * <li><i>phantom reads</i></li> + * </ul> + * + * @since Android 1.0 + */ + public static final int TRANSACTION_READ_UNCOMMITTED = 1; + + /** + * A constant indicating that <i>dirty reads</i> and <i>non-repeatable + * reads</i> are <b>prevented</b> but <i>phantom reads</i> can occur. + * + * @since Android 1.0 + */ + public static final int TRANSACTION_REPEATABLE_READ = 4; + + /** + * The constant that indicates that the following incidents are <b>all + * prevented</b> (the opposite of {@link #TRANSACTION_READ_UNCOMMITTED}): + * <ul> + * <li><i>dirty reads</i></li> + * <li><i>non-repeatable reads</i></li> + * <li><i>phantom reads</i></li> + * </ul> + * + * @since Android 1.0 + */ + public static final int TRANSACTION_SERIALIZABLE = 8; + + /** + * Discards all warnings that may have arisen for this connection. + * Subsequent calls to {@link #getWarnings()} will return {@code null} + * up until a new warning condition occurs. + * + * @throws SQLException + * if there is a problem accessing the database. + */ + public void clearWarnings() throws SQLException; + + /** + * Causes the instant release of all database and driver connection + * resources associated with this object. Any subsequent invocations of this + * method have no effect. + * <p> + * It is strongly recommended that all connections are closed before they + * are dereferenced by the application ready for garbage collection. + * Although the {@code finalize} method of the connection closes the + * connection before garbage collection takes place, it is not advisable to + * leave the {@code close} operation to take place in this way. Mainly + * because undesired side-effects may appear. + * </p> + * + * @throws SQLException + * if there is a problem accessing the database. + */ + public void close() throws SQLException; + + /** + * Commits all of the changes made since the last {@code commit} or + * {@code rollback} of the associated transaction. All locks in the database + * held by this connection are also relinquished. Calling this operation on + * connection objects in {@code auto-commit} mode leads to an error. + * + * @throws SQLException + * if there is a problem accessing the database or if the target + * connection instance is in auto-commit mode. + */ + public void commit() throws SQLException; + + /** + * Returns a new instance of {@code Statement} for issuing SQL commands to + * the remote database. + * <p> + * {@code ResultSets} generated by the returned statement will default to + * type {@code ResultSet.TYPE_FORWARD_ONLY} and concurrency level {@code + * ResultSet.CONCUR_READ_ONLY}. + * + * @return a {@code Statement} object with default settings. + * @throws SQLException + * if there is a problem accessing the database. + * @see ResultSet + */ + public Statement createStatement() throws SQLException; + + /** + * Returns a new instance of {@code Statement} whose associated {@code + * ResultSet}s have the characteristics specified in the type and + * concurrency arguments. + * + * @param resultSetType + * one of the following type specifiers: + * <ul> + * <li>{@link ResultSet#TYPE_SCROLL_SENSITIVE} </li> <li> + * {@link ResultSet#TYPE_SCROLL_INSENSITIVE} </li> <li> + * {@link ResultSet#TYPE_FORWARD_ONLY}</li> + * </ul> + * @param resultSetConcurrency + * one of the following concurrency mode specifiers: + * <ul> + * <li>{@link ResultSet#CONCUR_UPDATABLE}</li> <li> + * {@link ResultSet#CONCUR_READ_ONLY}</li> + * </ul> + * @return a new instance of {@code Statement} capable of manufacturing + * {@code ResultSet}s that satisfy the specified {@code + * resultSetType} and {@code resultSetConcurrency} values. + * @throws SQLException + * if there is a problem accessing the database + */ + public Statement createStatement(int resultSetType, int resultSetConcurrency) + throws SQLException; + + /** + * Returns a new instance of {@code Statement} whose associated + * {@code ResultSet}s will have the characteristics specified in the + * type, concurrency and holdability arguments. + * + * @param resultSetType + * one of the following type specifiers: + * <ul> + * <li>{@link ResultSet#TYPE_SCROLL_SENSITIVE}</li> + * <li>{@link ResultSet#TYPE_SCROLL_INSENSITIVE}</li> + * <li>{@link ResultSet#TYPE_FORWARD_ONLY}</li> + * </ul> + * @param resultSetConcurrency + * one of the following concurrency mode specifiers: + * <ul> + * <li>{@link ResultSet#CONCUR_UPDATABLE}</li> + * <li>{@link ResultSet#CONCUR_READ_ONLY}</li> + * </ul> + * @param resultSetHoldability + * one of the following holdability mode specifiers: + * <ul> + * <li>{@link ResultSet#HOLD_CURSORS_OVER_COMMIT}</li> + * <li>{@link ResultSet#CLOSE_CURSORS_AT_COMMIT}</li> + * </ul> + * @return a new instance of {@code Statement} capable of + * manufacturing {@code ResultSet}s that satisfy the + * specified {@code resultSetType}, + * {@code resultSetConcurrency} and + * {@code resultSetHoldability} values. + * @throws SQLException + * if there is a problem accessing the database. + */ + public Statement createStatement(int resultSetType, + int resultSetConcurrency, int resultSetHoldability) + throws SQLException; + + /** + * Returns a {@code boolean} indicating whether or not this connection is in + * the {@code auto-commit} operating mode. + * + * @return {@code true} if {@code auto-commit} is on, otherwise {@code + * false}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public boolean getAutoCommit() throws SQLException; + + /** + * Gets this {@code Connection} object's current catalog name. + * + * @return the catalog name. {@code null} if there is no catalog + * name. + * @throws SQLException + * if there is a problem accessing the database. + */ + public String getCatalog() throws SQLException; + + /** + * Returns the holdability property that any {@code ResultSet} produced by + * this instance will have. + * + * @return one of the following holdability mode specifiers: + * <ul> + * <li>{@link ResultSet#HOLD_CURSORS_OVER_COMMIT}</li> <li> + * {@link ResultSet#CLOSE_CURSORS_AT_COMMIT}</li> + * </ul> + * @throws SQLException + * if there is a problem accessing the a database. + * @since Android 1.0 + */ + public int getHoldability() throws SQLException; + + /** + * Gets the metadata about the database referenced by this connection. The + * returned {@code DatabaseMetaData} describes the database topography, + * available stored procedures, SQL syntax and so on. + * + * @return a {@code DatabaseMetaData} object containing the database + * description. + * @throws SQLException + * if there is a problem accessing the a database. + * @since Android 1.0 + */ + public DatabaseMetaData getMetaData() throws SQLException; + + /** + * Returns the transaction isolation level for this connection. + * + * @return the transaction isolation value. + * @throws SQLException + * if there is a problem accessing the database. + * @see #TRANSACTION_NONE + * @see #TRANSACTION_READ_COMMITTED + * @see #TRANSACTION_READ_UNCOMMITTED + * @see #TRANSACTION_REPEATABLE_READ + * @see #TRANSACTION_SERIALIZABLE + * @since Android 1.0 + */ + public int getTransactionIsolation() throws SQLException; + + /** + * Returns the type mapping associated with this {@code Connection} object. + * The type mapping must be set on the application level. + * + * @return the Type Map as a {@code java.util.Map}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public Map<String, Class<?>> getTypeMap() throws SQLException; + + /** + * Gets the first instance of any {@code SQLWarning} objects that may have + * been created in the use of this connection. If at least one warning has + * occurred then this operation returns the first one reported. A {@code + * null} indicates that no warnings have occurred. + * <p> + * By invoking the {@link SQLWarning#getNextWarning()} method of the + * returned {@code SQLWarning} object it is possible to obtain all of + * this connection's warning objects. + * </p> + * + * @return the first warning as an SQLWarning object (may be {@code null}). + * @throws SQLException + * if there is a problem accessing the database or if the call + * has been made on a connection which has been previously + * closed. + * @since Android 1.0 + */ + public SQLWarning getWarnings() throws SQLException; + + /** + * Returns a {@code boolean} indicating whether or not this connection is in + * the {@code closed} state. The {@code closed} state may be entered into as + * a consequence of a successful invocation of the {@link #close()} method + * or else if an error has occurred that prevents the connection from + * functioning normally. + * + * @return {@code true} if closed, otherwise {@code false}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public boolean isClosed() throws SQLException; + + /** + * Returns a {@code boolean} indicating whether or not this connection is + * currently in the {@code read-only} state. + * + * @return {@code true} if in read-only state, otherwise {@code false}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public boolean isReadOnly() throws SQLException; + + /** + * Returns a string representation of the input SQL statement + * {@code sql} expressed in the underlying system's native SQL + * syntax. + * + * @param sql + * the JDBC form of an SQL statement. + * @return the SQL statement in native database format. + * @throws SQLException + * if there is a problem accessing the database + */ + public String nativeSQL(String sql) throws SQLException; + + /** + * Returns a new instance of {@code CallableStatement} that may be used for + * making stored procedure calls to the database. + * + * @param sql + * the SQL statement that calls the stored function + * @return a new instance of {@code CallableStatement} representing the SQL + * statement. {@code ResultSet}s emitted from this {@code + * CallableStatement} will default to type + * {@link ResultSet#TYPE_FORWARD_ONLY} and concurrency + * {@link ResultSet#CONCUR_READ_ONLY}. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public CallableStatement prepareCall(String sql) throws SQLException; + + /** + * Returns a new instance of {@code CallableStatement} that may be used for + * making stored procedure calls to the database. {@code ResultSet}s emitted + * from this {@code CallableStatement} will satisfy the specified {@code + * resultSetType} and {@code resultSetConcurrency} values. + * + * @param sql + * the SQL statement + * @param resultSetType + * one of the following type specifiers: + * <ul> + * <li>{@link ResultSet#TYPE_SCROLL_SENSITIVE}</li> + * <li>{@link ResultSet#TYPE_SCROLL_INSENSITIVE}</li> + * <li>{@link ResultSet#TYPE_FORWARD_ONLY}</li> + * </ul> + * @param resultSetConcurrency + * one of the following concurrency mode specifiers: + * <ul> + * <li>{@link ResultSet#CONCUR_READ_ONLY}</li> + * <li>{@link ResultSet#CONCUR_UPDATABLE}</li> + * </ul> + * @return a new instance of {@code CallableStatement} representing the + * precompiled SQL statement. {@code ResultSet}s emitted from this + * {@code CallableStatement} will satisfy the specified {@code + * resultSetType} and {@code resultSetConcurrency} values. + * @throws SQLException + * if a problem occurs accessing the database + * @since Android 1.0 + */ + public CallableStatement prepareCall(String sql, int resultSetType, + int resultSetConcurrency) throws SQLException; + + /** + * Returns a new instance of {@code CallableStatement} that may be used for + * making stored procedure calls to the database. {@code ResultSet}s created + * from this {@code CallableStatement} will have characteristics determined + * by the specified type, concurrency and holdability arguments. + * + * @param sql + * the SQL statement + * @param resultSetType + * one of the following type specifiers: + * <ul> + * <li>{@link ResultSet#TYPE_SCROLL_SENSITIVE}</li> + * <li>{@link ResultSet#TYPE_SCROLL_INSENSITIVE}</li> + * <li>{@link ResultSet#TYPE_FORWARD_ONLY}</li> + * </ul> + * @param resultSetConcurrency + * one of the following concurrency mode specifiers: + * <ul> + * <li>{@link ResultSet#CONCUR_READ_ONLY}</li> + * <li>{@link ResultSet#CONCUR_UPDATABLE}</li> + * </ul> + * @param resultSetHoldability + * one of the following holdability mode specifiers: + * <ul> + * <li>{@link ResultSet#HOLD_CURSORS_OVER_COMMIT}</li> + * <li>{@link ResultSet#CLOSE_CURSORS_AT_COMMIT}</li> + * </ul> + * @return a new instance of {@code CallableStatement} representing the + * precompiled SQL statement. {@code ResultSet}s emitted from this + * {@code CallableStatement} will satisfy the specified {@code + * resultSetType}, {@code resultSetConcurrency} and {@code + * resultSetHoldability} values. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public CallableStatement prepareCall(String sql, int resultSetType, + int resultSetConcurrency, int resultSetHoldability) + throws SQLException; + + /** + * Returns a new instance of {@code PreparedStatement} that may be used any + * number of times to execute parameterized requests on the database server. + * <p> + * Subject to JDBC driver support, this operation will attempt to send the + * precompiled version of the statement to the database. If + * the driver does not support precompiled statements, the statement will + * not reach the database server until it is executed. This distinction + * determines the moment when {@code SQLException}s get raised. + * </p> + * By default, {@code ResultSet}s from the returned object will be + * {@link ResultSet#TYPE_FORWARD_ONLY} type with a + * {@link ResultSet#CONCUR_READ_ONLY} mode of concurrency. + * + * @param sql + * the SQL statement. + * @return the {@code PreparedStatement} containing the supplied SQL + * statement. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public PreparedStatement prepareStatement(String sql) throws SQLException; + + /** + * Creates a default {@code PreparedStatement} that can retrieve + * automatically generated keys. Parameter {@code autoGeneratedKeys} may be + * used to tell the driver whether such keys should be made accessible. + * This is only relevant when the {@code sql} statement is an {@code insert} + * statement. + * <p> + * An SQL statement which may have {@code IN} parameters can be stored and + * precompiled in a {@code PreparedStatement}. The {@code PreparedStatement} + * can then be then be used to execute the statement multiple times in an + * efficient way. + * </p> + * Subject to JDBC driver support, this operation will attempt to send the + * precompiled version of the statement to the database. If + * the driver does not support precompiled statements, the statement will + * not reach the database server until it is executed. This distinction + * determines the moment when {@code SQLException}s get raised. + * <p> + * By default, {@code ResultSet}s from the returned object will be + * {@link ResultSet#TYPE_FORWARD_ONLY} type with a + * {@link ResultSet#CONCUR_READ_ONLY} mode of concurrency. + * </p> + * + * @param sql + * the SQL statement. + * @param autoGeneratedKeys + * one of the following generated key options: + * <ul> + * <li>{@link Statement#RETURN_GENERATED_KEYS}</li> + * <li>{@link Statement#NO_GENERATED_KEYS}</li> + * </ul> + * @return a new {@code PreparedStatement} instance representing the input + * SQL statement. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) + throws SQLException; + + /** + * Creates a default {@code PreparedStatement} that can retrieve the + * auto-generated keys designated by a supplied array. If {@code sql} is an + * SQL {@code INSERT} statement, the parameter {@code columnIndexes} is expected + * to hold the index values for each column in the statement's intended + * database table containing the autogenerated-keys of interest. Otherwise + * {@code columnIndexes} is ignored. + * <p> + * Subject to JDBC driver support, this operation will attempt to send the + * precompiled version of the statement to the database. If + * the driver does not support precompiled statements, the statement will + * not reach the database server until it is executed. This distinction + * determines the moment when {@code SQLException}s get raised. + * </p> + * <p> + * By default, {@code ResultSet}s from the returned object will be + * {@link ResultSet#TYPE_FORWARD_ONLY} type with a + * {@link ResultSet#CONCUR_READ_ONLY} concurrency mode. + * </p> + * + * @param sql + * the SQL statement. + * @param columnIndexes + * the indexes of the columns for which auto-generated keys + * should be made available. + * @return the PreparedStatement containing the supplied SQL statement. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) + throws SQLException; + + /** + * Creates a {@code PreparedStatement} that generates {@code ResultSet}s + * with the specified values of {@code resultSetType} and {@code + * resultSetConcurrency}. + * + * @param sql + * the SQL statement. It can contain one or more {@code '?'} + * {@code IN} parameter placeholders. + * @param resultSetType + * one of the following type specifiers: + * <ul> + * <li>{@link ResultSet#TYPE_SCROLL_SENSITIVE}</li> + * <li>{@link ResultSet#TYPE_SCROLL_INSENSITIVE}</li> + * <li>{@link ResultSet#TYPE_FORWARD_ONLY}</li> + * </ul> + * @param resultSetConcurrency + * one of the following concurrency mode specifiers: + * <ul> + * <li>{@link ResultSet#CONCUR_READ_ONLY}</li> + * <li>{@link ResultSet#CONCUR_UPDATABLE}</li> + * </ul> + * @return a new instance of {@code PreparedStatement} containing the SQL + * statement {@code sql}. {@code ResultSet}s emitted from this + * {@code PreparedStatement} will satisfy the specified {@code + * resultSetType} and {@code resultSetConcurrency} values. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency) throws SQLException; + + /** + * Creates a {@code PreparedStatement} that generates {@code ResultSet}s + * with the specified type, concurrency and holdability + * + * @param sql + * the SQL statement. It can contain one or more {@code '?' IN} + * parameter placeholders. + * @param resultSetType + * one of the following type specifiers: + * <ul> + * <li>{@link ResultSet#TYPE_SCROLL_SENSITIVE}</li> + * <li>{@link ResultSet#TYPE_SCROLL_INSENSITIVE}</li> + * <li>{@link ResultSet#TYPE_FORWARD_ONLY}</li> + * </ul> + * @param resultSetConcurrency + * one of the following concurrency mode specifiers: + * <ul> + * <li>{@link ResultSet#CONCUR_READ_ONLY}</li> + * <li>{@link ResultSet#CONCUR_UPDATABLE}</li> + * </ul> + * @param resultSetHoldability + * one of the following holdability mode specifiers: + * <ul> + * <li>{@link ResultSet#HOLD_CURSORS_OVER_COMMIT}</li> + * <li>{@link ResultSet#CLOSE_CURSORS_AT_COMMIT}</li> + * </ul> + * @return a new instance of {@code PreparedStatement} containing the SQL + * statement {@code sql}. {@code ResultSet}s emitted from this + * {@code PreparedStatement} will satisfy the specified {@code + * resultSetType}, {@code resultSetConcurrency} and {@code + * resultSetHoldability} values. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency, int resultSetHoldability) + throws SQLException; + + /** + * Creates a default {@code PreparedStatement} that can retrieve the + * auto-generated keys designated by a supplied array. If {@code sql} is an + * SQL {@code INSERT} statement, {@code columnNames} is expected to hold the + * names of each column in the statement's associated database table + * containing the autogenerated-keys of interest. Otherwise {@code + * columnNames} is ignored. + * <p> + * Subject to JDBC driver support, this operation will attempt to send the + * precompiled version of the statement to the database. Alternatively, if + * the driver is not capable of handling precompiled statements, the + * statement will not reach the database server until it is executed. This + * will have a bearing on precisely <i>when</i> {@code SQLException} + * instances get raised. + * </p> + * <p> + * By default, ResultSets from the returned object will be + * {@link ResultSet#TYPE_FORWARD_ONLY} type with a + * {@link ResultSet#CONCUR_READ_ONLY} concurrency mode. + * </p> + * + * @param sql + * the SQL statement. + * @param columnNames + * the names of the columns for which auto-generated keys should + * be made available. + * @return the PreparedStatement containing the supplied SQL statement. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public PreparedStatement prepareStatement(String sql, String[] columnNames) + throws SQLException; + + /** + * Releases the specified {@code savepoint} from the present transaction. Once removed, + * the {@code Savepoint} is considered invalid and should not be referenced + * further. + * + * @param savepoint + * the object targeted for removal. + * @throws SQLException + * if there is a problem with accessing the database or if + * {@code savepoint} is considered not valid in this + * transaction. + * @since Android 1.0 + */ + public void releaseSavepoint(Savepoint savepoint) throws SQLException; + + /** + * Rolls back all updates made so far in this transaction and + * relinquishes all acquired database locks. It is an error to invoke this + * operation when in auto-commit mode. + * + * @throws SQLException + * if there is a problem with the database or if the method is + * called while in auto-commit mode of operation. + * @since Android 1.0 + */ + public void rollback() throws SQLException; + + /** + * Undoes all changes made after the supplied {@code Savepoint} object was + * set. This method should only be used when auto-commit mode is disabled. + * + * @param savepoint + * the Savepoint to roll back to + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public void rollback(Savepoint savepoint) throws SQLException; + + /** + * Sets this connection's auto-commit mode {@code on} or {@code off}. + * <p> + * Putting a Connection into auto-commit mode means that all associated SQL + * statements are run and committed as separate transactions. + * By contrast, setting auto-commit to {@code off} means that associated SQL + * statements get grouped into transactions that need to be completed by + * explicit calls to either the {@link #commit()} or {@link #rollback()} + * methods. + * </p> + * Auto-commit is the default mode for new connection instances. + * <p> + * When in this mode, commits will automatically occur upon successful SQL + * statement completion or upon successful completion of an execute. + * Statements are not considered successfully completed until all associated + * {@code ResultSet}s and output parameters have been obtained or closed. + * </p> + * <p> + * Calling this operation during an uncommitted transaction will result in + * it being committed. + * </p> + * + * @param autoCommit + * {@code boolean} indication of whether to put the target + * connection into auto-commit mode ({@code true}) or not ( + * {@code false}). + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public void setAutoCommit(boolean autoCommit) throws SQLException; + + /** + * Sets the catalog name for this connection. This is used to select a + * subspace of the database for future work. If the driver does not support + * catalog names, this method is ignored. + * + * @param catalog + * the catalog name to use. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public void setCatalog(String catalog) throws SQLException; + + /** + * Sets the holdability of the {@code ResultSet}s created by this Connection. + * + * @param holdability + * one of the following holdability mode specifiers: + * <ul> + * <li>{@link ResultSet#CLOSE_CURSORS_AT_COMMIT}</li> + * <li>{@link ResultSet#HOLD_CURSORS_OVER_COMMIT}</li> + * <li> + * </ul> + * @throws SQLException + * if there is a problem accessing the database + */ + public void setHoldability(int holdability) throws SQLException; + + /** + * Sets this connection to read-only mode. + * <p> + * This serves as a hint to the driver, which can enable database + * optimizations. + * </p> + * + * @param readOnly + * {@code true} to set the Connection to read only mode. {@code + * false} disables read-only mode. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public void setReadOnly(boolean readOnly) throws SQLException; + + /** + * Creates an unnamed {@code Savepoint} in the current transaction. + * + * @return a {@code Savepoint} object for this savepoint. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public Savepoint setSavepoint() throws SQLException; + + /** + * Creates a named {@code Savepoint} in the current transaction. + * + * @param name + * the name to use for the new {@code Savepoint}. + * @return a {@code Savepoint} object for this savepoint. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public Savepoint setSavepoint(String name) throws SQLException; + + /** + * Sets the transaction isolation level for this Connection. + * <p> + * If this method is called during a transaction, the results are + * implementation defined. + * </p> + * + * @param level + * the new transaction isolation level to use from the following + * list of possible values: + * <ul> + * <li>{@link #TRANSACTION_READ_COMMITTED} + * <li>{@link #TRANSACTION_READ_UNCOMMITTED} + * <li>{@link #TRANSACTION_REPEATABLE_READ} + * <li>{@link #TRANSACTION_SERIALIZABLE} + * </ul> + * @throws SQLException + * if there is a problem with the database or if the value of + * {@code level} is not one of the expected constant values. + * @since Android 1.0 + */ + public void setTransactionIsolation(int level) throws SQLException; + + /** + * Sets the {@code TypeMap} for this connection. The input {@code map} + * should contain mappings between complex Java and SQL types. + * + * @param map + * the new type map. + * @throws SQLException + * if there is a problem accessing the database or if {@code + * map} is not an instance of {@link Map}. + * @since Android 1.0 + */ + public void setTypeMap(Map<String, Class<?>> map) throws SQLException; +} diff --git a/sql/src/main/java/java/sql/DataTruncation.java b/sql/src/main/java/java/sql/DataTruncation.java new file mode 100644 index 0000000..a472cc5 --- /dev/null +++ b/sql/src/main/java/java/sql/DataTruncation.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.io.Serializable; + +/** + * An exception which is thrown when a JDBC driver unexpectedly truncates a data + * value either when reading (resulting in warning), or when writing data + * (resulting in an error). The {@code SQLState} error code for truncated data + * is {@code 01004}. + * + * @since Android 1.0 + */ +public class DataTruncation extends SQLWarning implements Serializable { + + private static final long serialVersionUID = 6464298989504059473L; + + private int index = 0; + + private boolean parameter = false; + + private boolean read = false; + + private int dataSize = 0; + + private int transferSize = 0; + + private static final String THE_REASON = "Data truncation"; //$NON-NLS-1$ + + private static final String THE_SQLSTATE = "01004"; //$NON-NLS-1$ + + private static final int THE_ERROR_CODE = 0; + + /** + * Creates the {@code DataTruncation} object. The reason is set to {@code + * "Data truncation"}, the {@code ErrorCode} is set to the {@code + * SQLException} default value, and the other fields are set to the values + * supplied as arguments. + * + * @param index + * the Index value of the column value or parameter that was + * truncated. + * @param parameter + * {@code true} if it was a parameter value that was truncated, + * {@code false} otherwise. + * @param read + * {@code true} if the truncation occurred on a read operation, + * {@code false} otherwise. + * @param dataSize + * the original size of the truncated data. + * @param transferSize + * the size of the data after truncation. + * @since Android 1.0 + */ + public DataTruncation(int index, boolean parameter, boolean read, + int dataSize, int transferSize) { + super(THE_REASON, THE_SQLSTATE, THE_ERROR_CODE); + this.index = index; + this.parameter = parameter; + this.read = read; + this.dataSize = dataSize; + this.transferSize = transferSize; + } + + /** + * Gets the number of bytes of data that should have been read/written. + * + * @return the number of bytes that should have been read or written. The + * value is set to {@code -1} if the size is unknown. + * @since Android 1.0 + */ + public int getDataSize() { + return dataSize; + } + + /** + * Gets the index of the column or of the parameter that was truncated. + * + * @return the index number of the column or of the parameter. + * @since Android 1.0 + */ + public int getIndex() { + return index; + } + + /** + * Gets whether the value truncated was a parameter value or a column value. + * + * @return {@code true} if the value truncated was a parameter value, + * {@code false} if it was a column value. + * @since Android 1.0 + */ + public boolean getParameter() { + return parameter; + } + + /** + * Gets whether the value was truncated on a read operation or a write + * operation + * + * @return {@code true} if the value was truncated on a read operation, + * {@code false} otherwise. + * @since Android 1.0 + */ + public boolean getRead() { + return read; + } + + /** + * Gets the number of bytes of data that was actually read or written. + * + * @return the number of bytes actually read/written. The value may be set + * to {@code -1} if the size is unknown. + * @since Android 1.0 + */ + public int getTransferSize() { + return transferSize; + } +} diff --git a/sql/src/main/java/java/sql/DatabaseMetaData.java b/sql/src/main/java/java/sql/DatabaseMetaData.java new file mode 100644 index 0000000..82219c5 --- /dev/null +++ b/sql/src/main/java/java/sql/DatabaseMetaData.java @@ -0,0 +1,3356 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +/** + * An interface which provides comprehensive information about the database + * management system and its supported features. + * <p> + * This interface is implemented by JDBC driver vendors in order to provide + * information about the underlying database capabilities in association with + * the JDBC driver. + * </p> + * <p> + * Some of the methods in this interface take string parameters which are + * patterns. Within these string patterns, {@code '%'} and {@code '_'} + * characters have special meanings. {@code '%'} means + * "match any substring of 0 or more characters". {@code '_'} means + * "match any character". Only metadata entries that match the pattern are + * returned. If such a search pattern string is set to {@code null}, that + * argument's criteria are dropped from the search. + * </p> + * + * @since Android 1.0 + */ +public interface DatabaseMetaData { + + /** + * States that it may not be permitted to store {@code NULL} values. + * + * @since Android 1.0 + */ + public static final short attributeNoNulls = 0; + + /** + * States that {@code NULL} values are definitely permitted. + * + * @since Android 1.0 + */ + public static final short attributeNullable = 1; + + /** + * States that whether {@code NULL} values are permitted is unknown. + * + * @since Android 1.0 + */ + public static final short attributeNullableUnknown = 2; + + /** + * States the best row identifier is <em>NOT</em> a pseudo column. + * + * @since Android 1.0 + */ + public static final int bestRowNotPseudo = 1; + + /** + * States that the best row identifier is a pseudo column. + * + * @since Android 1.0 + */ + public static final int bestRowPseudo = 2; + + /** + * States that the remainder of the current session is used as the scope for + * the best row identifier. + * + * @since Android 1.0 + */ + public static final int bestRowSession = 2; + + /** + * States that best row identifier scope lasts only while the row is being + * used. + * + * @since Android 1.0 + */ + public static final int bestRowTemporary = 0; + + /** + * States that the remainder of the current transaction is used as the scope + * for the best row identifier. + * + * @since Android 1.0 + */ + public static final int bestRowTransaction = 1; + + /** + * States that the best row identifier may or may not be a pseudo column. + * + * @since Android 1.0 + */ + public static final int bestRowUnknown = 0; + + /** + * States that the column must not allow {@code NULL} values. + * + * @since Android 1.0 + */ + public static final int columnNoNulls = 0; + + /** + * States that the column definitely allows {@code NULL} values. + * + * @since Android 1.0 + */ + public static final int columnNullable = 1; + + /** + * States that it is unknown whether the columns may be nulled. + * + * @since Android 1.0 + */ + public static final int columnNullableUnknown = 2; + + /** + * For the column {@code UPDATE_RULE}, states that when the primary key is + * updated, the foreign key (imported key) is changed accordingly. + * + * @since Android 1.0 + */ + public static final int importedKeyCascade = 0; + + /** + * States that the evaluation of foreign key constraints is deferred (delayed + * until commit). + * + * @since Android 1.0 + */ + public static final int importedKeyInitiallyDeferred = 5; + + /** + * States that the evaluation of foreign key constraint is {@code IMMEDIATE} + * . + * + * @since Android 1.0 + */ + public static final int importedKeyInitiallyImmediate = 6; + + /** + * For the columns {@code UPDATE_RULE} and {@code DELETE_RULE}, states that + * if the primary key has been imported, it cannot be updated or deleted. + * + * @since Android 1.0 + */ + public static final int importedKeyNoAction = 3; + + /** + * States that the evaluation of foreign key constraint must not be {@code + * DEFERRED}. + * + * @since Android 1.0 + */ + public static final int importedKeyNotDeferrable = 7; + + /** + * States that a primary key must not be updated when imported as a foreign + * key by some other table. Used for the column {@code UPDATE_RULE}. + * + * @since Android 1.0 + */ + public static final int importedKeyRestrict = 1; + + /** + * States that when the primary key is modified (updated or deleted) the + * foreign (imported) key is changed to its default value. Applies to the + * {@code UPDATE_RULE} and {@code DELETE_RULE} columns. + * + * @since Android 1.0 + */ + public static final int importedKeySetDefault = 4; + + /** + * States that when the primary key is modified (updated or deleted) the + * foreign (imported) key is changed to {@code NULL}. Applies to the {@code + * UPDATE_RULE} and {@code DELETE_RULE} columns. + * + * @since Android 1.0 + */ + public static final int importedKeySetNull = 2; + + /** + * States that the column stores {@code IN} type parameters. + * + * @since Android 1.0 + */ + public static final int procedureColumnIn = 1; + + /** + * States that this column stores {@code INOUT} type parameters. + * + * @since Android 1.0 + */ + public static final int procedureColumnInOut = 2; + + /** + * States that this column stores {@code OUT} type parameters. + * + * @since Android 1.0 + */ + public static final int procedureColumnOut = 4; + + /** + * States that the column stores results. + * + * @since Android 1.0 + */ + public static final int procedureColumnResult = 3; + + /** + * States that the column stores return values. + * + * @since Android 1.0 + */ + public static final int procedureColumnReturn = 5; + + /** + * States that type of the column is unknown. + * + * @since Android 1.0 + */ + public static final int procedureColumnUnknown = 0; + + /** + * States that {@code NULL} values are not permitted. + * + * @since Android 1.0 + */ + public static final int procedureNoNulls = 0; + + /** + * States that the procedure does not return a result. + * + * @since Android 1.0 + */ + public static final int procedureNoResult = 1; + + /** + * States that {@code NULL} values are permitted. + * + * @since Android 1.0 + */ + public static final int procedureNullable = 1; + + /** + * States that it is unknown whether {@code NULL} values are permitted. + * + * @since Android 1.0 + */ + public static final int procedureNullableUnknown = 2; + + /** + * States that it is unknown whether or not the procedure returns a result. + * + * @since Android 1.0 + */ + public static final int procedureResultUnknown = 0; + + /** + * States that the procedure returns a result. + * + * @since Android 1.0 + */ + public static final int procedureReturnsResult = 2; + + /** + * States that the value is an SQL99 {@code SQLSTATE} value. + * + * @since Android 1.0 + */ + public static final int sqlStateSQL99 = 2; + + /** + * States that the value is an SQL {@code CLI SQLSTATE} value as defined by + * the X/Open standard. + * + * @since Android 1.0 + */ + public static final int sqlStateXOpen = 1; + + /** + * States that this table index is a clustered index. + * + * @since Android 1.0 + */ + public static final short tableIndexClustered = 1; + + /** + * States that this table index is a hashed index. + * + * @since Android 1.0 + */ + public static final short tableIndexHashed = 2; + + /** + * States this table's index is neither a clustered index, not a hashed + * index, and not a table statistics index; i.e. it is something else. + * + * @since Android 1.0 + */ + public static final short tableIndexOther = 3; + + /** + * States this column has the table's statistics, and that it is returned in + * conjunction with the table's index description. + * + * @since Android 1.0 + */ + public static final short tableIndexStatistic = 0; + + /** + * States that a {@code NULL} value is <em>NOT</em> permitted for + * this data type. + * + * @since Android 1.0 + */ + public static final int typeNoNulls = 0; + + /** + * States that a {@code NULL} value is permitted for this data type. + * + * @since Android 1.0 + */ + public static final int typeNullable = 1; + + /** + * States that it is unknown if a {@code NULL} value is permitted for + * this data type. + * + * @since Android 1.0 + */ + public static final int typeNullableUnknown = 2; + + /** + * States that this column shall not be used for {@code WHERE} statements + * with a {@code LIKE} clause. + * + * @since Android 1.0 + */ + public static final int typePredBasic = 2; + + /** + * States that this column can only be used in a {@code WHERE...LIKE} + * statement. + * + * @since Android 1.0 + */ + public static final int typePredChar = 1; + + /** + * States that this column does not support searches. + * + * @since Android 1.0 + */ + public static final int typePredNone = 0; + + /** + * States that the column is searchable. + * + * @since Android 1.0 + */ + public static final int typeSearchable = 3; + + /** + * States that the version column is known to be not a pseudo column. + */ + public static final int versionColumnNotPseudo = 1; + + /** + * States that this version column is known to be a pseudo column. + */ + public static final int versionColumnPseudo = 2; + + /** + * States that the version column may be a pseudo column or not. + */ + public static final int versionColumnUnknown = 0; + + /** + * Returns whether all procedures returned by {@link #getProcedures} can be + * called by the current user. + * + * @return {@code true} if all procedures can be called by the current user, + * {@code false} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean allProceduresAreCallable() throws SQLException; + + /** + * Returns whether all the tables returned by {@code getTables} can be used + * by the current user in a {@code SELECT} statement. + * + * @return {@code true} if all the tables can be used,{@code false} + * otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean allTablesAreSelectable() throws SQLException; + + /** + * Returns whether a data definition statement in a transaction forces a {@code + * commit} of the transaction. + * + * @return {@code true} if the statement forces a commit, {@code false} + * otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean dataDefinitionCausesTransactionCommit() throws SQLException; + + /** + * Returns whether the database ignores data definition statements within a + * transaction. + * + * @return {@code true} if the database ignores a data definition statement, + * {@code false} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean dataDefinitionIgnoredInTransactions() throws SQLException; + + /** + * Returns whether a visible row delete can be detected by calling + * {@link ResultSet#rowDeleted}. + * + * @param type + * the type of the {@code ResultSet} involved: {@code + * ResultSet.TYPE_FORWARD_ONLY}, {@code + * ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code + * ResultSet.TYPE_SCROLL_SENSITIVE} + * @return {@code true} if the visible row delete can be detected, {@code + * false} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean deletesAreDetected(int type) throws SQLException; + + /** + * Returns whether the return value of {@code getMaxRowSize} includes the + * SQL data types {@code LONGVARCHAR} and {@code LONGVARBINARY}. + * + * @return {@code true} if the return value includes {@code LONGVARBINARY} + * and {@code LONGVARCHAR}, otherwise {@code false}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean doesMaxRowSizeIncludeBlobs() throws SQLException; + + /** + * Returns a {@code ResultSet} describing a subset of the attributes of a + * specified SQL User Defined Type (UDT) for a specified schema and catalog. + * The subset is determined by restricting to those attributes whose + * name matches the {@code attributeNamePattern} and whose type name + * matches the {@code typeNamePattern}. Each row of the {@code ResultSet} + * describes one attribute, and the rows are ordered by the columns {@code TYPE_SCHEM}, + * {@code TYPE_NAME} and {@code ORDINAL_POSITION}. Inherited attributes + * are not included. + * <p> + * The columns of the returned {@code ResultSet} object have the following + * names and meanings: + * <ol> + * <li>{@code TYPE_CAT} - String - the type catalog name (possibly {@code + * null})</li> + * <li>{@code TYPE_SCHEM} - String - the type schema name (possibly {@code + * null})</li> + * <li>{@code TYPE_NAME} - String - the type name</li> + * <li>{@code ATTR_NAME} - String - the attribute name</li> + * <li>{@code DATA_TYPE} - int - the attribute type as defined in {@code + * java.sql.Types}</li> + * <li>{@code ATTR_TYPE_NAME} - String - the attribute type name. This + * depends on the data source. For a {@code UDT} the name is fully + * qualified. For a {@code REF} it is both fully qualified and represents + * the target type of the reference.</li> + * <li>{@code ATTR_SIZE} - int - the column size. When referring to char and + * date types this value is the maximum number of characters. When referring + * to numeric types is is the precision.</li> + * <li>{@code DECIMAL_DIGITS} - int - how many fractional digits are + * supported</li> + * <li>{@code NUM_PREC_RADIX} - int - numeric values radix</li> + * <li>{@code NULLABLE} - int - whether {@code NULL} is permitted: + * <ul> + * <li>DatabaseMetaData.attributeNoNulls - {@code NULL} values not permitted</li> + * <li>DatabaseMetaData.attributeNullable - {@code NULL} values definitely + * permitted</li> + * <li>DatabaseMetaData.attributeNullableUnknown - unknown</li> + * </ul> + * </li> + * <li>{@code REMARKS} - String - a comment describing the attribute + * (possibly {@code null})</li> + * <li>ATTR_DEF - String - Default value for the attribute (possibly {@code + * null})</li> + * <li>{@code SQL_DATA_TYPE} - int - not used</li> + * <li>SQL_DATETIME_SUB - int - not used</li> + * <li>CHAR_OCTET_LENGTH - int - for {@code CHAR} types, the max number of + * bytes in the column</li> + * <li>ORDINAL_POSITION - int - The index of the column in the table (where + * the count starts from 1, not 0)</li> + * <li>IS_NULLABLE - String - {@code "NO"} = the column does not allow {@code + * NULL}s, {@code "YES"} = the column allows {@code NULL}s, "" = status unknown</li> + * <li>{@code SCOPE_CATALOG} - String - if the {@code DATA_TYPE} is {@code REF}, + * this gives the catalog of the table corresponding to the attribute's scope. + * NULL if the {@code DATA_TYPE} is not REF.</li> + * <li>{@code SCOPE_SCHEMA} - String - if the {@code DATA_TYPE} is {@code REF}, + * this gives the schema of the table corresponding to the attribute's scope. + * NULL if the {@code DATA_TYPE} is not REF.</li> + * <li>{@code SCOPE_TABLE} - String - if the {@code DATA_TYPE} is {@code REF}, + * this gives the name of the table corresponding to the attribute's scope. + * NULL if the {@code DATA_TYPE} is not REF.</li> + * <li>{@code SOURCE_DATA_TYPE} - String - The source type for a user + * generated REF type or for a Distinct type. ({@code NULL} if {@code + * DATA_TYPE} is not DISTINCT or a user generated REF)</li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schemaPattern + * a schema name pattern. {@code null} is used to imply no + * narrowing of the search by a schema name. Otherwise, the name + * must match a schema name in the database, with "" used to + * retrieve those without a schema name. + * @param typeNamePattern + * a type name. This pattern must match the type name stored in + * the database. + * @param attributeNamePattern + * an Attribute name. This pattern must match the attribute name as stored in + * the database. + * @return a {@code ResultSet}, where each row is an attribute description. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public ResultSet getAttributes(String catalog, String schemaPattern, + String typeNamePattern, String attributeNamePattern) + throws SQLException; + + /** + * Returns a list of a table's optimal set of columns that uniquely + * identify the rows. The results are ordered by {@code SCOPE} (see below). + * <p> + * The results are returned as a table, with one entry for each column, as + * follows: + * <ol> + * <li>{@code SCOPE} - short - the {@code SCOPE} of the result, as follows: + * <ul> + * <li>{@code DatabaseMetaData.bestRowTemporary} - the result is very temporary, + * only valid while on the current row</li> + * <li>{@code DatabaseMetaData.bestRowTransaction} - the result is good for remainder of + * current transaction</li> + * <li>{@code DatabaseMetaData.bestRowSession} - the result is good for remainder of + * database session</li> + * </ul> + * </li> + * <li>{@code COLUMN_NAME} - String - the column name</li> + * <li>{@code DATA_TYPE} - int - the Type of the data, as defined in {@code + * java.sql.Types}</li> + * <li>{@code TYPE_NAME} - String - the Name of the type - database dependent. + * For UDT types the name is fully qualified</li> + * <li>{@code COLUMN_SIZE} - int - the precision of the data in the column</li> + * <li>{@code BUFFER_LENGTH} - int - not used</li> + * <li>{@code DECIMAL_DIGITS} - short - number of fractional digits</li> + * <li>{@code PSEUDO_COLUMN} - short - whether this is a pseudo column (e.g. + * an Oracle {@code ROWID}): + * <ul> + * <li>{@code DatabaseMetaData.bestRowUnknown} - it is not known whether this is + * a pseudo column</li> + * <li>{@code DatabaseMetaData.bestRowNotPseudo} - the column is not pseudo</li> + * <li>{@code DatabaseMetaData.bestRowPseudo} - the column is a pseudo column</li> + * </ul> + * </li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schema + * a schema name pattern. {@code null} is used to imply no + * narrowing of the search by schema name. Otherwise, the name + * must match a schema name in the database, with "" used to + * retrieve those without a schema name. + * @param table + * the table name. This must match the name of the table as + * declared in the database. + * @param scope + * the {@code SCOPE} of interest, values as defined above. + * @param nullable + * {@code true} = include columns that are nullable, {@code + * false} = do not include nullable columns. + * @return a {@code ResultSet} where each row is a description of a column + * and the complete set of rows is the optimal set for this table. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public ResultSet getBestRowIdentifier(String catalog, String schema, + String table, int scope, boolean nullable) throws SQLException; + + /** + * Returns the set of catalog names available in this database. The set is + * returned ordered by catalog name. + * + * @return a {@code ResultSet} containing the catalog names, with each row + * containing one catalog name (as a {@code String}) in the + * single column named {@code TABLE_CAT}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public ResultSet getCatalogs() throws SQLException; + + /** + * Returns the separator that this database uses between a catalog name and + * table name. + * + * @return a String containing the separator. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public String getCatalogSeparator() throws SQLException; + + /** + * Returns the term that the database vendor prefers term for "catalog". + * + * @return a String with the vendor's term for "catalog". + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public String getCatalogTerm() throws SQLException; + + /** + * Returns a description of access rights for a table's columns. Only access + * rights matching the criteria for the column name are returned. + * <p> + * The description is returned as a {@code ResultSet} with rows of data for + * each access right, with columns as follows: + * <ol> + * <li>{@code TABLE_CAT} - String - the catalog name (possibly {@code null})</li> + * <li>{@code TABLE_SCHEM} - String - the schema name (possibly {@code null})</li> + * <li>{@code TABLE_NAME} - String - the table name</li> + * <li>{@code COLUMN_NAME} - String - the Column name</li> + * <li>{@code GRANTOR} - String - the grantor of access (possibly {@code + * null})</li> + * <li>{@code PRIVILEGE} - String - Access right - one of SELECT, INSERT, + * UPDATE, REFERENCES,...</li> + * <li>{@code IS_GRANTABLE} - String - {@code "YES"} implies that the + * receiver can grant access to others, {@code "NO"} if the receiver cannot + * grant access to others, {@code null} if unknown.</li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schema + * a schema name pattern. {@code null} is used to imply no + * narrowing of the search by schema name. Otherwise, the name + * must match a schema name in the database, with "" used to + * retrieve those without a schema name. + * @param table + * the table name. This must match the name of the table as + * declared in the database. + * @param columnNamePattern + * the column name. This must match the name of a column in the + * table in the database. + * @return a {@code ResultSet} containing the access rights, one row for + * each privilege description. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public ResultSet getColumnPrivileges(String catalog, String schema, + String table, String columnNamePattern) throws SQLException; + + /** + * Returns a description of table columns available in a specified catalog. + * Only descriptions meeting the specified catalog, schema, table, and column + * names are returned. + * <p> + * The descriptions are returned as a {@code ResultSet} conforming to the + * following data layout, with one row per table column: + * <ol> + * <li>{@code TABLE_CAT} - String - the catalog name (possibly {@code null})</li> + * <li>{@code TABLE_SCHEM} - String - the schema name (possibly {@code null})</li> + * <li>{@code TABLE_NAME} - String - the table name</li> + * <li>{@code COLUMN_NAME} - String - the column name</li> + * <li>{@code DATA_TYPE} - int - the SQL type as specified in {@code + * java.sql.Types}</li> + * <li>{@code TYPE_NAME} - String - the name of the data type, (database-dependent, + * UDT names are fully qualified)</li> + * <li>{@code COLUMN_SIZE} - int - the column size (the precision for numeric + * types, max characters for {@code char} and {@code date} types)</li> + * <li>{@code BUFFER_LENGTH} - int - Not used</li> + * <li>{@code DECIMAL_DIGITS} - int - maximum number of fractional digits</li> + * <li>{@code NUM_PREC_RADIX} - int - the radix for numerical types</li> + * <li>{@code NULLABLE} - int - whether the column allows {@code null}s: + * <ul> + * <li>DatabaseMetaData.columnNoNulls = may not allow {@code NULL}s</li> + * <li>DatabaseMetaData.columnNullable = does allow {@code NULL}s</li> + * <li>DatabaseMetaData.columnNullableUnknown = unknown {@code NULL} status</li> + * </ul> + * </li> + * <li>{@code REMARKS} - String - A description of the column (possibly + * {@code null})</li> + * <li>{@code COLUMN_DEF} - String - Default value for the column (possibly + * {@code null})</li> + * <li>{@code SQL_DATA_TYPE} - int - not used</li> + * <li>{@code SQL_DATETIME_SUB} - int - not used</li> + * <li>{@code CHAR_OCTET_LENGTH} - int - maximum number of bytes in the + * {@code char} type columns</li> + * <li>{@code ORDINAL_POSITION} - int - the column index in the table (1 based)</li> + * <li>{@code IS_NULLABLE} - String - {@code "NO"} = column does not allow + * NULLs, {@code "YES"} = column allows NULLs, "" = {@code NULL} status + * unknown</li> + * <li>{@code SCOPE_CATALOG} - String - if the {@code DATA_TYPE} is {@code REF}, + * this gives the catalog of the table corresponding to the attribute's scope. + * NULL if the {@code DATA_TYPE} is not REF.</li> + * <li>{@code SCOPE_SCHEMA} - String - if the {@code DATA_TYPE} is {@code REF}, + * this gives the schema of the table corresponding to the attribute's scope. + * NULL if the {@code DATA_TYPE} is not REF.</li> + * <li>{@code SCOPE_TABLE} - String - if the {@code DATA_TYPE} is {@code REF}, + * this gives the name of the table corresponding to the attribute's scope. + * NULL if the {@code DATA_TYPE} is not REF.</li> + * <li>{@code SOURCE_DATA_TYPE} - String - The source type for a user + * generated REF type or for a Distinct type. ({@code NULL} if {@code + * DATA_TYPE} is not DISTINCT or a user generated REF)</li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schemaPattern + * a schema name pattern. {@code null} is used to imply no + * narrowing of the search by schema name. Otherwise, the name + * must match a schema name in the database, with "" used to + * retrieve those without a schema name. + * @param tableNamePattern + * the table name. This must match the name of the table as + * declared in the database. + * @param columnNamePattern + * the column name. This must match the name of a column in the + * table in the database. + * @return the descriptions as a {@code ResultSet} with rows in the form + * defined above. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public ResultSet getColumns(String catalog, String schemaPattern, + String tableNamePattern, String columnNamePattern) + throws SQLException; + + /** + * Returns the database connection that created this metadata. + * + * @return the connection to the database. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public Connection getConnection() throws SQLException; + + /** + * Returns a list of foreign key columns in a given foreign key table that + * reference the primary key columns of a supplied primary key table. This + * describes how one table imports the key of another table. It would be + * expected to return a single foreign key - primary key pair in most cases. + * <p> + * The descriptions are returned as a {@code ResultSet} with one row for + * each foreign key, with the following layout: + * <ol> + * <li>{@code PKTABLE_CAT} - String - from the primary key table : Catalog + * (possibly {@code null})</li> + * <li>{@code PKTABLE_SCHEM} - String - from the primary key table : Schema + * (possibly {@code null})</li> + * <li>{@code PKTABLE_NAME} - String - from the primary key table : name</li> + * <li>{@code PKCOLUMN_NAME} - String - from the primary key column : name</li> + * <li>{@code FKTABLE_CAT} - String - from the foreign key table : the + * catalog name being exported (possibly {@code null})</li> + * <li>{@code FKTABLE_SCHEM} - String - from the foreign key table : the schema name + * being exported (possibly {@code null})</li> + * <li>{@code FKTABLE_NAME} - String - from the foreign key table : the name being + * exported</li> + * <li>{@code FKCOLUMN_NAME} - String - from the foreign key column : the name being + * exported</li> + * <li>{@code KEY_SEQ} - short - the sequence number (in the foreign key)</li> + * <li>{@code UPDATE_RULE} - short - a value giving the rule for how to treat the corresponding foreign key when a primary + * key is updated: + * <ul> + * <li>{@code DatabaseMetaData.importedKeyNoAction} - don't allow the + * primary key to be updated if it is imported as a foreign key</li> + * <li>{@code DatabaseMetaData.importedKeyCascade} - change the imported key to + * match the updated primary key</li> + * <li>{@code DatabaseMetaData.importedKeySetNull} - set the imported key to + * {@code null}</li> + * <li>{@code DatabaseMetaData.importedKeySetDefault} - set the imported key + * to its default value</li> + * <li>{@code DatabaseMetaData.importedKeyRestrict} - same as {@code + * importedKeyNoAction}</li> + * </ul> + * </li> + * <li>{@code DELETE_RULE} - short - a value giving the rule for how to treat the foreign key when the corresponding primary + * key is deleted: + * <ul> + * <li>{@code DatabaseMetaData.importedKeyNoAction} - don't allow the + * primary key to be deleted if it is imported as a foreign key</li> + * <li>{@code DatabaseMetaData.importedKeyCascade} - delete those rows that + * import a deleted key</li> + * <li>{@code DatabaseMetaData.importedKeySetNull} - set the imported key to + * {@code null}</li> + * <li>{@code DatabaseMetaData.importedKeySetDefault} - set the imported key + * to its default value</li> + * <li>{@code DatabaseMetaData.importedKeyRestrict} - same as + * importedKeyNoAction</li> + * </ul> + * </li> + * <li>{@code FK_NAME} - String - the foreign key name (possibly {@code null})</li> + * <li>{@code PK_NAME} - String - the primary key name (possibly {@code null})</li> + * <li>{@code DEFERRABILITY} - short - whether foreign key constraints can be + * deferred until commit (see the SQL92 specification for definitions): + * <ul> + * <li>{@code DatabaseMetaData.importedKeyInitiallyDeferred}</li> + * <li>{@code DatabaseMetaData.importedKeyInitiallyImmediate}</li> + * <li>{@code DatabaseMetaData.importedKeyNotDeferrable}</li> + * </ul> + * </li> + * </ol> + * </p> + * + * @param primaryCatalog + * a catalog name for the primary key table. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param primarySchema + * a schema name for the primary key table. {@code null} is used to imply no narrowing of + * the search by schema name. Otherwise, the name must match a + * schema name in the database, with "" used to retrieve those + * without a schema name. + * @param primaryTable + * the name of the table which exports the key. It must match the + * name of the table in the database. + * @param foreignCatalog + * a catalog name for the foreign key table. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param foreignSchema + * a schema name for the foreign key table. {@code null} is used to imply no narrowing of + * the search by schema name. Otherwise, the name must match a + * schema name in the database, with "" used to retrieve those + * without a schema name. + * @param foreignTable + * the name of the table importing the key. It must match the + * name of the table in the database. + * @return a {@code ResultSet} containing rows with the descriptions of the + * foreign keys laid out according to the format defined above. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public ResultSet getCrossReference(String primaryCatalog, + String primarySchema, String primaryTable, String foreignCatalog, + String foreignSchema, String foreignTable) throws SQLException; + + /** + * Returns the major version number of the database software. + * + * @return the major version number of the database software. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getDatabaseMajorVersion() throws SQLException; + + /** + * Returns the minor version number of the database software. + * + * @return the minor version number of the database software. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getDatabaseMinorVersion() throws SQLException; + + /** + * Returns the name of the database software. + * + * @return a {@code String} with the name of the database software. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getDatabaseProductName() throws SQLException; + + /** + * Returns the version number of this database software. + * + * @return a {@code String} with the version number of the database + * software. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getDatabaseProductVersion() throws SQLException; + + /** + * Returns the default transaction isolation level for this database. + * + * @return the default transaction isolation level. One of the following values: + * <ul> + * <li>{@code TRANSACTION_NONE}</li> + * <li>{@code TRANSACTION_READ_COMMITTED}</li> + * <li>{@code TRANSACTION_READ_UNCOMMITTED}</li> + * <li>{@code TRANSACTION_REPEATABLE_READ}</li> + * <li>{@code TRANSACTION_SERIALIZABLE}</li> + * </ul> + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getDefaultTransactionIsolation() throws SQLException; + + /** + * Returns the JDBC driver's major version number. + * + * @return the driver's major version number. + * @since Android 1.0 + */ + public int getDriverMajorVersion(); + + /** + * Returns the JDBC driver's minor version number. + * + * @return the driver's minor version number. + * @since Android 1.0 + */ + public int getDriverMinorVersion(); + + /** + * Returns the name of this JDBC driver. + * + * @return a {@code String} containing the name of the JDBC driver + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getDriverName() throws SQLException; + + /** + * Returns the version number of this JDBC driver. + * + * @return a {@code String} containing the complete version number of the + * JDBC driver. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getDriverVersion() throws SQLException; + + /** + * Returns a list of the foreign key columns that reference the primary key + * columns of a specified table (the foreign keys exported by a table). + * <p> + * The list is returned as a {@code ResultSet} with a row for each of the + * foreign key columns, ordered by {@code FKTABLE_CAT}, {@code + * FKTABLE_SCHEM}, {@code FKTABLE_NAME}, and {@code KEY_SEQ}, with the + * format for each row being: + * <ol> + * <li>{@code PKTABLE_CAT} - String - from the primary key table : the catalog (possibly + * {@code null})</li> + * <li>{@code PKTABLE_SCHEM} - String - from the primary key table : the schema (possibly + * {@code null})</li> + * <li>{@code PKTABLE_NAME} - String - from the primary key table : the name</li> + * <li>{@code PKCOLUMN_NAME} - String - from the primary key column : the name</li> + * <li>{@code FKTABLE_CAT} - String - from the foreign key table : the catalog name being + * exported (possibly {@code null})</li> + * <li>{@code FKTABLE_SCHEM} - String - from the foreign key table : the schema name + * being exported (possibly {@code null})</li> + * <li>{@code FKTABLE_NAME} - String - from the foreign key table : the name being + * exported</li> + * <li>{@code FKCOLUMN_NAME} - String - from the foreign key column : the name being + * exported</li> + * <li>{@code KEY_SEQ} - short - the sequence number (in the foreign key)</li> + * <li>{@code UPDATE_RULE} - short - a value giving the rule for how to treat the foreign key when the corresponding primary + * key is updated: + * <ul> + * <li>{@code DatabaseMetaData.importedKeyNoAction} - don't allow the + * primary key to be updated if it is imported as a foreign key</li> + * <li>{@code DatabaseMetaData.importedKeyCascade} - change the imported key to + * match the primary key update</li> + * <li>{@code DatabaseMetaData.importedKeySetNull} - set the imported key to + * {@code null}</li> + * <li>{@code DatabaseMetaData.importedKeySetDefault} - set the imported key + * to its default value</li> + * <li>{@code DatabaseMetaData.importedKeyRestrict} - same as + * importedKeyNoAction</li> + * </ul> + * </li> + * <li>{@code DELETE_RULE} - short - how to treat the foreign key when the corresponding primary + * key is deleted: + * <ul> + * <li>{@code DatabaseMetaData.importedKeyNoAction} - don't allow the + * primary key to be deleted if it is imported as a foreign key</li> + * <li>{@code DatabaseMetaData.importedKeyCascade} - the deletion should + * also delete rows that import a deleted key</li> + * <li>{@code DatabaseMetaData.importedKeySetNull} - the deletion sets the + * imported key to {@code null}</li> + * <li>{@code DatabaseMetaData.importedKeySetDefault} - the deletion sets the + * imported key to its default value</li> + * <li>{@code DatabaseMetaData.importedKeyRestrict} - same as + * importedKeyNoAction</li> + * </ul> + * </li> + * <li>{@code FK_NAME} - String - the foreign key name (possibly {@code null})</li> + * <li>{@code PK_NAME} - String - the primary key name (possibly {@code null})</li> + * <li>{@code DEFERRABILITY} - short - defines whether the foreign key + * constraints can be deferred until commit (see the SQL92 specification for + * definitions): + * <ul> + * <li>{@code DatabaseMetaData.importedKeyInitiallyDeferred}</li> + * <li>{@code DatabaseMetaData.importedKeyInitiallyImmediate}</li> + * <li>{@code DatabaseMetaData.importedKeyNotDeferrable}</li> + * </ul> + * </li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schema + * a schema name. {@code null} is used to imply no narrowing of + * the search by schema name. Otherwise, the name must match a + * schema name in the database, with "" used to retrieve those + * without a schema name. + * @param table + * a table name, which must match the name of a table in the + * database + * @return a {@code ResultSet} containing a row for each of the foreign key + * columns, as defined above + * @throws SQLException + * a database error occurred + * @since Android 1.0 + */ + public ResultSet getExportedKeys(String catalog, String schema, String table) + throws SQLException; + + /** + * Returns a string of characters that may be used in unquoted identifier + * names. The characters {@code a-z}, {@code A-Z}, {@code 0-9} and {@code _} + * are always permitted. + * + * @return a String containing all the additional permitted characters. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getExtraNameCharacters() throws SQLException; + + /** + * Returns the string used to quote SQL identifiers. Returns " " (space) if + * identifier quoting not supported. + * + * @return the String used to quote SQL identifiers. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getIdentifierQuoteString() throws SQLException; + + /** + * Returns a list columns in a table that are both primary keys and + * referenced by the table's foreign key columns (that is, the primary keys + * imported by a table). + * <p> + * The list returned is a {@code ResultSet} with a row entry for each + * primary key column, ordered by {@code PKTABLE_CAT}, {@code PKTABLE_SCHEM}, + * {@code PKTABLE_NAME}, and {@code KEY_SEQ}, with the following format: + * <ol> + * <li>{@code PKTABLE_CAT} - String - primary key catalog name being + * imported (possibly {@code null})</li> + * <li>{@code PKTABLE_SCHEM} - String - primary key schema name being + * imported (possibly {@code null})</li> + * <li>{@code PKTABLE_NAME} - String - primary key table name being imported + * </li> + * <li>{@code PKCOLUMN_NAME} - String - primary key column name being + * imported</li> + * <li>{@code FKTABLE_CAT} - String - foreign key table catalog name + * (possibly {@code null})</li> + * <li>{@code FKTABLE_SCHEM} - String - foreign key table schema name + * (possibly {@code null})</li> + * <li>{@code FKTABLE_NAME} - String - foreign key table name</li> + * <li>{@code FKCOLUMN_NAME} - String - foreign key column name</li> + * <li>{@code KEY_SEQ} - short - sequence number (in the foreign key)</li> + * <li>{@code UPDATE_RULE} - short - how to treat the foreign key when the corresponding primary + * key is updated: + * <ul> + * <li>{@code DatabaseMetaData.importedKeyNoAction} - don't allow any update of + * the primary key if it is imported as a foreign key</li> + * <li>{@code DatabaseMetaData.importedKeyCascade} - change imported key to + * match the primary key update</li> + * <li>{@code DatabaseMetaData.importedKeySetNull} - set the imported key to + * {@code null}</li> + * <li>{@code DatabaseMetaData.importedKeySetDefault} - set the imported key + * to its default value</li> + * <li>{@code DatabaseMetaData.importedKeyRestrict} - same as + * importedKeyNoAction</li> + * </ul> + * </li> + * <li>{@code DELETE_RULE} - short - how to treat the foreign key when the corresponding primary + * key is deleted: + * <ul> + * <li>{@code DatabaseMetaData.importedKeyNoAction} - don't allow the primary key to be deleted + * if it is imported as a foreign key</li> + * <li>{@code DatabaseMetaData.importedKeyCascade} - delete those rows that + * import a deleted key</li> + * <li>{@code DatabaseMetaData.importedKeySetNull} - set the imported key to + * {@code null}</li> + * <li>{@code DatabaseMetaData.importedKeySetDefault} - set the imported key + * to its default value</li> + * <li>{@code DatabaseMetaData.importedKeyRestrict} - same as {@code + * importedKeyNoAction}</li> + * </ul> + * </li> + * <li>{@code FK_NAME} - String - foreign key name (possibly {@code null})</li> + * <li>{@code PK_NAME} - String - primary key name (possibly {@code null})</li> + * <li>{@code DEFERRABILITY} - short - defines whether foreign key + * constraints can be deferred until commit (see SQL92 specification for + * definitions): + * <ul> + * <li>{@code DatabaseMetaData.importedKeyInitiallyDeferred}</li> + * <li>{@code DatabaseMetaData.importedKeyInitiallyImmediate}</li> + * <li>{@code DatabaseMetaData.importedKeyNotDeferrable}</li> + * </ul> + * </li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schema + * a schema name. {@code null} is used to imply no narrowing of + * the search by schema name. Otherwise, the name must match a + * schema name in the database, with "" used to retrieve those + * without a schema name. + * @param table + * a table name, which must match the name of a table in the + * database. + * @return a {@code ResultSet} containing the list of primary key columns as + * rows in the format defined above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getImportedKeys(String catalog, String schema, String table) + throws SQLException; + + /** + * Returns a list of indices and statistics for a specified table. + * <p> + * The list is returned as a {@code ResultSet}, with one row for each index + * or statistic. The list is ordered by {@code NON_UNIQUE}, {@code TYPE}, + * {@code INDEX_NAME}, and {@code ORDINAL_POSITION}. Each row has the + * following format: + * <ol> + * <li>{@code TABLE_CAT} - String - table catalog name (possibly {@code + * null})</li> + * <li>{@code TABLE_SCHEM} - String - table schema name (possibly {@code + * null})</li> + * <li>{@code TABLE_NAME} - String - The table name</li> + * <li>{@code NON_UNIQUE} - boolean - {@code true} when index values can be + * non-unique. Must be {@code false} when the TYPE is tableIndexStatistic</li> + * <li>{@code INDEX_QUALIFIER} - String : index catalog name. {@code null} + * when the TYPE is 'tableIndexStatistic'</li> + * <li>{@code INDEX_NAME} - String : index name. {@code null} when TYPE is + * 'tableIndexStatistic'</li> + * <li>{@code TYPE} - short - the index type. One of: + * <ul> + * <li>{@code DatabaseMetaData.tableIndexStatistic} - table statistics + * returned with Index descriptions</li> + * <li>{@code DatabaseMetaData.tableIndexClustered} - a clustered Index</li> + * <li>{@code DatabaseMetaData.tableIndexHashed} - a hashed Index</li> + * <li>{@code DatabaseMetaData.tableIndexOther} - other style of Index</li> + * </ul> + * </li> + * <li>{@code ORDINAL_POSITION} - short - column sequence within Index. 0 + * when TYPE is tableIndexStatistic</li> + * <li>{@code COLUMN_NAME} - String - the column name. {@code null} when + * TYPE is tableIndexStatistic</li> + * <li>{@code ASC_OR_DESC} - String - column sort sequence. {@code null} if + * sequencing not supported or TYPE is tableIndexStatistic; otherwise "A" + * means sort ascending and "D" means sort descending.</li> + * <li>{@code CARDINALITY} - int - Number of unique values in the Index. If + * TYPE is tableIndexStatistic, this is number of rows in the table.</li> + * <li>{@code PAGES} - int - Number of pages for current Index. If TYPE is + * tableIndexStatistic, this is number of pages used for the table.</li> + * <li>{@code FILTER_CONDITION} - String - Filter condition. (possibly null) + * </li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schema + * a schema name. {@code null} is used to imply no narrowing of + * the search by schema name. Otherwise, the name must match a + * schema name in the database, with "" used to retrieve those + * without a schema name. + * @param table + * a table name, which must match the name of a table in the + * database. + * @param unique + * {@code true} means only return indices for unique values, + * {@code false} implies that they can be returned even if not + * unique. + * @param approximate + * {@code true} implies that the list can contain approximate or + * "out of data" values, {@code false} implies that all values + * must be precisely accurate + * @return a {@code ResultSet} containing the list of indices and statistics + * for the table, in the format defined above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getIndexInfo(String catalog, String schema, String table, + boolean unique, boolean approximate) throws SQLException; + + /** + * Returns this driver's major JDBC version number. + * + * @return the major JDBC version number. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getJDBCMajorVersion() throws SQLException; + + /** + * Returns the minor JDBC version number for this driver. + * + * @return the Minor JDBC Version Number. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getJDBCMinorVersion() throws SQLException; + + /** + * Get the maximum number of hex characters in an in-line binary literal for + * this database. + * + * @return the maximum number of hex characters in an in-line binary + * literal. If the number is unlimited then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxBinaryLiteralLength() throws SQLException; + + /** + * Returns the maximum size of a catalog name in this database. + * + * @return the maximum size in characters for a catalog name. If the limit + * is unknown, or the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxCatalogNameLength() throws SQLException; + + /** + * Returns the maximum size for a character literal in this database. + * + * @return the maximum size in characters for a character literal. If the + * limit is unknown, or the value is unlimited, then the result is + * zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxCharLiteralLength() throws SQLException; + + /** + * Returns the maximum size for a Column name for this database. + * + * @return the maximum number of characters for a Column name. If the limit + * is unknown, or the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxColumnNameLength() throws SQLException; + + /** + * Get the maximum number of columns in a {@code GROUP BY} clause for this + * database. + * + * @return the maximum number of columns in a {@code GROUP BY} clause. If + * the limit is unknown, or the value is unlimited, then the result + * is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxColumnsInGroupBy() throws SQLException; + + /** + * Returns the maximum number of columns in an Index for this database. + * + * @return the maximum number of columns in an Index. If the limit is + * unknown, or the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxColumnsInIndex() throws SQLException; + + /** + * Returns the maximum number of columns in an {@code ORDER BY} clause for + * this database. + * + * @return the maximum number of columns in an {@code ORDER BY} clause. If + * the limit is unknown, or the value is unlimited, then the result + * is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxColumnsInOrderBy() throws SQLException; + + /** + * Returns the maximum number of columns in a {@code SELECT} list for this + * database. + * + * @return the maximum number of columns in a {@code SELECT} list. If the + * limit is unknown, or the value is unlimited, then the result is + * zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxColumnsInSelect() throws SQLException; + + /** + * Returns the maximum number of columns in a table for this database. + * + * @return the maximum number of columns in a table. If the limit is + * unknown, or the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxColumnsInTable() throws SQLException; + + /** + * Returns the database's maximum number of concurrent connections. + * + * @return the maximum number of connections. If the limit is unknown, or + * the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxConnections() throws SQLException; + + /** + * Returns the maximum length of a cursor name for this database. + * + * @return the maximum number of characters in a cursor name. If the limit + * is unknown, or the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxCursorNameLength() throws SQLException; + + /** + * Returns the maximum length in bytes for an Index for this database. This + * covers all the parts of a composite index. + * + * @return the maximum length in bytes for an Index. If the limit is + * unknown, or the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxIndexLength() throws SQLException; + + /** + * Returns the maximum number of characters for a procedure name in this + * database. + * + * @return the maximum number of character for a procedure name. If the + * limit is unknown, or the value is unlimited, then the result is + * zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxProcedureNameLength() throws SQLException; + + /** + * Returns the maximum number of bytes within a single row for this + * database. + * + * @return the maximum number of bytes for a single row. If the limit is + * unknown, or the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxRowSize() throws SQLException; + + /** + * Returns the maximum number of characters in a schema name for this + * database. + * + * @return the maximum number of characters in a schema name. If the limit + * is unknown, or the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxSchemaNameLength() throws SQLException; + + /** + * Returns the maximum number of characters in an SQL statement for this + * database. + * + * @return the maximum number of characters in an SQL statement. If the + * limit is unknown, or the value is unlimited, then the result is + * zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxStatementLength() throws SQLException; + + /** + * Get the maximum number of simultaneously open active statements for this + * database. + * + * @return the maximum number of open active statements. If the limit is + * unknown, or the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxStatements() throws SQLException; + + /** + * Returns the maximum size for a table name in the database. + * + * @return the maximum size in characters for a table name. If the limit is + * unknown, or the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxTableNameLength() throws SQLException; + + /** + * Returns the maximum number of tables permitted in a {@code SELECT} + * statement for the database. + * + * @return the maximum number of tables permitted in a {@code SELECT} + * statement. If the limit is unknown, or the value is unlimited, + * then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxTablesInSelect() throws SQLException; + + /** + * Returns the maximum number of characters in a user name for the database. + * + * @return the maximum number of characters in a user name. If the limit is + * unknown, or the value is unlimited, then the result is zero. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getMaxUserNameLength() throws SQLException; + + /** + * Returns a list of the math functions available with this database. These + * are used in the JDBC function escape clause and are the Open Group CLI + * math function names. + * + * @return a String which contains the list of math functions as a comma + * separated list. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getNumericFunctions() throws SQLException; + + /** + * Returns a list of the primary key columns of a specified table. + * <p> + * The list is returned as a {@code ResultSet} with one row for each primary + * key column, ordered by {@code COLUMN_NAME}, with each row having the + * structure as follows: + * <ol> + * <li>{@code TABLE_CAT} - String - table catalog name (possibly null)</li> + * <li>{@code TABLE_SCHEM} - String - table schema name (possibly null)</li> + * <li>{@code TABLE_NAME} - String - The table name</li> + * <li>{@code COLUMN_NAME} - String - The column name</li> + * <li>{@code KEY_SEQ} - short - the sequence number for this column in the + * primary key</li> + * <li>{@code PK_NAME} - String - the primary key name (possibly null)</li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with the empty string used + * to retrieve those without a catalog name. + * @param schema + * a schema name. {@code null} is used to imply no narrowing of + * the search by schema name. Otherwise, the name must match a + * schema name in the database, with the empty string used to + * retrieve those without a schema name. + * @param table + * the name of a table, which must match the name of a table in + * the database. + * @return a {@code ResultSet} containing the list of keys in the format + * defined above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getPrimaryKeys(String catalog, String schema, String table) + throws SQLException; + + /** + * Returns a list of parameter and result columns for the stored procedures + * belonging to a specified catalog. + * <p> + * The list is returned as a {@code ResultSet} with one row for each + * parameter or result column. The data is ordered by {@code + * PROCEDURE_SCHEM} and {@code PROCEDURE_NAME}, while for each procedure, + * the return value (if any) is first, followed by the parameters in the + * order they appear in the stored procedure call, followed by {@code + * ResultSet} columns in column number order. Each row has the following + * structure: + * <ol> + * <li>{@code PROCEDURE_CAT} - String - the procedure catalog name</li> + * <li>{@code PROCEDURE_SCHEM} - String - the procedure schema name + * (possibly null)</li> + * <li>{@code PROCEDURE_NAME} - String - the procedure name</li> + * <li>{@code COLUMN_NAME} - String - the name of the column</li> + * <li>{@code COLUMN_TYPE} - short - the kind of column or parameter, as + * follows: + * <ul> + * <li>{@code DatabaseMetaData.procedureColumnUnknown} - type unknown</li> + * <li>{@code DatabaseMetaData.procedureColumnIn} - an {@code IN} parameter</li> + * <li>{@code DatabaseMetaData.procedureColumnInOut} - an {@code INOUT} + * parameter</li> + * <li>{@code DatabaseMetaData.procedureColumnOut} - an {@code OUT} + * parameter</li> + * <li>{@code DatabaseMetaData.procedureColumnReturn} - a return value</li> + * <li>{@code DatabaseMetaData.procedureReturnsResult} - a result column in + * a result set</li> + * </ul> + * </li> + * <li>{@code DATA_TYPE} - int - the SQL type of the data, as in {@code + * java.sql.Types}</li> + * <li>{@code TYPE_NAME} - String - the SQL type name, for a UDT it is fully + * qualified</li> + * <li>{@code PRECISION} - int - the precision</li> + * <li>{@code LENGTH} - int - the length of the data in bytes</li> + * <li>{@code SCALE} - short - the scale for numeric types</li> + * <li>{@code RADIX} - short - the Radix for numeric data (typically 2 or + * 10)</li> + * <li>{@code NULLABLE} - short - can the data contain {@code null}: + * <ul> + * <li>{@code DatabaseMetaData.procedureNoNulls} - {@code NULL}s not + * permitted</li> + * <li>{@code DatabaseMetaData.procedureNullable} - {@code NULL}s are + * permitted</li> + * <li>{@code DatabaseMetaData.procedureNullableUnknown} - {@code NULL} + * status unknown</li> + * </ul> + * </li> + * <li>{@code REMARKS} - String - an explanatory comment about the data item + * </li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schemaPattern + * a schema name pattern. {@code null} is used to imply no + * narrowing of the search by schema name. Otherwise, the name + * must match a schema name in the database, with "" used to + * retrieve those without a schema name. + * @param procedureNamePattern + * a pattern that must match the name of the procedure stored in + * the database. + * @param columnNamePattern + * a column name pattern. The name must match the column name + * stored in the database. + * @return a {@code ResultSet} with the list of parameter and result columns + * in the format defined above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getProcedureColumns(String catalog, String schemaPattern, + String procedureNamePattern, String columnNamePattern) + throws SQLException; + + /** + * Returns a list of the stored procedures available in a specified catalog. + * <p> + * The list is returned as a {@code ResultSet} with one row for each stored + * procedure, ordered by PROCEDURE_SCHEM and PROCEDURE_NAME, with the data + * in each row as follows: + * <ol> + * <li>{@code PROCEDURE_CAT} - String : the procedure catalog name</li> + * <li>{@code PROCEDURE_SCHEM} - String : the procedure schema name + * (possibly {@code null})</li> + * <li>{@code PROCEDURE_NAME} - String : the procedure name</li> + * <li>{@code Reserved}</li> + * <li>{@code Reserved}</li> + * <li>{@code Reserved}</li> + * <li>{@code REMARKS} - String - information about the procedure</li> + * <li>{@code PROCEDURE_TYPE} - short : one of: + * <ul> + * <li>{@code DatabaseMetaData.procedureResultUnknown} - procedure may + * return a result</li> + * <li>{@code DatabaseMetaData.procedureNoResult} - procedure does not + * return a result</li> + * <li>{@code DatabaseMetaData.procedureReturnsResult} - procedure + * definitely returns a result</li> + * </ul> + * </li> + * </ol> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schemaPattern + * a schema name pattern. {@code null} is used to imply no + * narrowing of the search by schema name. Otherwise, the name + * must match a schema name in the database, with "" used to + * retrieve those without a schema name. + * @param procedureNamePattern + * a procedure name pattern, which must match the procedure name + * stored in the database. + * @return a {@code ResultSet} where each row is a description of a stored + * procedure in the format defined above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getProcedures(String catalog, String schemaPattern, + String procedureNamePattern) throws SQLException; + + /** + * Returns the database vendor's preferred name for "procedure". + * + * @return a String with the vendor's preferred name for "procedure". + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getProcedureTerm() throws SQLException; + + /** + * Returns the result set's default holdability. + * + * @return one of {@code ResultSet.HOLD_CURSORS_OVER_COMMIT} or {@code + * ResultSet.CLOSE_CURSORS_AT_COMMIT}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getResultSetHoldability() throws SQLException; + + /** + * Returns a list of the schema names in the database. The list is returned + * as a {@code ResultSet}, ordered by the schema name, with one row per + * schema in the following format: + * <ol> + * <li>{@code TABLE_SCHEM} - String - the schema name</li> <li>{@code + * TABLE_CATALOG} - String - the catalog name (possibly {@code null}) </li> + * </ol> + * + * @return a {@code ResultSet} with one row for each schema in the format + * defined above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getSchemas() throws SQLException; + + /** + * Returns the database vendor's preferred term for "schema". + * + * @return a String which is the vendor's preferred term for schema. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getSchemaTerm() throws SQLException; + + /** + * Returns the string that is used to escape wildcard characters. This + * string is used to escape the {@code '_'} and {@code '%'} wildcard + * characters in catalog search pattern strings. {@code '_'} is used to represent any single + * character while {@code '%'} is used for a sequence of zero or more + * characters. + * + * @return a String used to escape the wildcard characters. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getSearchStringEscape() throws SQLException; + + /** + * Returns a list of all the SQL keywords that are NOT also SQL92 keywords + * for the database. + * + * @return a String containing the list of SQL keywords in a comma separated + * format. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getSQLKeywords() throws SQLException; + + /** + * States the type of {@code SQLState} value returned by {@code + * SQLException.getSQLState}. This can either be the X/Open (now known as + * Open Group) SQL CLI form or the SQL99 form. + * + * @return an integer, which is either {@code + * DatabaseMetaData.sqlStateSQL99} or {@code + * DatabaseMetaData.sqlStateXOpen}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public int getSQLStateType() throws SQLException; + + /** + * Returns a list of string functions available with the database. These + * functions are used in JDBC function escape clause and follow the Open + * Group CLI string function names definition. + * + * @return a String containing the list of string functions in comma + * separated format. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getStringFunctions() throws SQLException; + + /** + * Returns a listing of the hierarchies of tables in a specified schema in + * the database. + * <p> + * The listing only contains entries for tables that have a super table. + * Super tables and corresponding subtables must be defined in the same catalog and schema. The + * list is returned as a {@code ResultSet}, with one row for each table that + * has a super table, in the following format: + * <ol> + * <li>{@code TABLE_CAT} - String - table catalog name (possibly {@code + * null})</li> + * <li>{@code TABLE_SCHEM} - String - Table schema name (possibly {@code + * null})</li> + * <li>{@code TABLE_NAME} - String - The table name</li> + * <li>SUPER{@code TABLE_NAME} - String - The super table name</li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schemaPattern + * a schema name pattern. {@code null} is used to imply no + * narrowing of the search by schema name. Otherwise, the name + * must match a schema name in the database, with "" used to + * retrieve those without a schema name. + * @param tableNamePattern + * a table name, which should match the table name as stored in + * the database. it may be a fully qualified name. If it is fully + * qualified the catalog name and schema name parameters are + * ignored. + * @return a {@code ResultSet} with one row for each table which has a super + * table, in the format defined above. An empty {@code ResultSet} is + * returned if the database does not support table hierarchies. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getSuperTables(String catalog, String schemaPattern, + String tableNamePattern) throws SQLException; + + /** + * Returns the User Defined Type (UDT) hierarchies for a given schema. Only + * the immediate parent/child relationship is described. If a UDT does not + * have a direct supertype, it is not listed. + * <p> + * The listing is returned as a {@code ResultSet} where there is one row for + * a specific UDT which describes its supertype, with the data organized in + * columns as follows: + * <ol> + * <li>{@code TYPE_CAT} - String - the UDT catalog name (possibly {@code + * null})</li> + * <li>{@code TYPE_SCHEM} - String - the UDT schema name (possibly {@code + * null})</li> + * <li>{@code TYPE_NAME} - String - the UDT type name</li> + * <li>SUPER{@code TYPE_CAT} - String - direct supertype's catalog name + * (possibly {@code null})</li> + * <li>SUPER{@code TYPE_SCHEM} - String - direct supertype's schema name + * (possibly {@code null})</li> + * <li>SUPER{@code TYPE_NAME} - String - direct supertype's name</li> + * </ol> + * </p> + * + * @param catalog + * the catalog name. "" means get the UDTs without a catalog. + * {@code null} means don't use the catalog name to restrict the + * search. + * @param schemaPattern + * the Schema pattern name. "" means get the UDT's without a + * schema. + * @param typeNamePattern + * the UDT name pattern. This may be a fully qualified name. When + * a fully qualified name is specified, the catalog name and + * schema name parameters are ignored. + * @return a {@code ResultSet} in which each row gives information about a + * particular UDT in the format defined above. An empty ResultSet is + * returned for a database that does not support type hierarchies. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getSuperTypes(String catalog, String schemaPattern, + String typeNamePattern) throws SQLException; + + /** + * Returns a list of system functions available with the database. These are + * names used in the JDBC function escape clause and are Open Group CLI + * function names. + * + * @return a String containing the list of system functions in a comma + * separated format. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getSystemFunctions() throws SQLException; + + /** + * Returns a description of access rights for each table present in a + * catalog. Table privileges can apply to one or more columns in the table - + * but are not guaranteed to apply to all columns. + * <p> + * The privileges are returned as a {@code ResultSet}, with one row for each + * privilege, ordered by {@code TABLE_SCHEM}, {@code TABLE_NAME}, {@code + * PRIVILEGE}, and each row has data as defined in the following column + * definitions: + * <ol> + * <li>{@code TABLE_CAT} - String - table catalog name (possibly {@code + * null})</li> + * <li>{@code TABLE_SCHEM} - String - Table schema name (possibly {@code + * null})</li> + * <li>{@code TABLE_NAME} - String - The table name</li> + * <li>GRANTOR - String - who granted the access</li> + * <li>GRANTEE - String - who received the access grant</li> + * <li>PRIVILEGE - String - the type of access granted - one of SELECT, + * INSERT, UPDATE, REFERENCES,...</li> + * <li>IS_GRANTABLE - String - {@code "YES"} implies the grantee can grant + * access to others, {@code "NO"} implies guarantee cannot grant access to + * others, {@code null} means this status is unknown</li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schemaPattern + * a schema name pattern. {@code null} is used to imply no + * narrowing of the search by schema name. Otherwise, the name + * must match a schema name in the database, with "" used to + * retrieve those without a schema name. + * @param tableNamePattern + * a Table Name, which should match the table name as stored in + * the database. + * @return a {@code ResultSet} containing a list with one row for each table + * in the format defined above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getTablePrivileges(String catalog, String schemaPattern, + String tableNamePattern) throws SQLException; + + /** + * Returns a description of the tables in a specified catalog. + * <p> + * The descriptions are returned as rows in a {@code ResultSet}, one row for + * each Table. The ResultSet is ordered by {@code TABLE_TYPE}, {@code + * TABLE_SCHEM} and {@code TABLE_NAME}. Each row in the ResultSet consists + * of a series of columns as follows: + * <ol> + * <li>{@code TABLE_CAT} - String - table catalog name (possibly {@code + * null})</li> + * <li>{@code TABLE_SCHEM} - String - Table schema name (possibly {@code + * null})</li> + * <li>{@code TABLE_NAME} - String - The table name</li> + * <li>{@code TABLE_TYPE} - String - Typical names include "TABLE", "VIEW", + * "SYSTEM TABLE", "ALIAS", "SYNONYM", "GLOBAL TEMPORARY"</li> + * <li>{@code REMARKS} - String - A comment describing the table</li> + * <li>{@code TYPE_CAT} - String - the 'Types' catalog(possibly {@code null} + * )</li> + * <li>{@code TYPE_SCHEM} - String - the 'Types' schema(possibly {@code + * null})</li> + * <li>{@code TYPE_NAME} - String - the 'Types' name (possibly {@code null}) + * </li> + * <li>{@code SELF_REFERENCING_COL_NAME} - String - the name of a designated + * identifier column in a typed table (possibly {@code null})</li> + * <li>REF_GENERATION - String - one of the following values : "SYSTEM" | + * "USER" | "DERIVED" - specifies how values in the {@code + * SELF_REFERENCING_COL_NAME} are created (possibly {@code null})</li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schemaPattern + * a schema name pattern. {@code null} is used to imply no + * narrowing of the search by schema name. Otherwise, the name + * must match a schema name in the database, with "" used to + * retrieve those without a schema name. + * @param tableNamePattern + * a table name, which should match the table name as stored in + * the database. + * @param types + * a list of table types to include in the list. {@code null} + * implies list all types. + * @return a {@code ResultSet} with one row per table in the format defined + * above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getTables(String catalog, String schemaPattern, + String tableNamePattern, String[] types) throws SQLException; + + /** + * Returns a list of table types supported by the database. + * <p> + * The list is returned as a {@code ResultSet} with one row per table type, + * ordered by the table type. The information in the {@code ResultSet} is + * structured into a single column per row, as follows: + * <ol> + * <li>{@code TABLE_TYPE} - String - the table type. Typical names include + * {@code "TABLE"}, {@code "VIEW"}, "{@code SYSTEM TABLE"}, {@code "ALIAS"}, + * {@code "SYNONYM"}, {@code "GLOBAL TEMPORARY"}</li> + * </ol> + * </p> + * + * @return a {@code ResultSet} with one row per table type in the format + * defined above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getTableTypes() throws SQLException; + + /** + * Returns a list of time and date functions available for the database. + * + * @return a string containing a comma separated list of the time and date + * functions. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getTimeDateFunctions() throws SQLException; + + /** + * Get a list of the standard SQL types supported by this database. The list + * is returned as a {@code ResultSet}, with one row for each type, ordered + * by the {@code DATA_TYPE} value, where the data in each row is structured + * into the following columns: + * <ol> + * <li>{@code TYPE_NAME} - String : the type name</li> + * <li>{@code DATA_TYPE} - int : the SQL data type value as defined in + * {@code java.sql.Types}</li> + * <li>{@code PRECISION} - int - the maximum precision of the type</li> + * <li>{@code LITERAL_PREFIX} - String : the prefix to be used when quoting + * a literal value (possibly {@code null})</li> + * <li>{@code LITERAL_SUFFIX} - String : the suffix to be used when quoting + * a literal value (possibly {@code null})</li> + * <li>{@code CREATE_PARAMS} - String : params used when creating the type + * (possibly {@code null})</li> + * <li>{@code NULLABLE} - short : shows if the value is nullable: + * <ul> + * <li>{@code DatabaseMetaData.typeNoNulls} : {@code NULL}s not permitted</li> + * <li>{@code DatabaseMetaData.typeNullable} : {@code NULL}s are permitted</li> + * <li>{@code DatabaseMetaData.typeNullableUnknown} : {@code NULL} status + * unknown</li> + * </ul> + * </li> + * <li>{@code CASE_SENSITIVE} - boolean : true if the type is case sensitive + * </li> + * <li>{@code SEARCHABLE} - short : how this type can be used with {@code WHERE} + * clauses: + * <ul> + * <li>{@code DatabaseMetaData.typePredNone} - {@code WHERE} clauses cannot be used</li> + * <li>{@code DatabaseMetaData.typePredChar} - support for {@code + * WHERE...LIKE} only</li> + * <li>{@code DatabaseMetaData.typePredBasic} - support except for {@code + * WHERE...LIKE}</li> + * <li>{@code DatabaseMetaData.typeSearchable} - support for all {@code + * WHERE} clauses</li> + * </ul> + * </li> + * <li>{@code UNSIGNED_ATTRIBUTE} - boolean - the type is unsigned or not</li> + * <li>{@code FIXED_PREC_SCALE} - boolean - fixed precision = it can be used + * as a money value</li> + * <li>{@code AUTO_INCREMENT} - boolean - can be used as an auto-increment + * value</li> + * <li>{@code LOCAL_TYPE_NAME} - String - a localized version of the type + * name (possibly {@code null})</li> + * <li>{@code MINIMUM_SCALE} - short - the minimum scale supported</li> + * <li>{@code MAXIMUM_SCALE} - short - the maximum scale supported</li> + * <li>{@code SQL_DATA_TYPE} - int - not used</li> + * <li>{@code SQL_DATETIME_SUB} - int - not used</li> + * <li>{@code NUM_PREC_RADIX} - int - number radix (typically 2 or 10)</li> + * </ol> + * + * @return a {@code ResultSet} which is structured as described above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getTypeInfo() throws SQLException; + + /** + * Returns a description of the User Defined Types (UDTs) defined in a given + * schema, which includes the types {@code DISTINCT}, {@code STRUCT} and + * {@code JAVA_OBJECT}. + * <p> + * The types matching the supplied the specified catalog, schema, type name + * and type are returned as rows in a {@code ResultSet} with columns of + * information as follows: + * <ol> + * <li>{@code TABLE_CAT} - String - catalog name (possibly {@code null})</li> + * <li>{@code TABLE_SCHEM} - String - schema name (possibly {@code null})</li> + * <li>{@code TABLE_NAME} - String - The table name</li> + * <li>{@code CLASS_NAME} - String - The Java class name</li> + * <li>{@code DATA_TYPE} - int - The SQL type as specified in {@code + * java.sql.Types}. One of DISTINCT, STRUCT, and JAVA_OBJECT</li> + * <li>{@code REMARKS} - String - A comment which describes the type</li> + * <li>{@code BASE_TYPE} - short - A type code. For a DISTINCT type, the + * source type. For a structured type this is the type that implements the + * user generated reference type of the {@code SELF_REFERENCING_COLUMN}. + * This is defined in {@code java.sql.Types}, and will be {@code null} if + * the {@code DATA_TYPE} does not match these criteria.</li> + * </ol> + * </p> + * <p> + * If the driver does not support UDTs, the {@code ResultSet} is empty. + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search by catalog name. Otherwise, the name must match a + * catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schemaPattern + * a schema name pattern. {@code null} is used to imply no + * narrowing of the search using schema name. Otherwise, the name + * must match a schema name in the database, with "" used to + * retrieve those without a schema name. + * @param typeNamePattern + * a type name pattern, which should match a type name as stored in the + * database. It may be fully qualified. + * @param types + * a list of the UDT types to include in the list - one of + * {@code DISTINCT}, {@code STRUCT} or {@code JAVA_OBJECT}. + * @return a {@code ResultSet} in the format described above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getUDTs(String catalog, String schemaPattern, + String typeNamePattern, int[] types) throws SQLException; + + /** + * Returns the URL for this database. + * + * @return the URL for the database. {@code null} if it cannot be generated. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getURL() throws SQLException; + + /** + * Determine the user name as known by the database. + * + * @return the user name. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public String getUserName() throws SQLException; + + /** + * Returns which of a table's columns are automatically updated when any + * value in a row is updated. + * <p> + * The result is laid-out in the following columns: + * <ol> + * <li>{@code SCOPE} - short - not used</li> + * <li>{@code COLUMN_NAME} - String - Column name</li> + * <li>{@code DATA_TYPE} - int - The SQL data type, as defined in {@code + * java.sql.Types}</li> + * <li>{@code TYPE_NAME} - String - The SQL type name, data source dependent + * </li> + * <li>{@code COLUMN_SIZE} - int - Precision for numeric types</li> + * <li>{@code BUFFER_LENGTH} - int - Length of a column value in bytes</li> + * <li>{@code DECIMAL_DIGITS} - short - Number of digits after the decimal + * point</li> + * <li>{@code PSEUDO_COLUMN} - short - If this is a pseudo-column (for + * example, an Oracle {@code ROWID}): + * <ul> + * <li>{@code DatabaseMetaData.bestRowUnknown} - don't know whether this is + * a pseudo column</li> + * <li>{@code DatabaseMetaData.bestRowNotPseudo} - column is not pseudo</li> + * <li>{@code DatabaseMetaData.bestRowPseudo} - column is a pseudo column</li> + * </ul> + * </li> + * </ol> + * </p> + * + * @param catalog + * a catalog name. {@code null} is used to imply no narrowing of + * the search using catalog name. Otherwise, the name must match + * a catalog name held in the database, with "" used to retrieve + * those without a catalog name. + * @param schema + * a schema name pattern. {@code null} is used to imply no + * narrowing of the search using schema names. Otherwise, the + * name must match a schema name in the database, with "" used to + * retrieve those without a schema name. + * @param table + * a table name. It must match the name of a table in the + * database. + * @return a {@code ResultSet} containing the descriptions, one row for each + * column, in the format defined above. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public ResultSet getVersionColumns(String catalog, String schema, + String table) throws SQLException; + + /** + * Determines whether a visible row insert can be detected by calling {@code + * ResultSet.rowInserted}. + * + * @param type + * the {@code ResultSet} type. This may be one of {@code + * ResultSet.TYPE_SCROLL_SENSITIVE} or {@code + * ResultSet.TYPE_SCROLL_INSENSITIVE} or {@code + * ResultSet.TYPE_FORWARD_ONLY}, + * @return {@code true} if {@code ResultSet.rowInserted} detects a visible + * row insert otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @see ResultSet#rowInserted() + * @since Android 1.0 + */ + public boolean insertsAreDetected(int type) throws SQLException; + + /** + * Determine whether a fully qualified table name is prefixed or suffixed to + * a fully qualified table name. + * + * @return {@code true} if the catalog appears at the start of a fully + * qualified table name, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean isCatalogAtStart() throws SQLException; + + /** + * Determines whether the database is in read-only mode. + * + * @return {@code true} if the database is in read-only mode, {@code false} + * otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean isReadOnly() throws SQLException; + + /** + * Determines whether updates are made to a copy of, or directly on, Large Objects + * ({@code LOB}s). + * + * @return {@code true} if updates are made to a copy of the Large Object, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean locatorsUpdateCopy() throws SQLException; + + /** + * Determines whether the database handles concatenations between {@code NULL} and + * non-{@code NULL} values by producing a {@code NULL} output. + * + * @return {@code true} if {@code NULL} to non-{@code NULL} concatenations + * produce a {@code NULL} result, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean nullPlusNonNullIsNull() throws SQLException; + + /** + * Determines whether {@code NULL} values are always sorted to the end of sorted + * results regardless of requested sort order. This means that they will + * appear at the end of sorted lists whatever other non-{@code NULL} values + * may be present. + * + * @return {@code true} if {@code NULL} values are sorted at the end, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean nullsAreSortedAtEnd() throws SQLException; + + /** + * Determines whether {@code NULL} values are always sorted at the start of the + * sorted list, irrespective of the sort order. This means that they appear + * at the start of sorted lists, whatever other values may be present. + * + * @return {@code true} if {@code NULL} values are sorted at the start, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean nullsAreSortedAtStart() throws SQLException; + + /** + * Determines whether {@code NULL} values are sorted high - i.e. they are sorted + * as if they are higher than any other values. + * + * @return {@code true} if {@code NULL} values are sorted high, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean nullsAreSortedHigh() throws SQLException; + + /** + * Determines whether {@code NULL} values are sorted low - i.e. they are sorted as + * if they are lower than any other values. + * + * @return {@code true} if {@code NULL} values are sorted low, {@code false} + * otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean nullsAreSortedLow() throws SQLException; + + /** + * Determines whether deletes made by others are visible, for a specified {@code + * ResultSet} type. + * + * @param type + * the type of the {@code ResultSet}. It may be either {@code + * ResultSet.TYPE_FORWARD_ONLY} or {@code + * ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code + * ResultSet.TYPE_SCROLL_SENSITIVE}) + * @return {@code true} if others' deletes are visible, {@code false} + * otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean othersDeletesAreVisible(int type) throws SQLException; + + /** + * Determines whether inserts made by others are visible, for a specified {@code + * ResultSet} type. + * + * @param type + * the type of the {@code ResultSet}. May be {@code + * ResultSet.TYPE_FORWARD_ONLY}, or {@code + * ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code + * ResultSet.TYPE_SCROLL_SENSITIVE} + * @return {@code true} if others' inserts are visible, otherwise {@code + * false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean othersInsertsAreVisible(int type) throws SQLException; + + /** + * Determines whether updates made by others are visible, for a specified {@code + * ResultSet} type. + * + * @param type + * the type of the {@code ResultSet}. May be {@code + * ResultSet.TYPE_FORWARD_ONLY}, or {@code + * ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code + * ResultSet.TYPE_SCROLL_SENSITIVE} + * @return {@code true} if others' inserts are visible, otherwise {@code + * false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean othersUpdatesAreVisible(int type) throws SQLException; + + /** + * Determines whether a {@code ResultSet} can see its own deletes, for a + * specified {@code ResultSet} type. + * + * @param type + * the type of the {@code ResultSet}: {@code + * ResultSet.TYPE_FORWARD_ONLY}, {@code + * ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code + * ResultSet.TYPE_SCROLL_SENSITIVE} + * @return {@code true} if the deletes are seen by the {@code + * ResultSet} itself, otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean ownDeletesAreVisible(int type) throws SQLException; + + /** + * Determines whether a {@code ResultSet} can see its own inserts, for a + * specified {@code ResultSet} type. + * + * @param type + * the type of the {@code ResultSet}: {@code + * ResultSet.TYPE_FORWARD_ONLY}, {@code + * ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code + * ResultSet.TYPE_SCROLL_SENSITIVE} + * @return {@code true} if the inserts are seen by the {@code + * ResultSet} itself, otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean ownInsertsAreVisible(int type) throws SQLException; + + /** + * Determines whether a {@code ResultSet} can see its own updates, for a + * specified {@code ResultSet} type. + * + * @param type + * the type of the {@code ResultSet}: {@code + * ResultSet.TYPE_FORWARD_ONLY}, {@code + * ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code + * ResultSet.TYPE_SCROLL_SENSITIVE} + * @return {@code true} if the updates are seen by the {@code + * ResultSet} itself, otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean ownUpdatesAreVisible(int type) throws SQLException; + + /** + * Determines whether the database treats SQL identifiers that are in mixed + * case (and unquoted) as case insensitive. If {@code true} then the + * database stores them in lower case. + * + * @return {@code true} if unquoted SQL identifiers are stored in lower + * case, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean storesLowerCaseIdentifiers() throws SQLException; + + /** + * Determines whether the database considers mixed case quoted SQL + * identifiers as case insensitive and stores them in lower case. + * + * @return {@code true} if quoted SQL identifiers are stored in lower case, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean storesLowerCaseQuotedIdentifiers() throws SQLException; + + /** + * Determines whether the database considers mixed case unquoted SQL + * identifiers as case insensitive and stores them in mixed case. + * + * @return {@code true} if unquoted SQL identifiers as stored in mixed case, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean storesMixedCaseIdentifiers() throws SQLException; + + /** + * Determines whether the database considers identifiers as case insensitive + * if they are mixed case quoted SQL. The database stores them in mixed + * case. + * + * @return {@code true} if quoted SQL identifiers are stored in mixed case, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean storesMixedCaseQuotedIdentifiers() throws SQLException; + + /** + * Determines whether the database considers mixed case unquoted SQL + * identifiers as case insensitive and stores them in upper case. + * + * @return {@code true} if unquoted SQL identifiers are stored in upper + * case, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean storesUpperCaseIdentifiers() throws SQLException; + + /** + * Determines whether the database considers mixed case quoted SQL + * identifiers as case insensitive and stores them in upper case. + * + * @return {@code true} if quoted SQL identifiers are stored in upper case, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean storesUpperCaseQuotedIdentifiers() throws SQLException; + + /** + * Determines whether the database supports {@code ALTER TABLE} operation with + * {@code ADD COLUMN}. + * + * @return {@code true} if {@code ALTER TABLE} with {@code ADD COLUMN} is + * supported, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsAlterTableWithAddColumn() throws SQLException; + + /** + * Determines whether the database supports {@code ALTER TABLE} operation with + * {@code DROP COLUMN}. + * + * @return {@code true} if {@code ALTER TABLE} with {@code DROP COLUMN} is + * supported, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsAlterTableWithDropColumn() throws SQLException; + + /** + * Determines whether the database supports the ANSI92 entry level SQL grammar. + * + * @return {@code true} if the ANSI92 entry level SQL grammar is supported, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsANSI92EntryLevelSQL() throws SQLException; + + /** + * Determines whether the database supports the ANSI92 full SQL grammar. + * + * @return {@code true} if the ANSI92 full SQL grammar is supported, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsANSI92FullSQL() throws SQLException; + + /** + * Determines whether the database supports the ANSI92 intermediate SQL Grammar. + * + * @return {@code true} if the ANSI92 intermediate SQL grammar is supported, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsANSI92IntermediateSQL() throws SQLException; + + /** + * Determines whether the database supports batch updates. + * + * @return {@code true} if batch updates are supported, {@code false} + * otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsBatchUpdates() throws SQLException; + + /** + * Determines whether catalog names may be used in data manipulation + * statements. + * + * @return {@code true} if catalog names can be used in data manipulation + * statements, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsCatalogsInDataManipulation() throws SQLException; + + /** + * Determines whether catalog names can be used in index definition statements. + * + * @return {@code true} if catalog names can be used in index definition + * statements, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsCatalogsInIndexDefinitions() throws SQLException; + + /** + * Determines whether catalog names can be used in privilege definition + * statements. + * + * @return {@code true} if catalog names can be used in privilege definition + * statements, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException; + + /** + * Determines whether catalog names can be used in procedure call statements. + * + * @return {@code true} if catalog names can be used in procedure call + * statements. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsCatalogsInProcedureCalls() throws SQLException; + + /** + * Determines whether catalog names may be used in table definition statements. + * + * @return {@code true} if catalog names can be used in definition + * statements, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsCatalogsInTableDefinitions() throws SQLException; + + /** + * Determines whether the database supports column aliasing. + * <p> + * If aliasing is supported, then the SQL AS clause is used to provide names + * for computed columns and provide alias names for columns. + * </p> + * + * @return {@code true} if column aliasing is supported, {@code false} + * otherwise. + * @throws SQLException + * a database error occurred. + */ + public boolean supportsColumnAliasing() throws SQLException; + + /** + * Determines whether the database supports the {@code CONVERT} operation between + * SQL types. + * + * @return {@code true} if the {@code CONVERT} operation is supported, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsConvert() throws SQLException; + + /** + * Determines whether the database supports {@code CONVERT} operation for two + * supplied SQL types. + * + * @param fromType + * the Type to convert from, as defined by {@code java.sql.Types} + * @param toType + * the Type to convert to, as defined by {@code java.sql.Types} + * @return {@code true} if the {@code CONVERT} operation is supported for + * these types, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsConvert(int fromType, int toType) + throws SQLException; + + /** + * Determines whether the database supports the Core SQL Grammar for ODBC. + * + * @return {@code true} if the Core SQL Grammar is supported, {@code false} + * otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsCoreSQLGrammar() throws SQLException; + + /** + * Determines whether the database supports correlated sub-queries. + * + * @return {@code true} if the database does support correlated sub-queries + * and {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsCorrelatedSubqueries() throws SQLException; + + /** + * Determines whether the database allows both data definition and data + * manipulation statements inside a transaction. + * + * @return {@code true} if both types of statement are permitted, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsDataDefinitionAndDataManipulationTransactions() + throws SQLException; + + /** + * Determines whether the database only allows data manipulation statements inside + * a transaction. + * + * @return {@code true} if data manipulation statements are permitted only within a transaction, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsDataManipulationTransactionsOnly() + throws SQLException; + + /** + * Determines whether table correlation names are required to be different from + * the names of the tables, when they are supported. + * + * @return {@code true} if correlation names must be different from table + * names, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsDifferentTableCorrelationNames() throws SQLException; + + /** + * Determines whether expressions in {@code ORDER BY} lists are supported. + * + * @return {@code true} if expressions in {@code ORDER BY} lists are + * supported. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsExpressionsInOrderBy() throws SQLException; + + /** + * Determines whether the Extended SQL Grammar for ODBC is supported. + * + * @return {@code true} if the Extended SQL Grammar is supported, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsExtendedSQLGrammar() throws SQLException; + + /** + * Determines whether the database supports full nested outer joins. + * + * @return {@code true} if full nested outer joins are supported, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsFullOuterJoins() throws SQLException; + + /** + * Determines whether auto generated keys can be returned when a statement + * executes. + * + * @return {@code true} if auto generated keys can be returned, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsGetGeneratedKeys() throws SQLException; + + /** + * Determines whether the database supports {@code GROUP BY} clauses. + * + * @return {@code true} if the {@code GROUP BY} clause is supported, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsGroupBy() throws SQLException; + + /** + * Determines whether the database supports using a column name in a {@code GROUP + * BY} clause not included in the {@code SELECT} statement as long as all of + * the columns in the {@code SELECT} statement are used in the {@code GROUP + * BY} clause. + * + * @return {@code true} if {@code GROUP BY} clauses can use column names in + * this way, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsGroupByBeyondSelect() throws SQLException; + + /** + * Determines whether the database supports using a column name in a {@code GROUP + * BY} clause that is not in the {@code SELECT} statement. + * + * @return {@code true} if {@code GROUP BY} clause can use a column name not + * in the {@code SELECT} statement, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsGroupByUnrelated() throws SQLException; + + /** + * Determines whether the database supports SQL Integrity Enhancement + * Facility. + * + * @return {@code true} if the Integrity Enhancement Facility is supported, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsIntegrityEnhancementFacility() throws SQLException; + + /** + * Determines whether the database supports a {@code LIKE} escape clause. + * + * @return {@code true} if LIKE escape clause is supported, {@code false} + * otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsLikeEscapeClause() throws SQLException; + + /** + * Determines whether the database provides limited support for outer join + * operations. + * + * @return {@code true} if there is limited support for outer join + * operations, {@code false} otherwise. This will be {@code true} if + * {@code supportsFullOuterJoins} returns {@code true}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsLimitedOuterJoins() throws SQLException; + + /** + * Determines whether the database supports Minimum SQL Grammar for ODBC. + * + * @return {@code true} if the Minimum SQL Grammar is supported, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsMinimumSQLGrammar() throws SQLException; + + /** + * Determines whether the database treats mixed case unquoted SQL identifiers as + * case sensitive storing them in mixed case. + * + * @return {@code true} if unquoted SQL identifiers are stored in mixed + * case, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsMixedCaseIdentifiers() throws SQLException; + + /** + * Determines whether the database considers mixed case quoted SQL + * identifiers as case sensitive, storing them in mixed case. + * + * @return {@code true} if quoted SQL identifiers are stored in mixed case, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException; + + /** + * Determines whether it is possible for a single {@code CallableStatement} to + * return multiple {@code ResultSet}s simultaneously. + * + * @return {@code true} if a single {@code CallableStatement} can return + * multiple {@code ResultSet}s simultaneously, {@code false} + * otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsMultipleOpenResults() throws SQLException; + + /** + * Determines whether retrieving multiple {@code ResultSet}s from a single + * call to the {@code execute} method is supported. + * + * @return {@code true} if multiple {@code ResultSet}s can be retrieved, + * {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsMultipleResultSets() throws SQLException; + + /** + * Determines whether multiple simultaneous transactions on + * different connections are supported. + * + * @return {@code true} if multiple open transactions are supported, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsMultipleTransactions() throws SQLException; + + /** + * Determines whether callable statements with named parameters is supported. + * + * @return {@code true} if named parameters can be used with callable + * statements, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsNamedParameters() throws SQLException; + + /** + * Determines whether columns in the database can be defined as non-nullable. + * + * @return {@code true} if columns can be defined non-nullable, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsNonNullableColumns() throws SQLException; + + /** + * Determines whether keeping cursors open across commit operations is + * supported. + * + * @return {@code true} if cursors can be kept open across commit + * operations, {@code false} if they might get closed. + * @throws SQLException + * a database error occurred. + */ + public boolean supportsOpenCursorsAcrossCommit() throws SQLException; + + /** + * Determines whether the database can keep cursors open across rollback + * operations. + * + * @return {@code true} if cursors can be kept open across rollback + * operations, {@code false} if they might get closed. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsOpenCursorsAcrossRollback() throws SQLException; + + /** + * Determines whether keeping statements open across commit operations is + * supported. + * + * @return {@code true} if statements can be kept open, {@code false} if + * they might not. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsOpenStatementsAcrossCommit() throws SQLException; + + /** + * Determines whether keeping statements open across rollback operations is + * supported. + * + * @return {@code true} if statements can be kept open, {@code false} if + * they might not. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsOpenStatementsAcrossRollback() throws SQLException; + + /** + * Determines whether using a column in an {@code ORDER BY} clause that is + * not in the {@code SELECT} statement is supported. + * + * @return {@code true} if it is possible to {@code ORDER} using a column + * not in the {@code SELECT}, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsOrderByUnrelated() throws SQLException; + + /** + * Determines whether outer join operations are supported. + * + * @return {@code true} if outer join operations are supported, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsOuterJoins() throws SQLException; + + /** + * Determines whether positioned {@code DELETE} statements are supported. + * + * @return {@code true} if the database supports positioned {@code DELETE} + * statements. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsPositionedDelete() throws SQLException; + + /** + * Determines whether positioned {@code UPDATE} statements are supported. + * + * @return {@code true} if the database supports positioned {@code UPDATE} + * statements, {@code false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsPositionedUpdate() throws SQLException; + + /** + * Determines whether there is support for a given concurrency style for the + * given {@code ResultSet}. + * + * @param type + * the {@code ResultSet} type, as defined in {@code + * java.sql.ResultSet}: + * <ul> + * <li>{@code ResultSet.TYPE_FORWARD_ONLY}</li> + * <li>{@code ResultSet.TYPE_SCROLL_INSENSITIVE}</li> + * <li>{@code ResultSet.TYPE_SCROLL_SENSITIVE}</li> + * </ul> + * @param concurrency + * a concurrency type, which may be one of {@code + * ResultSet.CONCUR_READ_ONLY} or {@code + * ResultSet.CONCUR_UPDATABLE}. + * @return {@code true} if that concurrency and {@code ResultSet} type + * pairing is supported otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsResultSetConcurrency(int type, int concurrency) + throws SQLException; + + /** + * Determines whether the supplied {@code ResultSet} holdability mode is + * supported. + * + * @param holdability + * as specified in {@code java.sql.ResultSet}: {@code + * ResultSet.HOLD_CURSORS_OVER_COMMIT} or {@code + * ResultSet.CLOSE_CURSORS_AT_COMMIT} + * @return {@code true} if the given ResultSet holdability is supported and + * if it isn't then {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsResultSetHoldability(int holdability) + throws SQLException; + + /** + * Determines whether the supplied {@code ResultSet} type is supported. + * + * @param type + * the {@code ResultSet} type as defined in {@code + * java.sql.ResultSet}: {@code ResultSet.TYPE_FORWARD_ONLY}, + * {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code + * ResultSet.TYPE_SCROLL_SENSITIVE} + * @return {@code true} if the {@code ResultSet} type is supported, {@code + * false} otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsResultSetType(int type) throws SQLException; + + /** + * Determines whether savepoints for transactions are supported. + * + * @return {@code true} if savepoints are supported, {@code false} + * otherwise. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsSavepoints() throws SQLException; + + /** + * Determines whether a schema name may be used in a data manipulation + * statement. + * + * @return {@code true} if a schema name can be used in a data manipulation, + * otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsSchemasInDataManipulation() throws SQLException; + + /** + * Determines whether a schema name may be used in an index definition + * statement. + * + * @return {@code true} if a schema name can be used in an index definition, + * otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsSchemasInIndexDefinitions() throws SQLException; + + /** + * Determines whether a database schema name can be used in a privilege + * definition statement. + * + * @return {@code true} if a database schema name may be used in a privilege + * definition, otherwise {@code false} + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException; + + /** + * Determines whether a procedure call statement may be contain in a schema name. + * + * @return {@code true} if a schema name can be used in a procedure call, + * otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsSchemasInProcedureCalls() throws SQLException; + + /** + * Determines whether a schema name can be used in a table definition statement. + * + * @return {@code true} if a schema name can be used in a table definition, + * otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsSchemasInTableDefinitions() throws SQLException; + + /** + * Determines whether the {@code SELECT FOR UPDATE} statement is supported. + * + * @return {@code true} if {@code SELECT FOR UPDATE} statements are + * supported, otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsSelectForUpdate() throws SQLException; + + /** + * Determines whether statement pooling is supported. + * + * @return {@code true} of the database does support statement pooling, + * otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsStatementPooling() throws SQLException; + + /** + * Determines whether stored procedure calls using the stored procedure + * escape syntax is supported. + * + * @return {@code true} if stored procedure calls using the stored procedure + * escape syntax are supported, otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsStoredProcedures() throws SQLException; + + /** + * Determines whether subqueries in comparison expressions are supported. + * + * @return {@code true} if subqueries are supported in comparison + * expressions. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsSubqueriesInComparisons() throws SQLException; + + /** + * Determines whether subqueries in {@code EXISTS} expressions are supported. + * + * @return {@code true} if subqueries are supported in {@code EXISTS} + * expressions, otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsSubqueriesInExists() throws SQLException; + + /** + * Determines whether subqueries in {@code IN} statements are supported. + * + * @return {@code true} if subqueries are supported in {@code IN} statements, + * otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsSubqueriesInIns() throws SQLException; + + /** + * Determines whether subqueries in quantified expressions are supported. + * + * @return {@code true} if subqueries are supported, otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsSubqueriesInQuantifieds() throws SQLException; + + /** + * Determines whether the database has table correlation names support. + * + * @return {@code true} if table correlation names are supported, otherwise + * {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsTableCorrelationNames() throws SQLException; + + /** + * Determines whether a specified transaction isolation level is supported. + * + * @param level + * the transaction isolation level, as specified in {@code + * java.sql.Connection}: {@code TRANSACTION_NONE}, {@code + * TRANSACTION_READ_COMMITTED}, {@code + * TRANSACTION_READ_UNCOMMITTED}, {@code + * TRANSACTION_REPEATABLE_READ}, {@code TRANSACTION_SERIALIZABLE} + * @return {@code true} if the specific isolation level is supported, + * otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsTransactionIsolationLevel(int level) + throws SQLException; + + /** + * Determines whether transactions are supported. + * <p> + * If transactions are not supported, then the {@code commit} method does + * nothing and the transaction isolation level is always {@code + * TRANSACTION_NONE}. + * </p> + * + * @return {@code true} if transactions are supported, otherwise {@code + * false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsTransactions() throws SQLException; + + /** + * Determines whether the {@code SQL UNION} operation is supported. + * + * @return {@code true} of the database does support {@code UNION}, otherwise + * {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsUnion() throws SQLException; + + /** + * Determines whether the {@code SQL UNION ALL} operation is supported. + * + * @return {@code true} if the database does support {@code UNION ALL}, + * otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean supportsUnionAll() throws SQLException; + + /** + * Determines whether the method {@code ResultSet.rowUpdated} can detect a visible + * row update for the specified {@code ResultSet} type. + * + * @param type + * {@code ResultSet} type: {@code ResultSet.TYPE_FORWARD_ONLY}, + * {@code ResultSet.TYPE_SCROLL_INSENSITIVE}, or {@code + * ResultSet.TYPE_SCROLL_SENSITIVE} + * @return {@code true} detecting changes is possible, otherwise {@code + * false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean updatesAreDetected(int type) throws SQLException; + + /** + * Determines whether this database uses a file for each table. + * + * @return {@code true} if the database uses one file for each table, + * otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean usesLocalFilePerTable() throws SQLException; + + /** + * Determines whether this database uses a local file to store tables. + * + * @return {@code true} if the database stores tables in a local file, + * otherwise {@code false}. + * @throws SQLException + * a database error occurred. + * @since Android 1.0 + */ + public boolean usesLocalFiles() throws SQLException; +} diff --git a/sql/src/main/java/java/sql/Date.java b/sql/src/main/java/java/sql/Date.java new file mode 100644 index 0000000..e506a43 --- /dev/null +++ b/sql/src/main/java/java/sql/Date.java @@ -0,0 +1,250 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.text.SimpleDateFormat; + +/** + * A class which can consume and produce dates in SQL {@code Date} format. + * <p> + * Dates are represented in SQL as {@code yyyy-mm-dd}. Note that this date + * format only deals with year, month and day values. There are no values for + * hours, minutes, seconds. + * </p> + * This is unlike the familiar {@code java.util.Date} object, which also includes + * values for hours, minutes, seconds, and milliseconds. + * <p> + * Time points are handled as millisecond values - milliseconds since the Epoch, + * January 1st 1970, 00:00:00.000 GMT. Time values passed to the {@code + * java.sql.Date} class are "normalized" to the time 00:00:00.000 GMT on the + * date implied by the time value. + * </p> + * + * @since Android 1.0 + */ +public class Date extends java.util.Date { + + private static final long serialVersionUID = 1511598038487230103L; + + /** + * Constructs a {@code Date} object corresponding to the supplied year, + * month and day. + * + * @deprecated Please use the constructor {@link #Date(long)}. + * @param theYear + * the year, specified as the year minus 1900. Must be in the + * range {@code [0,8099]}. + * @param theMonth + * the month, specified as a number with 0 = January. Must be in + * the range {@code [0,11]}. + * @param theDay + * the day in the month. Must be in the range {@code [1,31]}. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + public Date(int theYear, int theMonth, int theDay) { + super(theYear, theMonth, theDay); + } + + /** + * Creates a date which corresponds to the day determined by the supplied + * milliseconds time value {@code theDate}. + * + * @param theDate + * a time value in milliseconds since the epoch - January 1 1970 + * 00:00:00 GMT. The time value (hours, minutes, seconds, + * milliseconds) stored in the {@code Date} object is adjusted to + * correspond to 00:00:00 GMT on the day determined by the supplied + * time value. + * @since Android 1.0 + */ + public Date(long theDate) { + super(normalizeTime(theDate)); + } + + /** + * @deprecated This method is deprecated and must not be used. SQL {@code + * Date} values do not have an hours component. + * @return does not return anything. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public int getHours() { + throw new IllegalArgumentException(); + } + + /** + * @deprecated This method is deprecated and must not be used. SQL {@code + * Date} values do not have a minutes component. + * @return does not return anything. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public int getMinutes() { + throw new IllegalArgumentException(); + } + + /** + * @deprecated This method is deprecated and must not be used. SQL {@code + * Date} values do not have a seconds component. + * @return does not return anything. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public int getSeconds() { + throw new IllegalArgumentException(); + } + + /** + * @deprecated This method is deprecated and must not be used. SQL {@code + * Date} values do not have an hours component. + * @param theHours + * the number of hours to set. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public void setHours(int theHours) { + throw new IllegalArgumentException(); + } + + /** + * @deprecated This method is deprecated and must not be used. SQL {@code + * Date} values do not have a minutes component. + * @param theMinutes + * the number of minutes to set. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public void setMinutes(int theMinutes) { + throw new IllegalArgumentException(); + } + + /** + * @deprecated This method is deprecated and must not be used. SQL {@code + * Date} values do not have a seconds component. + * @param theSeconds + * the number of seconds to set. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public void setSeconds(int theSeconds) { + throw new IllegalArgumentException(); + } + + /** + * Sets this date to a date supplied as a milliseconds value. The date is + * set based on the supplied time value and rounded to zero GMT for that day. + * + * @param theTime + * the time in milliseconds since the Epoch. + * @since Android 1.0 + */ + @Override + public void setTime(long theTime) { + /* + * Store the Date based on the supplied time after removing any time + * elements finer than the day based on zero GMT + */ + super.setTime(normalizeTime(theTime)); + } + + /** + * Produces a string representation of the date in SQL format + * + * @return a string representation of the date in SQL format - {@code + * "yyyy-mm-dd"}. + * @since Android 1.0 + */ + @Override + public String toString() { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$ + return dateFormat.format(this); + } + + /** + * Creates a {@code Date} from a string representation of a date in SQL + * format. + * + * @param dateString + * the string representation of a date in SQL format - " {@code + * yyyy-mm-dd}". + * @return the {@code Date} object. + * @throws IllegalArgumentException + * if the format of the supplied string does not match the SQL + * format. + * @since Android 1.0 + */ + public static Date valueOf(String dateString) { + if (dateString == null) { + throw new IllegalArgumentException(); + } + int firstIndex = dateString.indexOf('-'); + int secondIndex = dateString.indexOf('-', firstIndex + 1); + // secondIndex == -1 means none or only one separator '-' has been + // found. + // The string is separated into three parts by two separator characters, + // if the first or the third part is null string, we should throw + // IllegalArgumentException to follow RI + if (secondIndex == -1 || firstIndex == 0 + || secondIndex + 1 == dateString.length()) { + throw new IllegalArgumentException(); + } + // parse each part of the string + int year = Integer.parseInt(dateString.substring(0, firstIndex)); + int month = Integer.parseInt(dateString.substring(firstIndex + 1, + secondIndex)); + int day = Integer.parseInt(dateString.substring(secondIndex + 1, + dateString.length())); + return new Date(year - 1900, month - 1, day); + } + + /* + * Private method which normalizes a Time value, removing all low + * significance digits corresponding to milliseconds, seconds, minutes and + * hours, so that the returned Time value corresponds to 00:00:00 GMT on a + * particular day. + */ + private static long normalizeTime(long theTime) { + return theTime; + } +} diff --git a/sql/src/main/java/java/sql/Driver.java b/sql/src/main/java/java/sql/Driver.java new file mode 100644 index 0000000..c0499cb --- /dev/null +++ b/sql/src/main/java/java/sql/Driver.java @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.util.Properties; + +/** + * An interface to a JDBC driver. + * <p> + * The JDBC driver uses URLs to specify the location of specific data. URL + * format typically takes the form " {@code xxxx:yyyy:SpecificData}", where " + * {@code xxxx:yyyy}" is referred to as the <i>subprotocol</i> and is normally + * the same for all of a particular driver. " {@code SpecificData}" is a string + * which identifies the particular data source that the driver should use. + * </p> + * <p> + * A driver needs to be registered with a {@link DriverManager}. It is + * registered and instantiated by calling {@code Class.forName("DriverURL")} + * with the URL string as argument. + * </p> + * @see DriverManager + * + * @since Android 1.0 + */ +public interface Driver { + + /** + * Returns whether the driver thinks that it can open a connection to the + * given URL. + * + * @param url + * the URL to connect to. + * @return {@code true} if the driver thinks that is can open a connection + * to the supplied URL, {@code false} otherwise. Typically, the + * driver will respond {@code true} if it thinks that it can handle + * the subprotocol specified by the driver. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public boolean acceptsURL(String url) throws SQLException; + + /** + * Attempts to make a database connection to a data source specified by a + * supplied URL. + * + * @param url + * the URL to connect. + * @param info + * some properties that should be used in establishing the + * connection. The properties consist of name/value pairs of + * strings. Normally, a connection to a database requires at + * least two properties - for {@code "user"} and {@code + * "password"} in order to pass authentication to the database. + * @return the connection to the database. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public Connection connect(String url, Properties info) throws SQLException; + + /** + * Gets the driver's major version number. + * + * @return the major version number of the driver - typically starts at 1. + * @since Android 1.0 + */ + public int getMajorVersion(); + + /** + * Gets the driver's minor version number. + * + * @return the minor version number of the driver - typically starts at 0. + * @since Android 1.0 + */ + public int getMinorVersion(); + + /** + * Gets information about possible properties for this driver. + * <p> + * This method is intended to provide a listing of possible properties that + * the client of the driver must supply in order to establish a connection + * to a database. Note that the returned array of properties may change + * depending on the supplied list of property values. + * </p> + * + * @param url + * the URL of the database. An application may call this method + * iteratively as the property list is built up - for example, + * when displaying a dialog to an end-user as part of the + * database login process. + * @param info + * a set of tag/value pairs giving data that a user may be + * prompted to provide in order to connect to the database. + * @return an array of {@code DriverPropertyInfo} records which provide + * details on which additional properties are required (in addition + * to those supplied in the {@code info} parameter) in order to + * connect to the database. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) + throws SQLException; + + /** + * Reports whether this driver is a genuine JDBC CompliantTM driver. The + * driver may only return {@code true} if it passes all the JDBC compliance + * tests. + * <p> + * A driver may not be fully compliant if the underlying database has + * limited functionality. + * </p> + * + * @return {@code true} if the driver is fully JDBC compliant, {@code false} + * otherwise. + * @since Android 1.0 + */ + public boolean jdbcCompliant(); + +} diff --git a/sql/src/main/java/java/sql/DriverManager.java b/sql/src/main/java/java/sql/DriverManager.java new file mode 100644 index 0000000..afcf2f5 --- /dev/null +++ b/sql/src/main/java/java/sql/DriverManager.java @@ -0,0 +1,463 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.util.Properties; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Set; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.util.HashSet; +import java.util.Vector; +import org.apache.harmony.sql.internal.nls.Messages; +// BEGIN android-changed +import dalvik.system.VMStack; +// END android-changed + +/** + * Provides facilities for managing JDBC drivers. + * <p> + * The {@code DriverManager} class loads JDBC drivers during its initialization, + * from the list of drivers referenced by the system property {@code + * "jdbc.drivers"}. + * </p> + * + * @since Android 1.0 + */ +public class DriverManager { + + /* + * Facilities for logging. The Print Stream is deprecated but is maintained + * here for compatibility. + */ + private static PrintStream thePrintStream; + + private static PrintWriter thePrintWriter; + + // Login timeout value - by default set to 0 -> "wait forever" + private static int loginTimeout = 0; + + /* + * Set to hold Registered Drivers - initial capacity 10 drivers (will expand + * automatically if necessary. + */ + private static final Set<Driver> theDriverSet = new HashSet<Driver>(10); + + // Permission for setting log + private static final SQLPermission logPermission = new SQLPermission("setLog"); //$NON-NLS-1$ + + /* + * Load drivers on initialization + */ + static { + loadInitialDrivers(); + } + + /* + * Loads the set of JDBC drivers defined by the Property "jdbc.drivers" if + * it is defined. + */ + private static void loadInitialDrivers() { + String theDriverList = System.getProperty("jdbc.drivers", null); //$NON-NLS-1$ + if (theDriverList == null) { + return; + } + + /* + * Get the names of the drivers as an array of Strings from the system + * property by splitting the property at the separator character ':' + */ + String[] theDriverNames = theDriverList.split(":"); //$NON-NLS-1$ + + for (String element : theDriverNames) { + try { + // Load the driver class + Class + .forName(element, true, ClassLoader + .getSystemClassLoader()); + } catch (Throwable t) { + // Ignored + } + } + } + + /* + * A private constructor to prevent allocation + */ + private DriverManager() { + super(); + } + + /** + * Removes a driver from the {@code DriverManager}'s registered driver list. + * This will only succeed when the caller's class loader loaded the driver + * that is to be removed. If the driver was loaded by a different class + * loader, the removal of the driver fails silently. + * <p> + * If the removal succeeds, the {@code DriverManager} will not use this + * driver in the future when asked to get a {@code Connection}. + * </p> + * + * @param driver + * the JDBC driver to remove. + * @throws SQLException + * if there is a problem interfering with accessing the + * database. + * @since Android 1.0 + */ + public static void deregisterDriver(Driver driver) throws SQLException { + if (driver == null) { + return; + } + // BEGIN android-changed + ClassLoader callerClassLoader = VMStack.getCallingClassLoader(); + // END android-changed + + if (!DriverManager.isClassFromClassLoader(driver, callerClassLoader)) { + // sql.1=DriverManager: calling class not authorized to deregister JDBC driver + throw new SecurityException(Messages.getString("sql.1")); //$NON-NLS-1$ + } // end if + synchronized (theDriverSet) { + theDriverSet.remove(driver); + } + } + + /** + * Attempts to establish a connection to the given database URL. + * + * @param url + * a URL string representing the database target to connect with. + * @return a {@code Connection} to the database identified by the URL. + * {@code null} if no connection can be established. + * @throws SQLException + * if there is an error while attempting to connect to the + * database identified by the URL. + * @since Android 1.0 + */ + public static Connection getConnection(String url) throws SQLException { + return getConnection(url, new Properties()); + } + + /** + * Attempts to establish a connection to the given database URL. + * + * @param url + * a URL string representing the database target to connect with + * @param info + * a set of properties to use as arguments to set up the + * connection. Properties are arbitrary string/value pairs. + * Normally, at least the properties {@code "user"} and {@code + * "password"} should be passed, with appropriate settings for + * the user ID and its corresponding password to get access to + * the corresponding database. + * @return a {@code Connection} to the database identified by the URL. + * {@code null} if no connection can be established. + * @throws SQLException + * if there is an error while attempting to connect to the + * database identified by the URL. + * @since Android 1.0 + */ + public static Connection getConnection(String url, Properties info) + throws SQLException { + // 08 - connection exception + // 001 - SQL-client unable to establish SQL-connection + String sqlState = "08001"; //$NON-NLS-1$ + if (url == null) { + // sql.5=The url cannot be null + throw new SQLException(Messages.getString("sql.5"), sqlState); //$NON-NLS-1$ + } + synchronized (theDriverSet) { + /* + * Loop over the drivers in the DriverSet checking to see if one can + * open a connection to the supplied URL - return the first + * connection which is returned + */ + for (Driver theDriver : theDriverSet) { + Connection theConnection = theDriver.connect(url, info); + if (theConnection != null) { + return theConnection; + } + } + } + // If we get here, none of the drivers are able to resolve the URL + // sql.6=No suitable driver + throw new SQLException(Messages.getString("sql.6"), sqlState); //$NON-NLS-1$ + } + + /** + * Attempts to establish a connection to the given database URL. + * + * @param url + * a URL string representing the database target to connect with. + * @param user + * a user ID used to login to the database. + * @param password + * a password for the user ID to login to the database. + * @return a {@code Connection} to the database identified by the URL. + * {@code null} if no connection can be established. + * @throws SQLException + * if there is an error while attempting to connect to the + * database identified by the URL. + * @since Android 1.0 + */ + public static Connection getConnection(String url, String user, + String password) throws SQLException { + Properties theProperties = new Properties(); + if(null != user){ + theProperties.setProperty("user", user); //$NON-NLS-1$ + } + if(null != password){ + theProperties.setProperty("password", password); //$NON-NLS-1$ + } + return getConnection(url, theProperties); + } + + /** + * Tries to find a driver that can interpret the supplied URL. + * + * @param url + * the URL of a database. + * @return a {@code Driver} that matches the provided URL. {@code null} if + * no {@code Driver} understands the URL + * @throws SQLException + * if there is any kind of problem accessing the database. + */ + public static Driver getDriver(String url) throws SQLException { + // BEGIN android-changed + ClassLoader callerClassLoader = VMStack.getCallingClassLoader(); + // END android-changed + + synchronized (theDriverSet) { + /* + * Loop over the drivers in the DriverSet checking to see if one + * does understand the supplied URL - return the first driver which + * does understand the URL + */ + Iterator<Driver> theIterator = theDriverSet.iterator(); + while (theIterator.hasNext()) { + Driver theDriver = theIterator.next(); + if (theDriver.acceptsURL(url) + && DriverManager.isClassFromClassLoader(theDriver, + callerClassLoader)) { + return theDriver; + } + } + } + // If no drivers understand the URL, throw an SQLException + // sql.6=No suitable driver + //SQLState: 08 - connection exception + //001 - SQL-client unable to establish SQL-connection + throw new SQLException(Messages.getString("sql.6"), "08001"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Returns an {@code Enumeration} that contains all of the loaded JDBC + * drivers that the current caller can access. + * + * @return An {@code Enumeration} containing all the currently loaded JDBC + * {@code Drivers}. + * @since Android 1.0 + */ + public static Enumeration<Driver> getDrivers() { + // BEGIN android-changed + ClassLoader callerClassLoader = VMStack.getCallingClassLoader(); + // END android-changed + /* + * Synchronize to avoid clashes with additions and removals of drivers + * in the DriverSet + */ + synchronized (theDriverSet) { + /* + * Create the Enumeration by building a Vector from the elements of + * the DriverSet + */ + Vector<Driver> theVector = new Vector<Driver>(); + Iterator<Driver> theIterator = theDriverSet.iterator(); + while (theIterator.hasNext()) { + Driver theDriver = theIterator.next(); + if (DriverManager.isClassFromClassLoader(theDriver, + callerClassLoader)) { + theVector.add(theDriver); + } + } + return theVector.elements(); + } + } + + /** + * Returns the login timeout when connecting to a database in seconds. + * + * @return the login timeout in seconds. + * @since Android 1.0 + */ + public static int getLoginTimeout() { + return loginTimeout; + } + + /** + * Gets the log {@code PrintStream} used by the {@code DriverManager} and + * all the JDBC Drivers. + * + * @deprecated use {@link #getLogWriter()} instead. + * @return the {@code PrintStream} used for logging activities. + * @since Android 1.0 + */ + @Deprecated + public static PrintStream getLogStream() { + return thePrintStream; + } + + /** + * Retrieves the log writer. + * + * @return A {@code PrintWriter} object used as the log writer. {@code null} + * if no log writer is set. + * @since Android 1.0 + */ + public static PrintWriter getLogWriter() { + return thePrintWriter; + } + + /** + * Prints a message to the current JDBC log stream. This is either the + * {@code PrintWriter} or (deprecated) the {@code PrintStream}, if set. + * + * @param message + * the message to print to the JDBC log stream. + * @since Android 1.0 + */ + public static void println(String message) { + if (thePrintWriter != null) { + thePrintWriter.println(message); + thePrintWriter.flush(); + } else if (thePrintStream != null) { + thePrintStream.println(message); + thePrintStream.flush(); + } + /* + * If neither the PrintWriter not the PrintStream are set, then silently + * do nothing the message is not recorded and no exception is generated. + */ + return; + } + + /** + * Registers a given JDBC driver with the {@code DriverManager}. + * <p> + * A newly loaded JDBC driver class should register itself with the + * {@code DriverManager} by calling this method. + * </p> + * + * @param driver + * the {@code Driver} to register with the {@code DriverManager}. + * @throws SQLException + * if a database access error occurs. + */ + public static void registerDriver(Driver driver) throws SQLException { + if (driver == null) { + throw new NullPointerException(); + } + synchronized (theDriverSet) { + theDriverSet.add(driver); + } + } + + /** + * Sets the login timeout when connecting to a database in seconds. + * + * @param seconds + * seconds until timeout. 0 indicates wait forever. + * @since Android 1.0 + */ + public static void setLoginTimeout(int seconds) { + loginTimeout = seconds; + return; + } + + /** + * Sets the print stream to use for logging data from the {@code + * DriverManager} and the JDBC drivers. + * + * @deprecated Use {@link #setLogWriter} instead. + * @param out + * the {@code PrintStream} to use for logging. + * @since Android 1.0 + */ + @Deprecated + public static void setLogStream(PrintStream out) { + checkLogSecurity(); + thePrintStream = out; + } + + /** + * Sets the {@code PrintWriter} that is used by all loaded drivers, and also + * the {@code DriverManager}. + * + * @param out + * the {@code PrintWriter} to be used. + * @since Android 1.0 + */ + public static void setLogWriter(PrintWriter out) { + checkLogSecurity(); + thePrintWriter = out; + } + + /* + * Method which checks to see if setting a logging stream is allowed by the + * Security manager + */ + private static void checkLogSecurity() { + SecurityManager securityManager = System.getSecurityManager(); + if (securityManager != null) { + // Throws a SecurityException if setting the log is not permitted + securityManager.checkPermission(logPermission); + } + } + + /** + * Determines whether the supplied object was loaded by the given {@code ClassLoader}. + * + * @param theObject + * the object to check. + * @param theClassLoader + * the {@code ClassLoader}. + * @return {@code true} if the Object does belong to the {@code ClassLoader} + * , {@code false} otherwise + */ + private static boolean isClassFromClassLoader(Object theObject, + ClassLoader theClassLoader) { + + if ((theObject == null) || (theClassLoader == null)) { + return false; + } + + Class<?> objectClass = theObject.getClass(); + + try { + Class<?> checkClass = Class.forName(objectClass.getName(), true, + theClassLoader); + if (checkClass == objectClass) { + return true; + } + } catch (Throwable t) { + // Empty + } + return false; + } +} diff --git a/sql/src/main/java/java/sql/DriverPropertyInfo.java b/sql/src/main/java/java/sql/DriverPropertyInfo.java new file mode 100644 index 0000000..3875abb --- /dev/null +++ b/sql/src/main/java/java/sql/DriverPropertyInfo.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +/** + * A class holding information about driver properties of a database connection. + * This class is returned by the + * {@link Driver#getPropertyInfo(String, java.util.Properties)} method and + * allows for the advanced connection handling. + * + * @since Android 1.0 + */ +public class DriverPropertyInfo { + + /** + * If the value member can be chosen from a set of possible values, they are + * contained here. Otherwise choices is {@code null}. + * + * @since Android 1.0 + */ + public String[] choices; + + /** + * A description of the property. May be {@code null}. + * + * @since Android 1.0 + */ + public String description; + + /** + * The name of the property. + * + * @since Android 1.0 + */ + public String name; + + /** + * {@code True} when the value member must be provided during {@code + * Driver.connect}. {@code False} otherwise. + * + * @since Android 1.0 + */ + public boolean required; + + /** + * The current value associated with this property. It is depending on the + * data gathered by the {@code getPropertyInfo} method, the general Java + * environment and the driver's default values. + * + * @since Android 1.0 + */ + public String value; + + /** + * Creates a {@code DriverPropertyInfo} instance with the supplied name and + * value. Other class members take their default values. + * + * @param name + * The property name. + * @param value + * The property value. + * @since Android 1.0 + */ + public DriverPropertyInfo(String name, String value) { + this.name = name; + this.value = value; + this.choices = null; + this.description = null; + this.required = false; + } +} diff --git a/sql/src/main/java/java/sql/ParameterMetaData.java b/sql/src/main/java/java/sql/ParameterMetaData.java new file mode 100644 index 0000000..94901ae --- /dev/null +++ b/sql/src/main/java/java/sql/ParameterMetaData.java @@ -0,0 +1,214 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +/** + * An interface used to get information about the types and properties of + * parameters in a {@code PreparedStatement}. + * + * @since Android 1.0 + */ +public interface ParameterMetaData { + + /** + * Indicates that the parameter mode is {@code IN}. + * + * @since Android 1.0 + */ + public static final int parameterModeIn = 1; + + /** + * Indicates that the parameter mode is {@code INOUT}. + * + * @since Android 1.0 + */ + public static final int parameterModeInOut = 2; + + /** + * Indicates that the parameter mode is {@code OUT}. + * + * @since Android 1.0 + */ + public static final int parameterModeOut = 4; + + /** + * Indicates that the parameter mode is not known. + * + * @since Android 1.0 + */ + public static final int parameterModeUnknown = 0; + + /** + * Indicates that a parameter is not permitted to be {@code NULL}. + * + * @since Android 1.0 + */ + public static final int parameterNoNulls = 0; + + /** + * Indicates that a parameter is permitted to be {@code NULL}. + * + * @since Android 1.0 + */ + public static final int parameterNullable = 1; + + /** + * Indicates that whether a parameter is allowed to be {@code null} or not + * is not known. + * + * @since Android 1.0 + */ + public static final int parameterNullableUnknown = 2; + + /** + * Gets the fully-qualified name of the Java class which should be passed as + * a parameter to the method {@code PreparedStatement.setObject}. + * + * @param paramIndex + * the index number of the parameter, where the first parameter + * has index 1. + * @return the fully qualified Java class name of the parameter with the + * specified index. This class name is used for custom mapping + * between SQL types and Java objects. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public String getParameterClassName(int paramIndex) throws SQLException; + + /** + * Gets the number of parameters in the {@code PreparedStatement} for which + * this {@code ParameterMetaData} contains information. + * + * @return the number of parameters. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int getParameterCount() throws SQLException; + + /** + * Gets the mode of the specified parameter. Can be one of: + * <ul> + * <li>ParameterMetaData.parameterModeIn</li> + * <li>ParameterMetaData.parameterModeOut</li> + * <li>ParameterMetaData.parameterModeInOut</li> + * <li>ParameterMetaData.parameterModeUnknown</li> + * </ul> + * + * @param paramIndex + * the index number of the parameter, where the first parameter + * has index 1. + * @return the parameter's mode. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int getParameterMode(int paramIndex) throws SQLException; + + /** + * Gets the SQL type of a specified parameter. + * + * @param paramIndex + * the index number of the parameter, where the first parameter + * has index 1. + * @return the SQL type of the parameter as defined in {@code + * java.sql.Types}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int getParameterType(int paramIndex) throws SQLException; + + /** + * Gets the database-specific type name of a specified parameter. + * + * @param paramIndex + * the index number of the parameter, where the first parameter + * has index 1. + * @return the type name for the parameter as used by the database. A + * fully-qualified name is returned if the parameter is a <i>User + * Defined Type</i> (UDT). + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public String getParameterTypeName(int paramIndex) throws SQLException; + + /** + * Gets the number of decimal digits for a specified parameter. + * + * @param paramIndex + * the index number of the parameter, where the first parameter + * has index 1. + * @return the number of decimal digits ("the precision") for the parameter. + * {@code 0} if the parameter is not a numeric type. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int getPrecision(int paramIndex) throws SQLException; + + /** + * Gets the number of digits after the decimal point for a specified + * parameter. + * + * @param paramIndex + * the index number of the parameter, where the first parameter + * has index 1. + * @return the number of digits after the decimal point ("the scale") for + * the parameter. {@code 0} if the parameter is not a numeric type. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int getScale(int paramIndex) throws SQLException; + + /** + * Gets whether {@code null} values are allowed for the specified parameter. + * The returned value is one of: + * <ul> + * <li>ParameterMetaData.parameterNoNulls</li> + * <li>ParameterMetaData.parameterNullable</li> + * <li>ParameterMetaData.parameterNullableUnknown</li> + * </ul> + * + * @param paramIndex + * the index number of the parameter, where the first parameter + * has index 1. + * @return the int code indicating the nullability of the parameter. + * @throws SQLException + * if a database error is encountered. + * @since Android 1.0 + */ + public int isNullable(int paramIndex) throws SQLException; + + /** + * Gets whether values for the specified parameter can be signed numbers. + * + * @param paramIndex + * the index number of the parameter, where the first parameter + * has index 1. + * @return {@code true} if values can be signed numbers for this parameter, + * {@code false} otherwise. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean isSigned(int paramIndex) throws SQLException; +} diff --git a/sql/src/main/java/java/sql/PreparedStatement.java b/sql/src/main/java/java/sql/PreparedStatement.java new file mode 100644 index 0000000..ab81871 --- /dev/null +++ b/sql/src/main/java/java/sql/PreparedStatement.java @@ -0,0 +1,742 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.util.Calendar; +import java.net.URL; +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; + +/** + * An interface for a precompiled SQL Statement. + * <p> + * An SQL Statement is put into a {@code PreparedStatement} and is precompiled + * so that it can be executed efficiently multiple times. + * </p> + * <p> + * Setter methods are supplied in the {@code PreparedStatement} interface for + * the setting of {@code IN} parameters for the statement. The setter method + * used for each {@code IN} parameter must match the parameter's type. + * </p> + * + * @since Android 1.0 + */ +public interface PreparedStatement extends Statement { + + /** + * Add a set of parameters to the {@code PreparedStatement}'s command batch. + * + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void addBatch() throws SQLException; + + /** + * Clear the current parameter values. + * <p> + * Typically, parameter values are retained for multiple executions of the + * {@code Statement}. Setting a parameter value replaces the previous value. This + * method clears the values for all parameters, releasing all resources used + * by those parameters. + * </p> + * + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void clearParameters() throws SQLException; + + /** + * Executes the SQL statement in this {@code PreparedStatement}. + * <p> + * A {@code PreparedStatement} may return multiple results. The execute + * method executes the {@code PreparedStatement} and returns a flag + * indicating the kind of result produced by the action. The methods + * {@code getResultSet} or {@code getUpdateCount} are used to retrieve + * the first result, and the second and subsequent results are + * retrieved with {@code getMoreResults}. + * </p> + * + * @return {@code true} if the result of the execution is a {@code + * ResultSet}, {@code false} if there is no result or if the result + * is an update count. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean execute() throws SQLException; + + /** + * Executes the SQL query in the {@code PreparedStatement} and returns the + * {@code ResultSet} generated by the query. + * + * @return the {@code ResultSet} generated by the query, never {@code null}. + * @throws SQLException + * if a database error happens or if the SQL statement does not + * produce a {@code ResultSet}. + * @since Android 1.0 + */ + public ResultSet executeQuery() throws SQLException; + + /** + * Invokes the SQL command contained within the prepared statement. This + * must be {@code INSERT}, {@code UPDATE}, {@code DELETE}, or a command that + * returns nothing. + * + * @return the number of affected rows for {@code INSERT}, {@code UPDATE} or {@code + * DELETE} statements, {@code 0} for statements that return nothing. + * @throws SQLException + * if a database error happens or if the SQL statement returns a + * {@code ResultSet}. + * @since Android 1.0 + */ + public int executeUpdate() throws SQLException; + + /** + * Returns a {@code ResultSetMetaData} describing the {@code + * ResultSet} that would be produced by execution of the {@code PreparedStatement}. + * <p> + * It is possible to know the metadata for the {@code ResultSet} without + * executing the {@code PreparedStatement}, because the {@code + * PreparedStatement} is precompiled. As a result the metadata can be + * queried ahead of time without actually executing the statement. + * </p> + * + * @return a {@code ResultSetMetaData} object with the information about the + * columns of the {@code ResultSet}, if the driver can return a + * {@code ResultSetMetaData}. {@code null} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public ResultSetMetaData getMetaData() throws SQLException; + + /** + * Gets information about the parameters of the {@code PreparedStatement}. + * + * @return a {@code ParameterMetaData} object which holds information about + * the number, type, and properties of the parameters of this {@code + * PreparedStatement}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public ParameterMetaData getParameterMetaData() throws SQLException; + + /** + * Sets the value of a specified parameter to the supplied {@code Array}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theArray + * a {@code java.sql.Array} giving the new value of the parameter at {@code + * parameterIndex}. + * @throws SQLException + * if a database error happens. + * @see Array + * @since Android 1.0 + */ + public void setArray(int parameterIndex, Array theArray) + throws SQLException; + + /** + * Sets the value of a specified parameter to the content of a supplied + * {@code InputStream}, which has a specified number of bytes. + * <p> + * This is a good method for setting an SQL {@code LONVARCHAR} parameter + * where the length of the data is large. Data is read from the {@code + * InputStream} until end-of-file is reached or the specified number of + * bytes is copied. + * </p> + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theInputStream + * the ASCII {@code InputStream} carrying the data to which the + * parameter at {@code parameterIndex} is set. + * @param length + * the number of bytes in the {@code InputStream} to copy to the + * parameter. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setAsciiStream(int parameterIndex, InputStream theInputStream, + int length) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.math.BigDecimal} value. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theBigDecimal + * the value to which the parameter at {@code parameterIndex} is + * set. + * @throws SQLException + * if a database error happens. + * @see java.math.BigDecimal + * @since Android 1.0 + */ + public void setBigDecimal(int parameterIndex, BigDecimal theBigDecimal) + throws SQLException; + + /** + * Sets the value of a specified parameter to the content of a supplied + * binary {@code InputStream}, which has a specified number of bytes. + * <p> + * Use this method when a large amount of data needs to be set into a + * {@code LONGVARBINARY} parameter. + * </p> + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theInputStream + * the binary {@code InputStream} carrying the data to update the + * parameter. + * @param length + * the number of bytes in the {@code InputStream} to copy to the + * parameter. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setBinaryStream(int parameterIndex, InputStream theInputStream, + int length) throws SQLException; + + /** + * Sets the value of a specified parameter to the given {@code Blob} object. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theBlob + * the {@code java.sql.Blob} to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + * @see Blob + */ + public void setBlob(int parameterIndex, Blob theBlob) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code boolean} + * value. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theBoolean + * the boolean value to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setBoolean(int parameterIndex, boolean theBoolean) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code byte} value. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theByte + * the byte value to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setByte(int parameterIndex, byte theByte) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied array of bytes. The + * array is mapped to a {@code VARBINARY} or {@code LONGVARBINARY} in the + * database. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theBytes + * the array of bytes to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setBytes(int parameterIndex, byte[] theBytes) + throws SQLException; + + /** + * Sets the value of a specified parameter to the character content of a + * {@code Reader} object, with the specified length of character data. + * <p> + * Data is read from the {@code + * Reader} until end-of-file is reached or the specified number of + * characters are copied. + * </p> + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1 + * @param reader + * the {@code java.io.Reader} containing the character data. + * @param length + * the number of characters to be read. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setCharacterStream(int parameterIndex, Reader reader, int length) + throws SQLException; + + /** + * Sets the value of a specified parameter to the given {@code Clob} object. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theClob + * a {@code java.sql.Clob} holding the data to which the + * parameter at {@code parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setClob(int parameterIndex, Clob theClob) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.sql.Date} value. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theDate + * a {@code java.sql.Date} to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setDate(int parameterIndex, Date theDate) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.sql.Date} value, using a supplied {@code Calendar} to map the Date. + * The {@code Calendar} allows the application to control the timezone used + * to compute the SQL {@code DATE} in the database - without the supplied + * {@code Calendar}, the driver uses the default timezone of the Java + * virtual machine. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theDate + * a {@code java.sql.Date} to which the parameter at {@code + * parameterIndex} is set. + * @param cal + * a {@code Calendar} to use to construct the SQL {@code DATE} + * value. + * @throws SQLException + * if a database error happens. + * @see Date + * @see java.util.Calendar + * @since Android 1.0 + */ + public void setDate(int parameterIndex, Date theDate, Calendar cal) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code double} + * value. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theDouble + * the {@code double} value to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setDouble(int parameterIndex, double theDouble) + throws SQLException; + + /** + * Sets the value of a specified parameter to to a supplied {@code float} + * value. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theFloat + * the {@code float} value to update the parameter. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setFloat(int parameterIndex, float theFloat) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code int} value. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theInt + * the {@code int} value to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setInt(int parameterIndex, int theInt) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code long} value. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theLong + * the {@code long} value to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setLong(int parameterIndex, long theLong) throws SQLException; + + /** + * Sets the value of a specified parameter to SQL {@code NULL}. Don't use + * this version of {@code setNull} for <i>User Defined Types</i> (UDT) or + * for REF type parameters. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param sqlType + * the SQL type of the parameter, as defined in {@code + * java.sql.Types}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setNull(int parameterIndex, int sqlType) throws SQLException; + + /** + * Sets the value of a specified parameter to SQL {@code NULL}. This version + * of {@code setNull} should be used for <i>User Defined Types</i> (UDTs) + * and also REF types. UDTs can be {@code STRUCT}, {@code DISTINCT}, {@code + * JAVA_OBJECT} and named array types. + * <p> + * Applications must provide the SQL type code and also a fully qualified + * SQL type name when supplying a {@code NULL} UDT or REF. For a UDT, the + * type name is the type name of the parameter itself, but for a REF + * parameter the type name is the type name of the referenced type. + * </p> + * + * @param paramIndex + * the parameter number index, where the first parameter has + * index 1. + * @param sqlType + * the SQL type of the parameter, as defined in {@code + * java.sql.Types}. + * @param typeName + * the fully qualified name of a UDT or REF type - ignored if the + * parameter is not a UDT. + * @throws SQLException + * if a database error happens. + * @see Types + * @since Android 1.0 + */ + public void setNull(int paramIndex, int sqlType, String typeName) + throws SQLException; + + /** + * Sets the value of a specified parameter using a supplied object. + * <p> + * There is a standard mapping from Java types to SQL types, defined in the + * JDBC specification. The passed object is then transformed into the + * appropriate SQL type, and then transferred to the database. {@code + * setObject} can be used to pass abstract data types unique to the + * database, by using a JDBC driver specific Java type. If the object's + * class implements the interface {@code SQLData}, the JDBC driver calls + * {@code SQLData.writeSQL} to write it to the SQL data stream. If the + * object's class implements {@code Ref}, {@code Blob}, {@code Clob}, + * {@code Struct}, or {@code Array}, the driver passes it to the database as + * a value of the corresponding SQL type. + * </p> + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theObject + * the object containing the value to which the parameter at + * {@code parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setObject(int parameterIndex, Object theObject) + throws SQLException; + + /** + * Sets the value of a specified parameter using a supplied object. + * <p> + * The object is converted to the given {@code targetSqlType} before it is + * sent to the database. If the object has a custom mapping (its class + * implements the interface {@code SQLData}), the JDBC driver will call the method + * {@code SQLData.writeSQL} to write it to the SQL data stream. If the + * object's class implements {@code Ref}, {@code Blob}, {@code Clob}, + * {@code Struct}, or {@code Array}, the driver will pass it to the database + * in the form of the relevant SQL type. + * </p> + * + * @param parameterIndex + * the parameter index, where the first parameter has index 1. + * @param theObject + * the Object containing the value to which the parameter at + * {@code parameterIndex} is set. + * @param targetSqlType + * the SQL type to send to the database, as defined in {@code + * java.sql.Types}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setObject(int parameterIndex, Object theObject, + int targetSqlType) throws SQLException; + + /** + * Sets the value of a specified parameter using a supplied object. + * <p> + * The object is converted to the given {@code targetSqlType} before it is + * sent to the database. If the object has a custom mapping (its class + * implements the interface {@code SQLData}), the JDBC driver will call the method + * {@code SQLData.writeSQL} to write it to the SQL data stream. If the + * object's class implements {@code Ref}, {@code Blob}, {@code Clob}, + * {@code Struct}, or {@code Array}, the driver will pass it to the database + * in the form of the relevant SQL type. + * </p> + * + * @param parameterIndex + * the parameter index, where the first parameter has index 1. + * @param theObject + * the Object containing the value to which the parameter at + * {@code parameterIndex} is set. + * @param targetSqlType + * the SQL type to send to the database, as defined in {@code + * java.sql.Types}. + * @param scale + * the number of digits after the decimal point - only applies to + * the types {@code java.sql.Types.DECIMAL} and {@code + * java.sql.Types.NUMERIC} - ignored for all other types. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setObject(int parameterIndex, Object theObject, + int targetSqlType, int scale) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * REF(<structured-type>)} value. This is stored as an SQL {@code REF}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theRef + * a {@code java.sql.Ref} value to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @see Ref + * @since Android 1.0 + */ + public void setRef(int parameterIndex, Ref theRef) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code short} + * value. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theShort + * a {@code short} value to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setShort(int parameterIndex, short theShort) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied string. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theString + * the value to which the parameter at {@code parameterIndex} is + * set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setString(int parameterIndex, String theString) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.sql.Time} value. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theTime + * a {@code java.sql.Time} value to which the parameter at + * {@code parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setTime(int parameterIndex, Time theTime) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.sql.Time} value, using a supplied {@code Calendar}. + * <p> + * The driver uses the supplied {@code Calendar} to create the SQL {@code + * TIME} value, which allows it to use a custom timezone - otherwise the + * driver uses the default timezone of the Java virtual machine. + * </p> + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theTime + * a {@code java.sql.Time} value to which the parameter at + * {@code parameterIndex} is set. + * @param cal + * a {@code Calendar} to use to construct the SQL {@code TIME} + * value. + * @throws SQLException + * if a database error happens. + * @see Time + * @see java.util.Calendar + * @since Android 1.0 + */ + public void setTime(int parameterIndex, Time theTime, Calendar cal) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied java.sql.Timestamp + * value. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theTimestamp + * the java.sql.Timestamp value to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setTimestamp(int parameterIndex, Timestamp theTimestamp) + throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.sql.Timestamp} value, using the supplied {@code Calendar}. + * <p> + * The driver uses the supplied {@code Calendar} to create the SQL {@code + * TIMESTAMP} value, which allows it to use a custom timezone - otherwise + * the driver uses the default timezone of the Java virtual machine. + * </p> + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theTimestamp + * the {@code java.sql.Timestamp} value to which the parameter at + * {@code parameterIndex} is set. + * @param cal + * a {@code Calendar} to use to construct the SQL {@code + * TIMESTAMP} value + * @throws SQLException + * if a database error happens. + * @see Timestamp + * @see java.util.Calendar + * @since Android 1.0 + */ + public void setTimestamp(int parameterIndex, Timestamp theTimestamp, + Calendar cal) throws SQLException; + + /** + * Sets the value of a specified parameter to the characters from a supplied + * {@code InputStream}, with a specified number of bytes. + * + * @deprecated Use {@link #setCharacterStream(int, Reader, int)} + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theInputStream + * the {@code InputStream} with the character data to which the + * parameter at {@code parameterIndex} is set. + * @param length + * the number of bytes to read from the {@code InputStream}. + * @throws SQLException + * if a database error happens. + */ + @Deprecated + public void setUnicodeStream(int parameterIndex, + InputStream theInputStream, int length) throws SQLException; + + /** + * Sets the value of a specified parameter to a supplied {@code + * java.net.URL}. + * + * @param parameterIndex + * the parameter number index, where the first parameter has + * index 1. + * @param theURL + * the {@code URL} to which the parameter at {@code + * parameterIndex} is set. + * @throws SQLException + * if a database error happens. + * @see URL + * @since Android 1.0 + */ + public void setURL(int parameterIndex, URL theURL) throws SQLException; +} diff --git a/sql/src/main/java/java/sql/Ref.java b/sql/src/main/java/java/sql/Ref.java new file mode 100644 index 0000000..2ceac8b --- /dev/null +++ b/sql/src/main/java/java/sql/Ref.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.util.Map; + +/** + * This interface represents an SQL Ref - a data object containing a cursor + * or pointer to a result table. + * <p> + * The data structure identified by an instance of Ref is held in the + * database, so the data is not necessarily read and converted + * into a Java object until {@code getObject} is called. However, if + * the database supports the {@code Ref} type, it is not typically + * necessary to get the underlying object before using it in a method call - + * the {@code Ref} object can be used in place of the data structure. + * </p> + * A {@code Ref} object is stored into the database using the + * {@link PreparedStatement#setRef(int, Ref)} method. + * + * @since Android 1.0 + */ +public interface Ref { + + /** + * Gets the fully-qualified SQL name of the SQL structured type that this + * {@code Ref} references. + * + * @return the fully qualified name of the SQL structured type. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public String getBaseTypeName() throws SQLException; + + /** + * Gets the SQL structured type instance referenced by this {@code Ref}. + * + * @return a Java object whose type is defined by the mapping for the SQL + * structured type. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public Object getObject() throws SQLException; + + /** + * Returns the associated object and uses the relevant mapping to convert it + * to a Java type. + * + * @param map + * the mapping for type conversion. + * @return a Java object whose type is defined by the mapping for the SQL + * structured type. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public Object getObject(Map<String, Class<?>> map) throws SQLException; + + /** + * Sets the value of the structured type that this {@code Ref} references to + * a supplied object. + * + * @param value + * the {@code Object} representing the new SQL structured type + * that this {@code Ref} references. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public void setObject(Object value) throws SQLException; +} diff --git a/sql/src/main/java/java/sql/ResultSet.java b/sql/src/main/java/java/sql/ResultSet.java new file mode 100644 index 0000000..f33f9de --- /dev/null +++ b/sql/src/main/java/java/sql/ResultSet.java @@ -0,0 +1,2122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.io.InputStream; +import java.math.BigDecimal; +import java.io.Reader; +import java.util.Calendar; +import java.util.Map; +import java.net.URL; + +/** + * An interface for an object which represents a database table entry, returned + * as the result of the query to the database. + * <p> + * {@code ResultSet}s have a cursor which points to the current data table row. + * When the {@code ResultSet} is created, the cursor's location is one position + * ahead of the first row. To move the cursor to the first and consecutive rows, + * use the {@code next} method. The {@code next} method returns {@code true} as + * long as there are more rows in the {@code ResultSet}, otherwise it returns + * {@code false}. + * </p> + * <p> + * The default type of {@code ResultSet} can not be updated and its cursor can + * only advance forward through the rows of data. This means that it is only + * possible to read through it once. However, other kinds of {@code ResultSet} + * are implemented: an <i>updatable</i> type and also types where the cursor can + * be <i>scrolled</i> forward and backward through the rows of data. How such a + * {@code ResultSet} is created is demonstrated in the following example: + * </p> + * <ul> + * <dd> + * {@code Connection con;}</dd> + * <dd>{@code Statement aStatement = con.createStatement( + * ResultSet.TYPE_SCROLL_SENSITIVE,}{@code ResultSet.CONCUR_UPDATABLE );}</dd> + * <dd>{@code ResultSet theResultSet = + * theStatement.executeQuery("SELECT price, quantity FROM STOCKTABLE");}</dd> + * <dd>{@code // theResultSet is both scrollable and updatable}</dd> </ul> + * <p> + * The {@code ResultSet} interface provides a series of methods for retrieving + * data from columns in the current row, such as {@code getDate} and {@code + * getFloat}. The columns are retrieved either by their index number (starting + * at 1) or by their name - there are separate methods for both techniques of + * column addressing. The column names are case insensitive. If several columns + * have the same name, then the getter methods use the first matching column. + * This means that if column names are used, it is not possible to guarantee + * that the name will retrieve data from the intended column - for certainty it + * is better to use column indexes. Ideally the columns should be read + * left-to-right and read once only, since not all databases are optimized to + * handle other techniques of reading the data. + * </p> + * <p> + * When reading data via the appropriate getter methods, the JDBC driver maps + * the SQL data retrieved from the database to the Java type implied by the + * method invoked by the application. The JDBC specification has a table for the + * mappings from SQL types to Java types. + * </p> + * <p> + * There are also methods for writing data into the {@code ResultSet}, such as + * {@code updateInt} and {@code updateString}. The update methods can be used + * either to modify the data of an existing row or to insert new data rows into + * the {@code ResultSet} . Modification of existing data involves moving the + * cursor to the row which needs modification and then using the update methods + * to modify the data, followed by calling the {@code ResultSet.updateRow} + * method. For insertion of new rows, the cursor is first moved to a special row + * called the <i>Insert Row</i>, data is added using the update methods, + * followed by calling the {@code ResultSet.insertRow} method. + * </p> + * <p> + * A {@code ResultSet} is closed if the statement which generated it closes, the + * statement is executed again, or the same statement's next {@code ResultSet} + * is retrieved (if the statement returned of multiple results). + * </p> + * + * @since Android 1.0 + */ +public interface ResultSet { + + /** + * A constant used to indicate that a {@code ResultSet} object must be + * closed when the method {@code Connection.commit} is invoked. + * + * @since Android 1.0 + */ + public static final int CLOSE_CURSORS_AT_COMMIT = 2; + + /** + * A constant used to indicate that a {@code ResultSet} object must not be + * closed when the method {@code Connection.commit} is invoked. + * + * @since Android 1.0 + */ + public static final int HOLD_CURSORS_OVER_COMMIT = 1; + + /** + * A constant used to indicate the concurrency mode for a {@code ResultSet} + * object that cannot be updated. + * + * @since Android 1.0 + */ + public static final int CONCUR_READ_ONLY = 1007; + + /** + * A constant used to indicate the concurrency mode for a {@code ResultSet} + * object that can be updated. + * + * @since Android 1.0 + */ + public static final int CONCUR_UPDATABLE = 1008; + + /** + * A constant used to indicate processing of the rows of a {@code ResultSet} + * in the forward direction, first to last. + * + * @since Android 1.0 + */ + public static final int FETCH_FORWARD = 1000; + + /** + * A constant used to indicate processing of the rows of a {@code ResultSet} + * in the reverse direction, last to first. + * + * @since Android 1.0 + */ + public static final int FETCH_REVERSE = 1001; + + /** + * A constant used to indicate that the order of processing of the rows of a + * {@code ResultSet} is unknown. + * + * @since Android 1.0 + */ + public static final int FETCH_UNKNOWN = 1002; + + /** + * A constant used to indicate a {@code ResultSet} object whose cursor can + * only move forward. + * + * @since Android 1.0 + */ + public static final int TYPE_FORWARD_ONLY = 1003; + + /** + * A constant used to indicate a {@code ResultSet} object which is + * scrollable but is insensitive to changes made by others. + * + * @since Android 1.0 + */ + public static final int TYPE_SCROLL_INSENSITIVE = 1004; + + /** + * A constant used to indicate a {@code ResultSet} object which is + * scrollable and sensitive to changes made by others. + * + * @since Android 1.0 + */ + public static final int TYPE_SCROLL_SENSITIVE = 1005; + + /** + * Moves the cursor to a specified row number in the {@code ResultSet}. + * + * @param row + * the index of the row starting at index 1. Index {@code -1} + * returns the last row. + * @return {@code true} if the new cursor position is on the {@code + * ResultSet}, {@code false} otherwise. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean absolute(int row) throws SQLException; + + /** + * Moves the cursor to the end of the {@code ResultSet}, after the last row. + * + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void afterLast() throws SQLException; + + /** + * Moves the cursor to the start of the {@code ResultSet}, before the first + * row. + * + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void beforeFirst() throws SQLException; + + /** + * Cancels any updates made to the current row in the {@code ResultSet}. + * + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void cancelRowUpdates() throws SQLException; + + /** + * Clears all warnings related to this {@code ResultSet}. + * + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void clearWarnings() throws SQLException; + + /** + * Releases this {@code ResultSet}'s database and JDBC resources. You are + * strongly advised to use this method rather than relying on the release + * being done when the {@code ResultSet}'s finalize method is called during + * garbage collection process. Note that the {@code close()} method might + * take some time to complete since it is dependent on the behavior of the + * connection to the database and the database itself. + * + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void close() throws SQLException; + + /** + * Deletes the current row from the {@code ResultSet} and from the + * underlying database. + * + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void deleteRow() throws SQLException; + + /** + * Gets the index number for a column in the {@code ResultSet} from the + * provided column name. + * + * @param columnName + * the column name. + * @return the column's index in the {@code ResultSet} identified by column + * name. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int findColumn(String columnName) throws SQLException; + + /** + * Shifts the cursor position to the first row in the {@code ResultSet}. + * + * @return {@code true} if the position is in a legitimate row, {@code + * false} if the {@code ResultSet} contains no rows. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean first() throws SQLException; + + /** + * Gets the content of a column specified by column index in the current row + * of this {@code ResultSet} as a {@code java.sql.Array}. + * + * @param columnIndex + * the index of the column to read + * @return a {@code java.sql.Array} with the data from the column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Array getArray(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name as a {@code + * java.sql.Array}. + * + * @param colName + * the name of the column to read. + * @return a {@code java.sql.Array} with the data from the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Array getArray(String colName) throws SQLException; + + /** + * Gets the value of a column specified by column index as an ASCII + * character stream. + * + * @param columnIndex + * the index of the column to read. + * @return an {@code InputStream} with the data from the column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public InputStream getAsciiStream(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name as an ASCII character + * stream. + * + * @param columnName + * the name of the column to read + * @return an {@code InputStream} with the data from the column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public InputStream getAsciiStream(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code + * java.math.BigDecimal}. + * + * @param columnIndex + * the index of the column to read. + * @return a {@code BigDecimal} with the value of the column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public BigDecimal getBigDecimal(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code + * java.math.BigDecimal}. + * + * @deprecated use {@link #getBigDecimal(int)} or + * {@link #getBigDecimal(String)} + * @param columnIndex + * the index of the column to read. + * @param scale + * the number of digits after the decimal point + * @return a {@code BigDecimal} with the value of the column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + @Deprecated + public BigDecimal getBigDecimal(int columnIndex, int scale) + throws SQLException; + + /** + * Gets the value of a column specified by column name, as a {@code + * java.math.BigDecimal}. + * + * @param columnName + * the name of the column to read. + * @return a BigDecimal with value of the column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public BigDecimal getBigDecimal(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column name, as a {@code + * java.math.BigDecimal}. + * + * @deprecated use {@link #getBigDecimal(int)} or + * {@link #getBigDecimal(String)} + * @param columnName + * the name of the column to read. + * @param scale + * the number of digits after the decimal point + * @return a BigDecimal with value of the column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + @Deprecated + public BigDecimal getBigDecimal(String columnName, int scale) + throws SQLException; + + /** + * Gets the value of a column specified by column index as a binary + * stream. + * <p> + * This method can be used to read {@code LONGVARBINARY} values. All of the + * data in the {@code InputStream} should be read before getting data from + * any other column. A further call to a getter method will implicitly close + * the {@code InputStream}. + * </p> + * + * @param columnIndex + * the index of the column to read. + * @return an {@code InputStream} with the data from the column. If the + * column value is SQL {@code NULL}, {@code null} is returned. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public InputStream getBinaryStream(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name as a binary stream. + * <p> + * This method can be used to read {@code LONGVARBINARY} values. All of the + * data in the {@code InputStream} should be read before getting data from + * any other column. A further call to a getter method will implicitly close + * the {@code InputStream}. + * </p> + * + * @param columnName + * the name of the column to read. + * @return an {@code InputStream} with the data from the column if the + * column value is SQL {@code NULL}, {@code null} is returned. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public InputStream getBinaryStream(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code + * java.sql.Blob} object. + * + * @param columnIndex + * the index of the column to read. + * @return a {@code java.sql.Blob} with the value of the column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Blob getBlob(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name, as a {@code + * java.sql.Blob} object. + * + * @param columnName + * the name of the column to read. + * @return a {@code java.sql.Blob} with the value of the column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Blob getBlob(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code boolean} + * . + * + * @param columnIndex + * the index of the column to read. + * @return a {@code boolean} value from the column. If the column is SQL + * {@code NULL}, {@code false} is returned. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean getBoolean(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name, as a {@code boolean} + * . + * + * @param columnName + * the name of the column to read. + * @return a {@code boolean} value from the column. If the column is SQL + * {@code NULL}, {@code false} is returned. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean getBoolean(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code byte}. + * + * @param columnIndex + * the index of the column to read. + * @return a {@code byte} equal to the value of the column. 0 if the value + * is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public byte getByte(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name as a {@code byte}. + * + * @param columnName + * the name of the column to read. + * @return a {@code byte} equal to the value of the column. 0 if the value + * is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public byte getByte(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index as a byte array. + * + * @param columnIndex + * the index of the column to read. + * @return a byte array containing the value of the column. {@code null} if + * the column contains SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public byte[] getBytes(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name as a byte array. + * + * @param columnName + * the name of the column to read. + * @return a byte array containing the value of the column. {@code null} if + * the column contains SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public byte[] getBytes(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code + * java.io.Reader} object. + * + * @param columnIndex + * the index of the column to read. + * @return a {@code Reader} holding the value of the column. {@code null} if + * the column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @see java.io.Reader + * @since Android 1.0 + */ + public Reader getCharacterStream(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name as a {@code + * java.io.Reader} object. + * + * @param columnName + * the name of the column to read. + * @return a {@code Reader} holding the value of the column. {@code null} if + * the column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Reader getCharacterStream(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code + * java.sql.Clob}. + * + * @param columnIndex + * the index of the column to read. + * @return a {@code Clob} object representing the value in the column. + * {@code null} if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Clob getClob(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name as a {@code + * java.sql.Clob}. + * + * @param colName + * the name of the column to read. + * @return a {@code Clob} object representing the value in the column. + * {@code null} if the value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Clob getClob(String colName) throws SQLException; + + /** + * Gets the concurrency mode of this {@code ResultSet}. + * + * @return the concurrency mode - one of: {@code ResultSet.CONCUR_READ_ONLY} + * , {@code ResultSet.CONCUR_UPDATABLE}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int getConcurrency() throws SQLException; + + /** + * Gets the name of the SQL cursor of this {@code ResultSet}. + * + * @return the SQL cursor name. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public String getCursorName() throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code + * java.sql.Date}. + * + * @param columnIndex + * the index of the column to read. + * @return a {@code java.sql.Date} matching the column value. {@code null} + * if the column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Date getDate(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code + * java.sql.Date}. This method uses a supplied calendar to compute the Date. + * + * @param columnIndex + * the index of the column to read. + * @param cal + * a {@code java.util.Calendar} to use in constructing the Date. + * @return a {@code java.sql.Date} matching the column value. {@code null} + * if the column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Date getDate(int columnIndex, Calendar cal) throws SQLException; + + /** + * Gets the value of a column specified by column name as a {@code + * java.sql.Date}. + * + * @param columnName + * the name of the column to read. + * @return a {@code java.sql.Date} matching the column value. {@code null} + * if the column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Date getDate(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column name, as a {@code + * java.sql.Date} object. + * + * @param columnName + * the name of the column to read. + * @param cal + * {@code java.util.Calendar} to use in constructing the Date. + * @return a {@code java.sql.Date} matching the column value. {@code null} + * if the column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Date getDate(String columnName, Calendar cal) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code double} + * value. + * + * @param columnIndex + * the index of the column to read. + * @return a {@code double} equal to the column value. {@code 0.0} if the + * column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public double getDouble(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name as a {@code double} + * value. + * + * @param columnName + * the name of the column to read. + * @return a {@code double} equal to the column value. {@code 0.0} if the + * column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public double getDouble(String columnName) throws SQLException; + + /** + * Gets the direction in which rows are fetched for this {@code ResultSet} + * object. + * + * @return the fetch direction. Will be one of: + * <ul> + * <li>ResultSet.FETCH_FORWARD</li><li>ResultSet.FETCH_REVERSE</li> + * <li>ResultSet.FETCH_UNKNOWN</li> + * </ul> + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int getFetchDirection() throws SQLException; + + /** + * Gets the fetch size (in number of rows) for this {@code ResultSet}. + * + * @return the fetch size as an int + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int getFetchSize() throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code float} + * value. + * + * @param columnIndex + * the index of the column to read. + * @return a {@code float} equal to the column value. {@code 0.0} if the + * column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public float getFloat(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name as a {@code float} + * value. + * + * @param columnName + * the name of the column to read. + * @return a {@code float} equal to the column value. {@code 0.0} if the + * column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public float getFloat(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index as an {@code int} + * value. + * + * @param columnIndex + * the index of the column to read. + * @return an {@code int} equal to the column value. {@code 0} if the + * column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int getInt(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name, as an {@code int} + * value. + * + * @param columnName + * the name of the column to read. + * @return an {@code int} equal to the column value. {@code 0} if the + * column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int getInt(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code long} + * value. + * + * @param columnIndex + * the index of the column to read. + * @return a {@code long} equal to the column value. {@code 0} if the + * column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public long getLong(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name, as a {@code long} + * value. + * + * @param columnName + * the name of the column to read. + * @return a {@code long} equal to the column value. {@code 0} if the + * column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public long getLong(String columnName) throws SQLException; + + /** + * Gets the metadata for this {@code ResultSet}. This defines the number, + * types and properties of the columns in the {@code ResultSet}. + * + * @return a {@code ResultSetMetaData} object with information about this + * {@code ResultSet}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public ResultSetMetaData getMetaData() throws SQLException; + + /** + * Gets the value of a specified column as a Java {@code Object}. The type + * of the returned object will be the default according to the column's SQL + * type, following the JDBC specification for built-in types. + * <p> + * For SQL User Defined Types, if a column value is Structured or Distinct, + * this method behaves the same as a call to: {@code + * getObject(columnIndex,this.getStatement().getConnection().getTypeMap())} + * </p> + * + * @param columnIndex + * the index of the column to read. + * @return an {@code Object} containing the value of the column. {@code + * null} if the column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Object getObject(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column index as a Java {@code + * Object}. + * <p> + * The type of the Java object will be determined by the supplied Map to + * perform the mapping of SQL {@code Struct} or Distinct types into Java + * objects. + * </p> + * + * @param columnIndex + * the index of the column to read. + * @param map + * a {@code java.util.Map} containing a mapping from SQL Type + * names to Java classes. + * @return an {@code Object} containing the value of the column. {@code + * null} if the column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Object getObject(int columnIndex, Map<String, Class<?>> map) + throws SQLException; + + /** + * Gets the value of a specified column as a Java {@code Object}. The type + * of the returned object will be the default according to the column's SQL + * type, following the JDBC specification for built-in types. + * <p> + * For SQL User Defined Types, if a column value is structured or distinct, + * this method behaves the same as a call to: {@code + * getObject(columnIndex,this.getStatement().getConnection().getTypeMap())} + * </p> + * + * @param columnName + * the name of the column to read. + * @return an {@code Object} containing the value of the column. {@code + * null} if the column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Object getObject(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column name as a Java {@code + * Object}. + * <p> + * The type of the Java object will be determined by the supplied Map to + * perform the mapping of SQL Struct or Distinct types into Java objects. + * </p> + * + * @param columnName + * the name of the column to read. + * @param map + * a {@code java.util.Map} containing a mapping from SQL Type names to + * Java classes. + * @return an {@code Object} containing the value of the column. {@code + * null} if the column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Object getObject(String columnName, Map<String, Class<?>> map) + throws SQLException; + + /** + * Gets the value of a column specified by column index as a Java {@code + * java.sql.Ref}. + * + * @param columnIndex + * the index of the column to read. + * @return a Ref representing the value of the SQL REF in the column + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Ref getRef(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name as a Java {@code + * java.sql.Ref}. + * + * @param colName + * the name of the column to read. + * @return a Ref representing the value of the SQL {@code REF} in the column + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Ref getRef(String colName) throws SQLException; + + /** + * Gets the number of the current row in the {@code ResultSet}. Row numbers + * start at 1 for the first row. + * + * @return the index number of the current row. {@code 0} is returned if + * there is no current row. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public int getRow() throws SQLException; + + /** + * Gets the value of a column specified by column index as a short value. + * + * @param columnIndex + * the index of the column to read. + * @return a short value equal to the value of the column. {@code 0} if + * the value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public short getShort(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name, as a short value. + * + * @param columnName + * the name of the column to read. + * @return a short value equal to the value of the column. {@code 0} if + * the value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public short getShort(String columnName) throws SQLException; + + /** + * Gets the statement that produced this {@code ResultSet}. If the {@code + * ResultSet} was not created by a statement (i.e. because it was returned + * from one of the {@link DatabaseMetaData} methods), {@code null} is + * returned. + * + * @return the Statement which produced this {@code ResultSet}, or {@code + * null} if the {@code ResultSet} was not created by a Statement. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Statement getStatement() throws SQLException; + + /** + * Gets the value of a column specified by column index as a String. + * + * @param columnIndex + * the index of the column to read. + * @return the String representing the value of the column, {@code null} if + * the column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public String getString(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name, as a String. + * + * @param columnName + * the name of the column to read. + * @return the String representing the value of the column, {@code null} if + * the column is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public String getString(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code + * java.sql.Time} value. + * + * @param columnIndex + * the index of the column to read. + * @return a Time representing the column value, {@code null} if the column + * value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Time getTime(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code + * java.sql.Time} value. The supplied {@code Calendar} is used to + * map the SQL {@code Time} value to a Java Time value. + * + * @param columnIndex + * the index of the column to read. + * @param cal + * a {@code Calendar} to use in creating the Java Time value. + * @return a Time representing the column value, {@code null} if the column + * value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Time getTime(int columnIndex, Calendar cal) throws SQLException; + + /** + * Gets the value of a column specified by column name, as a {@code + * java.sql.Time} value. + * + * @param columnName + * the name of the column to read. + * @return the column value, {@code null} if the column value is SQL {@code + * NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Time getTime(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index, as a {@code + * java.sql.Time} value. The supplied {@code Calendar} is used to + * map the SQL {@code Time} value to a Java Time value. + * + * @param columnName + * the name of the column to read. + * @param cal + * a {@code Calendar} to use in creating the Java time value. + * @return a Time representing the column value, {@code null} if the column + * value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Time getTime(String columnName, Calendar cal) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code + * java.sql.Timestamp} value. + * + * @param columnIndex + * the index of the column to read. + * @return a timestamp representing the column value, {@code null} if the + * column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Timestamp getTimestamp(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column index, as a {@code + * java.sql.Timestamp} value. The supplied Calendar is used when mapping + * the SQL {@code Timestamp} value to a Java {@code Timestamp} value. + * + * @param columnIndex + * the index of the column to read. + * @param cal + * Calendar to use in creating the Java timestamp value. + * @return a timestamp representing the column value, {@code null} if the + * column value is SQL NULL. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Timestamp getTimestamp(int columnIndex, Calendar cal) + throws SQLException; + + /** + * Gets the value of a column specified by column name, as a {@code + * java.sql.Timestamp} value. + * + * @param columnName + * the name of the column to read. + * @return a timestamp representing the column value, {@code null} if the + * column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Timestamp getTimestamp(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column name, as a {@code + * java.sql.Timestamp} value. The supplied Calendar is used when mapping + * the SQL {@code Timestamp} value to a Java {@code Timestamp} value. + * + * @param columnName + * the name of the column to read. + * @param cal + * Calendar to use in creating the Java {@code Timestamp} value. + * @return a timestamp representing the column value, {@code null} if the + * column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public Timestamp getTimestamp(String columnName, Calendar cal) + throws SQLException; + + /** + * Gets the type of the {@code ResultSet}. + * + * @return The {@code ResultSet} type, one of: + * <ul> + * <li>{@code ResultSet.TYPE_FORWARD_ONLY}</li> <li>{@code + * ResultSet.TYPE_SCROLL_INSENSITIVE}</li> <li>{@code + * ResultSet.TYPE_SCROLL_SENSITIVE}</li> + * </ul> + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public int getType() throws SQLException; + + /** + * Gets the value of the column as an {@code InputStream} of unicode + * characters. + * + * @deprecated Use {@link #getCharacterStream}. + * @param columnIndex + * the index of the column to read. + * @return an {@code InputStream} holding the value of the column. {@code + * null} if the column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + @Deprecated + public InputStream getUnicodeStream(int columnIndex) throws SQLException; + + /** + * Gets the value of the column as an {@code InputStream} of Unicode + * characters. + * + * @deprecated Use {@link #getCharacterStream} + * @param columnName + * the name of the column to read. + * @return an {@code InputStream} holding the value of the column. {@code + * null} if the column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + @Deprecated + public InputStream getUnicodeStream(String columnName) throws SQLException; + + /** + * Gets the value of a column specified by column index as a {@code + * java.net.URL}. + * + * @param columnIndex + * the index of the column to read. + * @return a URL. {@code null} if the column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public URL getURL(int columnIndex) throws SQLException; + + /** + * Gets the value of a column specified by column name as a {@code + * java.net.URL} object. + * + * @param columnName + * the name of the column to read. + * @return the column vaule as a URL. {@code null} if the column value is SQL {@code NULL}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public URL getURL(String columnName) throws SQLException; + + /** + * Gets the first warning generated by calls on this {@code ResultSet}. + * Subsequent warnings on this {@code ResultSet} are chained to the first + * one. + * <p> + * The warnings are cleared when a new Row is read from the {@code + * ResultSet}. The warnings returned by this method are only the warnings + * generated by {@code ResultSet} method calls - warnings generated by + * Statement methods are held by the Statement. + * <p> + * </p> + * An {@code SQLException} is generated if this method is called on a closed + * {@code ResultSet}. </p> + * + * @return an SQLWarning which is the first warning for this {@code + * ResultSet}. {@code null} if there are no warnings. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public SQLWarning getWarnings() throws SQLException; + + /** + * Insert the insert row into the {@code ResultSet} and into the underlying + * database. The cursor must be set to the Insert Row before this method is + * invoked. + * + * @throws SQLException + * if a database error happens. Particular cases include the + * cursor not being on the Insert Row or if any columns in the + * row do not have a value where the column is declared as + * not-nullable. + * @since Android 1.0 + */ + public void insertRow() throws SQLException; + + /** + * Gets if the cursor is after the last row of the {@code ResultSet}. + * + * @return {@code true} if the cursor is after the last row in the {@code + * ResultSet}, {@code false} if the cursor is at any other position + * in the {@code ResultSet}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean isAfterLast() throws SQLException; + + /** + * Gets if the cursor is before the first row of the {@code ResultSet}. + * + * @return {@code true} if the cursor is before the first row in the {@code + * ResultSet}, {@code false} if the cursor is at any other position + * in the {@code ResultSet}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean isBeforeFirst() throws SQLException; + + /** + * Gets if the cursor is on the first row of the {@code ResultSet}. + * + * @return {@code true} if the cursor is on the first row in the {@code + * ResultSet}, {@code false} if the cursor is at any other position + * in the {@code ResultSet}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean isFirst() throws SQLException; + + /** + * Gets if the cursor is on the last row of the {@code ResultSet} + * + * @return {@code true} if the cursor is on the last row in the {@code + * ResultSet}, {@code false} if the cursor is at any other position + * in the {@code ResultSet}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean isLast() throws SQLException; + + /** + * Shifts the cursor position to the last row of the {@code ResultSet}. + * + * @return {@code true} if the new position is in a legitimate row, {@code + * false} if the {@code ResultSet} contains no rows. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean last() throws SQLException; + + /** + * Moves the cursor to the remembered position, namely the + * row that was the current row before a call to {@code moveToInsertRow}. + * This only applies if the cursor is on the Insert Row. + * + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void moveToCurrentRow() throws SQLException; + + /** + * Moves the cursor position to the Insert Row. The current position is + * remembered and the cursor is positioned at the Insert Row. The columns in + * the Insert Row should be filled in with the appropriate update methods, + * before calling {@code insertRow} to insert the new row into the database. + * + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void moveToInsertRow() throws SQLException; + + /** + * Shifts the cursor position down one row in this {@code ResultSet} object. + * <p> + * Any input streams associated with the current row are closed and any + * warnings are cleared. + * </p> + * + * @return {@code true} if the updated cursor position is pointing to a + * valid row, {@code false} otherwise (i.e. when the cursor is after + * the last row in the {@code ResultSet}). + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean next() throws SQLException; + + /** + * Relocates the cursor position to the preceding row in this {@code + * ResultSet}. + * + * @return {@code true} if the new position is in a legitimate row, {@code + * false} if the cursor is now before the first row. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean previous() throws SQLException; + + /** + * Refreshes the current row with its most up to date value in the database. + * Must not be called when the cursor is on the Insert Row. + * <p> + * If any columns in the current row have been updated but the {@code + * updateRow} has not been called, then the updates are lost when this + * method is called. + * </p> + * + * @throws SQLException + * if a database error happens., including if the current row is + * the Insert row. + * @since Android 1.0 + */ + public void refreshRow() throws SQLException; + + /** + * Moves the cursor position up or down by a specified number of rows. If + * the new position is beyond the start row (or end row), the cursor position is + * set before the first row (or, respectively, after the last row). + * + * @param rows + * a number of rows to move the cursor - may be positive or + * negative + * @return {@code true} if the new cursor position is on a row, {@code + * false} otherwise + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean relative(int rows) throws SQLException; + + /** + * Indicates whether a row has been deleted. This method depends on whether + * the JDBC driver and database can detect deletions. + * + * @return {@code true} if a row has been deleted and if deletions are + * detected, {@code false} otherwise. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean rowDeleted() throws SQLException; + + /** + * Indicates whether the current row has had an insertion operation. This + * method depends on whether the JDBC driver and database can detect + * insertions. + * + * @return {@code true} if a row has been inserted and if insertions are + * detected, {@code false} otherwise. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean rowInserted() throws SQLException; + + /** + * Indicates whether the current row has been updated. This method depends + * on whether the JDBC driver and database can detect updates. + * + * @return {@code true} if the current row has been updated and if updates + * can be detected, {@code false} otherwise. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean rowUpdated() throws SQLException; + + /** + * Indicates which direction (forward/reverse) will be used to process the + * rows of this {@code ResultSet} object. This is treated as a hint by the + * JDBC driver. + * + * @param direction + * can be {@code ResultSet.FETCH_FORWARD}, {@code + * ResultSet.FETCH_REVERSE}, or {@code ResultSet.FETCH_UNKNOWN} + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public void setFetchDirection(int direction) throws SQLException; + + /** + * Indicates the number of rows to fetch from the database when extra rows + * are required for this {@code ResultSet}. This used as a hint to the JDBC + * driver. + * + * @param rows + * the number of rows to fetch. {@code 0} implies that the JDBC + * driver can make its own decision about the fetch size. The + * number should not be greater than the maximum number of rows + * established by the statement that generated the {@code + * ResultSet}. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void setFetchSize(int rows) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code + * java.sql.Array} value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateArray(int columnIndex, Array x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code java.sql.Array} + * value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateArray(String columnName, Array x) throws SQLException; + + /** + * Updates a column specified by a column index with an ASCII stream value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @param length + * the length of the data to write from the stream + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateAsciiStream(int columnIndex, InputStream x, int length) + throws SQLException; + + /** + * Updates a column specified by a column name with an Ascii stream value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @param length + * the length of the data to write from the stream + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateAsciiStream(String columnName, InputStream x, int length) + throws SQLException; + + /** + * Updates a column specified by a column index with a {@code + * java.sql.BigDecimal} value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateBigDecimal(int columnIndex, BigDecimal x) + throws SQLException; + + /** + * Updates a column specified by a column name with a {@code + * java.sql.BigDecimal} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateBigDecimal(String columnName, BigDecimal x) + throws SQLException; + + /** + * Updates a column specified by a column index with a binary stream value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @param length + * the number of bytes to be read from the the stream. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateBinaryStream(int columnIndex, InputStream x, int length) + throws SQLException; + + /** + * Updates a column specified by a column name with a binary stream value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @param length + * he number of bytes to be read from the the stream. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateBinaryStream(String columnName, InputStream x, int length) + throws SQLException; + + /** + * Updates a column specified by a column index with a {@code java.sql.Blob} + * value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateBlob(int columnIndex, Blob x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code java.sql.Blob} + * value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateBlob(String columnName, Blob x) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code boolean} + * value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateBoolean(int columnIndex, boolean x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code boolean} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateBoolean(String columnName, boolean x) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code byte} value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateByte(int columnIndex, byte x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code byte} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateByte(String columnName, byte x) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code byte} array + * value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateBytes(int columnIndex, byte[] x) throws SQLException; + + /** + * Updates a column specified by a column name with a byte array value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateBytes(String columnName, byte[] x) throws SQLException; + + /** + * Updates a column specified by a column index with a character stream + * value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @param length + * the length of data to write from the stream + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateCharacterStream(int columnIndex, Reader x, int length) + throws SQLException; + + /** + * Updates a column specified by a column name with a character stream + * value. + * + * @param columnName + * the name of the column to update. + * @param reader + * the new value for the specified column. + * @param length + * the length of data to write from the Reader + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateCharacterStream(String columnName, Reader reader, + int length) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code java.sql.Clob} + * value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateClob(int columnIndex, Clob x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code java.sql.Clob} + * value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateClob(String columnName, Clob x) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code java.sql.Date} + * value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateDate(int columnIndex, Date x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code java.sql.Date} + * value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateDate(String columnName, Date x) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code double} value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateDouble(int columnIndex, double x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code double} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateDouble(String columnName, double x) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code float} value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateFloat(int columnIndex, float x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code float} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateFloat(String columnName, float x) throws SQLException; + + /** + * Updates a column specified by a column index with an {@code int} value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateInt(int columnIndex, int x) throws SQLException; + + /** + * Updates a column specified by a column name with an {@code int} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateInt(String columnName, int x) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code long} value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column.. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateLong(int columnIndex, long x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code long} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateLong(String columnName, long x) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code null} value. + * + * @param columnIndex + * the index of the column to update. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateNull(int columnIndex) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code null} value. + * + * @param columnName + * the name of the column to update. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateNull(String columnName) throws SQLException; + + /** + * Updates a column specified by a column index with an {@code Object} + * value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateObject(int columnIndex, Object x) throws SQLException; + + /** + * Updates a column specified by a column index with an {@code Object} + * value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @param scale + * for the types {@code java.sql.Types.DECIMAL} or {@code + * java.sql.Types.NUMERIC}, this specifies the number of digits + * after the decimal point. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateObject(int columnIndex, Object x, int scale) + throws SQLException; + + /** + * Updates a column specified by a column name with an {@code Object} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateObject(String columnName, Object x) throws SQLException; + + /** + * Updates a column specified by a column name with an {@code Object} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @param scale + * for the types {@code java.sql.Types.DECIMAL} or {@code + * java.sql.Types.NUMERIC}, this specifies the number of digits + * after the decimal point. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateObject(String columnName, Object x, int scale) + throws SQLException; + + /** + * Updates a column specified by a column index with a {@code java.sql.Ref} + * value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateRef(int columnIndex, Ref x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code java.sql.Ref} + * value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateRef(String columnName, Ref x) throws SQLException; + + /** + * Updates the database with the new contents of the current row of this + * {@code ResultSet} object. + * + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateRow() throws SQLException; + + /** + * Updates a column specified by a column index with a {@code short} value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateShort(int columnIndex, short x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code short} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateShort(String columnName, short x) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code String} value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateString(int columnIndex, String x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code String} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateString(String columnName, String x) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code Time} value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateTime(int columnIndex, Time x) throws SQLException; + + /** + * Updates a column specified by a column name with a {@code Time} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateTime(String columnName, Time x) throws SQLException; + + /** + * Updates a column specified by a column index with a {@code Timestamp} + * value. + * + * @param columnIndex + * the index of the column to update. + * @param x + * the new timestamp value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateTimestamp(int columnIndex, Timestamp x) + throws SQLException; + + /** + * Updates a column specified by column name with a {@code Timestamp} value. + * + * @param columnName + * the name of the column to update. + * @param x + * the new timestamp value for the specified column. + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public void updateTimestamp(String columnName, Timestamp x) + throws SQLException; + + /** + * Determines whether the last column read from this {@code ResultSet} + * contained SQL {@code NULL}. + * + * @return {@code {@code true} if the last column contained SQL {@code + * NULL}, {@code false} otherwise + * @throws SQLException + * if a database error happens. + * @since Android 1.0 + */ + public boolean wasNull() throws SQLException; +} diff --git a/sql/src/main/java/java/sql/ResultSetMetaData.java b/sql/src/main/java/java/sql/ResultSetMetaData.java new file mode 100644 index 0000000..95c515d --- /dev/null +++ b/sql/src/main/java/java/sql/ResultSetMetaData.java @@ -0,0 +1,311 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +/** + * Provides information about the columns returned in a {@code ResultSet}. + * + * @since Android 1.0 + */ +public interface ResultSetMetaData { + + /** + * Indicates that a column cannot contain {@code NULL} values. + * + * @since Android 1.0 + */ + public static final int columnNoNulls = 0; + + /** + * Indicates that a column can contain {@code NULL} values. + * + * @since Android 1.0 + */ + public static final int columnNullable = 1; + + /** + * Indicates that it is unknown whether a column can contain {@code NULL}s or not. + * + * @since Android 1.0 + */ + public static final int columnNullableUnknown = 2; + + /** + * Returns the title of an indexed column's catalog. + * + * @param column + * the column index, starting at 1. + * @return the catalog title. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public String getCatalogName(int column) throws SQLException; + + /** + * Returns the fully-qualified type of the class that is produced when + * invoking {@code ResultSet.getObject} to recover this column's value. + * + * @param column + * the column index, starting at 1. + * @return the fully-qualified class name. + * @throws SQLException + * if there is a database error. + * @see ResultSet#getObject + * @since Android 1.0 + */ + public String getColumnClassName(int column) throws SQLException; + + /** + * Returns number of columns contained in the associated result set. + * + * @return the column count. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public int getColumnCount() throws SQLException; + + /** + * Returns the indexed column's standard maximum width, expressed in number + * of characters. + * + * @param column + * the column index, starting at 1. + * @return the column's max width. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public int getColumnDisplaySize(int column) throws SQLException; + + /** + * Returns a recommended title for the indexed column, to be used when the + * title needs to be displayed. + * + * @param column + * the column index, starting at 1. + * @return the column's title. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public String getColumnLabel(int column) throws SQLException; + + /** + * Returns the title of the indexed column. + * + * @param column + * the column index, starting at 1. + * @return the column title. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public String getColumnName(int column) throws SQLException; + + /** + * Returns the type of the indexed column as SQL type code. + * + * @param column + * the column index, starting at 1. + * @return the column type code. + * @throws SQLException + * if there is a database error. + * @see Types + * @since Android 1.0 + */ + public int getColumnType(int column) throws SQLException; + + /** + * Returns the type name of the indexed column. + * + * @param column + * the column index, starting at 1. + * @return the type name. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public String getColumnTypeName(int column) throws SQLException; + + /** + * Returns the decimal precision of the indexed column. + * + * @param column + * the column index, starting at 1. + * @return the precision. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public int getPrecision(int column) throws SQLException; + + /** + * Returns the number of digits to the right of the decimal point of the + * indexed column. + * + * @param column + * the column index, starting at 1. + * @return number of decimal places. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public int getScale(int column) throws SQLException; + + /** + * Returns the name of the indexed columns schema. + * + * @param column + * the column index, starting at 1. + * @return the name of the columns schema. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public String getSchemaName(int column) throws SQLException; + + /** + * Returns the title of the indexed columns table. + * + * @param column + * the column index, starting at 1. + * @return the table title. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public String getTableName(int column) throws SQLException; + + /** + * Returns an indication of whether the indexed column is automatically + * incremented and is therefore read-only. + * + * @param column + * the column index, starting at 1. + * @return {@code true} if it is automatically numbered, {@code false} + * otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean isAutoIncrement(int column) throws SQLException; + + /** + * Returns an indication of whether the case of the indexed column is + * important. + * + * @param column + * the column index, starting at 1. + * @return {@code true} if case matters, {@code false} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean isCaseSensitive(int column) throws SQLException; + + /** + * Returns whether the indexed column contains a monetary amount. + * + * @param column + * the column index, starting at 1. + * @return {@code true} if it is a monetary value, {@code false} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean isCurrency(int column) throws SQLException; + + /** + * Returns an indication of whether writing to the indexed column is + * guaranteed to be successful. + * + * @param column + * the column index, starting at 1. + * @return {@code true} if the write is guaranteed, {@code false} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean isDefinitelyWritable(int column) throws SQLException; + + /** + * Returns whether the indexed column is nullable. + * + * @param column + * the column index, starting at 1. + * @return {@code true} if it is nullable, {@code false} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public int isNullable(int column) throws SQLException; + + /** + * Returns an indication of whether writing to the indexed column is + * guaranteed to be unsuccessful. + * + * @param column + * the column index, starting at 1. + * @return {@code true} if the column is read-only, {@code false} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean isReadOnly(int column) throws SQLException; + + /** + * Returns an indication of whether the indexed column is searchable. + * + * @param column + * the column index, starting at 1. + * @return {@code true} if the indexed column is searchable, {@code false} + * otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean isSearchable(int column) throws SQLException; + + /** + * Returns an indication of whether the values contained in the indexed + * column are signed. + * + * @param column + * the column index, starting at 1. + * @return {@code true} if they are signed, {@code false} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean isSigned(int column) throws SQLException; + + /** + * Returns an indication of whether writing to the indexed column is + * possible. + * + * @param column + * the column index, starting at 1. + * @return {@code true} if it is possible to write, {@code false} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean isWritable(int column) throws SQLException; +} diff --git a/sql/src/main/java/java/sql/SQLData.java b/sql/src/main/java/java/sql/SQLData.java new file mode 100644 index 0000000..cae9d15 --- /dev/null +++ b/sql/src/main/java/java/sql/SQLData.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +/** + * An interface for the custom mapping of an SQL <i>User Defined Type</i> (UDT) + * to a Java class. The Java class object is added to the connection's type map + * paired with the SQL name of the corresponding UDT. + * <p> + * Usually within an implementation of {@code SQLData}, there is a corresponding + * field for every attribute of an SQL type, but only one field, if the type is + * SQL {@code DISTINCT}. When the UDT is returned within a {@code ResultSet}, it + * is accessed with the {@link ResultSet#getObject} method and is returned as an + * object which is an instance of the class defined by the {@code SQLData} + * mapping. The application can use this object just like any other Java object + * and can store changes back into the database using the + * {@link PreparedStatement#setObject} method which performs the reverse mapping + * into the SQL {@code UDT}. + * </p> + * Normally the implementation of a custom mapping is generated by + * a tool requiring the name of the SQL {@code UDT}, the name + * of the class which it is going to be mapped to, and the field names to which + * the UDT attributes are mapped. The tool can then implement the {@code + * SQLData}, {@code readSQL}, and {@code writeSQL} methods. {@code readSQL} reads + * attributes from an {@code SQLInput} object, and {@code writeSQL} writes them. + * This is done via {@code SQLInput} and {@code SQLOutput} method calls + * respectively. + * <p> + * Ordinarily an application would not call {@code SQLData} methods directly. + * Similarly {@code SQLInput} and {@code SQLOutput} methods are not usually + * called directly. + * </p> + * + * @since Android 1.0 + */ +public interface SQLData { + + /** + * Gets the SQL name of the <i>User Defined Type</i> (UDT) that this object + * represents. This method, usually invoked by the JDBC driver, retrieves + * the name of the UDT instance associated with this {@code SQLData} object. + * + * @return a string with UDT type name for this object mapping, passed to + * {@code readSQL} when the object was created. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public String getSQLTypeName() throws SQLException; + + /** + * Reads data from the database into this object. This method follows these + * steps: + * <p> + * <ul> + * <li>Utilize the passed input stream to read the attributes or entries of + * the SQL type</li> + * <li>This is carried out by reading each entry from the input stream, + * ordered as they are in the SQL definition.</li> + * <li>Assign the data to the appropriate fields or elements. This is done + * by calling the relevant reader method for the type involved (e.g. {@code + * SQLInput.readString}, {@code SQLInputreadBigDecimal}). If the type is + * distinct, then read its only data entry. For structured types, read every + * entry.</li> + * </ul> + * </p> + * <p> + * The supplied input stream is typically initialized by the calling JDBC + * driver with the type map before {@code readSQL} is called. + * </p> + * + * @param stream + * the {@code SQLInput} stream from which the type map data is + * read for the custom mapping. + * @param typeName + * the SQL type name for the type which is being mapped. + * @throws SQLException + * if a database error occurs. + * @see SQLInput + * @since Android 1.0 + */ + public void readSQL(SQLInput stream, String typeName) throws SQLException; + + /** + * Writes the object to a supplied {@code SQLOutput} data stream, writing it + * out as an SQL value to the data source. + * <p> + * This method follows the following steps: + * <ul> + * <li>Write each attribute of the SQL type to the output stream.</li> + * <li>Write each item by calling a method on the output stream, in the + * order they appear in the SQL definition of the type. Use the appropriate + * {@code SQLOutput} methods (e.g. {@code writeInt}, {@code writeString}). + * Write a single data element for a distinct type. For a structured type, + * write a value for each attribute of the the SQL type.</li> + * </ul> + * </p> + * + * @param stream + * the {@code SQLOutput} stream to use to write out the data for + * the custom mapping. + * @throws SQLException + * if a database error occurs. + * @see SQLOutput + * @since Android 1.0 + */ + public void writeSQL(SQLOutput stream) throws SQLException; +} diff --git a/sql/src/main/java/java/sql/SQLException.java b/sql/src/main/java/java/sql/SQLException.java new file mode 100644 index 0000000..2cea139 --- /dev/null +++ b/sql/src/main/java/java/sql/SQLException.java @@ -0,0 +1,168 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.io.Serializable; + +/** + * An {@code Exception} class that is used in conjunction with JDBC operations. + * It provides information about problems encountered with database access and + * other problems related to JDBC + * <p> + * The {@code SQLException} class provides the following information: + * <ul> + * <li>A standard Java exception message, as a {@code String}</li> + * <li>An {@code SQLState} string. This is an error description string which + * follows either the SQL 99 conventions or the X/OPEN {@code SQLstate} + * conventions. The potential values of the {@code SQLState} string are + * described in each of the specifications. Which of the conventions is being + * used by the {@code SQLState} string can be discovered by using the {@code + * getSQLStateType} method of the {@code DatabaseMetaData} interface.</li> + * <li>An error code, an an integer. The error code is specific to each database + * vendor and is typically the error code returned by the database itself.</li> + * <li>A chain to a next {@code Exception}, if relevant, which can give access + * to additional error information.</li> + * </ul> + * </p> + * + * @see DatabaseMetaData + * + * @since Android 1.0 + */ +public class SQLException extends Exception implements Serializable { + + private static final long serialVersionUID = 2135244094396331484L; + + private String SQLState = null; + + private int vendorCode = 0; + + private SQLException next = null; + + /** + * Creates an {@code SQLException} object. The reason string is set to + * {@code null}, the {@code SQLState} string is set to {@code null} and the + * error code is set to 0. + */ + public SQLException() { + super(); + } + + /** + * Creates an {@code SQLException} object. The reason string is set to the given + * reason string, the {@code SQLState} string is set to {@code null} and the error code is + * set to 0. + * + * @param theReason + * the string to use as the Reason string + */ + public SQLException(String theReason) { + this(theReason, null, 0); + } + + /** + * Creates an {@code SQLException} object. The reason string is set to the + * given reason string, the {@code SQLState} string is set to the given + * {@code SQLState} string and the error code is set to 0. + * + * @param theReason + * the string to use as the reason string. + * @param theSQLState + * the string to use as the {@code SQLState} string. + * @since Android 1.0 + */ + public SQLException(String theReason, String theSQLState) { + this(theReason, theSQLState, 0); + } + + /** + * Creates an {@code SQLException} object. The reason string is set to the + * given reason string, the {@code SQLState} string is set to the given + * {@code SQLState} string and the error code is set to the given error code + * value. + * + * @param theReason + * the string to use as the reason string. + * @param theSQLState + * the string to use as the {@code SQLState} string. + * @param theErrorCode + * the integer value for the error code. + * @since Android 1.0 + */ + public SQLException(String theReason, String theSQLState, int theErrorCode) { + super(theReason); + SQLState = theSQLState; + vendorCode = theErrorCode; + } + + /** + * Returns the integer error code for this {@code SQLException}. + * + * @return The integer error code for this {@code SQLException}. The meaning + * of the code is specific to the vendor of the database. + * @since Android 1.0 + */ + public int getErrorCode() { + return vendorCode; + } + + /** + * Retrieves the {@code SQLException} chained to this {@code SQLException}, + * if any. + * + * @return The {@code SQLException} chained to this {@code SQLException}. + * {@code null} if there is no {@code SQLException} chained to this + * {@code SQLException}. + */ + public SQLException getNextException() { + return next; + } + + /** + * Retrieves the {@code SQLState} description string for this {@code + * SQLException} object. + * + * @return The {@code SQLState} string for this {@code SQLException} object. + * This is an error description string which follows either the SQL + * 99 conventions or the X/OPEN {@code SQLstate} conventions. The + * potential values of the {@code SQLState} string are described in + * each of the specifications. Which of the conventions is being + * used by the {@code SQLState} string can be discovered by using + * the {@code getSQLStateType} method of the {@code + * DatabaseMetaData} interface. + */ + public String getSQLState() { + return SQLState; + } + + /** + * Adds the SQLException to the end of this {@code SQLException} chain. + * + * @param ex + * the new {@code SQLException} to be added to the end of the + * chain. + * @since Android 1.0 + */ + public void setNextException(SQLException ex) { + if (next != null) { + next.setNextException(ex); + } else { + next = ex; + } + } +} diff --git a/sql/src/main/java/java/sql/SQLInput.java b/sql/src/main/java/java/sql/SQLInput.java new file mode 100644 index 0000000..b72c839 --- /dev/null +++ b/sql/src/main/java/java/sql/SQLInput.java @@ -0,0 +1,341 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.math.BigDecimal; +import java.io.Reader; +import java.io.InputStream; +import java.net.URL; + +/** + * The {@code SQLInput} interface defines operations which apply to a type of + * input stream which carries a series of values representing an instance of + * an SQL structured type or SQL distinct type. + * <p> + * This interface is used to define custom mappings of SQL <i>User Defined + * Types</i> (UDTs) to Java classes. It is used by JDBC drivers, therefore + * application programmers do not normally use the {@code SQLInput} methods + * directly. Reader methods such as {@code readLong} and {@code readBytes} + * provide means to read values from an {@code SQLInput} stream. + * </p><p> + * When the {@code getObject} method is called with an object which implements + * the {@code SQLData} interface, the JDBC driver determines the SQL type of the + * UDT being mapped by calling the {@code SQLData.getSQLType} method. The driver + * creates an instance of an {@code SQLInput} stream, filling the stream with + * the attributes of the UDT. The {@code SQLInput} stream is passed to the + * {@code SQLData.readSQL} method which then calls the {@code SQLInput} reader + * methods to read the attributes. + * </p> + * + * @see SQLData + * + * @since Android 1.0 + */ +public interface SQLInput { + + /** + * Returns the next attribute in the stream in the form of a {@code String}. + * + * @return the next attribute. {@code null} if the value is SQL {@code NULL}. + * + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public String readString() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code boolean} + * . + * + * @return the next attribute as a {@code boolean}. {@code false} if the + * value is SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean readBoolean() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code byte}. + * + * @return the next attribute as a {@code byte}. 0 if the value is SQL + * {@code NULL}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public byte readByte() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code short}. + * + * @return the next attribute as a {@code short}. 0 if the value is SQL + * {@code NULL}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public short readShort() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of an {@code int}. + * + * @return the next attribute as an {@code int}. 0 if the value is SQL + * {@code NULL}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public int readInt() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code long}. + * + * @return the next attribute as a {@code long}. 0 if the value is SQL + * {@code NULL}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public long readLong() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code float}. + * + * @return the next attribute as a {@code float}. 0 if the value is SQL + * {@code NULL}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public float readFloat() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code double}. + * + * @return the next attribute as a {@code double}. 0 if the value is SQL + * {@code NULL}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public double readDouble() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code + * java.math.BigDecimal}. + * + * @return the attribute as a {@code java.math.BigDecimal}. {@code null} if + * the read returns SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @see java.math.BigDecimal + * @since Android 1.0 + */ + public BigDecimal readBigDecimal() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a byte array. + * + * @return the attribute as a byte array. {@code null} if the read returns + * SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public byte[] readBytes() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code + * java.sql.Date}. + * + * @return the next attribute as a {@code java.sql.Date}. {@code null} if + * the value is SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @see Date + * @since Android 1.0 + */ + public Date readDate() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code + * java.sql.Time}. + * + * @return the attribute as a {@code java.sql.Time}. {@code null} if the + * read returns SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @see Time + * @since Android 1.0 + */ + public Time readTime() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code + * java.sql.Timestamp}. + * + * @return the attribute as a {@code java.sql.Timestamp}. {@code null} if + * the read returns SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @see Timestamp + * @since Android 1.0 + */ + public Timestamp readTimestamp() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a Unicode + * character stream embodied as a {@code java.io.Reader}. + * + * @return the next attribute as a {@code java.io.Reader}. {@code null} if + * the value is SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @see java.io.Reader + * @since Android 1.0 + */ + public Reader readCharacterStream() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of an ASCII + * character stream embodied as a {@code java.io.InputStream}. + * + * @return the next attribute as a {@code java.io.InputStream}. {@code null} + * if the value is SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @see java.io.InputStream + * @since Android 1.0 + */ + public InputStream readAsciiStream() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a stream of bytes + * embodied as a {@code java.io.InputStream}. + * + * @return the next attribute as a {@code java.io.InputStream}. {@code null} + * if the value is SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @see java.io.InputStream + * @since Android 1.0 + */ + public InputStream readBinaryStream() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code + * java.lang.Object}. + * <p> + * The type of the {@code Object} returned is determined by the type mapping + * for this JDBC driver, including any customized mappings, if present. A + * type map is given to the {@code SQLInput} by the JDBC driver before the + * {@code SQLInput} is given to the application. + * </p> + * <p> + * If the attribute is an SQL structured or distinct type, its SQL type is + * determined. If the stream's type map contains an element for that SQL + * type, the driver creates an object for the relevant type and invokes the + * method {@code SQLData.readSQL} on it, which reads supplementary data from + * the stream using whichever protocol is defined for that method. + * </p> + * + * @return the next attribute as an Object. {@code null} if the value is SQL + * {@code NULL}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public Object readObject() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code + * java.sql.Ref}. + * + * @return the next attribute as a {@code java.sql.Ref}. {@code null} if the + * value is SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @see Ref + * @since Android 1.0 + */ + public Ref readRef() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code + * java.sql.Blob}. + * + * @return the next attribute as a {@code java.sql.Blob}. {@code null} if + * the value is SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public Blob readBlob() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code + * java.sql.Clob}. + * + * @return the next attribute as a {@code java.sql.Clob}. {@code null} if + * the value is SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @see Clob + * @since Android 1.0 + */ + public Clob readClob() throws SQLException; + + /** + * Returns the next attribute in the stream in the form of a {@code + * java.sql.Array}. + * + * @return the next attribute as an {@code Array}. {@code null} if the value + * is SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @see Array + * @since Android 1.0 + */ + public Array readArray() throws SQLException; + + /** + * Reports whether the last value read was SQL {@code NULL}. + * + * @return {@code true} if the last value read was SQL {@code NULL}, {@code + * false} otherwise. + * @throws SQLException + * if there is a database error. + * @since Android 1.0 + */ + public boolean wasNull() throws SQLException; + + /** + * Reads the next attribute in the stream (SQL DATALINK value) and returns + * it as a {@code java.net.URL} object. + * + * @return the next attribute as a {@code java.net.URL}. {@code null} if the + * value is SQL {@code NULL}. + * @throws SQLException + * if there is a database error. + * @see java.net.URL + * @since Android 1.0 + */ + public URL readURL() throws SQLException; +} diff --git a/sql/src/main/java/java/sql/SQLOutput.java b/sql/src/main/java/java/sql/SQLOutput.java new file mode 100644 index 0000000..9fded5e --- /dev/null +++ b/sql/src/main/java/java/sql/SQLOutput.java @@ -0,0 +1,321 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.URL; + +/** + * The interface for an output stream used to write attributes of an SQL <i>User + * Defined Type</i> (UDT) to the database. This interface is used for custom + * mapping of types and is called by the JDBC driver. It is not intended to be + * used by applications. + * <p> + * When an object which implements the {@code SQLData} interface is used as an + * argument to an SQL statement, the JDBC driver calls the method {@code + * SQLData.getSQLType} to establish the type of the SQL UDT that is being + * passed. The driver then creates an {@code SQLOutput} stream and passes it to + * the {@code SQLData.writeSQL} method, which in turn uses the appropriate + * {@code SQLOutput} writer methods to write the data from the {@code SQLData} + * object into the stream according to the defined mapping. + * </p> + * + * @see SQLData + * + * @since Android 1.0 + */ +public interface SQLOutput { + + /** + * Write a {@code String} value into the output stream. + * + * @param theString + * the {@code String} to write. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeString(String theString) throws SQLException; + + /** + * Write a {@code boolean} value into the output stream. + * + * @param theFlag + * the {@code boolean} value to write. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeBoolean(boolean theFlag) throws SQLException; + + /** + * Write a {@code byte} value into the output stream. + * + * @param theByte + * the {@code byte} value to write. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeByte(byte theByte) throws SQLException; + + /** + * Write a {@code short} value into the output stream. + * + * @param theShort + * the {@code short} value to write. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeShort(short theShort) throws SQLException; + + /** + * Write an {@code int} value into the output stream. + * + * @param theInt + * the {@code int} value to write. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeInt(int theInt) throws SQLException; + + /** + * Write a {@code long} value into the output stream. + * + * @param theLong + * the {@code long} value to write. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeLong(long theLong) throws SQLException; + + /** + * Write a {@code float} value into the output stream. + * + * @param theFloat + * the {@code float} value to write. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeFloat(float theFloat) throws SQLException; + + /** + * Write a {@code double} value into the output stream. + * + * @param theDouble + * the {@code double} value to write. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeDouble(double theDouble) throws SQLException; + + /** + * Write a {@code java.math.BigDecimal} value into the output stream. + * + * @param theBigDecimal + * the {@code BigDecimal} value to write. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeBigDecimal(BigDecimal theBigDecimal) throws SQLException; + + /** + * Write an array of bytes into the output stream. + * + * @param theBytes + * the array of bytes to write. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeBytes(byte[] theBytes) throws SQLException; + + /** + * Write a {@code java.sql.Date} value into the output stream. + * + * @param theDate + * the {@code Date} value to write. + * @throws SQLException + * if a database error occurs. + * @see Date + * @since Android 1.0 + */ + public void writeDate(Date theDate) throws SQLException; + + /** + * Write a {@code java.sql.Time} value into the output stream. + * + * @param theTime + * the {@code Time} value to write. + * @throws SQLException + * if a database error occurs. + * @see Time + * @since Android 1.0 + */ + public void writeTime(Time theTime) throws SQLException; + + /** + * Write a {@code java.sql.Timestamp} value into the output stream. + * + * @param theTimestamp + * the {@code Timestamp} value to write. + * @throws SQLException + * if a database error occurs. + * @see Timestamp + * @since Android 1.0 + */ + public void writeTimestamp(Timestamp theTimestamp) throws SQLException; + + /** + * Write a stream of unicode characters into the output stream. + * + * @param theStream + * the stream of unicode characters to write, as a {@code + * java.io.Reader} object. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeCharacterStream(Reader theStream) throws SQLException; + + /** + * Write a stream of ASCII characters into the output stream. + * + * @param theStream + * the stream of ASCII characters to write, as a {@code + * java.io.InputStream} object + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeAsciiStream(InputStream theStream) throws SQLException; + + /** + * Write a stream of uninterpreted bytes into the output stream. + * + * @param theStream + * the stream of bytes to write, as a {@code java.io.InputStream} + * object + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public void writeBinaryStream(InputStream theStream) throws SQLException; + + /** + * Write an {@code SQLData} object into the output stream. + * <p> + * If the {@code SQLData} object is null, writes {@code NULL} to the stream. + * </p> + * <p> + * Otherwise, calls the {@code SQLData.writeSQL} method of the object, which + * writes the object's attributes to the stream by calling the appropriate + * SQLOutput writer methods for each attribute, in order. The order of the + * attributes is the order they are listed in the SQL definition of the User + * Defined Type. + * </p> + * + * @param theObject + * the {@code SQLData} object to write. + * @throws SQLException + * if a database error occurs. + * @see SQLData + * @since Android 1.0 + */ + public void writeObject(SQLData theObject) throws SQLException; + + /** + * Write an SQL {@code Ref} value into the output stream. + * + * @param theRef + * the {@code java.sql.Ref} object to write. + * @throws SQLException + * if a database error occurs. + * @see Ref + * @since Android 1.0 + */ + public void writeRef(Ref theRef) throws SQLException; + + /** + * Write an SQL {@code Blob} value into the output stream. + * + * @param theBlob + * the {@code java.sql.Blob} object to write. + * @throws SQLException + * if a database error occurs. + * @see Blob + * @since Android 1.0 + */ + public void writeBlob(Blob theBlob) throws SQLException; + + /** + * Write an SQL {@code Clob} value into the output stream. + * + * @param theClob + * the {@code java.sql.Clob} object to write. + * @throws SQLException + * if a database error occurs. + * @see Clob + * @since Android 1.0 + */ + public void writeClob(Clob theClob) throws SQLException; + + /** + * Write an SQL {@code Struct} value into the output stream. + * + * @param theStruct + * the {@code java.sql.Struct} object to write. + * @throws SQLException + * if a database error occurs. + * @see Struct + * @since Android 1.0 + */ + public void writeStruct(Struct theStruct) throws SQLException; + + /** + * Write an SQL {@code Array} value into the output stream. + * + * @param theArray + * the {@code java.sql.Array} object to write. + * @throws SQLException + * if a database error occurs. + * @see Array + * @since Android 1.0 + */ + public void writeArray(Array theArray) throws SQLException; + + /** + * Write an SQL {@code DATALINK} value into the output stream. + * + * @param theURL + * the datalink value as a {@code java.net.URL} to write. + * @throws SQLException + * if a database error occurs. + * @see java.net.URL + * @since Android 1.0 + */ + public void writeURL(URL theURL) throws SQLException; +} diff --git a/sql/src/main/java/java/sql/SQLPermission.java b/sql/src/main/java/java/sql/SQLPermission.java new file mode 100644 index 0000000..a9f82d1 --- /dev/null +++ b/sql/src/main/java/java/sql/SQLPermission.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.io.Serializable; +import java.security.BasicPermission; +import java.security.Guard; + +/** + * A Permission relating to security access control in the {@code java.sql} + * package. + * <p> + * Currently, the only permission supported has the name " {@code setLog}". The + * {@code setLog} permission controls whether a Java application or applet can + * open a logging stream using the {@code DriverManager.setLogWriter} method or + * the {@code DriverManager.setLogStream} method. This is a potentially + * dangerous operation since the logging stream can contain sensitive + * information such as usernames and passwords. + * </p> + * + * @see DriverManager + * + * @since Android 1.0 + */ +public final class SQLPermission extends BasicPermission implements Guard, + Serializable { + + private static final long serialVersionUID = -1439323187199563495L; + + /** + * Creates a new {@code SQLPermission} object with the specified name. + * + * @param name + * the name to use for this {@code SQLPermission}. + */ + public SQLPermission(String name) { + super(name); + } + + /** + * Creates a new {@code SQLPermission} object with the specified name. + * + * @param name + * is the name of the {@code SQLPermission}. Currently only + * {@code "setLog"} is allowed. + * @param actions + * is currently unused and should be set to {@code null}. + */ + public SQLPermission(String name, String actions) { + super(name, null); + } +} diff --git a/sql/src/main/java/java/sql/SQLWarning.java b/sql/src/main/java/java/sql/SQLWarning.java new file mode 100644 index 0000000..de94da5 --- /dev/null +++ b/sql/src/main/java/java/sql/SQLWarning.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.io.Serializable; + +import org.apache.harmony.sql.internal.nls.Messages; + +/** + * An exception class that holds information about Database access warnings. + * + * @since Android 1.0 + */ +public class SQLWarning extends SQLException implements Serializable { + + private static final long serialVersionUID = 3917336774604784856L; + + /** + * Creates an {@code SQLWarning} object. The reason string is set to {@code + * null}, the {@code SQLState} string is set to {@code null} and the error + * code is set to 0. + * + * @since Android 1.0 + */ + public SQLWarning() { + super(); + } + + /** + * Creates an {@code SQLWarning} object. The reason string is set to the + * given reason string, the {@code SQLState} string is set to {@code null} + * and the error code is set to 0. + * + * @param theReason + * the reason why this warning is issued. + * @since Android 1.0 + */ + public SQLWarning(String theReason) { + super(theReason); + } + + /** + * Creates an {@code SQLWarning} object. The reason string is set to the + * given reason string, the {@code SQLState} string is set to the given + * {@code SQLState} string and the error code is set to 0. + * + * @param theReason + * the reason why this warning is issued. + * @param theSQLState + * the string to use as the {@code SQLState} string. + */ + public SQLWarning(String theReason, String theSQLState) { + super(theReason, theSQLState); + } + + /** + * Creates an {@code SQLWarning} object. The reason string is set to the + * given reason string, the {@code SQLState} string is set to the given + * {@code SQLState} string and the error code is set to the given error code + * value. + * + * @param theReason + * the reason why this warning is issued. + * @param theSQLState + * the X/Open standard specifc error code. + * @param theErrorCode + * a vendor specific error code. + * @since Android 1.0 + */ + public SQLWarning(String theReason, String theSQLState, int theErrorCode) { + super(theReason, theSQLState, theErrorCode); + } + + /** + * Gets the next {@code SQLWarning} chained to this {@code SQLWarning} object. + * + * @return the {@code SQLWarning} chained to this {@code SQLWarning}. + * {@code null} if no {@code SQLWarning} is chained to this {@code + * SQLWarning}. + * @since Android 1.0 + */ + public SQLWarning getNextWarning() { + SQLException next = super.getNextException(); + if (next == null) { + return null; + } + if (next instanceof SQLWarning) { + return (SQLWarning) next; + } + throw new Error(Messages.getString("sql.8")); //$NON-NLS-1$ + } + + /** + * Chains a supplied {@code SQLWarning} to this {@code SQLWarning}. + * + * @param w + * the {@code SQLWarning} linked to this {@code SQLWarning}. + * @since Android 1.0 + */ + public void setNextWarning(SQLWarning w) { + super.setNextException(w); + } +} diff --git a/sql/src/main/java/java/sql/Savepoint.java b/sql/src/main/java/java/sql/Savepoint.java new file mode 100644 index 0000000..42b4a17 --- /dev/null +++ b/sql/src/main/java/java/sql/Savepoint.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +/** + * A savepoint is an instant during the current transaction that can be utilized + * by a rollback via the {@link Connection#rollback} command. Rolling back to a + * particular savepoint means that all changes that occurred after that + * savepoint are undone. + * + * @since Android 1.0 + */ +public interface Savepoint { + + /** + * Returns the constructed ID for this savepoint. + * + * @return the ID for this savepoint. + * @throws SQLException + * if an error occurrs accessing the database. + * @since Android 1.0 + */ + public int getSavepointId() throws SQLException; + + /** + * Returns the name for this savepoint. + * + * @return the name of this savepoint. + * @throws SQLException + * if an error occurrs accessing the database. + * @since Android 1.0 + */ + public String getSavepointName() throws SQLException; +} diff --git a/sql/src/main/java/java/sql/Statement.java b/sql/src/main/java/java/sql/Statement.java new file mode 100644 index 0000000..4985a9e --- /dev/null +++ b/sql/src/main/java/java/sql/Statement.java @@ -0,0 +1,716 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +/** + * Interface used for executing static SQL statements to retrieve query results. + * The resulting table rows are returned as {@code ResultSet}s. For any given + * {@code Statement} object, only one {@code ResultSet} can be opened at one + * time. A call to any of the execution methods of {@code Statement} will cause + * any previously created {@code ResultSet} object for that {@code Statement} to + * be closed implicitly. + * <p> + * To have multiple {@code ResultSet} objects opened concurrently, multiple + * {@code Statement} objects must be created and then executed. + * </p> + * <p> + * To obtain such an executable statement one needs to invoke {@code + * Connection#createStatement}. + * </p> + * + * @see ResultSet + * @see Connection#createStatement + * + * @since Android 1.0 + */ +public interface Statement { + + /** + * Passing this constant to {@link #getMoreResults} implies that all {@code + * ResultSet} objects previously kept open should be closed. + * + * @since Android 1.0 + */ + public static final int CLOSE_ALL_RESULTS = 3; + + /** + * Passing this constant to {@link #getMoreResults} implies that the current + * {@code ResultSet} object should be closed. + * + * @since Android 1.0 + */ + public static final int CLOSE_CURRENT_RESULT = 1; + + /** + * Indicates that an error was encountered during execution of a batch + * statement. + * + * @since Android 1.0 + */ + public static final int EXECUTE_FAILED = -3; + + /** + * Passing this constant to <i>getMoreResults</i> implies that the current + * {@code ResultSet} object should not be closed. + * + * @since Android 1.0 + */ + public static final int KEEP_CURRENT_RESULT = 2; + + /** + * Indicates that generated keys should not be accessible for retrieval. + * + * @since Android 1.0 + */ + public static final int NO_GENERATED_KEYS = 2; + + /** + * Indicates that generated keys should be accessible for retrieval. + * + * @since Android 1.0 + */ + public static final int RETURN_GENERATED_KEYS = 1; + + /** + * Indicates that a batch statement was executed with a successful result, + * but a count of the number of rows it affected is unavailable. + * + * @since Android 1.0 + */ + public static final int SUCCESS_NO_INFO = -2; + + /** + * Adds a specified SQL command to the list of commands for this {@code + * Statement}. + * <p> + * The list of commands is executed by invoking the {@code executeBatch} + * method. + * </p> + * + * @param sql + * the SQL command as a String. Typically an {@code INSERT} or + * {@code UPDATE} statement. + * @throws SQLException + * if an error occurs accessing the database or the database + * does not support batch updates. + * @since Android 1.0 + */ + public void addBatch(String sql) throws SQLException; + + /** + * Cancels this statement's execution if both the database and the JDBC + * driver support aborting an SQL statement in flight. This method can be + * used by one thread to stop a statement that is executed on another + * thread. + * + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void cancel() throws SQLException; + + /** + * Clears the current list of SQL commands for this statement. + * + * @throws SQLException + * if an error occurs accessing the database or the database + * does not support batch updates. + * @since Android 1.0 + */ + public void clearBatch() throws SQLException; + + /** + * Clears all {@code SQLWarnings} from this statement. + * + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void clearWarnings() throws SQLException; + + /** + * Releases this statement's database and JDBC driver resources. + * <p> + * Using this method to release these resources as soon as possible is + * strongly recommended. + * </p> + * <p> + * One should not rely on the resources being automatically released when + * finalized during garbage collection. Doing so can result in unpredictable + * behavior for the application. + * </p> + * + * @throws SQLException + * if an error occurs accessing the database. + */ + public void close() throws SQLException; + + /** + * Executes a supplied SQL statement. This may return multiple {@code + * ResultSet}s. + * <p> + * Use the {@code getResultSet} or {@code getUpdateCount} methods to get the + * first result and {@code getMoreResults} to get any subsequent results. + * </p> + * + * @param sql + * the SQL statement to execute + * @return {@code true} if the first result is a {@code ResultSet}, {@code + * false} if the first result is an update count or if there is no + * result. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public boolean execute(String sql) throws SQLException; + + /** + * Executes a supplied SQL statement. This may return multiple {@code + * ResultSet}s. This method allows control of whether auto-generated Keys + * should be made available for retrieval, if the SQL statement is an + * {@code INSERT} statement. + * <p> + * Use the {@code getResultSet} or {@code getUpdateCount} methods to get the + * first result and {@code getMoreResults} to get any subsequent results. + * </p> + * + * @param sql + * the SQL statement to execute. + * @param autoGeneratedKeys + * a flag indicating whether to make auto generated keys + * available for retrieval. This parameter must be one of {@code + * Statement.NO_GENERATED_KEYS} or {@code + * Statement.RETURN_GENERATED_KEYS}. + * @return {@code true} if results exists and the first result is a {@code + * ResultSet}, {@code false} if the first result is an update count + * or if there is no result. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public boolean execute(String sql, int autoGeneratedKeys) + throws SQLException; + + /** + * Executes the supplied SQL statement. This may return multiple {@code + * ResultSet}s. This method allows retrieval of auto generated keys + * specified by the supplied array of column indexes, if the SQL statement + * is an {@code INSERT} statement. + * <p> + * Use the {@code getResultSet} or {@code getUpdateCount} methods to get the + * first result and {@code getMoreResults} to get any subsequent results. + * </p> + * + * @param sql + * the SQL statement to execute. + * @param columnIndexes + * an array of indexes of the columns in the inserted row which + * should be made available for retrieval via the {@code + * getGeneratedKeys} method. + * @return {@code true} if the first result is a {@code ResultSet}, {@code + * false} if the first result is an update count or if there is no + * result. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public boolean execute(String sql, int[] columnIndexes) throws SQLException; + + /** + * Executes the supplied SQL statement. This may return multiple {@code + * ResultSet}s. This method allows retrieval of auto generated keys + * specified by the supplied array of column indexes, if the SQL statement + * is an {@code INSERT} statement. + * <p> + * Use the {@code getResultSet} or {@code getUpdateCount} methods to get the + * first result and {@code getMoreResults} to get any subsequent results. + * </p> + * + * @param sql + * the SQL statement to execute. + * @param columnNames + * an array of column names in the inserted row which should be + * made available for retrieval via the {@code getGeneratedKeys} + * method. + * @return {@code true} if the first result is a {@code ResultSet}, {@code + * false} if the first result is an update count or if there is no + * result + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public boolean execute(String sql, String[] columnNames) + throws SQLException; + + /** + * Submits a batch of SQL commands to the database. Returns an array of + * update counts, if all the commands execute successfully. + * <p> + * If one of the commands in the batch fails, this method can throw a + * {@link BatchUpdateException} and the JDBC driver may or may not process + * the remaining commands. The JDBC driver must behave consistently with the + * underlying database, following the "all or nothing" principle. If the + * driver continues processing, the array of results returned contains the + * same number of elements as there are commands in the batch, with a + * minimum of one of the elements having the {@code EXECUTE_FAILED} value. + * + * @return an array of update counts, with one entry for each command in the + * batch. The elements are ordered according to the order in which + * the commands were added to the batch. + * <p> + * <ol> + * <li>If the value of an element is ≥ 0, the corresponding + * command completed successfully and the value is the <i>update + * count</i> (the number of rows in the database affected by the + * command) for that command.</li> + * <li>If the value is {@code SUCCESS_NO_INFO}, the command + * completed successfully but the number of rows affected is + * unknown. + * <li> + * <li>If the value is {@code EXECUTE_FAILED}, the command failed. + * </ol> + * @throws SQLException + * if an error occurs accessing the database. + */ + public int[] executeBatch() throws SQLException; + + /** + * Executes a supplied SQL statement. Returns a single {@code ResultSet}. + * + * @param sql + * an SQL statement to execute. Typically a {@code SELECT} + * statement + * @return a {@code ResultSet} containing the data produced by the SQL + * statement. Never null. + * @throws SQLException + * if an error occurs accessing the database or if the statement + * produces anything other than a single {@code ResultSet}. + * @since Android 1.0 + */ + public ResultSet executeQuery(String sql) throws SQLException; + + /** + * Executes the supplied SQL statement. The statement may be an {@code + * INSERT}, {@code UPDATE} or {@code DELETE} statement or a statement which + * returns nothing. + * + * @param sql + * an SQL statement to execute - an SQL {@code INSERT}, {@code + * UPDATE}, {@code DELETE} or a statement which returns nothing + * @return the count of updated rows, or 0 for a statement that returns + * nothing. + * @throws SQLException + * if an error occurs accessing the database or if the statement + * produces a {@code ResultSet}. + * @since Android 1.0 + */ + public int executeUpdate(String sql) throws SQLException; + + /** + * Executes the supplied SQL statement. This method allows control of + * whether auto-generated Keys should be made available for retrieval. + * + * @param sql + * an SQL statement to execute - an SQL {@code INSERT}, {@code + * UPDATE}, {@code DELETE} or a statement which does not return + * anything. + * @param autoGeneratedKeys + * a flag that indicates whether to allow retrieval of auto + * generated keys. Parameter must be one of {@code + * Statement.RETURN_GENERATED_KEYS} or {@code + * Statement.NO_GENERATED_KEYS} + * @return the number of updated rows, or 0 if the statement returns + * nothing. + * @throws SQLException + * if an error occurs accessing the database or if the statement + * produces a {@code ResultSet}. + * @since Android 1.0 + */ + public int executeUpdate(String sql, int autoGeneratedKeys) + throws SQLException; + + /** + * Executes the supplied SQL statement. This method allows retrieval of auto + * generated keys specified by the supplied array of column indexes. + * + * @param sql + * an SQL statement to execute - an SQL {@code INSERT}, {@code + * UPDATE}, {@code DELETE} or a statement which returns nothing + * @param columnIndexes + * an array of indexes of the columns in the inserted row which + * should be made available for retrieval via the {@code + * getGeneratedKeys} method. + * @return the count of updated rows, or 0 for a statement that returns + * nothing. + * @throws SQLException + * if an error occurs accessing the database or if the statement + * produces a {@code ResultSet}. + * @since Android 1.0 + */ + public int executeUpdate(String sql, int[] columnIndexes) + throws SQLException; + + /** + * Executes the supplied SQL statement. This method allows retrieval of auto + * generated keys specified by the supplied array of column names. + * + * @param sql + * an SQL statement to execute - an SQL {@code INSERT}, {@code + * UPDATE}, {@code DELETE} or a statement which returns nothing + * @param columnNames + * an array of column names in the inserted row which should be + * made available for retrieval via the {@code getGeneratedKeys} + * method. + * @return the count of updated rows, or 0 for a statement that returns + * nothing. + * @throws SQLException + * if an error occurs accessing the database or if the statement + * produces a {@code ResultSet}. + * @since Android 1.0 + */ + public int executeUpdate(String sql, String[] columnNames) + throws SQLException; + + /** + * Gets the {@code Connection} object which created this statement. + * + * @return the {@code Connection} through which this statement is + * transmitted to the database. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public Connection getConnection() throws SQLException; + + /** + * Gets the default direction for fetching rows for {@code ResultSet}s + * generated from this statement. + * + * @return the default fetch direction, one of: + * <ul> + * <li>ResultSet.FETCH_FORWARD</li> <li>ResultSet.FETCH_REVERSE</li> + * <li>ResultSet.FETCH_UNKNOWN</li> + * </ul> + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public int getFetchDirection() throws SQLException; + + /** + * Gets the default number of rows for a fetch for the {@code ResultSet} + * objects returned from this statement. + * + * @return the default fetch size for {@code ResultSet}s produced by this + * statement. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public int getFetchSize() throws SQLException; + + /** + * Returns auto generated keys created by executing this statement. + * + * @return a {@code ResultSet} containing the auto generated keys - empty if + * no keys are generated by this statement. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public ResultSet getGeneratedKeys() throws SQLException; + + /** + * Gets the maximum number of bytes which can be returned as values from + * character and binary type columns in a {@code ResultSet} derived from this + * statement. This limit applies to {@code BINARY}, {@code VARBINARY}, + * {@code LONGVARBINARY}, {@code CHAR}, {@code VARCHAR}, and {@code + * LONGVARCHAR} types. Any data exceeding the maximum size is abandoned + * without announcement. + * + * @return the current size limit, where {@code 0} means that there is no + * limit. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public int getMaxFieldSize() throws SQLException; + + /** + * Gets the maximum number of rows that a {@code ResultSet} can contain when + * produced from this statement. If the limit is exceeded, the excess rows + * are discarded silently. + * + * @return the current row limit, where {@code 0} means that there is no + * limit. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public int getMaxRows() throws SQLException; + + /** + * Moves to this statement's next result. Returns {@code true} if it is a + * {@code ResultSet}. Any current {@code ResultSet} objects previously + * obtained with {@code getResultSet()} are closed implicitly. + * + * @return {@code true} if the next result is a {@code ResultSet}, {@code + * false} if the next result is not a {@code ResultSet} or if there + * are no more results. Note that if there is no more data, this + * method will return {@code false} and {@code getUpdateCount} will + * return -1. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public boolean getMoreResults() throws SQLException; + + /** + * Moves to this statement's next result. Returns {@code true} if the next + * result is a {@code ResultSet}. Any current {@code ResultSet} objects + * previously obtained with {@code getResultSet()} are handled as indicated + * by a supplied Flag parameter. + * + * @param current + * a flag indicating what to do with existing {@code ResultSet}s. + * This parameter must be one of {@code + * Statement.CLOSE_ALL_RESULTS}, {@code + * Statement.CLOSE_CURRENT_RESULT} or {@code + * Statement.KEEP_CURRENT_RESULT}. + * @return {@code true} if the next result exists and is a {@code ResultSet} + * , {@code false} if the next result is not a {@code ResultSet} or + * if there are no more results. Note that if there is no more data, + * this method will return {@code false} and {@code getUpdateCount} + * will return -1. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public boolean getMoreResults(int current) throws SQLException; + + /** + * Gets the timeout value for the statement's execution time. The JDBC + * driver will wait up to this value for the execution to complete - after + * the limit is exceeded an SQL {@code Exception} is thrown. + * + * @return the current query timeout value, where {@code 0} indicates that + * there is no current timeout. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public int getQueryTimeout() throws SQLException; + + /** + * Gets the current result. Should only be called once per result. + * + * @return the {@code ResultSet} for the current result. {@code null} if the + * result is an update count or if there are no more results. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public ResultSet getResultSet() throws SQLException; + + /** + * Gets the concurrency setting for {@code ResultSet} objects generated by + * this statement. + * + * @return {@code ResultSet.CONCUR_READ_ONLY} or {@code + * ResultSet.CONCUR_UPDATABLE}. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public int getResultSetConcurrency() throws SQLException; + + /** + * Gets the cursor hold setting for {@code ResultSet} objects generated by + * this statement. + * + * @return {@code ResultSet.HOLD_CURSORS_OVER_COMMIT} or {@code + * ResultSet.CLOSE_CURSORS_AT_COMMIT} + * @throws SQLException + * if there is an error while accessing the database. + * @since Android 1.0 + */ + public int getResultSetHoldability() throws SQLException; + + /** + * Gets the {@code ResultSet} type setting for {@code ResultSet}s derived + * from this statement. + * + * @return {@code ResultSet.TYPE_FORWARD_ONLY} for a {@code ResultSet} where + * the cursor can only move forwards, {@code + * ResultSet.TYPE_SCROLL_INSENSITIVE} for a {@code ResultSet} which + * is scrollable but is not sensitive to changes made by others, + * {@code ResultSet.TYPE_SCROLL_SENSITIVE} for a {@code ResultSet} + * which is scrollable but is sensitive to changes made by others. + * @throws SQLException + * if there is an error accessing the database. + * @since Android 1.0 + */ + public int getResultSetType() throws SQLException; + + /** + * Gets an update count for the current result if it is not a {@code + * ResultSet}. + * + * @return the current result as an update count. {@code -1} if the current + * result is a {@code ResultSet} or if there are no more results. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public int getUpdateCount() throws SQLException; + + /** + * Retrieves the first {@code SQLWarning} reported by calls on this + * statement. If there are multiple warnings, subsequent warnings are + * chained to the first one. The chain of warnings is cleared each time the + * statement is executed. + * <p> + * Warnings associated with reads from the {@code ResultSet} returned from + * executing the statement will be attached to the {@code ResultSet}, not the + * statement object. + * </p> + * + * @return an SQLWarning, null if there are no warnings + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public SQLWarning getWarnings() throws SQLException; + + /** + * Sets the SQL cursor name. This name is used by subsequent statement + * execute methods. + * <p> + * Cursor names must be unique within one Connection. + * </p> + * <p> + * With the cursor name set, it can then be used in SQL positioned + * update or delete statements to determine the current row in a {@code + * ResultSet} generated from this statement. The positioned update or delete + * must be done with a different statement than this one. + * </p> + * + * @param name + * the Cursor name as a string, + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setCursorName(String name) throws SQLException; + + /** + * Sets Escape Processing mode. + * <p> + * If Escape Processing is on, the JDBC driver will do escape substitution + * on an SQL statement before sending it for execution. This does not apply + * to {@link PreparedStatement}s since they are processed when created, + * before this method can be called. + * </p> + * + * @param enable + * {@code true} to set escape processing mode <i>on</i>, {@code + * false} to turn it <i>off</i>. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setEscapeProcessing(boolean enable) throws SQLException; + + /** + * Sets the fetch direction - a hint to the JDBC driver about the direction + * of processing of rows in {@code ResultSet}s created by this statement. + * The default fetch direction is {@code FETCH_FORWARD}. + * + * @param direction + * which fetch direction to use. This parameter should be one of + * <ul> + * <li>{@code ResultSet.FETCH_UNKNOWN}</li> + * <li>{@code ResultSet.FETCH_FORWARD}</li> + * <li>{@code ResultSet.FETCH_REVERSE}</li> + * </ul> + * @throws SQLException + * if there is an error while accessing the database or if the + * fetch direction is unrecognized. + */ + public void setFetchDirection(int direction) throws SQLException; + + /** + * Sets the fetch size. This is a hint to the JDBC driver about how many + * rows should be fetched from the database when more are required by + * application processing. + * + * @param rows + * the number of rows that should be fetched. {@code 0} tells the driver + * to ignore the hint. Should be less than {@code getMaxRows} for + * this statement. Should not be negative. + * @throws SQLException + * if an error occurs accessing the database, or if the rows + * parameter is out of range. + * @since Android 1.0 + */ + public void setFetchSize(int rows) throws SQLException; + + /** + * Sets the maximum number of bytes for {@code ResultSet} columns that + * contain character or binary values. This applies to {@code BINARY}, + * {@code VARBINARY}, {@code LONGVARBINARY}, {@code CHAR}, {@code VARCHAR}, + * and {@code LONGVARCHAR} fields. Any data exceeding the maximum size is + * abandoned without announcement. + * + * @param max + * the maximum field size in bytes. {@code 0} means "no limit". + * @throws SQLException + * if an error occurs accessing the database or the {@code max} + * value is < {@code 0}. + * @since Android 1.0 + */ + public void setMaxFieldSize(int max) throws SQLException; + + /** + * Sets the maximum number of rows that any {@code ResultSet} can contain. + * If the number of rows exceeds this value, the additional rows are + * silently discarded. + * + * @param max + * the maximum number of rows. {@code 0} means "no limit". + * @throws SQLException + * if an error occurs accessing the database or if max < {@code + * 0}. + * @since Android 1.0 + */ + public void setMaxRows(int max) throws SQLException; + + /** + * Sets the timeout, in seconds, for queries - how long the driver will + * allow for completion of a statement execution. If the timeout is + * exceeded, the query will throw an {@code SQLException}. + * + * @param seconds + * timeout in seconds. 0 means no timeout ("wait forever") + * @throws SQLException + * if an error occurs accessing the database or if seconds < + * {@code 0}. + * @since Android 1.0 + */ + public void setQueryTimeout(int seconds) throws SQLException; +} diff --git a/sql/src/main/java/java/sql/Struct.java b/sql/src/main/java/java/sql/Struct.java new file mode 100644 index 0000000..1167cdf --- /dev/null +++ b/sql/src/main/java/java/sql/Struct.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.util.Map; + +/** + * An interface which provides facilities for manipulating an SQL structured type + * as a Java object. The {@code Struct} object has a value for each attribute of the SQL structured + * type. + * + * @since Android 1.0 + */ +public interface Struct { + + /** + * Gets the SQL Type name of the SQL structured type that this {@code + * Struct} represents. + * + * @return the fully qualified name of SQL structured type. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public String getSQLTypeName() throws SQLException; + + /** + * Gets the values of the attributes of this SQL structured type. This + * method uses the type map associated with the {@link Connection} for + * customized type mappings. Where there is no entry in the type mapping + * which matches this structured type, the JDBC driver uses the standard + * mapping. + * + * @return an {@code Object} array containing the ordered attributes. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public Object[] getAttributes() throws SQLException; + + /** + * Gets the values of the attributes of this SQL structured type. This + * method uses the supplied type mapping to determine how to map SQL types + * to their corresponding Java objects. In the + * case where there is no entry in the type mapping which matches this + * structured type, the JDBC driver uses the default mapping. The {@code + * Connection} type map is <i>never</i> utilized by this method. + * + * @param theMap + * a Map describing how SQL Type names are mapped to classes. + * @return an Object array containing the ordered attributes,. + * @throws SQLException + * if a database error occurs. + * @since Android 1.0 + */ + public Object[] getAttributes(Map<String, Class<?>> theMap) + throws SQLException; +} diff --git a/sql/src/main/java/java/sql/Time.java b/sql/src/main/java/java/sql/Time.java new file mode 100644 index 0000000..7fb28e1 --- /dev/null +++ b/sql/src/main/java/java/sql/Time.java @@ -0,0 +1,240 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Java representation of an SQL {@code TIME} value. Provides utilities to + * format and parse the time's representation as a String in JDBC escape format. + * + * @since Android 1.0 + */ +public class Time extends Date { + + private static final long serialVersionUID = 8397324403548013681L; + + /** + * Constructs a {@code Time} object using the supplied values for <i>Hour</i>, + * <i>Minute</i> and <i>Second</i>. The <i>Year</i>, <i>Month</i> and + * <i>Day</i> elements of the {@code Time} object are set to the date + * of the Epoch (January 1, 1970). + * <p> + * Any attempt to access the <i>Year</i>, <i>Month</i> or <i>Day</i> + * elements of a {@code Time} object will result in an {@code + * IllegalArgumentException}. + * </p><p> + * The result is undefined if any argument is out of bounds. + * </p> + * + * @deprecated Please use the constructor {@link #Time(long)}. + * @param theHour + * a value in the range {@code [0,23]}. + * @param theMinute + * a value in the range {@code [0,59]}. + * @param theSecond + * a value in the range {@code [0,59]}. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + public Time(int theHour, int theMinute, int theSecond) { + super(70, 0, 1, theHour, theMinute, theSecond); + } + + /** + * Constructs a {@code Time} object using a supplied time specified in + * milliseconds. + * + * @param theTime + * a {@code Time} specified in milliseconds since the + * <i>Epoch</i> (January 1st 1970, 00:00:00.000). + * @since Android 1.0 + */ + public Time(long theTime) { + super(theTime); + } + + /** + * @deprecated This method is deprecated and must not be used. An SQL + * {@code Time} object does not have a {@code Date} component. + * @return does not return anything. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public int getDate() { + throw new IllegalArgumentException(); + } + + /** + * @deprecated This method is deprecated and must not be used. An SQL + * {@code Time} object does not have a <i>Day</i> component. + * @return does not return anything. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public int getDay() { + throw new IllegalArgumentException(); + } + + /** + * @deprecated This method is deprecated and must not be used. An SQL + * {@code Time} object does not have a <i>Month</i> component. + * @return does not return anything. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public int getMonth() { + throw new IllegalArgumentException(); + } + + /** + * @deprecated This method is deprecated and must not be used. An SQL + * {@code Time} object does not have a <i>Year</i> component. + * @return does not return anything. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public int getYear() { + throw new IllegalArgumentException(); + } + + /** + * @deprecated This method is deprecated and must not be used. An SQL + * {@code Time} object does not have a {@code Date} component. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public void setDate(int i) { + throw new IllegalArgumentException(); + } + + /** + * @deprecated This method is deprecated and must not be used. An SQL + * {@code Time} object does not have a <i>Month</i> component. + * @throws IllegalArgumentException + * if this method is called. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public void setMonth(int i) { + throw new IllegalArgumentException(); + } + + /** + * @deprecated This method is deprecated and must not be used. An SQL + * {@code Time} object does not have a <i>Year</i> component. + * @throws IllegalArgumentException + * if this method is called. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public void setYear(int i) { + throw new IllegalArgumentException(); + } + + /** + * Sets the time for this {@code Time} object to the supplied milliseconds + * value. + * + * @param time + * A time value expressed as milliseconds since the <i>Epoch</i>. + * Negative values are milliseconds before the Epoch. The Epoch + * is January 1 1970, 00:00:00.000. + * @since Android 1.0 + */ + @Override + public void setTime(long time) { + super.setTime(time); + } + + /** + * Formats the {@code Time} as a String in JDBC escape format: {@code + * hh:mm:ss}. + * + * @return A String representing the {@code Time} value in JDBC escape + * format: {@code HH:mm:ss} + * @since Android 1.0 + */ + @Override + public String toString() { + SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$ + return dateFormat.format(this); + } + + /** + * Creates a {@code Time} object from a string holding a time represented in + * JDBC escape format: {@code hh:mm:ss}. + * <p> + * An exception occurs if the input string does not comply with this format. + * </p> + * + * @param timeString + * A String representing the time value in JDBC escape format: + * {@code hh:mm:ss}. + * @return The {@code Time} object set to a time corresponding to the given + * time. + * @throws IllegalArgumentException + * if the supplied time string is not in JDBC escape format. + * @since Android 1.0 + */ + public static Time valueOf(String timeString) { + if (timeString == null) { + throw new IllegalArgumentException(); + } + int firstIndex = timeString.indexOf(':'); + int secondIndex = timeString.indexOf(':', firstIndex + 1); + // secondIndex == -1 means none or only one separator '-' has been found. + // The string is separated into three parts by two separator characters, + // if the first or the third part is null string, we should throw + // IllegalArgumentException to follow RI + if (secondIndex == -1|| firstIndex == 0 || secondIndex + 1 == timeString.length()) { + throw new IllegalArgumentException(); + } + // parse each part of the string + int hour = Integer.parseInt(timeString.substring(0, firstIndex)); + int minute = Integer.parseInt(timeString.substring(firstIndex + 1, secondIndex)); + int second = Integer.parseInt(timeString.substring(secondIndex + 1, timeString + .length())); + return new Time(hour, minute, second); + } +} diff --git a/sql/src/main/java/java/sql/Timestamp.java b/sql/src/main/java/java/sql/Timestamp.java new file mode 100644 index 0000000..b526fb3 --- /dev/null +++ b/sql/src/main/java/java/sql/Timestamp.java @@ -0,0 +1,530 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +import java.text.DecimalFormat; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.apache.harmony.sql.internal.nls.Messages; + +/** + * A Java representation of the SQL {@code TIMESTAMP} type. It provides the + * capability of representing the SQL {@code TIMESTAMP} nanosecond value, in + * addition to the regular date/time value which has millisecond resolution. + * <p> + * The {@code Timestamp} class consists of a regular date/time value, where only + * the integral seconds value is stored, plus a nanoseconds value where the + * fractional seconds are stored. + * </p><p> + * The addition of the nanosecond value field to the {@code Timestamp} object + * makes it significantly different from the {@code java.util.Date} object which + * it extends. Users should be aware that {@code Timestamp} objects are not + * interchangable with {@code java.util.Date} objects when used outside the + * confines of the {@code java.sql} package. + * </p> + * + * @see Date + * @see Time + * @see java.util.Date + * @since Android 1.0 + */ +public class Timestamp extends Date { + + private static final long serialVersionUID = 2745179027874758501L; + + // The nanoseconds time value of the Timestamp + private int nanos; + + /** + * Returns a {@code Timestamp} corresponding to the time specified by the + * supplied values for <i>Year</i>, <i>Month</i>, <i>Date</i>, <i>Hour</i>, + * <i>Minutes</i>, <i>Seconds</i> and <i>Nanoseconds</i>. + * + * @deprecated Please use the constructor {@link #Timestamp(long)}. + * @param theYear + * specified as the year minus 1900. + * @param theMonth + * specified as an integer in the range [0,11]. + * @param theDate + * specified as an integer in the range [1,31]. + * @param theHour + * specified as an integer in the range [0,23]. + * @param theMinute + * specified as an integer in the range [0,59]. + * @param theSecond + * specified as an integer in the range [0,59]. + * @param theNano + * which defines the nanosecond value of the timestamp specified + * as an integer in the range [0,999'999'999] + * @throws IllegalArgumentException + * if any of the parameters is out of range. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Deprecated + public Timestamp(int theYear, int theMonth, int theDate, int theHour, + int theMinute, int theSecond, int theNano) + throws IllegalArgumentException { + super(theYear, theMonth, theDate, theHour, theMinute, theSecond); + if (theNano < 0 || theNano > 999999999) { + throw new IllegalArgumentException(); + } + nanos = theNano; + } + + /** + * Returns a {@code Timestamp} object corresponding to the time represented + * by a supplied time value. + * + * @param theTime + * a time value in the format of milliseconds since the Epoch + * (January 1 1970 00:00:00.000 GMT). + * @since Android 1.0 + */ + public Timestamp(long theTime) { + super(theTime); + /* + * Now set the time for this Timestamp object - which deals with the + * nanosecond value as well as the base time + */ + this.setTime(theTime); + } + + /** + * Returns {@code true} if this timestamp object is later than the supplied + * timestamp, otherwise returns {@code false}. + * + * @param theTimestamp + * the timestamp to compare with this timestamp object. + * @return {@code true} if this {@code Timestamp} object is later than the + * supplied timestamp, {@code false} otherwise. + * @since Android 1.0 + */ + public boolean after(Timestamp theTimestamp) { + long thisTime = this.getTime(); + long compareTime = theTimestamp.getTime(); + + // If the time value is later, the timestamp is later + if (thisTime > compareTime) { + return true; + } + // If the time value is earlier, the timestamp is not later + else if (thisTime < compareTime) { + return false; + } + /* + * Otherwise the time values are equal in which case the nanoseconds + * value determines whether this timestamp is later... + */ + else if (this.getNanos() > theTimestamp.getNanos()) { + return true; + } else { + return false; + } + } + + /** + * Returns {@code true} if this {@code Timestamp} object is earlier than the + * supplied timestamp, otherwise returns {@code false}. + * + * @param theTimestamp + * the timestamp to compare with this {@code Timestamp} object. + * @return {@code true} if this {@code Timestamp} object is earlier than the + * supplied timestamp, {@code false} otherwise. + * @since Android 1.0 + */ + public boolean before(Timestamp theTimestamp) { + long thisTime = this.getTime(); + long compareTime = theTimestamp.getTime(); + + // If the time value is later, the timestamp is later + if (thisTime < compareTime) { + return true; + } + // If the time value is earlier, the timestamp is not later + else if (thisTime > compareTime) { + return false; + } + /* + * Otherwise the time values are equal in which case the nanoseconds + * value determines whether this timestamp is later... + */ + else if (this.getNanos() < theTimestamp.getNanos()) { + return true; + } else { + return false; + } + } + + /** + * Compares this {@code Timestamp} object with a supplied {@code Timestamp} + * object. + * + * @param theObject + * the timestamp to compare with this {@code Timestamp} object, + * passed as an {@code Object}. + * @return <dd> + * <dl> + * {@code 0} if the two {@code Timestamp} objects are equal in time + * </dl> + * <dl> + * a value {@code < 0} if this {@code Timestamp} object is before + * the supplied {@code Timestamp} and a value + * </dl> + * <dl> + * {@code > 0} if this {@code Timestamp} object is after the + * supplied {@code Timestamp} + * </dl> + * </dd> + * @throws ClassCastException + * if the supplied object is not a {@code Timestamp} object. + * @since Android 1.0 + */ + @Override + public int compareTo(Date theObject) throws ClassCastException { + return this.compareTo((Timestamp) theObject); + } + + /** + * Compares this {@code Timestamp} object with a supplied {@code Timestamp} + * object. + * + * @param theTimestamp + * the timestamp to compare with this {@code Timestamp} object, + * passed in as a {@code Timestamp}. + * @return one of the following: + * <ul> + * <li>{@code 0}, if the two {@code Timestamp} objects are + * equal in time</li> + * <li>{@code < 0}, if this {@code Timestamp} object is before the + * supplied {@code Timestamp}</li> + * <li> {@code > 0}, if this {@code Timestamp} object is after the + * supplied {@code Timestamp}</li> + * </ul> + * @since Android 1.0 + */ + public int compareTo(Timestamp theTimestamp) { + int result = super.compareTo(theTimestamp); + if (result == 0) { + int thisNano = this.getNanos(); + int thatNano = theTimestamp.getNanos(); + if (thisNano > thatNano) { + return 1; + } else if (thisNano == thatNano) { + return 0; + } else { + return -1; + } + } + return result; + } + + /** + * Tests to see if this timestamp is equal to a supplied object. + * + * @param theObject + * the object to which this timestamp is compared. + * @return {@code true} if this {@code Timestamp} object is equal to the + * supplied {@code Timestamp} object<br>{@code false} if the object + * is not a {@code Timestamp} object or if the object is a {@code + * Timestamp} but represents a different instant in time. + * @since Android 1.0 + */ + @Override + public boolean equals(Object theObject) { + if (theObject instanceof Timestamp) { + return equals((Timestamp) theObject); + } + return false; + } + + /** + * Tests to see if this timestamp is equal to a supplied timestamp. + * + * @param theTimestamp + * the timestamp to compare with this {@code Timestamp} object, + * passed as an {@code Object}. + * @return {@code true} if this {@code Timestamp} object is equal to the + * supplied {@code Timestamp} object, {@code false} otherwise. + * @since Android 1.0 + */ + public boolean equals(Timestamp theTimestamp) { + if (theTimestamp == null) { + return false; + } + return (this.getTime() == theTimestamp.getTime()) + && (this.getNanos() == theTimestamp.getNanos()); + } + + /** + * Gets this {@code Timestamp}'s nanosecond value + * + * @return The timestamp's nanosecond value, an integer between 0 and + * 999,999,999. + * @since Android 1.0 + */ + public int getNanos() { + return nanos; + } + + /** + * Returns the time represented by this {@code Timestamp} object, as a long + * value containing the number of milliseconds since the Epoch (January 1 + * 1970, 00:00:00.000 GMT). + * + * @return the number of milliseconds that have passed since January 1 1970, + * 00:00:00.000 GMT. + * @since Android 1.0 + */ + @Override + public long getTime() { + long theTime = super.getTime(); + theTime = theTime + (nanos / 1000000); + return theTime; + } + + /** + * Sets the nanosecond value for this {@code Timestamp}. + * + * @param n + * number of nanoseconds. + * @throws IllegalArgumentException + * if number of nanoseconds smaller than 0 or greater than + * 999,999,999. + * @since Android 1.0 + */ + public void setNanos(int n) throws IllegalArgumentException { + if ((n < 0) || (n > 999999999)) { + // sql.0=Value out of range + throw new IllegalArgumentException(Messages.getString("sql.0")); //$NON-NLS-1$ + } + nanos = n; + } + + /** + * Sets the time represented by this {@code Timestamp} object to the + * supplied time, defined as the number of milliseconds since the Epoch + * (January 1 1970, 00:00:00.000 GMT). + * + * @param theTime + * number of milliseconds since the Epoch (January 1 1970, + * 00:00:00.000 GMT). + * @since Android 1.0 + */ + @Override + public void setTime(long theTime) { + /* + * Deal with the nanoseconds value. The supplied time is in milliseconds - + * so we must extract the milliseconds value and multiply by 1000000 to + * get nanoseconds. Things are more complex if theTime value is + * negative, since then the time value is the time before the Epoch but + * the nanoseconds value of the Timestamp must be positive - so we must + * take the "raw" milliseconds value and subtract it from 1000 to get to + * the true nanoseconds value Simultaneously, recalculate the time value + * to the exact nearest second and reset the Date time value + */ + int milliseconds = (int) (theTime % 1000); + theTime = theTime - milliseconds; + if (milliseconds < 0) { + theTime = theTime - 1000; + milliseconds = 1000 + milliseconds; + } + super.setTime(theTime); + setNanos(milliseconds * 1000000); + } + + /** + * Returns the timestamp formatted as a String in the JDBC Timestamp Escape + * format, which is {@code "yyyy-mm-dd hh:mm:ss.nnnnnnnnn"}. + * + * @return A string representing the instant defined by the {@code + * Timestamp}, in JDBC Timestamp escape format. + * @since Android 1.0 + */ + @SuppressWarnings("deprecation") + @Override + public String toString() { + /* + * Use a DecimalFormat to lay out the nanosecond value as a simple + * string of 9 integers, with leading Zeros + */ + DecimalFormat decimalFormat = new DecimalFormat("0"); //$NON-NLS-1$ + decimalFormat.setMinimumIntegerDigits(9); + decimalFormat.setMaximumIntegerDigits(9); + String theNanos = decimalFormat.format(nanos); + theNanos = stripTrailingZeros(theNanos); + + String year = format((getYear() + 1900), 4); + String month = format((getMonth() + 1), 2); + String date = format(getDate(), 2); + String hours = format(getHours(), 2); + String minutes = format(getMinutes(), 2); + String seconds = format(getSeconds(), 2); + + return year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + + ':' + seconds + '.' + theNanos; + } + + /* + * Private method to format the time + */ + private String format(int date, int digits) { + StringBuilder dateStringBuffer = new StringBuilder(String.valueOf(date)); + while (dateStringBuffer.length() < digits) { + dateStringBuffer = dateStringBuffer.insert(0,'0'); + } + return dateStringBuffer.toString(); + } + + /* + * Private method to strip trailing '0' characters from a string. @param + * inputString the starting string @return a string with the trailing zeros + * stripped - will leave a single 0 at the beginning of the string + */ + private String stripTrailingZeros(String inputString) { + String finalString; + + int i; + for (i = inputString.length(); i > 0; i--) { + if (inputString.charAt(i - 1) != '0') { + break; + } + /* + * If the string has a 0 as its first character, return a string + * with a single '0' + */ + if (i == 1) { + return "0"; //$NON-NLS-1$ + } + } + + finalString = inputString.substring(0, i); + return finalString; + } + + /** + * Creates a {@code Timestamp} object with a time value equal to the time + * specified by a supplied String holding the time in JDBC timestamp escape + * format, which is {@code "yyyy-mm-dd hh:mm:ss.nnnnnnnnn}" + * + * @param s + * the {@code String} containing a time in JDBC timestamp escape + * format. + * @return A {@code Timestamp} object with time value as defined by the + * supplied {@code String}. + * @throws IllegalArgumentException + * if the provided string is {@code null}. + * @since Android 1.0 + */ + public static Timestamp valueOf(String s) throws IllegalArgumentException { + if (s == null) { + // sql.3=Argument cannot be null + throw new IllegalArgumentException(Messages.getString("sql.3")); //$NON-NLS-1$ + } + + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //$NON-NLS-1$ + ParsePosition pp = new ParsePosition(0); + + /* + * First parse out the yyyy-MM-dd HH:mm:ss component of the String into + * a Date object using the SimpleDateFormat. This should stop after the + * seconds value, according to the definition of SimpleDateFormat.parse, + * with the ParsePosition indicating the index of the "." which should + * precede the nanoseconds value + */ + Date theDate; + try { + theDate = df.parse(s, pp); + } catch (Exception e) { + throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$ + } + + if (theDate == null) { + throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$ + } + + /* + * If we get here, the Date part of the string was OK - now for the + * nanoseconds value. Strictly, this requires the remaining part of the + * String to look like ".nnnnnnnnn". However, we accept anything with a + * '.' followed by 1 to 9 digits - we also accept nothing (no fractions + * of a second). Anything else is interpreted as incorrect format which + * will generate an IllegalArgumentException + */ + int position = pp.getIndex(); + int remaining = s.length() - position; + int theNanos; + + if (remaining == 0) { + // First, allow for the case where no fraction of a second is given: + theNanos = 0; + } else { + /* + * Case where fraction of a second is specified: Require 1 character + * plus the "." in the remaining part of the string... + */ + if ((s.length() - position) < ".n".length()) { //$NON-NLS-1$ + throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$ + } + + /* + * If we're strict, we should not allow any EXTRA characters after + * the 9 digits + */ + if ((s.length() - position) > ".nnnnnnnnn".length()) { //$NON-NLS-1$ + throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$ + } + + // Require the next character to be a "." + if (s.charAt(position) != '.') { + // sql.4=Bad input string format: expected '.' not {0} + throw new NumberFormatException(Messages.getString("sql.4", s.charAt(position))); //$NON-NLS-1$ + } + // Get the length of the number string - need to account for the '.' + int nanoLength = s.length() - position - 1; + + // Get the 9 characters following the "." as an integer + String theNanoString = s.substring(position + 1, position + 1 + + nanoLength); + /* + * We must adjust for the cases where the nanos String was not 9 + * characters long by padding out with zeros + */ + theNanoString = theNanoString + "000000000"; //$NON-NLS-1$ + theNanoString = theNanoString.substring(0, 9); + + try { + theNanos = Integer.parseInt(theNanoString); + } catch (Exception e) { + // If we get here, the string was not a number + throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$ + } + } + + if (theNanos < 0 || theNanos > 999999999) { + throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$ + } + + Timestamp theTimestamp = new Timestamp(theDate.getTime()); + theTimestamp.setNanos(theNanos); + + return theTimestamp; + } +} diff --git a/sql/src/main/java/java/sql/Types.java b/sql/src/main/java/java/sql/Types.java new file mode 100644 index 0000000..8ce0421 --- /dev/null +++ b/sql/src/main/java/java/sql/Types.java @@ -0,0 +1,247 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.sql; + +/** + * A class which defines constants used to identify generic SQL types, also + * called JDBC types. The type constant values are equivalent to those defined + * by X/OPEN. + * + * @since Android 1.0 + */ +public class Types { + + /* + * Private constructor to prevent instantiation. + */ + private Types() { + super(); + } + + /** + * The type code that identifies the SQL type {@code ARRAY}. + * + * @since Android 1.0 + */ + public static final int ARRAY = 2003; + + /** + * The type code that identifies the SQL type {@code BIGINT}. + * + * @since Android 1.0 + */ + public static final int BIGINT = -5; + + /** + * The type code that identifies the SQL type {@code BINARY}. + * + * @since Android 1.0 + */ + public static final int BINARY = -2; + + /** + * The type code that identifies the SQL type {@code BIT}. + * + * @since Android 1.0 + */ + public static final int BIT = -7; + + /** + * The type code that identifies the SQL type {@code BLOB}. + * + * @since Android 1.0 + */ + public static final int BLOB = 2004; + + /** + * The type code that identifies the SQL type {@code BOOLEAN}. + * + * @since Android 1.0 + */ + public static final int BOOLEAN = 16; + + /** + * The type code that identifies the SQL type {@code CHAR}. + * + * @since Android 1.0 + */ + public static final int CHAR = 1; + + /** + * The type code that identifies the SQL type {@code CLOB}. + * + * @since Android 1.0 + */ + public static final int CLOB = 2005; + + /** + * The type code that identifies the SQL type {@code DATALINK}. + * + * @since Android 1.0 + */ + public static final int DATALINK = 70; + + /** + * The type code that identifies the SQL type {@code DATE}. + * + * @since Android 1.0 + */ + public static final int DATE = 91; + + /** + * The type code that identifies the SQL type {@code DECIMAL}. + * + * @since Android 1.0 + */ + public static final int DECIMAL = 3; + + /** + * The type code that identifies the SQL type {@code DISTINCT}. + * + * @since Android 1.0 + */ + public static final int DISTINCT = 2001; + + /** + * The type code that identifies the SQL type {@code DOUBLE}. + * + * @since Android 1.0 + */ + public static final int DOUBLE = 8; + + /** + * The type code that identifies the SQL type {@code FLOAT}. + * + * @since Android 1.0 + */ + public static final int FLOAT = 6; + + /** + * The type code that identifies the SQL type {@code INTEGER}. + * + * @since Android 1.0 + */ + public static final int INTEGER = 4; + + /** + * The type code that identifies the SQL type {@code JAVA_OBJECT}. + * + * @since Android 1.0 + */ + public static final int JAVA_OBJECT = 2000; + + /** + * The type code that identifies the SQL type {@code LONGVARBINARY}. + * + * @since Android 1.0 + */ + public static final int LONGVARBINARY = -4; + + /** + * The type code that identifies the SQL type {@code LONGVARCHAR}. + * + * @since Android 1.0 + */ + public static final int LONGVARCHAR = -1; + + /** + * The type code that identifies the SQL type {@code NULL}. + * + * @since Android 1.0 + */ + public static final int NULL = 0; + + /** + * The type code that identifies the SQL type {@code NUMERIC}. + * + * @since Android 1.0 + */ + public static final int NUMERIC = 2; + + /** + * The type code that identifies that the SQL type is database specific and + * is mapped to a Java object, accessed via the methods + * {@code getObject} and {@code setObject}. + * + * @since Android 1.0 + */ + public static final int OTHER = 1111; + + /** + * The type code that identifies the SQL type {@code REAL}. + * + * @since Android 1.0 + */ + public static final int REAL = 7; + + /** + * The type code that identifies the SQL type {@code REF}. + * + * @since Android 1.0 + */ + public static final int REF = 2006; + + /** + * The type code that identifies the SQL type {@code SMALLINT}. + * + * @since Android 1.0 + */ + public static final int SMALLINT = 5; + + /** + * The type code that identifies the SQL type {@code STRUCT}. + * + * @since Android 1.0 + */ + public static final int STRUCT = 2002; + + /** + * The type code that identifies the SQL type {@code TIME}. + * + * @since Android 1.0 + */ + public static final int TIME = 92; + + /** + * The type code that identifies the SQL type {@code TIMESTAMP}. + * + * @since Android 1.0 + */ + public static final int TIMESTAMP = 93; + + /** + * The type code that identifies the SQL type {@code TINYINT}. + * + * @since Android 1.0 + */ + public static final int TINYINT = -6; + + /** + * The type code that identifies the SQL type {@code VARBINARY}. + * + * @since Android 1.0 + */ + public static final int VARBINARY = -3; + + /** + * The type code that identifies the SQL type {@code VARCHAR}. + * + * @since Android 1.0 + */ + public static final int VARCHAR = 12; +} diff --git a/sql/src/main/java/java/sql/package.html b/sql/src/main/java/java/sql/package.html new file mode 100644 index 0000000..9ae2488 --- /dev/null +++ b/sql/src/main/java/java/sql/package.html @@ -0,0 +1,8 @@ +<html> + <body> + <p> + Provides a standard interface for accessing SQL-based databases. + </p> + @since Android 1.0 + </body> +</html>
\ No newline at end of file diff --git a/sql/src/main/java/javax/sql/ConnectionEvent.java b/sql/src/main/java/javax/sql/ConnectionEvent.java new file mode 100644 index 0000000..e07e7c1 --- /dev/null +++ b/sql/src/main/java/javax/sql/ConnectionEvent.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.util.EventObject; +import java.sql.SQLException; +import java.io.Serializable; + +/** + * Sent when specific events happen on a {@link PooledConnection} object. These + * events are a facility to report when an application closes the pooled + * connection or when an error occurs in the pooled connection. + * + * @since Android 1.0 + */ +public class ConnectionEvent extends EventObject implements Serializable { + + private static final long serialVersionUID = -4843217645290030002L; + + private SQLException theSQLException; + + /** + * Creates a connection event initialized with the supplied {@code + * PooledConnection} reporting that the application has closed the + * connection. + * + * @param theConnection + * the connection for which this event is created. + * @since Android 1.0 + */ + public ConnectionEvent(PooledConnection theConnection) { + super(theConnection); + } + + /** + * Creates a {@code ConnectionEvent} initialized with the supplied {@code + * PooledConnection} and with the supplied {@code SQLException} indicating + * that an error has occurred within the {@code PooledConnection}. + * + * @param theConnection + * the connection for which this event is created. + * @param theException + * information about the state of error that has occurred on the + * application side. + * @since Android 1.0 + */ + public ConnectionEvent(PooledConnection theConnection, + SQLException theException) { + super(theConnection); + theSQLException = theException; + } + + /** + * Gets the {@code SQLException} which holds information about the error + * which occurred in the {@code PooledConnection}. + * + * @return a {@code SQLException} containing information about the error. + * May be {@code null} if no error has occurred. + * @since Android 1.0 + */ + public SQLException getSQLException() { + return theSQLException; + } +} diff --git a/sql/src/main/java/javax/sql/ConnectionEventListener.java b/sql/src/main/java/javax/sql/ConnectionEventListener.java new file mode 100644 index 0000000..1333814 --- /dev/null +++ b/sql/src/main/java/javax/sql/ConnectionEventListener.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.util.EventListener; + +/** + * An interface used to receive events generated by a {@link PooledConnection}. + * <p> + * This interface would typically be implemented by a component which manages a + * connection pool (a connection pool manager). A connection triggers an event + * to a {@code ConnectionEventListener} either when the application closes a + * connection it has been using or when a significant error occurs while the + * connection is being used. + * </p> + * <p> + * The connection pool manager can return closed connections to the pool for + * later reuse. Connections experiencing an error should be discarded. + * </p> + * + * @since Android 1.0 + */ +public interface ConnectionEventListener extends EventListener { + + /** + * Notifies the {@code ConnectionEventListener} that an application has + * called the {@code close} method on a pooled connection. + * + * @param theEvent + * a {@code ConnectionEvent} containing details about the source + * of the event. + * @since Android 1.0 + */ + public void connectionClosed(ConnectionEvent theEvent); + + /** + * Notifies the {@code ConnectionEventListener} that an error has occurred + * on a {@code PooledConnection}. This notification is triggered <i>before</i> the + * {@code SQLException}, which is available through the event argument, is + * thrown. + * + * @param theEvent + * a {@code ConnectionEvent} containing details about the source + * of the event and the {@code SQLException} that has occurred. + * @since Android 1.0 + */ + public void connectionErrorOccurred(ConnectionEvent theEvent); +} diff --git a/sql/src/main/java/javax/sql/ConnectionPoolDataSource.java b/sql/src/main/java/javax/sql/ConnectionPoolDataSource.java new file mode 100644 index 0000000..d73128b --- /dev/null +++ b/sql/src/main/java/javax/sql/ConnectionPoolDataSource.java @@ -0,0 +1,137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.sql.SQLException; +import java.io.PrintWriter; + +/** + * An interface for the creation of {@code ConnectionPoolDataSource} objects. + * Used internally within the package. + * <p> + * A class which implements the {@code ConnectionPoolDataSource} interface is + * typically registered with a JNDI naming service directory and is retrieved + * from there by name. + * </p> + * + * @since Android 1.0 + */ +public interface ConnectionPoolDataSource { + + /** + * Gets the login timeout value for this {@code ConnectionPoolDataSource}. + * The login timeout is the maximum time in seconds that the {@code + * ConnectionPoolDataSource} will wait when opening a connection to a + * database. A timeout value of 0 implies either the system default timeout + * value (if there is one) or that there is no timeout. The default value + * for the login timeout is {@code 0}. + * + * @return the login timeout value in seconds. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public int getLoginTimeout() throws SQLException; + + /** + * Gets the log writer for this {@code ConnectionPoolDataSource}. + * <p> + * The log writer is a stream to which all log and trace messages are sent + * from this {@code ConnectionPoolDataSource}. The log writer can be {@code + * null}, in which case the log and trace capture is disabled. The default + * value for the log writer when an {@code ConnectionPoolDataSource} is + * created is {@code null}. Note that the log writer for an {@code + * ConnectionPoolDataSource} is not the same as the log writer used by a + * {@code DriverManager}. + * </p> + * + * @return a {@code PrintWriter} which is the log writer for this {@code + * ConnectionPoolDataSource}. Can be {@code null}, in which case log + * writing is disabled for this {@code ConnectionPoolDataSource}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public PrintWriter getLogWriter() throws SQLException; + + /** + * Creates a connection to a database which can then be used as a pooled + * connection. + * + * @return a {@code PooledConnection} which represents the connection to the + * database. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public PooledConnection getPooledConnection() throws SQLException; + + /** + * Creates a connection to a database, using the supplied user name and + * password, which can then be used as a pooled connection. + * + * @param theUser + * the a user name for the database login. + * @param thePassword + * the password associated with the user identified by {@code + * theUser}. + * @return a {@code PooledConnection} object which represents the connection + * to the database. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public PooledConnection getPooledConnection(String theUser, + String thePassword) throws SQLException; + + /** + * Sets the login timeout value for this {@code ConnectionPoolDataSource}. + * The login timeout is the maximum time in seconds that the {@code + * ConnectionPoolDataSource} will wait when opening a connection to a + * database. A timeout value of 0 implies either the system default timeout + * value (if there is one) or that there is no timeout. The default value + * for the login timeout is 0. + * + * @param theTimeout + * the new login timeout value in seconds. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public void setLoginTimeout(int theTimeout) throws SQLException; + + /** + * Sets the log writer for this {@code ConnectionPoolDataSource}. + * <p> + * The log writer is a stream to which all log and trace messages are sent + * from this {@code ConnectionPoolDataSource}. The log writer can be {@code + * null}, in which case log and trace capture is disabled. The default value + * for the log writer, when a {@code ConnectionPoolDataSource} is created, + * is {@code null}. Note that the log writer for a {@code + * ConnectionPoolDataSource} is not the same as the log writer used by a + * {@code DriverManager}. + * </p> + * + * @param theWriter + * is the log writer for this {@code ConnectionPoolDataSource}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public void setLogWriter(PrintWriter theWriter) throws SQLException; +} diff --git a/sql/src/main/java/javax/sql/DataSource.java b/sql/src/main/java/javax/sql/DataSource.java new file mode 100644 index 0000000..98be761 --- /dev/null +++ b/sql/src/main/java/javax/sql/DataSource.java @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.sql.SQLException; +import java.sql.Connection; +import java.io.PrintWriter; + +/** + * An interface for the creation of {@code Connection} objects which represent a + * connection to a database. This interface is an alternative to the {@code + * java.sql.DriverManager}. + * <p> + * A class which implements the {@code DataSource} interface is typically + * registered with a JNDI naming service directory and is retrieved from there + * by name. + * </p> + * <p> + * The {@code DataSource} interface is typically implemented by the writer of a + * JDBC driver. There are three variants of the {@code DataSource} interface, + * which produce connections with different characteristics: + * </p> + * <ol> + * <li><i>Standard {@code DataSource}</i>: produces standard {@code Connection} + * objects with no special features.</li> + * <li><i>Connection Pool {@code DataSource}</i>: produces {@code + * PooledConnection} objects which require a connection pool manager as an + * intermediary component.</li> + * <li><i>Distributed transaction {@code DataSource} ("XADataSource")</i>: + * produces {@code XAConnection} objects which can be used to handle distributed + * transactions which typically require an intermediary transaction manager + * component. {@code XAConnection} objects also provide connection pooling + * capabilities as well as distributed transaction capabilities.</li> + * </ol> + * <p> + * Note that a JDBC driver which is accessed via the {@code DataSource} + * interface is loaded via a JNDI lookup process. A driver loaded in this way + * does not register itself with the {@code DriverManager}. + * </p> + * + * @since Android 1.0 + */ +public interface DataSource { + + /** + * Creates a connection to the database represented by this {@code + * DataSource}. + * + * @return a {@code Connection} object which is a connection to the + * database. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public Connection getConnection() throws SQLException; + + /** + * Creates a connection to the database represented by this {@code + * DataSource}, using the supplied user name and password. + * + * @param theUsername + * the a user name for the database login. + * @param thePassword + * the password associated with the user identified by {@code + * theUsername}. + * @return the {@code Connection} object which is the connection to the + * database. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public Connection getConnection(String theUsername, String thePassword) + throws SQLException; + + /** + * Gets the login timeout value for this {@code DataSource}. The login + * timeout is the maximum time in seconds that the {@code DataSource} will + * wait when opening a connection to a database. A timeout value of 0 + * implies either the system default timeout value (if there is one) or that + * there is no timeout. The default value for the login timeout is 0. + * + * @return the login timeout value in seconds. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public int getLoginTimeout() throws SQLException; + + /** + * Gets the log writer for this {@code DataSource}. + * <p> + * The log writer is a stream to which all log and trace messages are sent + * from this {@code DataSource}. The log writer can be {@code null}, in + * which case, log and trace capture is disabled. The default value for the + * log writer when an {@code DataSource} is created is {@code null}. Note + * that the log writer for a {@code DataSource} is not the same as the log + * writer used by a {@code DriverManager}. + * </p> + * + * @return a {@code PrintWriter} which is the log writer for this {@code + * DataSource}. Can be {@code null}, in which case log writing is + * disabled for this {@code DataSource}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public PrintWriter getLogWriter() throws SQLException; + + /** + * Sets the login timeout value for this {@code DataSource}. The login + * timeout is the maximum time in seconds that the {@code DataSource} will + * wait when opening a connection to a database. A timeout value of 0 + * implies either the system default timeout value (if there is one) or that + * there is no timeout. The default value for the login timeout is 0. + * + * @param theTimeout + * the new login timeout value in seconds. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public void setLoginTimeout(int theTimeout) throws SQLException; + + /** + * Sets the log writer for this {@code DataSource}. + * <p> + * The log writer is a stream to which all log and trace messages are sent + * from this {@code DataSource}. The log writer can be {@code null}, in + * which case, log and trace capture is disabled. The default value for the + * log writer when a {@code DataSource} is created is {@code null}. Note + * that the log writer for a {@code DataSource} is not the same as the log + * writer used by a {@code DriverManager}. + * </p> + * + * @param theWriter + * a {@code PrintWriter} to use as the log writer for this + * {@code DataSource}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public void setLogWriter(PrintWriter theWriter) throws SQLException; +} diff --git a/sql/src/main/java/javax/sql/PooledConnection.java b/sql/src/main/java/javax/sql/PooledConnection.java new file mode 100644 index 0000000..b4c5616 --- /dev/null +++ b/sql/src/main/java/javax/sql/PooledConnection.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.sql.SQLException; +import java.sql.Connection; + +/** + * An interface which provides facilities for handling connections to a database + * which are pooled. + * <p> + * Typically, a {@code PooledConnection} is recycled when it is no longer + * required by an application, rather than being closed and discarded. The + * reason for treating connections in this way is that it can be an expensive + * process both to establish a connection to a database and to destroy the + * connection. Reusing connections through a pool is a way of improving system + * performance and reducing overhead. + * </p> + * <p> + * It is not intended that an application uses the {@code PooledConnection} + * interface directly. The {@code PooledConnection} interface is intended for + * use by a component called a connection pool manager, typically part of the + * infrastructure that supports use of the database by applications. + * </p> + * <p> + * Applications obtain connections to the database by calling the + * {@link DataSource#getConnection} method. Behind the scenes, the connection + * pool manager will get a {@code PooledConnection} object from its connection + * pool and passes back a connection object that wraps or references the {@code + * PooledConnection} object. A new {@code PooledConnection} object will only be + * created if the pool is empty. + * </p> + * <p> + * When the application is finished using a {@code PooledConnection}, the + * application calls the {@link Connection#close} method. The connection pool + * manager is notified via a {@link ConnectionEvent} from the connection that + * this has happened (the pool manager registers itself with the connection + * before the connection is given to the application). The pool manager removes + * the underlying {@code PooledConnection} object from the connection and + * returns it to the pool for reuse - the {@code PooledConnection} is thus + * recycled rather than being destroyed. + * </p> + * <p> + * The connection to the database represented by the {@code PooledConnection} is + * kept open until the {@code PooledConnection} object itself is deactivated by + * the connection pool manager, which calls {@code PooledConnection.close()}. + * This is typically done if there are too many inactive connections in the + * pool, if the {@code PooledConnection} encounters a problem that makes it + * unusable or if the whole system is being shut down. + * </p> + * + * @since Android 1.0 + */ +public interface PooledConnection { + + /** + * Registers the supplied {@code ConnectionEventListener} with this {@code + * PooledConnection}. Once registered, the {@code ConnectionEventListener} + * will receive {@link ConnectionEvent} events when they occur in the + * {@code PooledConnection}. + * + * @param theListener + * an object which implements the {@code ConnectionEventListener} + * interface. + * @since Android 1.0 + */ + public void addConnectionEventListener(ConnectionEventListener theListener); + + /** + * Closes the connection to the database held by this {@code + * PooledConnection}. This method should not be called directly by + * application code - it is intended only for the connection pool manager + * component. + * + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public void close() throws SQLException; + + /** + * Creates a connection to the database. This method is typically called by + * the connection pool manager when an application invokes the method + * {@code DataSource.getConnection()} and there are no {@code + * PooledConnection} objects available in the connection pool. + * + * @return a {@code Connection} object. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public Connection getConnection() throws SQLException; + + /** + * Unregisters the supplied {@code ConnectionEventListener} from this {@code + * PooledConnection}. Once unregistered, the {@code ConnectionEventListener} + * will no longer receive events occurring in the {@code PooledConnection}. + * + * @param theListener + * an object which implements the {@code ConnectionEventListener} + * interface. This object should have previously been registered + * with the {@code PooledConnection} using the {@code + * addConnectionEventListener} method. + * @since Android 1.0 + */ + public void removeConnectionEventListener( + ConnectionEventListener theListener); +} diff --git a/sql/src/main/java/javax/sql/RowSet.java b/sql/src/main/java/javax/sql/RowSet.java new file mode 100644 index 0000000..4edc3d3 --- /dev/null +++ b/sql/src/main/java/javax/sql/RowSet.java @@ -0,0 +1,985 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Date; +import java.sql.Ref; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Map; +import java.io.InputStream; +import java.io.Reader; +import java.util.Calendar; +import java.math.BigDecimal; + +/** + * An interface which provides means to access data which + * persists on a database. It extends the functionality of + * {@link java.sql.ResultSet ResultSet} into a form that it can be used as a + * JavaBean component, suited for a visual programming environment. + * <p> + * {@code RowSet} provides getters and setters for properties relating to the + * general database environment together with the getters and setters for + * distinct data values which constitute the row set. The {@code RowSet} class + * supports JavaBean events so that other components in an application can be + * informed when changes happen such as changes in data values. + * </p> + * <p> + * {@code RowSet} is a facility implemented on top of the remainder of the JDBC + * API. It may be <i>connected</i>, maintaining a connection to the database + * throughout its lifecycle. The changes made on a <i>disconnected</i> {@code + * RowSet} on the other hand can be persisted only establishing a new connection + * with the database each time. + * </p> + * <p> + * Disconnected {@code RowSets} make use of {@code RowSetReaders} to populate + * the {@code RowSet} with data, possibly from a non-relational database source. + * They may also use {@code RowSetWriters} to send data back to the underlying + * data store. There is considerable freedom in the way that {@code + * RowSetReaders} and {@code RowSetWriters} may be implemented to retrieve and + * store data. + * </p> + * + * @see RowSetReader + * @see RowSetWriter + * @since Android 1.0 + */ +public interface RowSet extends ResultSet { + + /** + * Registers the supplied {@link RowSetListener} with this {@code RowSet}. + * Once registered, the {@link RowSetListener} is notified of events + * generated by the {@code RowSet}. + * + * @param theListener + * an object which implements the {@code rowSetListener} + * interface. + * @since Android 1.0 + */ + public void addRowSetListener(RowSetListener theListener); + + /** + * Clears the parameters previously set for this {@code RowSet}. + * <p> + * The {@code RowSet} object retains its value until either a new value for + * a parameter is set or its value is actively reset. {@code + * clearParameters} provides a facility to clear the values for all + * parameters with one method call. + * </p> + * + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void clearParameters() throws SQLException; + + /** + * Fetches data for this {@code RowSet} from the database. If successful, + * any existing data for the {@code RowSet} is discarded and its metadata is + * overwritten. + * <p> + * Data is retrieved connecting to the database and executing an + * according SQL statement. This requires some or all of the following + * properties to be set: URL, database name, user name, password, + * transaction isolation, type map; plus some or all of the properties: + * command, read only, maximum field size, maximum rows, escape processing, + * and query timeout. + * </p> + * <p> + * The {@code RowSet} may use a {@code RowSetReader} to access the database + * it will then invoke the {@link RowSetReader#readData} method on the + * reader to fetch the data. When the new data is fetched all the listeners + * are notified to take appropriate measures. + * </p> + * + * @throws SQLException + * if a problem occurs accessing the database or if the + * properties needed to access the database have not been set. + * @see RowSetMetaData + * @see RowSetReader + * @since Android 1.0 + */ + public void execute() throws SQLException; + + /** + * Gets the {@code RowSet}'s command property. + * + * @return a string containing the {@code RowSet}'s command property. A + * command is a SQL statement which is executed to fetch required + * data into the {@code RowSet}. + * @since Android 1.0 + */ + public String getCommand(); + + /** + * Gets the ODBC Data Source Name property associated with this {@code + * RowSet}. The database name can be used to find a {@link DataSource} + * which has been registered with a naming service - the {@link DataSource} + * can then be used to create a connection to the database. + * + * @return the name of the database. + * @since Android 1.0 + */ + public String getDataSourceName(); + + /** + * Reports if escape processing is enabled for this {@code RowSet}. If + * escape processing is on, the driver performs a substitution of the escape + * syntax with the applicable code before sending an SQL command to the + * database. The default value for escape processing is {@code true}. + * + * @return {@code true} if escape processing is enabled, {@code + * false} otherwise. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public boolean getEscapeProcessing() throws SQLException; + + /** + * Gets the maximum number of bytes that can be returned for column values + * which are of type {@code BINARY}, {@code VARBINARY}, {@code + * LONGVARBINARYBINARY}, {@code CHAR}, {@code VARCHAR}, or {@code + * LONGVARCHAR}. Excess data is silently discarded if the number is + * exceeded. + * + * @return the current maximum size in bytes. 0 implies no size limit. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public int getMaxFieldSize() throws SQLException; + + /** + * Gets the maximum number of rows for this {@code RowSet}. Excess rows are + * discarded silently if the limit is exceeded. + * + * @return the previous maximum number of rows. 0 implies no row limit. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public int getMaxRows() throws SQLException; + + /** + * Gets the value of the password property for this {@code RowSet}. This + * property is used when a connection to the database is established. + * Therefore it should be set prior to invoking the {@link #execute} method. + * + * @return the value of the password property. + * @since Android 1.0 + */ + public String getPassword(); + + /** + * Gets the timeout for the driver when a query operation is executed. If a + * query takes longer than the timeout then a {@code SQLException} is + * thrown. + * + * @return the timeout value in seconds. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public int getQueryTimeout() throws SQLException; + + /** + * Gets the transaction isolation level property set for this + * {@code RowSet}. The transaction isolation level defines the + * policy implemented on the database for maintaining the data + * values consistent. + * + * @return the current transaction isolation level. Must be one of: + * <ul> + * <li>{@code Connection.TRANSACTION_READ_UNCOMMITTED}</li> + * <li>{@code Connection.TRANSACTION_READ_COMMITTED}</li> + * <li>{@code Connection.TRANSACTION_REPEATABLE_READ}</li> + * <li>{@code Connection.TRANSACTION_SERIALIZABLE}</li> + * </ul> + * @see java.sql.Connection + * @since Android 1.0 + */ + public int getTransactionIsolation(); + + /** + * Gets the custom mapping of SQL User-Defined Types (UDTs) and Java classes + * for this {@code RowSet}, if applicable. + * + * @return the custom mappings of SQL types to Java classes. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public Map<String, Class<?>> getTypeMap() throws SQLException; + + /** + * Gets the URL property value for this {@code RowSet}. If there is no + * {@code DataSource} object specified, the {@code RowSet} uses the URL to + * establish a connection to the database. The default value for the URL is + * {@code null}. + * + * @return a String holding the value of the URL property. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public String getUrl() throws SQLException; + + /** + * Gets the value of the {@code username} property for this {@code RowSet}. + * The {@code username} is used when establishing a connection to the + * database and should be set before the {@code execute} method is invoked. + * + * @return a {@code String} holding the value of the {@code username} + * property. + * @since Android 1.0 + */ + public String getUsername(); + + /** + * Indicates if this {@code RowSet} is read-only. + * + * @return {@code true} if this {@code RowSet} is read-only, {@code false} + * if it is updatable. + * @since Android 1.0 + */ + public boolean isReadOnly(); + + /** + * Removes a specified {@link RowSetListener} object from the set of + * listeners which will be notified of events by this {@code RowSet}. + * + * @param theListener + * the {@link RowSetListener} to remove from the set of listeners + * for this {@code RowSet}. + * @since Android 1.0 + */ + public void removeRowSetListener(RowSetListener theListener); + + /** + * Sets the specified {@code ARRAY} parameter in the {@code RowSet} command + * with the supplied {@code java.sql.Array} value. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theArray + * the {@code Array} data value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setArray(int parameterIndex, Array theArray) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * with the ASCII data in the supplied {@code java.io.InputStream} value. + * Data is read from the {@code InputStream} until end-of-file is reached. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theInputStream + * the ASCII data value to which the parameter is set. + * @param length + * the length of the data in bytes. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setAsciiStream(int parameterIndex, InputStream theInputStream, + int length) throws SQLException; + + /** + * Sets the value of the specified SQL {@code NUMERIC} parameter in the + * {@code RowSet} command with the data in the supplied {@code + * java.math.BigDecimal} value. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theBigDecimal + * the big decimal value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setBigDecimal(int parameterIndex, BigDecimal theBigDecimal) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to the binary data in the supplied input stream. Data is read from the + * input stream until end-of-file is reached. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theInputStream + * the binary data stream to which the parameter is set. + * @param length + * the length of the data in bytes. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setBinaryStream(int parameterIndex, InputStream theInputStream, + int length) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to the supplied {@code Blob} value. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theBlob + * the {@code Blob} value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setBlob(int parameterIndex, Blob theBlob) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to the supplied boolean. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theBoolean + * the {@code boolean} value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setBoolean(int parameterIndex, boolean theBoolean) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to the supplied byte value. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theByte + * the {@code byte} value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setByte(int parameterIndex, byte theByte) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to the supplied byte array value. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theByteArray + * the {@code Array} of {@code bytes} to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setBytes(int parameterIndex, byte[] theByteArray) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to the sequence of Unicode characters carried by the supplied {@code + * java.io.Reader}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theReader + * the {@code Reader} which contains the Unicode data to set the + * parameter. + * @param length + * the length of the data in the {@code Reader} in characters. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setCharacterStream(int parameterIndex, Reader theReader, + int length) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * with the value of a supplied {@code java.sql.Clob}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theClob + * the {@code Clob} value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setClob(int parameterIndex, Clob theClob) throws SQLException; + + /** + * Sets the Command property for this {@code RowSet} - the command is an SQL + * query which runs when the {@code execute} method is invoked. This + * property is optional for databases that do not support commands. + * + * @param cmd + * the SQL query. Can be {@code null}. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setCommand(String cmd) throws SQLException; + + /** + * Sets the concurrency property of this {@code RowSet}. The default value + * is {@code ResultSet.CONCUR_READ_ONLY}. + * + * @param concurrency + * the concurrency value. One of: + * <ul> + * <li>{@code ResultSet.CONCUR_READ_ONLY}</li> + * <li>{@code ResultSet.CONCUR_UPDATABLE}</li> + * </ul> + * @throws SQLException + * if an error occurs accessing the database. + * @see java.sql.ResultSet + * @since Android 1.0 + */ + public void setConcurrency(int concurrency) throws SQLException; + + /** + * Sets the database name property for the {@code RowSet}. + * <p> + * The database name can be used to find a {@link DataSource} which has been + * registered with a naming service - the {@link DataSource} can then be + * used to create a connection to the database. + * </p> + * + * @param name + * the database name. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setDataSourceName(String name) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * with the value of a supplied {@code java.sql.Date}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theDate + * the date value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setDate(int parameterIndex, Date theDate) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * with the value of a supplied {@code java.sql.Date}, where the conversion + * of the date to an SQL {@code DATE} value is calculated using a supplied + * {@code Calendar}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theDate + * the date to which the parameter is set. + * @param theCalendar + * the {@code Calendar} to use in converting the Date to an SQL + * {@code DATE} value. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setDate(int parameterIndex, Date theDate, Calendar theCalendar) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * with the supplied {@code double}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theDouble + * the {@code double} value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setDouble(int parameterIndex, double theDouble) + throws SQLException; + + /** + * Sets the escape processing status for this {@code RowSet}. If escape + * processing is on, the driver performs a substitution of the escape syntax + * with the applicable code before sending an SQL command to the database. + * The default value for escape processing is {@code true}. + * + * @param enable + * {@code true} to enable escape processing, {@code false} to + * turn it off. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setEscapeProcessing(boolean enable) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * with the supplied {@code float}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theFloat + * the {@code float} value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setFloat(int parameterIndex, float theFloat) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * with the supplied {@code integer}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theInteger + * the {@code integer} value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setInt(int parameterIndex, int theInteger) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * with the supplied {@code long}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theLong + * the {@code long} value value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setLong(int parameterIndex, long theLong) throws SQLException; + + /** + * Sets the maximum number of bytes which can be returned for a column value + * where the column type is one of {@code BINARY}, {@code VARBINARY}, + * {@code LONGVARBINARYBINARY}, {@code CHAR}, {@code VARCHAR}, or {@code + * LONGVARCHAR}. Data which exceeds this limit is silently discarded. For + * portability, a value greater than 256 is recommended. + * + * @param max + * the maximum size of the returned column value in bytes. 0 + * implies no size limit. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setMaxFieldSize(int max) throws SQLException; + + /** + * Sets the maximum number of rows which can be held by the {@code RowSet}. + * Any additional rows are silently discarded. + * + * @param max + * the maximum number of rows which can be held in the {@code + * RowSet}. 0 means no limit. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setMaxRows(int max) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to SQL {@code NULL}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param sqlType + * the type of the parameter, as defined by {@code + * java.sql.Types}. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setNull(int parameterIndex, int sqlType) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to SQL {@code NULL}. This form of the {@code setNull} method should be + * used for User Defined Types and {@code REF} parameters. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param sqlType + * the type of the parameter, as defined by {@code + * java.sql.Types}. + * @param typeName + * the fully qualified name of an SQL user defined type or the + * name of the SQL structured type referenced by a {@code REF} + * type. Ignored if the sqlType is not a UDT or REF type. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setNull(int parameterIndex, int sqlType, String typeName) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to a supplied Java object. + * <p> + * The JDBC specification provides a standard mapping for Java objects to + * SQL data types. Database specific types can be mapped by JDBC driver + * specific Java types. + * </p> + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theObject + * the Java object containing the data value to which the + * parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setObject(int parameterIndex, Object theObject) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to a supplied Java object. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theObject + * the Java object containing the data value. + * @param targetSqlType + * the SQL type to send to the database, as defined in {@code + * java.sql.Types}. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setObject(int parameterIndex, Object theObject, + int targetSqlType) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to a supplied Java object. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theObject + * the Java object containing the data value. + * @param targetSqlType + * the SQL type to send to the database, as defined in {@code + * java.sql.Types}. + * @param scale + * the number of digits after the decimal point, for {@code + * java.sql.Types.DECIMAL} and {@code java.sql.Types.NUMERIC} + * types. Ignored for all other types. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setObject(int parameterIndex, Object theObject, + int targetSqlType, int scale) throws SQLException; + + /** + * Sets the database Password for this {@code RowSet}. This property is used + * when a connection to the database is established. Therefore it should be + * set prior to invoking the {@link #execute} method. + * + * @param password + * a {@code String} holding the password. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setPassword(String password) throws SQLException; + + /** + * Gets the timeout for the driver when a query operation is executed. If a + * query takes longer than the timeout, a {@code SQLException} is thrown. + * + * @param seconds + * the number of seconds for the timeout. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setQueryTimeout(int seconds) throws SQLException; + + /** + * Sets whether the {@code RowSet} is read-only or updatable. + * + * @param readOnly + * {@code true} to set the {@code RowSet} to read-only state, + * {@code false} to allow updates. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setReadOnly(boolean readOnly) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to a supplied {@code java.sql.Ref}. This is sent to the database as an + * SQL {@code REF} value. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theRef + * the value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @see java.sql.Ref + * @since Android 1.0 + */ + public void setRef(int parameterIndex, Ref theRef) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to a supplied {@code short integer}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theShort + * the value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setShort(int parameterIndex, short theShort) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to a supplied {@code String}. The string is placed into the database as a + * {@code VARCHAR} or {@code LONGVARCHAR} SQL value, depending on the + * database limits for the length of {@code VARCHAR} values. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theString + * the value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setString(int parameterIndex, String theString) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to a supplied {@code java.sql.Time}, converting it to an SQL {@code TIME} + * value using the system default {@code Calendar}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theTime + * the value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @see java.util.Calendar + * @see java.sql.Time + * @since Android 1.0 + */ + public void setTime(int parameterIndex, Time theTime) throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to a supplied {@code java.sql.Time}, converting it to an SQL {@code TIME} + * value using a supplied {@code Calendar}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theTime + * the value to which the parameter is set. + * @param theCalendar + * the {@code Calendar} to use in the conversion operation. + * @throws SQLException + * if an error occurs accessing the database. + * @see java.util.Calendar + * @see java.sql.Time + * @since Android 1.0 + */ + public void setTime(int parameterIndex, Time theTime, Calendar theCalendar) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to a supplied {@code java.sql.Timestamp}, converting it to an SQL {@code + * TIMESTAMP} value using the system default {@code Calendar}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theTimestamp + * the value to which the parameter is set. + * @throws SQLException + * if an error occurs accessing the database. + * @see java.util.Calendar + * @see java.sql.Timestamp + * @since Android 1.0 + */ + public void setTimestamp(int parameterIndex, Timestamp theTimestamp) + throws SQLException; + + /** + * Sets the value of the specified parameter in the {@code RowSet} command + * to a supplied {@code java.sql.Timestamp}, converting it to an SQL {@code + * TIMESTAMP} value using a supplied {@code Calendar}. + * + * @param parameterIndex + * the index of the parameter to set; the first parameter's index + * is 1. + * @param theTimestamp + * the value to which the parameter is set. + * @param theCalendar + * the {@code Calendar} to use in the conversion operation + * @throws SQLException + * if an error occurs accessing the database. + * @see java.util.Calendar + * @see java.sql.Timestamp + * @since Android 1.0 + */ + public void setTimestamp(int parameterIndex, Timestamp theTimestamp, + Calendar theCalendar) throws SQLException; + + /** + * Sets the target instance's transaction isolation level to one of a + * discrete set of possible values. The transaction isolation level defines + * the policy implemented on the database for maintaining the data values + * consistent. + * <p> + * Keep in mind that setting a transaction isolation level has no effect + * unless your driver and DBMS support it. + * </p> + * + * @param level + * the transaction isolation level. One of: + * <ul> + * <li>{@code Connection.TRANSACTION_READ_UNCOMMITTED}</li> + * <li>{@code Connection.TRANSACTION_READ_COMMITTED}</li> + * <li>{@code Connection.TRANSACTION_REPEATABLE_READ}</li> + * <li>{@code Connection.TRANSACTION_SERIALIZABLE}</li> + * </ul> + * @throws SQLException + * if an error occurs accessing the database. + * @see java.sql.Connection + * @since Android 1.0 + */ + public void setTransactionIsolation(int level) throws SQLException; + + /** + * Sets the type of this {@code RowSet}. By default, the type is + * non-scrollable. + * + * @param type + * the type for the {@code RowSet}. One of: + * <ul> + * <li>{@code ResultSet.TYPE_FORWARD_ONLY}</li> + * <li>{@code ResultSet.TYPE_SCROLL_INSENSITIVE}</li> + * <li>{@code ResultSet.TYPE_SCROLL_SENSITIVE}</li> + * </ul> + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setType(int type) throws SQLException; + + /** + * Sets the mapping of SQL User Defined Types (UDTs) to Java classes. The + * Java classes must all implement the {@link java.sql.SQLData SQLData} + * interface. + * + * @param theTypeMap + * the names of SQL UDTs and the Java classes to which they are + * mapped. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setTypeMap(Map<String, Class<?>> theTypeMap) + throws SQLException; + + /** + * Sets the URL used by this {@code RowSet} to access the database via a + * {@code DriverManager}. The URL is optional - an alternative is to use a + * database name to create a connection. + * + * @param theURL + * the URL for the database. Can be {@code null}. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setUrl(String theURL) throws SQLException; + + /** + * Sets the {@code Username} property for the {@code RowSet}, used to + * authenticate a connection to the database. + * + * @param theUsername + * the new user name for this row set. + * @throws SQLException + * if an error occurs accessing the database. + * @since Android 1.0 + */ + public void setUsername(String theUsername) throws SQLException; +} diff --git a/sql/src/main/java/javax/sql/RowSetEvent.java b/sql/src/main/java/javax/sql/RowSetEvent.java new file mode 100644 index 0000000..9d4c98c --- /dev/null +++ b/sql/src/main/java/javax/sql/RowSetEvent.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.util.EventObject; +import java.io.Serializable; + +/** + * An event which is sent when specific events happen to a {@link RowSet} + * object. The events are sent to inform registered listeners that changes have + * occurred to the {@code RowSet}. The events covered are: + * <ol> + * <li>A single row in the {@code RowSet} changes.</li> + * <li>The whole set of data in the {@code RowSet} changes.</li> + * <li>The {@code RowSet} cursor position changes.</li> + * </ol> + * <p> + * The event contains a reference to the {@code RowSet} object which generated + * the message so that the listeners can extract whatever information they need + * from that reference. + * </p> + * + * @since Android 1.0 + */ +public class RowSetEvent extends EventObject implements Serializable { + + private static final long serialVersionUID = -1875450876546332005L; + + /** + * Creates a {@code RowSetEvent} object containing a reference to the + * {@link RowSet} object that generated the event. Information about the + * changes that have occurred to the {@code RowSet} can be extracted from + * the {@code RowSet} using one or more of the query methods available on + * the {@code RowSet}. + * + * @param theSource + * the {@code RowSet} which generated the event. + * @since Android 1.0 + */ + public RowSetEvent(RowSet theSource) { + super(theSource); + } +} diff --git a/sql/src/main/java/javax/sql/RowSetInternal.java b/sql/src/main/java/javax/sql/RowSetInternal.java new file mode 100644 index 0000000..baa261d --- /dev/null +++ b/sql/src/main/java/javax/sql/RowSetInternal.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.sql.SQLException; +import java.sql.Connection; +import java.sql.ResultSet; + +/** + * An interface provided by a {@code RowSet} object to let either a {@code RowSetReader} or a + * {@code RowSetWriter} access its internal state, thereby providing facilities to read and update the state of + * the {@code RowSet}. + */ +public interface RowSetInternal { + + /** + * Gets the connection associated with this {@code RowSet} object. + * + * @return the connection or {@code null}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public Connection getConnection() throws SQLException; + + /** + * Gets the {@code ResultSet} that was the original (unmodified) content of + * the {@code RowSet}. + * <p> + * The {@code ResultSet}'s cursor is positioned before the first row of + * data. + * </p> + * + * @return the {@code ResultSet} that contained the original data value of + * the {@code RowSet}. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public ResultSet getOriginal() throws SQLException; + + /** + * Gets the original value of the current row only. If the current row did + * not have an original value, then an empty value is returned. + * + * @return a {@code ResultSet} containing the value of the current row only. + * @throws SQLException + * if there is a problem accessing the database, or if the + * cursor is not on a valid row (before the first row, after the + * last one or pointing to the insert row). + * @since Android 1.0 + */ + public ResultSet getOriginalRow() throws SQLException; + + /** + * Gets the parameter values that have been set for this {@code RowSet}'s + * command. + * + * @return the values of parameters that have been set. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public Object[] getParams() throws SQLException; + + /** + * Sets {@code RowSetMetaData} for this {@code RowSet}. The {@code + * RowSetMetaData} is used by a {@code RowSetReader} to set values giving + * information about the {@code RowSet}'s columns. + * + * @param theMetaData + * holds the metadata about the {@code RowSet}'s columns. + * @throws SQLException + * if there is a problem accessing the database. + * @since Android 1.0 + */ + public void setMetaData(RowSetMetaData theMetaData) throws SQLException; +} diff --git a/sql/src/main/java/javax/sql/RowSetListener.java b/sql/src/main/java/javax/sql/RowSetListener.java new file mode 100644 index 0000000..06a7253 --- /dev/null +++ b/sql/src/main/java/javax/sql/RowSetListener.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.util.EventListener; + +/** + * An interface used to send notification of events occurring in the context of + * a {@link RowSet}. To receive the notification events, an object must + * implement the {@code RowSetListener} interface and then register itself with + * the {@code RowSet} of interest using the + * {@link RowSet#addRowSetListener(RowSetListener)} method. + * + * @since Android 1.0 + */ +public interface RowSetListener extends EventListener { + + /** + * Notifies the listener that the {@code RowSet}'s cursor in {@code + * theEvent.getSource} has moved. + * + * @param theEvent + * a {@code RowSetEvent} that contains information about the + * {@code RowSet} involved. This information can be used to + * retrieve information about the change, such as the updated + * data values. + * @since Android 1.0 + */ + public void cursorMoved(RowSetEvent theEvent); + + /** + * Notifies the listener that one of the {@code RowSet}'s rows in {@code + * theEvent.getSource} has changed. + * + * @param theEvent + * a {@code RowSetEvent} that contains information about the + * {@code RowSet} involved. This information can be used to + * retrieve information about the change, such as the new cursor + * position. + * @since Android 1.0 + */ + public void rowChanged(RowSetEvent theEvent); + + /** + * Notifies the listener that the {@code RowSet}'s entire contents in + * {@code theEvent.getSource} have been updated (an example is the execution + * of a command which retrieves new data from the database). + * + * @param theEvent + * a {@code RowSetEvent} that contains information about the + * {@code RowSet} involved. This information can be used to + * retrieve information about the change, such as the updated + * rows of data. + * @since Android 1.0 + */ + public void rowSetChanged(RowSetEvent theEvent); +} diff --git a/sql/src/main/java/javax/sql/RowSetMetaData.java b/sql/src/main/java/javax/sql/RowSetMetaData.java new file mode 100644 index 0000000..3051876 --- /dev/null +++ b/sql/src/main/java/javax/sql/RowSetMetaData.java @@ -0,0 +1,314 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +/** + * An interface which provides facilities for getting information about the + * columns in a {@code RowSet}. + * <p> + * {@code RowSetMetaData} extends {@link java.sql.ResultSetMetaData}, adding new + * operations for carrying out value sets. + * </p> + * <p> + * Application code would not normally call this interface directly. It would be + * called internally when {@code RowSet.execute} is called. + * </p> + * + * @see RowSetInternal#setMetaData(RowSetMetaData) + * @since Android 1.0 + */ +public interface RowSetMetaData extends ResultSetMetaData { + + /** + * Sets automatic numbering for a specified column in the {@code RowSet}. If + * automatic numbering is on, the column is read-only. The default value for + * the auto increment parameter is {@code false}. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param autoIncrement + * {@code true} to set automatic numbering on, {@code false} to + * turn it off (default). + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setAutoIncrement(int columnIndex, boolean autoIncrement) + throws SQLException; + + /** + * Sets the case sensitive property for a specified column in the {@code + * RowSet}. The default is that the column is not case sensitive. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param caseSensitive + * {@code true} to make the column case sensitive, {@code false} + * to make it case insensitive (default). + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setCaseSensitive(int columnIndex, boolean caseSensitive) + throws SQLException; + + /** + * Sets the catalog name for a specified column in the {@code RowSet}. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param catalogName + * the new catalog's name. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setCatalogName(int columnIndex, String catalogName) + throws SQLException; + + /** + * Sets the number of columns contained in the row set. + * + * @param columnCount + * the number of columns contained in the {@code RowSet}. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setColumnCount(int columnCount) throws SQLException; + + /** + * Sets the normal maximum width in characters for a specified column in the + * {@code RowSet}. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param displaySize + * the normal maximum column width in characters. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setColumnDisplaySize(int columnIndex, int displaySize) + throws SQLException; + + /** + * Sets the suggested name as label for the column contained in the {@code + * RowSet}. The label is an alias for printing and displaying purposes. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param theLabel + * the alias name for the column. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setColumnLabel(int columnIndex, String theLabel) + throws SQLException; + + /** + * Sets the column name for a specified column in the {@code RowSet}. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param theColumnName + * the column's label. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setColumnName(int columnIndex, String theColumnName) + throws SQLException; + + /** + * Sets the SQL type for a specified column in the {@code RowSet}. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param theSQLType + * the SQL Type, as defined by {@code java.sql.Types}. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setColumnType(int columnIndex, int theSQLType) + throws SQLException; + + /** + * Sets the type name for a specified column in the {@code RowSet}, where + * the data type is specific to the data source. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param theTypeName + * the SQL type name for the column. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setColumnTypeName(int columnIndex, String theTypeName) + throws SQLException; + + /** + * Sets whether a specified column is a currency value. The default value is + * {@code false}. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param isCurrency + * {@code true} if the column should be treated as a currency + * value, {@code false} if it should not be treated as a currency + * value (default). + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setCurrency(int columnIndex, boolean isCurrency) + throws SQLException; + + /** + * Sets whether a specified column can contain SQL {@code NULL} values. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param nullability + * an integer which is one of the following values: + * <ul> + * <li>{@code ResultSetMetaData.columnNoNulls}</li> + * <li>{@code ResultSetMetaData.columnNullable}</li> + * <li>{@code ResultSetMetaData.columnNullableUnknown}</li> + * </ul> + * <p> + * The default value is {@code + * ResultSetMetaData.columnNullableUnknown}. + * </p> + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setNullable(int columnIndex, int nullability) + throws SQLException; + + /** + * Sets the number of decimal digits for a specified column in the {@code + * RowSet}. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param thePrecision + * the number of decimal digits. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setPrecision(int columnIndex, int thePrecision) + throws SQLException; + + /** + * Declares how many decimal digits there should be after a decimal point + * for the column specified by {@code columnIndex}. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param theScale + * the number of digits after the decimal point. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setScale(int columnIndex, int theScale) throws SQLException; + + /** + * Sets the schema name for a specified column in the {@code RowSet}. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param theSchemaName + * a {@code String} containing the schema name. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setSchemaName(int columnIndex, String theSchemaName) + throws SQLException; + + /** + * Sets whether a specified column can be used in a search involving a + * {@code WHERE} clause. The default value is {@code false}. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param isSearchable + * {@code true} of the column can be used in a {@code WHERE} + * clause search, {@code false} otherwise. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setSearchable(int columnIndex, boolean isSearchable) + throws SQLException; + + /** + * Sets if a specified column can contain signed numbers. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param isSigned + * {@code true} if the column can contain signed numbers, {@code + * false} otherwise. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setSigned(int columnIndex, boolean isSigned) + throws SQLException; + + /** + * Sets the table name for a specified column in the {@code RowSet}. + * + * @param columnIndex + * the index number for the column; the first column's index is + * 1. + * @param theTableName + * the table name for the column. + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public void setTableName(int columnIndex, String theTableName) + throws SQLException; +} diff --git a/sql/src/main/java/javax/sql/RowSetReader.java b/sql/src/main/java/javax/sql/RowSetReader.java new file mode 100644 index 0000000..d4a902f --- /dev/null +++ b/sql/src/main/java/javax/sql/RowSetReader.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.sql.SQLException; + +/** + * An interface which provides functionality for a disconnected {@code RowSet} + * to get data from a database into its rows. The {@code RowSet} calls the + * {@code RowSetReader} interface when the {@code RowSet}'s execute method is + * invoked - a {@code RowSetReader} must first be registered with the {@code + * RowSet} for this to work. + * + * @see RowSet + * @since Android 1.0 + */ +public interface RowSetReader { + + /** + * Reads new data into the {@code RowSet}. The calling {@code RowSet} object + * must itself implement the {@code RowSetInternal} interface and the + * {@code RowSetReader} must be registered as a reader on the + * {@code RowSet}. + * <p> + * This method adds rows into the calling {@code RowSet}. The reader may + * invoke any of the {@code RowSet}'s methods except for the {@code execute} + * method (calling {@code execute} will cause an {@code SQLException} to be + * thrown). However, when the reader calls the {@code RowSet}'s methods, no + * events are sent to listeners - any listeners are informed by the calling + * {@code RowSet}'s {@code execute} method once the reader returns from the + * {@code readData} method. + * </p> + * + * @param theCaller + * must be the calling {@code RowSet} object, which must have + * implemented the {@code RowSetInternal} interface. + * @throws SQLException + * if a problem occurs accessing the database or if the reader + * calls the {@link RowSet#execute()} method. + * @see RowSetInternal + * @since Android 1.0 + */ + public void readData(RowSetInternal theCaller) throws SQLException; +} diff --git a/sql/src/main/java/javax/sql/RowSetWriter.java b/sql/src/main/java/javax/sql/RowSetWriter.java new file mode 100644 index 0000000..34473b2 --- /dev/null +++ b/sql/src/main/java/javax/sql/RowSetWriter.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package javax.sql; + +import java.sql.SQLException; + +/** + * An interface which provides functionality for a disconnected {@code RowSet} + * to put data updates back to the data source from which the {@code RowSet} was + * originally populated. An object implementing this interface is called a + * writer. + * <p> + * The writer must establish a connection to the {@code RowSet}'s database + * before writing the data. The {@code RowSet} calling this interface must + * implement the {@code RowSetInternal} interface. + * </p> + * <p> + * The writer may encounter a situation where the updated data needs to be + * written back to the database, but has already been updated there in the mean + * time. How a conflict of this kind is handled is determined by the + * implementation of this writer. + * </p> + * + * @see RowSetInternal + * @since Android 1.0 + */ +public interface RowSetWriter { + + /** + * Writes changes made in the {@code RowSet}, which is associated with this + * {@code RowSetWriter}, back to the database. + * + * @param theRowSet + * a row set that fulfills the following criteria: + * <ul> + * <li>it must implement the {@code RowSetInternal} interface,</li> + * <li>have this {@code RowSetWriter} registered with it,</li> + * <li>must call this method internally.</li> + * </ul> + * @return {@code true} if the modified data was written, {@code false} + * otherwise (which typically implies some form of conflict). + * @throws SQLException + * if a problem occurs accessing the database. + * @since Android 1.0 + */ + public boolean writeData(RowSetInternal theRowSet) throws SQLException; +} diff --git a/sql/src/main/java/javax/sql/package.html b/sql/src/main/java/javax/sql/package.html new file mode 100644 index 0000000..6c9500f --- /dev/null +++ b/sql/src/main/java/javax/sql/package.html @@ -0,0 +1,9 @@ +<html> + <body> + <p> + Provides extensions to the standard interface for accessing SQL-based + databases. + <p> + @since Android 1.0 + </body> +</html>
\ No newline at end of file diff --git a/sql/src/main/java/org/apache/harmony/sql/internal/nls/Messages.java b/sql/src/main/java/org/apache/harmony/sql/internal/nls/Messages.java new file mode 100644 index 0000000..b3dbd32 --- /dev/null +++ b/sql/src/main/java/org/apache/harmony/sql/internal/nls/Messages.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL. + * All changes made to this file manually will be overwritten + * if this tool runs again. Better make changes in the template file. + */ + +// BEGIN android-note +// Redundant code has been removed and is now called from MsgHelp. +// END android-note + +package org.apache.harmony.sql.internal.nls; + + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +// BEGIN android-changed +import org.apache.harmony.luni.util.MsgHelp; +// END android-changed + +/** + * This class retrieves strings from a resource bundle and returns them, + * formatting them with MessageFormat when required. + * <p> + * It is used by the system classes to provide national language support, by + * looking up messages in the <code> + * org.apache.harmony.sql.internal.nls.messages + * </code> + * resource bundle. Note that if this file is not available, or an invalid key + * is looked up, or resource bundle support is not available, the key itself + * will be returned as the associated message. This means that the <em>KEY</em> + * should a reasonable human-readable (english) string. + * + */ +public class Messages { + + // BEGIN android-changed + private static final String sResource = + "org.apache.harmony.sql.internal.nls.messages"; //$NON-NLS-1$ + // END android-changed + + /** + * Retrieves a message which has no arguments. + * + * @param msg + * String the key to look up. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg) { + // BEGIN android-changed + return MsgHelp.getString(sResource, msg); + // END android-changed + } + + /** + * Retrieves a message which takes 1 argument. + * + * @param msg + * String the key to look up. + * @param arg + * Object the object to insert in the formatted output. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg, Object arg) { + return getString(msg, new Object[] { arg }); + } + + /** + * Retrieves a message which takes 1 integer argument. + * + * @param msg + * String the key to look up. + * @param arg + * int the integer to insert in the formatted output. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg, int arg) { + return getString(msg, new Object[] { Integer.toString(arg) }); + } + + /** + * Retrieves a message which takes 1 character argument. + * + * @param msg + * String the key to look up. + * @param arg + * char the character to insert in the formatted output. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg, char arg) { + return getString(msg, new Object[] { String.valueOf(arg) }); + } + + /** + * Retrieves a message which takes 2 arguments. + * + * @param msg + * String the key to look up. + * @param arg1 + * Object an object to insert in the formatted output. + * @param arg2 + * Object another object to insert in the formatted output. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg, Object arg1, Object arg2) { + return getString(msg, new Object[] { arg1, arg2 }); + } + + /** + * Retrieves a message which takes several arguments. + * + * @param msg + * String the key to look up. + * @param args + * Object[] the objects to insert in the formatted output. + * @return String the message for that key in the system message bundle. + */ + static public String getString(String msg, Object[] args) { + // BEGIN android-changed + return MsgHelp.getString(sResource, msg, args); + // END android-changed + } + + // BEGIN android-note + // Duplicate code was dropped in favor of using MsgHelp. + // END android-note +} diff --git a/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties b/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties new file mode 100644 index 0000000..3e6ff1d --- /dev/null +++ b/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties @@ -0,0 +1,42 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# messages for EN locale +sql.0=Value out of range +sql.1=DriverManager: calling class not authorized to deregister JDBC driver +sql.2=Timestamp format must be yyyy-mm-dd hh:mm:ss.fffffffff +sql.3=Argument cannot be null +sql.4=Bad input string format: expected '.' not {0} +sql.5=The url cannot be null +sql.6=No suitable driver +sql.8=SQLWarning chain holds value that is not a SQLWarning +sql.9=Cannot instantiate a SerialRef object with a null Ref object +sql.10=Cannot instantiate a SerialRef object that returns a null base type name +sql.11=SQLException: {0} +sql.12=Cannot serialize empty URL instance +sql.13=Cannot instantiate a SerialBlob object with a null Blob object +sql.14=Invalid starting position or length +sql.15=Invalid position in BLOB object set +sql.16=Invalid offset in byte array set +sql.17=javax.sql.rowset.serial.SerialException: Length more than what can be truncated +sql.18=Unsupported operation. SerialBlob cannot return a writable binary stream, unless instantiated with a Blob object that provides a setBinaryStream() implementation +sql.19=Cannot instantiate a SerialClob object with a null Clob object +sql.20=Invalid Clob object. Calls to getCharacterStream or getAsciiStream return null which cannot be serialized. +sql.21=Invalid position in CLOB object set +sql.22=Invalid position and substring length +sql.23=Buffer is not sufficient to hold the value +sql.24=Invalid length for truncate +sql.25=Unsupported operation. SerialClob is not instantiated with a fully implemented Clob object. |