Commit fe5e146

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2024-06-18 12:57:36
remove unnecessary functionality from old bp model
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 6e3bc5c
Changed files (5)
app/lib/model/blood_pressure/model.dart
@@ -1,15 +1,13 @@
 import 'dart:async';
 import 'dart:convert';
+import 'dart:io';
 
 import 'package:blood_pressure_app/model/blood_pressure/needle_pin.dart';
 import 'package:blood_pressure_app/model/blood_pressure/record.dart';
-import 'package:blood_pressure_app/model/storage/storage.dart';
 import 'package:blood_pressure_app/screens/error_reporting_screen.dart';
-import 'package:blood_pressure_app/screens/subsettings/export_import/export_button_bar.dart';
 import 'package:collection/collection.dart';
 import 'package:flutter/material.dart';
 import 'package:path/path.dart';
-import 'package:provider/provider.dart';
 import 'package:sqflite/sqflite.dart';
 
 /// Model to access values in the measurement database.
@@ -20,34 +18,6 @@ class BloodPressureModel extends ChangeNotifier {
 
   late final Database _database;
 
-  Future<void> _asyncInit(String? dbPath, bool isFullPath) async {
-    dbPath ??= await getDatabasesPath();
-
-    if (dbPath != inMemoryDatabasePath && !isFullPath) {
-      dbPath = join(dbPath, 'blood_pressure.db');
-    }
-
-    // In case safer data loading is needed: finish this.
-    /*
-    String? backupPath;
-    if (dbPath != inMemoryDatabasePath) {
-      assert(_database.isUndefinedOrNull);
-      backupPath = join(Directory.systemTemp.path, 'blood_pressure_bu_${DateTime.now().millisecondsSinceEpoch}.db');
-      final copiedFile = File(dbPath).copy(backupPath);
-      copiedFile.onError((error, stackTrace) => null)
-    }
-    var preserveBackup = false;
-    */
-
-    _database = await openDatabase(
-      dbPath,
-      onCreate: _onDBCreate,
-      onUpgrade: _onDBUpgrade,
-      // When increasing the version an update procedure from every other possible version is needed
-      version: 2,
-    );
-  }
-
   FutureOr<void> _onDBCreate(Database db, int version) => db.execute('CREATE TABLE bloodPressureModel('
         'timestamp INTEGER(14) PRIMARY KEY,'
         'systolic INTEGER, diastolic INTEGER,'
@@ -70,85 +40,20 @@ class BloodPressureModel extends ChangeNotifier {
   ///
   /// [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].
-  static Future<BloodPressureModel> create({String? dbPath, bool isFullPath = false}) async {
+  static Future<BloodPressureModel?> create({String? dbPath, bool isFullPath = false}) async {
     final component = BloodPressureModel._create();
-    await component._asyncInit(dbPath, isFullPath);
-    return component;
-  }
-
-  /// Adds a new measurement at the correct chronological position in the List.
-  ///
-  /// This is not suitable for user inputs, as in this case export is needed as
-  /// well. Consider using [BloodPressureModel.addAndExport] instead.
-  Future<void> add(BloodPressureRecord measurement) async {
-    if (!_database.isOpen) return;
-    final existing = await _database.query('bloodPressureModel',
-        where: 'timestamp = ?', whereArgs: [measurement.creationTime.millisecondsSinceEpoch],);
-    if (existing.isNotEmpty) {
-      await _database.update(
-          'bloodPressureModel',
-          {
-            'systolic': measurement.systolic,
-            'diastolic': measurement.diastolic,
-            'pulse': measurement.pulse,
-            'notes': measurement.notes,
-            'needlePin': jsonEncode(measurement.needlePin?.toMap()),
-          },
-          where: 'timestamp = ?',
-          whereArgs: [measurement.creationTime.millisecondsSinceEpoch],);
-    } else {
-      await _database.insert('bloodPressureModel', {
-        'timestamp': measurement.creationTime.millisecondsSinceEpoch,
-        'systolic': measurement.systolic,
-        'diastolic': measurement.diastolic,
-        'pulse': measurement.pulse,
-        'notes': measurement.notes,
-        'needlePin': jsonEncode(measurement.needlePin?.toMap()),
-      });
-    }
-    notifyListeners();
-  }
-
-  /// Convenience wrapper for [add] that follows best practices.
-  ///
-  /// This ensures no timeout occurs by waiting for operations to finish and
-  /// exports in case the [context] is provided and the option in export
-  /// settings is active.
-  Future<void> addAll(
-    List<BloodPressureRecord> measurements,
-    BuildContext? context,
-  ) async {
-    for (final measurement in measurements) {
-      await add(measurement);
-    }
-
-    if (context == null || !context.mounted) return;
-    final exportSettings = Provider.of<ExportSettings>(context, listen: false);
-    if (exportSettings.exportAfterEveryEntry) {
-      performExport(context);
-    }
-  }
-
-  /// Adds a measurement to the model and tries to export all measurements, if [ExportSettings.exportAfterEveryEntry] is
-  /// true.
-  Future<void> addAndExport(BuildContext context, BloodPressureRecord record) async {
-    await add(record);
+    dbPath ??= await getDatabasesPath();
 
-    if (!context.mounted) return;
-    final exportSettings = Provider.of<ExportSettings>(context, listen: false);
-    if (exportSettings.exportAfterEveryEntry) {
-      performExport(context);
+    if (dbPath != inMemoryDatabasePath && !isFullPath) {
+      dbPath = join(dbPath, 'blood_pressure.db');
     }
-  }
-
-  /// Try to remove the measurement at a specific timestamp from the database.
-  ///
-  /// When no measurement at that time exists, the operation won't fail and
-  /// listeners will get notified anyways.
-  Future<void> delete(DateTime timestamp) async {
-    if (!_database.isOpen) return;
-    _database.delete('bloodPressureModel', where: 'timestamp = ?', whereArgs: [timestamp.millisecondsSinceEpoch]);
-    notifyListeners();
+    if (!File(dbPath).existsSync()) return null;
+    component._database = await openDatabase(
+      dbPath,
+      onUpgrade: component._onDBUpgrade,
+      version: 2,
+    );
+    return component;
   }
 
   /// Returns all recordings in saved in a range in ascending order
app/test/model/bood_pressure_test.dart
@@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart';
 import 'package:path/path.dart';
 import 'package:sqflite_common_ffi/sqflite_ffi.dart';
 
-import '../ram_only_implementations.dart';
 
 void main() {
   group('BloodPressureRecord', () {
@@ -30,123 +29,11 @@ void main() {
       databaseFactory = databaseFactoryFfi;
     });
 
-    test('should initialize', () async {
-      expect(() async {
-        await BloodPressureModel.create(dbPath: join(inMemoryDatabasePath, 'BPMShouldInit.db'));
-      }, returnsNormally,);
-    });
-    test('should start empty', () async {
-      final m = await BloodPressureModel.create(dbPath: join(inMemoryDatabasePath, 'BPMShouldStartEmpty.db'));
-
-      expect((await m.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(1), DateTime.now())).length, 0);
-    });
-
-    test('should notify when adding entries', () async {
-      final m = await BloodPressureModel.create(dbPath: join(inMemoryDatabasePath, 'BPMShouldNotifyWhenAdding.db'));
-
-      int listenerCalls = 0;
-      m.addListener(() {
-        listenerCalls++;
-      });
-
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 0, 0, 0, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 0, 0, 0, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(2), 0, 0, 0, ''));
-
-      expect(listenerCalls, 3);
-    });
-
-    test('should return entries as added', () async {
-      final m = await BloodPressureModel.create(dbPath: join(inMemoryDatabasePath, 'BPMShouldReturnAddedEntries.db'));
-
-      final r = BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(31415926), -172, 10000, 0,
-          '((V⍳V)=⍳⍴V)/V←,V    ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈๏ แผ่นดินฮั่นเABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвг, \n \t д∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა',);
-      m.addListener(() async {
-        final res = (await m.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(1), DateTime.now())).first;
-        expect(res, isNotNull);
-        expect(res.creationTime, r.creationTime);
-        expect(res.systolic, r.systolic);
-        expect(res.diastolic, r.diastolic);
-        expect(res.pulse, r.pulse);
-        expect(res.notes, r.notes);
-        return;
-      });
-
-      m.add(r);
-    });
-
-    test('should save and load between objects/sessions', () async {
-      final m = await BloodPressureModel.create(dbPath: join(inMemoryDatabasePath, 'BPMShouldPersist.db'));
-      final r = BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(31415926), -172, 10000, 0,
-          '((V⍳V)=⍳⍴V)/V←,V    ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈๏ แผ่นดินฮั่นเABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвг, \n \t д∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა',);
-      await m.add(r);
-
-      final m2 = await BloodPressureModel.create(dbPath: join(inMemoryDatabasePath, 'BPMShouldPersist.db'));
-      final res = (await m2.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(1), DateTime.now())).first;
-
-      expect(res.creationTime, r.creationTime);
-      expect(res.systolic, r.systolic);
-      expect(res.diastolic, r.diastolic);
-      expect(res.pulse, r.pulse);
-      expect(res.notes, r.notes);
-    });
-
-    test('should delete', () async {
-      final m = await BloodPressureModel.create(dbPath: join(inMemoryDatabasePath, 'BPMShouldDelete.db'));
-
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(758934), 123, 87, 65, ';)'));
-      expect((await m.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(1), DateTime.now())).length, 1);
-      expect((await m.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(1), DateTime.now())).length, 1);
-
-      await m.delete(DateTime.fromMillisecondsSinceEpoch(758934));
-
-      expect((await m.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(1), DateTime.now())).length, 0);
-      expect((await m.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(1), DateTime.now())).length, 0);
-    });
-  });
-
-  group('RamBloodPressureModel should behave like BloodPressureModel', () {
-    test('should initialize', () async {
-      expect(() async => RamBloodPressureModel(), returnsNormally);
-    });
-
-    test('should start empty', () async {
-      final m = RamBloodPressureModel();
-      expect((await m.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(1), DateTime.now())).length, 0);
-    });
-
-    test('should notify when adding entries', () async {
-      final m = RamBloodPressureModel();
-
-      int listenerCalls = 0;
-      m.addListener(() {
-        listenerCalls++;
-      });
-
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 0, 0, 0, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1), 0, 0, 0, ''));
-      await m.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(2), 0, 0, 0, ''));
-
-      expect(listenerCalls, 3);
-    });
-
-    test('should return entries as added', () async {
-      final m = RamBloodPressureModel();
-
-      final r = BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(31415926), -172, 10000, 0,
-          '((V⍳V)=⍳⍴V)/V←,V    ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈๏ แผ่นดินฮั่นเABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвг, \n \t д∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა',);
-      m.addListener(() async {
-        final res = (await m.getInTimeRange(DateTime.fromMillisecondsSinceEpoch(1), DateTime.now())).first;
-        expect(res, isNotNull);
-        expect(res.creationTime, r.creationTime);
-        expect(res.systolic, r.systolic);
-        expect(res.diastolic, r.diastolic);
-        expect(res.pulse, r.pulse);
-        expect(res.notes, r.notes);
-        return;
-      });
-
-      m.add(r);
+    test("Doesn't create new models", () async {
+      final model = await BloodPressureModel
+        .create(dbPath: join(inMemoryDatabasePath, 'BPMShouldInit.db'));
+      expect(model, isNull);
     });
+    // TODO: test loading with db files from older versions
   });
 }
app/test/ui/components/util.dart
@@ -1,5 +1,3 @@
-import 'package:blood_pressure_app/model/blood_pressure/medicine/intake_history.dart';
-import 'package:blood_pressure_app/model/blood_pressure/model.dart';
 import 'package:blood_pressure_app/model/storage/storage.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -9,8 +7,6 @@ import 'package:health_data_store/health_data_store.dart';
 import 'package:provider/provider.dart';
 import 'package:sqflite_common_ffi/sqflite_ffi.dart';
 
-import '../../ram_only_implementations.dart';
-
 /// Create a root material widget with localizations.
 Widget materialApp(Widget child) => MaterialApp(
   localizationsDelegates: AppLocalizations.localizationsDelegates,
@@ -18,59 +14,8 @@ Widget materialApp(Widget child) => MaterialApp(
   home: Scaffold(body:child),
 );
 
-/// Create a root material widget with localizations and all providers but
-/// without a app root.
-@Deprecated('replace with newAppBase')
-Future<Widget> appBase(Widget child, {
-  Settings? settings,
-  ExportSettings? exportSettings,
-  CsvExportSettings? csvExportSettings,
-  PdfExportSettings? pdfExportSettings,
-  IntervallStoreManager? intervallStoreManager,
-  IntakeHistory? intakeHistory,
-  BloodPressureModel? model,
-}) async {
-  // TODO: migrate arguments
-  final db = await _getHealthDateStore();
-
-  final meds = settings?.medications.map((e) => Medicine(
-    designation: e.designation,
-    color: e.color.value,
-    dosis: e.defaultDosis != null ? Weight.mg(e.defaultDosis!) : null),
-  );
-  final medRepo = db.medRepo;
-  meds?.forEach(medRepo.add);
-
-  final intakeRepo = db.intakeRepo;
-  for (final e in intakeHistory?.getIntakes(DateTimeRange(
-      start: DateTime.fromMillisecondsSinceEpoch(0),
-      end: DateTime.fromMillisecondsSinceEpoch(999999999999))) ?? []) {
-    expect(meds, isNotNull);
-    expect(meds, isNotEmpty);
-    final med = meds!.firstWhere((e2) => e2.designation == e.medicine.designation);
-    intakeRepo.add(MedicineIntake(
-      time: e.timestamp,
-      dosis: Weight.mg(e.dosis),
-      medicine: med,
-    ));
-  }
-
-  return Provider<BloodPressureModel>(
-    create: (_) => model ?? RamBloodPressureModel(),
-    child: await newAppBase(child,
-      settings: settings,
-      exportSettings: exportSettings,
-      csvExportSettings: csvExportSettings,
-      pdfExportSettings: pdfExportSettings,
-      intervallStoreManager: intervallStoreManager,
-      medRepo: medRepo,
-      intakeRepo: intakeRepo,
-  ),);
-
-  // TODO: bpRepo
-}
 /// Creates a the same App as the main method.
-Future<Widget> newAppBase(Widget child,  {
+Future<Widget> appBase(Widget child,  {
   Settings? settings,
   ExportSettings? exportSettings,
   CsvExportSettings? csvExportSettings,
@@ -124,7 +69,7 @@ Future<Widget> appBaseWithData(Widget child,  {
   final medRepo = db.medRepo;
   final intakeRepo = db.intakeRepo;
 
-  return newAppBase(
+  return appBase(
     child,
     settings: settings,
     exportSettings: exportSettings,
app/test/ui/navigation_test.dart
@@ -1,109 +0,0 @@
-import 'package:blood_pressure_app/components/dialoges/add_measurement_dialoge.dart';
-import 'package:blood_pressure_app/components/dialoges/enter_timeformat_dialoge.dart';
-import 'package:blood_pressure_app/main.dart';
-import 'package:blood_pressure_app/model/blood_pressure/medicine/intake_history.dart';
-import 'package:blood_pressure_app/model/blood_pressure/model.dart';
-import 'package:blood_pressure_app/model/storage/db/config_dao.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';
-import 'package:blood_pressure_app/model/storage/intervall_store.dart';
-import 'package:blood_pressure_app/model/storage/settings_store.dart';
-import 'package:blood_pressure_app/screens/settings_screen.dart';
-import 'package:blood_pressure_app/screens/statistics_screen.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_gen/gen_l10n/app_localizations.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'components/util.dart';
-
-void main() {
-  group('start page', () {
-    testWidgets('should navigate to add entry page', (tester) async {
-      await _pumpAppRoot(tester);
-      expect(find.byIcon(Icons.add), findsOneWidget);
-      await tester.tap(find.byIcon(Icons.add));
-      await tester.pumpAndSettle();
-
-      expect(find.byType(AddEntryDialoge), findsOneWidget);
-    }, timeout: const Timeout(Duration(seconds: 4)),);
-    testWidgets('should navigate to settings page', (tester) async {
-      await _pumpAppRoot(tester);
-      expect(find.byIcon(Icons.settings), findsOneWidget);
-      await tester.tap(find.byIcon(Icons.settings));
-      await tester.pumpAndSettle();
-
-      expect(find.byType(SettingsPage), findsOneWidget);
-    });
-    testWidgets('should navigate to stats page', (tester) async {
-      await _pumpAppRoot(tester);
-      expect(find.byIcon(Icons.insights), findsOneWidget);
-      await tester.tap(find.byIcon(Icons.insights));
-      await tester.pumpAndSettle();
-
-      expect(find.byType(StatisticsScreen), findsOneWidget);
-    });
-  });
-  group('settings page', () {
-    testWidgets('open EnterTimeFormatScreen', (tester) async {
-      await _pumpAppRoot(tester);
-      expect(find.byIcon(Icons.settings), findsOneWidget);
-      await tester.tap(find.byIcon(Icons.settings));
-      await tester.pumpAndSettle();
-
-      expect(find.byType(SettingsPage), findsOneWidget);
-      expect(find.byType(EnterTimeFormatDialoge), findsNothing);
-      final localizations = await AppLocalizations.delegate.load(const Locale('en'));
-      expect(find.text(localizations.enterTimeFormatScreen), findsOneWidget);
-      await tester.tap(find.text(localizations.enterTimeFormatScreen));
-      await tester.pumpAndSettle();
-
-      expect(find.byType(EnterTimeFormatDialoge), findsOneWidget);
-    });
-    // TODO: ...
-  });
-}
-
-/// Creates a the same App as the main method.
-Future<void> _pumpAppRoot(WidgetTester tester, {
-  Settings? settings,
-  ExportSettings? exportSettings,
-  CsvExportSettings? csvExportSettings,
-  PdfExportSettings? pdfExportSettings,
-  IntervallStoreManager? intervallStoreManager,
-  IntakeHistory? intakeHistory,
-  BloodPressureModel? model,
-}) async {
-  await tester.pumpWidget(await appBase(const AppRoot(),
-    settings: settings,
-    exportSettings: exportSettings,
-    csvExportSettings: csvExportSettings,
-    pdfExportSettings: pdfExportSettings,
-    intervallStoreManager: intervallStoreManager,
-    intakeHistory: intakeHistory,
-    model: model,
-  ),);
-}
-
-class MockConfigDao implements ConfigDao {
-  @override
-  Future<CsvExportSettings> loadCsvExportSettings(int profileID) async => CsvExportSettings();
-
-  @override
-  Future<ExportSettings> loadExportSettings(int profileID) async => ExportSettings();
-
-  @override
-  Future<IntervallStorage> loadIntervallStorage(int profileID, int storageID) async => IntervallStorage();
-
-  @override
-  Future<PdfExportSettings> loadPdfExportSettings(int profileID) async => PdfExportSettings();
-
-  @override
-  Future<Settings> loadSettings(int profileID) async => Settings();
-
-  void reset() {}
-
-  @override
-  Future<ExportColumnsManager> loadExportColumnsManager(int profileID) async => ExportColumnsManager();
-}
app/test/ram_only_implementations.dart
@@ -1,57 +0,0 @@
-import 'dart:collection';
-
-import 'package:blood_pressure_app/model/blood_pressure/model.dart';
-import 'package:blood_pressure_app/model/blood_pressure/record.dart';
-import 'package:flutter/material.dart';
-
-class RamBloodPressureModel extends ChangeNotifier implements BloodPressureModel {
-  final List<BloodPressureRecord> _records = [];
-  
-  static RamBloodPressureModel fromEntries(List<BloodPressureRecord> records) {
-    final m = RamBloodPressureModel();
-    for (final e in records) {
-      m.add(e);
-    }
-    return m;
-  }
-
-  @override
-  Future<void> add(BloodPressureRecord measurement) async {
-    _records.add(measurement);
-    notifyListeners();
-  }
-
-  @override
-  Future<void> delete(DateTime timestamp) async {
-    _records.removeWhere((element) => element.creationTime.isAtSameMomentAs(timestamp));
-  }
-
-  @override
-  Future<UnmodifiableListView<BloodPressureRecord>> getInTimeRange(DateTime from, DateTime to) async {
-    final List<BloodPressureRecord> recordsInTime = [];
-    for (final e in _records) {
-      if (e.creationTime.isAfter(from) && e.creationTime.isBefore(to)) {
-        recordsInTime.add(e);
-      }
-    }
-    return UnmodifiableListView(recordsInTime);
-  }
-
-  @override
-  Future<UnmodifiableListView<BloodPressureRecord>> get all async => UnmodifiableListView(_records);
-
-  @override
-  Future<void> close() async {}
-
-  @override
-  Future<void> addAndExport(BuildContext context, BloodPressureRecord record) async {
-    add(record);
-  }
-
-  @override
-  Future<void> addAll(List<BloodPressureRecord> measurements, BuildContext? context) async {
-    for (final m in measurements) {
-      add(m);
-    }
-  }
-}