refactor(db): migrate app pages and APIs from Prisma facade to Drizzle (4)
Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
580972c0a0
commit
9aa4f331bf
40 files changed
+1259
-927
No files matched your search
@@ -1,8 +1,9 @@
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
import { apiJson } from "@/lib/api";
|
||||
import { bearerUserId } from "@/lib/api-auth";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { db, User, UsersSettings } from "@/lib/db";
|
||||
import { logger } from "@/lib/logger";
|
||||
import { Prisma, prisma } from "@/lib/prisma";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
@@ -60,21 +61,27 @@ function rankEntries(
|
||||
.map((e, i) => ({ ...e, rank: i + 1 }));
|
||||
}
|
||||
|
||||
async function rawRows<T>(query: ReturnType<typeof sql>): Promise<T[]> {
|
||||
const [rows] = (await db.execute(query)) as unknown as [T[], unknown];
|
||||
return rows;
|
||||
}
|
||||
|
||||
async function loadTotalBadgesBoard(
|
||||
userId: number | null,
|
||||
): Promise<BadgeLeaderboardBoard> {
|
||||
const rows = await prisma.$queryRaw<
|
||||
Array<{ userId: bigint; username: string; look: string; cnt: bigint }>
|
||||
>(
|
||||
Prisma.sql`
|
||||
const rows = await rawRows<{
|
||||
userId: bigint;
|
||||
username: string;
|
||||
look: string;
|
||||
cnt: bigint;
|
||||
}>(sql`
|
||||
SELECT ub.user_id AS userId, u.username, u.look, COUNT(*) AS cnt
|
||||
FROM users_badges ub
|
||||
JOIN users u ON u.id = ub.user_id
|
||||
GROUP BY ub.user_id
|
||||
ORDER BY cnt DESC
|
||||
LIMIT 20
|
||||
`,
|
||||
);
|
||||
`);
|
||||
|
||||
const entries = rankEntries(
|
||||
rows.map((r) => ({
|
||||
@@ -90,8 +97,8 @@ async function loadTotalBadgesBoard(
|
||||
entries.length > 0
|
||||
? Number(
|
||||
(
|
||||
await prisma.$queryRaw<Array<{ cnt: bigint }>>(
|
||||
Prisma.sql`SELECT COUNT(DISTINCT user_id) AS cnt FROM users_badges`,
|
||||
await rawRows<{ cnt: bigint }>(
|
||||
sql`SELECT COUNT(DISTINCT user_id) AS cnt FROM users_badges`,
|
||||
)
|
||||
)[0]?.cnt ?? 0,
|
||||
)
|
||||
@@ -99,8 +106,8 @@ async function loadTotalBadgesBoard(
|
||||
|
||||
let viewerEntry: Partial<BadgeLeaderboardEntry> | undefined;
|
||||
if (userId) {
|
||||
const viewerRow = await prisma.$queryRaw<Array<{ cnt: bigint }>>(
|
||||
Prisma.sql`SELECT COUNT(*) AS cnt FROM users_badges WHERE user_id = ${userId}`,
|
||||
const viewerRow = await rawRows<{ cnt: bigint }>(
|
||||
sql`SELECT COUNT(*) AS cnt FROM users_badges WHERE user_id = ${userId}`,
|
||||
);
|
||||
const viewerScore = Number(viewerRow[0]?.cnt ?? 0);
|
||||
if (viewerScore > 0) {
|
||||
@@ -108,20 +115,19 @@ async function loadTotalBadgesBoard(
|
||||
entries.length > 0
|
||||
? Number(
|
||||
(
|
||||
await prisma.$queryRaw<Array<{ cnt: bigint }>>(
|
||||
Prisma.sql`
|
||||
await rawRows<{ cnt: bigint }>(sql`
|
||||
SELECT COUNT(*) + 1 AS cnt
|
||||
FROM (SELECT user_id, COUNT(*) AS total FROM users_badges GROUP BY user_id) t
|
||||
WHERE t.total > ${viewerScore}
|
||||
`,
|
||||
)
|
||||
`)
|
||||
)[0]?.cnt ?? entries.length + 1,
|
||||
)
|
||||
: 1;
|
||||
const viewerUser = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { username: true, look: true },
|
||||
});
|
||||
const [viewerUser] = await db
|
||||
.select({ username: User.username, look: User.look })
|
||||
.from(User)
|
||||
.where(eq(User.id, userId))
|
||||
.limit(1);
|
||||
if (viewerUser) {
|
||||
viewerEntry = {
|
||||
userId,
|
||||
@@ -140,17 +146,18 @@ async function loadTotalBadgesBoard(
|
||||
async function loadAchievementBoard(
|
||||
userId: number | null,
|
||||
): Promise<BadgeLeaderboardBoard> {
|
||||
const rows = await prisma.$queryRaw<
|
||||
Array<{ userId: bigint; username: string; look: string; score: number }>
|
||||
>(
|
||||
Prisma.sql`
|
||||
const rows = await rawRows<{
|
||||
userId: bigint;
|
||||
username: string;
|
||||
look: string;
|
||||
score: number;
|
||||
}>(sql`
|
||||
SELECT us.user_id AS userId, u.username, u.look, us.achievement_score AS score
|
||||
FROM users_settings us
|
||||
JOIN users u ON u.id = us.user_id
|
||||
ORDER BY us.achievement_score DESC
|
||||
LIMIT 20
|
||||
`,
|
||||
);
|
||||
`);
|
||||
|
||||
const entries = rankEntries(
|
||||
rows.map((r) => ({
|
||||
@@ -166,8 +173,8 @@ async function loadAchievementBoard(
|
||||
entries.length > 0
|
||||
? Number(
|
||||
(
|
||||
await prisma.$queryRaw<Array<{ cnt: bigint }>>(
|
||||
Prisma.sql`SELECT COUNT(*) AS cnt FROM users_settings WHERE achievement_score > 0`,
|
||||
await rawRows<{ cnt: bigint }>(
|
||||
sql`SELECT COUNT(*) AS cnt FROM users_settings WHERE achievement_score > 0`,
|
||||
)
|
||||
)[0]?.cnt ?? 0,
|
||||
)
|
||||
@@ -175,23 +182,23 @@ async function loadAchievementBoard(
|
||||
|
||||
let viewerEntry: Partial<BadgeLeaderboardEntry> | undefined;
|
||||
if (userId) {
|
||||
const viewerUser = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { username: true, look: true },
|
||||
});
|
||||
const [viewerUser] = await db
|
||||
.select({ username: User.username, look: User.look })
|
||||
.from(User)
|
||||
.where(eq(User.id, userId))
|
||||
.limit(1);
|
||||
if (viewerUser) {
|
||||
const viewerSettings = await prisma.usersSettings.findUnique({
|
||||
where: { userId },
|
||||
select: { achievementScore: true },
|
||||
});
|
||||
const [viewerSettings] = await db
|
||||
.select({ achievementScore: UsersSettings.achievementScore })
|
||||
.from(UsersSettings)
|
||||
.where(eq(UsersSettings.userId, userId))
|
||||
.limit(1);
|
||||
if (viewerSettings && viewerSettings.achievementScore > 0) {
|
||||
const viewerRank = Number(
|
||||
(
|
||||
await prisma.$queryRaw<Array<{ cnt: bigint }>>(
|
||||
Prisma.sql`
|
||||
await rawRows<{ cnt: bigint }>(sql`
|
||||
SELECT COUNT(*) + 1 AS cnt FROM users_settings WHERE achievement_score > ${viewerSettings.achievementScore}
|
||||
`,
|
||||
)
|
||||
`)
|
||||
)[0]?.cnt ?? entries.length + 1,
|
||||
);
|
||||
viewerEntry = {
|
||||
@@ -215,12 +222,17 @@ async function loadRarityBoard(
|
||||
): Promise<BadgeLeaderboardBoard> {
|
||||
if (badgeCodes.length === 0) return { entries: [], totalPlayers: 0 };
|
||||
|
||||
const codes = Prisma.join(badgeCodes);
|
||||
const codes = sql.join(
|
||||
badgeCodes.map((c) => sql`${c}`),
|
||||
sql`, `,
|
||||
);
|
||||
|
||||
const rows = await prisma.$queryRaw<
|
||||
Array<{ userId: bigint; username: string; look: string; cnt: bigint }>
|
||||
>(
|
||||
Prisma.sql`
|
||||
const rows = await rawRows<{
|
||||
userId: bigint;
|
||||
username: string;
|
||||
look: string;
|
||||
cnt: bigint;
|
||||
}>(sql`
|
||||
SELECT ub.user_id AS userId, u.username, u.look, COUNT(*) AS cnt
|
||||
FROM users_badges ub
|
||||
JOIN users u ON u.id = ub.user_id
|
||||
@@ -228,8 +240,7 @@ async function loadRarityBoard(
|
||||
GROUP BY ub.user_id
|
||||
ORDER BY cnt DESC
|
||||
LIMIT 20
|
||||
`,
|
||||
);
|
||||
`);
|
||||
|
||||
const entries = rankEntries(
|
||||
rows.map((r) => ({
|
||||
@@ -245,39 +256,34 @@ async function loadRarityBoard(
|
||||
rows.length > 0
|
||||
? Number(
|
||||
(
|
||||
await prisma.$queryRaw<Array<{ cnt: bigint }>>(
|
||||
Prisma.sql`
|
||||
await rawRows<{ cnt: bigint }>(sql`
|
||||
SELECT COUNT(DISTINCT user_id) AS cnt FROM users_badges WHERE badge_code IN (${codes})
|
||||
`,
|
||||
)
|
||||
`)
|
||||
)[0]?.cnt ?? 0,
|
||||
)
|
||||
: 0;
|
||||
|
||||
let viewerEntry: Partial<BadgeLeaderboardEntry> | undefined;
|
||||
if (userId) {
|
||||
const viewerRow = await prisma.$queryRaw<Array<{ cnt: bigint }>>(
|
||||
Prisma.sql`
|
||||
const viewerRow = await rawRows<{ cnt: bigint }>(sql`
|
||||
SELECT COUNT(*) AS cnt FROM users_badges
|
||||
WHERE user_id = ${userId} AND badge_code IN (${codes})
|
||||
`,
|
||||
);
|
||||
`);
|
||||
const viewerScore = Number(viewerRow[0]?.cnt ?? 0);
|
||||
if (viewerScore > 0) {
|
||||
const viewerUser = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { username: true, look: true },
|
||||
});
|
||||
const [viewerUser] = await db
|
||||
.select({ username: User.username, look: User.look })
|
||||
.from(User)
|
||||
.where(eq(User.id, userId))
|
||||
.limit(1);
|
||||
if (viewerUser) {
|
||||
const viewerRank = Number(
|
||||
(
|
||||
await prisma.$queryRaw<Array<{ cnt: bigint }>>(
|
||||
Prisma.sql`
|
||||
await rawRows<{ cnt: bigint }>(sql`
|
||||
SELECT COUNT(*) + 1 AS cnt
|
||||
FROM (SELECT user_id, COUNT(*) AS total FROM users_badges WHERE badge_code IN (${codes}) GROUP BY user_id) t
|
||||
WHERE t.total > ${viewerScore}
|
||||
`,
|
||||
)
|
||||
`)
|
||||
)[0]?.cnt ?? entries.length + 1,
|
||||
);
|
||||
viewerEntry = {
|
||||
@@ -302,15 +308,14 @@ export async function GET(req: Request) {
|
||||
userId = session?.user?.id ? Number(session.user.id) : null;
|
||||
}
|
||||
|
||||
const badgeStatsRaw = await prisma.$queryRaw<
|
||||
Array<{ badgeCode: string; ownerCount: bigint }>
|
||||
>(
|
||||
Prisma.sql`
|
||||
const badgeStatsRaw = await rawRows<{
|
||||
badgeCode: string;
|
||||
ownerCount: bigint;
|
||||
}>(sql`
|
||||
SELECT badge_code AS badgeCode, COUNT(DISTINCT user_id) AS ownerCount
|
||||
FROM users_badges
|
||||
GROUP BY badge_code
|
||||
`,
|
||||
);
|
||||
`);
|
||||
|
||||
const badgeStats: BadgeLeaderboardStat[] = badgeStatsRaw.map((r) => ({
|
||||
badgeCode: r.badgeCode,
|
||||
|
||||
Reference in new issue
Block a user