diff --git a/lib/data/dao/team_dao.dart b/lib/data/dao/team_dao.dart new file mode 100644 index 0000000..a382643 --- /dev/null +++ b/lib/data/dao/team_dao.dart @@ -0,0 +1,145 @@ +import 'package:drift/drift.dart'; +import 'package:game_tracker/data/db/database.dart'; +import 'package:game_tracker/data/db/tables/team_table.dart'; +import 'package:game_tracker/data/dto/player.dart'; +import 'package:game_tracker/data/dto/team.dart'; + +part 'team_dao.g.dart'; + +@DriftAccessor(tables: [TeamTable]) +class TeamDao extends DatabaseAccessor with _$TeamDaoMixin { + TeamDao(super.db); + + /// Retrieves all teams from the database. + /// Note: This returns teams without their members. Use getTeamById for full team data. + Future> getAllTeams() async { + final query = select(teamTable); + final result = await query.get(); + return Future.wait( + result.map((row) async { + final members = await _getTeamMembers(teamId: row.id); + return Team( + id: row.id, + createdAt: row.createdAt, + members: members, + ); + }), + ); + } + + /// Retrieves a [Team] by its [teamId], including its members. + Future getTeamById({required String teamId}) async { + final query = select(teamTable)..where((t) => t.id.equals(teamId)); + final result = await query.getSingle(); + final members = await _getTeamMembers(teamId: teamId); + return Team( + id: result.id, + createdAt: result.createdAt, + members: members, + ); + } + + /// Helper method to get team members from player_match_table. + /// This assumes team members are tracked via the player_match_table. + Future> _getTeamMembers({required String teamId}) async { + // Get all player_match entries with this teamId + final playerMatchQuery = select(db.playerMatchTable) + ..where((pm) => pm.teamId.equals(teamId)); + final playerMatches = await playerMatchQuery.get(); + + if (playerMatches.isEmpty) return []; + + // Get unique player IDs + final playerIds = playerMatches.map((pm) => pm.playerId).toSet(); + + // Fetch all players + final players = await Future.wait( + playerIds.map((id) => db.playerDao.getPlayerById(playerId: id)), + ); + return players; + } + + /// Adds a new [team] to the database. + /// Returns `true` if the team was added, `false` otherwise. + Future addTeam({required Team team}) async { + if (!await teamExists(teamId: team.id)) { + await into(teamTable).insert( + TeamTableCompanion.insert( + id: team.id, + name: '', // Team name from table (not in DTO currently) + createdAt: team.createdAt, + ), + mode: InsertMode.insertOrReplace, + ); + return true; + } + return false; + } + + /// Adds multiple [teams] to the database in a batch operation. + Future addTeamsAsList({required List teams}) async { + if (teams.isEmpty) return false; + + await db.batch( + (b) => b.insertAll( + teamTable, + teams + .map( + (team) => TeamTableCompanion.insert( + id: team.id, + name: '', + createdAt: team.createdAt, + ), + ) + .toList(), + mode: InsertMode.insertOrIgnore, + ), + ); + + return true; + } + + /// Deletes the team with the given [teamId] from the database. + /// Returns `true` if the team was deleted, `false` otherwise. + Future deleteTeam({required String teamId}) async { + final query = delete(teamTable)..where((t) => t.id.equals(teamId)); + final rowsAffected = await query.go(); + return rowsAffected > 0; + } + + /// Checks if a team with the given [teamId] exists in the database. + /// Returns `true` if the team exists, `false` otherwise. + Future teamExists({required String teamId}) async { + final query = select(teamTable)..where((t) => t.id.equals(teamId)); + final result = await query.getSingleOrNull(); + return result != null; + } + + /// Updates the name of the team with the given [teamId]. + Future updateTeamName({ + required String teamId, + required String newName, + }) async { + await (update(teamTable)..where((t) => t.id.equals(teamId))).write( + TeamTableCompanion(name: Value(newName)), + ); + } + + /// Retrieves the total count of teams in the database. + Future getTeamCount() async { + final count = + await (selectOnly(teamTable)..addColumns([teamTable.id.count()])) + .map((row) => row.read(teamTable.id.count())) + .getSingle(); + return count ?? 0; + } + + /// Deletes all teams from the database. + /// Returns `true` if more than 0 rows were affected, otherwise `false`. + Future deleteAllTeams() async { + final query = delete(teamTable); + final rowsAffected = await query.go(); + return rowsAffected > 0; + } +} +