Updated player-match dao and tests

This commit is contained in:
2026-05-01 16:49:33 +02:00
parent f49440367c
commit cbc8a1afce
3 changed files with 415 additions and 694 deletions

View File

@@ -270,8 +270,9 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
if (row.groupId != null) {
group = await db.groupDao.getGroupById(groupId: row.groupId!);
}
final players =
await db.playerMatchDao.getPlayersOfMatch(matchId: row.id) ?? [];
final players = await db.playerMatchDao.getPlayersOfMatch(
matchId: row.id,
);
final scores = await db.scoreEntryDao.getAllMatchScores(
matchId: row.id,
@@ -307,8 +308,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
group = await db.groupDao.getGroupById(groupId: result.groupId!);
}
final players =
await db.playerMatchDao.getPlayersOfMatch(matchId: matchId) ?? [];
final players = await db.playerMatchDao.getPlayersOfMatch(matchId: matchId);
final scores = await db.scoreEntryDao.getAllMatchScores(matchId: matchId);
@@ -338,8 +338,9 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
rows.map((row) async {
final game = await db.gameDao.getGameById(gameId: row.gameId);
final group = await db.groupDao.getGroupById(groupId: groupId);
final players =
await db.playerMatchDao.getPlayersOfMatch(matchId: row.id) ?? [];
final players = await db.playerMatchDao.getPlayersOfMatch(
matchId: row.id,
);
final teams = await _getMatchTeams(matchId: row.id);
return Match(
id: row.id,
@@ -447,40 +448,6 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
return rowsAffected > 0;
}
/// Replaces all players in a match with the provided list of players.
/// Removes all existing players from the match and adds the new players.
/// Also adds any new players to the player table if they don't exist.
Future<void> updateMatchPlayers({
required String matchId,
required List<Player> newPlayers,
}) async {
await db.transaction(() async {
// Remove all existing players from the match
final deleteQuery = delete(db.playerMatchTable)
..where((p) => p.matchId.equals(matchId));
await deleteQuery.go();
// Add new players to the player table if they don't exist
await Future.wait(
newPlayers.map((player) async {
if (!await db.playerDao.playerExists(playerId: player.id)) {
await db.playerDao.addPlayer(player: player);
}
}),
);
// Add the new players to the match
await Future.wait(
newPlayers.map(
(player) => db.playerMatchDao.addPlayerToMatch(
matchId: matchId,
playerId: player.id,
),
),
);
});
}
/* Delete */
/// Deletes the match with the given [matchId] from the database.

View File

@@ -11,14 +11,16 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
with _$PlayerMatchDaoMixin {
PlayerMatchDao(super.db);
/* Create */
/// Associates a player with a match by inserting a record into the
/// [PlayerMatchTable]. Optionally associates with a team and sets initial score.
Future<void> addPlayerToMatch({
Future<bool> addPlayerToMatch({
required String matchId,
required String playerId,
String? teamId,
}) async {
await into(playerMatchTable).insert(
final rowsAffected = await into(playerMatchTable).insert(
PlayerMatchTableCompanion.insert(
playerId: playerId,
matchId: matchId,
@@ -26,42 +28,14 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
),
mode: InsertMode.insertOrReplace,
);
}
/// Retrieves a list of [Player]s associated with the given [matchId].
/// Returns null if no players are found.
Future<List<Player>?> getPlayersOfMatch({required String matchId}) async {
final result = await (select(
playerMatchTable,
)..where((p) => p.matchId.equals(matchId))).get();
if (result.isEmpty) return null;
final futures = result.map(
(row) => db.playerDao.getPlayerById(playerId: row.playerId),
);
final players = await Future.wait(futures);
return players;
}
/// Updates the team for a player in a match.
/// Returns `true` if the update was successful, otherwise `false`.
Future<bool> updatePlayerTeam({
required String matchId,
required String playerId,
required String? teamId,
}) async {
final rowsAffected =
await (update(playerMatchTable)..where(
(p) => p.matchId.equals(matchId) & p.playerId.equals(playerId),
))
.write(PlayerMatchTableCompanion(teamId: Value(teamId)));
return rowsAffected > 0;
}
/* Read */
/// Checks if there are any players associated with the given [matchId].
/// Returns `true` if there are players, otherwise `false`.
Future<bool> matchHasPlayers({required String matchId}) async {
Future<bool> hasMatchPlayers({required String matchId}) async {
final count =
await (selectOnly(playerMatchTable)
..where(playerMatchTable.matchId.equals(matchId))
@@ -87,32 +61,80 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
return (count ?? 0) > 0;
}
/// Removes the association of a player with a match by deleting the record
/// from the [PlayerMatchTable].
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> removePlayerFromMatch({
/// Retrieves a list of [Player]s associated with the given [matchId].
/// Returns empty list if no players are found.
Future<List<Player>> getPlayersOfMatch({required String matchId}) async {
final result = await (select(
playerMatchTable,
)..where((p) => p.matchId.equals(matchId))).get();
if (result.isEmpty) return [];
final futures = result.map(
(row) => db.playerDao.getPlayerById(playerId: row.playerId),
);
final players = await Future.wait(futures);
return players;
}
/// Retrieves a list of [Player]s associated with a specific team in a match.
/// Returns empty list if no players are found for the team in the match.
Future<List<Player>> getPlayersOfTeamInMatch({
required String matchId,
required String teamId,
}) async {
final result =
await (select(playerMatchTable)
..where((p) => p.matchId.equals(matchId))
..where((p) => p.teamId.equals(teamId)))
.get();
if (result.isEmpty) return [];
final futures = result.map(
(row) => db.playerDao.getPlayerById(playerId: row.playerId),
);
final players = await Future.wait(futures);
return players;
}
/* Updated */
/// Updates the team for a player in a match.
/// Returns `true` if the update was successful, otherwise `false`.
Future<bool> updatePlayersTeam({
required String matchId,
required String playerId,
required String? teamId,
}) async {
final query = delete(playerMatchTable)
..where((pg) => pg.matchId.equals(matchId))
..where((pg) => pg.playerId.equals(playerId));
final rowsAffected = await query.go();
final rowsAffected =
await (update(playerMatchTable)..where(
(p) => p.matchId.equals(matchId) & p.playerId.equals(playerId),
))
.write(PlayerMatchTableCompanion(teamId: Value(teamId)));
return rowsAffected > 0;
}
/// Updates the players associated with a match based on the provided
/// [newPlayer] list. It adds new players and removes players that are no
/// longer associated with the match.
Future<void> updatePlayersFromMatch({
Future<bool> updateMatchPlayers({
required String matchId,
required List<Player> newPlayer,
}) async {
if (newPlayer.isEmpty) return false;
final currentPlayers = await getPlayersOfMatch(matchId: matchId);
// Create sets of player IDs for easy comparison
final currentPlayerIds = currentPlayers?.map((p) => p.id).toSet() ?? {};
final currentPlayerIds = currentPlayers.map((p) => p.id).toSet();
final newPlayerIdsSet = newPlayer.map((p) => p.id).toSet();
// Are the current and new player identical?
if (currentPlayerIds.containsAll(newPlayerIdsSet) &&
newPlayerIdsSet.containsAll(currentPlayerIds)) {
return false;
}
// Determine players to add and remove
final playersToAdd = newPlayerIdsSet.difference(currentPlayerIds);
final playersToRemove = currentPlayerIds.difference(newPlayerIdsSet);
@@ -147,22 +169,22 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
);
}
});
return true;
}
/// Retrieves all players in a specific team for a match.
Future<List<Player>> getPlayersInTeam({
/* Delete */
/// Removes the association of a player with a match by deleting the record
/// from the [PlayerMatchTable].
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> removePlayerFromMatch({
required String matchId,
required String teamId,
required String playerId,
}) async {
final result = await (select(
playerMatchTable,
)..where((p) => p.matchId.equals(matchId) & p.teamId.equals(teamId))).get();
if (result.isEmpty) return [];
final futures = result.map(
(row) => db.playerDao.getPlayerById(playerId: row.playerId),
);
return Future.wait(futures);
final query = delete(playerMatchTable)
..where((pg) => pg.matchId.equals(matchId))
..where((pg) => pg.playerId.equals(playerId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}
}