Some checks failed
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Deploy Admin Panel / Deploy Admin Panel (push) Waiting to run
Deploy Admin Panel / Admin Panel Verification (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
Mobile App CI / test (push) Has been cancelled
Web App CI / test (push) Has been cancelled
Deploy Telegram Bot / Deploy Telegram Bot (push) Has been cancelled
Mobile App CI / build-android (push) Has been cancelled
Mobile App CI / build-ios (push) Has been cancelled
Web App CI / build (push) Has been cancelled
148 lines
5 KiB
Dart
148 lines
5 KiB
Dart
import 'package:drift/drift.dart';
|
||
import 'package:drift_postgres/drift_postgres.dart';
|
||
import '../database.dart';
|
||
import '../tables/tests.dart';
|
||
|
||
part 'test_dao.g.dart';
|
||
|
||
@DriftAccessor(tables: [Tests, TestQuestions, TestPackRelations, TestStatistics])
|
||
class TestDao extends DatabaseAccessor<AppDatabase> with _$TestDaoMixin {
|
||
TestDao(super.db);
|
||
|
||
// ==================== Tests ====================
|
||
|
||
/// Получить тест по ID (только активные)
|
||
Future<Test?> getTestById(String id) {
|
||
return (select(tests)
|
||
..where((t) => t.id.equals(id) & t.isDeleted.equals(false))
|
||
).getSingleOrNull();
|
||
}
|
||
|
||
/// Получить все тесты (только активные)
|
||
Future<List<Test>> getAllTests() {
|
||
return (select(tests)
|
||
..where((t) => t.isDeleted.equals(false))
|
||
).get();
|
||
}
|
||
|
||
/// Получить тесты пака (только активные)
|
||
Future<List<Test>> getTestsByPackId(String packId) async {
|
||
final query = select(tests).join([
|
||
innerJoin(
|
||
testPackRelations,
|
||
testPackRelations.testId.equalsExp(tests.id) &
|
||
testPackRelations.packId.equals(packId),
|
||
),
|
||
])
|
||
..where(tests.isDeleted.equals(false));
|
||
|
||
return query.map((row) => row.readTable(tests)).get();
|
||
}
|
||
|
||
/// Создать тест
|
||
Future<String> createTest(TestsCompanion test) async {
|
||
final inserted = await into(tests).insertReturning(test);
|
||
return inserted.id;
|
||
}
|
||
|
||
/// Обновить тест
|
||
Future<bool> updateTest(Test test) {
|
||
return update(tests).replace(test);
|
||
}
|
||
|
||
/// Удалить тест (soft delete)
|
||
Future<void> softDeleteTest(String testId) {
|
||
return (update(tests)..where((t) => t.id.equals(testId)))
|
||
.write(TestsCompanion(
|
||
isDeleted: const Value(true),
|
||
deletedAt: Value(PgDateTime(DateTime.now())),
|
||
updatedAt: Value(PgDateTime(DateTime.now())),
|
||
));
|
||
}
|
||
|
||
/// Связать тест с паком
|
||
Future<void> linkTestToPack(String testId, String packId) async {
|
||
await into(testPackRelations).insert(
|
||
TestPackRelationsCompanion.insert(
|
||
testId: testId,
|
||
packId: packId,
|
||
),
|
||
mode: InsertMode.insertOrIgnore,
|
||
);
|
||
}
|
||
|
||
/// Удалить связь теста с паком
|
||
Future<void> unlinkTestFromPack(String testId, String packId) async {
|
||
await (delete(testPackRelations)
|
||
..where((tpr) => tpr.testId.equals(testId) & tpr.packId.equals(packId))
|
||
).go();
|
||
}
|
||
|
||
/// Получить packId для теста
|
||
Future<String?> getPackIdForTest(String testId) async {
|
||
final relation = await (select(testPackRelations)
|
||
..where((tpr) => tpr.testId.equals(testId))
|
||
..limit(1)
|
||
).getSingleOrNull();
|
||
return relation?.packId;
|
||
}
|
||
|
||
/// Получить все packId для теста
|
||
Future<List<String>> getPackIdsForTest(String testId) async {
|
||
final relations = await (select(testPackRelations)
|
||
..where((tpr) => tpr.testId.equals(testId))
|
||
).get();
|
||
return relations.map((r) => r.packId).toList();
|
||
}
|
||
|
||
// ==================== TestQuestions ====================
|
||
|
||
/// Получить вопросы теста (только активные, отсортированные по orderIndex)
|
||
Future<List<TestQuestion>> getTestQuestions(String testId) {
|
||
return (select(testQuestions)
|
||
..where((tq) => tq.testId.equals(testId) & tq.isDeleted.equals(false))
|
||
..orderBy([(tq) => OrderingTerm(expression: tq.orderIndex)])
|
||
).get();
|
||
}
|
||
|
||
/// Создать вопрос теста
|
||
Future<String> createTestQuestion(TestQuestionsCompanion question) async {
|
||
final inserted = await into(testQuestions).insertReturning(question);
|
||
return inserted.id;
|
||
}
|
||
|
||
/// Обновить вопрос теста
|
||
Future<bool> updateTestQuestion(TestQuestion question) {
|
||
return update(testQuestions).replace(question);
|
||
}
|
||
|
||
/// Удалить вопрос теста (soft delete)
|
||
Future<void> softDeleteTestQuestion(String questionId) {
|
||
return (update(testQuestions)..where((tq) => tq.id.equals(questionId)))
|
||
.write(TestQuestionsCompanion(
|
||
isDeleted: const Value(true),
|
||
deletedAt: Value(PgDateTime(DateTime.now())),
|
||
updatedAt: Value(PgDateTime(DateTime.now())),
|
||
));
|
||
}
|
||
|
||
// ==================== TestStatistics ====================
|
||
|
||
/// Получить статистику теста пользователя
|
||
Future<TestStatistic?> getTestStatistics(String userId, String testId) {
|
||
return (select(testStatistics)
|
||
..where((ts) => ts.userId.equals(userId) & ts.testId.equals(testId))
|
||
).getSingleOrNull();
|
||
}
|
||
|
||
/// Создать статистику теста
|
||
Future<String> createTestStatistics(TestStatisticsCompanion statistics) async {
|
||
final inserted = await into(testStatistics).insertReturning(statistics);
|
||
return inserted.id;
|
||
}
|
||
|
||
/// Обновить статистику теста
|
||
Future<bool> updateTestStatistics(TestStatistic statistics) {
|
||
return update(testStatistics).replace(statistics);
|
||
}
|
||
}
|