diff --git a/lib/services/data_transfer_service.dart b/lib/services/data_transfer_service.dart index 6c7455d..a0fd57b 100644 --- a/lib/services/data_transfer_service.dart +++ b/lib/services/data_transfer_service.dart @@ -18,6 +18,7 @@ class DataTransferService { /// Deletes all data from the database. static Future deleteAllData(BuildContext context) async { final db = Provider.of(context, listen: false); + await db.matchDao.deleteAllMatches(); await db.teamDao.deleteAllTeams(); await db.groupDao.deleteAllGroups(); @@ -96,8 +97,8 @@ class DataTransferService { /// Exports the given JSON string to a file with the specified name. /// Returns an [ExportResult] indicating the outcome. /// - /// [jsonString] The JSON string to be exported. - /// [fileName] The desired name for the exported file (without extension). + /// - [jsonString]: The JSON string to be exported. + /// - [fileName]: The desired name for the exported file (without extension). static Future exportData( String jsonString, String fileName, @@ -163,21 +164,22 @@ class DataTransferService { @visibleForTesting static Future importDataToDatabase( AppDatabase db, - Map decoded, + Map decodedJson, ) async { - final importedPlayers = parsePlayersFromJson(decoded); + // Fetch all entities first to create lookup maps for relationships + final importedPlayers = parsePlayersFromJson(decodedJson); final playerById = {for (final p in importedPlayers) p.id: p}; - final importedGames = parseGamesFromJson(decoded); + final importedGames = parseGamesFromJson(decodedJson); final gameById = {for (final g in importedGames) g.id: g}; - final importedGroups = parseGroupsFromJson(decoded, playerById); + final importedGroups = parseGroupsFromJson(decodedJson, playerById); final groupById = {for (final g in importedGroups) g.id: g}; - final importedTeams = parseTeamsFromJson(decoded, playerById); + final importedTeams = parseTeamsFromJson(decodedJson, playerById); final importedMatches = parseMatchesFromJson( - decoded, + decodedJson, gameById, groupById, playerById, @@ -190,31 +192,30 @@ class DataTransferService { await db.matchDao.addMatchAsList(matches: importedMatches); } - /// Parses players from JSON data. + /* Parsing Methods */ + @visibleForTesting - static List parsePlayersFromJson(Map decoded) { - final playersJson = (decoded['players'] as List?) ?? []; + static List parsePlayersFromJson(Map decodedJson) { + final playersJson = (decodedJson['players'] as List?) ?? []; return playersJson .map((p) => Player.fromJson(p as Map)) .toList(); } - /// Parses games from JSON data. @visibleForTesting - static List parseGamesFromJson(Map decoded) { - final gamesJson = (decoded['games'] as List?) ?? []; + static List parseGamesFromJson(Map decodedJson) { + final gamesJson = (decodedJson['games'] as List?) ?? []; return gamesJson .map((g) => Game.fromJson(g as Map)) .toList(); } - /// Parses groups from JSON data. @visibleForTesting static List parseGroupsFromJson( - Map decoded, + Map decodedJson, Map playerById, ) { - final groupsJson = (decoded['groups'] as List?) ?? []; + final groupsJson = (decodedJson['groups'] as List?) ?? []; return groupsJson.map((g) { final map = g as Map; final memberIds = (map['memberIds'] as List? ?? []) @@ -238,10 +239,10 @@ class DataTransferService { /// Parses teams from JSON data. @visibleForTesting static List parseTeamsFromJson( - Map decoded, + Map decodedJson, Map playerById, ) { - final teamsJson = (decoded['teams'] as List?) ?? []; + final teamsJson = (decodedJson['teams'] as List?) ?? []; return teamsJson.map((t) { final map = t as Map; final memberIds = (map['memberIds'] as List? ?? []) @@ -264,46 +265,53 @@ class DataTransferService { /// Parses matches from JSON data. @visibleForTesting static List parseMatchesFromJson( - Map decoded, - Map gameById, - Map groupById, - Map playerById, + Map decodedJson, + Map gamesMap, + Map groupsMap, + Map playersMap, ) { - final matchesJson = (decoded['matches'] as List?) ?? []; + final matchesJson = (decodedJson['matches'] as List?) ?? []; return matchesJson.map((m) { final map = m as Map; + // Extract attributes from json + final id = map['id'] as String; + final name = map['name'] as String; final gameId = map['gameId'] as String; final groupId = map['groupId'] as String?; - final playerIds = (map['playerIds'] as List? ?? []) - .cast(); + final createdAt = DateTime.parse(map['createdAt'] as String); final endedAt = map['endedAt'] != null ? DateTime.parse(map['endedAt'] as String) : null; + final notes = map['notes'] as String? ?? ''; - final game = gameById[gameId] ?? createUnknownGame(); - final group = groupId != null ? groupById[groupId] : null; + // Link attributes to objects + final game = gamesMap[gameId] ?? getFallbackGame(); + final group = groupId != null ? groupsMap[groupId] : null; + + final playerIds = (map['playerIds'] as List? ?? []) + .cast(); final players = playerIds - .map((id) => playerById[id]) + .map((id) => playersMap[id]) .whereType() .toList(); return Match( - id: map['id'] as String, - name: map['name'] as String, + id: id, + name: name, game: game, group: group, players: players, - createdAt: DateTime.parse(map['createdAt'] as String), + createdAt: createdAt, endedAt: endedAt, - notes: map['notes'] as String? ?? '', + notes: notes, ); }).toList(); } /// Creates a fallback game when the referenced game is not found. @visibleForTesting - static Game createUnknownGame() { + static Game getFallbackGame() { return Game( name: 'Unknown', ruleset: Ruleset.singleWinner, @@ -320,7 +328,8 @@ class DataTransferService { return null; } - /// Validates the given JSON string against the predefined schema. + /// Validates the given JSON string against the schema + /// in `assets/schema.json`. @visibleForTesting static Future validateJsonSchema(String jsonString) async { final String schemaString;