fix(exercice): sélection d'un score par défaut à 0 impossible (ticket #71)
Corrige la contrainte CHECK sur la table exercises (tables.dart) qui empêchait à tort une valeur de score par défaut à 0, et ajoute la migration Drift schemaVersion 12→13 reconstruisant la table avec la contrainte corrigée (app_database.dart). build_runner OK, test de régression ajouté. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -46,7 +46,7 @@ final class AppDatabase extends _$AppDatabase {
|
||||
}
|
||||
|
||||
@override
|
||||
int get schemaVersion => 12;
|
||||
int get schemaVersion => 13;
|
||||
|
||||
@override
|
||||
MigrationStrategy get migration {
|
||||
@ -97,6 +97,9 @@ final class AppDatabase extends _$AppDatabase {
|
||||
if (from < 12) {
|
||||
await _migrateToSchema12(migrator);
|
||||
}
|
||||
if (from < 13) {
|
||||
await _migrateToSchema13();
|
||||
}
|
||||
await _createIndexes();
|
||||
},
|
||||
beforeOpen: (details) async {
|
||||
@ -359,4 +362,111 @@ extension on AppDatabase {
|
||||
await migrator.createTable(shareInboxItems);
|
||||
await migrator.createTable(pendingShareActions);
|
||||
}
|
||||
|
||||
Future<void> _migrateToSchema13() async {
|
||||
await customStatement('PRAGMA foreign_keys = OFF');
|
||||
await customStatement('''
|
||||
CREATE TABLE exercises_new (
|
||||
id TEXT NOT NULL PRIMARY KEY,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL,
|
||||
deleted_at INTEGER,
|
||||
schema_version INTEGER NOT NULL DEFAULT 1,
|
||||
sync_state TEXT NOT NULL CHECK (sync_state IN ('localOnly', 'dirty', 'synced', 'deleted')),
|
||||
local_revision INTEGER NOT NULL CHECK (local_revision >= 0),
|
||||
origin_device_id TEXT NOT NULL,
|
||||
future_owner_profile_id TEXT,
|
||||
last_synced_at INTEGER,
|
||||
remote_revision TEXT,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
icon_media_id TEXT REFERENCES media_assets(id),
|
||||
video_media_id TEXT REFERENCES media_assets(id),
|
||||
has_time_measure INTEGER NOT NULL CHECK (has_time_measure IN (0, 1)),
|
||||
has_reps_measure INTEGER NOT NULL CHECK (has_reps_measure IN (0, 1)),
|
||||
has_score_measure INTEGER NOT NULL CHECK (has_score_measure IN (0, 1)),
|
||||
score_input_mode TEXT NOT NULL DEFAULT 'manual',
|
||||
score_label TEXT,
|
||||
score_unit TEXT,
|
||||
default_target_time_seconds INTEGER,
|
||||
default_target_reps INTEGER,
|
||||
default_target_score REAL,
|
||||
default_target_score_time_ms INTEGER,
|
||||
archived_at INTEGER,
|
||||
CHECK (length(trim(origin_device_id)) > 0),
|
||||
CHECK (length(trim(name)) > 0),
|
||||
CHECK (has_time_measure OR has_reps_measure OR has_score_measure),
|
||||
CHECK (score_input_mode IN ('manual', 'stopwatch')),
|
||||
CHECK (has_score_measure OR score_input_mode = 'manual'),
|
||||
CHECK (score_input_mode != 'manual' OR NOT has_score_measure OR (score_label IS NOT NULL AND length(trim(score_label)) > 0 AND score_unit IS NOT NULL AND length(trim(score_unit)) > 0)),
|
||||
CHECK (default_target_time_seconds IS NULL OR default_target_time_seconds > 0),
|
||||
CHECK (default_target_reps IS NULL OR default_target_reps > 0),
|
||||
CHECK (default_target_score IS NULL OR default_target_score >= 0),
|
||||
CHECK (default_target_score_time_ms IS NULL OR default_target_score_time_ms > 0),
|
||||
CHECK (future_owner_profile_id IS NULL OR length(trim(future_owner_profile_id)) > 0),
|
||||
CHECK (remote_revision IS NULL OR length(trim(remote_revision)) > 0)
|
||||
)
|
||||
''');
|
||||
await customStatement('''
|
||||
INSERT INTO exercises_new (
|
||||
id,
|
||||
created_at,
|
||||
updated_at,
|
||||
deleted_at,
|
||||
schema_version,
|
||||
sync_state,
|
||||
local_revision,
|
||||
origin_device_id,
|
||||
future_owner_profile_id,
|
||||
last_synced_at,
|
||||
remote_revision,
|
||||
name,
|
||||
description,
|
||||
icon_media_id,
|
||||
video_media_id,
|
||||
has_time_measure,
|
||||
has_reps_measure,
|
||||
has_score_measure,
|
||||
score_input_mode,
|
||||
score_label,
|
||||
score_unit,
|
||||
default_target_time_seconds,
|
||||
default_target_reps,
|
||||
default_target_score,
|
||||
default_target_score_time_ms,
|
||||
archived_at
|
||||
)
|
||||
SELECT
|
||||
id,
|
||||
created_at,
|
||||
updated_at,
|
||||
deleted_at,
|
||||
schema_version,
|
||||
sync_state,
|
||||
local_revision,
|
||||
origin_device_id,
|
||||
future_owner_profile_id,
|
||||
last_synced_at,
|
||||
remote_revision,
|
||||
name,
|
||||
description,
|
||||
icon_media_id,
|
||||
video_media_id,
|
||||
has_time_measure,
|
||||
has_reps_measure,
|
||||
has_score_measure,
|
||||
score_input_mode,
|
||||
score_label,
|
||||
score_unit,
|
||||
default_target_time_seconds,
|
||||
default_target_reps,
|
||||
default_target_score,
|
||||
default_target_score_time_ms,
|
||||
archived_at
|
||||
FROM exercises
|
||||
''');
|
||||
await customStatement('DROP TABLE exercises');
|
||||
await customStatement('ALTER TABLE exercises_new RENAME TO exercises');
|
||||
await customStatement('PRAGMA foreign_keys = ON');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user