J'essaye de sauvegarder une base de données de pièce par programme.
Pour cela, je copie simplement le fichier .sqlite
qui contient la base de données entière.
Mais, avant la copie, en raison du fait que la pièce dispose de la fonction {journalisation en écriture anticipée}, nous devons fermer la base de données pour que le fichier -shm
et le fichier -wal
soient fusionnés en un seul fichier .sqlite
. Comme indiqué ici
Je lance .close()
sur RoomDatabase
object:
Tout fonctionne bien avec la sauvegarde, MAIS, plus tard, lorsque j'essaie d'exécuter une requête INSERT
, j'obtiens cette erreur:
Android.database.sqlite.SQLiteException: no such table: room_table_modification_log (code 1)
Comment puis-je rouvrir correctement la base de données après l'avoir fermée?
PS: .isOpen()
sur un objet RoomDatabase
renvoie true
avant INSERT
Version de la salle: 1.1.1-rc1
Comment puis-je rouvrir correctement la base de données après l'avoir fermée?
Je suis désolé de ne pas avoir de réponse à cette question.
Mais vous n'avez pas besoin de fermer la base de données pour tout déplacer dans le fichier de base de données d'origine. Vous pouvez forcer un point de contrôle en utilisant le pragma wal_checkpoint.
Interrogez l'instruction suivante sur la base de données.
pragma wal_checkpoint(full)
This link peut éclairer un peu le sujet.
Pour répondre plus précisément à votre question, voici comment je sauvegarde la base de données de la salle dans l’une de mes applications.
RoomDatabase
. Dans mon cas, AppDatabase
fait référence à un singleton qui contient une logique pour la construction initiale de la base de données de salles. AppDatabase.getInstance(this).getDatabase()
obtient l'instance actuelle du singleton et sa classe de base de données actuelle, qui s'étend de RoomDatabase
. Cela appelle essentiellement RoomDatabase.close()
.FileUtils
dans ce cas, fait référence à commons-io
.if(id == R.id.action_save_db) {
int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(permission == PackageManager.PERMISSION_GRANTED) {
AppDatabase.getInstance(this).getDatabase().close();
File db = getDatabasePath("my-db");
File dbShm = new File(db.getParent(), "my-db-shm");
File dbWal = new File(db.getParent(), "my-db-wal");
File db2 = new File("/sdcard/", "my-db");
File dbShm2 = new File(db2.getParent(), "my-db-shm");
File dbWal2 = new File(db2.getParent(), "my-db-wal");
try {
FileUtils.copyFile(db, db2);
FileUtils.copyFile(dbShm, dbShm2);
FileUtils.copyFile(dbWal, dbWal2);
} catch (Exception e) {
Log.e("SAVEDB", e.toString());
}
} else {
Snackbar.make(mDrawer, "Please allow access to your storage", Snackbar.LENGTH_LONG)
.setAction("Allow", view -> ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, 0)).show();
}
} else if(id == R.id.action_load_db) {
int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if(permission == PackageManager.PERMISSION_GRANTED) {
AppDatabase.getInstance(this).getDatabase().close();
File db = new File("/sdcard/", "my-db");
File dbShm = new File(db.getParent(), "my-db-shm");
File dbWal = new File(db.getParent(), "my-db-wal");
File db2 = getDatabasePath("my-db");
File dbShm2 = new File(db2.getParent(), "my-db-shm");
File dbWal2 = new File(db2.getParent(), "my-db-wal");
try {
FileUtils.copyFile(db, db2);
FileUtils.copyFile(dbShm, dbShm2);
FileUtils.copyFile(dbWal, dbWal2);
} catch (Exception e) {
Loge("RESTOREDB", e.toString());
}
} else {
Snackbar.make(mDrawer, "Please allow access to your storage", Snackbar.LENGTH_LONG)
.setAction("Allow", view -> ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE
}, 0)).show();
}
}
Alternativement, vous pouvez toujours créer votre base de données Room tout en le forçant à ne pas utiliser la journalisation en écriture anticipée:
Room.databaseBuilder(context, db.class, dbName)
.setJournalMode(JournalMode.TRUNCATE)
.build();
Tout d'abord, la base de données doit être fermée pour appliquer les modifications du fichier "dbName.db-wal"
.
Ensuite, vous pouvez copier la base de données avec toutes les tables et les dernières modifications de données
AppDatabase appDatabase = AppDatabase.getAppDatabase(getApplicationContext());
appDatabase.close();