Commit db39351
Changed files (5)
lib
model
test
model
export_import
lib/model/storage/db/config_dao.dart
@@ -1,5 +1,6 @@
import 'package:blood_pressure_app/model/export_import/legacy_column.dart';
import 'package:blood_pressure_app/model/storage/db/config_db.dart';
+import 'package:blood_pressure_app/model/storage/export_columns_store.dart';
import 'package:blood_pressure_app/model/storage/export_csv_settings_store.dart';
import 'package:blood_pressure_app/model/storage/export_pdf_settings_store.dart';
import 'package:blood_pressure_app/model/storage/export_settings_store.dart';
@@ -260,6 +261,54 @@ class ConfigDao {
conflictAlgorithm: ConflictAlgorithm.replace
);
}
+
+ /// Loads the profiles [ExportColumnsManager] object from the database.
+ ///
+ /// If any errors occur or the object is not present, a default one will be created. Changes in the object
+ /// will save to the database automatically (a listener gets attached).
+ ///
+ /// Changes to the database will not propagate to the object.
+ Future<ExportColumnsManager> loadExportColumnsManager(int profileID) async {
+ final dbEntry = await _configDB.database.query(
+ ConfigDB.exportColumnsTable,
+ columns: ['json'],
+ where: 'profile_id = ?',
+ whereArgs: [profileID]
+ );
+
+ late final ExportColumnsManager columnsManager;
+ if (dbEntry.isEmpty) {
+ columnsManager = ExportColumnsManager();
+ } else {
+ assert(dbEntry.length == 1, 'The profile_id should be unique.');
+ final json = dbEntry.first['json'];
+ if (json == null) {
+ columnsManager = ExportColumnsManager();
+ } else {
+ columnsManager = ExportColumnsManager.fromJson(json.toString());
+ }
+ }
+ _updateExportColumnsManager(profileID, columnsManager);
+ columnsManager.addListener(() {
+ _updateExportColumnsManager(profileID, columnsManager);
+ });
+ return columnsManager;
+ }
+
+ /// Update [ExportColumnsManager] for a profile in the database.
+ ///
+ /// Adds an entry if necessary.
+ Future<void> _updateExportColumnsManager(int profileID, ExportColumnsManager manager) async {
+ if (!_configDB.database.isOpen) return;
+ await _configDB.database.insert(
+ ConfigDB.exportColumnsTable,
+ {
+ 'profile_id': profileID,
+ 'json': manager.toJson()
+ },
+ conflictAlgorithm: ConflictAlgorithm.replace
+ );
+ }
/// Loads the current export columns from the database.
///
lib/model/storage/db/config_db.dart
@@ -76,10 +76,19 @@ class ConfigDB {
///
/// Format:
/// `CREATE TABLE exportStrings(internalColumnName STRING PRIMARY KEY, columnTitle STRING, formatPattern STRING)`
+ @Deprecated('removed after all usages are replaced by export_columns_store')
static const String exportStringsTable = 'exportStrings';
static const String _exportStringsTableCreationString =
'CREATE TABLE exportStrings(internalColumnName STRING PRIMARY KEY, columnTitle STRING, formatPattern STRING)';
+ /// Name of table of storing [ExportColumnsManager] objects
+ ///
+ /// Format:
+ /// `CREATE TABLE exportColumns(profile_id INTEGER PRIMARY KEY, json STRING)`
+ static const String exportColumnsTable = 'exportColumns';
+ static const String _exportColumnsTableCreationString =
+ 'CREATE TABLE exportColumns(profile_id INTEGER PRIMARY KEY, json STRING)';
+
late final Database _database;
/// [dbPath] is the path to the folder the database is in. When [dbPath] is left empty the default database file is
@@ -95,7 +104,7 @@ class ConfigDB {
onCreate: _onDBCreate,
onUpgrade: _onDBUpgrade,
// When increasing the version an update procedure from every other possible version is needed
- version: 2,
+ version: 3,
);
}
@@ -106,18 +115,23 @@ class ConfigDB {
await db.execute(_exportCsvSettingsTableCreationString);
await db.execute(_exportPdfSettingsTableCreationString);
await db.execute(_selectedIntervallStorageCreationString);
+ await db.execute(_exportColumnsTableCreationString);
}
FutureOr<void> _onDBUpgrade(Database db, int oldVersion, int newVersion) async {
// When adding more versions the upgrade procedure proposed in https://stackoverflow.com/a/75153875/21489239
// might be useful, to avoid duplicated code. Currently this would only lead to complexity without benefits.
- if (oldVersion == 1 && newVersion == 2) {
+ assert(newVersion == 3);
+ if (oldVersion == 1) { // TODO: migrate data, delete old table and test update
await db.execute(_settingsTableCreationString);
await db.execute(_exportSettingsTableCreationString);
await db.execute(_exportCsvSettingsTableCreationString);
await db.execute(_exportPdfSettingsTableCreationString);
await db.execute(_selectedIntervallStorageCreationString);
+ await db.execute(_exportColumnsTableCreationString);
await db.database.setVersion(2);
+ } else if (oldVersion == 2) {
+ await db.execute(_exportColumnsTableCreationString);
} else {
assert(false, 'Unexpected version upgrade from $oldVersion to $newVersion.');
}
lib/model/storage/export_columns_store.dart
@@ -37,6 +37,7 @@ class ExportColumnsManager extends ChangeNotifier {
void deleteUserColumn(String identifier) {
assert(_userColumns.containsKey(identifier), 'Don\'t call for non user columns');
_userColumns.remove(identifier);
+ notifyListeners();
}
String toJson() {
lib/main.dart
@@ -40,6 +40,7 @@ Future<Widget> _loadApp() async {
final csvExportSettings = await configDao.loadCsvExportSettings(0);
final pdfExportSettings = await configDao.loadPdfExportSettings(0);
final intervalStorageManager = await IntervallStoreManager.load(configDao, 0);
+ final exportColumnsManager = await configDao.loadExportColumnsManager(0);
await updateLegacySettings(settings, exportSettings, csvExportSettings, pdfExportSettings, intervalStorageManager);
@@ -55,6 +56,7 @@ Future<Widget> _loadApp() async {
ChangeNotifierProvider(create: (context) => csvExportSettings),
ChangeNotifierProvider(create: (context) => pdfExportSettings),
ChangeNotifierProvider(create: (context) => intervalStorageManager),
+ ChangeNotifierProvider(create: (context) => exportColumnsManager),
], child: const AppRoot());
}
test/model/export_import/columns_store_test.dart
@@ -16,7 +16,7 @@ void main() {
expect(manager.userColumns['test2']?.csvTitle, 'test2');
});
- test('should be restoreable from json', () async {
+ test('should be restoreable from json', () async { // TODO: consider moving to json_serialization_test and adding crash tests
final init = ExportColumnsManager();
init.addOrUpdate(UserColumn('test', 'test', '\$SYS'));
init.addOrUpdate(UserColumn('test2', 'test2', '234'));