From a13d9c55ea777096d896c091e4bc1552784ddec2 Mon Sep 17 00:00:00 2001 From: gelbeinhalb Date: Fri, 16 Jan 2026 12:37:37 +0100 Subject: [PATCH] add score_dao.dart --- lib/data/dao/score_dao.dart | 191 ++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 lib/data/dao/score_dao.dart diff --git a/lib/data/dao/score_dao.dart b/lib/data/dao/score_dao.dart new file mode 100644 index 0000000..5fa29da --- /dev/null +++ b/lib/data/dao/score_dao.dart @@ -0,0 +1,191 @@ +import 'package:drift/drift.dart'; +import 'package:game_tracker/data/db/database.dart'; +import 'package:game_tracker/data/db/tables/score_table.dart'; + +part 'score_dao.g.dart'; + +/// A data class representing a score entry. +class ScoreEntry { + final String playerId; + final String matchId; + final int roundNumber; + final int score; + final int change; + + ScoreEntry({ + required this.playerId, + required this.matchId, + required this.roundNumber, + required this.score, + required this.change, + }); +} + +@DriftAccessor(tables: [ScoreTable]) +class ScoreDao extends DatabaseAccessor with _$ScoreDaoMixin { + ScoreDao(super.db); + + /// Adds a score entry to the database. + Future addScore({ + required String playerId, + required String matchId, + required int roundNumber, + required int score, + required int change, + }) async { + await into(scoreTable).insert( + ScoreTableCompanion.insert( + playerId: playerId, + matchId: matchId, + roundNumber: roundNumber, + score: score, + change: change, + ), + mode: InsertMode.insertOrReplace, + ); + } + + /// Retrieves all scores for a specific match. + Future> getScoresForMatch({required String matchId}) async { + final query = select(scoreTable)..where((s) => s.matchId.equals(matchId)); + final result = await query.get(); + return result + .map( + (row) => ScoreEntry( + playerId: row.playerId, + matchId: row.matchId, + roundNumber: row.roundNumber, + score: row.score, + change: row.change, + ), + ) + .toList(); + } + + /// Retrieves all scores for a specific player in a match. + Future> getPlayerScoresInMatch({ + required String playerId, + required String matchId, + }) async { + final query = select(scoreTable) + ..where( + (s) => s.playerId.equals(playerId) & s.matchId.equals(matchId), + ) + ..orderBy([(s) => OrderingTerm.asc(s.roundNumber)]); + final result = await query.get(); + return result + .map( + (row) => ScoreEntry( + playerId: row.playerId, + matchId: row.matchId, + roundNumber: row.roundNumber, + score: row.score, + change: row.change, + ), + ) + .toList(); + } + + /// Retrieves the score for a specific round. + Future getScoreForRound({ + required String playerId, + required String matchId, + required int roundNumber, + }) async { + final query = select(scoreTable) + ..where( + (s) => + s.playerId.equals(playerId) & + s.matchId.equals(matchId) & + s.roundNumber.equals(roundNumber), + ); + final result = await query.getSingleOrNull(); + if (result == null) return null; + return ScoreEntry( + playerId: result.playerId, + matchId: result.matchId, + roundNumber: result.roundNumber, + score: result.score, + change: result.change, + ); + } + + /// Updates a score entry. + Future updateScore({ + required String playerId, + required String matchId, + required int roundNumber, + required int newScore, + required int newChange, + }) async { + final rowsAffected = await (update(scoreTable) + ..where( + (s) => + s.playerId.equals(playerId) & + s.matchId.equals(matchId) & + s.roundNumber.equals(roundNumber), + )) + .write( + ScoreTableCompanion( + score: Value(newScore), + change: Value(newChange), + ), + ); + return rowsAffected > 0; + } + + /// Deletes a score entry. + Future deleteScore({ + required String playerId, + required String matchId, + required int roundNumber, + }) async { + final query = delete(scoreTable) + ..where( + (s) => + s.playerId.equals(playerId) & + s.matchId.equals(matchId) & + s.roundNumber.equals(roundNumber), + ); + final rowsAffected = await query.go(); + return rowsAffected > 0; + } + + /// Deletes all scores for a specific match. + Future deleteScoresForMatch({required String matchId}) async { + final query = delete(scoreTable)..where((s) => s.matchId.equals(matchId)); + final rowsAffected = await query.go(); + return rowsAffected > 0; + } + + /// Deletes all scores for a specific player. + Future deleteScoresForPlayer({required String playerId}) async { + final query = delete(scoreTable)..where((s) => s.playerId.equals(playerId)); + final rowsAffected = await query.go(); + return rowsAffected > 0; + } + + /// Gets the latest round number for a match. + Future getLatestRoundNumber({required String matchId}) async { + final query = selectOnly(scoreTable) + ..where(scoreTable.matchId.equals(matchId)) + ..addColumns([scoreTable.roundNumber.max()]); + final result = await query.getSingle(); + return result.read(scoreTable.roundNumber.max()) ?? 0; + } + + /// Gets the total score for a player in a match (sum of all changes). + Future getTotalScoreForPlayer({ + required String playerId, + required String matchId, + }) async { + final scores = await getPlayerScoresInMatch( + playerId: playerId, + matchId: matchId, + ); + if (scores.isEmpty) return 0; + // Return the score from the latest round + return scores.last.score; + } +} +