Neue Datenbank Struktur #156

Open
gelbeinhalb wants to merge 88 commits from feature/88-neue-datenbank-struktur into development
11 changed files with 41 additions and 42 deletions
Showing only changes of commit 118b316a35 - Show all commits

View File

@@ -53,7 +53,7 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
id: game.id, id: game.id,
name: game.name, name: game.name,
ruleset: game.ruleset ?? '', ruleset: game.ruleset ?? '',
description: Value(game.description), description: game.description,
color: game.color, color: game.color,
icon: Value(game.icon), icon: Value(game.icon),
createdAt: game.createdAt, createdAt: game.createdAt,
@@ -79,7 +79,7 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
id: game.id, id: game.id,
name: game.name, name: game.name,
ruleset: game.ruleset ?? '', ruleset: game.ruleset ?? '',
description: Value(game.description), description: game.description,
color: game.color, color: game.color,
icon: Value(game.icon), icon: Value(game.icon),
createdAt: game.createdAt, createdAt: game.createdAt,
@@ -132,7 +132,7 @@ class GameDao extends DatabaseAccessor<AppDatabase> with _$GameDaoMixin {
/// Updates the description of the game with the given [gameId]. /// Updates the description of the game with the given [gameId].
Future<void> updateGameDescription({ Future<void> updateGameDescription({
required String gameId, required String gameId,
required String? newDescription, required String newDescription,
}) async { }) async {
await (update(gameTable)..where((g) => g.id.equals(gameId))).write( await (update(gameTable)..where((g) => g.id.equals(gameId))).write(
GameTableCompanion(description: Value(newDescription)), GameTableCompanion(description: Value(newDescription)),

View File

@@ -128,7 +128,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
id: game.id, id: game.id,
name: game.name, name: game.name,
ruleset: game.ruleset ?? '', ruleset: game.ruleset ?? '',
description: Value(game.description), description: game.description,
color: game.color, color: game.color,
icon: Value(game.icon), icon: Value(game.icon),
createdAt: game.createdAt, createdAt: game.createdAt,

View File

@@ -46,7 +46,7 @@ class AppDatabase extends _$AppDatabase {
AppDatabase([QueryExecutor? executor]) : super(executor ?? _openConnection()); AppDatabase([QueryExecutor? executor]) : super(executor ?? _openConnection());
@override @override
int get schemaVersion => 2; int get schemaVersion => 1;
gelbeinhalb marked this conversation as resolved Outdated

Habe beim ersten Starten der App diese Meldung bekommen:

[ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: Exception: You've bumped the schema version for your drift database but didn't provide a strategy for schema updates. Please do that by adapting the migrations getter in your database class.
package:drift/src/runtime/query_builder/migration.dart 20:5                             _defaultOnUpdate
package:drift/src/runtime/api/db_base.dart 133:43                                       GeneratedDatabase.beforeOpen.<fn>
dart:async/zone.dart 1525:13                                                            _rootRun
dart:async/zone.dart 1422:19                                                            _CustomZone.run
dart:async/zone.dart 2034:6                                                             _runZoned
dart:async/zone.dart 1960:10                                                            runZoned
package:drift/src/runtime/api/connection_user.dart 639:12                               DatabaseConnectionUser._runConnectionZone<…>

Ich glaube das ist für Datenbankmigrationen gedacht, also wenn man das Schema nachträglich verändert, deswegen lass das mal auf 1.

Habe beim ersten Starten der App diese Meldung bekommen: ```bash [ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: Exception: You've bumped the schema version for your drift database but didn't provide a strategy for schema updates. Please do that by adapting the migrations getter in your database class. package:drift/src/runtime/query_builder/migration.dart 20:5 _defaultOnUpdate package:drift/src/runtime/api/db_base.dart 133:43 GeneratedDatabase.beforeOpen.<fn> dart:async/zone.dart 1525:13 _rootRun dart:async/zone.dart 1422:19 _CustomZone.run dart:async/zone.dart 2034:6 _runZoned dart:async/zone.dart 1960:10 runZoned package:drift/src/runtime/api/connection_user.dart 639:12 DatabaseConnectionUser._runConnectionZone<…> ``` Ich glaube das ist für Datenbankmigrationen gedacht, also wenn man das Schema nachträglich verändert, deswegen lass das mal auf 1.

ups das war claude dann 😅

ups das war claude dann 😅
@override @override
MigrationStrategy get migration { MigrationStrategy get migration {

View File

@@ -673,9 +673,9 @@ class $GameTableTable extends GameTable
late final GeneratedColumn<String> description = GeneratedColumn<String>( late final GeneratedColumn<String> description = GeneratedColumn<String>(
'description', 'description',
aliasedName, aliasedName,
true, false,
type: DriftSqlType.string, type: DriftSqlType.string,
requiredDuringInsert: false, requiredDuringInsert: true,
); );
static const VerificationMeta _colorMeta = const VerificationMeta('color'); static const VerificationMeta _colorMeta = const VerificationMeta('color');
@override @override
@@ -757,6 +757,8 @@ class $GameTableTable extends GameTable
_descriptionMeta, _descriptionMeta,
), ),
); );
} else if (isInserting) {
context.missing(_descriptionMeta);
} }
if (data.containsKey('color')) { if (data.containsKey('color')) {
context.handle( context.handle(
@@ -804,7 +806,7 @@ class $GameTableTable extends GameTable
description: attachedDatabase.typeMapping.read( description: attachedDatabase.typeMapping.read(
DriftSqlType.string, DriftSqlType.string,
data['${effectivePrefix}description'], data['${effectivePrefix}description'],
), )!,
color: attachedDatabase.typeMapping.read( color: attachedDatabase.typeMapping.read(
DriftSqlType.string, DriftSqlType.string,
data['${effectivePrefix}color'], data['${effectivePrefix}color'],
@@ -830,7 +832,7 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
final String id; final String id;
final String name; final String name;
final String ruleset; final String ruleset;
final String? description; final String description;
final String color; final String color;
final String? icon; final String? icon;
final DateTime createdAt; final DateTime createdAt;
@@ -838,7 +840,7 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
required this.id, required this.id,
required this.name, required this.name,
required this.ruleset, required this.ruleset,
this.description, required this.description,
required this.color, required this.color,
this.icon, this.icon,
required this.createdAt, required this.createdAt,
@@ -849,9 +851,7 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
map['id'] = Variable<String>(id); map['id'] = Variable<String>(id);
map['name'] = Variable<String>(name); map['name'] = Variable<String>(name);
map['ruleset'] = Variable<String>(ruleset); map['ruleset'] = Variable<String>(ruleset);
if (!nullToAbsent || description != null) {
map['description'] = Variable<String>(description); map['description'] = Variable<String>(description);
}
map['color'] = Variable<String>(color); map['color'] = Variable<String>(color);
if (!nullToAbsent || icon != null) { if (!nullToAbsent || icon != null) {
map['icon'] = Variable<String>(icon); map['icon'] = Variable<String>(icon);
@@ -865,9 +865,7 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
id: Value(id), id: Value(id),
name: Value(name), name: Value(name),
ruleset: Value(ruleset), ruleset: Value(ruleset),
description: description == null && nullToAbsent description: Value(description),
? const Value.absent()
: Value(description),
color: Value(color), color: Value(color),
icon: icon == null && nullToAbsent ? const Value.absent() : Value(icon), icon: icon == null && nullToAbsent ? const Value.absent() : Value(icon),
createdAt: Value(createdAt), createdAt: Value(createdAt),
@@ -883,7 +881,7 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
id: serializer.fromJson<String>(json['id']), id: serializer.fromJson<String>(json['id']),
name: serializer.fromJson<String>(json['name']), name: serializer.fromJson<String>(json['name']),
ruleset: serializer.fromJson<String>(json['ruleset']), ruleset: serializer.fromJson<String>(json['ruleset']),
description: serializer.fromJson<String?>(json['description']), description: serializer.fromJson<String>(json['description']),
color: serializer.fromJson<String>(json['color']), color: serializer.fromJson<String>(json['color']),
icon: serializer.fromJson<String?>(json['icon']), icon: serializer.fromJson<String?>(json['icon']),
createdAt: serializer.fromJson<DateTime>(json['createdAt']), createdAt: serializer.fromJson<DateTime>(json['createdAt']),
@@ -896,7 +894,7 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
'id': serializer.toJson<String>(id), 'id': serializer.toJson<String>(id),
'name': serializer.toJson<String>(name), 'name': serializer.toJson<String>(name),
'ruleset': serializer.toJson<String>(ruleset), 'ruleset': serializer.toJson<String>(ruleset),
'description': serializer.toJson<String?>(description), 'description': serializer.toJson<String>(description),
'color': serializer.toJson<String>(color), 'color': serializer.toJson<String>(color),
'icon': serializer.toJson<String?>(icon), 'icon': serializer.toJson<String?>(icon),
'createdAt': serializer.toJson<DateTime>(createdAt), 'createdAt': serializer.toJson<DateTime>(createdAt),
@@ -907,7 +905,7 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
String? id, String? id,
String? name, String? name,
String? ruleset, String? ruleset,
Value<String?> description = const Value.absent(), String? description,
String? color, String? color,
Value<String?> icon = const Value.absent(), Value<String?> icon = const Value.absent(),
DateTime? createdAt, DateTime? createdAt,
@@ -915,7 +913,7 @@ class GameTableData extends DataClass implements Insertable<GameTableData> {
id: id ?? this.id, id: id ?? this.id,
name: name ?? this.name, name: name ?? this.name,
ruleset: ruleset ?? this.ruleset, ruleset: ruleset ?? this.ruleset,
description: description.present ? description.value : this.description, description: description ?? this.description,
color: color ?? this.color, color: color ?? this.color,
icon: icon.present ? icon.value : this.icon, icon: icon.present ? icon.value : this.icon,
createdAt: createdAt ?? this.createdAt, createdAt: createdAt ?? this.createdAt,
@@ -968,7 +966,7 @@ class GameTableCompanion extends UpdateCompanion<GameTableData> {
final Value<String> id; final Value<String> id;
final Value<String> name; final Value<String> name;
final Value<String> ruleset; final Value<String> ruleset;
final Value<String?> description; final Value<String> description;
final Value<String> color; final Value<String> color;
final Value<String?> icon; final Value<String?> icon;
final Value<DateTime> createdAt; final Value<DateTime> createdAt;
@@ -987,7 +985,7 @@ class GameTableCompanion extends UpdateCompanion<GameTableData> {
required String id, required String id,
required String name, required String name,
required String ruleset, required String ruleset,
this.description = const Value.absent(), required String description,
required String color, required String color,
this.icon = const Value.absent(), this.icon = const Value.absent(),
required DateTime createdAt, required DateTime createdAt,
@@ -995,6 +993,7 @@ class GameTableCompanion extends UpdateCompanion<GameTableData> {
}) : id = Value(id), }) : id = Value(id),
name = Value(name), name = Value(name),
ruleset = Value(ruleset), ruleset = Value(ruleset),
description = Value(description),
color = Value(color), color = Value(color),
createdAt = Value(createdAt); createdAt = Value(createdAt);
static Insertable<GameTableData> custom({ static Insertable<GameTableData> custom({
@@ -1023,7 +1022,7 @@ class GameTableCompanion extends UpdateCompanion<GameTableData> {
Value<String>? id, Value<String>? id,
Value<String>? name, Value<String>? name,
Value<String>? ruleset, Value<String>? ruleset,
Value<String?>? description, Value<String>? description,
Value<String>? color, Value<String>? color,
Value<String?>? icon, Value<String?>? icon,
Value<DateTime>? createdAt, Value<DateTime>? createdAt,
@@ -3663,7 +3662,7 @@ typedef $$GameTableTableCreateCompanionBuilder =
required String id, required String id,
required String name, required String name,
required String ruleset, required String ruleset,
Value<String?> description, required String description,
required String color, required String color,
Value<String?> icon, Value<String?> icon,
required DateTime createdAt, required DateTime createdAt,
@@ -3674,7 +3673,7 @@ typedef $$GameTableTableUpdateCompanionBuilder =
Value<String> id, Value<String> id,
Value<String> name, Value<String> name,
Value<String> ruleset, Value<String> ruleset,
Value<String?> description, Value<String> description,
Value<String> color, Value<String> color,
Value<String?> icon, Value<String?> icon,
Value<DateTime> createdAt, Value<DateTime> createdAt,
@@ -3908,7 +3907,7 @@ class $$GameTableTableTableManager
Value<String> id = const Value.absent(), Value<String> id = const Value.absent(),
Value<String> name = const Value.absent(), Value<String> name = const Value.absent(),
Value<String> ruleset = const Value.absent(), Value<String> ruleset = const Value.absent(),
Value<String?> description = const Value.absent(), Value<String> description = const Value.absent(),
Value<String> color = const Value.absent(), Value<String> color = const Value.absent(),
Value<String?> icon = const Value.absent(), Value<String?> icon = const Value.absent(),
Value<DateTime> createdAt = const Value.absent(), Value<DateTime> createdAt = const Value.absent(),
@@ -3928,7 +3927,7 @@ class $$GameTableTableTableManager
required String id, required String id,
required String name, required String name,
required String ruleset, required String ruleset,
Value<String?> description = const Value.absent(), required String description,
required String color, required String color,
Value<String?> icon = const Value.absent(), Value<String?> icon = const Value.absent(),
required DateTime createdAt, required DateTime createdAt,

View File

@@ -4,7 +4,7 @@ class GameTable extends Table {
TextColumn get id => text()(); TextColumn get id => text()();
TextColumn get name => text()(); TextColumn get name => text()();
TextColumn get ruleset => text()(); TextColumn get ruleset => text()();
gelbeinhalb marked this conversation as resolved
Review

Gleiche anmerkung wie oben, würde ich über einen int lösen

Gleiche anmerkung wie oben, würde ich über einen `int` lösen
TextColumn get description => text().nullable()(); TextColumn get description => text()();
gelbeinhalb marked this conversation as resolved Outdated

Gleiches wie oben, nicht nullable machen sondern einfach als Standard n leeren String

Gleiches wie oben, nicht nullable machen sondern einfach als Standard n leeren String
TextColumn get color => text()(); TextColumn get color => text()();
TextColumn get icon => text().nullable()(); TextColumn get icon => text().nullable()();
DateTimeColumn get createdAt => dateTime()(); DateTimeColumn get createdAt => dateTime()();

View File

@@ -6,7 +6,7 @@ class Game {
final DateTime createdAt; final DateTime createdAt;
final String name; final String name;
final String? ruleset; final String? ruleset;
gelbeinhalb marked this conversation as resolved
Review

Ruleset sollte nicht optional, weil das immer gebraucht wird
Ruleset als enum

Ruleset sollte nicht optional, weil das immer gebraucht wird Ruleset als enum
final String? description; final String description;
gelbeinhalb marked this conversation as resolved Outdated

Description als leeren string setzen, wenn nicht übergeben

Description als leeren string setzen, wenn nicht übergeben

warum findest du leeren string besser als nullable?

warum findest du leeren string besser als nullable?

Finde null sollte man nur dann verwenden, wenns halt nicht anders geht, wie z.B. bei objekten

Finde null sollte man nur dann verwenden, wenns halt nicht anders geht, wie z.B. bei objekten
final String color; final String color;
gelbeinhalb marked this conversation as resolved Outdated

Hier lieber enum, gerne auch mit einem Color.none

Hier lieber enum, gerne auch mit einem `Color.none`

warum aber nicht hex codes?

warum aber nicht hex codes?

oder willst du die farben vorgeben?

oder willst du die farben vorgeben?

Ja man könnte auch hexcodes machen. Würde die Farben so oder so vorgeben unabhängig davon wie man sie speichert

Ja man könnte auch hexcodes machen. Würde die Farben so oder so vorgeben unabhängig davon wie man sie speichert

würde enums maybe machen, weil man sonst im export einfach den hex code ändern könnte. Also idk ob das juckt aber 🤷‍♂️

würde enums maybe machen, weil man sonst im export einfach den hex code ändern könnte. Also idk ob das juckt aber 🤷‍♂️
final String? icon; final String? icon;
gelbeinhalb marked this conversation as resolved Outdated

Hier auch mit enum arbeiten?

Hier auch mit enum arbeiten?
@@ -15,7 +15,7 @@ class Game {
DateTime? createdAt, DateTime? createdAt,
required this.name, required this.name,
this.ruleset, this.ruleset,
this.description, required this.description,
required this.color, required this.color,
Review

Description sollte nicht obligatorisch sein, sondern optional. Wenn nicht gesetzt soll es ein leerer String werden.

Description sollte nicht obligatorisch sein, sondern optional. Wenn nicht gesetzt soll es ein leerer String werden.
Review

Dachte man soll den als leeren String selber setzen müssen

Dachte man soll den als leeren String selber setzen müssen
Review

würde das lieber so machen, weil man ja sonst immer unnötig die description setzten muss

würde das lieber so machen, weil man ja sonst immer unnötig die description setzten muss
Review

finde auch optional

finde auch optional
this.icon, this.icon,
}) : id = id ?? const Uuid().v4(), }) : id = id ?? const Uuid().v4(),

View File

@@ -131,7 +131,7 @@ void main() {
// Verifies that a game with null optional fields can be added and retrieved. // Verifies that a game with null optional fields can be added and retrieved.
test('addGame handles game with null optional fields', () async { test('addGame handles game with null optional fields', () async {
final gameWithNulls = Game(name: 'Simple Game', color: '0xFF000000'); final gameWithNulls = Game(name: 'Simple Game', description: 'A simple game', color: '0xFF000000');
final result = await database.gameDao.addGame(game: gameWithNulls); final result = await database.gameDao.addGame(game: gameWithNulls);
expect(result, true); expect(result, true);
@@ -139,7 +139,7 @@ void main() {
gameId: gameWithNulls.id, gameId: gameWithNulls.id,
); );
expect(fetchedGame.name, 'Simple Game'); expect(fetchedGame.name, 'Simple Game');
expect(fetchedGame.description, isNull); expect(fetchedGame.description, 'A simple game');
expect(fetchedGame.color, '0xFF000000'); expect(fetchedGame.color, '0xFF000000');
expect(fetchedGame.icon, isNull); expect(fetchedGame.icon, isNull);
}); });
@@ -305,19 +305,19 @@ void main() {
expect(updatedGame.description, 'An updated description'); expect(updatedGame.description, 'An updated description');
}); });
// Verifies that updateGameDescription can set the description to null. // Verifies that updateGameDescription can set the description to an empty string.
test('updateGameDescription can set description to null', () async { test('updateGameDescription can set description to empty string', () async {
await database.gameDao.addGame(game: testGame1); await database.gameDao.addGame(game: testGame1);
await database.gameDao.updateGameDescription( await database.gameDao.updateGameDescription(
gameId: testGame1.id, gameId: testGame1.id,
newDescription: null, newDescription: '',
); );
final updatedGame = await database.gameDao.getGameById( final updatedGame = await database.gameDao.getGameById(
gameId: testGame1.id, gameId: testGame1.id,
); );
expect(updatedGame.description, isNull); expect(updatedGame.description, '');
}); });
// Verifies that updateGameDescription does nothing when game doesn't exist. // Verifies that updateGameDescription does nothing when game doesn't exist.
@@ -502,7 +502,7 @@ void main() {
gameId: longGame.id, gameId: longGame.id,
); );
expect(fetchedGame.name.length, 10000); expect(fetchedGame.name.length, 10000);
expect(fetchedGame.description?.length, 10000); expect(fetchedGame.description.length, 10000);
expect(fetchedGame.ruleset?.length, 10000); expect(fetchedGame.ruleset?.length, 10000);
}); });

View File

@@ -48,7 +48,7 @@ void main() {
name: 'Test Group 2', name: 'Test Group 2',
members: [testPlayer4, testPlayer5], members: [testPlayer4, testPlayer5],
); );
testGame = Game(name: 'Test Game', color: '0xFF000000'); testGame = Game(name: 'Test Game', description: 'A test game', color: '0xFF000000');
testMatch1 = Match( testMatch1 = Match(
name: 'First Test Match', name: 'First Test Match',
game: testGame, game: testGame,

View File

@@ -46,7 +46,7 @@ void main() {
name: 'Test Group', name: 'Test Group',
members: [testPlayer1, testPlayer2, testPlayer3], members: [testPlayer1, testPlayer2, testPlayer3],
); );
testGame = Game(name: 'Test Game', color: '0xFF000000'); testGame = Game(name: 'Test Game', description: 'A test game', color: '0xFF000000');
testMatchOnlyGroup = Match( testMatchOnlyGroup = Match(
name: 'Test Match with Group', name: 'Test Match with Group',
game: testGame, game: testGame,

View File

@@ -31,7 +31,7 @@ void main() {
testPlayer1 = Player(name: 'Alice'); testPlayer1 = Player(name: 'Alice');
testPlayer2 = Player(name: 'Bob'); testPlayer2 = Player(name: 'Bob');
testPlayer3 = Player(name: 'Charlie'); testPlayer3 = Player(name: 'Charlie');
testGame = Game(name: 'Test Game', color: '0xFF000000'); testGame = Game(name: 'Test Game', description: 'A test game', color: '0xFF000000');
testMatch1 = Match( testMatch1 = Match(
name: 'Test Match 1', name: 'Test Match 1',
game: testGame, game: testGame,

View File

@@ -48,8 +48,8 @@ void main() {
name: 'Team Gamma', name: 'Team Gamma',
members: [testPlayer1, testPlayer3], members: [testPlayer1, testPlayer3],
); );
testGame1 = Game(name: 'Game 1', color: '0xFF000000'); testGame1 = Game(name: 'Game 1', description: 'Test game 1', color: '0xFF000000');
testGame2 = Game(name: 'Game 2', color: '0xFF000000'); testGame2 = Game(name: 'Game 2', description: 'Test game 2', color: '0xFF000000');
}); });
await database.playerDao.addPlayersAsList( await database.playerDao.addPlayersAsList(