mnemo_cards/mnemo_cards_backend/lib/database/daos/statistics_dao.dart
Dmitry 08143b9e30
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
fixes
2026-01-07 00:11:44 +03:00

118 lines
3.7 KiB
Dart

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<AppDatabase>
with _$StatisticsDaoMixin, SoftDeleteMixin<StudySessions, StudySession> {
StatisticsDao(super.db);
@override
TableInfo<StudySessions, StudySession> get table => studySessions;
/// Получить сессию по ID (только активные)
Future<StudySession?> getSessionById(String id) {
return getActiveById(id);
}
/// Получить сессию по sessionId (только активные)
Future<StudySession?> 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<List<StudySession>> getActiveSessions(String userId) {
return (selectActive()
..where((s) => s.userId.equals(userId))
..where((s) => s.endTime.isNull())
..orderBy([(s) => OrderingTerm.desc(s.startTime)]))
.get();
}
/// Получить сессии пользователя (только активные)
Future<List<StudySession>> 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<String> createSession(StudySessionsCompanion session) async {
final inserted = await into(studySessions).insertReturning(session);
return inserted.id;
}
/// Обновить сессию
Future<bool> updateSession(StudySession session) {
return update(studySessions).replace(session);
}
/// Завершить сессию
Future<void> 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<int> 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();
}
}