DbManagerImpl.java
package org.xutils.db;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.os.Build;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.xutils.DbManager;
import org.xutils.common.util.IOUtil;
import org.xutils.common.util.KeyValue;
import org.xutils.common.util.LogUtil;
import org.xutils.db.CursorUtils;
import org.xutils.db.Selector;
import org.xutils.db.sqlite.SqlInfo;
import org.xutils.db.sqlite.SqlInfoBuilder;
import org.xutils.db.sqlite.WhereBuilder;
import org.xutils.db.table.ColumnEntity;
import org.xutils.db.table.DbBase;
import org.xutils.db.table.DbModel;
import org.xutils.db.table.TableEntity;
import org.xutils.ex.DbException;
import org.xutils.x;
public final class DbManagerImpl
extends DbBase {
private static final HashMap<DbManager.DaoConfig, DbManagerImpl> DAO_MAP = new HashMap();
private SQLiteDatabase database;
private DbManager.DaoConfig daoConfig;
private boolean allowTransaction;
private DbManagerImpl(DbManager.DaoConfig config) {
if (config == null) {
throw new IllegalArgumentException("daoConfig may not be null");
}
this.daoConfig = config;
this.allowTransaction = config.isAllowTransaction();
this.database = this.openOrCreateDatabase(config);
DbManager.DbOpenListener dbOpenListener = config.getDbOpenListener();
if (dbOpenListener != null) {
dbOpenListener.onDbOpened(this);
}
}
public static synchronized DbManager getInstance(DbManager.DaoConfig daoConfig) {
DbManagerImpl dao;
if (daoConfig == null) {
daoConfig = new DbManager.DaoConfig();
}
if ((dao = DAO_MAP.get(daoConfig)) == null) {
dao = new DbManagerImpl(daoConfig);
DAO_MAP.put(daoConfig, dao);
} else {
dao.daoConfig = daoConfig;
}
SQLiteDatabase database = dao.database;
int oldVersion = database.getVersion();
int newVersion = daoConfig.getDbVersion();
if (oldVersion != newVersion) {
if (oldVersion != 0) {
DbManager.DbUpgradeListener upgradeListener = daoConfig.getDbUpgradeListener();
if (upgradeListener != null) {
upgradeListener.onUpgrade(dao, oldVersion, newVersion);
} else {
try {
dao.dropDb();
}
catch (DbException e) {
LogUtil.e(e.getMessage(), e);
}
}
}
database.setVersion(newVersion);
}
return dao;
}
@Override
public SQLiteDatabase getDatabase() {
return this.database;
}
@Override
public DbManager.DaoConfig getDaoConfig() {
return this.daoConfig;
}
@Override
public void saveOrUpdate(Object entity) throws DbException {
try {
this.beginTransaction();
if (entity instanceof List) {
List entities = (List)entity;
if (entities.isEmpty()) {
return;
}
TableEntity<?> table = this.getTable(entities.get(0).getClass());
this.createTableIfNotExist(table);
for (Object item : entities) {
this.saveOrUpdateWithoutTransaction(table, item);
}
} else {
TableEntity<?> table = this.getTable(entity.getClass());
this.createTableIfNotExist(table);
this.saveOrUpdateWithoutTransaction(table, entity);
}
this.setTransactionSuccessful();
}
finally {
this.endTransaction();
}
}
@Override
public void replace(Object entity) throws DbException {
try {
this.beginTransaction();
if (entity instanceof List) {
List entities = (List)entity;
if (entities.isEmpty()) {
return;
}
TableEntity<?> table = this.getTable(entities.get(0).getClass());
this.createTableIfNotExist(table);
for (Object item : entities) {
this.execNonQuery(SqlInfoBuilder.buildReplaceSqlInfo(table, item));
}
} else {
TableEntity<?> table = this.getTable(entity.getClass());
this.createTableIfNotExist(table);
this.execNonQuery(SqlInfoBuilder.buildReplaceSqlInfo(table, entity));
}
this.setTransactionSuccessful();
}
finally {
this.endTransaction();
}
}
@Override
public void save(Object entity) throws DbException {
try {
this.beginTransaction();
if (entity instanceof List) {
List entities = (List)entity;
if (entities.isEmpty()) {
return;
}
TableEntity<?> table = this.getTable(entities.get(0).getClass());
this.createTableIfNotExist(table);
for (Object item : entities) {
this.execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, item));
}
} else {
TableEntity<?> table = this.getTable(entity.getClass());
this.createTableIfNotExist(table);
this.execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, entity));
}
this.setTransactionSuccessful();
}
finally {
this.endTransaction();
}
}
@Override
public boolean saveBindingId(Object entity) throws DbException {
boolean result;
result = false;
try {
this.beginTransaction();
if (entity instanceof List) {
List entities = (List)entity;
if (entities.isEmpty()) {
boolean bl = false;
return bl;
}
TableEntity<?> table = this.getTable(entities.get(0).getClass());
this.createTableIfNotExist(table);
for (Object item : entities) {
if (this.saveBindingIdWithoutTransaction(table, item)) continue;
throw new DbException("saveBindingId error, transaction will not commit!");
}
} else {
TableEntity<?> table = this.getTable(entity.getClass());
this.createTableIfNotExist(table);
result = this.saveBindingIdWithoutTransaction(table, entity);
}
this.setTransactionSuccessful();
}
finally {
this.endTransaction();
}
return result;
}
@Override
public void deleteById(Class<?> entityType, Object idValue) throws DbException {
TableEntity<?> table = this.getTable(entityType);
if (!table.tableIsExist()) {
return;
}
try {
this.beginTransaction();
this.execNonQuery(SqlInfoBuilder.buildDeleteSqlInfoById(table, idValue));
this.setTransactionSuccessful();
}
finally {
this.endTransaction();
}
}
@Override
public void delete(Object entity) throws DbException {
try {
this.beginTransaction();
if (entity instanceof List) {
List entities = (List)entity;
if (entities.isEmpty()) {
return;
}
TableEntity<?> table = this.getTable(entities.get(0).getClass());
if (!table.tableIsExist()) {
return;
}
for (Object item : entities) {
this.execNonQuery(SqlInfoBuilder.buildDeleteSqlInfo(table, item));
}
} else {
TableEntity<?> table = this.getTable(entity.getClass());
if (!table.tableIsExist()) {
return;
}
this.execNonQuery(SqlInfoBuilder.buildDeleteSqlInfo(table, entity));
}
this.setTransactionSuccessful();
}
finally {
this.endTransaction();
}
}
@Override
public void delete(Class<?> entityType) throws DbException {
this.delete(entityType, null);
}
@Override
public int delete(Class<?> entityType, WhereBuilder whereBuilder) throws DbException {
int result;
TableEntity<?> table = this.getTable(entityType);
if (!table.tableIsExist()) {
return 0;
}
result = 0;
try {
this.beginTransaction();
result = this.executeUpdateDelete(SqlInfoBuilder.buildDeleteSqlInfo(table, whereBuilder));
this.setTransactionSuccessful();
}
finally {
this.endTransaction();
}
return result;
}
@Override
public void update(Object entity, String ... updateColumnNames) throws DbException {
try {
this.beginTransaction();
if (entity instanceof List) {
List entities = (List)entity;
if (entities.isEmpty()) {
return;
}
TableEntity<?> table = this.getTable(entities.get(0).getClass());
if (!table.tableIsExist()) {
return;
}
for (Object item : entities) {
this.execNonQuery(SqlInfoBuilder.buildUpdateSqlInfo(table, item, updateColumnNames));
}
} else {
TableEntity<?> table = this.getTable(entity.getClass());
if (!table.tableIsExist()) {
return;
}
this.execNonQuery(SqlInfoBuilder.buildUpdateSqlInfo(table, entity, updateColumnNames));
}
this.setTransactionSuccessful();
}
finally {
this.endTransaction();
}
}
@Override
public int update(Class<?> entityType, WhereBuilder whereBuilder, KeyValue ... nameValuePairs) throws DbException {
int result;
TableEntity<?> table = this.getTable(entityType);
if (!table.tableIsExist()) {
return 0;
}
result = 0;
try {
this.beginTransaction();
result = this.executeUpdateDelete(SqlInfoBuilder.buildUpdateSqlInfo(table, whereBuilder, nameValuePairs));
this.setTransactionSuccessful();
}
finally {
this.endTransaction();
}
return result;
}
@Override
public <T> T findById(Class<T> entityType, Object idValue) throws DbException {
TableEntity<T> table = this.getTable(entityType);
if (!table.tableIsExist()) {
return null;
}
Selector<T> selector = Selector.from(table).where(table.getId().getName(), "=", idValue);
String sql = selector.limit(1).toString();
Cursor cursor = this.execQuery(sql);
if (cursor != null) {
try {
if (cursor.moveToNext()) {
T t = CursorUtils.getEntity(table, cursor);
return t;
}
}
catch (Throwable e) {
throw new DbException(e);
}
finally {
IOUtil.closeQuietly(cursor);
}
}
return null;
}
@Override
public <T> T findFirst(Class<T> entityType) throws DbException {
return this.selector(entityType).findFirst();
}
@Override
public <T> List<T> findAll(Class<T> entityType) throws DbException {
return this.selector(entityType).findAll();
}
@Override
public <T> Selector<T> selector(Class<T> entityType) throws DbException {
return Selector.from(this.getTable(entityType));
}
@Override
public DbModel findDbModelFirst(SqlInfo sqlInfo) throws DbException {
Cursor cursor = this.execQuery(sqlInfo);
if (cursor != null) {
try {
if (cursor.moveToNext()) {
DbModel dbModel = CursorUtils.getDbModel(cursor);
return dbModel;
}
}
catch (Throwable e) {
throw new DbException(e);
}
finally {
IOUtil.closeQuietly(cursor);
}
}
return null;
}
@Override
public List<DbModel> findDbModelAll(SqlInfo sqlInfo) throws DbException {
ArrayList<DbModel> dbModelList;
dbModelList = new ArrayList<DbModel>();
Cursor cursor = this.execQuery(sqlInfo);
if (cursor != null) {
try {
while (cursor.moveToNext()) {
dbModelList.add(CursorUtils.getDbModel(cursor));
}
}
catch (Throwable e) {
throw new DbException(e);
}
finally {
IOUtil.closeQuietly(cursor);
}
}
return dbModelList;
}
private SQLiteDatabase openOrCreateDatabase(DbManager.DaoConfig config) {
SQLiteDatabase result = null;
File dbDir = config.getDbDir();
if (dbDir != null && (dbDir.exists() || dbDir.mkdirs())) {
File dbFile = new File(dbDir, config.getDbName());
result = SQLiteDatabase.openOrCreateDatabase((File)dbFile, null);
} else {
result = x.app().openOrCreateDatabase(config.getDbName(), 0, null);
}
return result;
}
private void saveOrUpdateWithoutTransaction(TableEntity<?> table, Object entity) throws DbException {
ColumnEntity id = table.getId();
if (id.isAutoId()) {
if (id.getColumnValue(entity) != null) {
this.execNonQuery(SqlInfoBuilder.buildUpdateSqlInfo(table, entity, new String[0]));
} else {
this.saveBindingIdWithoutTransaction(table, entity);
}
} else {
this.execNonQuery(SqlInfoBuilder.buildReplaceSqlInfo(table, entity));
}
}
private boolean saveBindingIdWithoutTransaction(TableEntity<?> table, Object entity) throws DbException {
ColumnEntity id = table.getId();
if (id.isAutoId()) {
this.execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, entity));
long idValue = this.getLastAutoIncrementId(table.getName());
if (idValue == -1L) {
return false;
}
id.setAutoIdValue(entity, idValue);
return true;
}
this.execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, entity));
return true;
}
private long getLastAutoIncrementId(String tableName) throws DbException {
long id;
id = -1L;
Cursor cursor = this.execQuery("SELECT seq FROM sqlite_sequence WHERE name='" + tableName + "' LIMIT 1");
if (cursor != null) {
try {
if (cursor.moveToNext()) {
id = cursor.getLong(0);
}
}
catch (Throwable e) {
throw new DbException(e);
}
finally {
IOUtil.closeQuietly(cursor);
}
}
return id;
}
@Override
public void close() throws IOException {
if (DAO_MAP.containsKey(this.daoConfig)) {
DAO_MAP.remove(this.daoConfig);
this.database.close();
}
}
private void beginTransaction() {
if (this.allowTransaction) {
if (Build.VERSION.SDK_INT >= 16 && this.database.isWriteAheadLoggingEnabled()) {
this.database.beginTransactionNonExclusive();
} else {
this.database.beginTransaction();
}
}
}
private void setTransactionSuccessful() {
if (this.allowTransaction) {
this.database.setTransactionSuccessful();
}
}
private void endTransaction() {
if (this.allowTransaction) {
this.database.endTransaction();
}
}
@Override
public int executeUpdateDelete(SqlInfo sqlInfo) throws DbException {
SQLiteStatement statement = null;
try {
statement = sqlInfo.buildStatement(this.database);
int n = statement.executeUpdateDelete();
return n;
}
catch (Throwable e) {
throw new DbException(e);
}
finally {
if (statement != null) {
try {
statement.releaseReference();
}
catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
}
}
@Override
public int executeUpdateDelete(String sql) throws DbException {
SQLiteStatement statement = null;
try {
statement = this.database.compileStatement(sql);
int n = statement.executeUpdateDelete();
return n;
}
catch (Throwable e) {
throw new DbException(e);
}
finally {
if (statement != null) {
try {
statement.releaseReference();
}
catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
}
}
@Override
public void execNonQuery(SqlInfo sqlInfo) throws DbException {
SQLiteStatement statement = null;
try {
statement = sqlInfo.buildStatement(this.database);
statement.execute();
}
catch (Throwable e) {
throw new DbException(e);
}
finally {
if (statement != null) {
try {
statement.releaseReference();
}
catch (Throwable ex) {
LogUtil.e(ex.getMessage(), ex);
}
}
}
}
@Override
public void execNonQuery(String sql) throws DbException {
try {
this.database.execSQL(sql);
}
catch (Throwable e) {
throw new DbException(e);
}
}
@Override
public Cursor execQuery(SqlInfo sqlInfo) throws DbException {
try {
return this.database.rawQuery(sqlInfo.getSql(), sqlInfo.getBindArgsAsStrArray());
}
catch (Throwable e) {
throw new DbException(e);
}
}
@Override
public Cursor execQuery(String sql) throws DbException {
try {
return this.database.rawQuery(sql, null);
}
catch (Throwable e) {
throw new DbException(e);
}
}
}