mirror of
https://github.com/amalthea-mc/ShopChest.git
synced 2024-11-22 10:22:29 +00:00
Now saves shops to a SQLite Database
This commit is contained in:
parent
477b6a4701
commit
ae756f43e7
106
libs/org/sqlite/Codes.java
Normal file
106
libs/org/sqlite/Codes.java
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
440
libs/org/sqlite/Conn.java
Normal file
440
libs/org/sqlite/Conn.java
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
/*
|
||||||
|
* 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");
|
||||||
|
}
|
||||||
|
}
|
444
libs/org/sqlite/DB.java
Normal file
444
libs/org/sqlite/DB.java
Normal file
@ -0,0 +1,444 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
116
libs/org/sqlite/ExtendedCommand.java
Normal file
116
libs/org/sqlite/ExtendedCommand.java
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
//--------------------------------------
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
182
libs/org/sqlite/Function.java
Normal file
182
libs/org/sqlite/Function.java
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
79
libs/org/sqlite/JDBC.java
Normal file
79
libs/org/sqlite/JDBC.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
1214
libs/org/sqlite/MetaData.java
Normal file
1214
libs/org/sqlite/MetaData.java
Normal file
File diff suppressed because it is too large
Load Diff
212
libs/org/sqlite/NativeDB.java
Normal file
212
libs/org/sqlite/NativeDB.java
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
662
libs/org/sqlite/NestedDB.java
Normal file
662
libs/org/sqlite/NestedDB.java
Normal file
@ -0,0 +1,662 @@
|
|||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
80
libs/org/sqlite/OSInfo.java
Normal file
80
libs/org/sqlite/OSInfo.java
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
* 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", "");
|
||||||
|
}
|
||||||
|
}
|
330
libs/org/sqlite/PrepStmt.java
Normal file
330
libs/org/sqlite/PrepStmt.java
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
/*
|
||||||
|
* 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");
|
||||||
|
}
|
||||||
|
}
|
540
libs/org/sqlite/RS.java
Normal file
540
libs/org/sqlite/RS.java
Normal file
@ -0,0 +1,540 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
102
libs/org/sqlite/ResourceFinder.java
Normal file
102
libs/org/sqlite/ResourceFinder.java
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
* 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 + "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
449
libs/org/sqlite/SQLiteConfig.java
Normal file
449
libs/org/sqlite/SQLiteConfig.java
Normal file
@ -0,0 +1,449 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
228
libs/org/sqlite/SQLiteDataSource.java
Normal file
228
libs/org/sqlite/SQLiteDataSource.java
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
92
libs/org/sqlite/SQLiteErrorCode.java
Normal file
92
libs/org/sqlite/SQLiteErrorCode.java
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
271
libs/org/sqlite/SQLiteJDBCLoader.java
Normal file
271
libs/org/sqlite/SQLiteJDBCLoader.java
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
59
libs/org/sqlite/SQLiteOpenMode.java
Normal file
59
libs/org/sqlite/SQLiteOpenMode.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
337
libs/org/sqlite/Stmt.java
Normal file
337
libs/org/sqlite/Stmt.java
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
244
libs/org/sqlite/Unused.java
Normal file
244
libs/org/sqlite/Unused.java
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/*
|
||||||
|
* 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(); }
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
name: ShopChest
|
name: ShopChest
|
||||||
main: de.epiceric.shopchest.ShopChest
|
main: de.epiceric.shopchest.ShopChest
|
||||||
version: 1.5.0
|
version: 1.5.1
|
||||||
author: EpicEric
|
author: EpicEric
|
||||||
website: https://www.spigotmc.org/resources/shopchest.11431/
|
website: https://www.spigotmc.org/resources/shopchest.11431/
|
||||||
depend: [Vault]
|
depend: [Vault]
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
package de.epiceric.shopchest;
|
package de.epiceric.shopchest;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.nio.file.Files;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.defaults.BukkitCommand;
|
import org.bukkit.command.defaults.BukkitCommand;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@ -28,7 +34,6 @@ import de.epiceric.shopchest.utils.ClickType;
|
|||||||
import de.epiceric.shopchest.utils.ClickType.EnumClickType;
|
import de.epiceric.shopchest.utils.ClickType.EnumClickType;
|
||||||
import de.epiceric.shopchest.utils.ShopUtils;
|
import de.epiceric.shopchest.utils.ShopUtils;
|
||||||
import de.epiceric.shopchest.utils.UpdateChecker;
|
import de.epiceric.shopchest.utils.UpdateChecker;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import net.milkbowl.vault.permission.Permission;
|
import net.milkbowl.vault.permission.Permission;
|
||||||
|
|
||||||
public class Commands extends BukkitCommand {
|
public class Commands extends BukkitCommand {
|
||||||
@ -156,6 +161,12 @@ public class Commands extends BukkitCommand {
|
|||||||
p.sendMessage(Config.noPermission_limits());
|
p.sendMessage(Config.noPermission_limits());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (args[0].equalsIgnoreCase("compile")){
|
||||||
|
|
||||||
|
if (perm.has(p, "shopchest.compile")) {
|
||||||
|
compile(p);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
sendBasicHelpMessage(p);
|
sendBasicHelpMessage(p);
|
||||||
return true;
|
return true;
|
||||||
@ -175,6 +186,65 @@ public class Commands extends BukkitCommand {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void compile(Player player) {
|
||||||
|
|
||||||
|
player.sendMessage(" ");
|
||||||
|
player.sendMessage(ChatColor.RED + "" + ChatColor.BOLD + "Starting Compilation...");
|
||||||
|
player.sendMessage(ChatColor.GOLD + "This command will be removed in the next update. Be sure to compile the shops in this version!");
|
||||||
|
player.sendMessage(ChatColor.GOLD + "Please execute this command only once or the whole plugin will get messed up and all shops must be deleted!");
|
||||||
|
|
||||||
|
File shopChestDataFolder = new File(plugin.getDataFolder(), "data");
|
||||||
|
if (!shopChestDataFolder.exists()) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Cannot find shops.yml file.");
|
||||||
|
player.sendMessage(ChatColor.RED + "Be sure it's located in \"/plugins/ShopChest/data/shops.yml\"");
|
||||||
|
player.sendMessage(" ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File shopChestsFile = new File(shopChestDataFolder, "shops.yml");
|
||||||
|
if (!shopChestsFile.exists()) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Cannot find shops.yml file.");
|
||||||
|
player.sendMessage(ChatColor.RED + "Be sure it's located in \"/plugins/ShopChest/data/shops.yml\"");
|
||||||
|
player.sendMessage(" ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
YamlConfiguration shopChests = YamlConfiguration.loadConfiguration(shopChestsFile);
|
||||||
|
|
||||||
|
Set<String> keys = shopChests.getKeys(false);
|
||||||
|
|
||||||
|
for (String key : keys) {
|
||||||
|
|
||||||
|
OfflinePlayer vendor = shopChests.getOfflinePlayer(key + ".vendor");
|
||||||
|
int locationX = shopChests.getInt(key + ".location.x");
|
||||||
|
int locationY = shopChests.getInt(key + ".location.y");
|
||||||
|
int locationZ = shopChests.getInt(key + ".location.z");
|
||||||
|
World locationWorld = plugin.getServer().getWorld(shopChests.getString(key + ".location.world"));
|
||||||
|
Location location = new Location(locationWorld, locationX, locationY, locationZ);
|
||||||
|
ItemStack product = shopChests.getItemStack(key + ".product");
|
||||||
|
double buyPrice = shopChests.getDouble(key + ".price.buy");
|
||||||
|
double sellPrice = shopChests.getDouble(key + ".price.sell");
|
||||||
|
boolean infinite = shopChests.getBoolean(key + ".infinite");
|
||||||
|
|
||||||
|
ShopChest.sqlite.addShop(new Shop(plugin, vendor, product, location, buyPrice, sellPrice, infinite));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Successfully compiled " + String.valueOf(keys.size()) + " Shops.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
Files.delete(shopChestsFile.toPath());
|
||||||
|
Files.delete(shopChestDataFolder.toPath());
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Successfully deleted data folder.");
|
||||||
|
} catch (IOException e) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Could not delete data folder. You may delete it yourself.");
|
||||||
|
}
|
||||||
|
|
||||||
|
player.sendMessage(" ");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void checkUpdates(Player player) {
|
private void checkUpdates(Player player) {
|
||||||
|
|
||||||
player.sendMessage(Config.checking_update());
|
player.sendMessage(Config.checking_update());
|
||||||
@ -205,8 +275,7 @@ public class Commands extends BukkitCommand {
|
|||||||
|
|
||||||
private void reload(Player player) {
|
private void reload(Player player) {
|
||||||
|
|
||||||
ShopChest.utils.reload();
|
ShopChest.utils.reload(player);
|
||||||
player.sendMessage(Config.reloaded_shops(ShopChest.getInstance().shopChests.getKeys(false).size()));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,22 +5,16 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.sql.Statement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.yi.acru.bukkit.Lockette.Lockette;
|
|
||||||
|
|
||||||
import com.griefcraft.lwc.LWC;
|
import com.griefcraft.lwc.LWC;
|
||||||
import com.griefcraft.lwc.LWCPlugin;
|
import com.griefcraft.lwc.LWCPlugin;
|
||||||
|
|
||||||
@ -36,6 +30,7 @@ import de.epiceric.shopchest.interfaces.utils.Utils_R1;
|
|||||||
import de.epiceric.shopchest.interfaces.utils.Utils_R2;
|
import de.epiceric.shopchest.interfaces.utils.Utils_R2;
|
||||||
import de.epiceric.shopchest.interfaces.utils.Utils_R3;
|
import de.epiceric.shopchest.interfaces.utils.Utils_R3;
|
||||||
import de.epiceric.shopchest.shop.Shop;
|
import de.epiceric.shopchest.shop.Shop;
|
||||||
|
import de.epiceric.shopchest.sql.SQLite;
|
||||||
import de.epiceric.shopchest.interfaces.JsonBuilder;
|
import de.epiceric.shopchest.interfaces.JsonBuilder;
|
||||||
import de.epiceric.shopchest.interfaces.JsonBuilder.ClickAction;
|
import de.epiceric.shopchest.interfaces.JsonBuilder.ClickAction;
|
||||||
import de.epiceric.shopchest.interfaces.JsonBuilder.HoverAction;
|
import de.epiceric.shopchest.interfaces.JsonBuilder.HoverAction;
|
||||||
@ -52,14 +47,13 @@ public class ShopChest extends JavaPlugin{
|
|||||||
|
|
||||||
private static ShopChest instance;
|
private static ShopChest instance;
|
||||||
|
|
||||||
public File shopChestsFile;
|
public static Statement statement;
|
||||||
public YamlConfiguration shopChests;
|
public static Logger logger;
|
||||||
|
|
||||||
public static Logger logger = Logger.getLogger("Minecraft");
|
|
||||||
public static Economy econ = null;
|
public static Economy econ = null;
|
||||||
public static Permission perm = null;
|
public static Permission perm = null;
|
||||||
public static LWC lwc = null;
|
public static LWC lwc = null;
|
||||||
public static boolean lockette = false;
|
public static boolean lockette = false;
|
||||||
|
public static SQLite sqlite;
|
||||||
|
|
||||||
public static boolean isUpdateNeeded = false;
|
public static boolean isUpdateNeeded = false;
|
||||||
public static String latestVersion = "";
|
public static String latestVersion = "";
|
||||||
@ -92,14 +86,16 @@ public class ShopChest extends JavaPlugin{
|
|||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
|
||||||
|
logger = getLogger();
|
||||||
|
|
||||||
if (getServer().getPluginManager().getPlugin("Vault") == null) {
|
if (getServer().getPluginManager().getPlugin("Vault") == null) {
|
||||||
logger.severe("[ShopChest] Could not find plugin 'Vault'!");
|
logger.severe("Could not find plugin 'Vault'!");
|
||||||
getServer().getPluginManager().disablePlugin(this);
|
getServer().getPluginManager().disablePlugin(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!setupEconomy() ) {
|
if (!setupEconomy() ) {
|
||||||
logger.severe("[ShopChest] Could not find any Vault dependency!");
|
logger.severe("Could not find any Vault dependency!");
|
||||||
getServer().getPluginManager().disablePlugin(this);
|
getServer().getPluginManager().disablePlugin(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -108,16 +104,19 @@ public class ShopChest extends JavaPlugin{
|
|||||||
Metrics metrics = new Metrics(this);
|
Metrics metrics = new Metrics(this);
|
||||||
metrics.start();
|
metrics.start();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.severe("[ShopChest] [PluginMetrics] Could not submit stats.");
|
logger.severe("Could not submit stats.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sqlite = new SQLite(this);
|
||||||
|
sqlite.load();
|
||||||
|
|
||||||
switch (Utils.getVersion(getServer())) {
|
switch (Utils.getVersion(getServer())) {
|
||||||
|
|
||||||
case "v1_8_R1": utils = new Utils_R1(); break;
|
case "v1_8_R1": utils = new Utils_R1(); break;
|
||||||
case "v1_8_R2": utils = new Utils_R2(); break;
|
case "v1_8_R2": utils = new Utils_R2(); break;
|
||||||
case "v1_8_R3": utils = new Utils_R3(); break;
|
case "v1_8_R3": utils = new Utils_R3(); break;
|
||||||
default:
|
default:
|
||||||
logger.severe("[ShopChest] Incompatible Server Version!");
|
logger.severe("Incompatible Server Version!");
|
||||||
getServer().getPluginManager().disablePlugin(this);
|
getServer().getPluginManager().disablePlugin(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -142,14 +141,14 @@ public class ShopChest extends JavaPlugin{
|
|||||||
saveDefaultConfig();
|
saveDefaultConfig();
|
||||||
|
|
||||||
UpdateChecker uc = new UpdateChecker(this, getDescription().getWebsite());
|
UpdateChecker uc = new UpdateChecker(this, getDescription().getWebsite());
|
||||||
logger.info("[ShopChest] Checking for Updates");
|
logger.info("Checking for Updates");
|
||||||
if(uc.updateNeeded()) {
|
if(uc.updateNeeded()) {
|
||||||
latestVersion = uc.getVersion();
|
latestVersion = uc.getVersion();
|
||||||
downloadLink = uc.getLink();
|
downloadLink = uc.getLink();
|
||||||
isUpdateNeeded = true;
|
isUpdateNeeded = true;
|
||||||
Bukkit.getConsoleSender().sendMessage("[ShopChest] " + ChatColor.GOLD + "New version available: " + ChatColor.RED + latestVersion);
|
Bukkit.getConsoleSender().sendMessage("[ShopChest] " + ChatColor.GOLD + "New version available: " + ChatColor.RED + latestVersion);
|
||||||
} else {
|
} else {
|
||||||
logger.info("[ShopChest] No new version available");
|
logger.info("No new version available");
|
||||||
isUpdateNeeded = false;
|
isUpdateNeeded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,14 +168,6 @@ public class ShopChest extends JavaPlugin{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
File shopChestDataFolder = new File(getDataFolder(), "data");
|
|
||||||
shopChestDataFolder.mkdirs();
|
|
||||||
|
|
||||||
shopChestsFile = new File(getDataFolder(), "/data/shops.yml");
|
|
||||||
if (!shopChestsFile.exists())
|
|
||||||
try {shopChestsFile.createNewFile();} catch (IOException e) {e.printStackTrace();}
|
|
||||||
|
|
||||||
File itemNamesFile = new File(getDataFolder(), "item_names.txt");
|
File itemNamesFile = new File(getDataFolder(), "item_names.txt");
|
||||||
|
|
||||||
if (!itemNamesFile.exists())
|
if (!itemNamesFile.exists())
|
||||||
@ -184,8 +175,6 @@ public class ShopChest extends JavaPlugin{
|
|||||||
|
|
||||||
copy(getResource("item_names.txt"), itemNamesFile);
|
copy(getResource("item_names.txt"), itemNamesFile);
|
||||||
|
|
||||||
shopChests = YamlConfiguration.loadConfiguration(shopChestsFile);
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Commands.registerCommand(new Commands(this, Config.main_command_name(), "Manage Shops.", "", new ArrayList<String>()), this);
|
Commands.registerCommand(new Commands(this, Config.main_command_name(), "Manage Shops.", "", new ArrayList<String>()), this);
|
||||||
@ -215,25 +204,25 @@ public class ShopChest extends JavaPlugin{
|
|||||||
|
|
||||||
private void initializeShops() {
|
private void initializeShops() {
|
||||||
|
|
||||||
Bukkit.getConsoleSender().sendMessage("[ShopChest] Found " + String.valueOf(shopChests.getKeys(false).size()) + " Shops");
|
int count = 0;
|
||||||
|
|
||||||
for (String key : shopChests.getKeys(false)) {
|
for (int id = 1; id < sqlite.getCount() + 1; id++) {
|
||||||
|
|
||||||
OfflinePlayer vendor = shopChests.getOfflinePlayer(key + ".vendor");
|
try {
|
||||||
int locationX = shopChests.getInt(key + ".location.x");
|
Shop shop = sqlite.getShop(id);
|
||||||
int locationY = shopChests.getInt(key + ".location.y");
|
shop.createHologram();
|
||||||
int locationZ = shopChests.getInt(key + ".location.z");
|
shop.createItem();
|
||||||
World locationWorld = getServer().getWorld(shopChests.getString(key + ".location.world"));
|
ShopUtils.addShop(shop);
|
||||||
Location location = new Location(locationWorld, locationX, locationY, locationZ);
|
} catch (NullPointerException e) {
|
||||||
ItemStack product = shopChests.getItemStack(key + ".product");
|
continue;
|
||||||
double buyPrice = shopChests.getDouble(key + ".price.buy");
|
}
|
||||||
double sellPrice = shopChests.getDouble(key + ".price.sell");
|
|
||||||
boolean infinite = shopChests.getBoolean(key + ".infinite");
|
|
||||||
|
|
||||||
ShopUtils.addShop(new Shop(this, vendor, product, location, buyPrice, sellPrice, infinite));
|
count++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.info("Initialized " + String.valueOf(count) + " Shops");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void copy(InputStream in, File file) {
|
public static void copy(InputStream in, File file) {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package de.epiceric.shopchest.event;
|
package de.epiceric.shopchest.event;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -9,11 +8,9 @@ import org.bukkit.Location;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.Chest;
|
import org.bukkit.block.Chest;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.Action;
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
@ -22,18 +19,17 @@ import org.bukkit.inventory.Inventory;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.yi.acru.bukkit.Lockette.Lockette;
|
import org.yi.acru.bukkit.Lockette.Lockette;
|
||||||
|
|
||||||
import com.griefcraft.lwc.LWC;
|
|
||||||
import com.griefcraft.model.Protection;
|
import com.griefcraft.model.Protection;
|
||||||
|
|
||||||
import de.epiceric.shopchest.ShopChest;
|
import de.epiceric.shopchest.ShopChest;
|
||||||
import de.epiceric.shopchest.config.Config;
|
import de.epiceric.shopchest.config.Config;
|
||||||
import de.epiceric.shopchest.shop.Shop;
|
import de.epiceric.shopchest.shop.Shop;
|
||||||
|
import de.epiceric.shopchest.sql.SQLite;
|
||||||
import de.epiceric.shopchest.utils.ClickType;
|
import de.epiceric.shopchest.utils.ClickType;
|
||||||
import de.epiceric.shopchest.utils.EnchantmentNames;
|
import de.epiceric.shopchest.utils.EnchantmentNames;
|
||||||
import de.epiceric.shopchest.utils.ItemNames;
|
import de.epiceric.shopchest.utils.ItemNames;
|
||||||
import de.epiceric.shopchest.utils.ShopUtils;
|
import de.epiceric.shopchest.utils.ShopUtils;
|
||||||
import de.epiceric.shopchest.interfaces.Utils;
|
import de.epiceric.shopchest.interfaces.Utils;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import net.milkbowl.vault.economy.Economy;
|
import net.milkbowl.vault.economy.Economy;
|
||||||
import net.milkbowl.vault.economy.EconomyResponse;
|
import net.milkbowl.vault.economy.EconomyResponse;
|
||||||
import net.milkbowl.vault.permission.Permission;
|
import net.milkbowl.vault.permission.Permission;
|
||||||
@ -43,11 +39,10 @@ public class InteractShop implements Listener{
|
|||||||
private ShopChest plugin;
|
private ShopChest plugin;
|
||||||
private Permission perm = ShopChest.perm;
|
private Permission perm = ShopChest.perm;
|
||||||
private Economy econ = ShopChest.econ;
|
private Economy econ = ShopChest.econ;
|
||||||
private YamlConfiguration shopChests;
|
private SQLite sqlite = ShopChest.sqlite;
|
||||||
|
|
||||||
public InteractShop(ShopChest plugin) {
|
public InteractShop(ShopChest plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
shopChests = plugin.shopChests;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@ -231,18 +226,10 @@ public class InteractShop implements Listener{
|
|||||||
private void create(Player executor, Location location, ItemStack product, double buyPrice, double sellPrice, boolean infinite) {
|
private void create(Player executor, Location location, ItemStack product, double buyPrice, double sellPrice, boolean infinite) {
|
||||||
|
|
||||||
Shop shop = new Shop(plugin, executor, product, location, buyPrice, sellPrice, infinite);
|
Shop shop = new Shop(plugin, executor, product, location, buyPrice, sellPrice, infinite);
|
||||||
|
shop.createHologram();
|
||||||
|
shop.createItem();
|
||||||
|
|
||||||
shopChests.set(ShopUtils.getConfigTitle(location) + ".vendor", executor);
|
sqlite.addShop(shop);
|
||||||
shopChests.set(ShopUtils.getConfigTitle(location) + ".location.world", location.getWorld().getName());
|
|
||||||
shopChests.set(ShopUtils.getConfigTitle(location) + ".location.x", location.getBlockX());
|
|
||||||
shopChests.set(ShopUtils.getConfigTitle(location) + ".location.y", location.getBlockY());
|
|
||||||
shopChests.set(ShopUtils.getConfigTitle(location) + ".location.z", location.getBlockZ());
|
|
||||||
shopChests.set(ShopUtils.getConfigTitle(location) + ".product", product);
|
|
||||||
shopChests.set(ShopUtils.getConfigTitle(location) + ".price.buy", buyPrice);
|
|
||||||
shopChests.set(ShopUtils.getConfigTitle(location) + ".price.sell", sellPrice);
|
|
||||||
shopChests.set(ShopUtils.getConfigTitle(location) + ".infinite", infinite);
|
|
||||||
|
|
||||||
try {shopChests.save(plugin.shopChestsFile);} catch (IOException ex) {ex.printStackTrace();}
|
|
||||||
|
|
||||||
ShopUtils.addShop(shop);
|
ShopUtils.addShop(shop);
|
||||||
executor.sendMessage(Config.shop_created());
|
executor.sendMessage(Config.shop_created());
|
||||||
@ -255,11 +242,9 @@ public class InteractShop implements Listener{
|
|||||||
|
|
||||||
private void remove(Player executor, Shop shop) {
|
private void remove(Player executor, Shop shop) {
|
||||||
|
|
||||||
shop.getItem().remove();
|
|
||||||
ShopUtils.removeShop(shop);
|
ShopUtils.removeShop(shop);
|
||||||
|
|
||||||
shopChests.set(ShopUtils.getConfigTitle(shop.getLocation()), null);
|
sqlite.removeShop(shop);
|
||||||
try {shopChests.save(plugin.shopChestsFile);} catch (IOException ex) {ex.printStackTrace();}
|
|
||||||
|
|
||||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||||
shop.getHologram().hidePlayer(player);
|
shop.getHologram().hidePlayer(player);
|
||||||
|
@ -19,7 +19,7 @@ public class RegenerateShopItemAfterRemove implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (containsShopItem) ShopChest.utils.reload();
|
if (containsShopItem) ShopChest.utils.reload(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
package de.epiceric.shopchest.interfaces;
|
package de.epiceric.shopchest.interfaces;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
public abstract class Utils {
|
public abstract class Utils {
|
||||||
|
|
||||||
public abstract void reload();
|
public abstract void reload(Player p);
|
||||||
|
|
||||||
public abstract void removeShops();
|
public abstract void removeShops();
|
||||||
|
|
||||||
@ -33,4 +36,29 @@ public abstract class Utils {
|
|||||||
return string.matches("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[34][0-9a-fA-F]{3}-[89ab][0-9a-fA-F]{3}-[0-9a-fA-F]{12}");
|
return string.matches("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[34][0-9a-fA-F]{3}-[89ab][0-9a-fA-F]{3}-[0-9a-fA-F]{12}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String encode(ItemStack itemStack) {
|
||||||
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
|
config.set("i", itemStack);
|
||||||
|
return new String(Base64.encodeBase64(config.saveToString().getBytes()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toString(ItemStack itemStack) {
|
||||||
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
|
config.set("i", itemStack);
|
||||||
|
return config.saveToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStack decode(String string) {
|
||||||
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
|
try {
|
||||||
|
config.loadFromString(new String(Base64.decodeBase64(string.getBytes())));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return config.getItemStack("i", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
package de.epiceric.shopchest.interfaces.utils;
|
package de.epiceric.shopchest.interfaces.utils;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import de.epiceric.shopchest.ShopChest;
|
import de.epiceric.shopchest.ShopChest;
|
||||||
|
import de.epiceric.shopchest.config.Config;
|
||||||
import de.epiceric.shopchest.interfaces.Utils;
|
import de.epiceric.shopchest.interfaces.Utils;
|
||||||
import de.epiceric.shopchest.interfaces.Hologram;
|
import de.epiceric.shopchest.interfaces.Hologram;
|
||||||
import de.epiceric.shopchest.shop.Shop;
|
import de.epiceric.shopchest.shop.Shop;
|
||||||
@ -17,7 +14,7 @@ import net.minecraft.server.v1_8_R1.EntityArmorStand;
|
|||||||
public class Utils_R1 extends Utils {
|
public class Utils_R1 extends Utils {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reload() {
|
public void reload(Player player) {
|
||||||
|
|
||||||
for (Shop shop : ShopUtils.getShops()) {
|
for (Shop shop : ShopUtils.getShops()) {
|
||||||
Hologram hologram = shop.getHologram();
|
Hologram hologram = shop.getHologram();
|
||||||
@ -37,23 +34,25 @@ public class Utils_R1 extends Utils {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String key : ShopChest.getInstance().shopChests.getKeys(false)) {
|
int count = 0;
|
||||||
|
|
||||||
OfflinePlayer vendor = ShopChest.getInstance().shopChests.getOfflinePlayer(key + ".vendor");
|
for (int id = 1; id < ShopChest.sqlite.getCount() + 1; id++) {
|
||||||
int locationX = ShopChest.getInstance().shopChests.getInt(key + ".location.x");
|
|
||||||
int locationY = ShopChest.getInstance().shopChests.getInt(key + ".location.y");
|
|
||||||
int locationZ = ShopChest.getInstance().shopChests.getInt(key + ".location.z");
|
|
||||||
World locationWorld = ShopChest.getInstance().getServer().getWorld(ShopChest.getInstance().shopChests.getString(key + ".location.world"));
|
|
||||||
Location location = new Location(locationWorld, locationX, locationY, locationZ);
|
|
||||||
ItemStack product = ShopChest.getInstance().shopChests.getItemStack(key + ".product");
|
|
||||||
double buyPrice = ShopChest.getInstance().shopChests.getDouble(key + ".price.buy");
|
|
||||||
double sellPrice = ShopChest.getInstance().shopChests.getDouble(key + ".price.sell");
|
|
||||||
boolean infinite = ShopChest.getInstance().shopChests.getBoolean(key + ".infinite");
|
|
||||||
|
|
||||||
ShopUtils.addShop(new Shop(ShopChest.getInstance(), vendor, product, location, buyPrice, sellPrice, infinite));
|
try {
|
||||||
|
Shop shop = ShopChest.sqlite.getShop(id);
|
||||||
|
shop.createHologram();
|
||||||
|
shop.createItem();
|
||||||
|
ShopUtils.addShop(shop);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player != null) player.sendMessage(Config.reloaded_shops(count));
|
||||||
|
|
||||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||||
Bukkit.getPluginManager().callEvent(new PlayerMoveEvent(p, p.getLocation(), p.getLocation()));
|
Bukkit.getPluginManager().callEvent(new PlayerMoveEvent(p, p.getLocation(), p.getLocation()));
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package de.epiceric.shopchest.interfaces.utils;
|
package de.epiceric.shopchest.interfaces.utils;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import de.epiceric.shopchest.ShopChest;
|
import de.epiceric.shopchest.ShopChest;
|
||||||
import de.epiceric.shopchest.interfaces.Utils;
|
import de.epiceric.shopchest.config.Config;
|
||||||
import de.epiceric.shopchest.interfaces.Hologram;
|
import de.epiceric.shopchest.interfaces.Hologram;
|
||||||
|
import de.epiceric.shopchest.interfaces.Utils;
|
||||||
import de.epiceric.shopchest.shop.Shop;
|
import de.epiceric.shopchest.shop.Shop;
|
||||||
import de.epiceric.shopchest.utils.ShopUtils;
|
import de.epiceric.shopchest.utils.ShopUtils;
|
||||||
import net.minecraft.server.v1_8_R2.EntityArmorStand;
|
import net.minecraft.server.v1_8_R2.EntityArmorStand;
|
||||||
@ -17,7 +15,7 @@ import net.minecraft.server.v1_8_R2.EntityArmorStand;
|
|||||||
public class Utils_R2 extends Utils {
|
public class Utils_R2 extends Utils {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reload() {
|
public void reload(Player player) {
|
||||||
|
|
||||||
for (Shop shop : ShopUtils.getShops()) {
|
for (Shop shop : ShopUtils.getShops()) {
|
||||||
Hologram hologram = shop.getHologram();
|
Hologram hologram = shop.getHologram();
|
||||||
@ -37,23 +35,25 @@ public class Utils_R2 extends Utils {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String key : ShopChest.getInstance().shopChests.getKeys(false)) {
|
int count = 0;
|
||||||
|
|
||||||
OfflinePlayer vendor = ShopChest.getInstance().shopChests.getOfflinePlayer(key + ".vendor");
|
for (int id = 1; id < ShopChest.sqlite.getCount() + 1; id++) {
|
||||||
int locationX = ShopChest.getInstance().shopChests.getInt(key + ".location.x");
|
|
||||||
int locationY = ShopChest.getInstance().shopChests.getInt(key + ".location.y");
|
|
||||||
int locationZ = ShopChest.getInstance().shopChests.getInt(key + ".location.z");
|
|
||||||
World locationWorld = ShopChest.getInstance().getServer().getWorld(ShopChest.getInstance().shopChests.getString(key + ".location.world"));
|
|
||||||
Location location = new Location(locationWorld, locationX, locationY, locationZ);
|
|
||||||
ItemStack product = ShopChest.getInstance().shopChests.getItemStack(key + ".product");
|
|
||||||
double buyPrice = ShopChest.getInstance().shopChests.getDouble(key + ".price.buy");
|
|
||||||
double sellPrice = ShopChest.getInstance().shopChests.getDouble(key + ".price.sell");
|
|
||||||
boolean infinite = ShopChest.getInstance().shopChests.getBoolean(key + ".infinite");
|
|
||||||
|
|
||||||
ShopUtils.addShop(new Shop(ShopChest.getInstance(), vendor, product, location, buyPrice, sellPrice, infinite));
|
try {
|
||||||
|
Shop shop = ShopChest.sqlite.getShop(id);
|
||||||
|
shop.createHologram();
|
||||||
|
shop.createItem();
|
||||||
|
ShopUtils.addShop(shop);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player != null) player.sendMessage(Config.reloaded_shops(count));
|
||||||
|
|
||||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||||
Bukkit.getPluginManager().callEvent(new PlayerMoveEvent(p, p.getLocation(), p.getLocation()));
|
Bukkit.getPluginManager().callEvent(new PlayerMoveEvent(p, p.getLocation(), p.getLocation()));
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
package de.epiceric.shopchest.interfaces.utils;
|
package de.epiceric.shopchest.interfaces.utils;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import de.epiceric.shopchest.ShopChest;
|
import de.epiceric.shopchest.ShopChest;
|
||||||
|
import de.epiceric.shopchest.config.Config;
|
||||||
import de.epiceric.shopchest.interfaces.Utils;
|
import de.epiceric.shopchest.interfaces.Utils;
|
||||||
import de.epiceric.shopchest.interfaces.Hologram;
|
import de.epiceric.shopchest.interfaces.Hologram;
|
||||||
import de.epiceric.shopchest.shop.Shop;
|
import de.epiceric.shopchest.shop.Shop;
|
||||||
@ -17,7 +14,7 @@ import net.minecraft.server.v1_8_R3.EntityArmorStand;
|
|||||||
public class Utils_R3 extends Utils {
|
public class Utils_R3 extends Utils {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reload() {
|
public void reload(Player player) {
|
||||||
|
|
||||||
for (Shop shop : ShopUtils.getShops()) {
|
for (Shop shop : ShopUtils.getShops()) {
|
||||||
Hologram hologram = shop.getHologram();
|
Hologram hologram = shop.getHologram();
|
||||||
@ -37,23 +34,25 @@ public class Utils_R3 extends Utils {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String key : ShopChest.getInstance().shopChests.getKeys(false)) {
|
int count = 0;
|
||||||
|
|
||||||
OfflinePlayer vendor = ShopChest.getInstance().shopChests.getOfflinePlayer(key + ".vendor");
|
for (int id = 1; id < ShopChest.sqlite.getCount() + 1; id++) {
|
||||||
int locationX = ShopChest.getInstance().shopChests.getInt(key + ".location.x");
|
|
||||||
int locationY = ShopChest.getInstance().shopChests.getInt(key + ".location.y");
|
|
||||||
int locationZ = ShopChest.getInstance().shopChests.getInt(key + ".location.z");
|
|
||||||
World locationWorld = ShopChest.getInstance().getServer().getWorld(ShopChest.getInstance().shopChests.getString(key + ".location.world"));
|
|
||||||
Location location = new Location(locationWorld, locationX, locationY, locationZ);
|
|
||||||
ItemStack product = ShopChest.getInstance().shopChests.getItemStack(key + ".product");
|
|
||||||
double buyPrice = ShopChest.getInstance().shopChests.getDouble(key + ".price.buy");
|
|
||||||
double sellPrice = ShopChest.getInstance().shopChests.getDouble(key + ".price.sell");
|
|
||||||
boolean infinite = ShopChest.getInstance().shopChests.getBoolean(key + ".infinite");
|
|
||||||
|
|
||||||
ShopUtils.addShop(new Shop(ShopChest.getInstance(), vendor, product, location, buyPrice, sellPrice, infinite));
|
try {
|
||||||
|
Shop shop = ShopChest.sqlite.getShop(id);
|
||||||
|
shop.createHologram();
|
||||||
|
shop.createItem();
|
||||||
|
ShopUtils.addShop(shop);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player != null) player.sendMessage(Config.reloaded_shops(count));
|
||||||
|
|
||||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||||
Bukkit.getPluginManager().callEvent(new PlayerMoveEvent(p, p.getLocation(), p.getLocation()));
|
Bukkit.getPluginManager().callEvent(new PlayerMoveEvent(p, p.getLocation(), p.getLocation()));
|
||||||
}
|
}
|
||||||
|
@ -45,11 +45,9 @@ public class Shop {
|
|||||||
this.buyPrice = buyPrice;
|
this.buyPrice = buyPrice;
|
||||||
this.sellPrice = sellPrice;
|
this.sellPrice = sellPrice;
|
||||||
this.infinite = infinite;
|
this.infinite = infinite;
|
||||||
this.hologram = createHologram(product, location, buyPrice, sellPrice);
|
|
||||||
this.item = createItem(product, location);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item createItem(ItemStack product, Location location) {
|
public void createItem() {
|
||||||
|
|
||||||
Item item;
|
Item item;
|
||||||
Location itemLocation;
|
Location itemLocation;
|
||||||
@ -70,19 +68,16 @@ public class Shop {
|
|||||||
item.setVelocity(new Vector(0, 0, 0));
|
item.setVelocity(new Vector(0, 0, 0));
|
||||||
item.setMetadata("shopItem", new FixedMetadataValue(plugin, true));
|
item.setMetadata("shopItem", new FixedMetadataValue(plugin, true));
|
||||||
|
|
||||||
return item;
|
this.item = item;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hologram createHologram(ItemStack product, Location shopLocation, double buyPrice, double sellPrice) {
|
public void createHologram() {
|
||||||
|
|
||||||
boolean doubleChest;
|
boolean doubleChest;
|
||||||
|
|
||||||
Hologram hologram;
|
|
||||||
|
|
||||||
Chest[] chests = new Chest[2];
|
Chest[] chests = new Chest[2];
|
||||||
|
|
||||||
Block b = shopLocation.getBlock();
|
Block b = location.getBlock();
|
||||||
|
|
||||||
if (b.getType().equals(Material.CHEST) || b.getType().equals(Material.TRAPPED_CHEST)) {
|
if (b.getType().equals(Material.CHEST) || b.getType().equals(Material.TRAPPED_CHEST)) {
|
||||||
|
|
||||||
@ -106,7 +101,7 @@ public class Shop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Location holoLocation;
|
Location holoLocation;
|
||||||
@ -145,11 +140,9 @@ public class Shop {
|
|||||||
case "v1_8_R1": hologram = new Hologram_R1(holoText, holoLocation); break;
|
case "v1_8_R1": hologram = new Hologram_R1(holoText, holoLocation); break;
|
||||||
case "v1_8_R2": hologram = new Hologram_R2(holoText, holoLocation); break;
|
case "v1_8_R2": hologram = new Hologram_R2(holoText, holoLocation); break;
|
||||||
case "v1_8_R3": hologram = new Hologram_R3(holoText, holoLocation); break;
|
case "v1_8_R3": hologram = new Hologram_R3(holoText, holoLocation); break;
|
||||||
default: return null;
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hologram;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public OfflinePlayer getVendor() {
|
public OfflinePlayer getVendor() {
|
||||||
|
487
src/de/epiceric/shopchest/sql/Database.java
Normal file
487
src/de/epiceric/shopchest/sql/Database.java
Normal file
@ -0,0 +1,487 @@
|
|||||||
|
package de.epiceric.shopchest.sql;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import de.epiceric.shopchest.ShopChest;
|
||||||
|
import de.epiceric.shopchest.interfaces.Utils;
|
||||||
|
import de.epiceric.shopchest.shop.Shop;
|
||||||
|
import de.epiceric.shopchest.utils.ShopUtils;
|
||||||
|
|
||||||
|
public abstract class Database {
|
||||||
|
ShopChest plugin;
|
||||||
|
Connection connection;
|
||||||
|
// The name of the table we created back in SQLite class.
|
||||||
|
public String table = "shop_list";
|
||||||
|
|
||||||
|
public String world = "";
|
||||||
|
public String vendor = "";
|
||||||
|
public ItemStack product = null;
|
||||||
|
public Location location = null;
|
||||||
|
public double buyPrice = 0;
|
||||||
|
public double sellPrice = 0;
|
||||||
|
public boolean infinite = false;
|
||||||
|
|
||||||
|
public Database(ShopChest instance){
|
||||||
|
plugin = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Connection getSQLConnection();
|
||||||
|
|
||||||
|
public abstract void load();
|
||||||
|
|
||||||
|
public void initialize(){
|
||||||
|
connection = getSQLConnection();
|
||||||
|
try{
|
||||||
|
PreparedStatement ps = connection.prepareStatement("SELECT * FROM " + table + " WHERE id = ?");
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
close(ps,rs);
|
||||||
|
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "Unable to retreive connection", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNextFreeID() {
|
||||||
|
for (int i = 1; i <= getCount(); i++) {
|
||||||
|
if (getProduct(i) == null) {
|
||||||
|
return i;
|
||||||
|
} else {
|
||||||
|
if (i == getCount()) {
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
int highestID = 0;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("SELECT * FROM " + table + ";");
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
while(rs.next()){
|
||||||
|
if(rs.getInt("id") > highestID) {
|
||||||
|
highestID = rs.getInt("id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return highestID;
|
||||||
|
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getShopID(Shop shop) {
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 1; i < getCount() + 1; i++) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Shop s = getShop(i);
|
||||||
|
if (s.getLocation().equals(shop.getLocation())) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
} catch (NullPointerException ex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeShop(Shop shop) {
|
||||||
|
|
||||||
|
int id = getShopID(shop);
|
||||||
|
if (id == 0) return;
|
||||||
|
|
||||||
|
shop.getItem().remove();
|
||||||
|
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("DELETE FROM " + table + " where id = " + id + ";");
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeShop(int id) {
|
||||||
|
|
||||||
|
if (id == 0) return;
|
||||||
|
removeShop(getShop(id));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private World getWorld(int id) {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("SELECT * FROM " + table + " WHERE id = " + id + ";");
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
while(rs.next()){
|
||||||
|
if(rs.getInt("id") == id) {
|
||||||
|
return Bukkit.getWorld(rs.getString("world"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public OfflinePlayer getVendor(int id) {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("SELECT * FROM " + table + " WHERE id = " + id + ";");
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
while(rs.next()){
|
||||||
|
if(rs.getInt("id") == id){
|
||||||
|
return (Utils.isUUID(rs.getString("vendor"))) ? Bukkit.getOfflinePlayer(UUID.fromString(rs.getString("vendor"))) : Bukkit.getOfflinePlayer(rs.getString("vendor"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getProduct(int id) {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("SELECT * FROM " + table + " WHERE id = " + id + ";");
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
while(rs.next()){
|
||||||
|
if(rs.getInt("id") == id){
|
||||||
|
return Utils.decode(rs.getString("product"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getX(int id) {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("SELECT * FROM " + table + " WHERE id = " + id + ";");
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
while(rs.next()){
|
||||||
|
if(rs.getInt("id") == id){
|
||||||
|
return rs.getInt("x");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getY(int id) {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("SELECT * FROM " + table + " WHERE id = " + id + ";");
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
while(rs.next()){
|
||||||
|
if(rs.getInt("id") == id){
|
||||||
|
return rs.getInt("y");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getZ(int id) {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("SELECT * FROM " + table + " WHERE id = " + id + ";");
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
while(rs.next()){
|
||||||
|
if(rs.getInt("id") == id){
|
||||||
|
return rs.getInt("z");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location getLocation(int id) {
|
||||||
|
return new Location(getWorld(id), getX(id), getY(id), getZ(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBuyPrice(int id) {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("SELECT * FROM " + table + " WHERE id = " + id + ";");
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
while(rs.next()){
|
||||||
|
if(rs.getInt("id") == id){
|
||||||
|
return rs.getDouble("buyprice");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSellPrice(int id) {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("SELECT * FROM " + table + " WHERE id = " + id + ";");
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
while(rs.next()){
|
||||||
|
if(rs.getInt("id") == id){
|
||||||
|
return rs.getDouble("sellprice");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInfinite(int id) {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("SELECT * FROM " + table + " WHERE id = " + id + ";");
|
||||||
|
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
while(rs.next()){
|
||||||
|
if(rs.getInt("id") == id){
|
||||||
|
return rs.getBoolean("infinite");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Shop getShop(int id) {
|
||||||
|
OfflinePlayer vendor = getVendor(id);
|
||||||
|
Location location = getLocation(id);
|
||||||
|
ItemStack product = getProduct(id);
|
||||||
|
double buyPrice = getBuyPrice(id);
|
||||||
|
double sellPrice = getSellPrice(id);
|
||||||
|
boolean infinite = isInfinite(id);
|
||||||
|
|
||||||
|
if (ShopUtils.isShop(location)) return ShopUtils.getShop(location);
|
||||||
|
else return new Shop(plugin, vendor, product, location, buyPrice, sellPrice, infinite);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setShop(int id, Shop shop) {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
try {
|
||||||
|
conn = getSQLConnection();
|
||||||
|
ps = conn.prepareStatement("REPLACE INTO " + table + " (id,vendor,product,world,x,y,z,buyprice,sellprice,infinite) VALUES(?,?,?,?,?,?,?,?,?,?)");
|
||||||
|
|
||||||
|
ps.setInt(1, id);
|
||||||
|
ps.setString(2, shop.getVendor().getUniqueId().toString());
|
||||||
|
ps.setString(3, Utils.encode(shop.getProduct()));
|
||||||
|
ps.setString(4, shop.getLocation().getWorld().getName());
|
||||||
|
ps.setInt(5, shop.getLocation().getBlockX());
|
||||||
|
ps.setInt(6, shop.getLocation().getBlockY());
|
||||||
|
ps.setInt(7, shop.getLocation().getBlockZ());
|
||||||
|
ps.setDouble(8, shop.getBuyPrice());
|
||||||
|
ps.setDouble(9, shop.getSellPrice());
|
||||||
|
ps.setBoolean(10, shop.isInfinite());
|
||||||
|
|
||||||
|
ps.executeUpdate();
|
||||||
|
return;
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (conn != null)
|
||||||
|
conn.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addShop(Shop shop) {
|
||||||
|
int id = getNextFreeID();
|
||||||
|
setShop(id, shop);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void close(PreparedStatement ps,ResultSet rs){
|
||||||
|
try {
|
||||||
|
if (ps != null)
|
||||||
|
ps.close();
|
||||||
|
if (rs != null)
|
||||||
|
rs.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
Error.close(plugin, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
src/de/epiceric/shopchest/sql/Error.java
Normal file
14
src/de/epiceric/shopchest/sql/Error.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package de.epiceric.shopchest.sql;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import de.epiceric.shopchest.ShopChest;
|
||||||
|
|
||||||
|
public class Error {
|
||||||
|
public static void execute(ShopChest plugin, Exception ex){
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "Couldn't execute MySQL statement: ", ex);
|
||||||
|
}
|
||||||
|
public static void close(ShopChest plugin, Exception ex){
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "Failed to close MySQL connection: ", ex);
|
||||||
|
}
|
||||||
|
}
|
16
src/de/epiceric/shopchest/sql/Errors.java
Normal file
16
src/de/epiceric/shopchest/sql/Errors.java
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package de.epiceric.shopchest.sql;
|
||||||
|
|
||||||
|
public class Errors {
|
||||||
|
public static String sqlConnectionExecute(){
|
||||||
|
return "Couldn't execute MySQL statement: ";
|
||||||
|
}
|
||||||
|
public static String sqlConnectionClose(){
|
||||||
|
return "Failed to close MySQL connection: ";
|
||||||
|
}
|
||||||
|
public static String noSQLConnection(){
|
||||||
|
return "Unable to retreive MYSQL connection: ";
|
||||||
|
}
|
||||||
|
public static String noTableFound(){
|
||||||
|
return "Database Error: No Table Found";
|
||||||
|
}
|
||||||
|
}
|
73
src/de/epiceric/shopchest/sql/SQLite.java
Normal file
73
src/de/epiceric/shopchest/sql/SQLite.java
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package de.epiceric.shopchest.sql;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import de.epiceric.shopchest.ShopChest;
|
||||||
|
|
||||||
|
public class SQLite extends Database {
|
||||||
|
|
||||||
|
String dbname;
|
||||||
|
|
||||||
|
public SQLite(ShopChest instance){
|
||||||
|
super(instance);
|
||||||
|
dbname = "shops";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String SQLiteCreateTokensTable = "CREATE TABLE IF NOT EXISTS shop_list (" +
|
||||||
|
"`id` int(11) NOT NULL," +
|
||||||
|
"`vendor` varchar(32) NOT NULL," +
|
||||||
|
"`product` varchar(32) NOT NULL," +
|
||||||
|
"`world` varchar(32) NOT NULL," +
|
||||||
|
"`x` int(11) NOT NULL," +
|
||||||
|
"`y` int(11) NOT NULL," +
|
||||||
|
"`z` int(11) NOT NULL," +
|
||||||
|
"`buyprice` float(32) NOT NULL," +
|
||||||
|
"`sellprice` float(32) NOT NULL," +
|
||||||
|
"`infinite` boolean NOT NULL," +
|
||||||
|
"PRIMARY KEY (`id`)" +
|
||||||
|
");";
|
||||||
|
|
||||||
|
|
||||||
|
// SQL creation stuff, You can leave the below stuff untouched.
|
||||||
|
public Connection getSQLConnection() {
|
||||||
|
File dataFolder = new File(plugin.getDataFolder(), dbname+".db");
|
||||||
|
if (!dataFolder.exists()){
|
||||||
|
try {
|
||||||
|
dataFolder.createNewFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "File write error: "+dbname+".db");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if(connection!=null&&!connection.isClosed()){
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
Class.forName("org.sqlite.JDBC");
|
||||||
|
connection = DriverManager.getConnection("jdbc:sqlite:" + dataFolder);
|
||||||
|
return connection;
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE,"SQLite exception on initialize", ex);
|
||||||
|
} catch (ClassNotFoundException ex) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "You need the SQLite JBDC library. Google it. Put it in /lib folder.");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load() {
|
||||||
|
connection = getSQLConnection();
|
||||||
|
try {
|
||||||
|
Statement s = connection.createStatement();
|
||||||
|
s.executeUpdate(SQLiteCreateTokensTable);
|
||||||
|
s.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
}
|
@ -91,6 +91,7 @@ public class ShopUtils {
|
|||||||
Chest r = (Chest) dc.getRightSide();
|
Chest r = (Chest) dc.getRightSide();
|
||||||
Chest l = (Chest) dc.getLeftSide();
|
Chest l = (Chest) dc.getLeftSide();
|
||||||
|
|
||||||
|
shop.getItem().remove();
|
||||||
shopLocation.remove(r.getLocation());
|
shopLocation.remove(r.getLocation());
|
||||||
shopLocation.remove(l.getLocation());
|
shopLocation.remove(l.getLocation());
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user