feat(exécution): dernière performance et meilleur score par exercice (ticket #81)
Ajoute la migration Drift v17 (colonne sourceExerciseIdSnapshot sur workout_history_set_results et workout_history_step_results, index associés), le port ExercisePerformanceReferenceRepository et son implémentation Drift, et le use case ExercisePerformanceReferenceUseCase (dernière performance + meilleur score par métrique active pour un exercice donné). Validé GO par Main : dart analyze propre (1 lint mineur de style), 178 tests (4 échecs préexistants sans rapport avec ce lot). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -13,6 +13,7 @@ abstract interface class AppDependencies {
|
||||
ActiveExerciseStepUseCases get activeExerciseStepUseCases;
|
||||
CloseWorkoutSessionUseCase get closeWorkoutSessionUseCase;
|
||||
WorkoutHistoryUseCases get workoutHistoryUseCases;
|
||||
ExercisePerformanceReferenceUseCase get exercisePerformanceReferenceUseCase;
|
||||
SyncUseCases get syncUseCases;
|
||||
ShareUseCases get shareUseCases;
|
||||
}
|
||||
@ -29,6 +30,7 @@ final class AppBootstrap implements AppDependencies {
|
||||
required this.activeExerciseStepUseCases,
|
||||
required this.closeWorkoutSessionUseCase,
|
||||
required this.workoutHistoryUseCases,
|
||||
required this.exercisePerformanceReferenceUseCase,
|
||||
required this.syncUseCases,
|
||||
required this.shareUseCases,
|
||||
required this.syncGateway,
|
||||
@ -54,6 +56,8 @@ final class AppBootstrap implements AppDependencies {
|
||||
@override
|
||||
final WorkoutHistoryUseCases workoutHistoryUseCases;
|
||||
@override
|
||||
final ExercisePerformanceReferenceUseCase exercisePerformanceReferenceUseCase;
|
||||
@override
|
||||
final SyncUseCases syncUseCases;
|
||||
@override
|
||||
final ShareUseCases shareUseCases;
|
||||
@ -77,6 +81,8 @@ final class AppBootstrap implements AppDependencies {
|
||||
final templateRepository = DriftWorkoutTemplateRepository(database);
|
||||
final activeSessionRepository = DriftActiveSessionRepository(database);
|
||||
final historyRepository = DriftWorkoutHistoryRepository(database);
|
||||
final performanceReferenceRepository =
|
||||
DriftExercisePerformanceReferenceRepository(database);
|
||||
final ids = LocalIdGenerator();
|
||||
const clock = SystemClock();
|
||||
const originDeviceId = 'local-device';
|
||||
@ -159,6 +165,9 @@ final class AppBootstrap implements AppDependencies {
|
||||
repository: historyRepository,
|
||||
clock: clock,
|
||||
),
|
||||
exercisePerformanceReferenceUseCase: ExercisePerformanceReferenceUseCase(
|
||||
repository: performanceReferenceRepository,
|
||||
),
|
||||
syncUseCases: SyncUseCases(
|
||||
tokenStore: const SecureStorageAuthTokenStore(),
|
||||
remoteSyncApi: remoteSyncApi,
|
||||
|
||||
@ -466,6 +466,106 @@ abstract interface class WorkoutHistoryRepository {
|
||||
Future<void> delete(String id, DateTime deletedAt);
|
||||
}
|
||||
|
||||
final class ActivePerformanceMeasures {
|
||||
const ActivePerformanceMeasures({
|
||||
required this.timeEnabled,
|
||||
required this.repsEnabled,
|
||||
required this.scoreEnabled,
|
||||
this.scoreInputMode = ScoreInputMode.manual,
|
||||
});
|
||||
|
||||
final bool timeEnabled;
|
||||
final bool repsEnabled;
|
||||
final bool scoreEnabled;
|
||||
final ScoreInputMode scoreInputMode;
|
||||
|
||||
bool get hasAny => timeEnabled || repsEnabled || scoreEnabled;
|
||||
}
|
||||
|
||||
enum PerformanceMetric { score, reps, time }
|
||||
|
||||
final class WorkoutHistorySetPerformance {
|
||||
const WorkoutHistorySetPerformance({
|
||||
required this.workoutHistoryId,
|
||||
required this.startedAt,
|
||||
required this.setIndex,
|
||||
required this.exerciseNameSnapshot,
|
||||
required this.scoreInputModeSnapshot,
|
||||
this.actualTimeMs,
|
||||
this.actualReps,
|
||||
this.actualScore,
|
||||
this.actualScoreTimeMs,
|
||||
this.completedAt,
|
||||
});
|
||||
|
||||
final String workoutHistoryId;
|
||||
final DateTime startedAt;
|
||||
final int setIndex;
|
||||
final String exerciseNameSnapshot;
|
||||
final ScoreInputMode scoreInputModeSnapshot;
|
||||
final int? actualTimeMs;
|
||||
final int? actualReps;
|
||||
final double? actualScore;
|
||||
final int? actualScoreTimeMs;
|
||||
final DateTime? completedAt;
|
||||
}
|
||||
|
||||
final class WorkoutHistoryMetricPerformance {
|
||||
const WorkoutHistoryMetricPerformance({
|
||||
required this.workoutHistoryId,
|
||||
required this.startedAt,
|
||||
required this.setIndex,
|
||||
required this.exerciseNameSnapshot,
|
||||
required this.metric,
|
||||
required this.scoreInputModeSnapshot,
|
||||
this.actualTimeMs,
|
||||
this.actualReps,
|
||||
this.actualScore,
|
||||
this.actualScoreTimeMs,
|
||||
this.completedAt,
|
||||
});
|
||||
|
||||
final String workoutHistoryId;
|
||||
final DateTime startedAt;
|
||||
final int setIndex;
|
||||
final String exerciseNameSnapshot;
|
||||
final PerformanceMetric metric;
|
||||
final ScoreInputMode scoreInputModeSnapshot;
|
||||
final int? actualTimeMs;
|
||||
final int? actualReps;
|
||||
final double? actualScore;
|
||||
final int? actualScoreTimeMs;
|
||||
final DateTime? completedAt;
|
||||
}
|
||||
|
||||
final class ExercisePerformanceReference {
|
||||
const ExercisePerformanceReference({
|
||||
required this.hasAnyHistoryForExercise,
|
||||
this.last,
|
||||
this.record,
|
||||
});
|
||||
|
||||
final bool hasAnyHistoryForExercise;
|
||||
final WorkoutHistorySetPerformance? last;
|
||||
final WorkoutHistoryMetricPerformance? record;
|
||||
}
|
||||
|
||||
abstract interface class ExercisePerformanceReferenceRepository {
|
||||
Future<bool> hasAnyCompletedHistoryForExercise(String exerciseId);
|
||||
|
||||
Future<WorkoutHistorySetPerformance?> findLatestSetPerformance({
|
||||
required String exerciseId,
|
||||
required ActivePerformanceMeasures activeMeasures,
|
||||
required int currentSetIndex,
|
||||
});
|
||||
|
||||
Future<WorkoutHistoryMetricPerformance?> findBestMetricPerformance({
|
||||
required String exerciseId,
|
||||
required PerformanceMetric metric,
|
||||
required ScoreInputMode scoreInputMode,
|
||||
});
|
||||
}
|
||||
|
||||
final class SyncRunSummary {
|
||||
const SyncRunSummary({
|
||||
required this.pushedChanges,
|
||||
|
||||
@ -3329,6 +3329,9 @@ final class CloseWorkoutSessionUseCase {
|
||||
final stepResults = await sessionRepository.listExerciseStepResults(
|
||||
sessionId,
|
||||
);
|
||||
final snapshots = _exerciseSnapshotsById(
|
||||
session.resolvedTemplateSnapshotJson,
|
||||
);
|
||||
final historyId = ids.newId();
|
||||
final historyResults = _historyResultsFromActiveResults(
|
||||
historyId: historyId,
|
||||
@ -3341,6 +3344,7 @@ final class CloseWorkoutSessionUseCase {
|
||||
final historyStepResults = _historyStepResultsFromActiveResults(
|
||||
historyId: historyId,
|
||||
results: stepResults,
|
||||
resolvedTemplateSnapshotJson: session.resolvedTemplateSnapshotJson,
|
||||
now: now,
|
||||
ids: ids,
|
||||
originDeviceId: originDeviceId,
|
||||
@ -3377,6 +3381,8 @@ final class CloseWorkoutSessionUseCase {
|
||||
'scoreInputModeSnapshot': result.scoreInputModeSnapshot.name,
|
||||
'scoreLabelSnapshot': result.scoreLabelSnapshot,
|
||||
'scoreUnitSnapshot': result.scoreUnitSnapshot,
|
||||
'sourceExerciseIdSnapshot':
|
||||
snapshots[result.exerciseSnapshotId]?.sourceExerciseId,
|
||||
'status': result.status.name,
|
||||
},
|
||||
)
|
||||
@ -3407,6 +3413,8 @@ final class CloseWorkoutSessionUseCase {
|
||||
'actualScore': result.actualScore,
|
||||
'actualScoreTimeMs': result.actualScoreTimeMs,
|
||||
'note': result.note,
|
||||
'sourceExerciseIdSnapshot':
|
||||
snapshots[result.exerciseSnapshotId]?.sourceExerciseId,
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
@ -3571,6 +3579,59 @@ void _validateExerciseSteps(List<ExerciseStep> steps) {
|
||||
}
|
||||
}
|
||||
|
||||
final class ExercisePerformanceReferenceUseCase {
|
||||
const ExercisePerformanceReferenceUseCase({required this.repository});
|
||||
|
||||
final ExercisePerformanceReferenceRepository repository;
|
||||
|
||||
Future<ExercisePerformanceReference> getExercisePerformanceReference({
|
||||
required String exerciseId,
|
||||
required ActivePerformanceMeasures activeMeasures,
|
||||
required int currentSetIndex,
|
||||
}) async {
|
||||
final hasAnyHistory = await repository.hasAnyCompletedHistoryForExercise(
|
||||
exerciseId,
|
||||
);
|
||||
if (!activeMeasures.hasAny) {
|
||||
return ExercisePerformanceReference(
|
||||
hasAnyHistoryForExercise: hasAnyHistory,
|
||||
);
|
||||
}
|
||||
|
||||
final last = await repository.findLatestSetPerformance(
|
||||
exerciseId: exerciseId,
|
||||
activeMeasures: activeMeasures,
|
||||
currentSetIndex: currentSetIndex,
|
||||
);
|
||||
final recordMetric = _recordMetricFor(activeMeasures);
|
||||
final record = recordMetric == null
|
||||
? null
|
||||
: await repository.findBestMetricPerformance(
|
||||
exerciseId: exerciseId,
|
||||
metric: recordMetric,
|
||||
scoreInputMode: activeMeasures.scoreInputMode,
|
||||
);
|
||||
return ExercisePerformanceReference(
|
||||
hasAnyHistoryForExercise: hasAnyHistory,
|
||||
last: last,
|
||||
record: record,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PerformanceMetric? _recordMetricFor(ActivePerformanceMeasures measures) {
|
||||
if (measures.scoreEnabled) {
|
||||
return PerformanceMetric.score;
|
||||
}
|
||||
if (measures.repsEnabled) {
|
||||
return PerformanceMetric.reps;
|
||||
}
|
||||
if (measures.timeEnabled) {
|
||||
return PerformanceMetric.time;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void _validateAuthInput({required String email, required String password}) {
|
||||
final normalizedEmail = email.trim();
|
||||
final hasBasicEmailShape = RegExp(
|
||||
@ -4055,6 +4116,7 @@ List<WorkoutHistorySetResult> _historyResultsFromActiveResults({
|
||||
result.scoreLabelSnapshot ?? snapshot?.scoreLabelSnapshot,
|
||||
scoreUnitSnapshot:
|
||||
result.scoreUnitSnapshot ?? snapshot?.scoreUnitSnapshot,
|
||||
sourceExerciseIdSnapshot: snapshot?.sourceExerciseId,
|
||||
startedAt: result.startedAt,
|
||||
completedAt: result.completedAt,
|
||||
status: result.status,
|
||||
@ -4089,6 +4151,7 @@ Map<String, _ResolvedExerciseSnapshot> _exerciseSnapshotsById(
|
||||
exerciseSnapshotId: id,
|
||||
programNameSnapshot: programName,
|
||||
exerciseNameSnapshot: exercise['exerciseNameSnapshot'] as String? ?? id,
|
||||
sourceExerciseId: exercise['sourceExerciseId'] as String?,
|
||||
timeEnabled: exercise['timeEnabled'] == true,
|
||||
repsEnabled: exercise['repsEnabled'] == true,
|
||||
scoreEnabled: exercise['scoreEnabled'] == true,
|
||||
@ -4118,6 +4181,7 @@ final class _ResolvedExerciseSnapshot {
|
||||
required this.exerciseSnapshotId,
|
||||
required this.programNameSnapshot,
|
||||
required this.exerciseNameSnapshot,
|
||||
this.sourceExerciseId,
|
||||
required this.timeEnabled,
|
||||
required this.repsEnabled,
|
||||
required this.scoreEnabled,
|
||||
@ -4136,6 +4200,7 @@ final class _ResolvedExerciseSnapshot {
|
||||
final String exerciseSnapshotId;
|
||||
final String programNameSnapshot;
|
||||
final String exerciseNameSnapshot;
|
||||
final String? sourceExerciseId;
|
||||
final bool timeEnabled;
|
||||
final bool repsEnabled;
|
||||
final bool scoreEnabled;
|
||||
@ -4181,11 +4246,14 @@ List<ExerciseStep> _exerciseStepsFromSnapshot(Object? value) {
|
||||
List<WorkoutHistoryStepResult> _historyStepResultsFromActiveResults({
|
||||
required String historyId,
|
||||
required List<ActiveExerciseStepResult> results,
|
||||
required String resolvedTemplateSnapshotJson,
|
||||
required DateTime now,
|
||||
required IdGenerator ids,
|
||||
required String originDeviceId,
|
||||
}) {
|
||||
final snapshots = _exerciseSnapshotsById(resolvedTemplateSnapshotJson);
|
||||
return results.map((result) {
|
||||
final snapshot = snapshots[result.exerciseSnapshotId];
|
||||
return WorkoutHistoryStepResult(
|
||||
metadata: _newMetadata(ids, originDeviceId, now),
|
||||
workoutHistoryId: historyId,
|
||||
@ -4214,6 +4282,7 @@ List<WorkoutHistoryStepResult> _historyStepResultsFromActiveResults({
|
||||
actualScore: result.actualScore,
|
||||
actualScoreTimeMs: result.actualScoreTimeMs,
|
||||
note: result.note,
|
||||
sourceExerciseIdSnapshot: snapshot?.sourceExerciseId,
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@ -1444,6 +1444,7 @@ final class WorkoutHistorySetResult {
|
||||
this.scoreInputModeSnapshot = ScoreInputMode.manual,
|
||||
this.scoreLabelSnapshot,
|
||||
this.scoreUnitSnapshot,
|
||||
this.sourceExerciseIdSnapshot,
|
||||
this.startedAt,
|
||||
this.completedAt,
|
||||
this.status = SetResultStatus.completed,
|
||||
@ -1493,6 +1494,7 @@ final class WorkoutHistorySetResult {
|
||||
final ScoreInputMode scoreInputModeSnapshot;
|
||||
final String? scoreLabelSnapshot;
|
||||
final String? scoreUnitSnapshot;
|
||||
final String? sourceExerciseIdSnapshot;
|
||||
final DateTime? startedAt;
|
||||
final DateTime? completedAt;
|
||||
final SetResultStatus status;
|
||||
@ -1527,6 +1529,7 @@ final class WorkoutHistoryStepResult {
|
||||
this.actualScore,
|
||||
this.actualScoreTimeMs,
|
||||
this.note,
|
||||
this.sourceExerciseIdSnapshot,
|
||||
}) {
|
||||
_validateExerciseStepResult(
|
||||
programIndex: programIndex,
|
||||
@ -1577,6 +1580,7 @@ final class WorkoutHistoryStepResult {
|
||||
final double? actualScore;
|
||||
final int? actualScoreTimeMs;
|
||||
final String? note;
|
||||
final String? sourceExerciseIdSnapshot;
|
||||
}
|
||||
|
||||
String _nonBlank(String? value, String label) {
|
||||
|
||||
@ -48,7 +48,7 @@ final class AppDatabase extends _$AppDatabase {
|
||||
}
|
||||
|
||||
@override
|
||||
int get schemaVersion => 16;
|
||||
int get schemaVersion => 17;
|
||||
|
||||
@override
|
||||
MigrationStrategy get migration {
|
||||
@ -113,6 +113,9 @@ final class AppDatabase extends _$AppDatabase {
|
||||
if (from < 16) {
|
||||
await _migrateToSchema16(migrator);
|
||||
}
|
||||
if (from < 17) {
|
||||
await _migrateToSchema17();
|
||||
}
|
||||
await _createIndexes();
|
||||
},
|
||||
beforeOpen: (details) async {
|
||||
@ -229,10 +232,24 @@ final class AppDatabase extends _$AppDatabase {
|
||||
'CREATE INDEX IF NOT EXISTS idx_workout_history_set_results_history_id '
|
||||
'ON workout_history_set_results (workout_history_id)',
|
||||
);
|
||||
await customStatement(
|
||||
'CREATE INDEX IF NOT EXISTS '
|
||||
'idx_workout_history_set_results_source_exercise '
|
||||
'ON workout_history_set_results (source_exercise_id_snapshot, '
|
||||
'set_index) WHERE deleted_at IS NULL AND '
|
||||
'source_exercise_id_snapshot IS NOT NULL',
|
||||
);
|
||||
await customStatement(
|
||||
'CREATE INDEX IF NOT EXISTS idx_workout_history_step_results_history_id '
|
||||
'ON workout_history_step_results (workout_history_id)',
|
||||
);
|
||||
await customStatement(
|
||||
'CREATE INDEX IF NOT EXISTS '
|
||||
'idx_workout_history_step_results_source_exercise '
|
||||
'ON workout_history_step_results (source_exercise_id_snapshot, '
|
||||
'set_index, step_index) WHERE deleted_at IS NULL AND '
|
||||
'source_exercise_id_snapshot IS NOT NULL',
|
||||
);
|
||||
await customStatement(
|
||||
'CREATE INDEX IF NOT EXISTS idx_change_log_entity '
|
||||
'ON change_log (entity_type, entity_id)',
|
||||
@ -697,6 +714,79 @@ CREATE TABLE IF NOT EXISTS active_set_timer_states (
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _migrateToSchema17() async {
|
||||
await _addColumnIfMissing(
|
||||
tableName: 'workout_history_set_results',
|
||||
columnName: 'source_exercise_id_snapshot',
|
||||
definition: 'source_exercise_id_snapshot TEXT',
|
||||
);
|
||||
await _addColumnIfMissing(
|
||||
tableName: 'workout_history_step_results',
|
||||
columnName: 'source_exercise_id_snapshot',
|
||||
definition: 'source_exercise_id_snapshot TEXT',
|
||||
);
|
||||
await _backfillWorkoutHistorySetSourceExerciseIds();
|
||||
await _backfillWorkoutHistoryStepSourceExerciseIds();
|
||||
}
|
||||
|
||||
Future<void> _backfillWorkoutHistorySetSourceExerciseIds() async {
|
||||
await customStatement(r'''
|
||||
UPDATE workout_history_set_results AS result
|
||||
SET source_exercise_id_snapshot = (
|
||||
SELECT json_extract(exercise.value, '$.sourceExerciseId')
|
||||
FROM workout_history AS history,
|
||||
json_each(
|
||||
COALESCE(
|
||||
json_extract(
|
||||
history.history_snapshot_json,
|
||||
'$.resolvedTemplateSnapshotJson'
|
||||
),
|
||||
history.history_snapshot_json
|
||||
),
|
||||
'$.programs'
|
||||
) AS program,
|
||||
json_each(
|
||||
json_extract(program.value, '$.programSnapshotJson'),
|
||||
'$.exercises'
|
||||
) AS exercise
|
||||
WHERE history.id = result.workout_history_id
|
||||
AND json_extract(program.value, '$.id') = result.program_snapshot_id
|
||||
AND json_extract(exercise.value, '$.id') = result.exercise_snapshot_id
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE result.source_exercise_id_snapshot IS NULL
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> _backfillWorkoutHistoryStepSourceExerciseIds() async {
|
||||
await customStatement(r'''
|
||||
UPDATE workout_history_step_results AS result
|
||||
SET source_exercise_id_snapshot = (
|
||||
SELECT json_extract(exercise.value, '$.sourceExerciseId')
|
||||
FROM workout_history AS history,
|
||||
json_each(
|
||||
COALESCE(
|
||||
json_extract(
|
||||
history.history_snapshot_json,
|
||||
'$.resolvedTemplateSnapshotJson'
|
||||
),
|
||||
history.history_snapshot_json
|
||||
),
|
||||
'$.programs'
|
||||
) AS program,
|
||||
json_each(
|
||||
json_extract(program.value, '$.programSnapshotJson'),
|
||||
'$.exercises'
|
||||
) AS exercise
|
||||
WHERE history.id = result.workout_history_id
|
||||
AND json_extract(program.value, '$.id') = result.program_snapshot_id
|
||||
AND json_extract(exercise.value, '$.id') = result.exercise_snapshot_id
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE result.source_exercise_id_snapshot IS NULL
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> _addColumnIfMissing({
|
||||
required String tableName,
|
||||
required String columnName,
|
||||
|
||||
@ -24020,6 +24020,17 @@ class $WorkoutHistorySetResultsTable extends WorkoutHistorySetResults
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
);
|
||||
static const VerificationMeta _sourceExerciseIdSnapshotMeta =
|
||||
const VerificationMeta('sourceExerciseIdSnapshot');
|
||||
@override
|
||||
late final GeneratedColumn<String> sourceExerciseIdSnapshot =
|
||||
GeneratedColumn<String>(
|
||||
'source_exercise_id_snapshot',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
);
|
||||
static const VerificationMeta _startedAtMeta = const VerificationMeta(
|
||||
'startedAt',
|
||||
);
|
||||
@ -24087,6 +24098,7 @@ class $WorkoutHistorySetResultsTable extends WorkoutHistorySetResults
|
||||
actualScoreTimeMs,
|
||||
scoreLabelSnapshot,
|
||||
scoreUnitSnapshot,
|
||||
sourceExerciseIdSnapshot,
|
||||
startedAt,
|
||||
completedAt,
|
||||
status,
|
||||
@ -24410,6 +24422,15 @@ class $WorkoutHistorySetResultsTable extends WorkoutHistorySetResults
|
||||
),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('source_exercise_id_snapshot')) {
|
||||
context.handle(
|
||||
_sourceExerciseIdSnapshotMeta,
|
||||
sourceExerciseIdSnapshot.isAcceptableOrUnknown(
|
||||
data['source_exercise_id_snapshot']!,
|
||||
_sourceExerciseIdSnapshotMeta,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('started_at')) {
|
||||
context.handle(
|
||||
_startedAtMeta,
|
||||
@ -24575,6 +24596,10 @@ class $WorkoutHistorySetResultsTable extends WorkoutHistorySetResults
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}score_unit_snapshot'],
|
||||
),
|
||||
sourceExerciseIdSnapshot: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}source_exercise_id_snapshot'],
|
||||
),
|
||||
startedAt: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.dateTime,
|
||||
data['${effectivePrefix}started_at'],
|
||||
@ -24631,6 +24656,7 @@ class WorkoutHistorySetResult extends DataClass
|
||||
final int? actualScoreTimeMs;
|
||||
final String? scoreLabelSnapshot;
|
||||
final String? scoreUnitSnapshot;
|
||||
final String? sourceExerciseIdSnapshot;
|
||||
final DateTime? startedAt;
|
||||
final DateTime? completedAt;
|
||||
final String status;
|
||||
@ -24668,6 +24694,7 @@ class WorkoutHistorySetResult extends DataClass
|
||||
this.actualScoreTimeMs,
|
||||
this.scoreLabelSnapshot,
|
||||
this.scoreUnitSnapshot,
|
||||
this.sourceExerciseIdSnapshot,
|
||||
this.startedAt,
|
||||
this.completedAt,
|
||||
required this.status,
|
||||
@ -24740,6 +24767,11 @@ class WorkoutHistorySetResult extends DataClass
|
||||
if (!nullToAbsent || scoreUnitSnapshot != null) {
|
||||
map['score_unit_snapshot'] = Variable<String>(scoreUnitSnapshot);
|
||||
}
|
||||
if (!nullToAbsent || sourceExerciseIdSnapshot != null) {
|
||||
map['source_exercise_id_snapshot'] = Variable<String>(
|
||||
sourceExerciseIdSnapshot,
|
||||
);
|
||||
}
|
||||
if (!nullToAbsent || startedAt != null) {
|
||||
map['started_at'] = Variable<DateTime>(startedAt);
|
||||
}
|
||||
@ -24815,6 +24847,9 @@ class WorkoutHistorySetResult extends DataClass
|
||||
scoreUnitSnapshot: scoreUnitSnapshot == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(scoreUnitSnapshot),
|
||||
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(sourceExerciseIdSnapshot),
|
||||
startedAt: startedAt == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(startedAt),
|
||||
@ -24890,6 +24925,9 @@ class WorkoutHistorySetResult extends DataClass
|
||||
scoreUnitSnapshot: serializer.fromJson<String?>(
|
||||
json['scoreUnitSnapshot'],
|
||||
),
|
||||
sourceExerciseIdSnapshot: serializer.fromJson<String?>(
|
||||
json['sourceExerciseIdSnapshot'],
|
||||
),
|
||||
startedAt: serializer.fromJson<DateTime?>(json['startedAt']),
|
||||
completedAt: serializer.fromJson<DateTime?>(json['completedAt']),
|
||||
status: serializer.fromJson<String>(json['status']),
|
||||
@ -24938,6 +24976,9 @@ class WorkoutHistorySetResult extends DataClass
|
||||
'actualScoreTimeMs': serializer.toJson<int?>(actualScoreTimeMs),
|
||||
'scoreLabelSnapshot': serializer.toJson<String?>(scoreLabelSnapshot),
|
||||
'scoreUnitSnapshot': serializer.toJson<String?>(scoreUnitSnapshot),
|
||||
'sourceExerciseIdSnapshot': serializer.toJson<String?>(
|
||||
sourceExerciseIdSnapshot,
|
||||
),
|
||||
'startedAt': serializer.toJson<DateTime?>(startedAt),
|
||||
'completedAt': serializer.toJson<DateTime?>(completedAt),
|
||||
'status': serializer.toJson<String>(status),
|
||||
@ -24978,6 +25019,7 @@ class WorkoutHistorySetResult extends DataClass
|
||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||
Value<String?> scoreLabelSnapshot = const Value.absent(),
|
||||
Value<String?> scoreUnitSnapshot = const Value.absent(),
|
||||
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||
Value<DateTime?> startedAt = const Value.absent(),
|
||||
Value<DateTime?> completedAt = const Value.absent(),
|
||||
String? status,
|
||||
@ -25034,6 +25076,9 @@ class WorkoutHistorySetResult extends DataClass
|
||||
scoreUnitSnapshot: scoreUnitSnapshot.present
|
||||
? scoreUnitSnapshot.value
|
||||
: this.scoreUnitSnapshot,
|
||||
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot.present
|
||||
? sourceExerciseIdSnapshot.value
|
||||
: this.sourceExerciseIdSnapshot,
|
||||
startedAt: startedAt.present ? startedAt.value : this.startedAt,
|
||||
completedAt: completedAt.present ? completedAt.value : this.completedAt,
|
||||
status: status ?? this.status,
|
||||
@ -25129,6 +25174,9 @@ class WorkoutHistorySetResult extends DataClass
|
||||
scoreUnitSnapshot: data.scoreUnitSnapshot.present
|
||||
? data.scoreUnitSnapshot.value
|
||||
: this.scoreUnitSnapshot,
|
||||
sourceExerciseIdSnapshot: data.sourceExerciseIdSnapshot.present
|
||||
? data.sourceExerciseIdSnapshot.value
|
||||
: this.sourceExerciseIdSnapshot,
|
||||
startedAt: data.startedAt.present ? data.startedAt.value : this.startedAt,
|
||||
completedAt: data.completedAt.present
|
||||
? data.completedAt.value
|
||||
@ -25173,6 +25221,7 @@ class WorkoutHistorySetResult extends DataClass
|
||||
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
||||
..write('scoreLabelSnapshot: $scoreLabelSnapshot, ')
|
||||
..write('scoreUnitSnapshot: $scoreUnitSnapshot, ')
|
||||
..write('sourceExerciseIdSnapshot: $sourceExerciseIdSnapshot, ')
|
||||
..write('startedAt: $startedAt, ')
|
||||
..write('completedAt: $completedAt, ')
|
||||
..write('status: $status')
|
||||
@ -25215,6 +25264,7 @@ class WorkoutHistorySetResult extends DataClass
|
||||
actualScoreTimeMs,
|
||||
scoreLabelSnapshot,
|
||||
scoreUnitSnapshot,
|
||||
sourceExerciseIdSnapshot,
|
||||
startedAt,
|
||||
completedAt,
|
||||
status,
|
||||
@ -25256,6 +25306,7 @@ class WorkoutHistorySetResult extends DataClass
|
||||
other.actualScoreTimeMs == this.actualScoreTimeMs &&
|
||||
other.scoreLabelSnapshot == this.scoreLabelSnapshot &&
|
||||
other.scoreUnitSnapshot == this.scoreUnitSnapshot &&
|
||||
other.sourceExerciseIdSnapshot == this.sourceExerciseIdSnapshot &&
|
||||
other.startedAt == this.startedAt &&
|
||||
other.completedAt == this.completedAt &&
|
||||
other.status == this.status);
|
||||
@ -25296,6 +25347,7 @@ class WorkoutHistorySetResultsCompanion
|
||||
final Value<int?> actualScoreTimeMs;
|
||||
final Value<String?> scoreLabelSnapshot;
|
||||
final Value<String?> scoreUnitSnapshot;
|
||||
final Value<String?> sourceExerciseIdSnapshot;
|
||||
final Value<DateTime?> startedAt;
|
||||
final Value<DateTime?> completedAt;
|
||||
final Value<String> status;
|
||||
@ -25334,6 +25386,7 @@ class WorkoutHistorySetResultsCompanion
|
||||
this.actualScoreTimeMs = const Value.absent(),
|
||||
this.scoreLabelSnapshot = const Value.absent(),
|
||||
this.scoreUnitSnapshot = const Value.absent(),
|
||||
this.sourceExerciseIdSnapshot = const Value.absent(),
|
||||
this.startedAt = const Value.absent(),
|
||||
this.completedAt = const Value.absent(),
|
||||
this.status = const Value.absent(),
|
||||
@ -25373,6 +25426,7 @@ class WorkoutHistorySetResultsCompanion
|
||||
this.actualScoreTimeMs = const Value.absent(),
|
||||
this.scoreLabelSnapshot = const Value.absent(),
|
||||
this.scoreUnitSnapshot = const Value.absent(),
|
||||
this.sourceExerciseIdSnapshot = const Value.absent(),
|
||||
this.startedAt = const Value.absent(),
|
||||
this.completedAt = const Value.absent(),
|
||||
this.status = const Value.absent(),
|
||||
@ -25428,6 +25482,7 @@ class WorkoutHistorySetResultsCompanion
|
||||
Expression<int>? actualScoreTimeMs,
|
||||
Expression<String>? scoreLabelSnapshot,
|
||||
Expression<String>? scoreUnitSnapshot,
|
||||
Expression<String>? sourceExerciseIdSnapshot,
|
||||
Expression<DateTime>? startedAt,
|
||||
Expression<DateTime>? completedAt,
|
||||
Expression<String>? status,
|
||||
@ -25480,6 +25535,8 @@ class WorkoutHistorySetResultsCompanion
|
||||
if (scoreLabelSnapshot != null)
|
||||
'score_label_snapshot': scoreLabelSnapshot,
|
||||
if (scoreUnitSnapshot != null) 'score_unit_snapshot': scoreUnitSnapshot,
|
||||
if (sourceExerciseIdSnapshot != null)
|
||||
'source_exercise_id_snapshot': sourceExerciseIdSnapshot,
|
||||
if (startedAt != null) 'started_at': startedAt,
|
||||
if (completedAt != null) 'completed_at': completedAt,
|
||||
if (status != null) 'status': status,
|
||||
@ -25521,6 +25578,7 @@ class WorkoutHistorySetResultsCompanion
|
||||
Value<int?>? actualScoreTimeMs,
|
||||
Value<String?>? scoreLabelSnapshot,
|
||||
Value<String?>? scoreUnitSnapshot,
|
||||
Value<String?>? sourceExerciseIdSnapshot,
|
||||
Value<DateTime?>? startedAt,
|
||||
Value<DateTime?>? completedAt,
|
||||
Value<String>? status,
|
||||
@ -25563,6 +25621,8 @@ class WorkoutHistorySetResultsCompanion
|
||||
actualScoreTimeMs: actualScoreTimeMs ?? this.actualScoreTimeMs,
|
||||
scoreLabelSnapshot: scoreLabelSnapshot ?? this.scoreLabelSnapshot,
|
||||
scoreUnitSnapshot: scoreUnitSnapshot ?? this.scoreUnitSnapshot,
|
||||
sourceExerciseIdSnapshot:
|
||||
sourceExerciseIdSnapshot ?? this.sourceExerciseIdSnapshot,
|
||||
startedAt: startedAt ?? this.startedAt,
|
||||
completedAt: completedAt ?? this.completedAt,
|
||||
status: status ?? this.status,
|
||||
@ -25688,6 +25748,11 @@ class WorkoutHistorySetResultsCompanion
|
||||
if (scoreUnitSnapshot.present) {
|
||||
map['score_unit_snapshot'] = Variable<String>(scoreUnitSnapshot.value);
|
||||
}
|
||||
if (sourceExerciseIdSnapshot.present) {
|
||||
map['source_exercise_id_snapshot'] = Variable<String>(
|
||||
sourceExerciseIdSnapshot.value,
|
||||
);
|
||||
}
|
||||
if (startedAt.present) {
|
||||
map['started_at'] = Variable<DateTime>(startedAt.value);
|
||||
}
|
||||
@ -25739,6 +25804,7 @@ class WorkoutHistorySetResultsCompanion
|
||||
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
||||
..write('scoreLabelSnapshot: $scoreLabelSnapshot, ')
|
||||
..write('scoreUnitSnapshot: $scoreUnitSnapshot, ')
|
||||
..write('sourceExerciseIdSnapshot: $sourceExerciseIdSnapshot, ')
|
||||
..write('startedAt: $startedAt, ')
|
||||
..write('completedAt: $completedAt, ')
|
||||
..write('status: $status, ')
|
||||
@ -26171,6 +26237,17 @@ class $WorkoutHistoryStepResultsTable extends WorkoutHistoryStepResults
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
);
|
||||
static const VerificationMeta _sourceExerciseIdSnapshotMeta =
|
||||
const VerificationMeta('sourceExerciseIdSnapshot');
|
||||
@override
|
||||
late final GeneratedColumn<String> sourceExerciseIdSnapshot =
|
||||
GeneratedColumn<String>(
|
||||
'source_exercise_id_snapshot',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [
|
||||
id,
|
||||
@ -26210,6 +26287,7 @@ class $WorkoutHistoryStepResultsTable extends WorkoutHistoryStepResults
|
||||
actualScore,
|
||||
actualScoreTimeMs,
|
||||
note,
|
||||
sourceExerciseIdSnapshot,
|
||||
];
|
||||
@override
|
||||
String get aliasedName => _alias ?? actualTableName;
|
||||
@ -26560,6 +26638,15 @@ class $WorkoutHistoryStepResultsTable extends WorkoutHistoryStepResults
|
||||
note.isAcceptableOrUnknown(data['note']!, _noteMeta),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('source_exercise_id_snapshot')) {
|
||||
context.handle(
|
||||
_sourceExerciseIdSnapshotMeta,
|
||||
sourceExerciseIdSnapshot.isAcceptableOrUnknown(
|
||||
data['source_exercise_id_snapshot']!,
|
||||
_sourceExerciseIdSnapshotMeta,
|
||||
),
|
||||
);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@ -26720,6 +26807,10 @@ class $WorkoutHistoryStepResultsTable extends WorkoutHistoryStepResults
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}note'],
|
||||
),
|
||||
sourceExerciseIdSnapshot: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}source_exercise_id_snapshot'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -26768,6 +26859,7 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
final double? actualScore;
|
||||
final int? actualScoreTimeMs;
|
||||
final String? note;
|
||||
final String? sourceExerciseIdSnapshot;
|
||||
const WorkoutHistoryStepResult({
|
||||
required this.id,
|
||||
required this.createdAt,
|
||||
@ -26806,6 +26898,7 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
this.actualScore,
|
||||
this.actualScoreTimeMs,
|
||||
this.note,
|
||||
this.sourceExerciseIdSnapshot,
|
||||
});
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
@ -26883,6 +26976,11 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
if (!nullToAbsent || note != null) {
|
||||
map['note'] = Variable<String>(note);
|
||||
}
|
||||
if (!nullToAbsent || sourceExerciseIdSnapshot != null) {
|
||||
map['source_exercise_id_snapshot'] = Variable<String>(
|
||||
sourceExerciseIdSnapshot,
|
||||
);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -26956,6 +27054,9 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
? const Value.absent()
|
||||
: Value(actualScoreTimeMs),
|
||||
note: note == null && nullToAbsent ? const Value.absent() : Value(note),
|
||||
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(sourceExerciseIdSnapshot),
|
||||
);
|
||||
}
|
||||
|
||||
@ -27018,6 +27119,9 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
actualScore: serializer.fromJson<double?>(json['actualScore']),
|
||||
actualScoreTimeMs: serializer.fromJson<int?>(json['actualScoreTimeMs']),
|
||||
note: serializer.fromJson<String?>(json['note']),
|
||||
sourceExerciseIdSnapshot: serializer.fromJson<String?>(
|
||||
json['sourceExerciseIdSnapshot'],
|
||||
),
|
||||
);
|
||||
}
|
||||
@override
|
||||
@ -27065,6 +27169,9 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
'actualScore': serializer.toJson<double?>(actualScore),
|
||||
'actualScoreTimeMs': serializer.toJson<int?>(actualScoreTimeMs),
|
||||
'note': serializer.toJson<String?>(note),
|
||||
'sourceExerciseIdSnapshot': serializer.toJson<String?>(
|
||||
sourceExerciseIdSnapshot,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@ -27106,6 +27213,7 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
Value<double?> actualScore = const Value.absent(),
|
||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||
Value<String?> note = const Value.absent(),
|
||||
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||
}) => WorkoutHistoryStepResult(
|
||||
id: id ?? this.id,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
@ -27160,6 +27268,9 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
? actualScoreTimeMs.value
|
||||
: this.actualScoreTimeMs,
|
||||
note: note.present ? note.value : this.note,
|
||||
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot.present
|
||||
? sourceExerciseIdSnapshot.value
|
||||
: this.sourceExerciseIdSnapshot,
|
||||
);
|
||||
WorkoutHistoryStepResult copyWithCompanion(
|
||||
WorkoutHistoryStepResultsCompanion data,
|
||||
@ -27256,6 +27367,9 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
? data.actualScoreTimeMs.value
|
||||
: this.actualScoreTimeMs,
|
||||
note: data.note.present ? data.note.value : this.note,
|
||||
sourceExerciseIdSnapshot: data.sourceExerciseIdSnapshot.present
|
||||
? data.sourceExerciseIdSnapshot.value
|
||||
: this.sourceExerciseIdSnapshot,
|
||||
);
|
||||
}
|
||||
|
||||
@ -27298,7 +27412,8 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
..write('actualReps: $actualReps, ')
|
||||
..write('actualScore: $actualScore, ')
|
||||
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
||||
..write('note: $note')
|
||||
..write('note: $note, ')
|
||||
..write('sourceExerciseIdSnapshot: $sourceExerciseIdSnapshot')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
@ -27342,6 +27457,7 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
actualScore,
|
||||
actualScoreTimeMs,
|
||||
note,
|
||||
sourceExerciseIdSnapshot,
|
||||
]);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
@ -27383,7 +27499,8 @@ class WorkoutHistoryStepResult extends DataClass
|
||||
other.actualReps == this.actualReps &&
|
||||
other.actualScore == this.actualScore &&
|
||||
other.actualScoreTimeMs == this.actualScoreTimeMs &&
|
||||
other.note == this.note);
|
||||
other.note == this.note &&
|
||||
other.sourceExerciseIdSnapshot == this.sourceExerciseIdSnapshot);
|
||||
}
|
||||
|
||||
class WorkoutHistoryStepResultsCompanion
|
||||
@ -27425,6 +27542,7 @@ class WorkoutHistoryStepResultsCompanion
|
||||
final Value<double?> actualScore;
|
||||
final Value<int?> actualScoreTimeMs;
|
||||
final Value<String?> note;
|
||||
final Value<String?> sourceExerciseIdSnapshot;
|
||||
final Value<int> rowid;
|
||||
const WorkoutHistoryStepResultsCompanion({
|
||||
this.id = const Value.absent(),
|
||||
@ -27464,6 +27582,7 @@ class WorkoutHistoryStepResultsCompanion
|
||||
this.actualScore = const Value.absent(),
|
||||
this.actualScoreTimeMs = const Value.absent(),
|
||||
this.note = const Value.absent(),
|
||||
this.sourceExerciseIdSnapshot = const Value.absent(),
|
||||
this.rowid = const Value.absent(),
|
||||
});
|
||||
WorkoutHistoryStepResultsCompanion.insert({
|
||||
@ -27504,6 +27623,7 @@ class WorkoutHistoryStepResultsCompanion
|
||||
this.actualScore = const Value.absent(),
|
||||
this.actualScoreTimeMs = const Value.absent(),
|
||||
this.note = const Value.absent(),
|
||||
this.sourceExerciseIdSnapshot = const Value.absent(),
|
||||
this.rowid = const Value.absent(),
|
||||
}) : id = Value(id),
|
||||
createdAt = Value(createdAt),
|
||||
@ -27563,6 +27683,7 @@ class WorkoutHistoryStepResultsCompanion
|
||||
Expression<double>? actualScore,
|
||||
Expression<int>? actualScoreTimeMs,
|
||||
Expression<String>? note,
|
||||
Expression<String>? sourceExerciseIdSnapshot,
|
||||
Expression<int>? rowid,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
@ -27610,6 +27731,8 @@ class WorkoutHistoryStepResultsCompanion
|
||||
if (actualScore != null) 'actual_score': actualScore,
|
||||
if (actualScoreTimeMs != null) 'actual_score_time_ms': actualScoreTimeMs,
|
||||
if (note != null) 'note': note,
|
||||
if (sourceExerciseIdSnapshot != null)
|
||||
'source_exercise_id_snapshot': sourceExerciseIdSnapshot,
|
||||
if (rowid != null) 'rowid': rowid,
|
||||
});
|
||||
}
|
||||
@ -27652,6 +27775,7 @@ class WorkoutHistoryStepResultsCompanion
|
||||
Value<double?>? actualScore,
|
||||
Value<int?>? actualScoreTimeMs,
|
||||
Value<String?>? note,
|
||||
Value<String?>? sourceExerciseIdSnapshot,
|
||||
Value<int>? rowid,
|
||||
}) {
|
||||
return WorkoutHistoryStepResultsCompanion(
|
||||
@ -27694,6 +27818,8 @@ class WorkoutHistoryStepResultsCompanion
|
||||
actualScore: actualScore ?? this.actualScore,
|
||||
actualScoreTimeMs: actualScoreTimeMs ?? this.actualScoreTimeMs,
|
||||
note: note ?? this.note,
|
||||
sourceExerciseIdSnapshot:
|
||||
sourceExerciseIdSnapshot ?? this.sourceExerciseIdSnapshot,
|
||||
rowid: rowid ?? this.rowid,
|
||||
);
|
||||
}
|
||||
@ -27820,6 +27946,11 @@ class WorkoutHistoryStepResultsCompanion
|
||||
if (note.present) {
|
||||
map['note'] = Variable<String>(note.value);
|
||||
}
|
||||
if (sourceExerciseIdSnapshot.present) {
|
||||
map['source_exercise_id_snapshot'] = Variable<String>(
|
||||
sourceExerciseIdSnapshot.value,
|
||||
);
|
||||
}
|
||||
if (rowid.present) {
|
||||
map['rowid'] = Variable<int>(rowid.value);
|
||||
}
|
||||
@ -27866,6 +27997,7 @@ class WorkoutHistoryStepResultsCompanion
|
||||
..write('actualScore: $actualScore, ')
|
||||
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
||||
..write('note: $note, ')
|
||||
..write('sourceExerciseIdSnapshot: $sourceExerciseIdSnapshot, ')
|
||||
..write('rowid: $rowid')
|
||||
..write(')'))
|
||||
.toString();
|
||||
@ -45147,6 +45279,7 @@ typedef $$WorkoutHistorySetResultsTableCreateCompanionBuilder =
|
||||
Value<int?> actualScoreTimeMs,
|
||||
Value<String?> scoreLabelSnapshot,
|
||||
Value<String?> scoreUnitSnapshot,
|
||||
Value<String?> sourceExerciseIdSnapshot,
|
||||
Value<DateTime?> startedAt,
|
||||
Value<DateTime?> completedAt,
|
||||
Value<String> status,
|
||||
@ -45187,6 +45320,7 @@ typedef $$WorkoutHistorySetResultsTableUpdateCompanionBuilder =
|
||||
Value<int?> actualScoreTimeMs,
|
||||
Value<String?> scoreLabelSnapshot,
|
||||
Value<String?> scoreUnitSnapshot,
|
||||
Value<String?> sourceExerciseIdSnapshot,
|
||||
Value<DateTime?> startedAt,
|
||||
Value<DateTime?> completedAt,
|
||||
Value<String> status,
|
||||
@ -45395,6 +45529,11 @@ class $$WorkoutHistorySetResultsTableFilterComposer
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||
column: $table.sourceExerciseIdSnapshot,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<DateTime> get startedAt => $composableBuilder(
|
||||
column: $table.startedAt,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
@ -45603,6 +45742,11 @@ class $$WorkoutHistorySetResultsTableOrderingComposer
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||
column: $table.sourceExerciseIdSnapshot,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<DateTime> get startedAt => $composableBuilder(
|
||||
column: $table.startedAt,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
@ -45799,6 +45943,11 @@ class $$WorkoutHistorySetResultsTableAnnotationComposer
|
||||
builder: (column) => column,
|
||||
);
|
||||
|
||||
GeneratedColumn<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||
column: $table.sourceExerciseIdSnapshot,
|
||||
builder: (column) => column,
|
||||
);
|
||||
|
||||
GeneratedColumn<DateTime> get startedAt =>
|
||||
$composableBuilder(column: $table.startedAt, builder: (column) => column);
|
||||
|
||||
@ -45906,6 +46055,7 @@ class $$WorkoutHistorySetResultsTableTableManager
|
||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||
Value<String?> scoreLabelSnapshot = const Value.absent(),
|
||||
Value<String?> scoreUnitSnapshot = const Value.absent(),
|
||||
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||
Value<DateTime?> startedAt = const Value.absent(),
|
||||
Value<DateTime?> completedAt = const Value.absent(),
|
||||
Value<String> status = const Value.absent(),
|
||||
@ -45944,6 +46094,7 @@ class $$WorkoutHistorySetResultsTableTableManager
|
||||
actualScoreTimeMs: actualScoreTimeMs,
|
||||
scoreLabelSnapshot: scoreLabelSnapshot,
|
||||
scoreUnitSnapshot: scoreUnitSnapshot,
|
||||
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot,
|
||||
startedAt: startedAt,
|
||||
completedAt: completedAt,
|
||||
status: status,
|
||||
@ -45984,6 +46135,7 @@ class $$WorkoutHistorySetResultsTableTableManager
|
||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||
Value<String?> scoreLabelSnapshot = const Value.absent(),
|
||||
Value<String?> scoreUnitSnapshot = const Value.absent(),
|
||||
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||
Value<DateTime?> startedAt = const Value.absent(),
|
||||
Value<DateTime?> completedAt = const Value.absent(),
|
||||
Value<String> status = const Value.absent(),
|
||||
@ -46022,6 +46174,7 @@ class $$WorkoutHistorySetResultsTableTableManager
|
||||
actualScoreTimeMs: actualScoreTimeMs,
|
||||
scoreLabelSnapshot: scoreLabelSnapshot,
|
||||
scoreUnitSnapshot: scoreUnitSnapshot,
|
||||
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot,
|
||||
startedAt: startedAt,
|
||||
completedAt: completedAt,
|
||||
status: status,
|
||||
@ -46135,6 +46288,7 @@ typedef $$WorkoutHistoryStepResultsTableCreateCompanionBuilder =
|
||||
Value<double?> actualScore,
|
||||
Value<int?> actualScoreTimeMs,
|
||||
Value<String?> note,
|
||||
Value<String?> sourceExerciseIdSnapshot,
|
||||
Value<int> rowid,
|
||||
});
|
||||
typedef $$WorkoutHistoryStepResultsTableUpdateCompanionBuilder =
|
||||
@ -46176,6 +46330,7 @@ typedef $$WorkoutHistoryStepResultsTableUpdateCompanionBuilder =
|
||||
Value<double?> actualScore,
|
||||
Value<int?> actualScoreTimeMs,
|
||||
Value<String?> note,
|
||||
Value<String?> sourceExerciseIdSnapshot,
|
||||
Value<int> rowid,
|
||||
});
|
||||
|
||||
@ -46401,6 +46556,11 @@ class $$WorkoutHistoryStepResultsTableFilterComposer
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||
column: $table.sourceExerciseIdSnapshot,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
$$WorkoutHistoriesTableFilterComposer get workoutHistoryId {
|
||||
final $$WorkoutHistoriesTableFilterComposer composer = $composerBuilder(
|
||||
composer: this,
|
||||
@ -46614,6 +46774,11 @@ class $$WorkoutHistoryStepResultsTableOrderingComposer
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||
column: $table.sourceExerciseIdSnapshot,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
$$WorkoutHistoriesTableOrderingComposer get workoutHistoryId {
|
||||
final $$WorkoutHistoriesTableOrderingComposer composer = $composerBuilder(
|
||||
composer: this,
|
||||
@ -46807,6 +46972,11 @@ class $$WorkoutHistoryStepResultsTableAnnotationComposer
|
||||
GeneratedColumn<String> get note =>
|
||||
$composableBuilder(column: $table.note, builder: (column) => column);
|
||||
|
||||
GeneratedColumn<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||
column: $table.sourceExerciseIdSnapshot,
|
||||
builder: (column) => column,
|
||||
);
|
||||
|
||||
$$WorkoutHistoriesTableAnnotationComposer get workoutHistoryId {
|
||||
final $$WorkoutHistoriesTableAnnotationComposer composer = $composerBuilder(
|
||||
composer: this,
|
||||
@ -46910,6 +47080,7 @@ class $$WorkoutHistoryStepResultsTableTableManager
|
||||
Value<double?> actualScore = const Value.absent(),
|
||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||
Value<String?> note = const Value.absent(),
|
||||
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||
Value<int> rowid = const Value.absent(),
|
||||
}) => WorkoutHistoryStepResultsCompanion(
|
||||
id: id,
|
||||
@ -46949,6 +47120,7 @@ class $$WorkoutHistoryStepResultsTableTableManager
|
||||
actualScore: actualScore,
|
||||
actualScoreTimeMs: actualScoreTimeMs,
|
||||
note: note,
|
||||
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot,
|
||||
rowid: rowid,
|
||||
),
|
||||
createCompanionCallback:
|
||||
@ -46990,6 +47162,7 @@ class $$WorkoutHistoryStepResultsTableTableManager
|
||||
Value<double?> actualScore = const Value.absent(),
|
||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||
Value<String?> note = const Value.absent(),
|
||||
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||
Value<int> rowid = const Value.absent(),
|
||||
}) => WorkoutHistoryStepResultsCompanion.insert(
|
||||
id: id,
|
||||
@ -47029,6 +47202,7 @@ class $$WorkoutHistoryStepResultsTableTableManager
|
||||
actualScore: actualScore,
|
||||
actualScoreTimeMs: actualScoreTimeMs,
|
||||
note: note,
|
||||
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot,
|
||||
rowid: rowid,
|
||||
),
|
||||
withReferenceMapper: (p0) => p0
|
||||
|
||||
@ -1602,6 +1602,138 @@ final class DriftWorkoutHistoryRepository implements WorkoutHistoryRepository {
|
||||
}
|
||||
}
|
||||
|
||||
final class DriftExercisePerformanceReferenceRepository
|
||||
implements ExercisePerformanceReferenceRepository {
|
||||
const DriftExercisePerformanceReferenceRepository(this.database);
|
||||
|
||||
final db.AppDatabase database;
|
||||
|
||||
@override
|
||||
Future<bool> hasAnyCompletedHistoryForExercise(String exerciseId) async {
|
||||
final row = await database
|
||||
.customSelect(
|
||||
'SELECT 1 FROM workout_history_set_results AS result '
|
||||
'INNER JOIN workout_history AS history '
|
||||
'ON history.id = result.workout_history_id '
|
||||
'WHERE result.deleted_at IS NULL '
|
||||
'AND history.deleted_at IS NULL '
|
||||
'AND history.completed = 1 '
|
||||
'AND result.status = ? '
|
||||
'AND result.source_exercise_id_snapshot = ? '
|
||||
'LIMIT 1',
|
||||
variables: [
|
||||
const Variable<String>('completed'),
|
||||
Variable<String>(exerciseId),
|
||||
],
|
||||
)
|
||||
.getSingleOrNull();
|
||||
return row != null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<WorkoutHistorySetPerformance?> findLatestSetPerformance({
|
||||
required String exerciseId,
|
||||
required ActivePerformanceMeasures activeMeasures,
|
||||
required int currentSetIndex,
|
||||
}) async {
|
||||
final valuePredicate = _activeMeasuresPredicate(activeMeasures);
|
||||
if (valuePredicate == null) {
|
||||
return null;
|
||||
}
|
||||
final row = await database
|
||||
.customSelect(
|
||||
'''
|
||||
WITH candidates AS (
|
||||
SELECT
|
||||
result.workout_history_id,
|
||||
history.started_at AS history_started_at,
|
||||
result.set_index,
|
||||
result.exercise_name_snapshot,
|
||||
result.score_input_mode_snapshot,
|
||||
result.actual_time_ms,
|
||||
result.actual_reps,
|
||||
result.actual_score,
|
||||
result.actual_score_time_ms,
|
||||
result.completed_at
|
||||
FROM workout_history_set_results AS result
|
||||
INNER JOIN workout_history AS history
|
||||
ON history.id = result.workout_history_id
|
||||
WHERE result.deleted_at IS NULL
|
||||
AND history.deleted_at IS NULL
|
||||
AND history.completed = 1
|
||||
AND result.status = ?
|
||||
AND result.source_exercise_id_snapshot = ?
|
||||
AND ($valuePredicate)
|
||||
),
|
||||
latest_history AS (
|
||||
SELECT workout_history_id
|
||||
FROM candidates
|
||||
ORDER BY history_started_at DESC
|
||||
LIMIT 1
|
||||
)
|
||||
SELECT *
|
||||
FROM candidates
|
||||
WHERE workout_history_id = (SELECT workout_history_id FROM latest_history)
|
||||
ORDER BY
|
||||
CASE WHEN set_index = ? THEN 0 ELSE 1 END,
|
||||
set_index DESC
|
||||
LIMIT 1
|
||||
''',
|
||||
variables: [
|
||||
const Variable<String>('completed'),
|
||||
Variable<String>(exerciseId),
|
||||
Variable<int>(currentSetIndex),
|
||||
],
|
||||
)
|
||||
.getSingleOrNull();
|
||||
return row == null ? null : _setPerformanceFromRow(row);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<WorkoutHistoryMetricPerformance?> findBestMetricPerformance({
|
||||
required String exerciseId,
|
||||
required PerformanceMetric metric,
|
||||
required domain.ScoreInputMode scoreInputMode,
|
||||
}) async {
|
||||
final metricSql = _metricSql(metric, scoreInputMode);
|
||||
final row = await database
|
||||
.customSelect(
|
||||
'''
|
||||
SELECT
|
||||
result.workout_history_id,
|
||||
history.started_at AS history_started_at,
|
||||
result.set_index,
|
||||
result.exercise_name_snapshot,
|
||||
result.score_input_mode_snapshot,
|
||||
result.actual_time_ms,
|
||||
result.actual_reps,
|
||||
result.actual_score,
|
||||
result.actual_score_time_ms,
|
||||
result.completed_at
|
||||
FROM workout_history_set_results AS result
|
||||
INNER JOIN workout_history AS history
|
||||
ON history.id = result.workout_history_id
|
||||
WHERE result.deleted_at IS NULL
|
||||
AND history.deleted_at IS NULL
|
||||
AND history.completed = 1
|
||||
AND result.status = ?
|
||||
AND result.source_exercise_id_snapshot = ?
|
||||
AND ${metricSql.predicate}
|
||||
ORDER BY ${metricSql.ordering},
|
||||
history.started_at DESC,
|
||||
result.completed_at DESC
|
||||
LIMIT 1
|
||||
''',
|
||||
variables: [
|
||||
const Variable<String>('completed'),
|
||||
Variable<String>(exerciseId),
|
||||
],
|
||||
)
|
||||
.getSingleOrNull();
|
||||
return row == null ? null : _metricPerformanceFromRow(row, metric: metric);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _upsertWithChangeLog({
|
||||
required db.AppDatabase database,
|
||||
required String tableName,
|
||||
@ -2863,6 +2995,94 @@ domain.ActiveRestState _activeRestStateFromCustomRow(QueryRow row) {
|
||||
);
|
||||
}
|
||||
|
||||
WorkoutHistorySetPerformance _setPerformanceFromRow(QueryRow row) {
|
||||
final data = row.data;
|
||||
return WorkoutHistorySetPerformance(
|
||||
workoutHistoryId: data['workout_history_id'] as String,
|
||||
startedAt: _dateTimeFromData(data, 'history_started_at'),
|
||||
setIndex: data['set_index'] as int,
|
||||
exerciseNameSnapshot: data['exercise_name_snapshot'] as String,
|
||||
scoreInputModeSnapshot: _scoreInputModeFromDb(
|
||||
data['score_input_mode_snapshot'] as String,
|
||||
),
|
||||
actualTimeMs: data['actual_time_ms'] as int?,
|
||||
actualReps: data['actual_reps'] as int?,
|
||||
actualScore: (data['actual_score'] as num?)?.toDouble(),
|
||||
actualScoreTimeMs: data['actual_score_time_ms'] as int?,
|
||||
completedAt: _dateTimeOrNullFromData(data, 'completed_at'),
|
||||
);
|
||||
}
|
||||
|
||||
WorkoutHistoryMetricPerformance _metricPerformanceFromRow(
|
||||
QueryRow row, {
|
||||
required PerformanceMetric metric,
|
||||
}) {
|
||||
final set = _setPerformanceFromRow(row);
|
||||
return WorkoutHistoryMetricPerformance(
|
||||
workoutHistoryId: set.workoutHistoryId,
|
||||
startedAt: set.startedAt,
|
||||
setIndex: set.setIndex,
|
||||
exerciseNameSnapshot: set.exerciseNameSnapshot,
|
||||
metric: metric,
|
||||
scoreInputModeSnapshot: set.scoreInputModeSnapshot,
|
||||
actualTimeMs: set.actualTimeMs,
|
||||
actualReps: set.actualReps,
|
||||
actualScore: set.actualScore,
|
||||
actualScoreTimeMs: set.actualScoreTimeMs,
|
||||
completedAt: set.completedAt,
|
||||
);
|
||||
}
|
||||
|
||||
String? _activeMeasuresPredicate(ActivePerformanceMeasures measures) {
|
||||
final predicates = <String>[];
|
||||
if (measures.scoreEnabled) {
|
||||
predicates.add(
|
||||
measures.scoreInputMode == domain.ScoreInputMode.stopwatch
|
||||
? "(result.score_input_mode_snapshot = 'stopwatch' "
|
||||
'AND result.actual_score_time_ms IS NOT NULL)'
|
||||
: "(result.score_input_mode_snapshot = 'manual' "
|
||||
'AND result.actual_score IS NOT NULL)',
|
||||
);
|
||||
}
|
||||
if (measures.repsEnabled) {
|
||||
predicates.add('result.actual_reps IS NOT NULL');
|
||||
}
|
||||
if (measures.timeEnabled) {
|
||||
predicates.add('result.actual_time_ms IS NOT NULL');
|
||||
}
|
||||
return predicates.isEmpty ? null : predicates.join(' OR ');
|
||||
}
|
||||
|
||||
({String predicate, String ordering}) _metricSql(
|
||||
PerformanceMetric metric,
|
||||
domain.ScoreInputMode scoreInputMode,
|
||||
) {
|
||||
return switch (metric) {
|
||||
PerformanceMetric.score =>
|
||||
scoreInputMode == domain.ScoreInputMode.stopwatch
|
||||
? (
|
||||
predicate:
|
||||
"result.score_input_mode_snapshot = 'stopwatch' "
|
||||
'AND result.actual_score_time_ms IS NOT NULL',
|
||||
ordering: 'result.actual_score_time_ms ASC',
|
||||
)
|
||||
: (
|
||||
predicate:
|
||||
"result.score_input_mode_snapshot = 'manual' "
|
||||
'AND result.actual_score IS NOT NULL',
|
||||
ordering: 'result.actual_score DESC',
|
||||
),
|
||||
PerformanceMetric.reps => (
|
||||
predicate: 'result.actual_reps IS NOT NULL',
|
||||
ordering: 'result.actual_reps DESC',
|
||||
),
|
||||
PerformanceMetric.time => (
|
||||
predicate: 'result.actual_time_ms IS NOT NULL',
|
||||
ordering: 'result.actual_time_ms DESC',
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
db.ActiveScoreStopwatchStatesCompanion _activeScoreStopwatchStateCompanion(
|
||||
domain.ActiveScoreStopwatchState state,
|
||||
) {
|
||||
@ -3108,6 +3328,7 @@ db.WorkoutHistorySetResultsCompanion _workoutHistorySetResultCompanion(
|
||||
actualScoreTimeMs: Value(result.actualScoreTimeMs),
|
||||
scoreLabelSnapshot: Value(result.scoreLabelSnapshot),
|
||||
scoreUnitSnapshot: Value(result.scoreUnitSnapshot),
|
||||
sourceExerciseIdSnapshot: Value(result.sourceExerciseIdSnapshot),
|
||||
startedAt: Value(_utcOrNull(result.startedAt)),
|
||||
completedAt: Value(_utcOrNull(result.completedAt)),
|
||||
status: Value(_setResultStatusToDb(result.status)),
|
||||
@ -3160,6 +3381,7 @@ db.WorkoutHistoryStepResultsCompanion _workoutHistoryStepResultCompanion(
|
||||
actualScore: Value<double?>(result.actualScore),
|
||||
actualScoreTimeMs: Value<int?>(result.actualScoreTimeMs),
|
||||
note: Value<String?>(result.note),
|
||||
sourceExerciseIdSnapshot: Value<String?>(result.sourceExerciseIdSnapshot),
|
||||
);
|
||||
}
|
||||
|
||||
@ -3210,6 +3432,7 @@ domain.WorkoutHistorySetResult _workoutHistorySetResultFromRow(
|
||||
actualScoreTimeMs: row.actualScoreTimeMs,
|
||||
scoreLabelSnapshot: row.scoreLabelSnapshot,
|
||||
scoreUnitSnapshot: row.scoreUnitSnapshot,
|
||||
sourceExerciseIdSnapshot: row.sourceExerciseIdSnapshot,
|
||||
startedAt: _utcOrNull(row.startedAt),
|
||||
completedAt: _utcOrNull(row.completedAt),
|
||||
status: _setResultStatusFromDb(row.status),
|
||||
@ -3249,6 +3472,7 @@ domain.WorkoutHistoryStepResult _workoutHistoryStepResultFromRow(
|
||||
actualScore: row.actualScore,
|
||||
actualScoreTimeMs: row.actualScoreTimeMs,
|
||||
note: row.note,
|
||||
sourceExerciseIdSnapshot: row.sourceExerciseIdSnapshot,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -745,6 +745,7 @@ class WorkoutHistorySetResults extends SyncableTable {
|
||||
IntColumn get actualScoreTimeMs => integer().nullable()();
|
||||
TextColumn get scoreLabelSnapshot => text().nullable()();
|
||||
TextColumn get scoreUnitSnapshot => text().nullable()();
|
||||
TextColumn get sourceExerciseIdSnapshot => text().nullable()();
|
||||
DateTimeColumn get startedAt => dateTime().nullable()();
|
||||
DateTimeColumn get completedAt => dateTime().nullable()();
|
||||
TextColumn get status => text().withDefault(const Constant('completed'))();
|
||||
@ -821,6 +822,7 @@ class WorkoutHistoryStepResults extends SyncableTable {
|
||||
RealColumn get actualScore => real().nullable()();
|
||||
IntColumn get actualScoreTimeMs => integer().nullable()();
|
||||
TextColumn get note => text().nullable()();
|
||||
TextColumn get sourceExerciseIdSnapshot => text().nullable()();
|
||||
|
||||
@override
|
||||
List<String> get customConstraints => [
|
||||
|
||||
Reference in New Issue
Block a user