Datenbankstruktur für Spiele #16

Merged
flixcoo merged 22 commits from feature/13-datenbankstruktur-fuer-spiele into development 2025-11-15 15:56:40 +00:00
6 changed files with 62 additions and 39 deletions
Showing only changes of commit ca40ae668d - Show all commits

View File

@@ -19,17 +19,17 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
} }
/// Retrieves a [Game] by its [gameId]. /// Retrieves a [Game] by its [gameId].
Future<Game> getGameById(String gameId) async { Future<Game> getGameById({required String gameId}) async {
final query = select(gameTable)..where((g) => g.id.equals(gameId)); final query = select(gameTable)..where((g) => g.id.equals(gameId));
final result = await query.getSingle(); final result = await query.getSingle();
List<Player>? players; List<Player>? players;
sneeex marked this conversation as resolved
Review

Wieso gehst du überall davon aus, dass players null sein kann? Man kann doch kein Game ohne Player erstellen oder in welchem case ist das der Fall?

Wieso gehst du überall davon aus, dass players null sein kann? Man kann doch kein Game ohne Player erstellen oder in welchem case ist das der Fall?
Review

Weil ein Game ja auch nur eine Group bekommern kann

Weil ein `Game` ja auch nur eine `Group` bekommern kann
if (await db.playerGameDao.hasGamePlayers(gameId)) { if (await db.playerGameDao.hasGamePlayers(gameId: gameId)) {
players = await db.playerGameDao.getPlayersByGameId(gameId); players = await db.playerGameDao.getPlayersByGameId(gameId: gameId);
} }
Group? group; Group? group;
if (await db.groupGameDao.hasGameGroup(gameId)) { if (await db.groupGameDao.hasGameGroup(gameId: gameId)) {
group = await db.groupGameDao.getGroupByGameId(gameId); group = await db.groupGameDao.getGroupByGameId(gameId: gameId);
} }
return Game( return Game(
@@ -41,14 +41,16 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
); );
} }
Future<void> addGame(Game game) async { /// Adds a new [Game] to the database.
/// Also adds associated players and group if they exist.
Future<void> addGame({required Game game}) async {
await db.transaction(() async { await db.transaction(() async {
for (final p in game.players ?? []) { for (final p in game.players ?? []) {
await db.playerDao.addPlayer(p); await db.playerDao.addPlayer(player: p);
await db.playerGameDao.addPlayerToGame(game.id, p.id); await db.playerGameDao.addPlayerToGame(gameId: game.id, playerId: p.id);
} }
if (game.group != null) { if (game.group != null) {
await db.groupDao.addGroup(game.group!); await db.groupDao.addGroup(group: game.group!);
await db.groupGameDao.addGroupToGame(game.id, game.group!.id); await db.groupGameDao.addGroupToGame(game.id, game.group!.id);
} }
await into(gameTable).insert( await into(gameTable).insert(

View File

@@ -20,12 +20,12 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
} }
/// Retrieves a [Group] by its [groupId], including its members. /// Retrieves a [Group] by its [groupId], including its members.
Future<Group> getGroupById(String groupId) async { Future<Group> getGroupById({required String groupId}) async {
final query = select(groupTable)..where((g) => g.id.equals(groupId)); final query = select(groupTable)..where((g) => g.id.equals(groupId));
final result = await query.getSingle(); final result = await query.getSingle();
List<Player> members = await db.playerGroupDao.getPlayersOfGroupById( List<Player> members = await db.playerGroupDao.getPlayersOfGroupById(
groupId, groupId: groupId,
); );
return Group(id: result.id, name: result.name, members: members); return Group(id: result.id, name: result.name, members: members);
@@ -33,7 +33,7 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
/// Adds a new group with the given [id] and [name] to the database. /// Adds a new group with the given [id] and [name] to the database.
/// This method also adds the group's members to the [PlayerGroupTable]. /// This method also adds the group's members to the [PlayerGroupTable].
Future<void> addGroup(Group group) async { Future<void> addGroup({required Group group}) async {
await db.transaction(() async { await db.transaction(() async {
await into( await into(
groupTable, groupTable,
@@ -56,15 +56,18 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
/// Deletes the group with the given [id] from the database. /// Deletes the group with the given [id] from the database.
/// Returns `true` if more than 0 rows were affected, otherwise `false`. /// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> deleteGroup(String id) async { Future<bool> deleteGroup({required String groupId}) async {
final query = (delete(groupTable)..where((g) => g.id.equals(id))); final query = (delete(groupTable)..where((g) => g.id.equals(groupId)));
final rowsAffected = await query.go(); final rowsAffected = await query.go();
return rowsAffected > 0; return rowsAffected > 0;
} }
/// Updates the name of the group with the given [id] to [newName]. /// Updates the name of the group with the given [id] to [newName].
/// Returns `true` if more than 0 rows were affected, otherwise `false`. /// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> updateGroupname(String id, String newName) async { Future<bool> updateGroupname({
required String id,
required String newName,
}) async {
final rowsAffected = final rowsAffected =
await (update(groupTable)..where((g) => g.id.equals(id))).write( await (update(groupTable)..where((g) => g.id.equals(id))).write(
GroupTableCompanion(name: Value(newName)), GroupTableCompanion(name: Value(newName)),

View File

@@ -12,7 +12,7 @@ class GroupGameDao extends DatabaseAccessor<AppDatabase>
/// Checks if there is a group associated with the given [gameId]. /// Checks if there is a group associated with the given [gameId].
/// Returns `true` if there is a group, otherwise `false`. /// Returns `true` if there is a group, otherwise `false`.
Future<bool> hasGameGroup(String gameId) async { Future<bool> hasGameGroup({required String gameId}) async {
final count = final count =
await (selectOnly(groupGameTable) await (selectOnly(groupGameTable)
..where(groupGameTable.gameId.equals(gameId)) ..where(groupGameTable.gameId.equals(gameId))
@@ -22,12 +22,12 @@ class GroupGameDao extends DatabaseAccessor<AppDatabase>
return (count ?? 0) > 0; return (count ?? 0) > 0;
} }
flixcoo marked this conversation as resolved
Review

doku vergessen

doku vergessen
Future<Group> getGroupByGameId(String gameId) async { Future<Group> getGroupByGameId({required String gameId}) async {
final result = await (select( final result = await (select(
groupGameTable, groupGameTable,
)..where((g) => g.gameId.equals(gameId))).getSingle(); )..where((g) => g.gameId.equals(gameId))).getSingle();
final group = await db.groupDao.getGroupById(result.groupId); final group = await db.groupDao.getGroupById(groupId: result.groupId);
return group; return group;
} }

View File

@@ -17,38 +17,47 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
} }
/// Retrieves a [Player] by their [id]. /// Retrieves a [Player] by their [id].
Future<Player> getPlayerById(String id) async { Future<Player> getPlayerById({required String playerId}) async {
final query = select(playerTable)..where((p) => p.id.equals(id)); final query = select(playerTable)..where((p) => p.id.equals(playerId));
final result = await query.getSingle(); final result = await query.getSingle();
return Player(id: result.id, name: result.name); return Player(id: result.id, name: result.name);
} }
/// Adds a new [player] to the database. /// Adds a new [player] to the database.
Future<void> addPlayer(Player player) async { /// If a player with the same ID already exists, updates their name to
/// the new one.
Future<void> addPlayer({required Player player}) async {
if (!await playerExists(playerId: player.id)) {
await into( await into(
playerTable, playerTable,
).insert(PlayerTableCompanion.insert(id: player.id, name: player.name)); ).insert(PlayerTableCompanion.insert(id: player.id, name: player.name));
} else {
await updatePlayername(playerId: player.id, newName: player.name);
}
} }
/// Deletes the player with the given [id] from the database. /// Deletes the player with the given [id] from the database.
/// Returns `true` if the player was deleted, `false` if the player did not exist. /// Returns `true` if the player was deleted, `false` if the player did not exist.
Future<bool> deletePlayer(String id) async { Future<bool> deletePlayer({required String playerId}) async {
final query = delete(playerTable)..where((p) => p.id.equals(id)); final query = delete(playerTable)..where((p) => p.id.equals(playerId));
final rowsAffected = await query.go(); final rowsAffected = await query.go();
return rowsAffected > 0; return rowsAffected > 0;
} }
/// Checks if a player with the given [id] exists in the database. /// Checks if a player with the given [id] exists in the database.
/// Returns `true` if the player exists, `false` otherwise. /// Returns `true` if the player exists, `false` otherwise.
Future<bool> playerExists(String id) async { Future<bool> playerExists({required String playerId}) async {
final query = select(playerTable)..where((p) => p.id.equals(id)); final query = select(playerTable)..where((p) => p.id.equals(playerId));
final result = await query.getSingleOrNull(); final result = await query.getSingleOrNull();
return result != null; return result != null;
} }
/// Updates the name of the player with the given [id] to [newName]. /// Updates the name of the player with the given [playerId] to [newName].
Future<void> updatePlayername(String id, String newName) async { Future<void> updatePlayername({
await (update(playerTable)..where((p) => p.id.equals(id))).write( required String playerId,
required String newName,
}) async {
await (update(playerTable)..where((p) => p.id.equals(playerId))).write(
PlayerTableCompanion(name: Value(newName)), PlayerTableCompanion(name: Value(newName)),
); );
} }

View File

@@ -12,7 +12,7 @@ class PlayerGameDao extends DatabaseAccessor<AppDatabase>
/// Checks if there are any players associated with the given [gameId]. /// Checks if there are any players associated with the given [gameId].
/// Returns `true` if there are players, otherwise `false`. /// Returns `true` if there are players, otherwise `false`.
Future<bool> hasGamePlayers(String gameId) async { Future<bool> hasGamePlayers({required String gameId}) async {
final count = final count =
flixcoo marked this conversation as resolved
Review

Finde den namen hasGamePlayers schlecht, besser gameHasPlayers

Finde den namen hasGamePlayers schlecht, besser `gameHasPlayers`
await (selectOnly(playerGameTable) await (selectOnly(playerGameTable)
..where(playerGameTable.gameId.equals(gameId)) ..where(playerGameTable.gameId.equals(gameId))
@@ -24,7 +24,7 @@ class PlayerGameDao extends DatabaseAccessor<AppDatabase>
/// Retrieves a list of [Player]s associated with the given [gameId]. /// Retrieves a list of [Player]s associated with the given [gameId].
/// Returns an empty list if no players are found. /// Returns an empty list if no players are found.
Future<List<Player>> getPlayersByGameId(String gameId) async { Future<List<Player>> getPlayersByGameId({required String gameId}) async {
final result = await (select( final result = await (select(
playerGameTable, playerGameTable,
)..where((p) => p.gameId.equals(gameId))).get(); )..where((p) => p.gameId.equals(gameId))).get();
@@ -32,7 +32,7 @@ class PlayerGameDao extends DatabaseAccessor<AppDatabase>
if (result.isEmpty) return <Player>[]; if (result.isEmpty) return <Player>[];
final futures = result.map( final futures = result.map(
(row) => db.playerDao.getPlayerById(row.playerId), (row) => db.playerDao.getPlayerById(playerId: row.playerId),
); );
final players = await Future.wait(futures); final players = await Future.wait(futures);
return players.whereType<Player>().toList(); return players.whereType<Player>().toList();
@@ -40,7 +40,10 @@ class PlayerGameDao extends DatabaseAccessor<AppDatabase>
/// Associates a player with a game by inserting a record into the /// Associates a player with a game by inserting a record into the
/// [PlayerGameTable]. /// [PlayerGameTable].
Future<void> addPlayerToGame(String gameId, String playerId) async { Future<void> addPlayerToGame({
required String gameId,
required String playerId,
}) async {
await into(playerGameTable).insert( await into(playerGameTable).insert(
PlayerGameTableCompanion.insert(playerId: playerId, gameId: gameId), PlayerGameTableCompanion.insert(playerId: playerId, gameId: gameId),
); );

View File

@@ -11,7 +11,7 @@ class PlayerGroupDao extends DatabaseAccessor<AppDatabase>
PlayerGroupDao(super.db); PlayerGroupDao(super.db);
/// Retrieves all players belonging to a specific group by [groupId]. /// Retrieves all players belonging to a specific group by [groupId].
Future<List<Player>> getPlayersOfGroupById(String groupId) async { Future<List<Player>> getPlayersOfGroupById({required String groupId}) async {
final query = select(playerGroupTable) final query = select(playerGroupTable)
..where((pG) => pG.groupId.equals(groupId)); ..where((pG) => pG.groupId.equals(groupId));
final result = await query.get(); final result = await query.get();
@@ -19,7 +19,7 @@ class PlayerGroupDao extends DatabaseAccessor<AppDatabase>
List<Player> groupMembers = []; List<Player> groupMembers = [];
for (var entry in result) { for (var entry in result) {
final player = await db.playerDao.getPlayerById(entry.playerId); final player = await db.playerDao.getPlayerById(playerId: entry.playerId);
groupMembers.add(player); groupMembers.add(player);
} }
@@ -28,7 +28,10 @@ class PlayerGroupDao extends DatabaseAccessor<AppDatabase>
/// Removes a player from a group based on [playerId] and [groupId]. /// Removes a player from a group based on [playerId] and [groupId].
/// Returns `true` if more than 0 rows were affected, otherwise `false`. /// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> removePlayerFromGroup(String playerId, String groupId) async { Future<bool> removePlayerFromGroup({
required String playerId,
required String groupId,
}) async {
final query = delete(playerGroupTable) final query = delete(playerGroupTable)
..where((p) => p.playerId.equals(playerId) & p.groupId.equals(groupId)); ..where((p) => p.playerId.equals(playerId) & p.groupId.equals(groupId));
final rowsAffected = await query.go(); final rowsAffected = await query.go();
@@ -36,7 +39,10 @@ class PlayerGroupDao extends DatabaseAccessor<AppDatabase>
} }
/// Adds a player to a group with the given [playerId] and [groupId]. /// Adds a player to a group with the given [playerId] and [groupId].
Future<void> addPlayerToGroup(String playerId, String groupId) async { Future<void> addPlayerToGroup({
required String playerId,
required String groupId,
}) async {
await into(playerGroupTable).insert( await into(playerGroupTable).insert(
PlayerGroupTableCompanion.insert(playerId: playerId, groupId: groupId), PlayerGroupTableCompanion.insert(playerId: playerId, groupId: groupId),
); );