Search in sources :

Example 1 with DbProperty

use of com.coredata.db.DbProperty in project CoreData by FangCloud-Android.

the class CoreDao method onDataBaseUpgrade.

/**
 * 数据库升级
 *
 * @param db         {@link CoreDatabaseManager#onUpgrade(CoreDatabase, int, int)}
 * @param oldVersion 老版本
 * @param newVersion 新版本
 */
void onDataBaseUpgrade(CoreDatabase db, int oldVersion, int newVersion) {
    synchronized (lock) {
        List<DbProperty> dbProperties = new ArrayList<>();
        Cursor cursor = null;
        try {
            cursor = db.rawQuery(String.format("PRAGMA TABLE_INFO(%s)", getTableName()), null);
            int nameCursorIndex = cursor.getColumnIndex("name");
            int typeCursorIndex = cursor.getColumnIndex("type");
            int nonNullCursorIndex = cursor.getColumnIndex("notnull");
            int defValCursorIndex = cursor.getColumnIndex("dflt_value");
            int primaryKeyCursorIndex = cursor.getColumnIndex("pk");
            while (cursor.moveToNext()) {
                String name = cursor.getString(nameCursorIndex);
                String type = cursor.getString(typeCursorIndex);
                boolean primaryKey = cursor.getInt(primaryKeyCursorIndex) == 1;
                dbProperties.add(new DbProperty(name, type, primaryKey));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeCursor(cursor);
        }
        if (dbProperties.isEmpty()) {
            // 如果找不到建表语句,则删除旧表重新创建
            db.execSQL(SqlUtils.getDropTableSql(getTableName()));
            db.execSQL(getCreateTableSql());
        } else {
            // 解析原始表创建语句,分析字段对应类型及主键,索引等参数是否一致,并进行修改
            // 匹配相交的数据
            List<Property> tableProperties = getTableProperties();
            List<DbProperty> newDbProperties = new ArrayList<>();
            for (Property property : tableProperties) {
                newDbProperties.add(new DbProperty(property.name, SqlUtils.getSqlTypeByClazz(property.type), property.primaryKey));
            }
            // 如果求交集数据有变化,或者新旧表列数不相等,则需要迁移
            if (newDbProperties.retainAll(dbProperties) || tableProperties.size() != dbProperties.size()) {
                // 修改老表到临时表
                String tempTableName = getTableName() + "_" + oldVersion;
                boolean needMoveData = true;
                try {
                    db.execSQL(String.format("ALTER TABLE %s RENAME TO %s", getTableName(), tempTableName));
                } catch (SQLException e) {
                    // 修改表结构失败
                    db.execSQL(SqlUtils.getDropTableSql(getTableName()));
                    needMoveData = false;
                }
                // 创建新的表
                db.execSQL(getCreateTableSql());
                if (needMoveData && !newDbProperties.isEmpty()) {
                    try {
                        // 取出老的数据
                        boolean isJoinPrimaryKey = false;
                        for (DbProperty dbProperty : newDbProperties) {
                            if (dbProperty.primaryKey) {
                                isJoinPrimaryKey = true;
                                break;
                            }
                        }
                        // 如果主键不一致,说明数据没有迁移的必要
                        if (isJoinPrimaryKey) {
                            // 从老表中取出所有交集的数据
                            StringBuilder sqlBuilder = new StringBuilder("SELECT ");
                            boolean isFirst = true;
                            for (DbProperty dbProperty : newDbProperties) {
                                if (!isFirst) {
                                    sqlBuilder.append(", ");
                                }
                                isFirst = false;
                                sqlBuilder.append(dbProperty.name);
                            }
                            sqlBuilder.append(" FROM ").append(tempTableName);
                            List<ContentValues> contentValuesList = new ArrayList<>();
                            Cursor cursorData = null;
                            try {
                                // 取出所有相交的数据,并转换为ContentValues
                                cursorData = db.rawQuery(sqlBuilder.toString(), null);
                                while (cursorData.moveToNext()) {
                                    ContentValues contentValues = new ContentValues();
                                    DatabaseUtils.cursorRowToContentValues(cursorData, contentValues);
                                    contentValuesList.add(contentValues);
                                }
                            } finally {
                                closeCursor(cursorData);
                            }
                            // 插入新表
                            if (!contentValuesList.isEmpty()) {
                                db.beginTransaction();
                                for (ContentValues cv : contentValuesList) {
                                    db.replace(getTableName(), null, cv);
                                }
                                db.setTransactionSuccessful();
                                db.endTransaction();
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                // 删除旧表
                db.execSQL(SqlUtils.getDropTableSql(tempTableName));
            }
        }
    }
}
Also used : ContentValues(android.content.ContentValues) SQLException(android.database.SQLException) ArrayList(java.util.ArrayList) Cursor(android.database.Cursor) SQLException(android.database.SQLException) DbProperty(com.coredata.db.DbProperty) Property(com.coredata.db.Property) DbProperty(com.coredata.db.DbProperty)

Aggregations

ContentValues (android.content.ContentValues)1 Cursor (android.database.Cursor)1 SQLException (android.database.SQLException)1 DbProperty (com.coredata.db.DbProperty)1 Property (com.coredata.db.Property)1 ArrayList (java.util.ArrayList)1