mirror of
https://github.com/amalthea-mc/ShopChest.git
synced 2024-11-22 10:22:29 +00:00
Removed SQLite Library
This commit is contained in:
parent
246cd5d298
commit
1309591d4c
@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
interface Codes
|
|
||||||
{
|
|
||||||
/** Successful result */
|
|
||||||
public static final int SQLITE_OK = 0;
|
|
||||||
|
|
||||||
/** SQL error or missing database */
|
|
||||||
public static final int SQLITE_ERROR = 1;
|
|
||||||
|
|
||||||
/** An internal logic error in SQLite */
|
|
||||||
public static final int SQLITE_INTERNAL = 2;
|
|
||||||
|
|
||||||
/** Access permission denied */
|
|
||||||
public static final int SQLITE_PERM = 3;
|
|
||||||
|
|
||||||
/** Callback routine requested an abort */
|
|
||||||
public static final int SQLITE_ABORT = 4;
|
|
||||||
|
|
||||||
/** The database file is locked */
|
|
||||||
public static final int SQLITE_BUSY = 5;
|
|
||||||
|
|
||||||
/** A table in the database is locked */
|
|
||||||
public static final int SQLITE_LOCKED = 6;
|
|
||||||
|
|
||||||
/** A malloc() failed */
|
|
||||||
public static final int SQLITE_NOMEM = 7;
|
|
||||||
|
|
||||||
/** Attempt to write a readonly database */
|
|
||||||
public static final int SQLITE_READONLY = 8;
|
|
||||||
|
|
||||||
/** Operation terminated by sqlite_interrupt() */
|
|
||||||
public static final int SQLITE_INTERRUPT = 9;
|
|
||||||
|
|
||||||
/** Some kind of disk I/O error occurred */
|
|
||||||
public static final int SQLITE_IOERR = 10;
|
|
||||||
|
|
||||||
/** The database disk image is malformed */
|
|
||||||
public static final int SQLITE_CORRUPT = 11;
|
|
||||||
|
|
||||||
/** (Internal Only) Table or record not found */
|
|
||||||
public static final int SQLITE_NOTFOUND = 12;
|
|
||||||
|
|
||||||
/** Insertion failed because database is full */
|
|
||||||
public static final int SQLITE_FULL = 13;
|
|
||||||
|
|
||||||
/** Unable to open the database file */
|
|
||||||
public static final int SQLITE_CANTOPEN = 14;
|
|
||||||
|
|
||||||
/** Database lock protocol error */
|
|
||||||
public static final int SQLITE_PROTOCOL = 15;
|
|
||||||
|
|
||||||
/** (Internal Only) Database table is empty */
|
|
||||||
public static final int SQLITE_EMPTY = 16;
|
|
||||||
|
|
||||||
/** The database schema changed */
|
|
||||||
public static final int SQLITE_SCHEMA = 17;
|
|
||||||
|
|
||||||
/** Too much data for one row of a table */
|
|
||||||
public static final int SQLITE_TOOBIG = 18;
|
|
||||||
|
|
||||||
/** Abort due to constraint violation */
|
|
||||||
public static final int SQLITE_CONSTRAINT = 19;
|
|
||||||
|
|
||||||
/** Data type mismatch */
|
|
||||||
public static final int SQLITE_MISMATCH = 20;
|
|
||||||
|
|
||||||
/** Library used incorrectly */
|
|
||||||
public static final int SQLITE_MISUSE = 21;
|
|
||||||
|
|
||||||
/** Uses OS features not supported on host */
|
|
||||||
public static final int SQLITE_NOLFS = 22;
|
|
||||||
|
|
||||||
/** Authorization denied */
|
|
||||||
public static final int SQLITE_AUTH = 23;
|
|
||||||
|
|
||||||
/** sqlite_step() has another row ready */
|
|
||||||
public static final int SQLITE_ROW = 100;
|
|
||||||
|
|
||||||
/** sqlite_step() has finished executing */
|
|
||||||
public static final int SQLITE_DONE = 101;
|
|
||||||
|
|
||||||
|
|
||||||
// types returned by sqlite3_column_type()
|
|
||||||
|
|
||||||
public static final int SQLITE_INTEGER = 1;
|
|
||||||
public static final int SQLITE_FLOAT = 2;
|
|
||||||
public static final int SQLITE_TEXT = 3;
|
|
||||||
public static final int SQLITE_BLOB = 4;
|
|
||||||
public static final int SQLITE_NULL = 5;
|
|
||||||
}
|
|
@ -1,440 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.sql.CallableStatement;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DatabaseMetaData;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.SQLWarning;
|
|
||||||
import java.sql.Savepoint;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.sql.Struct;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
class Conn implements Connection
|
|
||||||
{
|
|
||||||
private final String url;
|
|
||||||
private String fileName;
|
|
||||||
private DB db = null;
|
|
||||||
private MetaData meta = null;
|
|
||||||
private boolean autoCommit = true;
|
|
||||||
private int transactionIsolation = TRANSACTION_SERIALIZABLE;
|
|
||||||
private int timeout = 0;
|
|
||||||
|
|
||||||
public Conn(String url, String fileName) throws SQLException {
|
|
||||||
this(url, fileName, new Properties());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Conn(String url, String fileName, Properties prop) throws SQLException {
|
|
||||||
this.url = url;
|
|
||||||
this.fileName = fileName;
|
|
||||||
|
|
||||||
SQLiteConfig config = new SQLiteConfig(prop);
|
|
||||||
open(config.getOpenModeFlags());
|
|
||||||
|
|
||||||
boolean enableSharedCache = config.isEnabledSharedCache();
|
|
||||||
boolean enableLoadExtension = config.isEnabledLoadExtension();
|
|
||||||
db.shared_cache(enableSharedCache);
|
|
||||||
db.enable_load_extension(enableLoadExtension);
|
|
||||||
|
|
||||||
// set pragmas
|
|
||||||
config.apply(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String RESOURCE_NAME_PREFIX = ":resource:";
|
|
||||||
|
|
||||||
private void open(int openModeFlags) throws SQLException {
|
|
||||||
// check the path to the file exists
|
|
||||||
if (!":memory:".equals(fileName)) {
|
|
||||||
if (fileName.startsWith(RESOURCE_NAME_PREFIX)) {
|
|
||||||
String resourceName = fileName.substring(RESOURCE_NAME_PREFIX.length());
|
|
||||||
|
|
||||||
// search the class path
|
|
||||||
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
|
|
||||||
URL resourceAddr = contextCL.getResource(resourceName);
|
|
||||||
if (resourceAddr == null) {
|
|
||||||
try {
|
|
||||||
resourceAddr = new URL(resourceName);
|
|
||||||
}
|
|
||||||
catch (MalformedURLException e) {
|
|
||||||
throw new SQLException(String.format("resource %s not found: %s", resourceName, e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
fileName = extractResource(resourceAddr).getAbsolutePath();
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new SQLException(String.format("failed to load %s: %s", resourceName, e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
File file = new File(fileName).getAbsoluteFile();
|
|
||||||
File parent = file.getParentFile();
|
|
||||||
if (parent != null && !parent.exists()) {
|
|
||||||
for (File up = parent; up != null && !up.exists();) {
|
|
||||||
parent = up;
|
|
||||||
up = up.getParentFile();
|
|
||||||
}
|
|
||||||
throw new SQLException("path to '" + fileName + "': '" + parent + "' does not exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
// check write access if file does not exist
|
|
||||||
try {
|
|
||||||
// The extra check to exists() is necessary as createNewFile()
|
|
||||||
// does not follow the JavaDoc when used on read-only shares.
|
|
||||||
if (!file.exists() && file.createNewFile())
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new SQLException("opening db: '" + fileName + "': " + e.getMessage());
|
|
||||||
}
|
|
||||||
fileName = file.getAbsolutePath();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// tries to load native library first
|
|
||||||
try {
|
|
||||||
Class< ? > nativedb = Class.forName("org.sqlite.NativeDB");
|
|
||||||
if (((Boolean) nativedb.getDeclaredMethod("load", (Class< ? >[]) null).invoke((Object) null,
|
|
||||||
(Object[]) null)).booleanValue())
|
|
||||||
db = (DB) nativedb.newInstance();
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception e) {} // fall through to nested library
|
|
||||||
|
|
||||||
// load nested library (pure-java SQLite)
|
|
||||||
if (db == null) {
|
|
||||||
try {
|
|
||||||
db = (DB) Class.forName("org.sqlite.NestedDB").newInstance();
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new SQLException("no SQLite library found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
db.open(this, fileName, openModeFlags);
|
|
||||||
setTimeout(3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param resourceAddr
|
|
||||||
* @return extracted file name
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private File extractResource(URL resourceAddr) throws IOException {
|
|
||||||
if (resourceAddr.getProtocol().equals("file")) {
|
|
||||||
try {
|
|
||||||
return new File(resourceAddr.toURI());
|
|
||||||
}
|
|
||||||
catch (URISyntaxException e) {
|
|
||||||
throw new IOException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String tempFolder = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath();
|
|
||||||
String dbFileName = String.format("sqlite-jdbc-tmp-%d.db", resourceAddr.hashCode());
|
|
||||||
File dbFile = new File(tempFolder, dbFileName);
|
|
||||||
|
|
||||||
if (dbFile.exists()) {
|
|
||||||
long resourceLastModified = resourceAddr.openConnection().getLastModified();
|
|
||||||
long tmpFileLastModified = dbFile.lastModified();
|
|
||||||
if (resourceLastModified < tmpFileLastModified) {
|
|
||||||
return dbFile;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// remove the old DB file
|
|
||||||
boolean deletionSucceeded = dbFile.delete();
|
|
||||||
if (!deletionSucceeded) {
|
|
||||||
throw new IOException("failed to remove existing DB file: " + dbFile.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String md5sum1 = SQLiteJDBCLoader.md5sum(resourceAddr.openStream());
|
|
||||||
// String md5sum2 = SQLiteJDBCLoader.md5sum(new FileInputStream(dbFile));
|
|
||||||
//
|
|
||||||
// if (md5sum1.equals(md5sum2))
|
|
||||||
// return dbFile; // no need to extract the DB file
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] buffer = new byte[8192]; // 8K buffer
|
|
||||||
FileOutputStream writer = new FileOutputStream(dbFile);
|
|
||||||
InputStream reader = resourceAddr.openStream();
|
|
||||||
try {
|
|
||||||
int bytesRead = 0;
|
|
||||||
while ((bytesRead = reader.read(buffer)) != -1) {
|
|
||||||
writer.write(buffer, 0, bytesRead);
|
|
||||||
}
|
|
||||||
return dbFile;
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
writer.close();
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int getTimeout() {
|
|
||||||
return timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTimeout(int ms) throws SQLException {
|
|
||||||
timeout = ms;
|
|
||||||
db.busy_timeout(ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
String url() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
String libversion() throws SQLException {
|
|
||||||
return db.libversion();
|
|
||||||
}
|
|
||||||
|
|
||||||
DB db() {
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkOpen() throws SQLException {
|
|
||||||
if (db == null)
|
|
||||||
throw new SQLException("database connection closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkCursor(int rst, int rsc, int rsh) throws SQLException {
|
|
||||||
if (rst != ResultSet.TYPE_FORWARD_ONLY)
|
|
||||||
throw new SQLException("SQLite only supports TYPE_FORWARD_ONLY cursors");
|
|
||||||
if (rsc != ResultSet.CONCUR_READ_ONLY)
|
|
||||||
throw new SQLException("SQLite only supports CONCUR_READ_ONLY cursors");
|
|
||||||
if (rsh != ResultSet.CLOSE_CURSORS_AT_COMMIT)
|
|
||||||
throw new SQLException("SQLite only supports closing cursors at commit");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void finalize() throws SQLException {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() throws SQLException {
|
|
||||||
if (db == null)
|
|
||||||
return;
|
|
||||||
if (meta != null)
|
|
||||||
meta.close();
|
|
||||||
|
|
||||||
db.close();
|
|
||||||
db = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isClosed() throws SQLException {
|
|
||||||
return db == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCatalog() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCatalog(String catalog) throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHoldability() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
return ResultSet.CLOSE_CURSORS_AT_COMMIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHoldability(int h) throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
if (h != ResultSet.CLOSE_CURSORS_AT_COMMIT)
|
|
||||||
throw new SQLException("SQLite only supports CLOSE_CURSORS_AT_COMMIT");
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTransactionIsolation() {
|
|
||||||
return transactionIsolation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransactionIsolation(int level) throws SQLException {
|
|
||||||
switch (level) {
|
|
||||||
case TRANSACTION_SERIALIZABLE:
|
|
||||||
db.exec("PRAGMA read_uncommitted = false;");
|
|
||||||
break;
|
|
||||||
case TRANSACTION_READ_UNCOMMITTED:
|
|
||||||
db.exec("PRAGMA read_uncommitted = true;");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new SQLException("SQLite supports only TRANSACTION_SERIALIZABLE and TRANSACTION_READ_UNCOMMITTED.");
|
|
||||||
}
|
|
||||||
transactionIsolation = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map getTypeMap() throws SQLException {
|
|
||||||
throw new SQLException("not yet implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTypeMap(Map map) throws SQLException {
|
|
||||||
throw new SQLException("not yet implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReadOnly() throws SQLException {
|
|
||||||
return false;
|
|
||||||
} // FIXME
|
|
||||||
|
|
||||||
public void setReadOnly(boolean ro) throws SQLException {}
|
|
||||||
|
|
||||||
public DatabaseMetaData getMetaData() {
|
|
||||||
if (meta == null)
|
|
||||||
meta = new MetaData(this);
|
|
||||||
return meta;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String nativeSQL(String sql) {
|
|
||||||
return sql;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearWarnings() throws SQLException {}
|
|
||||||
|
|
||||||
public SQLWarning getWarnings() throws SQLException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getAutoCommit() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
return autoCommit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAutoCommit(boolean ac) throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
if (autoCommit == ac)
|
|
||||||
return;
|
|
||||||
autoCommit = ac;
|
|
||||||
db.exec(autoCommit ? "commit;" : "begin;");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void commit() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
if (autoCommit)
|
|
||||||
throw new SQLException("database in auto-commit mode");
|
|
||||||
db.exec("commit;");
|
|
||||||
db.exec("begin;");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void rollback() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
if (autoCommit)
|
|
||||||
throw new SQLException("database in auto-commit mode");
|
|
||||||
db.exec("rollback;");
|
|
||||||
db.exec("begin;");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Statement createStatement() throws SQLException {
|
|
||||||
return createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
|
|
||||||
ResultSet.CLOSE_CURSORS_AT_COMMIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Statement createStatement(int rsType, int rsConcurr) throws SQLException {
|
|
||||||
return createStatement(rsType, rsConcurr, ResultSet.CLOSE_CURSORS_AT_COMMIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Statement createStatement(int rst, int rsc, int rsh) throws SQLException {
|
|
||||||
checkCursor(rst, rsc, rsh);
|
|
||||||
return new Stmt(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CallableStatement prepareCall(String sql) throws SQLException {
|
|
||||||
return prepareCall(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
|
|
||||||
ResultSet.CLOSE_CURSORS_AT_COMMIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CallableStatement prepareCall(String sql, int rst, int rsc) throws SQLException {
|
|
||||||
return prepareCall(sql, rst, rsc, ResultSet.CLOSE_CURSORS_AT_COMMIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CallableStatement prepareCall(String sql, int rst, int rsc, int rsh) throws SQLException {
|
|
||||||
throw new SQLException("SQLite does not support Stored Procedures");
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
|
||||||
return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepareStatement(String sql, int autoC) throws SQLException {
|
|
||||||
return prepareStatement(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepareStatement(String sql, int[] colInds) throws SQLException {
|
|
||||||
return prepareStatement(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepareStatement(String sql, String[] colNames) throws SQLException {
|
|
||||||
return prepareStatement(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepareStatement(String sql, int rst, int rsc) throws SQLException {
|
|
||||||
return prepareStatement(sql, rst, rsc, ResultSet.CLOSE_CURSORS_AT_COMMIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedStatement prepareStatement(String sql, int rst, int rsc, int rsh) throws SQLException {
|
|
||||||
checkCursor(rst, rsc, rsh);
|
|
||||||
return new PrepStmt(this, sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Used to supply DatabaseMetaData.getDriverVersion(). */
|
|
||||||
String getDriverVersion() {
|
|
||||||
if (db != null) {
|
|
||||||
String dbname = db.getClass().getName();
|
|
||||||
if (dbname.indexOf("NestedDB") >= 0)
|
|
||||||
return "pure";
|
|
||||||
if (dbname.indexOf("NativeDB") >= 0)
|
|
||||||
return "native";
|
|
||||||
}
|
|
||||||
return "unloaded";
|
|
||||||
}
|
|
||||||
|
|
||||||
// UNUSED FUNCTIONS /////////////////////////////////////////////
|
|
||||||
|
|
||||||
public Savepoint setSavepoint() throws SQLException {
|
|
||||||
throw new SQLException("unsupported by SQLite: savepoints");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Savepoint setSavepoint(String name) throws SQLException {
|
|
||||||
throw new SQLException("unsupported by SQLite: savepoints");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
|
|
||||||
throw new SQLException("unsupported by SQLite: savepoints");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void rollback(Savepoint savepoint) throws SQLException {
|
|
||||||
throw new SQLException("unsupported by SQLite: savepoints");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Struct createStruct(String t, Object[] attr) throws SQLException {
|
|
||||||
throw new SQLException("unsupported by SQLite");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,444 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.sql.BatchUpdateException;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This class is the interface to SQLite. It provides some helper functions
|
|
||||||
* used by other parts of the driver. The goal of the helper functions here
|
|
||||||
* are not only to provide functionality, but to handle contractual
|
|
||||||
* differences between the JDBC specification and the SQLite C API.
|
|
||||||
*
|
|
||||||
* The process of moving SQLite weirdness into this class is incomplete.
|
|
||||||
* You'll still find lots of code in Stmt and PrepStmt that are doing
|
|
||||||
* implicit contract conversions. Sorry.
|
|
||||||
*
|
|
||||||
* The two subclasses, NativeDB and NestedDB, provide the actual access to
|
|
||||||
* SQLite functions.
|
|
||||||
*/
|
|
||||||
abstract class DB implements Codes
|
|
||||||
{
|
|
||||||
/** The JDBC Connection that 'owns' this database instance. */
|
|
||||||
Conn conn = null;
|
|
||||||
|
|
||||||
/** The "begin;"and "commit;" statement handles. */
|
|
||||||
long begin = 0;
|
|
||||||
long commit = 0;
|
|
||||||
|
|
||||||
/** Tracer for statements to avoid unfinalized statements on db close. */
|
|
||||||
private final Map<Long, Stmt> stmts = new HashMap<Long, Stmt>();
|
|
||||||
|
|
||||||
// WRAPPER FUNCTIONS ////////////////////////////////////////////
|
|
||||||
|
|
||||||
abstract void interrupt() throws SQLException;
|
|
||||||
|
|
||||||
abstract void busy_timeout(int ms) throws SQLException;
|
|
||||||
|
|
||||||
abstract String errmsg() throws SQLException;
|
|
||||||
|
|
||||||
abstract String libversion() throws SQLException;
|
|
||||||
|
|
||||||
abstract int changes() throws SQLException;
|
|
||||||
|
|
||||||
abstract int shared_cache(boolean enable) throws SQLException;
|
|
||||||
|
|
||||||
abstract int enable_load_extension(boolean enable) throws SQLException;
|
|
||||||
|
|
||||||
final synchronized void exec(String sql) throws SQLException {
|
|
||||||
long pointer = 0;
|
|
||||||
try {
|
|
||||||
pointer = prepare(sql);
|
|
||||||
switch (step(pointer)) {
|
|
||||||
case SQLITE_DONE:
|
|
||||||
ensureAutoCommit();
|
|
||||||
return;
|
|
||||||
case SQLITE_ROW:
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
throwex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
finalize(pointer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final synchronized void open(Conn conn, String file, int openFlags) throws SQLException {
|
|
||||||
this.conn = conn;
|
|
||||||
_open(file, openFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
final synchronized void close() throws SQLException {
|
|
||||||
// finalize any remaining statements before closing db
|
|
||||||
synchronized (stmts) {
|
|
||||||
Iterator i = stmts.entrySet().iterator();
|
|
||||||
while (i.hasNext()) {
|
|
||||||
Map.Entry entry = (Map.Entry) i.next();
|
|
||||||
Stmt stmt = (Stmt) entry.getValue();
|
|
||||||
finalize(((Long) entry.getKey()).longValue());
|
|
||||||
if (stmt != null) {
|
|
||||||
stmt.pointer = 0;
|
|
||||||
}
|
|
||||||
i.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove memory used by user-defined functions
|
|
||||||
free_functions();
|
|
||||||
|
|
||||||
// clean up commit object
|
|
||||||
if (begin != 0) {
|
|
||||||
finalize(begin);
|
|
||||||
begin = 0;
|
|
||||||
}
|
|
||||||
if (commit != 0) {
|
|
||||||
finalize(commit);
|
|
||||||
commit = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_close();
|
|
||||||
}
|
|
||||||
|
|
||||||
final synchronized void prepare(Stmt stmt) throws SQLException {
|
|
||||||
if (stmt.pointer != 0)
|
|
||||||
finalize(stmt);
|
|
||||||
stmt.pointer = prepare(stmt.sql);
|
|
||||||
stmts.put(new Long(stmt.pointer), stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
final synchronized int finalize(Stmt stmt) throws SQLException {
|
|
||||||
if (stmt.pointer == 0)
|
|
||||||
return 0;
|
|
||||||
int rc = SQLITE_ERROR;
|
|
||||||
try {
|
|
||||||
rc = finalize(stmt.pointer);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
stmts.remove(new Long(stmt.pointer));
|
|
||||||
stmt.pointer = 0;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void _open(String filename, int openFlags) throws SQLException;
|
|
||||||
|
|
||||||
protected abstract void _close() throws SQLException;
|
|
||||||
|
|
||||||
protected abstract int _exec(String sql) throws SQLException;
|
|
||||||
|
|
||||||
protected abstract long prepare(String sql) throws SQLException;
|
|
||||||
|
|
||||||
protected abstract int finalize(long stmt) throws SQLException;
|
|
||||||
|
|
||||||
protected abstract int step(long stmt) throws SQLException;
|
|
||||||
|
|
||||||
protected abstract int reset(long stmt) throws SQLException;
|
|
||||||
|
|
||||||
abstract int clear_bindings(long stmt) throws SQLException; // TODO remove?
|
|
||||||
|
|
||||||
abstract int bind_parameter_count(long stmt) throws SQLException;
|
|
||||||
|
|
||||||
abstract int column_count(long stmt) throws SQLException;
|
|
||||||
|
|
||||||
abstract int column_type(long stmt, int col) throws SQLException;
|
|
||||||
|
|
||||||
abstract String column_decltype(long stmt, int col) throws SQLException;
|
|
||||||
|
|
||||||
abstract String column_table_name(long stmt, int col) throws SQLException;
|
|
||||||
|
|
||||||
abstract String column_name(long stmt, int col) throws SQLException;
|
|
||||||
|
|
||||||
abstract String column_text(long stmt, int col) throws SQLException;
|
|
||||||
|
|
||||||
abstract byte[] column_blob(long stmt, int col) throws SQLException;
|
|
||||||
|
|
||||||
abstract double column_double(long stmt, int col) throws SQLException;
|
|
||||||
|
|
||||||
abstract long column_long(long stmt, int col) throws SQLException;
|
|
||||||
|
|
||||||
abstract int column_int(long stmt, int col) throws SQLException;
|
|
||||||
|
|
||||||
abstract int bind_null(long stmt, int pos) throws SQLException;
|
|
||||||
|
|
||||||
abstract int bind_int(long stmt, int pos, int v) throws SQLException;
|
|
||||||
|
|
||||||
abstract int bind_long(long stmt, int pos, long v) throws SQLException;
|
|
||||||
|
|
||||||
abstract int bind_double(long stmt, int pos, double v) throws SQLException;
|
|
||||||
|
|
||||||
abstract int bind_text(long stmt, int pos, String v) throws SQLException;
|
|
||||||
|
|
||||||
abstract int bind_blob(long stmt, int pos, byte[] v) throws SQLException;
|
|
||||||
|
|
||||||
abstract void result_null(long context) throws SQLException;
|
|
||||||
|
|
||||||
abstract void result_text(long context, String val) throws SQLException;
|
|
||||||
|
|
||||||
abstract void result_blob(long context, byte[] val) throws SQLException;
|
|
||||||
|
|
||||||
abstract void result_double(long context, double val) throws SQLException;
|
|
||||||
|
|
||||||
abstract void result_long(long context, long val) throws SQLException;
|
|
||||||
|
|
||||||
abstract void result_int(long context, int val) throws SQLException;
|
|
||||||
|
|
||||||
abstract void result_error(long context, String err) throws SQLException;
|
|
||||||
|
|
||||||
abstract int value_bytes(Function f, int arg) throws SQLException;
|
|
||||||
|
|
||||||
abstract String value_text(Function f, int arg) throws SQLException;
|
|
||||||
|
|
||||||
abstract byte[] value_blob(Function f, int arg) throws SQLException;
|
|
||||||
|
|
||||||
abstract double value_double(Function f, int arg) throws SQLException;
|
|
||||||
|
|
||||||
abstract long value_long(Function f, int arg) throws SQLException;
|
|
||||||
|
|
||||||
abstract int value_int(Function f, int arg) throws SQLException;
|
|
||||||
|
|
||||||
abstract int value_type(Function f, int arg) throws SQLException;
|
|
||||||
|
|
||||||
abstract int create_function(String name, Function f) throws SQLException;
|
|
||||||
|
|
||||||
abstract int destroy_function(String name) throws SQLException;
|
|
||||||
|
|
||||||
abstract void free_functions() throws SQLException;
|
|
||||||
|
|
||||||
abstract int backup(String dbName, String destFileName, ProgressObserver observer) throws SQLException;
|
|
||||||
|
|
||||||
abstract int restore(String dbName, String sourceFileName, ProgressObserver observer) throws SQLException;
|
|
||||||
|
|
||||||
public static interface ProgressObserver
|
|
||||||
{
|
|
||||||
public void progress(int remaining, int pageCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides metadata for the columns of a statement. Returns: res[col][0] =
|
|
||||||
* true if column constrained NOT NULL res[col][1] = true if column is part
|
|
||||||
* of the primary key res[col][2] = true if column is auto-increment
|
|
||||||
*/
|
|
||||||
abstract boolean[][] column_metadata(long stmt) throws SQLException;
|
|
||||||
|
|
||||||
// COMPOUND FUNCTIONS ////////////////////////////////////////////
|
|
||||||
|
|
||||||
final synchronized String[] column_names(long stmt) throws SQLException {
|
|
||||||
String[] names = new String[column_count(stmt)];
|
|
||||||
for (int i = 0; i < names.length; i++)
|
|
||||||
names[i] = column_name(stmt, i);
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
final synchronized int sqlbind(long stmt, int pos, Object v) throws SQLException {
|
|
||||||
pos++;
|
|
||||||
if (v == null) {
|
|
||||||
return bind_null(stmt, pos);
|
|
||||||
}
|
|
||||||
else if (v instanceof Integer) {
|
|
||||||
return bind_int(stmt, pos, ((Integer) v).intValue());
|
|
||||||
}
|
|
||||||
else if (v instanceof Short) {
|
|
||||||
return bind_int(stmt, pos, ((Short) v).intValue());
|
|
||||||
}
|
|
||||||
else if (v instanceof Long) {
|
|
||||||
return bind_long(stmt, pos, ((Long) v).longValue());
|
|
||||||
}
|
|
||||||
else if (v instanceof Float) {
|
|
||||||
return bind_double(stmt, pos, ((Float) v).doubleValue());
|
|
||||||
}
|
|
||||||
else if (v instanceof Double) {
|
|
||||||
return bind_double(stmt, pos, ((Double) v).doubleValue());
|
|
||||||
}
|
|
||||||
else if (v instanceof String) {
|
|
||||||
return bind_text(stmt, pos, (String) v);
|
|
||||||
}
|
|
||||||
else if (v instanceof byte[]) {
|
|
||||||
return bind_blob(stmt, pos, (byte[]) v);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new SQLException("unexpected param type: " + v.getClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final synchronized int[] executeBatch(long stmt, int count, Object[] vals) throws SQLException {
|
|
||||||
if (count < 1)
|
|
||||||
throw new SQLException("count (" + count + ") < 1");
|
|
||||||
|
|
||||||
final int params = bind_parameter_count(stmt);
|
|
||||||
|
|
||||||
int rc;
|
|
||||||
int[] changes = new int[count];
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
reset(stmt);
|
|
||||||
for (int j = 0; j < params; j++)
|
|
||||||
if (sqlbind(stmt, j, vals[(i * params) + j]) != SQLITE_OK)
|
|
||||||
throwex();
|
|
||||||
|
|
||||||
rc = step(stmt);
|
|
||||||
if (rc != SQLITE_DONE) {
|
|
||||||
reset(stmt);
|
|
||||||
if (rc == SQLITE_ROW)
|
|
||||||
throw new BatchUpdateException("batch entry " + i + ": query returns results", changes);
|
|
||||||
throwex();
|
|
||||||
}
|
|
||||||
|
|
||||||
changes[i] = changes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
ensureAutoCommit();
|
|
||||||
}
|
|
||||||
|
|
||||||
reset(stmt);
|
|
||||||
return changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
final synchronized boolean execute(Stmt stmt, Object[] vals) throws SQLException {
|
|
||||||
if (vals != null) {
|
|
||||||
final int params = bind_parameter_count(stmt.pointer);
|
|
||||||
if (params != vals.length)
|
|
||||||
throw new SQLException("assertion failure: param count (" + params + ") != value count (" + vals.length
|
|
||||||
+ ")");
|
|
||||||
|
|
||||||
for (int i = 0; i < params; i++)
|
|
||||||
if (sqlbind(stmt.pointer, i, vals[i]) != SQLITE_OK)
|
|
||||||
throwex();
|
|
||||||
}
|
|
||||||
|
|
||||||
int statusCode = step(stmt.pointer);
|
|
||||||
switch (statusCode) {
|
|
||||||
case SQLITE_DONE:
|
|
||||||
reset(stmt.pointer);
|
|
||||||
ensureAutoCommit();
|
|
||||||
return false;
|
|
||||||
case SQLITE_ROW:
|
|
||||||
return true;
|
|
||||||
case SQLITE_BUSY:
|
|
||||||
case SQLITE_LOCKED:
|
|
||||||
case SQLITE_MISUSE:
|
|
||||||
throw newSQLException(statusCode);
|
|
||||||
default:
|
|
||||||
finalize(stmt);
|
|
||||||
throw newSQLException(statusCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
final synchronized boolean execute(String sql) throws SQLException {
|
|
||||||
int statusCode = _exec(sql);
|
|
||||||
switch (statusCode) {
|
|
||||||
case SQLITE_OK:
|
|
||||||
return false;
|
|
||||||
case SQLITE_DONE:
|
|
||||||
ensureAutoCommit();
|
|
||||||
return false;
|
|
||||||
case SQLITE_ROW:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
throw newSQLException(statusCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final synchronized int executeUpdate(Stmt stmt, Object[] vals) throws SQLException {
|
|
||||||
if (execute(stmt, vals))
|
|
||||||
throw new SQLException("query returns results");
|
|
||||||
reset(stmt.pointer);
|
|
||||||
return changes();
|
|
||||||
}
|
|
||||||
|
|
||||||
final void throwex() throws SQLException {
|
|
||||||
throw new SQLException(errmsg());
|
|
||||||
}
|
|
||||||
|
|
||||||
final void throwex(int errorCode) throws SQLException {
|
|
||||||
throw newSQLException(errorCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
final void throwex(int errorCode, String errorMessage) throws SQLException {
|
|
||||||
throw newSQLException(errorCode, errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
static SQLException newSQLException(int errorCode, String errorMessage) throws SQLException {
|
|
||||||
SQLiteErrorCode code = SQLiteErrorCode.getErrorCode(errorCode);
|
|
||||||
return new SQLException(String.format("%s (%s)", code, errorMessage));
|
|
||||||
}
|
|
||||||
|
|
||||||
private SQLException newSQLException(int errorCode) throws SQLException {
|
|
||||||
return newSQLException(errorCode, errmsg());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SQLite and the JDBC API have very different ideas about the meaning
|
|
||||||
* of auto-commit. Under JDBC, when executeUpdate() returns in
|
|
||||||
* auto-commit mode (the default), the programmer assumes the data has
|
|
||||||
* been written to disk. In SQLite however, a call to sqlite3_step()
|
|
||||||
* with an INSERT statement can return SQLITE_OK, and yet the data is
|
|
||||||
* still in limbo.
|
|
||||||
*
|
|
||||||
* This limbo appears when another statement on the database is active,
|
|
||||||
* e.g. a SELECT. SQLite auto-commit waits until the final read
|
|
||||||
* statement finishes, and then writes whatever updates have already
|
|
||||||
* been OKed. So if a program crashes before the reads are complete,
|
|
||||||
* data is lost. E.g:
|
|
||||||
*
|
|
||||||
* select begins
|
|
||||||
* insert
|
|
||||||
* select continues
|
|
||||||
* select finishes
|
|
||||||
*
|
|
||||||
* Works as expected, however
|
|
||||||
*
|
|
||||||
* select beings
|
|
||||||
* insert
|
|
||||||
* select continues
|
|
||||||
* crash
|
|
||||||
*
|
|
||||||
* Results in the data never being written to disk.
|
|
||||||
*
|
|
||||||
* As a solution, we call "commit" after every statement in auto-commit
|
|
||||||
* mode.
|
|
||||||
*/
|
|
||||||
final void ensureAutoCommit() throws SQLException {
|
|
||||||
if (!conn.getAutoCommit())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (begin == 0)
|
|
||||||
begin = prepare("begin;");
|
|
||||||
if (commit == 0)
|
|
||||||
commit = prepare("commit;");
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (step(begin) != SQLITE_DONE)
|
|
||||||
return; // assume we are in a transaction
|
|
||||||
if (step(commit) != SQLITE_DONE) {
|
|
||||||
reset(commit);
|
|
||||||
throwex();
|
|
||||||
}
|
|
||||||
//throw new SQLException("unable to auto-commit");
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
reset(begin);
|
|
||||||
reset(commit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,116 +0,0 @@
|
|||||||
//--------------------------------------
|
|
||||||
// sqlite-jdbc Project
|
|
||||||
//
|
|
||||||
// ExtendedCommand.java
|
|
||||||
// Since: Mar 12, 2010
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Author$
|
|
||||||
//--------------------------------------
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* parsing SQLite specific extension of SQL command
|
|
||||||
*
|
|
||||||
* @author leo
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ExtendedCommand
|
|
||||||
{
|
|
||||||
public static interface SQLExtension
|
|
||||||
{
|
|
||||||
public void execute(DB db) throws SQLException;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SQLExtension parse(String sql) throws SQLException {
|
|
||||||
if (sql == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (sql.startsWith("backup"))
|
|
||||||
return BackupCommand.parse(sql);
|
|
||||||
else if (sql.startsWith("restore"))
|
|
||||||
return RestoreCommand.parse(sql);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String removeQuotation(String s) {
|
|
||||||
if (s == null)
|
|
||||||
return s;
|
|
||||||
|
|
||||||
if ((s.startsWith("\"") && s.endsWith("\"")) || (s.startsWith("'") && s.endsWith("'")))
|
|
||||||
return s.substring(1, s.length() - 1);
|
|
||||||
else
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class BackupCommand implements SQLExtension
|
|
||||||
{
|
|
||||||
public final String srcDB;
|
|
||||||
public final String destFile;
|
|
||||||
|
|
||||||
public BackupCommand(String srcDB, String destFile) {
|
|
||||||
this.srcDB = srcDB;
|
|
||||||
this.destFile = destFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Pattern backupCmd = Pattern
|
|
||||||
.compile("backup(\\s+(\"[^\"]*\"|'[^\']*\'|\\S+))?\\s+to\\s+(\"[^\"]*\"|'[^\']*\'|\\S+)");
|
|
||||||
|
|
||||||
public static BackupCommand parse(String sql) throws SQLException {
|
|
||||||
if (sql != null) {
|
|
||||||
Matcher m = backupCmd.matcher(sql);
|
|
||||||
if (m.matches()) {
|
|
||||||
String dbName = removeQuotation(m.group(2));
|
|
||||||
String dest = removeQuotation(m.group(3));
|
|
||||||
if (dbName == null || dbName.length() == 0)
|
|
||||||
dbName = "main";
|
|
||||||
|
|
||||||
return new BackupCommand(dbName, dest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new SQLException("syntax error: " + sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void execute(DB db) throws SQLException {
|
|
||||||
db.backup(srcDB, destFile, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class RestoreCommand implements SQLExtension
|
|
||||||
{
|
|
||||||
public final String targetDB;
|
|
||||||
public final String srcFile;
|
|
||||||
private static Pattern restoreCmd = Pattern
|
|
||||||
.compile("restore(\\s+(\"[^\"]*\"|'[^\']*\'|\\S+))?\\s+from\\s+(\"[^\"]*\"|'[^\']*\'|\\S+)");
|
|
||||||
|
|
||||||
public RestoreCommand(String targetDB, String srcFile) {
|
|
||||||
this.targetDB = targetDB;
|
|
||||||
this.srcFile = srcFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RestoreCommand parse(String sql) throws SQLException {
|
|
||||||
if (sql != null) {
|
|
||||||
Matcher m = restoreCmd.matcher(sql);
|
|
||||||
if (m.matches()) {
|
|
||||||
String dbName = removeQuotation(m.group(2));
|
|
||||||
String dest = removeQuotation(m.group(3));
|
|
||||||
if (dbName == null || dbName.length() == 0)
|
|
||||||
dbName = "main";
|
|
||||||
return new RestoreCommand(dbName, dest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new SQLException("syntax error: " + sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void execute(DB db) throws SQLException {
|
|
||||||
db.restore(targetDB, srcFile, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,182 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.sql.*;
|
|
||||||
|
|
||||||
/** Provides an interface for creating SQLite user-defined functions.
|
|
||||||
*
|
|
||||||
* <p>A subclass of <tt>org.sqlite.Function</tt> can be registered with
|
|
||||||
* <tt>Function.create()</tt> and called by the name it was given. All
|
|
||||||
* functions must implement <tt>xFunc()</tt>, which is called when SQLite
|
|
||||||
* runs the custom function.</p>
|
|
||||||
*
|
|
||||||
* Eg.
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* Class.forName("org.sqlite.JDBC");
|
|
||||||
* Connection conn = DriverManager.getConnection("jdbc:sqlite:");
|
|
||||||
*
|
|
||||||
* Function.create(conn, "myFunc", new Function() {
|
|
||||||
* protected void xFunc() {
|
|
||||||
* System.out.println("myFunc called!");
|
|
||||||
* }
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* conn.createStatement().execute("select myFunc();");
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* <p>Arguments passed to a custom function can be accessed using the
|
|
||||||
* <tt>protected</tt> functions provided. <tt>args()</tt> returns
|
|
||||||
* the number of arguments passed, while
|
|
||||||
* <tt>value_<type>(int)</tt> returns the value of the specific
|
|
||||||
* argument. Similarly a function can return a value using the
|
|
||||||
* <tt>result(<type>)</tt> function.</p>
|
|
||||||
*
|
|
||||||
* <p>Aggregate functions are not yet supported, but coming soon.</p>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public abstract class Function
|
|
||||||
{
|
|
||||||
private Conn conn;
|
|
||||||
private DB db;
|
|
||||||
|
|
||||||
long context = 0; // pointer sqlite3_context*
|
|
||||||
long value = 0; // pointer sqlite3_value**
|
|
||||||
int args = 0;
|
|
||||||
|
|
||||||
/** Registers the given function with the Connection using the
|
|
||||||
* provided name. */
|
|
||||||
public static final void create(Connection conn, String name, Function f)
|
|
||||||
throws SQLException {
|
|
||||||
if (conn == null || !(conn instanceof Conn))
|
|
||||||
throw new SQLException("connection must be to an SQLite db");
|
|
||||||
if (conn.isClosed())
|
|
||||||
throw new SQLException("connection closed");
|
|
||||||
|
|
||||||
f.conn = (Conn)conn;
|
|
||||||
f.db = f.conn.db();
|
|
||||||
|
|
||||||
if (name == null || name.length() > 255)
|
|
||||||
throw new SQLException("invalid function name: '"+name+"'");
|
|
||||||
|
|
||||||
if (f.db.create_function(name, f) != Codes.SQLITE_OK)
|
|
||||||
throw new SQLException("error creating function");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Removes the named function form the Connection. */
|
|
||||||
public static final void destroy(Connection conn, String name)
|
|
||||||
throws SQLException {
|
|
||||||
if (conn == null || !(conn instanceof Conn))
|
|
||||||
throw new SQLException("connection must be to an SQLite db");
|
|
||||||
((Conn)conn).db().destroy_function(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Called by SQLite as a custom function. Should access arguments
|
|
||||||
* through <tt>value_*(int)</tt>, return results with
|
|
||||||
* <tt>result(*)</tt> and throw errors with <tt>error(String)</tt>. */
|
|
||||||
protected abstract void xFunc() throws SQLException;
|
|
||||||
|
|
||||||
|
|
||||||
/** Returns the number of arguments passed to the function.
|
|
||||||
* Can only be called from <tt>xFunc()</tt>. */
|
|
||||||
protected synchronized final int args()
|
|
||||||
throws SQLException { checkContext(); return args; }
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to return a value. */
|
|
||||||
protected synchronized final void result(byte[] value)
|
|
||||||
throws SQLException { checkContext(); db.result_blob(context, value); }
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to return a value. */
|
|
||||||
protected synchronized final void result(double value)
|
|
||||||
throws SQLException { checkContext(); db.result_double(context,value);}
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to return a value. */
|
|
||||||
protected synchronized final void result(int value)
|
|
||||||
throws SQLException { checkContext(); db.result_int(context, value); }
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to return a value. */
|
|
||||||
protected synchronized final void result(long value)
|
|
||||||
throws SQLException { checkContext(); db.result_long(context, value); }
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to return a value. */
|
|
||||||
protected synchronized final void result()
|
|
||||||
throws SQLException { checkContext(); db.result_null(context); }
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to return a value. */
|
|
||||||
protected synchronized final void result(String value)
|
|
||||||
throws SQLException { checkContext(); db.result_text(context, value); }
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to throw an error. */
|
|
||||||
protected synchronized final void error(String err)
|
|
||||||
throws SQLException { checkContext(); db.result_error(context, err); }
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to access the value of an argument. */
|
|
||||||
protected synchronized final int value_bytes(int arg)
|
|
||||||
throws SQLException {checkValue(arg); return db.value_bytes(this,arg);}
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to access the value of an argument. */
|
|
||||||
protected synchronized final String value_text(int arg)
|
|
||||||
throws SQLException {checkValue(arg); return db.value_text(this,arg);}
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to access the value of an argument. */
|
|
||||||
protected synchronized final byte[] value_blob(int arg)
|
|
||||||
throws SQLException {checkValue(arg); return db.value_blob(this,arg); }
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to access the value of an argument. */
|
|
||||||
protected synchronized final double value_double(int arg)
|
|
||||||
throws SQLException {checkValue(arg); return db.value_double(this,arg);}
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to access the value of an argument. */
|
|
||||||
protected synchronized final int value_int(int arg)
|
|
||||||
throws SQLException {checkValue(arg); return db.value_int(this, arg); }
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to access the value of an argument. */
|
|
||||||
protected synchronized final long value_long(int arg)
|
|
||||||
throws SQLException { checkValue(arg); return db.value_long(this,arg); }
|
|
||||||
|
|
||||||
/** Called by <tt>xFunc</tt> to access the value of an argument. */
|
|
||||||
protected synchronized final int value_type(int arg)
|
|
||||||
throws SQLException {checkValue(arg); return db.value_type(this,arg); }
|
|
||||||
|
|
||||||
|
|
||||||
private void checkContext() throws SQLException {
|
|
||||||
if (conn == null || conn.db() == null || context == 0)
|
|
||||||
throw new SQLException("no context, not allowed to read value");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkValue(int arg) throws SQLException {
|
|
||||||
if (conn == null || conn.db() == null || value == 0)
|
|
||||||
throw new SQLException("not in value access state");
|
|
||||||
if (arg >= args)
|
|
||||||
throw new SQLException("arg "+arg+" out bounds [0,"+args+")");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static abstract class Aggregate
|
|
||||||
extends Function
|
|
||||||
implements Cloneable
|
|
||||||
{
|
|
||||||
protected final void xFunc() {}
|
|
||||||
protected abstract void xStep() throws SQLException;
|
|
||||||
protected abstract void xFinal() throws SQLException;
|
|
||||||
|
|
||||||
public Object clone() throws CloneNotSupportedException {
|
|
||||||
return super.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.Driver;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.DriverPropertyInfo;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
public class JDBC implements Driver
|
|
||||||
{
|
|
||||||
public static final String PREFIX = "jdbc:sqlite:";
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
DriverManager.registerDriver(new JDBC());
|
|
||||||
}
|
|
||||||
catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMajorVersion() {
|
|
||||||
return SQLiteJDBCLoader.getMajorVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMinorVersion() {
|
|
||||||
return SQLiteJDBCLoader.getMinorVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean jdbcCompliant() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean acceptsURL(String url) {
|
|
||||||
return isValidURL(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isValidURL(String url) {
|
|
||||||
return url != null && url.toLowerCase().startsWith(PREFIX);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
|
|
||||||
return SQLiteConfig.getDriverPropertyInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Connection connect(String url, Properties info) throws SQLException {
|
|
||||||
return createConnection(url, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String extractAddress(String url) {
|
|
||||||
// if no file name is given use a memory database
|
|
||||||
return PREFIX.equalsIgnoreCase(url) ? ":memory:" : url.substring(PREFIX.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Connection createConnection(String url, Properties prop) throws SQLException {
|
|
||||||
if (!isValidURL(url))
|
|
||||||
throw new SQLException("invalid database address: " + url);
|
|
||||||
|
|
||||||
url = url.trim();
|
|
||||||
return new Conn(url, extractAddress(url), prop);
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,212 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
/** This class provides a thin JNI layer over the SQLite3 C API. */
|
|
||||||
final class NativeDB extends DB
|
|
||||||
{
|
|
||||||
/** SQLite connection handle. */
|
|
||||||
long pointer = 0;
|
|
||||||
|
|
||||||
private static boolean isLoaded = false;
|
|
||||||
private static boolean loadSucceeded = false;
|
|
||||||
|
|
||||||
static boolean load() {
|
|
||||||
if (isLoaded)
|
|
||||||
return loadSucceeded == true;
|
|
||||||
|
|
||||||
loadSucceeded = SQLiteJDBCLoader.initialize();
|
|
||||||
isLoaded = true;
|
|
||||||
return loadSucceeded;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** linked list of all instanced UDFDatas */
|
|
||||||
private final long udfdatalist = 0;
|
|
||||||
|
|
||||||
// WRAPPER FUNCTIONS ////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected native synchronized void _open(String file, int openFlags) throws SQLException;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected native synchronized void _close() throws SQLException;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected native synchronized int _exec(String sql) throws SQLException;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int shared_cache(boolean enable);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int enable_load_extension(boolean enable);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized void interrupt();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized void busy_timeout(int ms);
|
|
||||||
|
|
||||||
//native synchronized void exec(String sql) throws SQLException;
|
|
||||||
@Override
|
|
||||||
protected native synchronized long prepare(String sql) throws SQLException;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized String errmsg();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized String libversion();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int changes();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected native synchronized int finalize(long stmt);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected native synchronized int step(long stmt);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected native synchronized int reset(long stmt);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int clear_bindings(long stmt);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int bind_parameter_count(long stmt);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int column_count(long stmt);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int column_type(long stmt, int col);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized String column_decltype(long stmt, int col);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized String column_table_name(long stmt, int col);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized String column_name(long stmt, int col);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized String column_text(long stmt, int col);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized byte[] column_blob(long stmt, int col);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized double column_double(long stmt, int col);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized long column_long(long stmt, int col);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int column_int(long stmt, int col);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int bind_null(long stmt, int pos);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int bind_int(long stmt, int pos, int v);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int bind_long(long stmt, int pos, long v);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int bind_double(long stmt, int pos, double v);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int bind_text(long stmt, int pos, String v);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int bind_blob(long stmt, int pos, byte[] v);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized void result_null(long context);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized void result_text(long context, String val);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized void result_blob(long context, byte[] val);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized void result_double(long context, double val);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized void result_long(long context, long val);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized void result_int(long context, int val);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized void result_error(long context, String err);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int value_bytes(Function f, int arg);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized String value_text(Function f, int arg);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized byte[] value_blob(Function f, int arg);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized double value_double(Function f, int arg);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized long value_long(Function f, int arg);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int value_int(Function f, int arg);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int value_type(Function f, int arg);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int create_function(String name, Function func);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int destroy_function(String name);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized void free_functions();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int backup(String dbName, String destFileName, ProgressObserver observer) throws SQLException;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
native synchronized int restore(String dbName, String sourceFileName, ProgressObserver observer)
|
|
||||||
throws SQLException;
|
|
||||||
|
|
||||||
// COMPOUND FUNCTIONS (for optimisation) /////////////////////////
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides metadata for the columns of a statement. Returns: res[col][0] =
|
|
||||||
* true if column constrained NOT NULL res[col][1] = true if column is part
|
|
||||||
* of the primary key res[col][2] = true if column is auto-increment
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
native synchronized boolean[][] column_metadata(long stmt);
|
|
||||||
|
|
||||||
static void throwex(String msg) throws SQLException {
|
|
||||||
throw new SQLException(msg);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,662 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import org.ibex.nestedvm.Runtime;
|
|
||||||
|
|
||||||
// FEATURE: strdup is wasteful, SQLite interface will take unterminated char*
|
|
||||||
|
|
||||||
/** Communicates with the Java version of SQLite provided by NestedVM. */
|
|
||||||
final class NestedDB extends DB implements Runtime.CallJavaCB
|
|
||||||
{
|
|
||||||
/** database pointer */
|
|
||||||
int handle = 0;
|
|
||||||
|
|
||||||
/** sqlite binary embedded in nestedvm */
|
|
||||||
private Runtime rt = null;
|
|
||||||
|
|
||||||
/** user defined functions referenced by position (stored in used data) */
|
|
||||||
private Function[] functions = null;
|
|
||||||
private String[] funcNames = null;
|
|
||||||
|
|
||||||
// WRAPPER FUNCTIONS ////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected synchronized void _open(String filename, int openFlags) throws SQLException {
|
|
||||||
if (handle != 0)
|
|
||||||
throw new SQLException("DB already open");
|
|
||||||
|
|
||||||
// handle silly windows drive letter mapping
|
|
||||||
if (filename.length() > 2) {
|
|
||||||
char drive = Character.toLowerCase(filename.charAt(0));
|
|
||||||
if (filename.charAt(1) == ':' && drive >= 'a' && drive <= 'z') {
|
|
||||||
|
|
||||||
// convert to nestedvm's "/c:/file" format
|
|
||||||
filename = filename.substring(2);
|
|
||||||
filename = filename.replace('\\', '/');
|
|
||||||
filename = "/" + drive + ":" + filename;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// start the nestedvm runtime
|
|
||||||
try {
|
|
||||||
rt = (Runtime) Class.forName("org.sqlite.SQLite").newInstance();
|
|
||||||
rt.start();
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new CausedSQLException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// callback for user defined functions
|
|
||||||
rt.setCallJavaCB(this);
|
|
||||||
|
|
||||||
// open the db and retrieve sqlite3_db* pointer
|
|
||||||
int passback = rt.xmalloc(4);
|
|
||||||
int str = rt.strdup(filename);
|
|
||||||
// if (call("sqlite3_open_v2", str, openFlags, 0, passback) != SQLITE_OK)
|
|
||||||
if (call("sqlite3_open_v2", str, passback, openFlags, 0) != SQLITE_OK)
|
|
||||||
throwex();
|
|
||||||
handle = deref(passback);
|
|
||||||
rt.free(str);
|
|
||||||
rt.free(passback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* callback for Runtime.CallJavaCB above */
|
|
||||||
public int call(int xType, int context, int args, int value) {
|
|
||||||
xUDF(xType, context, args, value);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected synchronized void _close() throws SQLException {
|
|
||||||
if (handle == 0)
|
|
||||||
return;
|
|
||||||
try {
|
|
||||||
if (call("sqlite3_close", handle) != SQLITE_OK)
|
|
||||||
throwex();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
handle = 0;
|
|
||||||
rt.stop();
|
|
||||||
rt = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
int shared_cache(boolean enable) throws SQLException {
|
|
||||||
// The shared cache is per-process, so it is useless as
|
|
||||||
// each nested connection is its own process.
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
int enable_load_extension(boolean enable) throws SQLException {
|
|
||||||
// TODO enable_load_extension is not supported in pure-java mode
|
|
||||||
//return call("sqlite3_enable_load_extension", handle, enable ? 1 : 0);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized void interrupt() throws SQLException {
|
|
||||||
call("sqlite3_interrupt", handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized void busy_timeout(int ms) throws SQLException {
|
|
||||||
call("sqlite3_busy_timeout", handle, ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected synchronized long prepare(String sql) throws SQLException {
|
|
||||||
|
|
||||||
int passback = rt.xmalloc(4);
|
|
||||||
int str = rt.strdup(sql);
|
|
||||||
int ret = call("sqlite3_prepare_v2", handle, str, -1, passback, 0);
|
|
||||||
rt.free(str);
|
|
||||||
if (ret != SQLITE_OK) {
|
|
||||||
rt.free(passback);
|
|
||||||
throwex(ret);
|
|
||||||
}
|
|
||||||
int pointer = deref(passback);
|
|
||||||
rt.free(passback);
|
|
||||||
return pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized String errmsg() throws SQLException {
|
|
||||||
return cstring(call("sqlite3_errmsg", handle));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized String libversion() throws SQLException {
|
|
||||||
return cstring(call("sqlite3_libversion", handle));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int changes() throws SQLException {
|
|
||||||
return call("sqlite3_changes", handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected synchronized int _exec(String sql) throws SQLException {
|
|
||||||
if (rt == null)
|
|
||||||
throw DB.newSQLException(SQLiteErrorCode.SQLITE_MISUSE.code, "attempt to use the closed conection");
|
|
||||||
int passback = rt.xmalloc(4);
|
|
||||||
int str = rt.strdup(sql);
|
|
||||||
int status = call("sqlite3_exec", handle, str, 0, 0, passback);
|
|
||||||
if (status != SQLITE_OK) {
|
|
||||||
String errorMessage = cstring(passback);
|
|
||||||
call("sqlite3_free", deref(passback));
|
|
||||||
rt.free(passback);
|
|
||||||
throwex(status, errorMessage);
|
|
||||||
}
|
|
||||||
rt.free(passback);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected synchronized int finalize(long stmt) throws SQLException {
|
|
||||||
return call("sqlite3_finalize", (int) stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected synchronized int step(long stmt) throws SQLException {
|
|
||||||
return call("sqlite3_step", (int) stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected synchronized int reset(long stmt) throws SQLException {
|
|
||||||
return call("sqlite3_reset", (int) stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int clear_bindings(long stmt) throws SQLException {
|
|
||||||
return call("sqlite3_clear_bindings", (int) stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int bind_parameter_count(long stmt) throws SQLException {
|
|
||||||
return call("sqlite3_bind_parameter_count", (int) stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int column_count(long stmt) throws SQLException {
|
|
||||||
return call("sqlite3_column_count", (int) stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int column_type(long stmt, int col) throws SQLException {
|
|
||||||
return call("sqlite3_column_type", (int) stmt, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized String column_name(long stmt, int col) throws SQLException {
|
|
||||||
return utfstring(call("sqlite3_column_name", (int) stmt, col));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized String column_text(long stmt, int col) throws SQLException {
|
|
||||||
return utfstring(call("sqlite3_column_text", (int) stmt, col));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized byte[] column_blob(long stmt, int col) throws SQLException {
|
|
||||||
int addr = call("sqlite3_column_blob", (int) stmt, col);
|
|
||||||
if (addr == 0)
|
|
||||||
return null;
|
|
||||||
byte[] blob = new byte[call("sqlite3_column_bytes", (int) stmt, col)];
|
|
||||||
copyin(addr, blob, blob.length);
|
|
||||||
return blob;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized double column_double(long stmt, int col) throws SQLException {
|
|
||||||
try {
|
|
||||||
return Double.parseDouble(column_text(stmt, col));
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e) {
|
|
||||||
return Double.NaN;
|
|
||||||
} // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized long column_long(long stmt, int col) throws SQLException {
|
|
||||||
try {
|
|
||||||
return Long.parseLong(column_text(stmt, col));
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e) {
|
|
||||||
return 0;
|
|
||||||
} // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int column_int(long stmt, int col) throws SQLException {
|
|
||||||
return call("sqlite3_column_int", (int) stmt, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized String column_decltype(long stmt, int col) throws SQLException {
|
|
||||||
return utfstring(call("sqlite3_column_decltype", (int) stmt, col));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized String column_table_name(long stmt, int col) throws SQLException {
|
|
||||||
return utfstring(call("sqlite3_column_table_name", (int) stmt, col));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int bind_null(long stmt, int pos) throws SQLException {
|
|
||||||
return call("sqlite3_bind_null", (int) stmt, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int bind_int(long stmt, int pos, int v) throws SQLException {
|
|
||||||
return call("sqlite3_bind_int", (int) stmt, pos, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int bind_long(long stmt, int pos, long v) throws SQLException {
|
|
||||||
return bind_text(stmt, pos, Long.toString(v)); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int bind_double(long stmt, int pos, double v) throws SQLException {
|
|
||||||
return bind_text(stmt, pos, Double.toString(v)); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int bind_text(long stmt, int pos, String v) throws SQLException {
|
|
||||||
if (v == null)
|
|
||||||
return bind_null(stmt, pos);
|
|
||||||
return call("sqlite3_bind_text", (int) stmt, pos, rt.strdup(v), -1, rt.lookupSymbol("free"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int bind_blob(long stmt, int pos, byte[] buf) throws SQLException {
|
|
||||||
if (buf == null || buf.length < 1)
|
|
||||||
return bind_null(stmt, pos);
|
|
||||||
int len = buf.length;
|
|
||||||
int blob = rt.xmalloc(len); // free()ed by sqlite3_bind_blob
|
|
||||||
copyout(buf, blob, len);
|
|
||||||
return call("sqlite3_bind_blob", (int) stmt, pos, blob, len, rt.lookupSymbol("free"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized void result_null(long cxt) throws SQLException {
|
|
||||||
call("sqlite3_result_null", (int) cxt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized void result_text(long cxt, String val) throws SQLException {
|
|
||||||
call("sqlite3_result_text", (int) cxt, rt.strdup(val), -1, rt.lookupSymbol("free"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized void result_blob(long cxt, byte[] val) throws SQLException {
|
|
||||||
if (val == null || val.length == 0) {
|
|
||||||
result_null(cxt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int blob = rt.xmalloc(val.length);
|
|
||||||
copyout(val, blob, val.length);
|
|
||||||
call("sqlite3_result_blob", (int) cxt, blob, val.length, rt.lookupSymbol("free"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized void result_double(long cxt, double val) throws SQLException {
|
|
||||||
result_text(cxt, Double.toString(val));
|
|
||||||
} // TODO
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized void result_long(long cxt, long val) throws SQLException {
|
|
||||||
result_text(cxt, Long.toString(val));
|
|
||||||
} // TODO
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized void result_int(long cxt, int val) throws SQLException {
|
|
||||||
call("sqlite3_result_int", (int) cxt, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized void result_error(long cxt, String err) throws SQLException {
|
|
||||||
int str = rt.strdup(err);
|
|
||||||
call("sqlite3_result_error", (int) cxt, str, -1);
|
|
||||||
rt.free(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int value_bytes(Function f, int arg) throws SQLException {
|
|
||||||
return call("sqlite3_value_bytes", value(f, arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized String value_text(Function f, int arg) throws SQLException {
|
|
||||||
return utfstring(call("sqlite3_value_text", value(f, arg)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized byte[] value_blob(Function f, int arg) throws SQLException {
|
|
||||||
int addr = call("sqlite3_value_blob", value(f, arg));
|
|
||||||
if (addr == 0)
|
|
||||||
return null;
|
|
||||||
byte[] blob = new byte[value_bytes(f, arg)];
|
|
||||||
copyin(addr, blob, blob.length);
|
|
||||||
return blob;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized double value_double(Function f, int arg) throws SQLException {
|
|
||||||
return Double.parseDouble(value_text(f, arg)); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized long value_long(Function f, int arg) throws SQLException {
|
|
||||||
return Long.parseLong(value_text(f, arg)); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int value_int(Function f, int arg) throws SQLException {
|
|
||||||
return call("sqlite3_value_int", value(f, arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int value_type(Function f, int arg) throws SQLException {
|
|
||||||
return call("sqlite3_value_type", value(f, arg));
|
|
||||||
}
|
|
||||||
|
|
||||||
private int value(Function f, int arg) throws SQLException {
|
|
||||||
return deref((int) f.value + (arg * 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int create_function(String name, Function func) throws SQLException {
|
|
||||||
if (functions == null) {
|
|
||||||
functions = new Function[10];
|
|
||||||
funcNames = new String[10];
|
|
||||||
}
|
|
||||||
|
|
||||||
// find a position
|
|
||||||
int pos;
|
|
||||||
for (pos = 0; pos < functions.length; pos++)
|
|
||||||
if (functions[pos] == null)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (pos == functions.length) { // expand function arrays
|
|
||||||
Function[] fnew = new Function[functions.length * 2];
|
|
||||||
String[] nnew = new String[funcNames.length * 2];
|
|
||||||
System.arraycopy(functions, 0, fnew, 0, functions.length);
|
|
||||||
System.arraycopy(funcNames, 0, nnew, 0, funcNames.length);
|
|
||||||
functions = fnew;
|
|
||||||
funcNames = nnew;
|
|
||||||
}
|
|
||||||
|
|
||||||
// register function
|
|
||||||
functions[pos] = func;
|
|
||||||
funcNames[pos] = name;
|
|
||||||
int rc;
|
|
||||||
int str = rt.strdup(name);
|
|
||||||
rc = call("create_function_helper", handle, str, pos, func instanceof Function.Aggregate ? 1 : 0);
|
|
||||||
rt.free(str);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
synchronized int destroy_function(String name) throws SQLException {
|
|
||||||
if (name == null)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// find function position number
|
|
||||||
int pos;
|
|
||||||
for (pos = 0; pos < funcNames.length; pos++)
|
|
||||||
if (name.equals(funcNames[pos]))
|
|
||||||
break;
|
|
||||||
if (pos == funcNames.length)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
functions[pos] = null;
|
|
||||||
funcNames[pos] = null;
|
|
||||||
|
|
||||||
// deregister function
|
|
||||||
int rc;
|
|
||||||
int str = rt.strdup(name);
|
|
||||||
rc = call("create_function_helper", handle, str, -1, 0);
|
|
||||||
rt.free(str);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unused as we use the user_data pointer to store a single word */
|
|
||||||
@Override
|
|
||||||
synchronized void free_functions() {}
|
|
||||||
|
|
||||||
/** Callback used by xFunc (1), xStep (2) and xFinal (3). */
|
|
||||||
synchronized void xUDF(int xType, int context, int args, int value) {
|
|
||||||
Function func = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
int pos = call("sqlite3_user_data", context);
|
|
||||||
func = functions[pos];
|
|
||||||
if (func == null)
|
|
||||||
throw new SQLException("function state inconsistent");
|
|
||||||
|
|
||||||
func.context = context;
|
|
||||||
func.value = value;
|
|
||||||
func.args = args;
|
|
||||||
|
|
||||||
switch (xType) {
|
|
||||||
case 1:
|
|
||||||
func.xFunc();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
((Function.Aggregate) func).xStep();
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
((Function.Aggregate) func).xFinal();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (SQLException e) {
|
|
||||||
try {
|
|
||||||
String err = e.toString();
|
|
||||||
if (err == null)
|
|
||||||
err = "unknown error";
|
|
||||||
int str = rt.strdup(err);
|
|
||||||
call("sqlite3_result_error", context, str, -1);
|
|
||||||
rt.free(str);
|
|
||||||
}
|
|
||||||
catch (SQLException exp) {
|
|
||||||
exp.printStackTrace();//TODO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if (func != null) {
|
|
||||||
func.context = 0;
|
|
||||||
func.value = 0;
|
|
||||||
func.args = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Calls support function found in upstream/sqlite-metadata.patch */
|
|
||||||
@Override
|
|
||||||
synchronized boolean[][] column_metadata(long stmt) throws SQLException {
|
|
||||||
int colCount = call("sqlite3_column_count", (int) stmt);
|
|
||||||
boolean[][] meta = new boolean[colCount][3];
|
|
||||||
int pass;
|
|
||||||
|
|
||||||
pass = rt.xmalloc(12); // struct metadata
|
|
||||||
|
|
||||||
for (int i = 0; i < colCount; i++) {
|
|
||||||
call("column_metadata_helper", handle, (int) stmt, i, pass);
|
|
||||||
meta[i][0] = deref(pass) == 1;
|
|
||||||
meta[i][1] = deref(pass + 4) == 1;
|
|
||||||
meta[i][2] = deref(pass + 8) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt.free(pass);
|
|
||||||
return meta;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
int backup(String dbName, String destFileName, ProgressObserver observer) throws SQLException {
|
|
||||||
throw new SQLException("backup command is not supported in pure-java mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
int restore(String dbName, String sourceFileName, ProgressObserver observer) throws SQLException {
|
|
||||||
throw new SQLException("restore command is not supported in pure-java mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPER FUNCTIONS /////////////////////////////////////////////
|
|
||||||
|
|
||||||
/** safe to reuse parameter arrays as all functions are syncrhonized */
|
|
||||||
private final int[] p0 = new int[] {}, p1 = new int[] { 0 }, p2 = new int[] { 0, 0 }, p3 = new int[] { 0, 0, 0 },
|
|
||||||
p4 = new int[] { 0, 0, 0, 0 }, p5 = new int[] { 0, 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
private int call(String addr, int a0) throws SQLException {
|
|
||||||
p1[0] = a0;
|
|
||||||
return call(addr, p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int call(String addr, int a0, int a1) throws SQLException {
|
|
||||||
p2[0] = a0;
|
|
||||||
p2[1] = a1;
|
|
||||||
return call(addr, p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int call(String addr, int a0, int a1, int a2) throws SQLException {
|
|
||||||
p3[0] = a0;
|
|
||||||
p3[1] = a1;
|
|
||||||
p3[2] = a2;
|
|
||||||
return call(addr, p3);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int call(String addr, int a0, int a1, int a2, int a3) throws SQLException {
|
|
||||||
p4[0] = a0;
|
|
||||||
p4[1] = a1;
|
|
||||||
p4[2] = a2;
|
|
||||||
p4[3] = a3;
|
|
||||||
return call(addr, p4);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int call(String addr, int a0, int a1, int a2, int a3, int a4) throws SQLException {
|
|
||||||
p5[0] = a0;
|
|
||||||
p5[1] = a1;
|
|
||||||
p5[2] = a2;
|
|
||||||
p5[3] = a3;
|
|
||||||
p5[4] = a4;
|
|
||||||
return call(addr, p5);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int call(String func, int[] args) throws SQLException {
|
|
||||||
try {
|
|
||||||
return rt.call(func, args);
|
|
||||||
}
|
|
||||||
catch (Runtime.CallException e) {
|
|
||||||
throw new CausedSQLException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Dereferences a pointer, returning the word it points to. */
|
|
||||||
private int deref(int pointer) throws SQLException {
|
|
||||||
try {
|
|
||||||
return rt.memRead(pointer);
|
|
||||||
}
|
|
||||||
catch (Runtime.ReadFaultException e) {
|
|
||||||
throw new CausedSQLException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String utfstring(int str) throws SQLException {
|
|
||||||
try {
|
|
||||||
return rt.utfstring(str);
|
|
||||||
}
|
|
||||||
catch (Runtime.ReadFaultException e) {
|
|
||||||
throw new CausedSQLException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String cstring(int str) throws SQLException {
|
|
||||||
try {
|
|
||||||
return rt.cstring(str);
|
|
||||||
}
|
|
||||||
catch (Runtime.ReadFaultException e) {
|
|
||||||
throw new CausedSQLException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void copyin(int addr, byte[] buf, int count) throws SQLException {
|
|
||||||
try {
|
|
||||||
rt.copyin(addr, buf, count);
|
|
||||||
}
|
|
||||||
catch (Runtime.ReadFaultException e) {
|
|
||||||
throw new CausedSQLException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void copyout(byte[] buf, int addr, int count) throws SQLException {
|
|
||||||
try {
|
|
||||||
rt.copyout(buf, addr, count);
|
|
||||||
}
|
|
||||||
catch (Runtime.FaultException e) {
|
|
||||||
throw new CausedSQLException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Maps any exception onto an SQLException. */
|
|
||||||
private static final class CausedSQLException extends SQLException
|
|
||||||
{
|
|
||||||
private final Exception cause;
|
|
||||||
|
|
||||||
CausedSQLException(Exception e) {
|
|
||||||
if (e == null)
|
|
||||||
throw new RuntimeException("null exception cause");
|
|
||||||
cause = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Throwable getCause() {
|
|
||||||
return cause;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void printStackTrace() {
|
|
||||||
cause.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void printStackTrace(PrintWriter s) {
|
|
||||||
cause.printStackTrace(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Throwable fillInStackTrace() {
|
|
||||||
return cause.fillInStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StackTraceElement[] getStackTrace() {
|
|
||||||
return cause.getStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
return cause.getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
/*--------------------------------------------------------------------------
|
|
||||||
* Copyright 2008 Taro L. Saito
|
|
||||||
*
|
|
||||||
* Licensed 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.
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
//--------------------------------------
|
|
||||||
// sqlite-jdbc Project
|
|
||||||
//
|
|
||||||
// OSInfo.java
|
|
||||||
// Since: May 20, 2008
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Author$
|
|
||||||
//--------------------------------------
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides OS name and architecture name.
|
|
||||||
*
|
|
||||||
* @author leo
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class OSInfo
|
|
||||||
{
|
|
||||||
public static void main(String[] args) {
|
|
||||||
if (args.length >= 1) {
|
|
||||||
if ("--os".equals(args[0])) {
|
|
||||||
System.out.print(getOSName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ("--arch".equals(args[0])) {
|
|
||||||
System.out.print(getArchName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.print(getNativeLibFolderPathForCurrentOS());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getNativeLibFolderPathForCurrentOS() {
|
|
||||||
return getOSName() + "/" + getArchName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getOSName() {
|
|
||||||
return translateOSNameToFolderName(System.getProperty("os.name"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getArchName() {
|
|
||||||
return translateArchNameToFolderName(System.getProperty("os.arch"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String translateOSNameToFolderName(String osName) {
|
|
||||||
if (osName.contains("Windows")) {
|
|
||||||
return "Windows";
|
|
||||||
}
|
|
||||||
else if (osName.contains("Mac")) {
|
|
||||||
return "Mac";
|
|
||||||
}
|
|
||||||
else if (osName.contains("Linux")) {
|
|
||||||
return "Linux";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return osName.replaceAll("\\W", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String translateArchNameToFolderName(String archName) {
|
|
||||||
return archName.replaceAll("\\W", "");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,330 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.sql.Date;
|
|
||||||
import java.sql.ParameterMetaData;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.ResultSetMetaData;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.sql.Time;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.sql.Types;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
final class PrepStmt extends Stmt implements PreparedStatement, ParameterMetaData, Codes
|
|
||||||
{
|
|
||||||
private int columnCount;
|
|
||||||
private int paramCount;
|
|
||||||
|
|
||||||
PrepStmt(Conn conn, String sql) throws SQLException {
|
|
||||||
super(conn);
|
|
||||||
|
|
||||||
this.sql = sql;
|
|
||||||
db.prepare(this);
|
|
||||||
rs.colsMeta = db.column_names(pointer);
|
|
||||||
columnCount = db.column_count(pointer);
|
|
||||||
paramCount = db.bind_parameter_count(pointer);
|
|
||||||
batch = new Object[paramCount];
|
|
||||||
batchPos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearParameters() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
db.reset(pointer);
|
|
||||||
clearBatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void finalize() throws SQLException {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean execute() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
rs.close();
|
|
||||||
db.reset(pointer);
|
|
||||||
resultsWaiting = db.execute(this, batch);
|
|
||||||
return columnCount != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResultSet executeQuery() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
if (columnCount == 0)
|
|
||||||
throw new SQLException("query does not return results");
|
|
||||||
rs.close();
|
|
||||||
db.reset(pointer);
|
|
||||||
resultsWaiting = db.execute(this, batch);
|
|
||||||
return getResultSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int executeUpdate() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
if (columnCount != 0)
|
|
||||||
throw new SQLException("query returns results");
|
|
||||||
rs.close();
|
|
||||||
db.reset(pointer);
|
|
||||||
return db.executeUpdate(this, batch);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int[] executeBatch() throws SQLException {
|
|
||||||
if (batchPos == 0)
|
|
||||||
return new int[] {};
|
|
||||||
try {
|
|
||||||
return db.executeBatch(pointer, batchPos / paramCount, batch);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
clearBatch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getUpdateCount() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
if (pointer == 0 || resultsWaiting)
|
|
||||||
return -1;
|
|
||||||
return db.changes();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addBatch() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
batchPos += paramCount;
|
|
||||||
if (batchPos + paramCount > batch.length) {
|
|
||||||
Object[] nb = new Object[batch.length * 2];
|
|
||||||
System.arraycopy(batch, 0, nb, 0, batch.length);
|
|
||||||
batch = nb;
|
|
||||||
}
|
|
||||||
System.arraycopy(batch, batchPos - paramCount, batch, batchPos, paramCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParameterMetaData FUNCTIONS //////////////////////////////////
|
|
||||||
|
|
||||||
public ParameterMetaData getParameterMetaData() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getParameterCount() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
return paramCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getParameterClassName(int param) throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
return "java.lang.String";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getParameterTypeName(int pos) {
|
|
||||||
return "VARCHAR";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getParameterType(int pos) {
|
|
||||||
return Types.VARCHAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getParameterMode(int pos) {
|
|
||||||
return parameterModeIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPrecision(int pos) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getScale(int pos) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int isNullable(int pos) {
|
|
||||||
return parameterNullable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSigned(int pos) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Statement getStatement() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PARAMETER FUNCTIONS //////////////////////////////////////////
|
|
||||||
|
|
||||||
private void batch(int pos, Object value) throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
if (batch == null)
|
|
||||||
batch = new Object[paramCount];
|
|
||||||
batch[batchPos + pos - 1] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBoolean(int pos, boolean value) throws SQLException {
|
|
||||||
setInt(pos, value ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setByte(int pos, byte value) throws SQLException {
|
|
||||||
setInt(pos, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBytes(int pos, byte[] value) throws SQLException {
|
|
||||||
batch(pos, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDouble(int pos, double value) throws SQLException {
|
|
||||||
batch(pos, new Double(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFloat(int pos, float value) throws SQLException {
|
|
||||||
batch(pos, new Float(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInt(int pos, int value) throws SQLException {
|
|
||||||
batch(pos, new Integer(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLong(int pos, long value) throws SQLException {
|
|
||||||
batch(pos, new Long(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNull(int pos, int u1) throws SQLException {
|
|
||||||
setNull(pos, u1, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNull(int pos, int u1, String u2) throws SQLException {
|
|
||||||
batch(pos, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObject(int pos, Object value) throws SQLException {
|
|
||||||
if (value == null)
|
|
||||||
batch(pos, null);
|
|
||||||
else if (value instanceof java.util.Date)
|
|
||||||
batch(pos, new Long(((java.util.Date) value).getTime()));
|
|
||||||
else if (value instanceof Date)
|
|
||||||
batch(pos, new Long(((Date) value).getTime()));
|
|
||||||
else if (value instanceof Time)
|
|
||||||
batch(pos, new Long(((Time) value).getTime()));
|
|
||||||
else if (value instanceof Timestamp)
|
|
||||||
batch(pos, new Long(((Timestamp) value).getTime()));
|
|
||||||
else if (value instanceof Long)
|
|
||||||
batch(pos, value);
|
|
||||||
else if (value instanceof Integer)
|
|
||||||
batch(pos, value);
|
|
||||||
else if (value instanceof Short)
|
|
||||||
batch(pos, new Integer(((Short) value).intValue()));
|
|
||||||
else if (value instanceof Float)
|
|
||||||
batch(pos, value);
|
|
||||||
else if (value instanceof Double)
|
|
||||||
batch(pos, value);
|
|
||||||
else if (value instanceof Boolean)
|
|
||||||
setBoolean(pos, ((Boolean) value).booleanValue());
|
|
||||||
else if (value instanceof byte[])
|
|
||||||
batch(pos, value);
|
|
||||||
else
|
|
||||||
batch(pos, value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObject(int p, Object v, int t) throws SQLException {
|
|
||||||
setObject(p, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObject(int p, Object v, int t, int s) throws SQLException {
|
|
||||||
setObject(p, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShort(int pos, short value) throws SQLException {
|
|
||||||
setInt(pos, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setString(int pos, String value) throws SQLException {
|
|
||||||
batch(pos, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCharacterStream(int pos, Reader reader, int length) throws SQLException {
|
|
||||||
try {
|
|
||||||
// copy chars from reader to StringBuffer
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
char[] cbuf = new char[8192];
|
|
||||||
int cnt;
|
|
||||||
|
|
||||||
while ((cnt = reader.read(cbuf)) > 0) {
|
|
||||||
sb.append(cbuf, 0, cnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set as string
|
|
||||||
setString(pos, sb.toString());
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new SQLException("Cannot read from character stream, exception message: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDate(int pos, Date x) throws SQLException {
|
|
||||||
setObject(pos, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDate(int pos, Date x, Calendar cal) throws SQLException {
|
|
||||||
setObject(pos, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTime(int pos, Time x) throws SQLException {
|
|
||||||
setObject(pos, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTime(int pos, Time x, Calendar cal) throws SQLException {
|
|
||||||
setObject(pos, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimestamp(int pos, Timestamp x) throws SQLException {
|
|
||||||
setObject(pos, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimestamp(int pos, Timestamp x, Calendar cal) throws SQLException {
|
|
||||||
setObject(pos, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResultSetMetaData getMetaData() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
return rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// UNUSED ///////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean execute(String sql) throws SQLException {
|
|
||||||
throw unused();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int executeUpdate(String sql) throws SQLException {
|
|
||||||
throw unused();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResultSet executeQuery(String sql) throws SQLException {
|
|
||||||
throw unused();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addBatch(String sql) throws SQLException {
|
|
||||||
throw unused();
|
|
||||||
}
|
|
||||||
|
|
||||||
private SQLException unused() {
|
|
||||||
return new SQLException("not supported by PreparedStatment");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,540 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.sql.Date;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.ResultSetMetaData;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.SQLWarning;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.sql.Time;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.sql.Types;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements a JDBC ResultSet.
|
|
||||||
*/
|
|
||||||
final class RS extends Unused implements ResultSet, ResultSetMetaData, Codes
|
|
||||||
{
|
|
||||||
private final Stmt stmt;
|
|
||||||
private final DB db;
|
|
||||||
|
|
||||||
boolean open = false; // true means have results and can iterate them
|
|
||||||
int maxRows; // max. number of rows as set by a Statement
|
|
||||||
String[] cols = null; // if null, the RS is closed()
|
|
||||||
String[] colsMeta = null; // same as cols, but used by Meta interface
|
|
||||||
boolean[][] meta = null;
|
|
||||||
|
|
||||||
private int limitRows; // 0 means no limit, must check against maxRows
|
|
||||||
private int row = 0; // number of current row, starts at 1 (0 is for before loading data)
|
|
||||||
private int lastCol; // last column accessed, for wasNull(). -1 if none
|
|
||||||
|
|
||||||
RS(Stmt stmt) {
|
|
||||||
this.stmt = stmt;
|
|
||||||
this.db = stmt.db;
|
|
||||||
}
|
|
||||||
|
|
||||||
// INTERNAL FUNCTIONS ///////////////////////////////////////////
|
|
||||||
|
|
||||||
boolean isOpen() {
|
|
||||||
return open;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Throws SQLException if ResultSet is not open. */
|
|
||||||
void checkOpen() throws SQLException {
|
|
||||||
if (!open)
|
|
||||||
throw new SQLException("ResultSet closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
// takes col in [1,x] form, returns in [0,x-1] form
|
|
||||||
private int checkCol(int col) throws SQLException {
|
|
||||||
if (colsMeta == null)
|
|
||||||
throw new IllegalStateException("SQLite JDBC: inconsistent internal state");
|
|
||||||
if (col < 1 || col > colsMeta.length)
|
|
||||||
throw new SQLException("column " + col + " out of bounds [1," + colsMeta.length + "]");
|
|
||||||
return --col;
|
|
||||||
}
|
|
||||||
|
|
||||||
// takes col in [1,x] form, marks it as last accessed and returns [0,x-1]
|
|
||||||
private int markCol(int col) throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
checkCol(col);
|
|
||||||
lastCol = col;
|
|
||||||
return --col;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkMeta() throws SQLException {
|
|
||||||
checkCol(1);
|
|
||||||
if (meta == null)
|
|
||||||
meta = db.column_metadata(stmt.pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResultSet Functions //////////////////////////////////////////
|
|
||||||
|
|
||||||
public void close() throws SQLException {
|
|
||||||
cols = null;
|
|
||||||
colsMeta = null;
|
|
||||||
meta = null;
|
|
||||||
open = false;
|
|
||||||
limitRows = 0;
|
|
||||||
row = 0;
|
|
||||||
lastCol = -1;
|
|
||||||
|
|
||||||
if (stmt == null)
|
|
||||||
return;
|
|
||||||
if (stmt != null && stmt.pointer != 0)
|
|
||||||
db.reset(stmt.pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns col in [1,x] form
|
|
||||||
public int findColumn(String col) throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
int c = -1;
|
|
||||||
for (int i = 0; i < cols.length; i++) {
|
|
||||||
if (col.equalsIgnoreCase(cols[i])
|
|
||||||
|| (cols[i].toUpperCase().endsWith(col.toUpperCase()) && cols[i].charAt(cols[i].length()
|
|
||||||
- col.length()) == '.')) {
|
|
||||||
if (c == -1)
|
|
||||||
c = i;
|
|
||||||
else
|
|
||||||
throw new SQLException("ambiguous column: '" + col + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (c == -1)
|
|
||||||
throw new SQLException("no such column: '" + col + "'");
|
|
||||||
else
|
|
||||||
return c + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean next() throws SQLException {
|
|
||||||
if (!open)
|
|
||||||
return false; // finished ResultSet
|
|
||||||
lastCol = -1;
|
|
||||||
|
|
||||||
// first row is loaded by execute(), so do not step() again
|
|
||||||
if (row == 0) {
|
|
||||||
row++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if we are row limited by the statement or the ResultSet
|
|
||||||
if (maxRows != 0 && row > maxRows)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// do the real work
|
|
||||||
int statusCode = db.step(stmt.pointer);
|
|
||||||
switch (statusCode) {
|
|
||||||
case SQLITE_DONE:
|
|
||||||
close(); // agressive closing to avoid writer starvation
|
|
||||||
return false;
|
|
||||||
case SQLITE_ROW:
|
|
||||||
row++;
|
|
||||||
return true;
|
|
||||||
case SQLITE_BUSY:
|
|
||||||
default:
|
|
||||||
db.throwex(statusCode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getType() throws SQLException {
|
|
||||||
return TYPE_FORWARD_ONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFetchSize() throws SQLException {
|
|
||||||
return limitRows;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFetchSize(int rows) throws SQLException {
|
|
||||||
if (0 > rows || (maxRows != 0 && rows > maxRows))
|
|
||||||
throw new SQLException("fetch size " + rows + " out of bounds " + maxRows);
|
|
||||||
limitRows = rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFetchDirection() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
return ResultSet.FETCH_FORWARD;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFetchDirection(int d) throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
if (d != ResultSet.FETCH_FORWARD)
|
|
||||||
throw new SQLException("only FETCH_FORWARD direction supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAfterLast() throws SQLException {
|
|
||||||
return !open;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isBeforeFirst() throws SQLException {
|
|
||||||
return open && row == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFirst() throws SQLException {
|
|
||||||
return row == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLast() throws SQLException { // FIXME
|
|
||||||
throw new SQLException("function not yet implemented for SQLite");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void finalize() throws SQLException {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRow() throws SQLException {
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean wasNull() throws SQLException {
|
|
||||||
return db.column_type(stmt.pointer, markCol(lastCol)) == SQLITE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DATA ACCESS FUNCTIONS ////////////////////////////////////////
|
|
||||||
|
|
||||||
public boolean getBoolean(int col) throws SQLException {
|
|
||||||
return getInt(col) == 0 ? false : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getBoolean(String col) throws SQLException {
|
|
||||||
return getBoolean(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte getByte(int col) throws SQLException {
|
|
||||||
return (byte) getInt(col);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte getByte(String col) throws SQLException {
|
|
||||||
return getByte(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes(int col) throws SQLException {
|
|
||||||
return db.column_blob(stmt.pointer, markCol(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes(String col) throws SQLException {
|
|
||||||
return getBytes(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Reader getCharacterStream(int col) throws SQLException {
|
|
||||||
return new StringReader(getString(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Reader getCharacterStream(String col) throws SQLException {
|
|
||||||
return getCharacterStream(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getDate(int col) throws SQLException {
|
|
||||||
if (db.column_type(stmt.pointer, markCol(col)) == SQLITE_NULL)
|
|
||||||
return null;
|
|
||||||
return new Date(db.column_long(stmt.pointer, markCol(col)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getDate(int col, Calendar cal) throws SQLException {
|
|
||||||
if (db.column_type(stmt.pointer, markCol(col)) == SQLITE_NULL)
|
|
||||||
return null;
|
|
||||||
if (cal == null)
|
|
||||||
return getDate(col);
|
|
||||||
cal.setTimeInMillis(db.column_long(stmt.pointer, markCol(col)));
|
|
||||||
return new Date(cal.getTime().getTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getDate(String col) throws SQLException {
|
|
||||||
return getDate(findColumn(col), Calendar.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getDate(String col, Calendar cal) throws SQLException {
|
|
||||||
return getDate(findColumn(col), cal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDouble(int col) throws SQLException {
|
|
||||||
if (db.column_type(stmt.pointer, markCol(col)) == SQLITE_NULL)
|
|
||||||
return 0;
|
|
||||||
return db.column_double(stmt.pointer, markCol(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDouble(String col) throws SQLException {
|
|
||||||
return getDouble(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getFloat(int col) throws SQLException {
|
|
||||||
if (db.column_type(stmt.pointer, markCol(col)) == SQLITE_NULL)
|
|
||||||
return 0;
|
|
||||||
return (float) db.column_double(stmt.pointer, markCol(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getFloat(String col) throws SQLException {
|
|
||||||
return getFloat(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getInt(int col) throws SQLException {
|
|
||||||
return db.column_int(stmt.pointer, markCol(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getInt(String col) throws SQLException {
|
|
||||||
return getInt(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLong(int col) throws SQLException {
|
|
||||||
return db.column_long(stmt.pointer, markCol(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLong(String col) throws SQLException {
|
|
||||||
return getLong(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getShort(int col) throws SQLException {
|
|
||||||
return (short) getInt(col);
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getShort(String col) throws SQLException {
|
|
||||||
return getShort(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getString(int col) throws SQLException {
|
|
||||||
return db.column_text(stmt.pointer, markCol(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getString(String col) throws SQLException {
|
|
||||||
return getString(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Time getTime(int col) throws SQLException {
|
|
||||||
if (db.column_type(stmt.pointer, markCol(col)) == SQLITE_NULL)
|
|
||||||
return null;
|
|
||||||
return new Time(db.column_long(stmt.pointer, markCol(col)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Time getTime(int col, Calendar cal) throws SQLException {
|
|
||||||
if (cal == null)
|
|
||||||
return getTime(col);
|
|
||||||
if (db.column_type(stmt.pointer, markCol(col)) == SQLITE_NULL)
|
|
||||||
return null;
|
|
||||||
cal.setTimeInMillis(db.column_long(stmt.pointer, markCol(col)));
|
|
||||||
return new Time(cal.getTime().getTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Time getTime(String col) throws SQLException {
|
|
||||||
return getTime(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Time getTime(String col, Calendar cal) throws SQLException {
|
|
||||||
return getTime(findColumn(col), cal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getTimestamp(int col) throws SQLException {
|
|
||||||
if (db.column_type(stmt.pointer, markCol(col)) == SQLITE_NULL)
|
|
||||||
return null;
|
|
||||||
return new Timestamp(db.column_long(stmt.pointer, markCol(col)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getTimestamp(int col, Calendar cal) throws SQLException {
|
|
||||||
if (cal == null)
|
|
||||||
return getTimestamp(col);
|
|
||||||
if (db.column_type(stmt.pointer, markCol(col)) == SQLITE_NULL)
|
|
||||||
return null;
|
|
||||||
cal.setTimeInMillis(db.column_long(stmt.pointer, markCol(col)));
|
|
||||||
return new Timestamp(cal.getTime().getTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getTimestamp(String col) throws SQLException {
|
|
||||||
return getTimestamp(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Timestamp getTimestamp(String c, Calendar ca) throws SQLException {
|
|
||||||
return getTimestamp(findColumn(c), ca);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getObject(int col) throws SQLException {
|
|
||||||
switch (db.column_type(stmt.pointer, checkCol(col))) {
|
|
||||||
case SQLITE_INTEGER:
|
|
||||||
long val = getLong(col);
|
|
||||||
if (val > Integer.MAX_VALUE || val < Integer.MIN_VALUE)
|
|
||||||
return new Long(val);
|
|
||||||
else
|
|
||||||
return new Integer((int) val);
|
|
||||||
case SQLITE_FLOAT:
|
|
||||||
return new Double(getDouble(col));
|
|
||||||
case SQLITE_BLOB:
|
|
||||||
return getBytes(col);
|
|
||||||
case SQLITE_NULL:
|
|
||||||
return null;
|
|
||||||
case SQLITE_TEXT:
|
|
||||||
default:
|
|
||||||
return getString(col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getObject(String col) throws SQLException {
|
|
||||||
return getObject(findColumn(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Statement getStatement() {
|
|
||||||
return stmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCursorName() throws SQLException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SQLWarning getWarnings() throws SQLException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearWarnings() throws SQLException {}
|
|
||||||
|
|
||||||
// ResultSetMetaData Functions //////////////////////////////////
|
|
||||||
|
|
||||||
// we do not need to check the RS is open, only that colsMeta
|
|
||||||
// is not null, done with checkCol(int).
|
|
||||||
|
|
||||||
public ResultSetMetaData getMetaData() throws SQLException {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCatalogName(int col) throws SQLException {
|
|
||||||
return db.column_table_name(stmt.pointer, checkCol(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getColumnClassName(int col) throws SQLException {
|
|
||||||
checkCol(col);
|
|
||||||
return "java.lang.Object";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColumnCount() throws SQLException {
|
|
||||||
checkCol(1);
|
|
||||||
return colsMeta.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColumnDisplaySize(int col) throws SQLException {
|
|
||||||
return Integer.MAX_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getColumnLabel(int col) throws SQLException {
|
|
||||||
return getColumnName(col);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getColumnName(int col) throws SQLException {
|
|
||||||
return db.column_name(stmt.pointer, checkCol(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColumnType(int col) throws SQLException {
|
|
||||||
switch (db.column_type(stmt.pointer, checkCol(col))) {
|
|
||||||
case SQLITE_INTEGER:
|
|
||||||
return Types.INTEGER;
|
|
||||||
case SQLITE_FLOAT:
|
|
||||||
return Types.FLOAT;
|
|
||||||
case SQLITE_BLOB:
|
|
||||||
return Types.BLOB;
|
|
||||||
case SQLITE_NULL:
|
|
||||||
return Types.NULL;
|
|
||||||
case SQLITE_TEXT:
|
|
||||||
default:
|
|
||||||
return Types.VARCHAR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getColumnTypeName(int col) throws SQLException {
|
|
||||||
switch (db.column_type(stmt.pointer, checkCol(col))) {
|
|
||||||
case SQLITE_INTEGER:
|
|
||||||
return "integer";
|
|
||||||
case SQLITE_FLOAT:
|
|
||||||
return "float";
|
|
||||||
case SQLITE_BLOB:
|
|
||||||
return "blob";
|
|
||||||
case SQLITE_NULL:
|
|
||||||
return "null";
|
|
||||||
case SQLITE_TEXT:
|
|
||||||
default:
|
|
||||||
return "text";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPrecision(int col) throws SQLException {
|
|
||||||
return 0;
|
|
||||||
} // FIXME
|
|
||||||
|
|
||||||
public int getScale(int col) throws SQLException {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSchemaName(int col) throws SQLException {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTableName(int col) throws SQLException {
|
|
||||||
return db.column_table_name(stmt.pointer, checkCol(col));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int isNullable(int col) throws SQLException {
|
|
||||||
checkMeta();
|
|
||||||
return meta[checkCol(col)][1] ? columnNoNulls : columnNullable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAutoIncrement(int col) throws SQLException {
|
|
||||||
checkMeta();
|
|
||||||
return meta[checkCol(col)][2];
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCaseSensitive(int col) throws SQLException {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCurrency(int col) throws SQLException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDefinitelyWritable(int col) throws SQLException {
|
|
||||||
return true;
|
|
||||||
} // FIXME: check db file constraints?
|
|
||||||
|
|
||||||
public boolean isReadOnly(int col) throws SQLException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSearchable(int col) throws SQLException {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSigned(int col) throws SQLException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isWritable(int col) throws SQLException {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getConcurrency() throws SQLException {
|
|
||||||
return CONCUR_READ_ONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean rowDeleted() throws SQLException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean rowInserted() throws SQLException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean rowUpdated() throws SQLException {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,102 +0,0 @@
|
|||||||
/*--------------------------------------------------------------------------
|
|
||||||
* Copyright 2009 Taro L. Saito
|
|
||||||
*
|
|
||||||
* Licensed 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.
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
//--------------------------------------
|
|
||||||
// sqlite-jdbc Project
|
|
||||||
//
|
|
||||||
// ResourceFinder.java
|
|
||||||
// Since: Apr 28, 2009
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Author$
|
|
||||||
//--------------------------------------
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resource address finder for files inside the jar file
|
|
||||||
*
|
|
||||||
* @author leo
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ResourceFinder
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Gets the {@link URL} of the file resource
|
|
||||||
*
|
|
||||||
* @param referenceClass
|
|
||||||
* the base class for finding resources files. This method will
|
|
||||||
* search the package containing the given referenceClass.
|
|
||||||
* @param resourceFileName
|
|
||||||
* the resource file name relative to the package of the
|
|
||||||
* referenceClass
|
|
||||||
* @return the URL of the file resource
|
|
||||||
*/
|
|
||||||
public static URL find(Class< ? > referenceClass, String resourceFileName)
|
|
||||||
{
|
|
||||||
return find(referenceClass.getClassLoader(), referenceClass.getPackage(), resourceFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the {@link URL} of the resource
|
|
||||||
*
|
|
||||||
* @param basePackage
|
|
||||||
* the base package to find the resource
|
|
||||||
* @param resourceFileName
|
|
||||||
* the resource file name relative to the package folder
|
|
||||||
* @return the URL of the specified resource
|
|
||||||
*/
|
|
||||||
public static URL find(ClassLoader classLoader, Package basePackage, String resourceFileName)
|
|
||||||
{
|
|
||||||
return find(classLoader, basePackage.getName(), resourceFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the {@link URL} of the resource
|
|
||||||
*
|
|
||||||
* @param packageName
|
|
||||||
* the base package name to find the resource
|
|
||||||
* @param resourceFileName
|
|
||||||
* the resource file name relative to the package folder
|
|
||||||
* @return the URL of the specified resource
|
|
||||||
*/
|
|
||||||
public static URL find(ClassLoader classLoader, String packageName, String resourceFileName)
|
|
||||||
{
|
|
||||||
String packagePath = packagePath(packageName);
|
|
||||||
String resourcePath = packagePath + resourceFileName;
|
|
||||||
if (!resourcePath.startsWith("/"))
|
|
||||||
resourcePath = "/" + resourcePath;
|
|
||||||
|
|
||||||
return classLoader.getResource(resourcePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String packagePath(Class< ? > referenceClass)
|
|
||||||
{
|
|
||||||
return packagePath(referenceClass.getPackage());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String packagePath(Package basePackage)
|
|
||||||
{
|
|
||||||
return packagePath(basePackage.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String packagePath(String packageName)
|
|
||||||
{
|
|
||||||
String packageAsPath = packageName.replaceAll("\\.", "/");
|
|
||||||
return packageAsPath.endsWith("/") ? packageAsPath : packageAsPath + "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,449 +0,0 @@
|
|||||||
/*--------------------------------------------------------------------------
|
|
||||||
* Copyright 2009 Taro L. Saito
|
|
||||||
*
|
|
||||||
* Licensed 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.
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
//--------------------------------------
|
|
||||||
// sqlite-jdbc Project
|
|
||||||
//
|
|
||||||
// SQLiteConfig.java
|
|
||||||
// Since: Dec 8, 2009
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Author$
|
|
||||||
//--------------------------------------
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.DriverPropertyInfo;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQLite Configuration
|
|
||||||
*
|
|
||||||
* See also http://www.sqlite.org/pragma.html
|
|
||||||
*
|
|
||||||
* @author leo
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SQLiteConfig
|
|
||||||
{
|
|
||||||
private final Properties pragmaTable;
|
|
||||||
private int openModeFlag = 0x00;
|
|
||||||
|
|
||||||
public SQLiteConfig() {
|
|
||||||
this(new Properties());
|
|
||||||
}
|
|
||||||
|
|
||||||
public SQLiteConfig(Properties prop) {
|
|
||||||
this.pragmaTable = prop;
|
|
||||||
String openMode = pragmaTable.getProperty(Pragma.OPEN_MODE.pragmaName);
|
|
||||||
if (openMode != null) {
|
|
||||||
openModeFlag = Integer.parseInt(openMode);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// set the default open mode of SQLite3
|
|
||||||
setOpenMode(SQLiteOpenMode.READWRITE);
|
|
||||||
setOpenMode(SQLiteOpenMode.CREATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new JDBC connection using the current configuration
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* @throws SQLException
|
|
||||||
*/
|
|
||||||
public Connection createConnection(String url) throws SQLException {
|
|
||||||
return JDBC.createConnection(url, toProperties());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply the current configuration to connection
|
|
||||||
*
|
|
||||||
* @param conn
|
|
||||||
* @throws SQLException
|
|
||||||
*/
|
|
||||||
public void apply(Connection conn) throws SQLException {
|
|
||||||
|
|
||||||
HashSet<String> pragmaParams = new HashSet<String>();
|
|
||||||
for (Pragma each : Pragma.values()) {
|
|
||||||
pragmaParams.add(each.pragmaName);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragmaParams.remove(Pragma.OPEN_MODE.pragmaName);
|
|
||||||
pragmaParams.remove(Pragma.SHARED_CACHE.pragmaName);
|
|
||||||
pragmaParams.remove(Pragma.LOAD_EXTENSION.pragmaName);
|
|
||||||
|
|
||||||
Statement stat = conn.createStatement();
|
|
||||||
try {
|
|
||||||
int count = 0;
|
|
||||||
for (Object each : pragmaTable.keySet()) {
|
|
||||||
String key = each.toString();
|
|
||||||
if (!pragmaParams.contains(key))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
String value = pragmaTable.getProperty(key);
|
|
||||||
if (value != null) {
|
|
||||||
String sql = String.format("pragma %s=%s", key, value);
|
|
||||||
stat.addBatch(sql);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (count > 0)
|
|
||||||
stat.executeBatch();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if (stat != null)
|
|
||||||
stat.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void set(Pragma pragma, boolean flag) {
|
|
||||||
setPragma(pragma, Boolean.toString(flag));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void set(Pragma pragma, int num) {
|
|
||||||
setPragma(pragma, Integer.toString(num));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean getBoolean(Pragma pragma, String defaultValue) {
|
|
||||||
return Boolean.parseBoolean(pragmaTable.getProperty(pragma.pragmaName, defaultValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnabledSharedCache() {
|
|
||||||
return getBoolean(Pragma.SHARED_CACHE, "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnabledLoadExtension() {
|
|
||||||
return getBoolean(Pragma.LOAD_EXTENSION, "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOpenModeFlags() {
|
|
||||||
return openModeFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a pragma value. To take effect the pragma settings,
|
|
||||||
*
|
|
||||||
* @param pragma
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void setPragma(Pragma pragma, String value) {
|
|
||||||
pragmaTable.put(pragma.pragmaName, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert this SQLiteConfig settings into a Properties object, that can be
|
|
||||||
* passed to the {@link DriverManager#getConnection(String, Properties)}.
|
|
||||||
*
|
|
||||||
* @return properties representation of this configuration
|
|
||||||
*/
|
|
||||||
public Properties toProperties() {
|
|
||||||
pragmaTable.setProperty(Pragma.OPEN_MODE.pragmaName, Integer.toString(openModeFlag));
|
|
||||||
|
|
||||||
return pragmaTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DriverPropertyInfo[] getDriverPropertyInfo() {
|
|
||||||
Pragma[] pragma = Pragma.values();
|
|
||||||
DriverPropertyInfo[] result = new DriverPropertyInfo[pragma.length];
|
|
||||||
int index = 0;
|
|
||||||
for (Pragma p : Pragma.values()) {
|
|
||||||
DriverPropertyInfo di = new DriverPropertyInfo(p.pragmaName, null);
|
|
||||||
di.choices = p.choices;
|
|
||||||
di.description = p.description;
|
|
||||||
di.required = false;
|
|
||||||
result[index++] = di;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String[] OnOff = new String[] { "true", "false" };
|
|
||||||
|
|
||||||
private static enum Pragma {
|
|
||||||
|
|
||||||
// Parameters requiring SQLite3 API invocation
|
|
||||||
OPEN_MODE("open_mode", "Database open-mode flag", null),
|
|
||||||
SHARED_CACHE("shared_cache", "Enablse SQLite Shared-Cache mode, native driver only", OnOff),
|
|
||||||
LOAD_EXTENSION("enable_load_extension", "Enable SQLite load_extention() function, native driver only", OnOff),
|
|
||||||
|
|
||||||
// Pragmas that can be set after opening the database
|
|
||||||
CACHE_SIZE("cache_size"),
|
|
||||||
CASE_SENSITIVE_LIKE("case_sensitive_like", OnOff),
|
|
||||||
COUNT_CHANGES("count_changes", OnOff),
|
|
||||||
DEFAULT_CACHE_SIZE("default_cache_size"),
|
|
||||||
EMPTY_RESULT_CALLBACKS("empty_result_callback", OnOff),
|
|
||||||
ENCODING("encoding", toStringArray(Encoding.values())),
|
|
||||||
FOREIGN_KEYS("foreign_keys", OnOff),
|
|
||||||
FULL_COLUMN_NAMES("full_column_names", OnOff),
|
|
||||||
FULL_SYNC("fullsync", OnOff),
|
|
||||||
INCREMENTAL_VACUUM("incremental_vacuum"),
|
|
||||||
JOURNAL_MODE("journal_mode", toStringArray(JournalMode.values())),
|
|
||||||
JOURNAL_SIZE_LIMIT("journal_size_limit"),
|
|
||||||
LEGACY_FILE_FORMAT("legacy_file_format", OnOff),
|
|
||||||
LOCKING_MODE("locking_mode", toStringArray(LockingMode.values())),
|
|
||||||
PAGE_SIZE("page_size"),
|
|
||||||
MAX_PAGE_COUNT("max_page_count"),
|
|
||||||
READ_UNCOMMITED("read_uncommited", OnOff),
|
|
||||||
RECURSIVE_TRIGGERS("recursive_triggers", OnOff),
|
|
||||||
REVERSE_UNORDERED_SELECTS("reverse_unordered_selects", OnOff),
|
|
||||||
SHORT_COLUMN_NAMES("short_column_names", OnOff),
|
|
||||||
SYNCHRONOUS("synchronous", toStringArray(SynchronousMode.values())),
|
|
||||||
TEMP_STORE("temp_store", toStringArray(TempStore.values())),
|
|
||||||
TEMP_STORE_DIRECTORY("temp_store_directory"),
|
|
||||||
USER_VERSION("user_version");
|
|
||||||
|
|
||||||
public final String pragmaName;
|
|
||||||
public final String[] choices;
|
|
||||||
public final String description;
|
|
||||||
|
|
||||||
private Pragma(String pragmaName) {
|
|
||||||
this(pragmaName, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Pragma(String pragmaName, String[] choices) {
|
|
||||||
this(pragmaName, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Pragma(String pragmaName, String description, String[] choices) {
|
|
||||||
this.pragmaName = pragmaName;
|
|
||||||
this.description = description;
|
|
||||||
this.choices = choices;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the database open mode
|
|
||||||
*
|
|
||||||
* @param mode
|
|
||||||
*/
|
|
||||||
public void setOpenMode(SQLiteOpenMode mode) {
|
|
||||||
openModeFlag |= mode.flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the specified database open mode flag
|
|
||||||
*
|
|
||||||
* @param mode
|
|
||||||
*/
|
|
||||||
public void resetOpenMode(SQLiteOpenMode mode) {
|
|
||||||
openModeFlag &= ~mode.flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSharedCache(boolean enable) {
|
|
||||||
set(Pragma.SHARED_CACHE, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableLoadExtension(boolean enable) {
|
|
||||||
set(Pragma.LOAD_EXTENSION, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReadOnly(boolean readOnly) {
|
|
||||||
if (readOnly) {
|
|
||||||
setOpenMode(SQLiteOpenMode.READONLY);
|
|
||||||
resetOpenMode(SQLiteOpenMode.READWRITE);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setOpenMode(SQLiteOpenMode.READWRITE);
|
|
||||||
resetOpenMode(SQLiteOpenMode.READONLY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCacheSize(int numberOfPages) {
|
|
||||||
set(Pragma.CACHE_SIZE, numberOfPages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableCaseSensitiveLike(boolean enable) {
|
|
||||||
set(Pragma.CASE_SENSITIVE_LIKE, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableCountChanges(boolean enable) {
|
|
||||||
set(Pragma.COUNT_CHANGES, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the cache size persistently across database connections
|
|
||||||
*
|
|
||||||
* @param numberOfPages
|
|
||||||
*/
|
|
||||||
public void setDefaultCacheSize(int numberOfPages) {
|
|
||||||
set(Pragma.DEFAULT_CACHE_SIZE, numberOfPages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableEmptyResultCallBacks(boolean enable) {
|
|
||||||
set(Pragma.EMPTY_RESULT_CALLBACKS, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The common interface for retrieving the available pragma parameter
|
|
||||||
* values.
|
|
||||||
*
|
|
||||||
* @author leo
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static interface PragmaValue
|
|
||||||
{
|
|
||||||
public String getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the given Enum values to a string array
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static String[] toStringArray(PragmaValue[] list) {
|
|
||||||
String[] result = new String[list.length];
|
|
||||||
for (int i = 0; i < list.length; i++) {
|
|
||||||
result[i] = list[i].getValue();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum Encoding implements PragmaValue {
|
|
||||||
UTF8("UTF-8"), UTF16("UTF-16"), UTF16_LITTLE_ENDIAN("UTF-16le"), UTF16_BIG_ENDIAN("UTF-16be");
|
|
||||||
public final String typeName;
|
|
||||||
|
|
||||||
private Encoding(String typeName) {
|
|
||||||
this.typeName = typeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return typeName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum JournalMode implements PragmaValue {
|
|
||||||
DELETE, TRUNCATE, PERSIST, MEMORY, OFF;
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return name();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEncoding(Encoding encoding) {
|
|
||||||
setPragma(Pragma.ENCODING, encoding.typeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enforceForeignKeys(boolean enforce) {
|
|
||||||
set(Pragma.FOREIGN_KEYS, enforce);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableFullColumnNames(boolean enable) {
|
|
||||||
set(Pragma.FULL_COLUMN_NAMES, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableFullSync(boolean enable) {
|
|
||||||
set(Pragma.FULL_SYNC, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void incrementalVacuum(int numberOfPagesToBeRemoved) {
|
|
||||||
set(Pragma.INCREMENTAL_VACUUM, numberOfPagesToBeRemoved);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJournalMode(JournalMode mode) {
|
|
||||||
setPragma(Pragma.JOURNAL_MODE, mode.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
// public void setJournalMode(String databaseName, JournalMode mode) {
|
|
||||||
// setPragma(databaseName, Pragma.JOURNAL_MODE, mode.name());
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void setJounalSizeLimit(int limit) {
|
|
||||||
set(Pragma.JOURNAL_SIZE_LIMIT, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void useLegacyFileFormat(boolean use) {
|
|
||||||
set(Pragma.LEGACY_FILE_FORMAT, use);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum LockingMode implements PragmaValue {
|
|
||||||
NORMAL, EXCLUSIVE;
|
|
||||||
public String getValue() {
|
|
||||||
return name();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLockingMode(LockingMode mode) {
|
|
||||||
setPragma(Pragma.LOCKING_MODE, mode.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
// public void setLockingMode(String databaseName, LockingMode mode) {
|
|
||||||
// setPragma(databaseName, Pragma.LOCKING_MODE, mode.name());
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void setPageSize(int numBytes) {
|
|
||||||
set(Pragma.PAGE_SIZE, numBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxPageCount(int numPages) {
|
|
||||||
set(Pragma.MAX_PAGE_COUNT, numPages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReadUncommited(boolean useReadUncommitedIsolationMode) {
|
|
||||||
set(Pragma.READ_UNCOMMITED, useReadUncommitedIsolationMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableRecursiveTriggers(boolean enable) {
|
|
||||||
set(Pragma.RECURSIVE_TRIGGERS, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableReverseUnorderedSelects(boolean enable) {
|
|
||||||
set(Pragma.REVERSE_UNORDERED_SELECTS, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableShortColumnNames(boolean enable) {
|
|
||||||
set(Pragma.SHORT_COLUMN_NAMES, enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum SynchronousMode implements PragmaValue {
|
|
||||||
OFF, NORMAL, FULL;
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return name();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSynchronous(SynchronousMode mode) {
|
|
||||||
setPragma(Pragma.SYNCHRONOUS, mode.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum TempStore implements PragmaValue {
|
|
||||||
DEFAULT, FILE, MEMORY;
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return name();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTempStore(TempStore storeType) {
|
|
||||||
setPragma(Pragma.TEMP_STORE, storeType.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTempStoreDirectory(String directoryName) {
|
|
||||||
setPragma(Pragma.TEMP_STORE_DIRECTORY, String.format("'%s'", directoryName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserVersion(int version) {
|
|
||||||
set(Pragma.USER_VERSION, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,228 +0,0 @@
|
|||||||
/*--------------------------------------------------------------------------
|
|
||||||
* Copyright 2010 Taro L. Saito
|
|
||||||
*
|
|
||||||
* Licensed 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.
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
//--------------------------------------
|
|
||||||
// sqlite-jdbc Project
|
|
||||||
//
|
|
||||||
// SQLiteDataSource.java
|
|
||||||
// Since: Mar 11, 2010
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Author$
|
|
||||||
//--------------------------------------
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
import org.sqlite.SQLiteConfig.Encoding;
|
|
||||||
import org.sqlite.SQLiteConfig.JournalMode;
|
|
||||||
import org.sqlite.SQLiteConfig.LockingMode;
|
|
||||||
import org.sqlite.SQLiteConfig.SynchronousMode;
|
|
||||||
import org.sqlite.SQLiteConfig.TempStore;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides {@link DataSource} API for configuring SQLite database connection
|
|
||||||
*
|
|
||||||
* @author leo
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SQLiteDataSource implements DataSource
|
|
||||||
{
|
|
||||||
private SQLiteConfig config;
|
|
||||||
private transient PrintWriter logger;
|
|
||||||
private int loginTimeout = 1;
|
|
||||||
|
|
||||||
private String url = JDBC.PREFIX; // use memory database in default
|
|
||||||
|
|
||||||
public SQLiteDataSource() {
|
|
||||||
this.config = new SQLiteConfig(); // default configuration
|
|
||||||
}
|
|
||||||
|
|
||||||
public SQLiteDataSource(SQLiteConfig config) {
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the configuration parameters via {@link SQLiteConfig} object
|
|
||||||
*
|
|
||||||
* @param config
|
|
||||||
*/
|
|
||||||
public void setConfig(SQLiteConfig config) {
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SQLiteConfig getConfig() {
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
// configuration parameters
|
|
||||||
public void setUrl(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSharedCache(boolean enable) {
|
|
||||||
config.setSharedCache(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLoadExtension(boolean enable) {
|
|
||||||
config.enableLoadExtension(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReadOnly(boolean readOnly) {
|
|
||||||
config.setReadOnly(readOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCacheSize(int numberOfPages) {
|
|
||||||
config.setCacheSize(numberOfPages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCaseSensitiveLike(boolean enable) {
|
|
||||||
config.enableCaseSensitiveLike(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCouncChanges(boolean enable) {
|
|
||||||
config.enableCountChanges(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefaultCacheSize(int numberOfPages) {
|
|
||||||
config.setDefaultCacheSize(numberOfPages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEncoding(String encoding) {
|
|
||||||
config.setEncoding(Encoding.valueOf(encoding));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnforceForeinKeys(boolean enforce) {
|
|
||||||
config.enforceForeignKeys(enforce);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFullColumnNames(boolean enable) {
|
|
||||||
config.enableFullColumnNames(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFullSync(boolean enable) {
|
|
||||||
config.enableFullSync(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIncrementalVacuum(int numberOfPagesToBeRemoved) {
|
|
||||||
config.incrementalVacuum(numberOfPagesToBeRemoved);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJournalMode(String mode) {
|
|
||||||
config.setJournalMode(JournalMode.valueOf(mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJournalSizeLimit(int limit) {
|
|
||||||
config.setJounalSizeLimit(limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLegacyFileFormat(boolean use) {
|
|
||||||
config.useLegacyFileFormat(use);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLockingMode(String mode) {
|
|
||||||
config.setLockingMode(LockingMode.valueOf(mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPageSize(int numBytes) {
|
|
||||||
config.setPageSize(numBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxPageCount(int numPages) {
|
|
||||||
config.setMaxPageCount(numPages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReadUncommited(boolean useReadUncommitedIsolationMode) {
|
|
||||||
config.setReadUncommited(useReadUncommitedIsolationMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRecursiveTriggers(boolean enable) {
|
|
||||||
config.enableRecursiveTriggers(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReverseUnorderedSelects(boolean enable) {
|
|
||||||
config.enableReverseUnorderedSelects(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShortColumnNames(boolean enable) {
|
|
||||||
config.enableShortColumnNames(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSynchronous(String mode) {
|
|
||||||
config.setSynchronous(SynchronousMode.valueOf(mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTempStore(String storeType) {
|
|
||||||
config.setTempStore(TempStore.valueOf(storeType));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTempStoreDirectory(String directoryName) {
|
|
||||||
config.setTempStoreDirectory(directoryName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserVersion(int version) {
|
|
||||||
config.setUserVersion(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
// codes for the DataSource interface
|
|
||||||
|
|
||||||
public Connection getConnection() throws SQLException {
|
|
||||||
return getConnection(null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Connection getConnection(String username, String password) throws SQLException {
|
|
||||||
Properties p = config.toProperties();
|
|
||||||
if (username != null)
|
|
||||||
p.put("user", username);
|
|
||||||
if (password != null)
|
|
||||||
p.put("pass", password);
|
|
||||||
return JDBC.createConnection(url, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PrintWriter getLogWriter() throws SQLException {
|
|
||||||
return logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLoginTimeout() throws SQLException {
|
|
||||||
return loginTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLogWriter(PrintWriter out) throws SQLException {
|
|
||||||
this.logger = out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLoginTimeout(int seconds) throws SQLException {
|
|
||||||
loginTimeout = seconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isWrapperFor(Class< ? > iface) throws SQLException {
|
|
||||||
return iface.isInstance(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
|
||||||
return (T) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
/*--------------------------------------------------------------------------
|
|
||||||
* Copyright 2009 Taro L. Saito
|
|
||||||
*
|
|
||||||
* Licensed 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.
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
//--------------------------------------
|
|
||||||
// sqlite-jdbc Project
|
|
||||||
//
|
|
||||||
// SQLiteErrorCode.java
|
|
||||||
// Since: Apr 21, 2009
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Author$
|
|
||||||
//--------------------------------------
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQLite3 error code
|
|
||||||
*
|
|
||||||
* @author leo
|
|
||||||
* @see http://www.sqlite.org/c3ref/c_abort.html
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public enum SQLiteErrorCode {
|
|
||||||
|
|
||||||
UNKNOWN_ERROR(-1, "unknown error"),
|
|
||||||
SQLITE_OK(0, "Successful result"),
|
|
||||||
/* beginning-of-error-codes */
|
|
||||||
SQLITE_ERROR(1, "SQL error or missing database"),
|
|
||||||
SQLITE_INTERNAL(2, "Internal logic error in SQLite"),
|
|
||||||
SQLITE_PERM(3, " Access permission denied"),
|
|
||||||
SQLITE_ABORT(4, " Callback routine requested an abort"),
|
|
||||||
SQLITE_BUSY(5, " The database file is locked"),
|
|
||||||
SQLITE_LOCKED(6, " A table in the database is locked"),
|
|
||||||
SQLITE_NOMEM(7, " A malloc() failed"),
|
|
||||||
SQLITE_READONLY(8, " Attempt to write a readonly database"),
|
|
||||||
SQLITE_INTERRUPT(9, " Operation terminated by sqlite3_interrupt()"),
|
|
||||||
SQLITE_IOERR(10, " Some kind of disk I/O error occurred"),
|
|
||||||
SQLITE_CORRUPT(11, " The database disk image is malformed"),
|
|
||||||
SQLITE_NOTFOUND(12, " NOT USED. Table or record not found"),
|
|
||||||
SQLITE_FULL(13, " Insertion failed because database is full"),
|
|
||||||
SQLITE_CANTOPEN(14, " Unable to open the database file"),
|
|
||||||
SQLITE_PROTOCOL(15, " NOT USED. Database lock protocol error"),
|
|
||||||
SQLITE_EMPTY(16, " Database is empty"),
|
|
||||||
SQLITE_SCHEMA(17, " The database schema changed"),
|
|
||||||
SQLITE_TOOBIG(18, " String or BLOB exceeds size limit"),
|
|
||||||
SQLITE_CONSTRAINT(19, " Abort due to constraint violation"),
|
|
||||||
SQLITE_MISMATCH(20, " Data type mismatch"),
|
|
||||||
SQLITE_MISUSE(21, " Library used incorrectly"),
|
|
||||||
SQLITE_NOLFS(22, " Uses OS features not supported on host"),
|
|
||||||
SQLITE_AUTH(23, " Authorization denied"),
|
|
||||||
SQLITE_FORMAT(24, " Auxiliary database format error"),
|
|
||||||
SQLITE_RANGE(25, " 2nd parameter to sqlite3_bind out of range"),
|
|
||||||
SQLITE_NOTADB(26, " File opened that is not a database file"),
|
|
||||||
SQLITE_ROW(100, " sqlite3_step() has another row ready"),
|
|
||||||
SQLITE_DONE(101, " sqlite3_step() has finished executing");
|
|
||||||
|
|
||||||
public final int code;
|
|
||||||
public final String message;
|
|
||||||
|
|
||||||
private SQLiteErrorCode(int code, String message)
|
|
||||||
{
|
|
||||||
this.code = code;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SQLiteErrorCode getErrorCode(int errorCode)
|
|
||||||
{
|
|
||||||
for (SQLiteErrorCode each : SQLiteErrorCode.values())
|
|
||||||
{
|
|
||||||
if (errorCode == each.code)
|
|
||||||
return each;
|
|
||||||
}
|
|
||||||
return UNKNOWN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return String.format("[%s] %s", this.name(), message);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,271 +0,0 @@
|
|||||||
/*--------------------------------------------------------------------------
|
|
||||||
* Copyright 2007 Taro L. Saito
|
|
||||||
*
|
|
||||||
* Licensed 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.
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
//--------------------------------------
|
|
||||||
// SQLite JDBC Project
|
|
||||||
//
|
|
||||||
// SQLite.java
|
|
||||||
// Since: 2007/05/10
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Author$
|
|
||||||
//--------------------------------------
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.security.DigestInputStream;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the system properties, org.sqlite.lib.path, org.sqlite.lib.name,
|
|
||||||
* appropriately so that the SQLite JDBC driver can find *.dll, *.jnilib and
|
|
||||||
* *.so files, according to the current OS (win, linux, mac).
|
|
||||||
*
|
|
||||||
* The library files are automatically extracted from this project's package
|
|
||||||
* (JAR).
|
|
||||||
*
|
|
||||||
* usage: call {@link #initialize()} before using SQLite JDBC driver.
|
|
||||||
*
|
|
||||||
* @author leo
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SQLiteJDBCLoader
|
|
||||||
{
|
|
||||||
|
|
||||||
private static boolean extracted = false;
|
|
||||||
|
|
||||||
public static boolean initialize() {
|
|
||||||
loadSQLiteNativeLibrary();
|
|
||||||
return extracted;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean getPureJavaFlag() {
|
|
||||||
return Boolean.parseBoolean(System.getProperty("sqlite.purejava", "false"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isPureJavaMode() {
|
|
||||||
return !isNativeMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isNativeMode() {
|
|
||||||
if (getPureJavaFlag())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// load the driver
|
|
||||||
initialize();
|
|
||||||
return extracted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the MD5 value of the input stream
|
|
||||||
*
|
|
||||||
* @param input
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
* @throws NoSuchAlgorithmException
|
|
||||||
*/
|
|
||||||
static String md5sum(InputStream input) throws IOException {
|
|
||||||
BufferedInputStream in = new BufferedInputStream(input);
|
|
||||||
|
|
||||||
try {
|
|
||||||
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
|
|
||||||
DigestInputStream digestInputStream = new DigestInputStream(in, digest);
|
|
||||||
for (; digestInputStream.read() >= 0;) {
|
|
||||||
|
|
||||||
}
|
|
||||||
ByteArrayOutputStream md5out = new ByteArrayOutputStream();
|
|
||||||
md5out.write(digest.digest());
|
|
||||||
return md5out.toString();
|
|
||||||
}
|
|
||||||
catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new IllegalStateException("MD5 algorithm is not available: " + e);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract the specified library file to the target folder
|
|
||||||
*
|
|
||||||
* @param libFolderForCurrentOS
|
|
||||||
* @param libraryFileName
|
|
||||||
* @param targetFolder
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static boolean extractAndLoadLibraryFile(String libFolderForCurrentOS, String libraryFileName,
|
|
||||||
String targetFolder) {
|
|
||||||
String nativeLibraryFilePath = libFolderForCurrentOS + "/" + libraryFileName;
|
|
||||||
final String prefix = "sqlite-" + getVersion() + "-";
|
|
||||||
|
|
||||||
String extractedLibFileName = prefix + libraryFileName;
|
|
||||||
File extractedLibFile = new File(targetFolder, extractedLibFileName);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (extractedLibFile.exists()) {
|
|
||||||
// test md5sum value
|
|
||||||
String md5sum1 = md5sum(SQLiteJDBCLoader.class.getResourceAsStream(nativeLibraryFilePath));
|
|
||||||
String md5sum2 = md5sum(new FileInputStream(extractedLibFile));
|
|
||||||
|
|
||||||
if (md5sum1.equals(md5sum2)) {
|
|
||||||
return loadNativeLibrary(targetFolder, extractedLibFileName);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// remove old native library file
|
|
||||||
boolean deletionSucceeded = extractedLibFile.delete();
|
|
||||||
if (!deletionSucceeded) {
|
|
||||||
throw new IOException("failed to remove existing native library file: "
|
|
||||||
+ extractedLibFile.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract file into the current directory
|
|
||||||
InputStream reader = SQLiteJDBCLoader.class.getResourceAsStream(nativeLibraryFilePath);
|
|
||||||
FileOutputStream writer = new FileOutputStream(extractedLibFile);
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int bytesRead = 0;
|
|
||||||
while ((bytesRead = reader.read(buffer)) != -1) {
|
|
||||||
writer.write(buffer, 0, bytesRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.close();
|
|
||||||
reader.close();
|
|
||||||
|
|
||||||
if (!System.getProperty("os.name").contains("Windows")) {
|
|
||||||
try {
|
|
||||||
Runtime.getRuntime().exec(new String[] { "chmod", "755", extractedLibFile.getAbsolutePath() })
|
|
||||||
.waitFor();
|
|
||||||
}
|
|
||||||
catch (Throwable e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
return loadNativeLibrary(targetFolder, extractedLibFileName);
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
System.err.println(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static synchronized boolean loadNativeLibrary(String path, String name) {
|
|
||||||
File libPath = new File(path, name);
|
|
||||||
if (libPath.exists()) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
System.load(new File(path, name).getAbsolutePath());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (UnsatisfiedLinkError e) {
|
|
||||||
System.err.println(e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void loadSQLiteNativeLibrary() {
|
|
||||||
if (extracted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
boolean runInPureJavaMode = getPureJavaFlag();
|
|
||||||
if (runInPureJavaMode) {
|
|
||||||
extracted = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try loading library from org.sqlite.lib.path library path */
|
|
||||||
String sqliteNativeLibraryPath = System.getProperty("org.sqlite.lib.path");
|
|
||||||
String sqliteNativeLibraryName = System.getProperty("org.sqlite.lib.name");
|
|
||||||
if (sqliteNativeLibraryName == null)
|
|
||||||
sqliteNativeLibraryName = System.mapLibraryName("sqlitejdbc");
|
|
||||||
|
|
||||||
if (sqliteNativeLibraryPath != null) {
|
|
||||||
if (loadNativeLibrary(sqliteNativeLibraryPath, sqliteNativeLibraryName)) {
|
|
||||||
extracted = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the os-dependent library from a jar file
|
|
||||||
sqliteNativeLibraryPath = "/native/" + OSInfo.getNativeLibFolderPathForCurrentOS();
|
|
||||||
|
|
||||||
if (SQLiteJDBCLoader.class.getResource(sqliteNativeLibraryPath + "/" + sqliteNativeLibraryName) == null) {
|
|
||||||
// use nested VM version
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// temporary library folder
|
|
||||||
String tempFolder = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath();
|
|
||||||
// Try extracting the library from jar
|
|
||||||
if (extractAndLoadLibraryFile(sqliteNativeLibraryPath, sqliteNativeLibraryName, tempFolder)) {
|
|
||||||
extracted = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
extracted = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void getNativeLibraryFolderForTheCurrentOS() {
|
|
||||||
String osName = OSInfo.getOSName();
|
|
||||||
String archName = OSInfo.getArchName();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getMajorVersion() {
|
|
||||||
String[] c = getVersion().split("\\.");
|
|
||||||
return (c.length > 0) ? Integer.parseInt(c[0]) : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getMinorVersion() {
|
|
||||||
String[] c = getVersion().split("\\.");
|
|
||||||
return (c.length > 1) ? Integer.parseInt(c[1]) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getVersion() {
|
|
||||||
|
|
||||||
URL versionFile = SQLiteJDBCLoader.class.getResource("/META-INF/maven/org.xerial/sqlite-jdbc/pom.properties");
|
|
||||||
if (versionFile == null)
|
|
||||||
versionFile = SQLiteJDBCLoader.class.getResource("/META-INF/maven/org.xerial/sqlite-jdbc/VERSION");
|
|
||||||
|
|
||||||
String version = "unknown";
|
|
||||||
try {
|
|
||||||
if (versionFile != null) {
|
|
||||||
Properties versionData = new Properties();
|
|
||||||
versionData.load(versionFile.openStream());
|
|
||||||
version = versionData.getProperty("version", version);
|
|
||||||
version = version.trim().replaceAll("[^0-9\\.]", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
System.err.println(e);
|
|
||||||
}
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
/*--------------------------------------------------------------------------
|
|
||||||
* Copyright 2009 Taro L. Saito
|
|
||||||
*
|
|
||||||
* Licensed 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.
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
//--------------------------------------
|
|
||||||
// sqlite-jdbc Project
|
|
||||||
//
|
|
||||||
// SQLiteOpenMode.java
|
|
||||||
// Since: Dec 8, 2009
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Author$
|
|
||||||
//--------------------------------------
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Database file open modes of SQLite.
|
|
||||||
*
|
|
||||||
* See also http://sqlite.org/c3ref/open.html
|
|
||||||
*
|
|
||||||
* @author leo
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public enum SQLiteOpenMode {
|
|
||||||
READONLY(0x00000001), /* Ok for int SQLITE3_open_v2() */
|
|
||||||
READWRITE(0x00000002), /* Ok for int SQLITE3_open_v2() */
|
|
||||||
CREATE(0x00000004), /* Ok for int SQLITE3_open_v2() */
|
|
||||||
DELETEONCLOSE(0x00000008), /* VFS only */
|
|
||||||
EXCLUSIVE(0x00000010), /* VFS only */
|
|
||||||
MAIN_DB(0x00000100), /* VFS only */
|
|
||||||
TEMP_DB(0x00000200), /* VFS only */
|
|
||||||
TRANSIENT_DB(0x00000400), /* VFS only */
|
|
||||||
MAIN_JOURNAL(0x00000800), /* VFS only */
|
|
||||||
TEMP_JOURNAL(0x00001000), /* VFS only */
|
|
||||||
SUBJOURNAL(0x00002000), /* VFS only */
|
|
||||||
MASTER_JOURNAL(0x00004000), /* VFS only */
|
|
||||||
NOMUTEX(0x00008000), /* Ok for int SQLITE3_open_v2() */
|
|
||||||
FULLMUTEX(0x00010000), /* Ok for int SQLITE3_open_v2() */
|
|
||||||
SHAREDCACHE(0x00020000), /* Ok for int SQLITE3_open_v2() */
|
|
||||||
PRIVATECACHE(0x00040000) /* Ok for sqlite3_open_v2() */
|
|
||||||
;
|
|
||||||
|
|
||||||
public final int flag;
|
|
||||||
|
|
||||||
private SQLiteOpenMode(int flag) {
|
|
||||||
this.flag = flag;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,337 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.sql.BatchUpdateException;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.SQLWarning;
|
|
||||||
import java.sql.Statement;
|
|
||||||
|
|
||||||
import org.sqlite.DB.ProgressObserver;
|
|
||||||
import org.sqlite.ExtendedCommand.SQLExtension;
|
|
||||||
|
|
||||||
class Stmt extends Unused implements Statement, Codes
|
|
||||||
{
|
|
||||||
final Conn conn;
|
|
||||||
final DB db;
|
|
||||||
final RS rs;
|
|
||||||
|
|
||||||
long pointer;
|
|
||||||
String sql = null;
|
|
||||||
|
|
||||||
int batchPos;
|
|
||||||
Object[] batch = null;
|
|
||||||
boolean resultsWaiting = false;
|
|
||||||
|
|
||||||
Stmt(Conn c) {
|
|
||||||
conn = c;
|
|
||||||
db = conn.db();
|
|
||||||
rs = new RS(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final void checkOpen() throws SQLException {
|
|
||||||
if (pointer == 0)
|
|
||||||
throw new SQLException("statement is not executing");
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isOpen() throws SQLException {
|
|
||||||
return (pointer != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Calls sqlite3_step() and sets up results. Expects a clean stmt. */
|
|
||||||
protected boolean exec() throws SQLException {
|
|
||||||
if (sql == null)
|
|
||||||
throw new SQLException("SQLiteJDBC internal error: sql==null");
|
|
||||||
if (rs.isOpen())
|
|
||||||
throw new SQLException("SQLite JDBC internal error: rs.isOpen() on exec.");
|
|
||||||
|
|
||||||
boolean rc = false;
|
|
||||||
try {
|
|
||||||
rc = db.execute(this, null);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
resultsWaiting = rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return db.column_count(pointer) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean exec(String sql) throws SQLException {
|
|
||||||
if (sql == null)
|
|
||||||
throw new SQLException("SQLiteJDBC internal error: sql==null");
|
|
||||||
if (rs.isOpen())
|
|
||||||
throw new SQLException("SQLite JDBC internal error: rs.isOpen() on exec.");
|
|
||||||
|
|
||||||
boolean rc = false;
|
|
||||||
try {
|
|
||||||
rc = db.execute(sql);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
resultsWaiting = rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return db.column_count(pointer) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PUBLIC INTERFACE /////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void close() throws SQLException {
|
|
||||||
if (pointer == 0)
|
|
||||||
return;
|
|
||||||
rs.close();
|
|
||||||
batch = null;
|
|
||||||
batchPos = 0;
|
|
||||||
int resp = db.finalize(this);
|
|
||||||
if (resp != SQLITE_OK && resp != SQLITE_MISUSE)
|
|
||||||
db.throwex();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void finalize() throws SQLException {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean execute(String sql) throws SQLException {
|
|
||||||
close();
|
|
||||||
this.sql = sql;
|
|
||||||
|
|
||||||
db.prepare(this);
|
|
||||||
return exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResultSet executeQuery(String sql) throws SQLException {
|
|
||||||
close();
|
|
||||||
this.sql = sql;
|
|
||||||
|
|
||||||
db.prepare(this);
|
|
||||||
if (!exec()) {
|
|
||||||
close();
|
|
||||||
throw new SQLException("query does not return ResultSet");
|
|
||||||
}
|
|
||||||
return getResultSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
static class BackupObserver implements ProgressObserver
|
|
||||||
{
|
|
||||||
public void progress(int remaining, int pageCount) {
|
|
||||||
System.out.println(String.format("remaining:%d, page count:%d", remaining, pageCount));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int executeUpdate(String sql) throws SQLException {
|
|
||||||
close();
|
|
||||||
this.sql = sql;
|
|
||||||
|
|
||||||
int changes = 0;
|
|
||||||
SQLExtension ext = ExtendedCommand.parse(sql);
|
|
||||||
if (ext != null) {
|
|
||||||
// execute extended command
|
|
||||||
ext.execute(db);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
//db.prepare(this);
|
|
||||||
//changes = db.executeUpdate(this, null);
|
|
||||||
|
|
||||||
// directly invokes the exec API to support multiple SQL statements
|
|
||||||
int statusCode = db._exec(sql);
|
|
||||||
if (statusCode != SQLITE_OK)
|
|
||||||
throw DB.newSQLException(statusCode, "");
|
|
||||||
|
|
||||||
changes = db.changes();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResultSet getResultSet() throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
if (rs.isOpen())
|
|
||||||
throw new SQLException("ResultSet already requested");
|
|
||||||
if (db.column_count(pointer) == 0)
|
|
||||||
throw new SQLException("no ResultSet available");
|
|
||||||
if (rs.colsMeta == null)
|
|
||||||
rs.colsMeta = db.column_names(pointer);
|
|
||||||
rs.cols = rs.colsMeta;
|
|
||||||
|
|
||||||
rs.open = resultsWaiting;
|
|
||||||
resultsWaiting = false;
|
|
||||||
return rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function has a complex behaviour best understood by carefully
|
|
||||||
* reading the JavaDoc for getMoreResults() and considering the test
|
|
||||||
* StatementTest.execute().
|
|
||||||
*/
|
|
||||||
public int getUpdateCount() throws SQLException {
|
|
||||||
if (pointer != 0 && !rs.isOpen() && !resultsWaiting && db.column_count(pointer) == 0)
|
|
||||||
return db.changes();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addBatch(String sql) throws SQLException {
|
|
||||||
close();
|
|
||||||
if (batch == null || batchPos + 1 >= batch.length) {
|
|
||||||
Object[] nb = new Object[Math.max(10, batchPos * 2)];
|
|
||||||
if (batch != null)
|
|
||||||
System.arraycopy(batch, 0, nb, 0, batch.length);
|
|
||||||
batch = nb;
|
|
||||||
}
|
|
||||||
batch[batchPos++] = sql;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearBatch() throws SQLException {
|
|
||||||
batchPos = 0;
|
|
||||||
if (batch != null)
|
|
||||||
for (int i = 0; i < batch.length; i++)
|
|
||||||
batch[i] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] executeBatch() throws SQLException {
|
|
||||||
// TODO: optimize
|
|
||||||
close();
|
|
||||||
if (batch == null || batchPos == 0)
|
|
||||||
return new int[] {};
|
|
||||||
|
|
||||||
int[] changes = new int[batchPos];
|
|
||||||
|
|
||||||
synchronized (db) {
|
|
||||||
try {
|
|
||||||
for (int i = 0; i < changes.length; i++) {
|
|
||||||
try {
|
|
||||||
this.sql = (String) batch[i];
|
|
||||||
db.prepare(this);
|
|
||||||
changes[i] = db.executeUpdate(this, null);
|
|
||||||
}
|
|
||||||
catch (SQLException e) {
|
|
||||||
throw new BatchUpdateException("batch entry " + i + ": " + e.getMessage(), changes);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
db.finalize(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
clearBatch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCursorName(String name) {}
|
|
||||||
|
|
||||||
public SQLWarning getWarnings() throws SQLException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearWarnings() throws SQLException {}
|
|
||||||
|
|
||||||
public Connection getConnection() throws SQLException {
|
|
||||||
return conn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancel() throws SQLException {
|
|
||||||
rs.checkOpen();
|
|
||||||
db.interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getQueryTimeout() throws SQLException {
|
|
||||||
return conn.getTimeout();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setQueryTimeout(int seconds) throws SQLException {
|
|
||||||
if (seconds < 0)
|
|
||||||
throw new SQLException("query timeout must be >= 0");
|
|
||||||
conn.setTimeout(1000 * seconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: write test
|
|
||||||
public int getMaxRows() throws SQLException {
|
|
||||||
//checkOpen();
|
|
||||||
return rs.maxRows;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxRows(int max) throws SQLException {
|
|
||||||
//checkOpen();
|
|
||||||
if (max < 0)
|
|
||||||
throw new SQLException("max row count must be >= 0");
|
|
||||||
rs.maxRows = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxFieldSize() throws SQLException {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxFieldSize(int max) throws SQLException {
|
|
||||||
if (max < 0)
|
|
||||||
throw new SQLException("max field size " + max + " cannot be negative");
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFetchSize() throws SQLException {
|
|
||||||
return rs.getFetchSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFetchSize(int r) throws SQLException {
|
|
||||||
rs.setFetchSize(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFetchDirection() throws SQLException {
|
|
||||||
return rs.getFetchDirection();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFetchDirection(int d) throws SQLException {
|
|
||||||
rs.setFetchDirection(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* As SQLite's last_insert_rowid() function is DB-specific not statement
|
|
||||||
* specific, this function introduces a race condition if the same
|
|
||||||
* connection is used by two threads and both insert.
|
|
||||||
*/
|
|
||||||
public ResultSet getGeneratedKeys() throws SQLException {
|
|
||||||
return ((MetaData) conn.getMetaData()).getGeneratedKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** SQLite does not support multiple results from execute(). */
|
|
||||||
public boolean getMoreResults() throws SQLException {
|
|
||||||
return getMoreResults(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getMoreResults(int c) throws SQLException {
|
|
||||||
checkOpen();
|
|
||||||
close(); // as we never have another result, clean up pointer
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getResultSetConcurrency() throws SQLException {
|
|
||||||
return ResultSet.CONCUR_READ_ONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getResultSetHoldability() throws SQLException {
|
|
||||||
return ResultSet.CLOSE_CURSORS_AT_COMMIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getResultSetType() throws SQLException {
|
|
||||||
return ResultSet.TYPE_FORWARD_ONLY;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,244 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sqlite;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.math.*;
|
|
||||||
import java.net.*;
|
|
||||||
import java.sql.*;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/** Unused JDBC functions from Statement, PreparedStatement and ResultSet. */
|
|
||||||
abstract class Unused
|
|
||||||
{
|
|
||||||
private SQLException unused() {
|
|
||||||
return new SQLException("not implemented by SQLite JDBC driver");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Statement ////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void setEscapeProcessing(boolean enable)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public boolean execute(String sql, int[] colinds)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public boolean execute(String sql, String[] colnames)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public int executeUpdate(String sql, int autoKeys)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public int executeUpdate(String sql, int[] colinds)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public int executeUpdate(String sql, String[] cols)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public boolean execute(String sql, int autokeys)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
|
|
||||||
|
|
||||||
// PreparedStatement ////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void setArray(int i, Array x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void setAsciiStream(int parameterIndex, InputStream x, int length)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void setBigDecimal(int parameterIndex, BigDecimal x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void setBinaryStream(int parameterIndex, InputStream x, int length)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void setBlob(int i, Blob x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void setClob(int i, Clob x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void setRef(int i, Ref x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void setUnicodeStream(int pos, InputStream x, int length)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void setURL(int pos, URL x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
|
|
||||||
|
|
||||||
// ResultSet ////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public Array getArray(int i)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public Array getArray(String col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public InputStream getAsciiStream(int col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public InputStream getAsciiStream(String col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public BigDecimal getBigDecimal(int col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public BigDecimal getBigDecimal(int col, int s)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public BigDecimal getBigDecimal(String col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public BigDecimal getBigDecimal(String col, int s)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public InputStream getBinaryStream(int col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public InputStream getBinaryStream(String col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public Blob getBlob(int col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public Blob getBlob(String col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public Clob getClob(int col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public Clob getClob(String col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public Object getObject(int col, Map map)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public Object getObject(String col, Map map)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public Ref getRef(int i)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public Ref getRef(String col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
|
|
||||||
public InputStream getUnicodeStream(int col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public InputStream getUnicodeStream(String col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public URL getURL(int col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public URL getURL(String col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
|
|
||||||
public void insertRow() throws SQLException {
|
|
||||||
throw new SQLException("ResultSet is TYPE_FORWARD_ONLY"); }
|
|
||||||
public void moveToCurrentRow() throws SQLException {
|
|
||||||
throw new SQLException("ResultSet is TYPE_FORWARD_ONLY"); }
|
|
||||||
public void moveToInsertRow() throws SQLException {
|
|
||||||
throw new SQLException("ResultSet is TYPE_FORWARD_ONLY"); }
|
|
||||||
public boolean last() throws SQLException {
|
|
||||||
throw new SQLException("ResultSet is TYPE_FORWARD_ONLY"); }
|
|
||||||
public boolean previous() throws SQLException {
|
|
||||||
throw new SQLException("ResultSet is TYPE_FORWARD_ONLY"); }
|
|
||||||
public boolean relative(int rows) throws SQLException {
|
|
||||||
throw new SQLException("ResultSet is TYPE_FORWARD_ONLY"); }
|
|
||||||
public boolean absolute(int row) throws SQLException {
|
|
||||||
throw new SQLException("ResultSet is TYPE_FORWARD_ONLY"); }
|
|
||||||
public void afterLast() throws SQLException {
|
|
||||||
throw new SQLException("ResultSet is TYPE_FORWARD_ONLY"); }
|
|
||||||
public void beforeFirst() throws SQLException {
|
|
||||||
throw new SQLException("ResultSet is TYPE_FORWARD_ONLY"); }
|
|
||||||
public boolean first() throws SQLException {
|
|
||||||
throw new SQLException("ResultSet is TYPE_FORWARD_ONLY"); }
|
|
||||||
|
|
||||||
public void cancelRowUpdates()
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void deleteRow()
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
|
|
||||||
public void updateArray(int col, Array x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateArray(String col, Array x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateAsciiStream(int col, InputStream x, int l)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateAsciiStream(String col, InputStream x, int l)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateBigDecimal(int col, BigDecimal x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateBigDecimal(String col, BigDecimal x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateBinaryStream(int c, InputStream x, int l)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateBinaryStream(String c, InputStream x, int l)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateBlob(int col, Blob x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateBlob(String col, Blob x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateBoolean(int col, boolean x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateBoolean(String col, boolean x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateByte(int col, byte x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateByte(String col, byte x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateBytes(int col, byte[] x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateBytes(String col, byte[] x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateCharacterStream(int c, Reader x, int l)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateCharacterStream(String c, Reader r, int l)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateClob(int col, Clob x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateClob(String col, Clob x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateDate(int col, Date x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateDate(String col, Date x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateDouble(int col, double x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateDouble(String col, double x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateFloat(int col, float x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateFloat(String col, float x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateInt(int col, int x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateInt(String col, int x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateLong(int col, long x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateLong(String col, long x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateNull(int col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateNull(String col)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateObject(int c, Object x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateObject(int c, Object x, int s)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateObject(String col, Object x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateObject(String c, Object x, int s)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateRef(int col, Ref x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateRef(String c, Ref x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateRow()
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateShort(int c, short x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateShort(String c, short x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateString(int c, String x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateString(String c, String x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateTime(int c, Time x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateTime(String c, Time x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateTimestamp(int c, Timestamp x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
public void updateTimestamp(String c, Timestamp x)
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
|
|
||||||
public void refreshRow()
|
|
||||||
throws SQLException { throw unused(); }
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user