Skip to content

Commit

Permalink
[sqflite] doc asset db and versioning
Browse files Browse the repository at this point in the history
  • Loading branch information
alextekartik committed Jul 2, 2024
1 parent ee2bdf6 commit 4f270a0
Showing 1 changed file with 78 additions and 0 deletions.
78 changes: 78 additions & 0 deletions sqflite/doc/opening_asset_db.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,84 @@ You might want to have a versioning strategy (not yet part of this project) to o
it changes in the build system or might also allow the user to modify the database (in this case you must copy it
first).

#### One simple solution

Since issues like 'I updated my asset database but the app still see the old one', I propose a simple solution.

One simple solution is to uses a versioning system using an incremental number. An asset version file stores this number. When the app starts,
it checks the version file currently existing on the file system, compare it to the one in the assets and decide
to copy the asset (the db and the version file) or not.

Let's assume that you have a version file named `db_version_num.txt` in your assets folder.
The content of the file is a single line with the version number.

`db_version_num.txt`
```txt
1
```

along with the database file `my_asset_database.db`

You could have the following code to copy the asset database only if the version number is different:
```dart
/// Copy the asset database if needed and open it.
///
/// It uses an external version file to keep track of the asset version.
Future<Database> copyIfNeededAndOpenAssetDatabase(
{required String databasesPath,
required String versionNumFilename,
required String dbFilename}) async {
var dbPath = join(databasesPath, dbFilename);
// First check the currently installed version
var versionNumFile = File(join(databasesPath, versionNumFilename));
var existingVersionNum = 0;
if (versionNumFile.existsSync()) {
existingVersionNum = int.parse(await versionNumFile.readAsString());
}
// Read the asset version
var assetVersionNum = int.parse(
(await rootBundle.loadString(url.join('assets', versionNumFilename))).trim());
// Compare them.
print('existing/asset: $existingVersionNum/$assetVersionNum');
// If needed, copy the asset database
if (existingVersionNum < assetVersionNum) {
print('copying new version $assetVersionNum');
// Make sure the parent directory exists
try {
await Directory(databasesPath).create(recursive: true);
} catch (_) {}
// Copy from asset
var data = await rootBundle.load(url.join('assets', dbFilename));
var bytes = Uint8List.sublistView(data);
// Write and flush the database bytes written
await File(dbPath).writeAsBytes(bytes, flush: true);
// Write and flush the version file
await versionNumFile.writeAsString('$assetVersionNum', flush: true);
}
var db = await openDatabase(dbPath);
return db;
}
```

You can then call this function to open the database:
```dart
var db = await copyIfNeededAndOpenAssetDatabase(
databasesPath: await getDatabasesPath(),
// The asset database filename.
dbFilename: 'my_asset_database.db',
// The version num.
versionNumFilename: 'db_version_num.txt');
```

When you want to force updating the asset database, you can simply increment the number in the version file (2, 3...).

### Web support

Check [opening_asset_db_web.md](../../packages_web/sqflite_common_ffi_web/doc/opening_asset_db_web.md) for web support.
Expand Down

0 comments on commit 4f270a0

Please sign in to comment.