Reputation: 103
For my app I'm loading in a pre-populated database with some starter/default data for the user following this tutorial: https://github.com/tekartik/sqflite/blob/master/doc/opening_asset_db.md While debugging I'm going to be adding/deleting a bunch of test data and don't want to have to manually reset things every time I want to reload the app, so I have it load a fresh copy from the database every time.
For some reason however it isn't loading a new copy from the asset but rather still opening the existing modified database. I've checked the asset file and it's not been modified and the block that opens the existing database on the machine without deleting the previous version is not reached.
I'm not getting any errors in the console either.
Here's the code for initializing the database:
static Database _db;
Future<Database> get db async {
if(_db != null)
return _db;
_db = await initDb();
return _db;
}
bool get isInDebugMode {
bool inDebugMode = false;
assert(inDebugMode = true);
return inDebugMode;
}
//load database from existing db or copy pre-loaded db from assets
initDb() async {
//if in debug mode always load from asset file
//done to reload from asset when default values added to database asset
//and get rid of testing data
//since it would be annoying to have to delete the file on the emulator every time
debugPrint("initializing the db connection");
var databasesPath = await getDatabasesPath();
var path = join(databasesPath, "myDatabase.db");
if(isInDebugMode){
// delete existing if any
await deleteDatabase(path);
// Copy from asset
ByteData data = await rootBundle.load(join("assets", "assetDB.db"));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await new File(path).writeAsBytes(bytes);
// open the database
var db = await openDatabase(path, readOnly: false);
return db;
} else {
// try opening (will work if it exists)
Database db;
try {
db = await openDatabase(path, readOnly: false);
} catch (e) {
print("Error $e");
}
if (db == null) {
// Should happen only the first time you launch your application
print("Creating new copy from asset");
// Copy from asset
ByteData data = await rootBundle.load(join("assets", "assetDB.db"));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await new File(path).writeAsBytes(bytes);
//debugPrint(bytes.length.toString());
// open the database
db = await openDatabase(path, readOnly: true);
} else {
print("Opening existing database");
}
return db;
}
}
I should mention I'm not doing a hot reload when I load these changes and the block that initializes the new database from the asset for when in debug mode is reached.
Thanks for your help!
Upvotes: 8
Views: 14636
Reputation: 6239
Hotreload and plugins don't always play well together unless you take extra cares. In your case, you try to delete a database that might still be opened. So you should try to close it before deleting it. One solution is to hold a global reference to the database and closing it before calling deleteDatabase
Upvotes: 6