Module Update
This commit is contained in:
93
src/modules/questions/data-access.ts
Normal file
93
src/modules/questions/data-access.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import 'server-only';
|
||||
|
||||
import { db } from "@/shared/db";
|
||||
import { questions, questionsToKnowledgePoints } from "@/shared/db/schema";
|
||||
import { and, eq, inArray, count, desc, sql } from "drizzle-orm";
|
||||
import { cache } from "react";
|
||||
|
||||
// Types for filters
|
||||
export type GetQuestionsParams = {
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
knowledgePointId?: string;
|
||||
difficulty?: number;
|
||||
};
|
||||
|
||||
// Cached Data Access Function
|
||||
// Using React's cache() to deduplicate requests if called multiple times in one render pass
|
||||
export const getQuestions = cache(async ({
|
||||
page = 1,
|
||||
pageSize = 10,
|
||||
knowledgePointId,
|
||||
difficulty,
|
||||
}: GetQuestionsParams = {}) => {
|
||||
const offset = (page - 1) * pageSize;
|
||||
|
||||
// Build Where Conditions
|
||||
const conditions = [];
|
||||
|
||||
if (difficulty) {
|
||||
conditions.push(eq(questions.difficulty, difficulty));
|
||||
}
|
||||
|
||||
// Filter by Knowledge Point (using subquery pattern for Many-to-Many)
|
||||
if (knowledgePointId) {
|
||||
const subQuery = db
|
||||
.select({ questionId: questionsToKnowledgePoints.questionId })
|
||||
.from(questionsToKnowledgePoints)
|
||||
.where(eq(questionsToKnowledgePoints.knowledgePointId, knowledgePointId));
|
||||
|
||||
conditions.push(inArray(questions.id, subQuery));
|
||||
}
|
||||
|
||||
// Only fetch top-level questions (parent questions)
|
||||
// Assuming we only want to list "root" questions, not sub-questions
|
||||
conditions.push(sql`${questions.parentId} IS NULL`);
|
||||
|
||||
const whereClause = conditions.length > 0 ? and(...conditions) : undefined;
|
||||
|
||||
// 1. Get Total Count (for Pagination)
|
||||
// Optimization: separate count query is often faster than fetching all data
|
||||
const [totalResult] = await db
|
||||
.select({ count: count() })
|
||||
.from(questions)
|
||||
.where(whereClause);
|
||||
|
||||
const total = totalResult?.count ?? 0;
|
||||
|
||||
// 2. Get Data with Relations
|
||||
const data = await db.query.questions.findMany({
|
||||
where: whereClause,
|
||||
limit: pageSize,
|
||||
offset: offset,
|
||||
orderBy: [desc(questions.createdAt)],
|
||||
with: {
|
||||
// Preload Knowledge Points
|
||||
questionsToKnowledgePoints: {
|
||||
with: {
|
||||
knowledgePoint: true,
|
||||
},
|
||||
},
|
||||
// Preload Author
|
||||
author: {
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
image: true,
|
||||
},
|
||||
},
|
||||
// Preload Child Questions (first level)
|
||||
children: true,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
data,
|
||||
meta: {
|
||||
page,
|
||||
pageSize,
|
||||
total,
|
||||
totalPages: Math.ceil(total / pageSize),
|
||||
},
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user