import 'package:drift/drift.dart'; import '../../application/application.dart'; import '../../domain/domain.dart' as domain; import 'app_database.dart' as db; final class DriftExerciseRepository implements ExerciseRepository { const DriftExerciseRepository(this.database); final db.AppDatabase database; @override Future findById(String id) async { final row = await (database.select( database.exercises, )..where((table) => table.id.equals(id))).getSingleOrNull(); return row == null ? null : _exerciseFromRow(row); } @override Future> listActive() async { final rows = await (database.select(database.exercises) ..where( (table) => table.deletedAt.isNull() & table.archivedAt.isNull(), ) ..orderBy([(table) => OrderingTerm.asc(table.name)])) .get(); return rows.map(_exerciseFromRow).toList(); } @override Future isReferencedByProgram(String id) async { final row = await (database.select(database.programExercises) ..where( (table) => table.deletedAt.isNull() & table.sourceExerciseId.equals(id), ) ..limit(1)) .getSingleOrNull(); return row != null; } @override Future save(domain.Exercise exercise) async { await database .into(database.exercises) .insertOnConflictUpdate(_exerciseCompanion(exercise)); } } final class DriftMediaAssetRepository implements MediaAssetRepository { const DriftMediaAssetRepository(this.database); final db.AppDatabase database; @override Future findById(String id) async { final row = await (database.select( database.mediaAssets, )..where((table) => table.id.equals(id))).getSingleOrNull(); return row == null ? null : _mediaAssetFromRow(row); } @override Future> listActive() async { final rows = await (database.select( database.mediaAssets, )..where((table) => table.deletedAt.isNull())).get(); return rows.map(_mediaAssetFromRow).toList(); } @override Future save(domain.MediaAsset mediaAsset) async { await database .into(database.mediaAssets) .insertOnConflictUpdate(_mediaAssetCompanion(mediaAsset)); } } final class DriftProgramRepository implements ProgramRepository { const DriftProgramRepository(this.database); final db.AppDatabase database; @override Future findById(String id) async { final query = database.select(database.programs) ..where((table) => table.id.equals(id) & table.deletedAt.isNull()); final row = await query.getSingleOrNull(); if (row == null) { return null; } final exercises = await (database.select(database.programExercises) ..where( (table) => table.programId.equals(id) & table.deletedAt.isNull(), ) ..orderBy([(table) => OrderingTerm.asc(table.position)])) .get(); return _programFromRow( row, exercises.map(_programExerciseFromRow).toList(), ); } @override Future> listActive() async { final rows = await (database.select(database.programs) ..where((table) => table.deletedAt.isNull()) ..orderBy([(table) => OrderingTerm.asc(table.name)])) .get(); final programs = []; for (final row in rows) { final exercises = await (database.select(database.programExercises) ..where( (table) => table.programId.equals(row.id) & table.deletedAt.isNull(), ) ..orderBy([(table) => OrderingTerm.asc(table.position)])) .get(); programs.add( _programFromRow(row, exercises.map(_programExerciseFromRow).toList()), ); } return programs; } @override Future save(domain.Program program) async { await database .into(database.programs) .insertOnConflictUpdate(_programCompanion(program)); for (final exercise in program.exercises) { await saveExercise(exercise); } } @override Future saveExercise(domain.ProgramExercise exercise) async { await database .into(database.programExercises) .insertOnConflictUpdate(_programExerciseCompanion(exercise)); } @override Future replaceExercises( domain.Program program, DateTime deletedAt, ) async { await database.transaction(() async { await save(program); final activeIds = program.exercises .map((exercise) => exercise.metadata.id) .toSet(); final update = database.update(database.programExercises); if (activeIds.isEmpty) { update.where( (table) => table.programId.equals(program.metadata.id) & table.deletedAt.isNull(), ); } else { update.where( (table) => table.programId.equals(program.metadata.id) & table.deletedAt.isNull() & table.id.isNotIn(activeIds), ); } await update.write( db.ProgramExercisesCompanion( deletedAt: Value(deletedAt), updatedAt: Value(deletedAt), ), ); }); } } final class DriftWorkoutTemplateRepository implements WorkoutTemplateRepository { const DriftWorkoutTemplateRepository(this.database); final db.AppDatabase database; @override Future findById(String id) async { final row = await (database.select( database.workoutTemplates, )..where((table) => table.id.equals(id) & table.deletedAt.isNull())) .getSingleOrNull(); if (row == null) { return null; } final programs = await (database.select(database.workoutTemplatePrograms) ..where( (table) => table.workoutTemplateId.equals(id) & table.deletedAt.isNull(), ) ..orderBy([(table) => OrderingTerm.asc(table.position)])) .get(); final programIds = programs.map((program) => program.id).toSet(); final overrides = programIds.isEmpty ? [] : await (database.select(database.workoutTemplateExerciseOverrides) ..where( (table) => table.workoutTemplateProgramId.isIn(programIds) & table.deletedAt.isNull(), )) .get(); return _workoutTemplateFromRow( row, programs.map(_workoutTemplateProgramFromRow).toList(), overrides.map(_workoutTemplateExerciseOverrideFromRow).toList(), ); } @override Future> listActive() async { final rows = await (database.select(database.workoutTemplates) ..where((table) => table.deletedAt.isNull()) ..orderBy([(table) => OrderingTerm.asc(table.name)])) .get(); final templates = []; for (final row in rows) { final template = await findById(row.id); if (template != null) { templates.add(template); } } return templates; } @override Future save(domain.WorkoutTemplate template) async { await database .into(database.workoutTemplates) .insertOnConflictUpdate(_workoutTemplateCompanion(template)); for (final program in template.programs) { await saveProgram(program); } for (final override in template.overrides) { await saveOverride(override); } } @override Future saveProgram(domain.WorkoutTemplateProgram program) async { await database .into(database.workoutTemplatePrograms) .insertOnConflictUpdate(_workoutTemplateProgramCompanion(program)); } @override Future saveOverride( domain.WorkoutTemplateExerciseOverride override, ) async { await database .into(database.workoutTemplateExerciseOverrides) .insertOnConflictUpdate( _workoutTemplateExerciseOverrideCompanion(override), ); } @override Future replaceComposition( domain.WorkoutTemplate template, DateTime deletedAt, ) async { await database.transaction(() async { final previousPrograms = await (database.select(database.workoutTemplatePrograms)..where( (table) => table.workoutTemplateId.equals(template.metadata.id) & table.deletedAt.isNull(), )) .get(); final previousProgramIds = previousPrograms .map((program) => program.id) .toSet(); await save(template); final activeProgramIds = template.programs .map((program) => program.metadata.id) .toSet(); final programUpdate = database.update(database.workoutTemplatePrograms); if (activeProgramIds.isEmpty) { programUpdate.where( (table) => table.workoutTemplateId.equals(template.metadata.id) & table.deletedAt.isNull(), ); } else { programUpdate.where( (table) => table.workoutTemplateId.equals(template.metadata.id) & table.deletedAt.isNull() & table.id.isNotIn(activeProgramIds), ); } await programUpdate.write( db.WorkoutTemplateProgramsCompanion( deletedAt: Value(deletedAt), updatedAt: Value(deletedAt), ), ); final activeOverrideIds = template.overrides .map((override) => override.metadata.id) .toSet(); final relevantProgramIds = {...previousProgramIds, ...activeProgramIds}; if (relevantProgramIds.isEmpty) { return; } final overrideUpdate = database.update( database.workoutTemplateExerciseOverrides, ); if (activeOverrideIds.isEmpty) { overrideUpdate.where( (table) => table.workoutTemplateProgramId.isIn(relevantProgramIds) & table.deletedAt.isNull(), ); } else { overrideUpdate.where( (table) => table.workoutTemplateProgramId.isIn(relevantProgramIds) & table.deletedAt.isNull() & table.id.isNotIn(activeOverrideIds), ); } await overrideUpdate.write( db.WorkoutTemplateExerciseOverridesCompanion( deletedAt: Value(deletedAt), updatedAt: Value(deletedAt), ), ); }); } } final class DriftActiveSessionRepository implements ActiveSessionRepository { const DriftActiveSessionRepository(this.database); final db.AppDatabase database; @override Future findById(String id) async { final row = await (database.select( database.activeWorkoutSessions, )..where((table) => table.id.equals(id))).getSingleOrNull(); return row == null ? null : _activeWorkoutSessionFromRow(row); } @override Future findOpen() async { final row = await (database.select(database.activeWorkoutSessions) ..where( (table) => table.deletedAt.isNull() & table.status.isIn(['running', 'paused', 'savedExit']), ) ..orderBy([(table) => OrderingTerm.desc(table.updatedAt)]) ..limit(1)) .getSingleOrNull(); return row == null ? null : _activeWorkoutSessionFromRow(row); } @override Future save(domain.ActiveWorkoutSession session) async { await database .into(database.activeWorkoutSessions) .insertOnConflictUpdate(_activeWorkoutSessionCompanion(session)); } @override Future saveSetResult(domain.ActiveSetResult result) async { await database .into(database.activeSetResults) .insertOnConflictUpdate(_activeSetResultCompanion(result)); } @override Future saveRestState(domain.ActiveRestState restState) async { await database .into(database.activeRestStates) .insertOnConflictUpdate(_activeRestStateCompanion(restState)); } @override Future> listSetResults(String sessionId) async { final rows = await (database.select(database.activeSetResults) ..where((table) => table.activeWorkoutSessionId.equals(sessionId)) ..orderBy([ (table) => OrderingTerm.asc(table.programIndex), (table) => OrderingTerm.asc(table.exerciseIndex), (table) => OrderingTerm.asc(table.setIndex), ])) .get(); return rows.map(_activeSetResultFromRow).toList(); } @override Future> listRestStates(String sessionId) async { final rows = await (database.select(database.activeRestStates) ..where((table) => table.activeWorkoutSessionId.equals(sessionId)) ..orderBy([(table) => OrderingTerm.asc(table.startedAt)])) .get(); return rows.map(_activeRestStateFromRow).toList(); } } final class DriftWorkoutHistoryRepository implements WorkoutHistoryRepository { const DriftWorkoutHistoryRepository(this.database); final db.AppDatabase database; @override Future save(domain.WorkoutHistory history) async { await database .into(database.workoutHistories) .insertOnConflictUpdate(_workoutHistoryCompanion(history)); for (final result in history.results) { await saveSetResult(result); } } @override Future saveSetResult(domain.WorkoutHistorySetResult result) async { await database .into(database.workoutHistorySetResults) .insertOnConflictUpdate(_workoutHistorySetResultCompanion(result)); } } domain.EntityMetadata _metadataFromRow(dynamic row) { return domain.EntityMetadata( id: row.id as String, createdAt: row.createdAt as DateTime, updatedAt: row.updatedAt as DateTime, deletedAt: row.deletedAt as DateTime?, schemaVersion: row.schemaVersion as int, syncState: _syncStateFromDb(row.syncState as String), localRevision: row.localRevision as int, originDeviceId: row.originDeviceId as String, futureOwnerProfileId: row.futureOwnerProfileId as String?, lastSyncedAt: row.lastSyncedAt as DateTime?, remoteRevision: row.remoteRevision as String?, ); } List> _metadataValues(domain.EntityMetadata metadata) => [ Value(metadata.id), Value(metadata.createdAt), Value(metadata.updatedAt), Value(metadata.deletedAt), Value(metadata.schemaVersion), Value(_syncStateToDb(metadata.syncState)), Value(metadata.localRevision), Value(metadata.originDeviceId), Value(metadata.futureOwnerProfileId), Value(metadata.lastSyncedAt), Value(metadata.remoteRevision), ]; db.ExercisesCompanion _exerciseCompanion(domain.Exercise exercise) { final values = _metadataValues(exercise.metadata); return db.ExercisesCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, name: Value(exercise.name), description: Value(exercise.description), imageMediaId: Value(exercise.imageMediaId), videoMediaId: Value(exercise.videoMediaId), hasTimeMeasure: Value(exercise.hasTimeMeasure), hasRepsMeasure: Value(exercise.hasRepsMeasure), hasScoreMeasure: Value(exercise.hasScoreMeasure), scoreLabel: Value(exercise.scoreLabel), scoreUnit: Value(exercise.scoreUnit), archivedAt: Value(exercise.archivedAt), ); } domain.Exercise _exerciseFromRow(db.Exercise row) { return domain.Exercise( metadata: _metadataFromRow(row), name: row.name, description: row.description, imageMediaId: row.imageMediaId, videoMediaId: row.videoMediaId, hasTimeMeasure: row.hasTimeMeasure, hasRepsMeasure: row.hasRepsMeasure, hasScoreMeasure: row.hasScoreMeasure, scoreLabel: row.scoreLabel, scoreUnit: row.scoreUnit, archivedAt: row.archivedAt, ); } db.MediaAssetsCompanion _mediaAssetCompanion(domain.MediaAsset asset) { final values = _metadataValues(asset.metadata); return db.MediaAssetsCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, kind: Value(_mediaKindToDb(asset.kind)), localUri: Value(asset.localUri), mimeType: Value(asset.mimeType), sizeBytes: Value(asset.sizeBytes), width: Value(asset.width), height: Value(asset.height), durationMs: Value(asset.durationMs), checksum: Value(asset.checksum), remoteUri: Value(asset.remoteUri), thumbnailLocalUri: Value(asset.thumbnailLocalUri), ); } domain.MediaAsset _mediaAssetFromRow(db.MediaAsset row) { return domain.MediaAsset( metadata: _metadataFromRow(row), kind: _mediaKindFromDb(row.kind), localUri: row.localUri, mimeType: row.mimeType, sizeBytes: row.sizeBytes, width: row.width, height: row.height, durationMs: row.durationMs, checksum: row.checksum, remoteUri: row.remoteUri, thumbnailLocalUri: row.thumbnailLocalUri, ); } db.ProgramsCompanion _programCompanion(domain.Program program) { final values = _metadataValues(program.metadata); return db.ProgramsCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, name: Value(program.name), defaultRestSeconds: Value(program.defaultRestSeconds), ); } domain.Program _programFromRow( db.Program row, List exercises, ) { return domain.Program( metadata: _metadataFromRow(row), name: row.name, defaultRestSeconds: row.defaultRestSeconds, exercises: exercises, ); } db.ProgramExercisesCompanion _programExerciseCompanion( domain.ProgramExercise exercise, ) { final values = _metadataValues(exercise.metadata); return db.ProgramExercisesCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, programId: Value(exercise.programId), sourceExerciseId: Value(exercise.sourceExerciseId), position: Value(exercise.position), exerciseNameSnapshot: Value(exercise.exerciseNameSnapshot), exerciseDescriptionSnapshot: Value(exercise.exerciseDescriptionSnapshot), exerciseImageMediaIdSnapshot: Value(exercise.exerciseImageMediaIdSnapshot), exerciseVideoMediaIdSnapshot: Value(exercise.exerciseVideoMediaIdSnapshot), exerciseArchivedSnapshot: Value(exercise.exerciseArchivedSnapshot), availableTimeSnapshot: Value(exercise.availableTimeSnapshot), availableRepsSnapshot: Value(exercise.availableRepsSnapshot), availableScoreSnapshot: Value(exercise.availableScoreSnapshot), scoreLabelSnapshot: Value(exercise.scoreLabelSnapshot), scoreUnitSnapshot: Value(exercise.scoreUnitSnapshot), setsCount: Value(exercise.setsCount), timeEnabled: Value(exercise.timeEnabled), repsEnabled: Value(exercise.repsEnabled), scoreEnabled: Value(exercise.scoreEnabled), targetTimeSeconds: Value(exercise.targetTimeSeconds), targetReps: Value(exercise.targetReps), targetScore: Value(exercise.targetScore), restSecondsOverride: Value(exercise.restSecondsOverride), ); } domain.ProgramExercise _programExerciseFromRow(db.ProgramExercise row) { return domain.ProgramExercise( metadata: _metadataFromRow(row), programId: row.programId, sourceExerciseId: row.sourceExerciseId, position: row.position, exerciseNameSnapshot: row.exerciseNameSnapshot, exerciseDescriptionSnapshot: row.exerciseDescriptionSnapshot, exerciseImageMediaIdSnapshot: row.exerciseImageMediaIdSnapshot, exerciseVideoMediaIdSnapshot: row.exerciseVideoMediaIdSnapshot, exerciseArchivedSnapshot: row.exerciseArchivedSnapshot, availableTimeSnapshot: row.availableTimeSnapshot, availableRepsSnapshot: row.availableRepsSnapshot, availableScoreSnapshot: row.availableScoreSnapshot, scoreLabelSnapshot: row.scoreLabelSnapshot, scoreUnitSnapshot: row.scoreUnitSnapshot, setsCount: row.setsCount, timeEnabled: row.timeEnabled, repsEnabled: row.repsEnabled, scoreEnabled: row.scoreEnabled, targetTimeSeconds: row.targetTimeSeconds, targetReps: row.targetReps, targetScore: row.targetScore, restSecondsOverride: row.restSecondsOverride, ); } db.WorkoutTemplatesCompanion _workoutTemplateCompanion( domain.WorkoutTemplate template, ) { final values = _metadataValues(template.metadata); return db.WorkoutTemplatesCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, name: Value(template.name), lastStartedAt: Value(template.lastStartedAt), ); } domain.WorkoutTemplate _workoutTemplateFromRow( db.WorkoutTemplate row, List programs, List overrides, ) { return domain.WorkoutTemplate( metadata: _metadataFromRow(row), name: row.name, lastStartedAt: row.lastStartedAt, programs: programs, overrides: overrides, ); } db.WorkoutTemplateProgramsCompanion _workoutTemplateProgramCompanion( domain.WorkoutTemplateProgram program, ) { final values = _metadataValues(program.metadata); return db.WorkoutTemplateProgramsCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, workoutTemplateId: Value(program.workoutTemplateId), sourceProgramId: Value(program.sourceProgramId), position: Value(program.position), programNameSnapshot: Value(program.programNameSnapshot), defaultRestSecondsSnapshot: Value(program.defaultRestSecondsSnapshot), programSnapshotJson: Value(program.programSnapshotJson), ); } domain.WorkoutTemplateProgram _workoutTemplateProgramFromRow( db.WorkoutTemplateProgram row, ) { return domain.WorkoutTemplateProgram( metadata: _metadataFromRow(row), workoutTemplateId: row.workoutTemplateId, sourceProgramId: row.sourceProgramId, position: row.position, programNameSnapshot: row.programNameSnapshot, defaultRestSecondsSnapshot: row.defaultRestSecondsSnapshot, programSnapshotJson: row.programSnapshotJson, ); } db.WorkoutTemplateExerciseOverridesCompanion _workoutTemplateExerciseOverrideCompanion( domain.WorkoutTemplateExerciseOverride override, ) { final values = _metadataValues(override.metadata); return db.WorkoutTemplateExerciseOverridesCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, workoutTemplateProgramId: Value(override.workoutTemplateProgramId), snapshotProgramExerciseId: Value(override.snapshotProgramExerciseId), setsCountOverride: Value(override.setsCountOverride), targetTimeSecondsOverride: Value(override.targetTimeSecondsOverride), targetRepsOverride: Value(override.targetRepsOverride), targetScoreOverride: Value(override.targetScoreOverride), ); } domain.WorkoutTemplateExerciseOverride _workoutTemplateExerciseOverrideFromRow( db.WorkoutTemplateExerciseOverride row, ) { return domain.WorkoutTemplateExerciseOverride( metadata: _metadataFromRow(row), workoutTemplateProgramId: row.workoutTemplateProgramId, snapshotProgramExerciseId: row.snapshotProgramExerciseId, setsCountOverride: row.setsCountOverride, targetTimeSecondsOverride: row.targetTimeSecondsOverride, targetRepsOverride: row.targetRepsOverride, targetScoreOverride: row.targetScoreOverride, ); } db.ActiveWorkoutSessionsCompanion _activeWorkoutSessionCompanion( domain.ActiveWorkoutSession session, ) { final values = _metadataValues(session.metadata); return db.ActiveWorkoutSessionsCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, sourceWorkoutTemplateId: Value(session.sourceWorkoutTemplateId), status: Value(_activeStatusToDb(session.status)), startedAt: Value(session.startedAt), pausedAt: Value(session.pausedAt), endedAt: Value(session.endedAt), lastPersistedAt: Value(session.lastPersistedAt), elapsedActiveMs: Value(session.elapsedActiveMs), currentProgramIndex: Value(session.currentProgramIndex), currentExerciseIndex: Value(session.currentExerciseIndex), currentSetIndex: Value(session.currentSetIndex), resolvedTemplateSnapshotJson: Value(session.resolvedTemplateSnapshotJson), ); } domain.ActiveWorkoutSession _activeWorkoutSessionFromRow( db.ActiveWorkoutSession row, ) { return domain.ActiveWorkoutSession( metadata: _metadataFromRow(row), sourceWorkoutTemplateId: row.sourceWorkoutTemplateId, status: _activeStatusFromDb(row.status), startedAt: row.startedAt, pausedAt: row.pausedAt, endedAt: row.endedAt, lastPersistedAt: row.lastPersistedAt, elapsedActiveMs: row.elapsedActiveMs, currentProgramIndex: row.currentProgramIndex, currentExerciseIndex: row.currentExerciseIndex, currentSetIndex: row.currentSetIndex, resolvedTemplateSnapshotJson: row.resolvedTemplateSnapshotJson, ); } db.ActiveSetResultsCompanion _activeSetResultCompanion( domain.ActiveSetResult result, ) { final values = _metadataValues(result.metadata); return db.ActiveSetResultsCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, activeWorkoutSessionId: Value(result.activeWorkoutSessionId), programSnapshotId: Value(result.programSnapshotId), exerciseSnapshotId: Value(result.exerciseSnapshotId), programIndex: Value(result.programIndex), exerciseIndex: Value(result.exerciseIndex), setIndex: Value(result.setIndex), startedAt: Value(result.startedAt), completedAt: Value(result.completedAt), actualTimeMs: Value(result.actualTimeMs), actualReps: Value(result.actualReps), actualScore: Value(result.actualScore), scoreLabelSnapshot: Value(result.scoreLabelSnapshot), scoreUnitSnapshot: Value(result.scoreUnitSnapshot), note: Value(result.note), ); } domain.ActiveSetResult _activeSetResultFromRow(db.ActiveSetResult row) { return domain.ActiveSetResult( metadata: _metadataFromRow(row), activeWorkoutSessionId: row.activeWorkoutSessionId, programSnapshotId: row.programSnapshotId, exerciseSnapshotId: row.exerciseSnapshotId, programIndex: row.programIndex, exerciseIndex: row.exerciseIndex, setIndex: row.setIndex, startedAt: row.startedAt, completedAt: row.completedAt, actualTimeMs: row.actualTimeMs, actualReps: row.actualReps, actualScore: row.actualScore, scoreLabelSnapshot: row.scoreLabelSnapshot, scoreUnitSnapshot: row.scoreUnitSnapshot, note: row.note, ); } db.ActiveRestStatesCompanion _activeRestStateCompanion( domain.ActiveRestState restState, ) { final values = _metadataValues(restState.metadata); return db.ActiveRestStatesCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, activeWorkoutSessionId: Value(restState.activeWorkoutSessionId), afterProgramIndex: Value(restState.afterProgramIndex), afterExerciseIndex: Value(restState.afterExerciseIndex), afterSetIndex: Value(restState.afterSetIndex), plannedRestSeconds: Value(restState.plannedRestSeconds), adjustedRestSeconds: Value(restState.adjustedRestSeconds), startedAt: Value(restState.startedAt), endedAt: Value(restState.endedAt), skippedAt: Value(restState.skippedAt), ); } domain.ActiveRestState _activeRestStateFromRow(db.ActiveRestState row) { return domain.ActiveRestState( metadata: _metadataFromRow(row), activeWorkoutSessionId: row.activeWorkoutSessionId, afterProgramIndex: row.afterProgramIndex, afterExerciseIndex: row.afterExerciseIndex, afterSetIndex: row.afterSetIndex, plannedRestSeconds: row.plannedRestSeconds, adjustedRestSeconds: row.adjustedRestSeconds, startedAt: row.startedAt, endedAt: row.endedAt, skippedAt: row.skippedAt, ); } db.WorkoutHistoriesCompanion _workoutHistoryCompanion( domain.WorkoutHistory history, ) { final values = _metadataValues(history.metadata); return db.WorkoutHistoriesCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, sourceWorkoutTemplateId: Value(history.sourceWorkoutTemplateId), sourceActiveWorkoutSessionId: Value(history.sourceActiveWorkoutSessionId), nameSnapshot: Value(history.nameSnapshot), startedAt: Value(history.startedAt), endedAt: Value(history.endedAt), totalActiveMs: Value(history.totalActiveMs), completed: Value(history.completed), historySnapshotJson: Value(history.historySnapshotJson), ); } db.WorkoutHistorySetResultsCompanion _workoutHistorySetResultCompanion( domain.WorkoutHistorySetResult result, ) { final values = _metadataValues(result.metadata); return db.WorkoutHistorySetResultsCompanion( id: values[0] as Value, createdAt: values[1] as Value, updatedAt: values[2] as Value, deletedAt: values[3] as Value, schemaVersion: values[4] as Value, syncState: values[5] as Value, localRevision: values[6] as Value, originDeviceId: values[7] as Value, futureOwnerProfileId: values[8] as Value, lastSyncedAt: values[9] as Value, remoteRevision: values[10] as Value, workoutHistoryId: Value(result.workoutHistoryId), programSnapshotId: Value(result.programSnapshotId), exerciseSnapshotId: Value(result.exerciseSnapshotId), programIndex: Value(result.programIndex), exerciseIndex: Value(result.exerciseIndex), setIndex: Value(result.setIndex), programNameSnapshot: Value(result.programNameSnapshot), exerciseNameSnapshot: Value(result.exerciseNameSnapshot), timeEnabledSnapshot: Value(result.timeEnabledSnapshot), repsEnabledSnapshot: Value(result.repsEnabledSnapshot), scoreEnabledSnapshot: Value(result.scoreEnabledSnapshot), targetTimeSecondsSnapshot: Value(result.targetTimeSecondsSnapshot), targetRepsSnapshot: Value(result.targetRepsSnapshot), targetScoreSnapshot: Value(result.targetScoreSnapshot), actualTimeMs: Value(result.actualTimeMs), actualReps: Value(result.actualReps), actualScore: Value(result.actualScore), scoreLabelSnapshot: Value(result.scoreLabelSnapshot), scoreUnitSnapshot: Value(result.scoreUnitSnapshot), startedAt: Value(result.startedAt), completedAt: Value(result.completedAt), ); } String _syncStateToDb(domain.SyncState state) => switch (state) { domain.SyncState.localOnly => 'localOnly', domain.SyncState.dirty => 'dirty', domain.SyncState.synced => 'synced', domain.SyncState.deleted => 'deleted', }; domain.SyncState _syncStateFromDb(String value) => switch (value) { 'localOnly' => domain.SyncState.localOnly, 'dirty' => domain.SyncState.dirty, 'synced' => domain.SyncState.synced, 'deleted' => domain.SyncState.deleted, _ => throw domain.DomainException('Unknown sync state: $value'), }; String _activeStatusToDb(domain.ActiveWorkoutStatus status) => switch (status) { domain.ActiveWorkoutStatus.running => 'running', domain.ActiveWorkoutStatus.paused => 'paused', domain.ActiveWorkoutStatus.savedExit => 'savedExit', domain.ActiveWorkoutStatus.completed => 'completed', domain.ActiveWorkoutStatus.abandoned => 'abandoned', }; String _mediaKindToDb(domain.MediaKind kind) => switch (kind) { domain.MediaKind.image => 'image', domain.MediaKind.video => 'video', }; domain.MediaKind _mediaKindFromDb(String value) => switch (value) { 'image' => domain.MediaKind.image, 'video' => domain.MediaKind.video, _ => throw domain.DomainException('Unknown media kind: $value'), }; domain.ActiveWorkoutStatus _activeStatusFromDb(String value) => switch (value) { 'running' => domain.ActiveWorkoutStatus.running, 'paused' => domain.ActiveWorkoutStatus.paused, 'savedExit' => domain.ActiveWorkoutStatus.savedExit, 'completed' => domain.ActiveWorkoutStatus.completed, 'abandoned' => domain.ActiveWorkoutStatus.abandoned, _ => throw domain.DomainException('Unknown active workout status: $value'), };