added endedAt to matches

This commit is contained in:
gelbeinhalb
2026-02-01 17:55:42 +01:00
parent 2a3ea32193
commit 415cae18cd
6 changed files with 101 additions and 4 deletions

View File

@@ -142,6 +142,9 @@
"createdAt": { "createdAt": {
"type": "string" "type": "string"
}, },
"endedAt": {
"type": ["string", "null"]
},
"gameId": { "gameId": {
"type": "string" "type": "string"
}, },

View File

@@ -38,6 +38,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
players: players, players: players,
notes: row.notes ?? '', notes: row.notes ?? '',
createdAt: row.createdAt, createdAt: row.createdAt,
endedAt: row.endedAt,
); );
}), }),
); );
@@ -68,6 +69,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
players: players, players: players,
notes: result.notes ?? '', notes: result.notes ?? '',
createdAt: result.createdAt, createdAt: result.createdAt,
endedAt: result.endedAt,
); );
} }
@@ -84,6 +86,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
name: Value(match.name), name: Value(match.name),
notes: Value(match.notes), notes: Value(match.notes),
createdAt: match.createdAt, createdAt: match.createdAt,
endedAt: Value(match.endedAt),
), ),
mode: InsertMode.insertOrReplace, mode: InsertMode.insertOrReplace,
); );
@@ -166,6 +169,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
name: Value(match.name), name: Value(match.name),
notes: Value(match.notes), notes: Value(match.notes),
createdAt: match.createdAt, createdAt: match.createdAt,
endedAt: Value(match.endedAt),
), ),
) )
.toList(), .toList(),
@@ -346,6 +350,20 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
return rowsAffected > 0; return rowsAffected > 0;
} }
/// Updates the endedAt timestamp of the match with the given [matchId].
/// Pass null to remove the ended time (mark match as ongoing).
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> updateMatchEndedAt({
required String matchId,
required DateTime? endedAt,
}) async {
final query = update(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.write(
MatchTableCompanion(endedAt: Value(endedAt)),
);
return rowsAffected > 0;
}
// ============================================================ // ============================================================
// TEMPORARY: Winner methods - these are stubs and do not persist data // TEMPORARY: Winner methods - these are stubs and do not persist data
// TODO: Implement proper winner handling // TODO: Implement proper winner handling

View File

@@ -1155,6 +1155,17 @@ class $MatchTableTable extends MatchTable
type: DriftSqlType.dateTime, type: DriftSqlType.dateTime,
requiredDuringInsert: true, requiredDuringInsert: true,
); );
static const VerificationMeta _endedAtMeta = const VerificationMeta(
'endedAt',
);
@override
late final GeneratedColumn<DateTime> endedAt = GeneratedColumn<DateTime>(
'ended_at',
aliasedName,
true,
type: DriftSqlType.dateTime,
requiredDuringInsert: false,
);
@override @override
List<GeneratedColumn> get $columns => [ List<GeneratedColumn> get $columns => [
id, id,
@@ -1163,6 +1174,7 @@ class $MatchTableTable extends MatchTable
name, name,
notes, notes,
createdAt, createdAt,
endedAt,
]; ];
@override @override
String get aliasedName => _alias ?? actualTableName; String get aliasedName => _alias ?? actualTableName;
@@ -1215,6 +1227,12 @@ class $MatchTableTable extends MatchTable
} else if (isInserting) { } else if (isInserting) {
context.missing(_createdAtMeta); context.missing(_createdAtMeta);
} }
if (data.containsKey('ended_at')) {
context.handle(
_endedAtMeta,
endedAt.isAcceptableOrUnknown(data['ended_at']!, _endedAtMeta),
);
}
return context; return context;
} }
@@ -1248,6 +1266,10 @@ class $MatchTableTable extends MatchTable
DriftSqlType.dateTime, DriftSqlType.dateTime,
data['${effectivePrefix}created_at'], data['${effectivePrefix}created_at'],
)!, )!,
endedAt: attachedDatabase.typeMapping.read(
DriftSqlType.dateTime,
data['${effectivePrefix}ended_at'],
),
); );
} }
@@ -1264,6 +1286,7 @@ class MatchTableData extends DataClass implements Insertable<MatchTableData> {
final String? name; final String? name;
final String? notes; final String? notes;
final DateTime createdAt; final DateTime createdAt;
final DateTime? endedAt;
const MatchTableData({ const MatchTableData({
required this.id, required this.id,
required this.gameId, required this.gameId,
@@ -1271,6 +1294,7 @@ class MatchTableData extends DataClass implements Insertable<MatchTableData> {
this.name, this.name,
this.notes, this.notes,
required this.createdAt, required this.createdAt,
this.endedAt,
}); });
@override @override
Map<String, Expression> toColumns(bool nullToAbsent) { Map<String, Expression> toColumns(bool nullToAbsent) {
@@ -1287,6 +1311,9 @@ class MatchTableData extends DataClass implements Insertable<MatchTableData> {
map['notes'] = Variable<String>(notes); map['notes'] = Variable<String>(notes);
} }
map['created_at'] = Variable<DateTime>(createdAt); map['created_at'] = Variable<DateTime>(createdAt);
if (!nullToAbsent || endedAt != null) {
map['ended_at'] = Variable<DateTime>(endedAt);
}
return map; return map;
} }
@@ -1302,6 +1329,9 @@ class MatchTableData extends DataClass implements Insertable<MatchTableData> {
? const Value.absent() ? const Value.absent()
: Value(notes), : Value(notes),
createdAt: Value(createdAt), createdAt: Value(createdAt),
endedAt: endedAt == null && nullToAbsent
? const Value.absent()
: Value(endedAt),
); );
} }
@@ -1317,6 +1347,7 @@ class MatchTableData extends DataClass implements Insertable<MatchTableData> {
name: serializer.fromJson<String?>(json['name']), name: serializer.fromJson<String?>(json['name']),
notes: serializer.fromJson<String?>(json['notes']), notes: serializer.fromJson<String?>(json['notes']),
createdAt: serializer.fromJson<DateTime>(json['createdAt']), createdAt: serializer.fromJson<DateTime>(json['createdAt']),
endedAt: serializer.fromJson<DateTime?>(json['endedAt']),
); );
} }
@override @override
@@ -1329,6 +1360,7 @@ class MatchTableData extends DataClass implements Insertable<MatchTableData> {
'name': serializer.toJson<String?>(name), 'name': serializer.toJson<String?>(name),
'notes': serializer.toJson<String?>(notes), 'notes': serializer.toJson<String?>(notes),
'createdAt': serializer.toJson<DateTime>(createdAt), 'createdAt': serializer.toJson<DateTime>(createdAt),
'endedAt': serializer.toJson<DateTime?>(endedAt),
}; };
} }
@@ -1339,6 +1371,7 @@ class MatchTableData extends DataClass implements Insertable<MatchTableData> {
Value<String?> name = const Value.absent(), Value<String?> name = const Value.absent(),
Value<String?> notes = const Value.absent(), Value<String?> notes = const Value.absent(),
DateTime? createdAt, DateTime? createdAt,
Value<DateTime?> endedAt = const Value.absent(),
}) => MatchTableData( }) => MatchTableData(
id: id ?? this.id, id: id ?? this.id,
gameId: gameId ?? this.gameId, gameId: gameId ?? this.gameId,
@@ -1346,6 +1379,7 @@ class MatchTableData extends DataClass implements Insertable<MatchTableData> {
name: name.present ? name.value : this.name, name: name.present ? name.value : this.name,
notes: notes.present ? notes.value : this.notes, notes: notes.present ? notes.value : this.notes,
createdAt: createdAt ?? this.createdAt, createdAt: createdAt ?? this.createdAt,
endedAt: endedAt.present ? endedAt.value : this.endedAt,
); );
MatchTableData copyWithCompanion(MatchTableCompanion data) { MatchTableData copyWithCompanion(MatchTableCompanion data) {
return MatchTableData( return MatchTableData(
@@ -1355,6 +1389,7 @@ class MatchTableData extends DataClass implements Insertable<MatchTableData> {
name: data.name.present ? data.name.value : this.name, name: data.name.present ? data.name.value : this.name,
notes: data.notes.present ? data.notes.value : this.notes, notes: data.notes.present ? data.notes.value : this.notes,
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
endedAt: data.endedAt.present ? data.endedAt.value : this.endedAt,
); );
} }
@@ -1366,13 +1401,15 @@ class MatchTableData extends DataClass implements Insertable<MatchTableData> {
..write('groupId: $groupId, ') ..write('groupId: $groupId, ')
..write('name: $name, ') ..write('name: $name, ')
..write('notes: $notes, ') ..write('notes: $notes, ')
..write('createdAt: $createdAt') ..write('createdAt: $createdAt, ')
..write('endedAt: $endedAt')
..write(')')) ..write(')'))
.toString(); .toString();
} }
@override @override
int get hashCode => Object.hash(id, gameId, groupId, name, notes, createdAt); int get hashCode =>
Object.hash(id, gameId, groupId, name, notes, createdAt, endedAt);
@override @override
bool operator ==(Object other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
@@ -1382,7 +1419,8 @@ class MatchTableData extends DataClass implements Insertable<MatchTableData> {
other.groupId == this.groupId && other.groupId == this.groupId &&
other.name == this.name && other.name == this.name &&
other.notes == this.notes && other.notes == this.notes &&
other.createdAt == this.createdAt); other.createdAt == this.createdAt &&
other.endedAt == this.endedAt);
} }
class MatchTableCompanion extends UpdateCompanion<MatchTableData> { class MatchTableCompanion extends UpdateCompanion<MatchTableData> {
@@ -1392,6 +1430,7 @@ class MatchTableCompanion extends UpdateCompanion<MatchTableData> {
final Value<String?> name; final Value<String?> name;
final Value<String?> notes; final Value<String?> notes;
final Value<DateTime> createdAt; final Value<DateTime> createdAt;
final Value<DateTime?> endedAt;
final Value<int> rowid; final Value<int> rowid;
const MatchTableCompanion({ const MatchTableCompanion({
this.id = const Value.absent(), this.id = const Value.absent(),
@@ -1400,6 +1439,7 @@ class MatchTableCompanion extends UpdateCompanion<MatchTableData> {
this.name = const Value.absent(), this.name = const Value.absent(),
this.notes = const Value.absent(), this.notes = const Value.absent(),
this.createdAt = const Value.absent(), this.createdAt = const Value.absent(),
this.endedAt = const Value.absent(),
this.rowid = const Value.absent(), this.rowid = const Value.absent(),
}); });
MatchTableCompanion.insert({ MatchTableCompanion.insert({
@@ -1409,6 +1449,7 @@ class MatchTableCompanion extends UpdateCompanion<MatchTableData> {
this.name = const Value.absent(), this.name = const Value.absent(),
this.notes = const Value.absent(), this.notes = const Value.absent(),
required DateTime createdAt, required DateTime createdAt,
this.endedAt = const Value.absent(),
this.rowid = const Value.absent(), this.rowid = const Value.absent(),
}) : id = Value(id), }) : id = Value(id),
gameId = Value(gameId), gameId = Value(gameId),
@@ -1420,6 +1461,7 @@ class MatchTableCompanion extends UpdateCompanion<MatchTableData> {
Expression<String>? name, Expression<String>? name,
Expression<String>? notes, Expression<String>? notes,
Expression<DateTime>? createdAt, Expression<DateTime>? createdAt,
Expression<DateTime>? endedAt,
Expression<int>? rowid, Expression<int>? rowid,
}) { }) {
return RawValuesInsertable({ return RawValuesInsertable({
@@ -1429,6 +1471,7 @@ class MatchTableCompanion extends UpdateCompanion<MatchTableData> {
if (name != null) 'name': name, if (name != null) 'name': name,
if (notes != null) 'notes': notes, if (notes != null) 'notes': notes,
if (createdAt != null) 'created_at': createdAt, if (createdAt != null) 'created_at': createdAt,
if (endedAt != null) 'ended_at': endedAt,
if (rowid != null) 'rowid': rowid, if (rowid != null) 'rowid': rowid,
}); });
} }
@@ -1440,6 +1483,7 @@ class MatchTableCompanion extends UpdateCompanion<MatchTableData> {
Value<String?>? name, Value<String?>? name,
Value<String?>? notes, Value<String?>? notes,
Value<DateTime>? createdAt, Value<DateTime>? createdAt,
Value<DateTime?>? endedAt,
Value<int>? rowid, Value<int>? rowid,
}) { }) {
return MatchTableCompanion( return MatchTableCompanion(
@@ -1449,6 +1493,7 @@ class MatchTableCompanion extends UpdateCompanion<MatchTableData> {
name: name ?? this.name, name: name ?? this.name,
notes: notes ?? this.notes, notes: notes ?? this.notes,
createdAt: createdAt ?? this.createdAt, createdAt: createdAt ?? this.createdAt,
endedAt: endedAt ?? this.endedAt,
rowid: rowid ?? this.rowid, rowid: rowid ?? this.rowid,
); );
} }
@@ -1474,6 +1519,9 @@ class MatchTableCompanion extends UpdateCompanion<MatchTableData> {
if (createdAt.present) { if (createdAt.present) {
map['created_at'] = Variable<DateTime>(createdAt.value); map['created_at'] = Variable<DateTime>(createdAt.value);
} }
if (endedAt.present) {
map['ended_at'] = Variable<DateTime>(endedAt.value);
}
if (rowid.present) { if (rowid.present) {
map['rowid'] = Variable<int>(rowid.value); map['rowid'] = Variable<int>(rowid.value);
} }
@@ -1489,6 +1537,7 @@ class MatchTableCompanion extends UpdateCompanion<MatchTableData> {
..write('name: $name, ') ..write('name: $name, ')
..write('notes: $notes, ') ..write('notes: $notes, ')
..write('createdAt: $createdAt, ') ..write('createdAt: $createdAt, ')
..write('endedAt: $endedAt, ')
..write('rowid: $rowid') ..write('rowid: $rowid')
..write(')')) ..write(')'))
.toString(); .toString();
@@ -4005,6 +4054,7 @@ typedef $$MatchTableTableCreateCompanionBuilder =
Value<String?> name, Value<String?> name,
Value<String?> notes, Value<String?> notes,
required DateTime createdAt, required DateTime createdAt,
Value<DateTime?> endedAt,
Value<int> rowid, Value<int> rowid,
}); });
typedef $$MatchTableTableUpdateCompanionBuilder = typedef $$MatchTableTableUpdateCompanionBuilder =
@@ -4015,6 +4065,7 @@ typedef $$MatchTableTableUpdateCompanionBuilder =
Value<String?> name, Value<String?> name,
Value<String?> notes, Value<String?> notes,
Value<DateTime> createdAt, Value<DateTime> createdAt,
Value<DateTime?> endedAt,
Value<int> rowid, Value<int> rowid,
}); });
@@ -4129,6 +4180,11 @@ class $$MatchTableTableFilterComposer
builder: (column) => ColumnFilters(column), builder: (column) => ColumnFilters(column),
); );
ColumnFilters<DateTime> get endedAt => $composableBuilder(
column: $table.endedAt,
builder: (column) => ColumnFilters(column),
);
$$GameTableTableFilterComposer get gameId { $$GameTableTableFilterComposer get gameId {
final $$GameTableTableFilterComposer composer = $composerBuilder( final $$GameTableTableFilterComposer composer = $composerBuilder(
composer: this, composer: this,
@@ -4255,6 +4311,11 @@ class $$MatchTableTableOrderingComposer
builder: (column) => ColumnOrderings(column), builder: (column) => ColumnOrderings(column),
); );
ColumnOrderings<DateTime> get endedAt => $composableBuilder(
column: $table.endedAt,
builder: (column) => ColumnOrderings(column),
);
$$GameTableTableOrderingComposer get gameId { $$GameTableTableOrderingComposer get gameId {
final $$GameTableTableOrderingComposer composer = $composerBuilder( final $$GameTableTableOrderingComposer composer = $composerBuilder(
composer: this, composer: this,
@@ -4323,6 +4384,9 @@ class $$MatchTableTableAnnotationComposer
GeneratedColumn<DateTime> get createdAt => GeneratedColumn<DateTime> get createdAt =>
$composableBuilder(column: $table.createdAt, builder: (column) => column); $composableBuilder(column: $table.createdAt, builder: (column) => column);
GeneratedColumn<DateTime> get endedAt =>
$composableBuilder(column: $table.endedAt, builder: (column) => column);
$$GameTableTableAnnotationComposer get gameId { $$GameTableTableAnnotationComposer get gameId {
final $$GameTableTableAnnotationComposer composer = $composerBuilder( final $$GameTableTableAnnotationComposer composer = $composerBuilder(
composer: this, composer: this,
@@ -4459,6 +4523,7 @@ class $$MatchTableTableTableManager
Value<String?> name = const Value.absent(), Value<String?> name = const Value.absent(),
Value<String?> notes = const Value.absent(), Value<String?> notes = const Value.absent(),
Value<DateTime> createdAt = const Value.absent(), Value<DateTime> createdAt = const Value.absent(),
Value<DateTime?> endedAt = const Value.absent(),
Value<int> rowid = const Value.absent(), Value<int> rowid = const Value.absent(),
}) => MatchTableCompanion( }) => MatchTableCompanion(
id: id, id: id,
@@ -4467,6 +4532,7 @@ class $$MatchTableTableTableManager
name: name, name: name,
notes: notes, notes: notes,
createdAt: createdAt, createdAt: createdAt,
endedAt: endedAt,
rowid: rowid, rowid: rowid,
), ),
createCompanionCallback: createCompanionCallback:
@@ -4477,6 +4543,7 @@ class $$MatchTableTableTableManager
Value<String?> name = const Value.absent(), Value<String?> name = const Value.absent(),
Value<String?> notes = const Value.absent(), Value<String?> notes = const Value.absent(),
required DateTime createdAt, required DateTime createdAt,
Value<DateTime?> endedAt = const Value.absent(),
Value<int> rowid = const Value.absent(), Value<int> rowid = const Value.absent(),
}) => MatchTableCompanion.insert( }) => MatchTableCompanion.insert(
id: id, id: id,
@@ -4485,6 +4552,7 @@ class $$MatchTableTableTableManager
name: name, name: name,
notes: notes, notes: notes,
createdAt: createdAt, createdAt: createdAt,
endedAt: endedAt,
rowid: rowid, rowid: rowid,
), ),
withReferenceMapper: (p0) => p0 withReferenceMapper: (p0) => p0

View File

@@ -11,6 +11,7 @@ class MatchTable extends Table {
TextColumn get name => text().nullable()(); TextColumn get name => text().nullable()();
TextColumn get notes => text().nullable()(); TextColumn get notes => text().nullable()();
DateTimeColumn get createdAt => dateTime()(); DateTimeColumn get createdAt => dateTime()();
DateTimeColumn get endedAt => dateTime().nullable()();
@override @override
Set<Column<Object>> get primaryKey => {id}; Set<Column<Object>> get primaryKey => {id};

View File

@@ -8,6 +8,7 @@ import 'package:uuid/uuid.dart';
class Match { class Match {
final String id; final String id;
final DateTime createdAt; final DateTime createdAt;
final DateTime? endedAt;
final String name; final String name;
final Game game; final Game game;
final Group? group; final Group? group;
@@ -18,6 +19,7 @@ class Match {
Match({ Match({
String? id, String? id,
DateTime? createdAt, DateTime? createdAt,
this.endedAt,
required this.name, required this.name,
required this.game, required this.game,
this.group, this.group,
@@ -29,7 +31,7 @@ class Match {
@override @override
String toString() { String toString() {
return 'Match{id: $id, name: $name, game: $game, group: $group, players: $players, notes: $notes}'; return 'Match{id: $id, name: $name, game: $game, group: $group, players: $players, notes: $notes, endedAt: $endedAt}';
} }
/// Creates a Match instance from a JSON object (ID references format). /// Creates a Match instance from a JSON object (ID references format).
@@ -37,6 +39,7 @@ class Match {
Match.fromJson(Map<String, dynamic> json) Match.fromJson(Map<String, dynamic> json)
: id = json['id'], : id = json['id'],
createdAt = DateTime.parse(json['createdAt']), createdAt = DateTime.parse(json['createdAt']),
endedAt = json['endedAt'] != null ? DateTime.parse(json['endedAt']) : null,
name = json['name'], name = json['name'],
game = Game(name: '', ruleset: Ruleset.singleWinner, description: '', color: '', icon: ''), // Populated during import via DataTransferService game = Game(name: '', ruleset: Ruleset.singleWinner, description: '', color: '', icon: ''), // Populated during import via DataTransferService
group = null, // Populated during import via DataTransferService group = null, // Populated during import via DataTransferService
@@ -47,6 +50,7 @@ class Match {
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
'id': id, 'id': id,
'createdAt': createdAt.toIso8601String(), 'createdAt': createdAt.toIso8601String(),
'endedAt': endedAt?.toIso8601String(),
'name': name, 'name': name,
'gameId': game.id, 'gameId': game.id,
'groupId': group?.id, 'groupId': group?.id,

View File

@@ -61,6 +61,7 @@ class DataTransferService {
'id': m.id, 'id': m.id,
'name': m.name, 'name': m.name,
'createdAt': m.createdAt.toIso8601String(), 'createdAt': m.createdAt.toIso8601String(),
'endedAt': m.endedAt?.toIso8601String(),
'gameId': m.game.id, 'gameId': m.game.id,
'groupId': m.group?.id, 'groupId': m.group?.id,
'playerIds': (m.players ?? []).map((p) => p.id).toList(), 'playerIds': (m.players ?? []).map((p) => p.id).toList(),
@@ -195,6 +196,7 @@ class DataTransferService {
final String gameId = map['gameId'] as String; final String gameId = map['gameId'] as String;
final String? groupId = map['groupId'] as String?; final String? groupId = map['groupId'] as String?;
final List<String> playerIds = (map['playerIds'] as List<dynamic>? ?? []).cast<String>(); final List<String> playerIds = (map['playerIds'] as List<dynamic>? ?? []).cast<String>();
final DateTime? endedAt = map['endedAt'] != null ? DateTime.parse(map['endedAt'] as String) : null;
final game = gameById[gameId]; final game = gameById[gameId];
final group = (groupId == null) ? null : groupById[groupId]; final group = (groupId == null) ? null : groupById[groupId];
@@ -210,6 +212,7 @@ class DataTransferService {
group: group, group: group,
players: players.isNotEmpty ? players : null, players: players.isNotEmpty ? players : null,
createdAt: DateTime.parse(map['createdAt'] as String), createdAt: DateTime.parse(map['createdAt'] as String),
endedAt: endedAt,
notes: map['notes'] as String? ?? '', notes: map['notes'] as String? ?? '',
); );
}).toList(); }).toList();