From cb66b76e5a4bd8bb16a70bfdc311044c053a19d2 Mon Sep 17 00:00:00 2001 From: gelbeinhalb Date: Fri, 16 Jan 2026 11:55:47 +0100 Subject: [PATCH] add game_dao.dart --- lib/data/dao/game_dao.dart | 179 +++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 lib/data/dao/game_dao.dart diff --git a/lib/data/dao/game_dao.dart b/lib/data/dao/game_dao.dart new file mode 100644 index 0000000..4b99dfa --- /dev/null +++ b/lib/data/dao/game_dao.dart @@ -0,0 +1,179 @@ +import 'package:drift/drift.dart'; +import 'package:game_tracker/data/db/database.dart'; +import 'package:game_tracker/data/db/tables/game_table.dart'; +import 'package:game_tracker/data/dto/game.dart'; + +part 'game_dao.g.dart'; + +@DriftAccessor(tables: [GameTable]) +class GameDao extends DatabaseAccessor with _$GameDaoMixin { + GameDao(super.db); + + /// Retrieves all games from the database. + Future> getAllGames() async { + final query = select(gameTable); + final result = await query.get(); + return result + .map( + (row) => Game( + id: row.id, + name: row.name, + ruleset: row.ruleset, + description: row.description, + color: row.color != null ? int.tryParse(row.color!) : null, + icon: row.icon, + createdAt: row.createdAt, + ), + ) + .toList(); + } + + /// Retrieves a [Game] by its [gameId]. + Future getGameById({required String gameId}) async { + final query = select(gameTable)..where((g) => g.id.equals(gameId)); + final result = await query.getSingle(); + return Game( + id: result.id, + name: result.name, + ruleset: result.ruleset, + description: result.description, + color: result.color != null ? int.tryParse(result.color!) : null, + icon: result.icon, + createdAt: result.createdAt, + ); + } + + /// Adds a new [game] to the database. + /// If a game with the same ID already exists, no action is taken. + /// Returns `true` if the game was added, `false` otherwise. + Future addGame({required Game game}) async { + if (!await gameExists(gameId: game.id)) { + await into(gameTable).insert( + GameTableCompanion.insert( + id: game.id, + name: game.name, + ruleset: game.ruleset ?? '', + description: Value(game.description), + color: Value(game.color?.toString()), + icon: Value(game.icon), + createdAt: game.createdAt, + ), + mode: InsertMode.insertOrReplace, + ); + return true; + } + return false; + } + + /// Adds multiple [games] to the database in a batch operation. + /// Uses insertOrIgnore to avoid overwriting existing games. + Future addGamesAsList({required List games}) async { + if (games.isEmpty) return false; + + await db.batch( + (b) => b.insertAll( + gameTable, + games + .map( + (game) => GameTableCompanion.insert( + id: game.id, + name: game.name, + ruleset: game.ruleset ?? '', + description: Value(game.description), + color: Value(game.color?.toString()), + icon: Value(game.icon), + createdAt: game.createdAt, + ), + ) + .toList(), + mode: InsertMode.insertOrIgnore, + ), + ); + + return true; + } + + /// Deletes the game with the given [gameId] from the database. + /// Returns `true` if the game was deleted, `false` if the game did not exist. + Future deleteGame({required String gameId}) async { + final query = delete(gameTable)..where((g) => g.id.equals(gameId)); + final rowsAffected = await query.go(); + return rowsAffected > 0; + } + + /// Checks if a game with the given [gameId] exists in the database. + /// Returns `true` if the game exists, `false` otherwise. + Future gameExists({required String gameId}) async { + final query = select(gameTable)..where((g) => g.id.equals(gameId)); + final result = await query.getSingleOrNull(); + return result != null; + } + + /// Updates the name of the game with the given [gameId] to [newName]. + Future updateGameName({ + required String gameId, + required String newName, + }) async { + await (update(gameTable)..where((g) => g.id.equals(gameId))).write( + GameTableCompanion(name: Value(newName)), + ); + } + + /// Updates the ruleset of the game with the given [gameId]. + Future updateGameRuleset({ + required String gameId, + required String newRuleset, + }) async { + await (update(gameTable)..where((g) => g.id.equals(gameId))).write( + GameTableCompanion(ruleset: Value(newRuleset)), + ); + } + + /// Updates the description of the game with the given [gameId]. + Future updateGameDescription({ + required String gameId, + required String? newDescription, + }) async { + await (update(gameTable)..where((g) => g.id.equals(gameId))).write( + GameTableCompanion(description: Value(newDescription)), + ); + } + + /// Updates the color of the game with the given [gameId]. + Future updateGameColor({ + required String gameId, + required int? newColor, + }) async { + await (update(gameTable)..where((g) => g.id.equals(gameId))).write( + GameTableCompanion(color: Value(newColor?.toString())), + ); + } + + /// Updates the icon of the game with the given [gameId]. + Future updateGameIcon({ + required String gameId, + required String? newIcon, + }) async { + await (update(gameTable)..where((g) => g.id.equals(gameId))).write( + GameTableCompanion(icon: Value(newIcon)), + ); + } + + /// Retrieves the total count of games in the database. + Future getGameCount() async { + final count = + await (selectOnly(gameTable)..addColumns([gameTable.id.count()])) + .map((row) => row.read(gameTable.id.count())) + .getSingle(); + return count ?? 0; + } + + /// Deletes all games from the database. + /// Returns `true` if more than 0 rows were affected, otherwise `false`. + Future deleteAllGames() async { + final query = delete(gameTable); + final rowsAffected = await query.go(); + return rowsAffected > 0; + } +} +