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