DbManagerImpl.java

/*
 * Decompiled with CFR 0_132.
 * 
 * Could not load the following classes:
 *  android.database.Cursor
 *  android.database.sqlite.SQLiteDatabase
 *  android.database.sqlite.SQLiteDatabase$CursorFactory
 *  android.database.sqlite.SQLiteStatement
 *  android.os.Build
 *  android.os.Build$VERSION
 */
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;
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @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();
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @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();
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @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();
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @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;
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @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();
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @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);
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @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;
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @Override
    public /* varargs */ 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();
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @Override
    public /* varargs */ 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);
        }
    }
}