/*
* Copyright 2016 requery.io
*
* 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.
*/
package io.requery.android.sqlite;
import android.database.sqlite.SQLiteDatabase;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Statement;
/**
* {@link java.sql.Connection} implementation using Android's local SQLite database Java API.
*
* @author Nikhil Purushe
*/
class SqliteConnection extends BaseConnection {
private final SQLiteDatabase db;
private final SqliteMetaData metaData;
private boolean enteredTransaction;
SqliteConnection(SQLiteDatabase db) {
if(db == null) {
throw new IllegalArgumentException("null db");
}
this.db = db;
autoCommit = true;
metaData = new SqliteMetaData(this);
}
SQLiteDatabase getDatabase() {
return db;
}
@Override
protected void ensureTransaction() {
if (!autoCommit) {
if (!db.inTransaction()) {
db.beginTransactionNonExclusive();
enteredTransaction = true;
}
}
}
@Override
protected void execSQL(String sql) throws SQLException {
try {
db.execSQL(sql);
} catch (android.database.SQLException e) {
throwSQLException(e);
}
}
@Override
public void commit() throws SQLException {
if (autoCommit) {
throw new SQLException("commit called while in autoCommit mode");
}
if (db.inTransaction() && enteredTransaction) {
try {
db.setTransactionSuccessful();
} catch (IllegalStateException e) {
throw new SQLException(e);
} finally {
db.endTransaction();
enteredTransaction = false;
}
}
}
@Override
public Statement createStatement() throws SQLException {
return new SqliteStatement(this);
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency)
throws SQLException {
return createStatement(resultSetType,
resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) {
throw new SQLFeatureNotSupportedException("CONCUR_UPDATABLE not supported");
}
return new SqliteStatement(this);
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
return metaData;
}
@Override
public boolean isClosed() throws SQLException {
return !db.isOpen();
}
@Override
public boolean isReadOnly() throws SQLException {
return db.isReadOnly();
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
throws SQLException {
return new SqlitePreparedStatement(this, sql, autoGeneratedKeys);
}
@Override
public PreparedStatement prepareStatement(String sql,
int resultSetType,
int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) {
throw new SQLFeatureNotSupportedException("CONCUR_UPDATABLE not supported");
}
return new SqlitePreparedStatement(this, sql, Statement.NO_GENERATED_KEYS);
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames)
throws SQLException {
if (columnNames.length != 1) {
throw new SQLFeatureNotSupportedException();
}
return new SqlitePreparedStatement(this, sql, Statement.RETURN_GENERATED_KEYS);
}
@Override
public void rollback() throws SQLException {
if (autoCommit) {
throw new SQLException("commit called while in autoCommit mode");
}
db.endTransaction();
}
}