gpt4 book ai didi

android - 如何将旧版本的数据库文件导入新版本?

转载 作者:搜寻专家 更新时间:2023-10-30 23:39:18 24 4
gpt4 key购买 nike

在我的应用程序中,用户可以导出和导入他的数据库文件以备份数据。我更新了数据库版本并添加了更多新列。现在,用户可能备份版本 1 的旧数据库。在他尝试导入之后,他将得到类似“(1) 没有这样的列:(以及此处的列名)”之类的信息。导入后如何在旧数据库上调用 onUpgrade?我可以在加载的数据库上手动调用 onUpgrade 吗?我该如何解决?为了安全起见,我是否需要在更新应用程序后告诉用户再次进行新备份?有人知道吗?

我如何导入的代码:

// importing database
public boolean importDB(String path , File dbFile) {
try {
boolean isValid = checkDbIsValid(dbFile);
if(!isValid){
Toast.makeText(context, context.getResources().getString(R.string.errorFile),Toast.LENGTH_LONG).show();
return false;
}

//Last loaded file name will be the auto backup file destination
int lastIndexOf = path.lastIndexOf('/');
String loadedFileName = path.substring(lastIndexOf + 1);
new MySharedPreferences(context).putStringLastFileNameSent(loadedFileName);


FileInputStream fis = new FileInputStream(path);
//Destination to:
String outFileName = DATABASE_DIRECTORY + DbContract.DB_NAME;

OutputStream output = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
// Close the streams
output.flush();
output.close();
fis.close();

Toast.makeText(context, context.getResources().getString(R.string.importDatabaseSucceed),Toast.LENGTH_LONG).show();

return true;
} catch (Exception e) {
Toast.makeText(context,context.getResources().getString(R.string.errorImportDatabase),Toast.LENGTH_LONG).show();
e.printStackTrace();
return false;
}
}

这就是我如何检查数据库文件是否有效:

public static boolean checkDbIsValid(File db) {
SQLiteDatabase sqlDb;
Cursor cursor;
try {
sqlDb = SQLiteDatabase.openDatabase (db.getPath(), null, SQLiteDatabase.CONFLICT_NONE);
cursor = sqlDb.query(true,DbContract.TABLE_DAY, null, null, null, null, null, null, null);
for( String s : DbContract.ALL_COLUMN_KEYS_IN_TABLE_DAY){
cursor.getColumnIndexOrThrow(s);
}

//This make sure the user can import old database on new Version of table
try {
cursor = sqlDb.query(true,DbContract.TABLE_SETTING,null, null, null, null, null, null, null);
for( String s : DbContract.ALL_COLUMN_KEYS_IN_TABLE_SETTING_v2){
cursor.getColumnIndexOrThrow(s);
}
System.out.println("DATABASE LOADED FROM V2");
}catch (Exception fileNotV1){
System.out.println("ERROR FILE .. IS NOT V2");
try {
for( String s : DbContract.ALL_COLUMN_KEYS_IN_TABLE_SETTING_v1){
cursor.getColumnIndexOrThrow(s);
}

System.out.println("DATABASE LOADED FROM V1");
}catch (Exception fileNotV2){
System.out.println("ERROR FILE .. IS NOT V1");
return false;
}
}

if(DbContract.VERSION<sqlDb.getVersion() ){
return false;
}
sqlDb.close();
cursor.close();
} catch (IllegalArgumentException e) {
e.printStackTrace();
return false;
} catch (SQLiteException e) {
e.printStackTrace();
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}

公共(public)类 DbHelper 扩展了 SQLiteOpenHelper {

    public DbHelper(Context context) {
super(context, DbContract.DB_NAME, null, DbContract.VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DbContract.CREATE_TABLE_WORKS);
db.execSQL(DbContract.CREATE_TABLE_SETTING);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion == 1) {
updateToVersion2(db);
}
}

public void updateToVersion2(SQLiteDatabase db){
db.execSQL("ALTER TABLE " + DbContract.TABLE_SETTING + " ADD "
+ DbContract.COLUMN1 + " REAL DEFAULT 1");
db.execSQL("ALTER TABLE " + DbContract.TABLE_SETTING + " ADD "
+ DbContract.COLUMN0 + " REAL DEFAULT 0");
db.execSQL("ALTER TABLE " + DbContract.TABLE_SETTING + " ADD "
+ DbContract.COLUMN2 + " REAL DEFAULT 0");
}
}

最佳答案

如果您实际上是将 db 文件复制到存储或从存储中复制,那么理论上当您调用 getReadableDatabase()getWriteableDatabase() 时,它应该检查数据库版本并完成典型的升级流程,调用 onUpgrade()并为您提供新旧版本号。如果是这种情况,并且您正确地实现了 onUpgrade(),那么事情应该“正常工作”。

如果升级没有自动发生,在打开数据库后,您可以使用 getVersion() 自行检查数据库版本。并执行您喜欢的任何命令以手动升级架构。

编辑

为了让 onUpgrade() 自动运行,您需要使用 DbHelper 类打开数据库。否则,您需要一个 DbHelper 实例,以便您可以调用它的 onUpgrade() 方法并将它传递给您手动打开的 SQLiteDatabase

SQLiteDatabase sqlDb = ...;
DbHelper dbHelper = ...;
dbHelper.onUpgrade(sqlDb, sqlDb.getVersion(), DbContract.VERSION);

我不是特别喜欢你检查数据库文件是否有效的方法。您必须跟踪契约(Contract)中的每个模式版本并检查每个版本;这看起来很笨重。相反,如果您将文件复制到应用程序数据库目录中的临时文件中,使用 DbHelper 打开它(它应该尝试打开它),如果出现任何失败,您可以中止并删除该文件会怎么样?如果成功,您只需重命名文件并重新打开数据库即可。这可能就是我的处理方式。

关于android - 如何将旧版本的数据库文件导入新版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37041461/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com