All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.j256.ormlite.android.AndroidCompiledStatement Maven / Gradle / Ivy
Go to download
Lightweight Object Relational Model (ORM) Android classes
package com.j256.ormlite.android;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import com.j256.ormlite.android.compat.ApiCompatibility;
import com.j256.ormlite.android.compat.ApiCompatibility.CancellationHook;
import com.j256.ormlite.android.compat.ApiCompatibilityUtils;
import com.j256.ormlite.dao.ObjectCache;
import com.j256.ormlite.field.SqlType;
import com.j256.ormlite.logger.Logger;
import com.j256.ormlite.logger.LoggerFactory;
import com.j256.ormlite.misc.SqlExceptionUtil;
import com.j256.ormlite.stmt.StatementBuilder.StatementType;
import com.j256.ormlite.support.CompiledStatement;
import com.j256.ormlite.support.DatabaseResults;
/**
* Android implementation of the compiled statement.
*
* @author kevingalligan, graywatson
*/
public class AndroidCompiledStatement implements CompiledStatement {
private static Logger logger = LoggerFactory.getLogger(AndroidCompiledStatement.class);
private static final String[] NO_STRING_ARGS = new String[0];
private static final ApiCompatibility apiCompatibility = ApiCompatibilityUtils.getCompatibility();
private final String sql;
private final SQLiteDatabase db;
private final StatementType type;
private final boolean cancelQueriesEnabled;
private Cursor cursor;
private List args;
private Integer max;
private CancellationHook cancellationHook;
public AndroidCompiledStatement(String sql, SQLiteDatabase db, StatementType type, boolean cancelQueriesEnabled) {
this.sql = sql;
this.db = db;
this.type = type;
this.cancelQueriesEnabled = cancelQueriesEnabled;
}
public int getColumnCount() throws SQLException {
return getCursor().getColumnCount();
}
public String getColumnName(int column) throws SQLException {
return getCursor().getColumnName(column);
}
public DatabaseResults runQuery(ObjectCache objectCache) throws SQLException {
// this could come from DELETE or UPDATE, just not a SELECT
if (!type.isOkForQuery()) {
throw new IllegalArgumentException("Cannot call query on a " + type + " statement");
}
return new AndroidDatabaseResults(getCursor(), objectCache);
}
public int runUpdate() throws SQLException {
if (!type.isOkForUpdate()) {
throw new IllegalArgumentException("Cannot call update on a " + type + " statement");
}
String finalSql;
if (max == null) {
finalSql = sql;
} else {
finalSql = sql + " " + max;
}
return execSql(db, "runUpdate", finalSql, getArgArray());
}
public int runExecute() throws SQLException {
if (!type.isOkForExecute()) {
throw new IllegalArgumentException("Cannot call execute on a " + type + " statement");
}
return execSql(db, "runExecute", sql, getArgArray());
}
public void close() throws SQLException {
if (cursor != null) {
try {
cursor.close();
} catch (android.database.SQLException e) {
throw SqlExceptionUtil.create("Problems closing Android cursor", e);
}
}
cancellationHook = null;
}
public void closeQuietly() {
try {
close();
} catch (SQLException e) {
// ignored
}
}
public void cancel() {
if (cancellationHook != null) {
cancellationHook.cancel();
}
}
public void setObject(int parameterIndex, Object obj, SqlType sqlType) throws SQLException {
isInPrep();
if (args == null) {
args = new ArrayList();
}
if (obj == null) {
args.add(parameterIndex, null);
return;
}
switch (sqlType) {
case STRING :
case LONG_STRING :
case DATE :
case BOOLEAN :
case CHAR :
case BYTE :
case SHORT :
case INTEGER :
case LONG :
case FLOAT :
case DOUBLE :
args.add(parameterIndex, obj.toString());
break;
case BYTE_ARRAY :
case SERIALIZABLE :
args.add(parameterIndex, obj);
break;
case BLOB :
// this is only for derby serializable
case BIG_DECIMAL :
// this should be handled as a STRING
throw new SQLException("Invalid Android type: " + sqlType);
case UNKNOWN :
default :
throw new SQLException("Unknown sql argument type: " + sqlType);
}
}
public void setMaxRows(int max) throws SQLException {
isInPrep();
this.max = max;
}
public void setQueryTimeout(long millis) {
// as far as I could tell this is not supported by Android API
}
/***
* This is mostly an internal class but is exposed for those people who need access to the Cursor itself.
*
*
* NOTE: This is not thread safe. Not sure if we need it, but keep that in mind.
*
*/
public Cursor getCursor() throws SQLException {
if (cursor == null) {
String finalSql = null;
try {
if (max == null) {
finalSql = sql;
} else {
finalSql = sql + " " + max;
}
if (cancelQueriesEnabled) {
cancellationHook = apiCompatibility.createCancellationHook();
}
cursor = apiCompatibility.rawQuery(db, finalSql, getStringArray(), cancellationHook);
cursor.moveToFirst();
logger.trace("{}: started rawQuery cursor for: {}", this, finalSql);
} catch (android.database.SQLException e) {
throw SqlExceptionUtil.create("Problems executing Android query: " + finalSql, e);
}
}
return cursor;
}
@Override
public String toString() {
return getClass().getSimpleName() + "@" + Integer.toHexString(super.hashCode());
}
/**
* Execute some SQL on the database and return the number of rows changed.
*/
static int execSql(SQLiteDatabase db, String label, String finalSql, Object[] argArray) throws SQLException {
try {
db.execSQL(finalSql, argArray);
} catch (android.database.SQLException e) {
throw SqlExceptionUtil.create("Problems executing " + label + " Android statement: " + finalSql, e);
}
int result;
SQLiteStatement stmt = null;
try {
// ask sqlite how many rows were just changed
stmt = db.compileStatement("SELECT CHANGES()");
result = (int) stmt.simpleQueryForLong();
} catch (android.database.SQLException e) {
// ignore the exception and just return 1 if it failed
result = 1;
} finally {
if (stmt != null) {
stmt.close();
}
}
logger.trace("executing statement {} changed {} rows: {}", label, result, finalSql);
return result;
}
private void isInPrep() throws SQLException {
if (cursor != null) {
throw new SQLException("Query already run. Cannot add argument values.");
}
}
private Object[] getArgArray() {
if (args == null) {
// this will work for Object[] as well as String[]
return NO_STRING_ARGS;
} else {
return args.toArray(new Object[args.size()]);
}
}
private String[] getStringArray() {
if (args == null) {
return NO_STRING_ARGS;
} else {
// we assume we have Strings in args
return args.toArray(new String[args.size()]);
}
}
}