mnemo_cards/mnemo_cards_backend/lib/database/daos/statistics_dao.dart

115 lines
3.6 KiB
Dart
Raw Normal View History

2025-12-13 13:27:05 +00:00
import 'package:drift/drift.dart';
2025-12-13 23:35:14 +00:00
import 'package:drift_postgres/drift_postgres.dart';
2025-12-13 13:27:05 +00:00
import '../database.dart';
import '../tables/statistics.dart';
import '../tables/users.dart';
2025-12-14 20:36:05 +00:00
import 'mixins/soft_delete_mixin.dart';
2025-12-13 13:27:05 +00:00
part 'statistics_dao.g.dart';
@DriftAccessor(tables: [StudySessions])
2025-12-20 18:26:15 +00:00
class StatisticsDao extends DatabaseAccessor<AppDatabase>
2025-12-14 20:36:05 +00:00
with _$StatisticsDaoMixin, SoftDeleteMixin<StudySessions, StudySession> {
2025-12-13 13:27:05 +00:00
StatisticsDao(super.db);
2025-12-20 18:26:15 +00:00
2025-12-14 20:36:05 +00:00
@override
TableInfo<StudySessions, StudySession> get table => studySessions;
2025-12-20 18:26:15 +00:00
2025-12-14 20:36:05 +00:00
/// Получить сессию по ID (только активные)
2025-12-13 20:55:50 +00:00
Future<StudySession?> getSessionById(String id) {
2025-12-14 20:36:05 +00:00
return getActiveById(id);
2025-12-13 13:27:05 +00:00
}
2025-12-20 18:26:15 +00:00
2025-12-14 20:36:05 +00:00
/// Получить сессию по sessionId (только активные)
2025-12-13 13:27:05 +00:00
Future<StudySession?> getSessionBySessionId(String sessionId) {
2025-12-20 18:26:15 +00:00
return (selectActive()..where((s) => s.sessionId.equals(sessionId)))
.getSingleOrNull();
2025-12-13 13:27:05 +00:00
}
2025-12-20 18:26:15 +00:00
2025-12-14 20:36:05 +00:00
/// Получить активные сессии пользователя (не завершенные и не удаленные)
2025-12-13 20:55:50 +00:00
Future<List<StudySession>> getActiveSessions(String userId) {
2025-12-14 20:36:05 +00:00
return (selectActive()
2025-12-20 18:26:15 +00:00
..where((s) => s.userId.equals(userId))
..where((s) => s.endTime.isNull())
..orderBy([(s) => OrderingTerm.desc(s.startTime)]))
.get();
2025-12-13 13:27:05 +00:00
}
2025-12-20 18:26:15 +00:00
2025-12-14 20:36:05 +00:00
/// Получить сессии пользователя (только активные)
2025-12-20 18:26:15 +00:00
Future<List<StudySession>> getSessionsByUserId(
String userId, {
2025-12-13 13:27:05 +00:00
int? limit,
int? offset,
DateTime? fromDate,
DateTime? toDate,
}) {
2025-12-14 20:36:05 +00:00
final query = selectActive()
2025-12-13 13:27:05 +00:00
..where((s) => s.userId.equals(userId))
..orderBy([(s) => OrderingTerm.desc(s.startTime)]);
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
if (fromDate != null) {
2025-12-20 18:26:15 +00:00
query.where(
(s) => s.startTime.isBiggerOrEqualValue(PgDateTime(fromDate)),
);
2025-12-13 13:27:05 +00:00
}
if (toDate != null) {
2025-12-13 23:35:14 +00:00
query.where((s) => s.startTime.isSmallerOrEqualValue(PgDateTime(toDate)));
2025-12-13 13:27:05 +00:00
}
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
if (limit != null) {
query.limit(limit, offset: offset);
}
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
return query.get();
}
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
/// Создать сессию
2025-12-13 20:55:50 +00:00
Future<String> createSession(StudySessionsCompanion session) async {
final inserted = await into(studySessions).insertReturning(session);
return inserted.id;
2025-12-13 13:27:05 +00:00
}
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
/// Обновить сессию
Future<bool> updateSession(StudySession session) {
return update(studySessions).replace(session);
}
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
/// Завершить сессию
2025-12-20 18:26:15 +00:00
Future<void> endSession(
String sessionId, {
2025-12-13 13:27:05 +00:00
int? wordsLearned,
int? testsCompleted,
double? accuracy,
}) {
final updates = StudySessionsCompanion(
id: Value(sessionId),
2025-12-13 23:35:14 +00:00
endTime: Value(PgDateTime(DateTime.now())),
updatedAt: Value(PgDateTime(DateTime.now())),
2025-12-20 18:26:15 +00:00
wordsLearned: wordsLearned != null
? Value(wordsLearned)
: const Value.absent(),
testsCompleted: testsCompleted != null
? Value(testsCompleted)
: const Value.absent(),
2025-12-13 13:27:05 +00:00
accuracy: accuracy != null ? Value(accuracy) : const Value.absent(),
);
2025-12-20 18:26:15 +00:00
return (update(
studySessions,
)..where((s) => s.id.equals(sessionId))).write(updates);
2025-12-13 13:27:05 +00:00
}
2025-12-20 18:26:15 +00:00
2025-12-14 20:36:05 +00:00
/// Подсчитать сессии пользователя (только активные)
2025-12-13 20:55:50 +00:00
Future<int> countSessionsByUserId(String userId) async {
2025-12-13 13:27:05 +00:00
final countExpr = studySessions.id.count();
final query = selectOnly(studySessions)
..addColumns([countExpr])
2025-12-20 18:26:15 +00:00
..where(
studySessions.userId.equals(userId) &
studySessions.isDeleted.equals(false),
);
2025-12-13 13:27:05 +00:00
return await query.map((row) => row.read(countExpr)!).getSingle();
}
}