Commit a0cac39

derdilla <derdilla06@gmail.com>
2023-05-01 05:20:01
save to db
1 parent 9fe979c
Changed files (2)
lib/components/measurement_list.dart
@@ -10,10 +10,10 @@ class MeasurementList extends StatelessWidget {
 
   MeasurementList(BuildContext context, {super.key}) {
     if (MediaQuery.of(context).size.width < 1000) {
-      _tableElementsSizes = [30,10,10,10,30];
+      _tableElementsSizes = [33,9,9,9,30];
       _sideFlex = 1;
     } else {
-      _tableElementsSizes = [9,7,7,7,60];
+      _tableElementsSizes = [20,5,5,5,60];
       _sideFlex = 5;
     }
   }
lib/model/blood_pressure.dart
@@ -5,8 +5,10 @@ import 'package:sqflite_common_ffi/sqflite_ffi.dart';
 import 'package:sqflite/sqflite.dart';
 
 class BloodPressureModel extends ChangeNotifier {
-  final List<BloodPressureRecord> _allMeasurements = [];
+  static const maxEntries = 2E64; // https://www.sqlite.org/limits.html Nr.13
   late final Database _database;
+  List<BloodPressureRecord> _allMeasurements = [];
+  var _cacheCount = 100; // how many db entries are cached on default
 
   BloodPressureModel._create();
   Future<void> _asyncInit() async {
@@ -14,14 +16,14 @@ class BloodPressureModel extends ChangeNotifier {
       join(await getDatabasesPath(), 'blood_pressure.db'),
       // runs when the database is first created
       onCreate: (db, version) {
-        return db.execute('CREATE TABLE bloodPressureModel(timestamp INTEGER(14) PRIMARY KEY, systolic INTEGER, diastolic INTEGER, pulse INTEGER, notes STRING)',
-      );
-    },
-    version: 1,
+        return db.execute('CREATE TABLE bloodPressureModel(timestamp INTEGER(14) PRIMARY KEY, systolic INTEGER, diastolic INTEGER, pulse INTEGER, notes STRING)');
+      },
+      version: 1,
     );
+    await _cacheLast();
   }
   // factory method, to allow for async contructor
-  static Future<BloodPressureModel> create() async{
+  static Future<BloodPressureModel> create() async {
     final component = BloodPressureModel._create();
     await component._asyncInit();
     return component;
@@ -30,49 +32,57 @@ class BloodPressureModel extends ChangeNotifier {
   // All measurements (might get slow after some time)
   UnmodifiableListView<BloodPressureRecord> get allMeasurements => UnmodifiableListView(_allMeasurements);
 
+  Future<void> _cacheLast() async {
+    var dbEntries = await _database.query('bloodPressureModel',
+        orderBy: 'timestamp DESC', limit: _cacheCount); // descending
+    // syncronous part
+    _allMeasurements = [];
+    for (var e in dbEntries) {
+      _allMeasurements.add(BloodPressureRecord(
+        DateTime.fromMillisecondsSinceEpoch(e['timestamp']as int), 
+        e['systolic'] as int, 
+        e['diastolic'] as int, 
+        e['pulse'] as int, 
+        e['notes'] as String));
+    }
+    
+    notifyListeners();
+  }
+
   /// Adds a new measurement at the correct chronological position in the List.
-  /// If the measurement was taken at exactly the same time as an existing
-  /// measurement, the existing measurement gets replaced.
   Future<void> add(BloodPressureRecord measurement) async {
     assert(_database.isOpen);
-    final existingMeasurements = await _database.query('bloodPressureModel',
-          columns: ['timestamp'],
-          orderBy: 'timestamp'
-    );
-    print(existingMeasurements);
 
-    if (_allMeasurements.isNotEmpty &&
-        _allMeasurements.last.compareTo(measurement) >= 0) {
-      // naive approach; change algorithm
-      for (int i = 0; i < _allMeasurements.length; i++) {
-        if (_allMeasurements[i].compareTo(measurement) == 0) {
-          _allMeasurements[i] = measurement;
-        } else if (_allMeasurements[i].compareTo(measurement) > 0) {
-          _allMeasurements.insert(i, measurement);
-        }
-      }
-    } else {
-        _allMeasurements.add(measurement);
-        _database.rawInsert('INSERT INTO bloodPressureModel(timestamp, systolic, diastolic, pulse, notes) VALUES (?, ?, ?, ?, ?)', [
-            measurement.creationTime.millisecondsSinceEpoch,
-            measurement.systolic,
-            measurement.diastolic,
-            measurement.pulse,
-            measurement.notes]);
-    }
-    notifyListeners();
+    _database.rawInsert('INSERT INTO bloodPressureModel(timestamp, systolic, diastolic, pulse, notes) VALUES (?, ?, ?, ?, ?)', [
+      measurement.creationTime.millisecondsSinceEpoch,
+      measurement.systolic,
+      measurement.diastolic,
+      measurement.pulse,
+      measurement.notes]);
+
+    _cacheLast();
   }
 
-  /// Returns the
+  /// Returns the last x BloodPressureRecords from new to old
+  /// caches new ones if necessary
   UnmodifiableListView<BloodPressureRecord> getLastX(int count) {
-    final List<BloodPressureRecord> lastMeasurements = [];
-    // example length = 30 (last index  29) count = 5 => 29, 28, 27, 26, 25 (5)
-    for (int i = _allMeasurements.length-1; i>=_allMeasurements.length-count &&
-            i>=0; i--) {
-      lastMeasurements.add(_allMeasurements[i]); // new list gets sorted high to low
+    List<BloodPressureRecord> lastMeasurements = [];
+    
+    // fetch more if needed
+    if (count > _cacheCount) {
+      _cacheCount = count;
+      _cacheLast();
+    } else if (count == _cacheCount) { // small optimization
+      lastMeasurements = _allMeasurements;
+    } else {
+      for (int i = 0; (i<count && i<_allMeasurements.length); i++) {
+        lastMeasurements.add(_allMeasurements[i]);
+      }
     }
+    
     return UnmodifiableListView(lastMeasurements);
   }
+  
 
 /* TODO:
   - bool deleteFromTime (timestamp)