2025-05-06 13:33:37 +00:00
|
|
|
import "server-only";
|
|
|
|
|
|
|
|
import { cache } from "react";
|
|
|
|
import { logger } from "@/lib/logger";
|
|
|
|
import { unstable_cache } from "next/cache";
|
2025-04-01 03:46:07 +00:00
|
|
|
import { PrismaClient } from "@/generated/client";
|
|
|
|
|
2025-05-06 13:33:37 +00:00
|
|
|
const log = logger.child({ module: "prisma" });
|
|
|
|
|
2025-03-12 07:06:08 +00:00
|
|
|
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
|
2025-05-06 13:33:37 +00:00
|
|
|
|
2025-03-12 07:25:31 +00:00
|
|
|
const prisma = globalForPrisma.prisma || new PrismaClient();
|
2025-05-06 13:33:37 +00:00
|
|
|
|
2025-03-11 04:46:57 +00:00
|
|
|
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
2025-03-12 07:25:31 +00:00
|
|
|
|
|
|
|
export default prisma;
|
2025-05-06 13:33:37 +00:00
|
|
|
|
|
|
|
const getProblems = async () => {
|
|
|
|
const startTime = Date.now();
|
|
|
|
log.debug("Fetching all problems from database");
|
|
|
|
try {
|
|
|
|
const problems = await prisma.problem.findMany();
|
|
|
|
log.debug(
|
|
|
|
{ count: problems.length, durationMs: Date.now() - startTime },
|
|
|
|
"Fetched problems successfully"
|
|
|
|
);
|
|
|
|
return problems;
|
|
|
|
} catch (error) {
|
|
|
|
log.error(
|
|
|
|
{ durationMs: Date.now() - startTime, error },
|
|
|
|
"Failed to fetch problems"
|
|
|
|
);
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getCachedProblems = cache(
|
|
|
|
unstable_cache(
|
|
|
|
async () => {
|
|
|
|
const startTime = Date.now();
|
|
|
|
log.debug("Calling getProblemsCached (expect cache hit if warmed)");
|
|
|
|
try {
|
|
|
|
const result = await getProblems();
|
|
|
|
log.info(
|
|
|
|
{ durationMs: Date.now() - startTime },
|
|
|
|
"getProblemsCached finished"
|
|
|
|
);
|
|
|
|
return result;
|
|
|
|
} catch (error) {
|
|
|
|
log.error(
|
|
|
|
{ durationMs: Date.now() - startTime, error },
|
|
|
|
"getProblemsCached failed"
|
|
|
|
);
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
["getProblems"],
|
|
|
|
{
|
|
|
|
tags: ["problems"],
|
|
|
|
}
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2025-05-07 06:47:20 +00:00
|
|
|
const getProblem = async (problemId: string) => {
|
2025-05-06 13:33:37 +00:00
|
|
|
const startTime = Date.now();
|
2025-05-07 06:47:20 +00:00
|
|
|
log.debug({ problemId }, "Fetching single problem");
|
2025-05-06 13:33:37 +00:00
|
|
|
try {
|
2025-05-07 06:47:20 +00:00
|
|
|
const problem = await prisma.problem.findUnique({
|
|
|
|
where: { id: problemId },
|
|
|
|
});
|
2025-05-06 13:33:37 +00:00
|
|
|
if (problem) {
|
2025-05-07 06:47:20 +00:00
|
|
|
log.debug(
|
|
|
|
{ problemId, durationMs: Date.now() - startTime },
|
|
|
|
"Problem found"
|
|
|
|
);
|
2025-05-06 13:33:37 +00:00
|
|
|
} else {
|
2025-05-07 06:47:20 +00:00
|
|
|
log.warn(
|
|
|
|
{ problemId, durationMs: Date.now() - startTime },
|
|
|
|
"Problem not found"
|
|
|
|
);
|
2025-05-06 13:33:37 +00:00
|
|
|
}
|
|
|
|
return problem;
|
|
|
|
} catch (error) {
|
|
|
|
log.error(
|
2025-05-07 06:47:20 +00:00
|
|
|
{ problemId, durationMs: Date.now() - startTime, error },
|
2025-05-06 13:33:37 +00:00
|
|
|
"Failed to fetch problem"
|
|
|
|
);
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2025-05-07 06:47:20 +00:00
|
|
|
export const getCachedProblem = cache((problemId: string) =>
|
2025-05-06 13:33:37 +00:00
|
|
|
unstable_cache(
|
|
|
|
async () => {
|
|
|
|
const startTime = Date.now();
|
|
|
|
log.debug(
|
2025-05-07 06:47:20 +00:00
|
|
|
{ problemId },
|
2025-05-06 13:33:37 +00:00
|
|
|
"Calling getProblemCached (expect cache hit if warmed)"
|
|
|
|
);
|
|
|
|
try {
|
2025-05-07 06:47:20 +00:00
|
|
|
const result = await getProblem(problemId);
|
2025-05-06 13:33:37 +00:00
|
|
|
log.info(
|
2025-05-07 06:47:20 +00:00
|
|
|
{ problemId, durationMs: Date.now() - startTime },
|
2025-05-06 13:33:37 +00:00
|
|
|
"getProblemCached finished"
|
|
|
|
);
|
|
|
|
return result;
|
|
|
|
} catch (error) {
|
|
|
|
log.error(
|
2025-05-07 06:47:20 +00:00
|
|
|
{ problemId, durationMs: Date.now() - startTime, error },
|
2025-05-06 13:33:37 +00:00
|
|
|
"getProblemCached failed"
|
|
|
|
);
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
},
|
2025-05-07 06:47:20 +00:00
|
|
|
["getProblem", problemId],
|
2025-05-06 13:33:37 +00:00
|
|
|
{
|
2025-05-07 06:47:20 +00:00
|
|
|
tags: [`problem-${problemId}`],
|
2025-05-06 13:33:37 +00:00
|
|
|
}
|
|
|
|
)()
|
|
|
|
);
|