Commit 9929539
Changed files (5)
app
lib
features
export_import
health_data_store
health_data_store/lib/src/database_manager.dart
@@ -27,22 +27,22 @@ class DatabaseManager {
///
/// If [db] doesn't contain a scheme or contains an outdated scheme, one will
/// be created.
- static Future<DatabaseManager> load(Database db) async {
+ static Future<DatabaseManager> load(Database db, [bool isReadOnly = false]) async {
final dbMngr = DatabaseManager._create(db);
final tables = await dbMngr._db.query('"main".sqlite_master');
- if (tables.length <= 3) {
+ if (tables.length <= 3 && !isReadOnly) {
// DB has just been created, no version yet.
await dbMngr._db.setVersion(2);
}
- if (await dbMngr._db.getVersion() < 3) {
+ if (!isReadOnly && await dbMngr._db.getVersion() < 3) {
await dbMngr._setUpTables();
await dbMngr._db.setVersion(3);
}
// When updating the schema the update steps are maintained for ensured
// compatability.
-
+ // TODO: develop strategy for loading older db versions as read only.
return dbMngr;
}
health_data_store/lib/src/health_data_store.dart
@@ -9,6 +9,7 @@ import 'package:health_data_store/src/repositories/medicine_repository.dart';
import 'package:health_data_store/src/repositories/medicine_repository_impl.dart';
import 'package:health_data_store/src/repositories/note_repository.dart';
import 'package:health_data_store/src/repositories/note_repository_impl.dart';
+import 'package:health_data_store/src/repositories/repository.dart';
import 'package:sqflite_common/sqflite.dart';
/// Factory class for objects that provide access to the health database.
@@ -30,11 +31,17 @@ class HealthDataStore {
/// decrease database performance in the first milliseconds after being
/// returned. This is done to improve performance while interacting with the
/// database.
- static Future<HealthDataStore> load(Database db) async {
+ ///
+ /// When loading a database as [isReadOnly] no automatic changes to the
+ /// database are made. It will however not protect you from manually
+ /// attempting to modify the stored contents (e.g. in [Repository] methods).
+ static Future<HealthDataStore> load(Database db, [bool isReadOnly = false]) async {
// TODO: loading readOnly dbs
assert(db.isOpen);
final mngr = await DatabaseManager.load(db);
- unawaited(mngr.performCleanup());
+ if (!isReadOnly) {
+ unawaited(mngr.performCleanup());
+ }
return HealthDataStore._create(mngr);
}
health_data_store/test/src/database_manager_test.dart
@@ -1,6 +1,5 @@
import 'package:health_data_store/src/database_manager.dart';
import 'package:health_data_store/src/extensions/datetime_seconds.dart';
-import 'package:sqflite_common/sqflite.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:test/test.dart';
@@ -222,4 +221,5 @@ void main() {
}
Future<DatabaseManager> mockDBManager() async => DatabaseManager.load(
- await openDatabase(inMemoryDatabasePath));
+ await openDatabase(inMemoryDatabasePath),
+);
health_data_store/test/src/health_data_store_test.dart
@@ -36,4 +36,10 @@ void main() {
expect(data.length, 1);
expect(data, contains(r));
});
+ test('should not modify read-only databases', () async {
+ final db = await openReadOnlyDatabase(inMemoryDatabasePath);
+ await HealthDataStore.load(db, true);
+ await db.close();
+ // Potential unawaited async exceptions would cause the method to fail.
+ });
}