Revert "Merge branch 'feature/193-statisticsview-rework' into development"
All checks were successful
Push Pipeline / update_version (push) Successful in 6s
Push Pipeline / generate_licenses (push) Successful in 38s
Push Pipeline / generate_localizations (push) Successful in 29s
Push Pipeline / test (push) Successful in 1m35s
Push Pipeline / sort_arb_files (push) Successful in 31s
Push Pipeline / format (push) Successful in 55s
Push Pipeline / build (push) Successful in 4m58s

This reverts commit 24f49e17b9, reversing
changes made to dba6c218d6.

# Conflicts:
#	pubspec.yaml
This commit is contained in:
2026-05-25 14:55:19 +02:00
parent 5659dc36c2
commit 9b208f4780
69 changed files with 834 additions and 6965 deletions

View File

@@ -77,8 +77,8 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
/// Returns `true` if the game exists, `false` otherwise.
Future<bool> gameExists({required String gameId}) async {
final query = select(gameTable)..where((g) => g.id.equals(gameId));
final row = await query.getSingleOrNull();
return row != null;
final result = await query.getSingleOrNull();
return result != null;
}
/// Retrieves all games from the database.
@@ -92,7 +92,7 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
name: row.name,
ruleset: Ruleset.values.firstWhere((e) => e.name == row.ruleset),
description: row.description,
color: AppColor.values.firstWhere((e) => e.name == row.color),
color: GameColor.values.firstWhere((e) => e.name == row.color),
icon: row.icon,
createdAt: row.createdAt,
),
@@ -103,15 +103,15 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
/// Retrieves a [Game] by its [gameId].
Future<Game> getGameById({required String gameId}) async {
final query = select(gameTable)..where((g) => g.id.equals(gameId));
final row = await query.getSingle();
final result = await query.getSingle();
return Game(
id: row.id,
name: row.name,
ruleset: Ruleset.values.firstWhere((e) => e.name == row.ruleset),
description: row.description,
color: AppColor.values.firstWhere((e) => e.name == row.color),
icon: row.icon,
createdAt: row.createdAt,
id: result.id,
name: result.name,
ruleset: Ruleset.values.firstWhere((e) => e.name == result.ruleset),
description: result.description,
color: GameColor.values.firstWhere((e) => e.name == result.color),
icon: result.icon,
createdAt: result.createdAt,
);
}
@@ -123,7 +123,7 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
required String name,
}) async {
final rowsAffected =
await (update(gameTable)..where((tbl) => tbl.id.equals(gameId))).write(
await (update(gameTable)..where((g) => g.id.equals(gameId))).write(
GameTableCompanion(name: Value(name)),
);
return rowsAffected > 0;
@@ -135,7 +135,7 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
required Ruleset ruleset,
}) async {
final rowsAffected =
await (update(gameTable)..where((tbl) => tbl.id.equals(gameId))).write(
await (update(gameTable)..where((g) => g.id.equals(gameId))).write(
GameTableCompanion(ruleset: Value(ruleset.name)),
);
return rowsAffected > 0;
@@ -147,7 +147,7 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
required String description,
}) async {
final rowsAffected =
await (update(gameTable)..where((tbl) => tbl.id.equals(gameId))).write(
await (update(gameTable)..where((g) => g.id.equals(gameId))).write(
GameTableCompanion(description: Value(description)),
);
return rowsAffected > 0;
@@ -156,10 +156,10 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
/// Updates the color of the game with the given [gameId].
Future<bool> updateGameColor({
required String gameId,
required AppColor color,
required GameColor color,
}) async {
final rowsAffected =
await (update(gameTable)..where((tbl) => tbl.id.equals(gameId))).write(
await (update(gameTable)..where((g) => g.id.equals(gameId))).write(
GameTableCompanion(color: Value(color.name)),
);
return rowsAffected > 0;
@@ -171,7 +171,7 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
required String icon,
}) async {
final rowsAffected =
await (update(gameTable)..where((tbl) => tbl.id.equals(gameId))).write(
await (update(gameTable)..where((g) => g.id.equals(gameId))).write(
GameTableCompanion(icon: Value(icon)),
);
return rowsAffected > 0;
@@ -182,7 +182,7 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
/// 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<bool> deleteGame({required String gameId}) async {
final query = delete(gameTable)..where((tbl) => tbl.id.equals(gameId));
final query = delete(gameTable)..where((g) => g.id.equals(gameId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}

View File

@@ -143,16 +143,16 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
final query = select(groupTable);
final result = await query.get();
return Future.wait(
result.map((row) async {
result.map((groupData) async {
final members = await db.playerGroupDao.getPlayersOfGroup(
groupId: row.id,
groupId: groupData.id,
);
return Group(
id: row.id,
name: row.name,
description: row.description,
id: groupData.id,
name: groupData.name,
description: groupData.description,
members: members,
createdAt: row.createdAt,
createdAt: groupData.createdAt,
);
}),
);
@@ -161,18 +161,18 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
/// Retrieves a [Group] by its [groupId], including its members.
Future<Group> getGroupById({required String groupId}) async {
final query = select(groupTable)..where((g) => g.id.equals(groupId));
final row = await query.getSingle();
final result = await query.getSingle();
List<Player> members = await db.playerGroupDao.getPlayersOfGroup(
groupId: groupId,
);
return Group(
id: row.id,
name: row.name,
description: row.description,
id: result.id,
name: result.name,
description: result.description,
members: members,
createdAt: row.createdAt,
createdAt: result.createdAt,
);
}
@@ -180,49 +180,17 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
Future<int> getGroupCount() async {
final count =
await (selectOnly(groupTable)..addColumns([groupTable.id.count()]))
.map((tbl) => tbl.read(groupTable.id.count()))
.map((row) => row.read(groupTable.id.count()))
.getSingle();
return count ?? 0;
}
/// Retrieves all groups a specific player belongs to.
/// Returns an empty list if the player is not part of any group.
Future<List<Group>> getGroupsByPlayer({required String playerId}) async {
final playerGroups = await (select(
playerGroupTable,
)..where((tbl) => tbl.playerId.equals(playerId))).get();
if (playerGroups.isEmpty) return [];
final groupIds = playerGroups.map((pg) => pg.groupId).toSet().toList();
final result =
await (select(groupTable)
..where((tbl) => tbl.id.isIn(groupIds))
..orderBy([(tbl) => OrderingTerm.desc(tbl.createdAt)]))
.get();
return Future.wait(
result.map((row) async {
final members = await db.playerGroupDao.getPlayersOfGroup(
groupId: row.id,
);
return Group(
id: row.id,
name: row.name,
description: row.description,
members: members,
createdAt: row.createdAt,
);
}),
);
}
/// Checks if a group with the given [groupId] exists in the database.
/// Returns `true` if the group exists, `false` otherwise.
Future<bool> groupExists({required String groupId}) async {
final query = select(groupTable)..where((g) => g.id.equals(groupId));
final row = await query.getSingleOrNull();
return row != null;
final result = await query.getSingleOrNull();
return result != null;
}
/* Delete */
@@ -252,8 +220,9 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
required String name,
}) async {
final rowsAffected =
await (update(groupTable)..where((tbl) => tbl.id.equals(groupId)))
.write(GroupTableCompanion(name: Value(name)));
await (update(groupTable)..where((g) => g.id.equals(groupId))).write(
GroupTableCompanion(name: Value(name)),
);
return rowsAffected > 0;
}
@@ -264,8 +233,9 @@ class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
required String description,
}) async {
final rowsAffected =
await (update(groupTable)..where((tbl) => tbl.id.equals(groupId)))
.write(GroupTableCompanion(description: Value(description)));
await (update(groupTable)..where((g) => g.id.equals(groupId))).write(
GroupTableCompanion(description: Value(description)),
);
return rowsAffected > 0;
}
}

View File

@@ -258,15 +258,15 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
/// Returns `true` if the match exists, otherwise `false`.
Future<bool> matchExists({required String matchId}) async {
final query = select(matchTable)..where((g) => g.id.equals(matchId));
final row = await query.getSingleOrNull();
return row != null;
final result = await query.getSingleOrNull();
return result != null;
}
/// Retrieves the number of matches in the database.
Future<int> getMatchCount() async {
final count =
await (selectOnly(matchTable)..addColumns([matchTable.id.count()]))
.map((tbl) => tbl.read(matchTable.id.count()))
.map((row) => row.read(matchTable.id.count()))
.getSingle();
return count ?? 0;
}
@@ -279,12 +279,10 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
return Future.wait(
result.map((row) async {
final game = await db.gameDao.getGameById(gameId: row.gameId);
Group? group;
if (row.groupId != null) {
group = await db.groupDao.getGroupById(groupId: row.groupId!);
}
final players = await db.playerMatchDao.getPlayersOfMatch(
matchId: row.id,
);
@@ -314,13 +312,13 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
/// Retrieves a [Match] by its [matchId].
Future<Match> getMatchById({required String matchId}) async {
final query = select(matchTable)..where((g) => g.id.equals(matchId));
final row = await query.getSingle();
final result = await query.getSingle();
final game = await db.gameDao.getGameById(gameId: row.gameId);
final game = await db.gameDao.getGameById(gameId: result.gameId);
Group? group;
if (row.groupId != null) {
group = await db.groupDao.getGroupById(groupId: row.groupId!);
if (result.groupId != null) {
group = await db.groupDao.getGroupById(groupId: result.groupId!);
}
final players = await db.playerMatchDao.getPlayersOfMatch(matchId: matchId);
@@ -330,15 +328,15 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
final teams = await _getMatchTeams(matchId: matchId);
return Match(
id: row.id,
name: row.name,
id: result.id,
name: result.name,
game: game,
group: group,
players: players,
teams: teams.isEmpty ? null : teams,
notes: row.notes,
createdAt: row.createdAt,
endedAt: row.endedAt,
notes: result.notes,
createdAt: result.createdAt,
endedAt: result.endedAt,
scores: scores,
);
}
@@ -349,73 +347,25 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
await (selectOnly(matchTable)
..where(matchTable.gameId.equals(gameId))
..addColumns([matchTable.id.count()]))
.map((tbl) => tbl.read(matchTable.id.count()))
.map((row) => row.read(matchTable.id.count()))
.getSingle();
return count ?? 0;
}
Future<List<Match>> getMatchesByPlayer({required String playerId}) async {
final playerMatches = await (select(
playerMatchTable,
)..where((tbl) => tbl.playerId.equals(playerId))).get();
if (playerMatches.isEmpty) return [];
final matchIds = playerMatches.map((tbl) => tbl.matchId).toSet().toList();
final result =
await (select(matchTable)
..where((tbl) => tbl.id.isIn(matchIds))
..orderBy([(tbl) => OrderingTerm.desc(tbl.createdAt)]))
.get();
return Future.wait(
result.map((row) async {
final game = await db.gameDao.getGameById(gameId: row.gameId);
Group? group;
if (row.groupId != null) {
group = await db.groupDao.getGroupById(groupId: row.groupId!);
}
final players = await db.playerMatchDao.getPlayersOfMatch(
matchId: row.id,
);
final scores = await db.scoreEntryDao.getAllMatchScores(
matchId: row.id,
);
final teams = await _getMatchTeams(matchId: row.id);
return Match(
id: row.id,
name: row.name,
game: game,
group: group,
players: players,
teams: teams.isEmpty ? null : teams,
notes: row.notes,
createdAt: row.createdAt,
endedAt: row.endedAt,
scores: scores,
);
}),
);
}
/// Retrieves all matches associated with the given [groupId].
/// Queries the database directly, filtering by [groupId].
Future<List<Match>> getMatchesByGroup({required String groupId}) async {
final query = select(matchTable)..where((m) => m.groupId.equals(groupId));
final result = await query.get();
final rows = await query.get();
return Future.wait(
result.map((row) async {
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 teams = await _getMatchTeams(matchId: row.id);
return Match(
id: row.id,
name: row.name,
@@ -435,7 +385,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
Future<List<Team>> _getMatchTeams({required String matchId}) async {
// Get all unique team IDs from PlayerMatchTable for this match
final playerMatchQuery = select(db.playerMatchTable)
..where((tbl) => tbl.matchId.equals(matchId) & tbl.teamId.isNotNull());
..where((pm) => pm.matchId.equals(matchId) & pm.teamId.isNotNull());
final playerMatches = await playerMatchQuery.get();
if (playerMatches.isEmpty) return [];
@@ -462,7 +412,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
required String matchId,
required String name,
}) async {
final query = update(matchTable)..where((tbl) => tbl.id.equals(matchId));
final query = update(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.write(
MatchTableCompanion(name: Value(name)),
);
@@ -477,7 +427,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
required String matchId,
required String? groupId,
}) async {
final query = update(matchTable)..where((tbl) => tbl.id.equals(matchId));
final query = update(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.write(
MatchTableCompanion(groupId: Value(groupId)),
);
@@ -490,7 +440,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
required String matchId,
required String notes,
}) async {
final query = update(matchTable)..where((tbl) => tbl.id.equals(matchId));
final query = update(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.write(
MatchTableCompanion(notes: Value(notes)),
);
@@ -501,7 +451,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
/// Sets the groupId to null.
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> removeMatchGroup({required String matchId}) async {
final query = update(matchTable)..where((tbl) => tbl.id.equals(matchId));
final query = update(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.write(
const MatchTableCompanion(groupId: Value(null)),
);
@@ -515,7 +465,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
required String matchId,
required DateTime endedAt,
}) async {
final query = update(matchTable)..where((tbl) => tbl.id.equals(matchId));
final query = update(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.write(
MatchTableCompanion(endedAt: Value(endedAt)),
);
@@ -527,7 +477,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
/// Deletes the match with the given [matchId] from the database.
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> deleteMatch({required String matchId}) async {
final query = delete(matchTable)..where((tbl) => tbl.id.equals(matchId));
final query = delete(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}
@@ -543,7 +493,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
/// Deletes all matches associated with a specific game.
/// Returns the number of matches deleted.
Future<int> deleteMatchesByGame({required String gameId}) async {
final query = delete(matchTable)..where((tbl) => tbl.gameId.equals(gameId));
final query = delete(matchTable)..where((m) => m.gameId.equals(gameId));
final rowsAffected = await query.go();
return rowsAffected;
}

View File

@@ -17,7 +17,7 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
/// the new one.
Future<bool> addPlayer({required Player player}) async {
if (!await playerExists(playerId: player.id)) {
final int nameCount = await _processNameCount(name: player.name);
final int nameCount = await calculateNameCount(name: player.name);
await into(playerTable).insert(
PlayerTableCompanion.insert(
@@ -64,7 +64,7 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
final playersWithName = entry.value;
// Get the current nameCount
var nameCount = await _processNameCount(name: name);
var nameCount = await calculateNameCount(name: name);
// One player with the same name
if (playersWithName.length == 1) {
@@ -113,7 +113,7 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
Future<int> getPlayerCount() async {
final count =
await (selectOnly(playerTable)..addColumns([playerTable.id.count()]))
.map((tbl) => tbl.read(playerTable.id.count()))
.map((row) => row.read(playerTable.id.count()))
.getSingle();
return count ?? 0;
}
@@ -122,8 +122,8 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
/// Returns `true` if the player exists, `false` otherwise.
Future<bool> playerExists({required String playerId}) async {
final query = select(playerTable)..where((p) => p.id.equals(playerId));
final row = await query.getSingleOrNull();
return row != null;
final result = await query.getSingleOrNull();
return result != null;
}
/// Retrieves all players from the database.
@@ -146,76 +146,57 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
/// Retrieves a [Player] by their [id].
Future<Player> getPlayerById({required String playerId}) async {
final query = select(playerTable)..where((p) => p.id.equals(playerId));
final row = await query.getSingle();
final result = await query.getSingle();
return Player(
id: row.id,
name: row.name,
description: row.description,
createdAt: row.createdAt,
nameCount: row.nameCount,
id: result.id,
name: result.name,
description: result.description,
createdAt: result.createdAt,
nameCount: result.nameCount,
);
}
/* Update */
/// Updates the name of the player with the given [playerId] to [name].
///
/// Keeps the `nameCount` values of the affected name groups consistent:
/// - The renamed player gets a fresh `nameCount` for the new name group.
/// - All players in the previous name group whose `nameCount` was greater
/// than the removed one get decremented by 1, so the numbering stays
/// contiguous (1..N) in `createdAt` order.
/// - If only one player remains in the previous name group, their
/// `nameCount` is reset to 0.
Future<bool> updatePlayerName({
required String playerId,
required String name,
}) async {
return transaction(() async {
final previousPlayer = await (select(
playerTable,
)..where((tbl) => tbl.id.equals(playerId))).getSingleOrNull();
if (previousPlayer == null) return false;
// Get previous name and name count for the player before updating
final previousPlayerName =
await (select(playerTable)..where((p) => p.id.equals(playerId)))
.map((row) => row.name)
.getSingleOrNull() ??
'';
final previousNameCount = await getNameCount(name: previousPlayerName);
final previousName = previousPlayer.name;
final previousCount = previousPlayer.nameCount;
final rowsAffected =
await (update(playerTable)..where((p) => p.id.equals(playerId))).write(
PlayerTableCompanion(name: Value(name)),
);
// Determine the nameCount for the renamed player in the new group.
final newNameCount = await _processNameCount(name: name);
// Update name count for the new name
final count = await calculateNameCount(name: name);
if (count > 0) {
await (update(playerTable)..where((p) => p.name.equals(name))).write(
PlayerTableCompanion(nameCount: Value(count)),
);
}
final rowsAffected =
await (update(
playerTable,
)..where((tbl) => tbl.id.equals(playerId))).write(
PlayerTableCompanion(
name: Value(name),
nameCount: Value(newNameCount),
),
);
// Consolidate the previous name group.
final remainingCount = await getNameCount(name: previousName);
if (remainingCount == 1) {
// Only one player left
await (update(playerTable)..where((p) => p.name.equals(previousName)))
.write(const PlayerTableCompanion(nameCount: Value(0)));
} else if (remainingCount > 1 && previousCount > 0) {
// Shift every player above the gap down by one to keep numbering in order.
await (update(playerTable)..where(
(tbl) =>
tbl.name.equals(previousName) &
tbl.nameCount.isBiggerThanValue(previousCount),
))
.write(
PlayerTableCompanion.custom(
nameCount: playerTable.nameCount - const Constant(1),
),
);
if (previousNameCount > 0) {
// Get the player with that name and the hightest nameCount, and update their nameCount to previousNameCount
final player = await getPlayerWithHighestNameCount(
name: previousPlayerName,
);
if (player != null) {
await updateNameCount(
playerId: player.id,
nameCount: previousNameCount,
);
}
return rowsAffected > 0;
});
}
return rowsAffected > 0;
}
/// Updates the description of the player with the given [playerId] to
@@ -226,8 +207,9 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
required String description,
}) async {
final rowsAffected =
await (update(playerTable)..where((tbl) => tbl.id.equals(playerId)))
.write(PlayerTableCompanion(description: Value(description)));
await (update(playerTable)..where((g) => g.id.equals(playerId))).write(
PlayerTableCompanion(description: Value(description)),
);
return rowsAffected > 0;
}
@@ -236,7 +218,7 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
/// Deletes the player with the given [id] from the database.
/// Returns `true` if the player was deleted, `false` if the player did not exist.
Future<bool> deletePlayer({required String playerId}) async {
final query = delete(playerTable)..where((tbl) => tbl.id.equals(playerId));
final query = delete(playerTable)..where((p) => p.id.equals(playerId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}
@@ -244,10 +226,8 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
/* Name count management */
/// Retrieves the count of players with the given [name].
/// Returns the highest name count if players with the same name exist,
/// otherwise `null`.
Future<int> getNameCount({required String name}) async {
final query = select(playerTable)..where((tbl) => tbl.name.equals(name));
final query = select(playerTable)..where((p) => p.name.equals(name));
final result = await query.get();
return result.length;
}
@@ -258,7 +238,7 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
required String playerId,
required int nameCount,
}) async {
final query = update(playerTable)..where((tbl) => tbl.id.equals(playerId));
final query = update(playerTable)..where((p) => p.id.equals(playerId));
final rowsAffected = await query.write(
PlayerTableCompanion(nameCount: Value(nameCount)),
);
@@ -268,8 +248,8 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
@visibleForTesting
Future<Player?> getPlayerWithHighestNameCount({required String name}) async {
final query = select(playerTable)
..where((tbl) => tbl.name.equals(name))
..orderBy([(tbl) => OrderingTerm.desc(tbl.nameCount)])
..where((p) => p.name.equals(name))
..orderBy([(p) => OrderingTerm.desc(p.nameCount)])
..limit(1);
final result = await query.getSingleOrNull();
if (result != null) {
@@ -284,47 +264,34 @@ class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
return null;
}
/// Processes the name count for a new player with the given [name].
///- 0 Player: returning 0
///- 1 Player: returning 2, and initializes the nameCount for the existing player to 1
///- Other: returning the existing count + 1
Future<int> _processNameCount({required String name}) async {
final nameCount = await calculateNameCount(name: name);
if (nameCount == 2) {
// If one other player exists with the same name, initialize the nameCount
await initializeNameCount(name: name);
}
return nameCount;
}
@visibleForTesting
/// Calculates the name count for a new player with the given [name].
/// - 0 Players: Name count is 0
/// - 1 Player: Name count is 2 (since the existing player will be 1)
/// - Other: Name count is the existing count + 1
Future<int> calculateNameCount({required String name}) async {
final count = await getNameCount(name: name);
final int nameCount;
if (count == 0) {
// If no other players exist with the same name, the returned nameCount is 0
nameCount = 0;
} else if (count == 1) {
// If one other player with the name count exists, the returned name count is 2
if (count == 1) {
// If one other player exists with the same name, initialize the nameCount
await initializeNameCount(name: name);
// And for the new player, set nameCount to 2
nameCount = 2;
} else {
} else if (count > 1) {
// If more than one player exists with the same name, just increment
// the nameCount for the new player
nameCount = count + 1;
} else {
// If no other players exist with the same name, set nameCount to 0
nameCount = 0;
}
return nameCount;
}
@visibleForTesting
Future<bool> initializeNameCount({required String name}) async {
final rowsAffected =
await (update(playerTable)..where((tbl) => tbl.name.equals(name)))
.write(const PlayerTableCompanion(nameCount: Value(1)));
await (update(playerTable)..where((p) => p.name.equals(name))).write(
const PlayerTableCompanion(nameCount: Value(1)),
);
return rowsAffected > 0;
}

View File

@@ -39,25 +39,18 @@ class PlayerGroupDao extends DatabaseAccessor<AppDatabase>
/// Retrieves all players belonging to a specific group by [groupId].
Future<List<Player>> getPlayersOfGroup({required String groupId}) async {
final query = select(playerGroupTable).join([
innerJoin(
playerTable,
playerTable.id.equalsExp(playerGroupTable.playerId),
),
])..where(playerGroupTable.groupId.equals(groupId));
final query = select(playerGroupTable)
..where((pG) => pG.groupId.equals(groupId));
final result = await query.get();
final result = await query.map((row) => row.readTable(playerTable)).get();
return result
.map(
(row) => Player(
id: row.id,
createdAt: row.createdAt,
name: row.name,
nameCount: row.nameCount,
description: row.description,
),
)
.toList();
List<Player> groupMembers = List.empty(growable: true);
for (var entry in result) {
final player = await db.playerDao.getPlayerById(playerId: entry.playerId);
groupMembers.add(player);
}
return groupMembers;
}
/// Checks if a player with [playerId] is in the group with [groupId].
@@ -67,9 +60,7 @@ class PlayerGroupDao extends DatabaseAccessor<AppDatabase>
required String groupId,
}) async {
final query = select(playerGroupTable)
..where(
(tbl) => tbl.playerId.equals(playerId) & tbl.groupId.equals(groupId),
);
..where((p) => p.playerId.equals(playerId) & p.groupId.equals(groupId));
final result = await query.getSingleOrNull();
return result != null;
}
@@ -90,7 +81,7 @@ class PlayerGroupDao extends DatabaseAccessor<AppDatabase>
await db.transaction(() async {
// Remove all existing players from the group
final deleteQuery = delete(db.playerGroupTable)
..where((tbl) => tbl.groupId.equals(groupId));
..where((p) => p.groupId.equals(groupId));
await deleteQuery.go();
// Add new players to the player table if they don't exist
@@ -130,9 +121,7 @@ class PlayerGroupDao extends DatabaseAccessor<AppDatabase>
required String groupId,
}) async {
final query = delete(playerGroupTable)
..where(
(tbl) => tbl.playerId.equals(playerId) & tbl.groupId.equals(groupId),
);
..where((p) => p.playerId.equals(playerId) & p.groupId.equals(groupId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}

View File

@@ -40,7 +40,7 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
await (selectOnly(playerMatchTable)
..where(playerMatchTable.matchId.equals(matchId))
..addColumns([playerMatchTable.playerId.count()]))
.map((tbl) => tbl.read(playerMatchTable.playerId.count()))
.map((row) => row.read(playerMatchTable.playerId.count()))
.getSingle();
return (count ?? 0) > 0;
}
@@ -56,7 +56,7 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
..where(playerMatchTable.matchId.equals(matchId))
..where(playerMatchTable.playerId.equals(playerId))
..addColumns([playerMatchTable.playerId.count()]))
.map((tbl) => tbl.read(playerMatchTable.playerId.count()))
.map((row) => row.read(playerMatchTable.playerId.count()))
.getSingle();
return (count ?? 0) > 0;
}
@@ -66,7 +66,7 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
Future<List<Player>> getPlayersOfMatch({required String matchId}) async {
final result = await (select(
playerMatchTable,
)..where((tbl) => tbl.matchId.equals(matchId))).get();
)..where((p) => p.matchId.equals(matchId))).get();
if (result.isEmpty) return [];
@@ -85,8 +85,8 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
}) async {
final result =
await (select(playerMatchTable)
..where((tbl) => tbl.matchId.equals(matchId))
..where((tbl) => tbl.teamId.equals(teamId)))
..where((p) => p.matchId.equals(matchId))
..where((p) => p.teamId.equals(teamId)))
.get();
if (result.isEmpty) return [];
@@ -109,8 +109,7 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
}) async {
final rowsAffected =
await (update(playerMatchTable)..where(
(tbl) =>
tbl.matchId.equals(matchId) & tbl.playerId.equals(playerId),
(p) => p.matchId.equals(matchId) & p.playerId.equals(playerId),
))
.write(PlayerMatchTableCompanion(teamId: Value(teamId)));
return rowsAffected > 0;
@@ -144,9 +143,9 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
// Remove old players
if (playersToRemove.isNotEmpty) {
await (delete(playerMatchTable)..where(
(tbl) =>
tbl.matchId.equals(matchId) &
tbl.playerId.isIn(playersToRemove.toList()),
(pg) =>
pg.matchId.equals(matchId) &
pg.playerId.isIn(playersToRemove.toList()),
))
.go();
}
@@ -183,8 +182,8 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
required String playerId,
}) async {
final query = delete(playerMatchTable)
..where((tbl) => tbl.matchId.equals(matchId))
..where((tbl) => tbl.playerId.equals(playerId));
..where((pg) => pg.matchId.equals(matchId))
..where((pg) => pg.playerId.equals(playerId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}

View File

@@ -70,10 +70,10 @@ class ScoreEntryDao extends DatabaseAccessor<AppDatabase>
}) async {
final query = select(scoreEntryTable)
..where(
(tbl) =>
tbl.playerId.equals(playerId) &
tbl.matchId.equals(matchId) &
tbl.roundNumber.equals(roundNumber),
(s) =>
s.playerId.equals(playerId) &
s.matchId.equals(matchId) &
s.roundNumber.equals(roundNumber),
);
final result = await query.getSingleOrNull();
@@ -91,7 +91,7 @@ class ScoreEntryDao extends DatabaseAccessor<AppDatabase>
required String matchId,
}) async {
final query = select(scoreEntryTable)
..where((tbl) => tbl.matchId.equals(matchId));
..where((s) => s.matchId.equals(matchId));
final result = await query.get();
final Map<String, ScoreEntry?> scoresByPlayer = {};
@@ -113,10 +113,8 @@ class ScoreEntryDao extends DatabaseAccessor<AppDatabase>
required String matchId,
}) async {
final query = select(scoreEntryTable)
..where(
(tbl) => tbl.playerId.equals(playerId) & tbl.matchId.equals(matchId),
)
..orderBy([(tbl) => OrderingTerm.asc(tbl.roundNumber)]);
..where((s) => s.playerId.equals(playerId) & s.matchId.equals(matchId))
..orderBy([(s) => OrderingTerm.asc(s.roundNumber)]);
final result = await query.get();
return result
.map(
@@ -138,8 +136,8 @@ class ScoreEntryDao extends DatabaseAccessor<AppDatabase>
final query = selectOnly(scoreEntryTable)
..where(scoreEntryTable.matchId.equals(matchId))
..addColumns([scoreEntryTable.roundNumber.max()]);
final row = await query.getSingle();
return row.read(scoreEntryTable.roundNumber.max());
final result = await query.getSingle();
return result.read(scoreEntryTable.roundNumber.max());
}
/// Aggregates the total score for a player in a match by summing all their
@@ -168,10 +166,10 @@ class ScoreEntryDao extends DatabaseAccessor<AppDatabase>
}) async {
final rowsAffected =
await (update(scoreEntryTable)..where(
(tbl) =>
tbl.playerId.equals(playerId) &
tbl.matchId.equals(matchId) &
tbl.roundNumber.equals(entry.roundNumber),
(s) =>
s.playerId.equals(playerId) &
s.matchId.equals(matchId) &
s.roundNumber.equals(entry.roundNumber),
))
.write(
ScoreEntryTableCompanion(
@@ -192,10 +190,10 @@ class ScoreEntryDao extends DatabaseAccessor<AppDatabase>
}) async {
final query = delete(scoreEntryTable)
..where(
(tbl) =>
tbl.playerId.equals(playerId) &
tbl.matchId.equals(matchId) &
tbl.roundNumber.equals(roundNumber),
(s) =>
s.playerId.equals(playerId) &
s.matchId.equals(matchId) &
s.roundNumber.equals(roundNumber),
);
final rowsAffected = await query.go();
return rowsAffected > 0;
@@ -203,7 +201,7 @@ class ScoreEntryDao extends DatabaseAccessor<AppDatabase>
Future<bool> deleteAllScoresForMatch({required String matchId}) async {
final query = delete(scoreEntryTable)
..where((tbl) => tbl.matchId.equals(matchId));
..where((s) => s.matchId.equals(matchId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}
@@ -213,9 +211,7 @@ class ScoreEntryDao extends DatabaseAccessor<AppDatabase>
required String playerId,
}) async {
final query = delete(scoreEntryTable)
..where(
(tbl) => tbl.playerId.equals(playerId) & tbl.matchId.equals(matchId),
);
..where((s) => s.playerId.equals(playerId) & s.matchId.equals(matchId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}

View File

@@ -1,127 +0,0 @@
import 'package:collection/collection.dart';
import 'package:drift/drift.dart';
import 'package:tallee/core/enums.dart';
import 'package:tallee/data/db/database.dart';
import 'package:tallee/data/db/tables/statistic_table.dart';
import 'package:tallee/data/models/statistic.dart';
part 'statistic_dao.g.dart';
@DriftAccessor(tables: [StatisticTable])
class StatisticDao extends DatabaseAccessor<AppDatabase>
with _$StatisticDaoMixin {
StatisticDao(super.db);
/* Create */
Future<bool> addStatistic({required Statistic statistic}) async {
await into(statisticTable).insert(
StatisticTableCompanion.insert(
id: statistic.id,
type: statistic.type.name,
timeframe: Value(statistic.timeframe?.name),
displayCount: Value(statistic.displayCount),
),
mode: InsertMode.insertOrReplace,
);
await db.statisticScopeDao.addStatisticScopes(
statisticId: statistic.id,
scopes: statistic.scopes,
);
if (statistic.selectedGroups != null) {
await db.statisticGroupDao.addStatisticGroups(
statisticId: statistic.id,
groups: statistic.selectedGroups!,
);
}
if (statistic.selectedGames != null) {
await db.statisticGameDao.addStatisticGames(
statisticId: statistic.id,
games: statistic.selectedGames!,
);
}
return true;
}
/* Read */
Future<Statistic?> getStatisticById(String statisticId) async {
final query = select(statisticTable);
final row = await query.getSingleOrNull();
if (row != null) {
final groups = await db.statisticGroupDao.getGroupsForStatistic(row.id);
final games = await db.statisticGameDao.getGamesForStatistic(row.id);
final scopes = await db.statisticScopeDao.getScopeForStatistic(row.id);
return Statistic(
type: StatisticType.values.firstWhere((type) => type.name == row.type),
scopes: scopes,
timeframe: Timeframe.values.firstWhereOrNull(
(t) => t.name == row.timeframe,
),
selectedGroups: groups,
selectedGames: games,
displayCount: row.displayCount,
id: row.id,
);
}
return null;
}
/// Retrieves all statistics from the database, including their associated groups and games.
Future<List<Statistic>> getAllStatistics() async {
final query = select(statisticTable);
final result = await query.get();
return Future.wait(
result.map((row) async {
final groups = await db.statisticGroupDao.getGroupsForStatistic(row.id);
final games = await db.statisticGameDao.getGamesForStatistic(row.id);
final scopes = await db.statisticScopeDao.getScopeForStatistic(row.id);
return Statistic(
type: StatisticType.values.firstWhere(
(type) => type.name == row.type,
),
scopes: scopes,
timeframe: Timeframe.values.firstWhereOrNull(
(t) => t.name == row.timeframe,
),
selectedGroups: groups,
selectedGames: games,
displayCount: row.displayCount,
id: row.id,
);
}),
);
}
/* Update */
Future<bool> updateDisplayCount(String statisticId, int displayCount) async {
final rowsUpdated =
await (update(statisticTable)
..where((tbl) => tbl.id.equals(statisticId)))
.write(StatisticTableCompanion(displayCount: Value(displayCount)));
return rowsUpdated > 0;
}
/* Delete */
Future<bool> deleteStatistic(String statisticId) async {
final rowsDeleted = await (delete(
statisticTable,
)..where((tbl) => tbl.id.equals(statisticId))).go();
return rowsDeleted > 0;
}
Future<bool> deleteAllStatistics() async {
final rowsDeleted = await delete(statisticTable).go();
return rowsDeleted > 0;
}
}

View File

@@ -1,19 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'statistic_dao.dart';
// ignore_for_file: type=lint
mixin _$StatisticDaoMixin on DatabaseAccessor<AppDatabase> {
$StatisticTableTable get statisticTable => attachedDatabase.statisticTable;
StatisticDaoManager get managers => StatisticDaoManager(this);
}
class StatisticDaoManager {
final _$StatisticDaoMixin _db;
StatisticDaoManager(this._db);
$$StatisticTableTableTableManager get statisticTable =>
$$StatisticTableTableTableManager(
_db.attachedDatabase,
_db.statisticTable,
);
}

View File

@@ -1,61 +0,0 @@
import 'package:drift/drift.dart';
import 'package:tallee/core/enums.dart';
import 'package:tallee/data/db/database.dart';
import 'package:tallee/data/db/tables/statistic_game_table.dart';
import 'package:tallee/data/models/game.dart';
part 'statistic_game_dao.g.dart';
@DriftAccessor(tables: [StatisticGameTable])
class StatisticGameDao extends DatabaseAccessor<AppDatabase>
with _$StatisticGameDaoMixin {
StatisticGameDao(super.db);
/// Retrieves a list of games associated with a specific statistic.
Future<List<Game>?> getGamesForStatistic(String statisticId) async {
final query = select(statisticGameTable).join([
innerJoin(gameTable, gameTable.id.equalsExp(statisticGameTable.gameId)),
])..where(statisticGameTable.statisticId.equals(statisticId));
final results = await query.map((row) => row.readTable(gameTable)).get();
if (results.isEmpty) return null;
return results
.map(
(row) => Game(
id: row.id,
name: row.name,
ruleset: Ruleset.values.firstWhere((e) => e.name == row.ruleset),
description: row.description,
color: AppColor.values.firstWhere((e) => e.name == row.color),
icon: row.icon,
createdAt: row.createdAt,
),
)
.toList();
}
Future<bool> addStatisticGames({
required String statisticId,
required List<Game> games,
}) {
final entries = games
.map(
(game) => StatisticGameTableCompanion.insert(
statisticId: statisticId,
gameId: game.id,
),
)
.toList();
return batch((batch) {
batch.insertAll(
statisticGameTable,
entries,
mode: InsertMode.insertOrReplace,
);
}).then((_) => true).catchError((error) {
print('Error adding statistic games: $error');
return false;
});
}
}

View File

@@ -1,29 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'statistic_game_dao.dart';
// ignore_for_file: type=lint
mixin _$StatisticGameDaoMixin on DatabaseAccessor<AppDatabase> {
$StatisticTableTable get statisticTable => attachedDatabase.statisticTable;
$GameTableTable get gameTable => attachedDatabase.gameTable;
$StatisticGameTableTable get statisticGameTable =>
attachedDatabase.statisticGameTable;
StatisticGameDaoManager get managers => StatisticGameDaoManager(this);
}
class StatisticGameDaoManager {
final _$StatisticGameDaoMixin _db;
StatisticGameDaoManager(this._db);
$$StatisticTableTableTableManager get statisticTable =>
$$StatisticTableTableTableManager(
_db.attachedDatabase,
_db.statisticTable,
);
$$GameTableTableTableManager get gameTable =>
$$GameTableTableTableManager(_db.attachedDatabase, _db.gameTable);
$$StatisticGameTableTableTableManager get statisticGameTable =>
$$StatisticGameTableTableTableManager(
_db.attachedDatabase,
_db.statisticGameTable,
);
}

View File

@@ -1,67 +0,0 @@
import 'package:drift/drift.dart';
import 'package:tallee/data/db/database.dart';
import 'package:tallee/data/db/tables/group_table.dart';
import 'package:tallee/data/db/tables/statistic_group_table.dart';
import 'package:tallee/data/models/group.dart';
part 'statistic_group_dao.g.dart';
@DriftAccessor(tables: [StatisticGroupTable, GroupTable])
class StatisticGroupDao extends DatabaseAccessor<AppDatabase>
with _$StatisticGroupDaoMixin {
StatisticGroupDao(super.db);
/// Retrieves a list of groups associated with a specific statistic.
Future<List<Group>?> getGroupsForStatistic(String statisticId) async {
final query = select(statisticGroupTable).join([
innerJoin(
groupTable,
groupTable.id.equalsExp(statisticGroupTable.groupId),
),
])..where(statisticGroupTable.statisticId.equals(statisticId));
final results = await query.map((row) => row.readTable(groupTable)).get();
if (results.isEmpty) return null;
final groups = await Future.wait(
results.map((result) async {
final groupMembers = await db.playerGroupDao.getPlayersOfGroup(
groupId: result.id,
);
return Group(
id: result.id,
createdAt: result.createdAt,
name: result.name,
description: result.description,
members: groupMembers,
);
}),
);
return groups;
}
Future<bool> addStatisticGroups({
required String statisticId,
required List<Group> groups,
}) async {
final entries = groups
.map(
(group) => StatisticGroupTableCompanion.insert(
statisticId: statisticId,
groupId: group.id,
),
)
.toList();
return batch((batch) {
batch.insertAll(
statisticGroupTable,
entries,
mode: InsertMode.insertOrReplace,
);
}).then((_) => true).catchError((error) {
print('Error adding statistic groups: $error');
return false;
});
}
}

View File

@@ -1,29 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'statistic_group_dao.dart';
// ignore_for_file: type=lint
mixin _$StatisticGroupDaoMixin on DatabaseAccessor<AppDatabase> {
$StatisticTableTable get statisticTable => attachedDatabase.statisticTable;
$GroupTableTable get groupTable => attachedDatabase.groupTable;
$StatisticGroupTableTable get statisticGroupTable =>
attachedDatabase.statisticGroupTable;
StatisticGroupDaoManager get managers => StatisticGroupDaoManager(this);
}
class StatisticGroupDaoManager {
final _$StatisticGroupDaoMixin _db;
StatisticGroupDaoManager(this._db);
$$StatisticTableTableTableManager get statisticTable =>
$$StatisticTableTableTableManager(
_db.attachedDatabase,
_db.statisticTable,
);
$$GroupTableTableTableManager get groupTable =>
$$GroupTableTableTableManager(_db.attachedDatabase, _db.groupTable);
$$StatisticGroupTableTableTableManager get statisticGroupTable =>
$$StatisticGroupTableTableTableManager(
_db.attachedDatabase,
_db.statisticGroupTable,
);
}

View File

@@ -1,55 +0,0 @@
import 'package:drift/drift.dart';
import 'package:tallee/core/enums.dart';
import 'package:tallee/data/db/database.dart';
import 'package:tallee/data/db/tables/statistic_scope_table.dart';
part 'statistic_scope_dao.g.dart';
@DriftAccessor(tables: [StatisticScopeTable])
class StatisticScopeDao extends DatabaseAccessor<AppDatabase>
with _$StatisticScopeDaoMixin {
StatisticScopeDao(super.db);
/// Retrieves a list of statistic scopes associated with a specific statistic ID.
Future<List<StatisticScope>> getScopeForStatistic(String statisticId) async {
final query = select(statisticScopeTable)
..where((tbl) => tbl.statisticId.equals(statisticId));
final result = await query.get();
return result
.map(
(row) => StatisticScope.values.firstWhere(
(e) => e.name == row.scope,
orElse: () => throw Exception(
'Invalid scope value: ${row.scope} for statistic ID: $statisticId',
),
),
)
.toList();
}
Future<bool> addStatisticScopes({
required String statisticId,
required List<StatisticScope> scopes,
}) async {
final entries = scopes
.map(
(scope) => StatisticScopeTableCompanion.insert(
statisticId: statisticId,
scope: scope.name,
),
)
.toList();
return batch((batch) {
batch.insertAll(
statisticScopeTable,
entries,
mode: InsertMode.insertOrReplace,
);
}).then((_) => true).catchError((error) {
print('Error adding statistic scopes: $error');
return false;
});
}
}

View File

@@ -1,26 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'statistic_scope_dao.dart';
// ignore_for_file: type=lint
mixin _$StatisticScopeDaoMixin on DatabaseAccessor<AppDatabase> {
$StatisticTableTable get statisticTable => attachedDatabase.statisticTable;
$StatisticScopeTableTable get statisticScopeTable =>
attachedDatabase.statisticScopeTable;
StatisticScopeDaoManager get managers => StatisticScopeDaoManager(this);
}
class StatisticScopeDaoManager {
final _$StatisticScopeDaoMixin _db;
StatisticScopeDaoManager(this._db);
$$StatisticTableTableTableManager get statisticTable =>
$$StatisticTableTableTableManager(
_db.attachedDatabase,
_db.statisticTable,
);
$$StatisticScopeTableTableTableManager get statisticScopeTable =>
$$StatisticScopeTableTableTableManager(
_db.attachedDatabase,
_db.statisticScopeTable,
);
}

View File

@@ -86,7 +86,7 @@ class TeamDao extends DatabaseAccessor<AppDatabase> with _$TeamDaoMixin {
Future<int> getTeamCount() async {
final count =
await (selectOnly(teamTable)..addColumns([teamTable.id.count()]))
.map((tbl) => tbl.read(teamTable.id.count()))
.map((row) => row.read(teamTable.id.count()))
.getSingle();
return count ?? 0;
}
@@ -95,8 +95,8 @@ class TeamDao extends DatabaseAccessor<AppDatabase> with _$TeamDaoMixin {
/// Returns `true` if the team exists, `false` otherwise.
Future<bool> teamExists({required String teamId}) async {
final query = select(teamTable)..where((t) => t.id.equals(teamId));
final row = await query.getSingleOrNull();
return row != null;
final result = await query.getSingleOrNull();
return result != null;
}
/// Retrieves all teams from the database.
@@ -119,12 +119,12 @@ class TeamDao extends DatabaseAccessor<AppDatabase> with _$TeamDaoMixin {
/// Retrieves a [Team] by its [teamId], including its members.
Future<Team> getTeamById({required String teamId}) async {
final query = select(teamTable)..where((t) => t.id.equals(teamId));
final row = await query.getSingle();
final result = await query.getSingle();
final members = await _getTeamMembers(teamId: teamId);
return Team(
id: row.id,
name: row.name,
createdAt: row.createdAt,
id: result.id,
name: result.name,
createdAt: result.createdAt,
members: members,
);
}
@@ -133,13 +133,13 @@ class TeamDao extends DatabaseAccessor<AppDatabase> with _$TeamDaoMixin {
Future<List<Player>> _getTeamMembers({required String teamId}) async {
// Get all player_match entries with this teamId
final playerMatchQuery = select(db.playerMatchTable)
..where((tbl) => tbl.teamId.equals(teamId));
..where((pm) => pm.teamId.equals(teamId));
final playerMatches = await playerMatchQuery.get();
if (playerMatches.isEmpty) return [];
// Get unique player IDs
final playerIds = playerMatches.map((tbl) => tbl.playerId).toSet();
final playerIds = playerMatches.map((pm) => pm.playerId).toSet();
// Fetch all players
final players = await Future.wait(
@@ -156,7 +156,7 @@ class TeamDao extends DatabaseAccessor<AppDatabase> with _$TeamDaoMixin {
required String name,
}) async {
final rowsAffected =
await (update(teamTable)..where((tbl) => tbl.id.equals(teamId))).write(
await (update(teamTable)..where((t) => t.id.equals(teamId))).write(
TeamTableCompanion(name: Value(name)),
);
return rowsAffected > 0;
@@ -175,7 +175,7 @@ class TeamDao extends DatabaseAccessor<AppDatabase> with _$TeamDaoMixin {
/// Deletes the team with the given [teamId] from the database.
/// Returns `true` if the team was deleted, `false` otherwise.
Future<bool> deleteTeam({required String teamId}) async {
final query = delete(teamTable)..where((tbl) => tbl.id.equals(teamId));
final query = delete(teamTable)..where((t) => t.id.equals(teamId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}

View File

@@ -8,10 +8,6 @@ import 'package:tallee/data/dao/player_dao.dart';
import 'package:tallee/data/dao/player_group_dao.dart';
import 'package:tallee/data/dao/player_match_dao.dart';
import 'package:tallee/data/dao/score_entry_dao.dart';
import 'package:tallee/data/dao/statistic_dao.dart';
import 'package:tallee/data/dao/statistic_game_dao.dart';
import 'package:tallee/data/dao/statistic_group_dao.dart';
import 'package:tallee/data/dao/statistic_scope_dao.dart';
import 'package:tallee/data/dao/team_dao.dart';
import 'package:tallee/data/db/tables/game_table.dart';
import 'package:tallee/data/db/tables/group_table.dart';
@@ -20,10 +16,6 @@ import 'package:tallee/data/db/tables/player_group_table.dart';
import 'package:tallee/data/db/tables/player_match_table.dart';
import 'package:tallee/data/db/tables/player_table.dart';
import 'package:tallee/data/db/tables/score_entry_table.dart';
import 'package:tallee/data/db/tables/statistic_game_table.dart';
import 'package:tallee/data/db/tables/statistic_group_table.dart';
import 'package:tallee/data/db/tables/statistic_scope_table.dart';
import 'package:tallee/data/db/tables/statistic_table.dart';
import 'package:tallee/data/db/tables/team_table.dart';
part 'database.g.dart';
@@ -38,10 +30,6 @@ part 'database.g.dart';
GameTable,
TeamTable,
ScoreEntryTable,
StatisticTable,
StatisticScopeTable,
StatisticGameTable,
StatisticGroupTable,
],
daos: [
PlayerDao,
@@ -52,10 +40,6 @@ part 'database.g.dart';
GameDao,
ScoreEntryDao,
TeamDao,
StatisticDao,
StatisticScopeDao,
StatisticGameDao,
StatisticGroupDao,
],
)
class AppDatabase extends _$AppDatabase {

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +0,0 @@
import 'package:drift/drift.dart';
import 'package:tallee/data/db/tables/game_table.dart';
import 'package:tallee/data/db/tables/statistic_table.dart';
class StatisticGameTable extends Table {
TextColumn get statisticId =>
text().references(StatisticTable, #id, onDelete: KeyAction.cascade)();
TextColumn get gameId =>
text().references(GameTable, #id, onDelete: KeyAction.cascade)();
@override
Set<Column<Object>> get primaryKey => {statisticId, gameId};
}

View File

@@ -1,13 +0,0 @@
import 'package:drift/drift.dart';
import 'package:tallee/data/db/tables/group_table.dart';
import 'package:tallee/data/db/tables/statistic_table.dart';
class StatisticGroupTable extends Table {
TextColumn get statisticId =>
text().references(StatisticTable, #id, onDelete: KeyAction.cascade)();
TextColumn get groupId =>
text().references(GroupTable, #id, onDelete: KeyAction.cascade)();
@override
Set<Column<Object>> get primaryKey => {statisticId, groupId};
}

View File

@@ -1,11 +0,0 @@
import 'package:drift/drift.dart';
import 'package:tallee/data/db/tables/statistic_table.dart';
class StatisticScopeTable extends Table {
TextColumn get statisticId =>
text().references(StatisticTable, #id, onDelete: KeyAction.cascade)();
TextColumn get scope => text()();
@override
Set<Column<Object>> get primaryKey => {statisticId, scope};
}

View File

@@ -1,11 +0,0 @@
import 'package:drift/drift.dart';
class StatisticTable extends Table {
TextColumn get id => text()();
TextColumn get type => text()();
TextColumn get timeframe => text().nullable()();
IntColumn get displayCount => integer().withDefault(const Constant(5))();
@override
Set<Column<Object>> get primaryKey => {id};
}

View File

@@ -8,13 +8,13 @@ class Game {
final String name;
final Ruleset ruleset;
final String description;
final AppColor color;
final GameColor color;
final String icon;
Game({
required this.name,
required this.ruleset,
this.color = AppColor.orange,
this.color = GameColor.orange,
this.description = '',
this.icon = '',
String? id,
@@ -33,7 +33,7 @@ class Game {
String? name,
Ruleset? ruleset,
String? description,
AppColor? color,
GameColor? color,
String? icon,
}) {
return Game(
@@ -73,7 +73,7 @@ class Game {
orElse: () => Ruleset.singleWinner,
),
description = json['description'],
color = AppColor.values.firstWhere((e) => e.name == json['color']),
color = GameColor.values.firstWhere((e) => e.name == json['color']),
icon = json['icon'];
Map<String, dynamic> toJson() => {

View File

@@ -5,17 +5,17 @@ import 'package:uuid/uuid.dart';
class Group {
final String id;
final DateTime createdAt;
final String name;
final List<Player> members;
final String description;
final DateTime createdAt;
final List<Player> members;
Group({
required this.name,
required this.members,
String? id,
DateTime? createdAt,
required this.name,
String? description,
required this.members,
}) : id = id ?? const Uuid().v4(),
createdAt = createdAt ?? clock.now(),
description = description ?? '';

View File

@@ -107,7 +107,7 @@ class Match {
name: '',
ruleset: Ruleset.singleWinner,
description: '',
color: AppColor.blue,
color: GameColor.blue,
icon: '',
),
group = null,

View File

@@ -1,48 +0,0 @@
import 'package:tallee/core/enums.dart';
import 'package:tallee/data/models/game.dart';
import 'package:tallee/data/models/group.dart';
import 'package:uuid/uuid.dart';
class Statistic {
final String id;
final StatisticType type;
final List<StatisticScope> scopes;
final Timeframe? timeframe;
final List<Group>? selectedGroups;
final List<Game>? selectedGames;
final int displayCount;
Statistic({
required this.type,
required this.scopes,
this.timeframe,
this.selectedGroups,
this.selectedGames,
this.displayCount = 5,
String? id,
}) : id = id ?? const Uuid().v4();
@override
String toString() {
return 'Statistic(id: $id, type: $type, scopes: $scopes, timeframe: $timeframe, selectedGroups: $selectedGroups, selectedGames: $selectedGames)';
}
Statistic copyWith({
StatisticType? type,
List<StatisticScope>? scopes,
Timeframe? timeframe,
List<Group>? selectedGroups,
List<Game>? selectedGames,
int? displayCount,
}) {
return Statistic(
id: id,
type: type ?? this.type,
scopes: scopes ?? this.scopes,
timeframe: timeframe ?? this.timeframe,
selectedGroups: selectedGroups ?? this.selectedGroups,
selectedGames: selectedGames ?? this.selectedGames,
displayCount: displayCount ?? this.displayCount,
);
}
}