Skip to content

Commit df06cef

Browse files
committed
await for all setExercisesAndUnits calls
Not setting the "await" was causing the method to be run asynchronously which means that sometimes these would get called several times for the same exercise, which in turn would cause exercises to be written several times to the local db, polluting the exercise list, etc. etc. We increase the schemaVersion of the database because this causes all the cache tables to be dropped and re-created
1 parent a0beb07 commit df06cef

15 files changed

+53
-43
lines changed

lib/database/exercises/exercise_database.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class ExerciseDatabase extends _$ExerciseDatabase {
7878

7979
/// Note that this needs to be bumped if the JSON response from the server changes
8080
@override
81-
int get schemaVersion => 2;
81+
int get schemaVersion => 3;
8282

8383
/// There is not really a migration strategy. If we bump the version
8484
/// number, delete everything and recreate the new tables. The provider

lib/providers/exercises.dart

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,10 @@ class ExercisesProvider with ChangeNotifier {
310310
) async {
311311
Exercise exercise;
312312

313-
// TODO: this should be a .getSingleOrNull()!!! However, for some reason there
314-
// can be duplicates in the db. Perhaps a race condition so that two
315-
// entries are written at the same time or something?
313+
// NOTE: this should not be necessary anymore. We had a bug that would
314+
// create duplicate entries in the database and should be fixed now.
315+
// However, we keep it here for now to be on the safe side.
316+
// In the future this can be replaced by a .getSingleOrNull()
316317
final exerciseResult =
317318
await (database.select(database.exercises)..where((e) => e.id.equals(exerciseId))).get();
318319

@@ -321,9 +322,13 @@ class ExercisesProvider with ChangeNotifier {
321322
exerciseDb = exerciseResult.first;
322323
}
323324

325+
// Note that this shouldn't happen anymore...
326+
if (exerciseResult.length > 1) {
327+
_logger.warning('Found ${exerciseResult.length} entries for exercise $exerciseId in the db');
328+
}
329+
324330
// Exercise is already known locally
325331
if (exerciseDb != null) {
326-
// _logger.fine('Exercise $exerciseId found in local cache');
327332
final nextFetch = exerciseDb.lastFetched.add(const Duration(days: EXERCISE_CACHE_DAYS));
328333
exercise = Exercise.fromApiDataString(exerciseDb.data, _languages);
329334

@@ -455,15 +460,13 @@ class ExercisesProvider with ChangeNotifier {
455460

456461
/// Updates the exercise database with *all* the exercises from the server
457462
Future<void> updateExerciseCache(ExerciseDatabase database) async {
458-
final data = await baseProvider.fetch(
459-
baseProvider.makeUrl(exerciseInfoUrlPath, query: {'limit': '1000'}),
463+
final data = await baseProvider.fetchPaginated(
464+
baseProvider.makeUrl(exerciseInfoUrlPath, query: {'limit': '999'}),
460465
);
461-
462-
final List<dynamic> exercisesData = data['results'];
463-
exercises = exercisesData.map((e) => Exercise.fromApiDataJson(e, _languages)).toList();
466+
exercises = data.map((e) => Exercise.fromApiDataJson(e, _languages)).toList();
464467

465468
// Insert new entries and update ones that have been edited
466-
Future.forEach(exercisesData, (exerciseData) async {
469+
Future.forEach(data, (exerciseData) async {
467470
final exercise = await (database.select(database.exercises)
468471
..where((e) => e.id.equals(exerciseData['id'])))
469472
.getSingleOrNull();

lib/providers/routines.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import 'dart:convert';
2020

2121
import 'package:flutter/material.dart';
2222
import 'package:logging/logging.dart';
23-
import 'package:shared_preferences/shared_preferences.dart';
2423
import 'package:wger/exceptions/http_exception.dart';
2524
import 'package:wger/helpers/consts.dart';
2625
import 'package:wger/helpers/shared_preferences.dart';
@@ -199,7 +198,7 @@ class RoutinesProvider with ChangeNotifier {
199198
notifyListeners();
200199
}
201200

202-
void setExercisesAndUnits(List<DayData> entries) async {
201+
Future<void> setExercisesAndUnits(List<DayData> entries) async {
203202
for (final entry in entries) {
204203
for (final slot in entry.slots) {
205204
for (final setConfig in slot.setConfigs) {
@@ -276,10 +275,10 @@ class RoutinesProvider with ChangeNotifier {
276275
* note that setExercisesAndUnits modifies the list in-place
277276
*/
278277
final dayDataEntriesDisplay = dayData.map((entry) => DayData.fromJson(entry)).toList();
279-
setExercisesAndUnits(dayDataEntriesDisplay);
278+
await setExercisesAndUnits(dayDataEntriesDisplay);
280279

281280
final dayDataEntriesGym = dayDataGym.map((entry) => DayData.fromJson(entry)).toList();
282-
setExercisesAndUnits(dayDataEntriesGym);
281+
await setExercisesAndUnits(dayDataEntriesGym);
283282

284283
final sessionDataEntries =
285284
sessionData.map((entry) => WorkoutSessionApi.fromJson(entry)).toList();

test/core/settings_test.mocks.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ class MockExercisesProvider extends _i1.Mock implements _i17.ExercisesProvider {
176176

177177
@override
178178
Map<int, List<_i4.Exercise>> get exerciseByVariation => (super.noSuchMethod(
179-
Invocation.getter(#exerciseBasesByVariation),
179+
Invocation.getter(#exerciseByVariation),
180180
returnValue: <int, List<_i4.Exercise>>{},
181181
) as Map<int, List<_i4.Exercise>>);
182182

test/exercises/exercises_detail_widget_test.mocks.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class MockExercisesProvider extends _i1.Mock implements _i9.ExercisesProvider {
119119

120120
@override
121121
Map<int, List<_i4.Exercise>> get exerciseByVariation => (super.noSuchMethod(
122-
Invocation.getter(#exerciseBasesByVariation),
122+
Invocation.getter(#exerciseByVariation),
123123
returnValue: <int, List<_i4.Exercise>>{},
124124
) as Map<int, List<_i4.Exercise>>);
125125

test/workout/day_form_test.mocks.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,11 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
219219
) as _i13.Future<void>);
220220

221221
@override
222-
void setExercisesAndUnits(List<_i14.DayData>? entries) => super.noSuchMethod(
222+
_i13.Future<void> setExercisesAndUnits(List<_i14.DayData>? entries) => (super.noSuchMethod(
223223
Invocation.method(#setExercisesAndUnits, [entries]),
224-
returnValueForMissingStub: null,
225-
);
224+
returnValue: _i13.Future<void>.value(),
225+
returnValueForMissingStub: _i13.Future<void>.value(),
226+
) as _i13.Future<void>);
226227

227228
@override
228229
_i13.Future<_i5.Routine> fetchAndSetRoutineSparse(int? planId) => (super.noSuchMethod(

test/workout/gym_mode_screen_test.mocks.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ class MockExercisesProvider extends _i1.Mock implements _i12.ExercisesProvider {
248248

249249
@override
250250
Map<int, List<_i6.Exercise>> get exerciseByVariation => (super.noSuchMethod(
251-
Invocation.getter(#exerciseBasesByVariation),
251+
Invocation.getter(#exerciseByVariation),
252252
returnValue: <int, List<_i6.Exercise>>{},
253253
) as Map<int, List<_i6.Exercise>>);
254254

test/workout/repetition_unit_form_widget_test.mocks.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,11 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
219219
) as _i13.Future<void>);
220220

221221
@override
222-
void setExercisesAndUnits(List<_i14.DayData>? entries) => super.noSuchMethod(
222+
_i13.Future<void> setExercisesAndUnits(List<_i14.DayData>? entries) => (super.noSuchMethod(
223223
Invocation.method(#setExercisesAndUnits, [entries]),
224-
returnValueForMissingStub: null,
225-
);
224+
returnValue: _i13.Future<void>.value(),
225+
returnValueForMissingStub: _i13.Future<void>.value(),
226+
) as _i13.Future<void>);
226227

227228
@override
228229
_i13.Future<_i5.Routine> fetchAndSetRoutineSparse(int? planId) => (super.noSuchMethod(

test/workout/routine_edit_screen_test.mocks.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,11 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
219219
) as _i13.Future<void>);
220220

221221
@override
222-
void setExercisesAndUnits(List<_i14.DayData>? entries) => super.noSuchMethod(
222+
_i13.Future<void> setExercisesAndUnits(List<_i14.DayData>? entries) => (super.noSuchMethod(
223223
Invocation.method(#setExercisesAndUnits, [entries]),
224-
returnValueForMissingStub: null,
225-
);
224+
returnValue: _i13.Future<void>.value(),
225+
returnValueForMissingStub: _i13.Future<void>.value(),
226+
) as _i13.Future<void>);
226227

227228
@override
228229
_i13.Future<_i5.Routine> fetchAndSetRoutineSparse(int? planId) => (super.noSuchMethod(

test/workout/routine_edit_test.mocks.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,11 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider {
219219
) as _i13.Future<void>);
220220

221221
@override
222-
void setExercisesAndUnits(List<_i14.DayData>? entries) => super.noSuchMethod(
222+
_i13.Future<void> setExercisesAndUnits(List<_i14.DayData>? entries) => (super.noSuchMethod(
223223
Invocation.method(#setExercisesAndUnits, [entries]),
224-
returnValueForMissingStub: null,
225-
);
224+
returnValue: _i13.Future<void>.value(),
225+
returnValueForMissingStub: _i13.Future<void>.value(),
226+
) as _i13.Future<void>);
226227

227228
@override
228229
_i13.Future<_i5.Routine> fetchAndSetRoutineSparse(int? planId) => (super.noSuchMethod(

0 commit comments

Comments
 (0)