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));
}
}
}
}
Aggregations