Commit c5c3421
Changed files (4)
lib
model
lib/model/storage/db/config_dao.dart
@@ -1,3 +1,4 @@
+import 'package:blood_pressure_app/model/export_options.dart';
import 'package:blood_pressure_app/model/storage/db/config_db.dart';
import 'package:blood_pressure_app/model/storage/settings_store.dart';
import 'package:sqflite/sqflite.dart';
@@ -50,4 +51,39 @@ class ConfigDao {
conflictAlgorithm: ConflictAlgorithm.replace
);
}
+
+ // TODO: test if custom export columns still work
+ Future<List<ExportColumn>> loadExportColumns() async {
+ final existingDbEntries = await _configDB.database.query(
+ ConfigDB.exportStringsTable,
+ columns: ['internalColumnName', 'columnTitle', 'formatPattern']
+ );
+ return [
+ for (final e in existingDbEntries)
+ ExportColumn(
+ internalName: e['internalColumnName'].toString(),
+ columnTitle: e['columnTitle'].toString(),
+ formatPattern: e['formatPattern'].toString()
+ ),
+ ];
+ }
+
+ Future<void> updateExportColumn(ExportColumn exportColumn) async {
+ await _configDB.database.insert(
+ ConfigDB.exportStringsTable,
+ {
+ 'internalColumnName': exportColumn.internalName,
+ 'columnTitle': exportColumn.columnTitle,
+ 'formatPattern': exportColumn.formatPattern
+ },
+ conflictAlgorithm: ConflictAlgorithm.replace
+ );
+ }
+
+ Future<void> deleteExportColumn(String internalName) async {
+ await _configDB.database.delete('exportStrings', where: 'internalColumnName = ?', whereArgs: [internalName]);
+ }
+
+
+ // TODO: ExportConfigurationModel
}
\ No newline at end of file
lib/model/storage/db/config_db.dart
@@ -15,7 +15,10 @@ class ConfigDB {
/// Name of the settings table.
///
- /// It is used to store json representations of [Settings] objects.
+ /// It is used to store json representations of [Settings] objects. Settings are saved as json, as there is no use
+ /// case where accessing individual fields for SQLs logic and matching is needed and the complexity of maintaining
+ /// different settings formats (export) is not worth it. Disk space doesn't play a role, as in most cases there will
+ /// be only one entry in the table.
///
/// Format:
/// `CREATE TABLE settings(profile_id: INTEGER PRIMARY KEY, settings_json: STRING)`
@@ -25,7 +28,10 @@ class ConfigDB {
'CREATE TABLE settings(profile_id: INTEGER PRIMARY KEY, settings_json: STRING)';
/// Name of the exportStrings table. It is used to store formats used in the [ExportConfigurationModel].
- static const String exportStrings = 'exportStrings';
+ ///
+ /// Format:
+ /// `CREATE TABLE exportStrings(internalColumnName STRING PRIMARY KEY, columnTitle STRING, formatPattern STRING)`
+ static const String exportStringsTable = 'exportStrings';
// instead of just changing this string when changing the format, _onDBUpgrade should be used.
static const String _exportStringsTableCreationString =
'CREATE TABLE exportStrings(internalColumnName STRING PRIMARY KEY, columnTitle STRING, formatPattern STRING)';
@@ -68,7 +74,7 @@ class ConfigDB {
///
/// [dbPath] is the path to the folder the database is in. When [dbPath] is left empty the default database file is
/// used. The [isFullPath] option tells the constructor not to add the default filename at the end of [dbPath].
- Future<ConfigDB> open({String? dbPath, bool isFullPath = false}) async {
+ static Future<ConfigDB> open({String? dbPath, bool isFullPath = false}) async {
final instance = ConfigDB._create();
await instance._asyncInit(dbPath, isFullPath);
return instance;
lib/model/export_options.dart
@@ -4,12 +4,11 @@ import 'package:blood_pressure_app/main.dart';
import 'package:blood_pressure_app/model/blood_pressure.dart';
import 'package:blood_pressure_app/model/export_import.dart';
import 'package:blood_pressure_app/model/settings_store.dart';
+import 'package:blood_pressure_app/model/storage/db/config_dao.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:function_tree/function_tree.dart';
import 'package:intl/intl.dart';
-import 'package:path/path.dart';
-import 'package:sqflite/sqflite.dart';
class ExportFields {
static const defaultCsv = ['timestampUnixMs', 'systolic', 'diastolic', 'pulse', 'notes', 'color'];
@@ -23,7 +22,7 @@ class ExportConfigurationModel {
final Settings settings;
final AppLocalizations localizations;
- late final Database _database;
+ final ConfigDao _configDao; // TODO: remove after #181 is complete
final List<ExportColumn> _availableFormats = [];
@@ -35,33 +34,16 @@ class ExportConfigurationModel {
('"My Heart" export', ['DATUM', 'SYSTOLE', 'DIASTOLE', 'PULS', 'Beschreibung', 'Tags', 'Gewicht', 'Sauerstoffsättigung']),
];
- ExportConfigurationModel._create(this.settings, this.localizations);
- Future<void> _asyncInit(String? dbPath, bool isFullPath) async {
- dbPath ??= await getDatabasesPath();
- if (dbPath != inMemoryDatabasePath && !isFullPath) {
- dbPath = join(dbPath, 'config.db');
- }
-
- _database = await openDatabase(
- dbPath,
- onCreate: (db, version) {
- return db.execute(
- 'CREATE TABLE exportStrings(internalColumnName STRING PRIMARY KEY, columnTitle STRING, formatPattern STRING)');
- },
- version: 1,
- );
+ ExportConfigurationModel._create(this.settings, this.localizations, this._configDao);
+ Future<void> _asyncInit() async {
- final existingDbEntries = await _database.rawQuery('SELECT * FROM exportStrings');
- for (final e in existingDbEntries) {
- _availableFormats.add(ExportColumn(internalName: e['internalColumnName'].toString(),
- columnTitle: e['columnTitle'].toString(), formatPattern: e['formatPattern'].toString()));
- }
_availableFormats.addAll(getDefaultFormates());
+ _availableFormats.addAll(await _configDao.loadExportColumns());
}
static Future<ExportConfigurationModel> get(Settings settings, AppLocalizations localizations, {String? dbPath, bool isFullPath = false}) async {
if (_instance == null) {
- _instance = ExportConfigurationModel._create(settings, localizations);
- await _instance!._asyncInit(dbPath, isFullPath);
+ _instance = ExportConfigurationModel._create(settings, localizations, globalConfigDao);
+ await _instance!._asyncInit();
}
return _instance!;
}
@@ -102,37 +84,16 @@ class ExportConfigurationModel {
ExportColumn(internalName: 'Sauerstoffsättigung', columnTitle: '"My Heart" export oxygen', formatPattern: r'0', editable: false, hidden: true),
];
- // TODO: testing
void addOrUpdate(ExportColumn format) {
- final existingEntries = _availableFormats.where((element) => element.internalName == format.internalName);
- if (existingEntries.isNotEmpty) {
- assert(existingEntries.length == 1);
- if (!existingEntries.first.editable) {
- assert(false, 'Attempted to update non editable field. While this doesn\'t cause any direct issues, it should not be made possible through the UI.');
- return;
- }
- _availableFormats.remove(existingEntries.first);
- _availableFormats.add(format);
- _database.update('exportStrings', {
- 'columnTitle': format.columnTitle,
- 'formatPattern': format.formatPattern
- }, where: 'internalColumnName = ?', whereArgs: [format.internalName]);
- } else {
- _availableFormats.add(format);
- _database.insert('exportStrings', {
- 'internalColumnName': format.internalName,
- 'columnTitle': format.columnTitle,
- 'formatPattern': format.formatPattern
- },);
- }
-
+ _availableFormats.add(format);
+ _configDao.updateExportColumn(format);
}
void delete(ExportColumn format) {
final existingEntries = _availableFormats.where((element) => (element.internalName == format.internalName) && element.editable);
assert(existingEntries.isNotEmpty, r"Tried to delete entry that doesn't exist or is not editable.");
_availableFormats.removeWhere((element) => element.internalName == format.internalName);
- _database.delete('exportStrings', where: 'internalColumnName = ?', whereArgs: [format.internalName]);
+ _configDao.deleteExportColumn(format.internalName);
}
UnmodifiableListView<ExportColumn> get availableFormats => UnmodifiableListView(_availableFormats);
lib/main.dart
@@ -1,12 +1,17 @@
import 'package:blood_pressure_app/model/blood_pressure.dart';
import 'package:blood_pressure_app/model/settings_store.dart';
+import 'package:blood_pressure_app/model/storage/db/config_dao.dart';
+import 'package:blood_pressure_app/model/storage/db/config_db.dart';
import 'package:blood_pressure_app/screens/home.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.dart';
+@Deprecated('see #182')
late AppLocalizations gLocalizations;
+@Deprecated('This should not be used for new code, but rather for migrating existing code.')
+late final ConfigDao globalConfigDao;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
@@ -14,6 +19,9 @@ void main() async {
final dataModel = await BloodPressureModel.create();
final settingsModel = await Settings.create();
+ // TODO:
+ globalConfigDao = ConfigDao(await ConfigDB.open());
+
// Reset the step size intervall to current on startup
settingsModel.changeStepSize(settingsModel.graphStepSize);