fixed build performance issues; optimized queries

This commit is contained in:
2025-03-15 20:31:38 +01:00
parent cff9dad54c
commit 324451e082
27 changed files with 289 additions and 208 deletions
+4
View File
@@ -1,8 +1,12 @@
"use server";
import fs from "node:fs/promises";
import { revalidatePath } from "next/cache";
import { auth } from "../auth";
import { hasPermission, Role } from "@/lib/validation/permissions";
export async function uploadFile(formData: FormData) {
const session = await auth();
if (!session || hasPermission(session.user.role, Role.EDITOR)) return false;
const file = formData.get("file") as File;
const arrayBuffer = await file.arrayBuffer();
const buffer = new Uint8Array(arrayBuffer);
-23
View File
@@ -1,29 +1,6 @@
import { z } from "zod";
import { createTRPCRouter, publicProcedure } from "../trpc";
import { desc, ilike, like } from "drizzle-orm";
import {
articles as articlesTable,
categories as categoriesTable,
lower,
} from "@/server/db/schema";
export const appRouter = createTRPCRouter({
searchContent: publicProcedure
.input(
z.object({
query: z.string().optional(),
}),
)
.query(async ({ ctx, input }) => {
const articles = await ctx.db.query.articles.findMany({
where: ilike(articlesTable.title, "%" + input.query + "%"),
});
const categories = await ctx.db.query.categories.findMany({
where: like(categoriesTable.name, "%" + input.query + "%"),
});
return { articles, categories };
}),
getSidebarMain: publicProcedure.query(async ({ ctx }) => {
const categories = await ctx.db.query.categories.findMany({
limit: 3,
+5 -5
View File
@@ -71,10 +71,10 @@ export const articleRouter = createTRPCRouter({
get: publicProcedure
.input(z.object({ slug: z.string() }))
.query(async ({ ctx, input }) => {
return await ctx.db.query.articles.findFirst({
return (await ctx.db.query.articles.findFirst({
where: eq(articles.slug, input.slug),
with: { category: true },
});
})) as Article;
}),
getByCursor: publicProcedure
.input(
@@ -131,7 +131,6 @@ export const articleRouter = createTRPCRouter({
let nextCursor: string | undefined = undefined;
if (items.length > limit) {
console.log("Configure next cursor");
const cursorItem = items.pop();
// Create a cursor object with the relevant fields for sorting
const cursorData: ArticleCursor = {
@@ -150,7 +149,7 @@ export const articleRouter = createTRPCRouter({
nextCursor,
};
}),
getAll: publicProcedure
getMany: publicProcedure
.input(
z
.object({
@@ -160,11 +159,12 @@ export const articleRouter = createTRPCRouter({
.optional(),
)
.query(async ({ ctx, input }) => {
const limit = input?.limit ?? 50;
return (await ctx.db.query.articles.findMany({
where: input?.categoryId
? eq(articles.categoryId, input.categoryId)
: undefined,
limit: input?.limit,
limit: limit,
columns: {
title: true,
slug: true,
+1 -1
View File
@@ -1,4 +1,4 @@
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
import { createTRPCRouter, publicProcedure } from "../trpc";
export const authorRouter = createTRPCRouter({
getCount: publicProcedure.query(async ({ ctx }) => {
+17 -13
View File
@@ -12,11 +12,11 @@ import {
count,
desc,
eq,
gt,
gte,
ilike,
like,
lte,
sql,
} from "drizzle-orm";
import { hasPermission, Role } from "@/lib/validation/permissions";
import {
@@ -60,13 +60,6 @@ const getCategorySorting = (sort: string, cursor?: CategoryCursor) => {
};
export const categoryRouter = createTRPCRouter({
search: publicProcedure
.input(z.object({ query: z.string() }))
.query(async ({ ctx, input }) => {
return await ctx.db.query.categories.findMany({
where: like(categories.name, "%" + input.query + "%"),
});
}),
get: publicProcedure
.input(z.object({ slug: z.string(), with: z.any() }))
.query(async ({ ctx, input }) => {
@@ -76,7 +69,7 @@ export const categoryRouter = createTRPCRouter({
})) as Category;
}),
getAll: publicProcedure
getMany: publicProcedure
.input(
z
.object({
@@ -85,9 +78,15 @@ export const categoryRouter = createTRPCRouter({
.optional(),
)
.query(async ({ ctx, input }) => {
return await ctx.db.query.categories.findMany({
limit: input?.limit,
});
const limit = input?.limit ?? 50;
return (await ctx.db.query.categories.findMany({
limit: limit,
columns: {
name: true,
slug: true,
createdAt: true,
},
})) as Category[];
}),
getByCursor: publicProcedure
@@ -135,7 +134,6 @@ export const categoryRouter = createTRPCRouter({
let nextCursor: string | undefined = undefined;
if (items.length > limit) {
console.log("Configure next cursor");
const cursorItem = items.pop();
// Create a cursor object with the relevant fields for sorting
const cursorData: CategoryCursor = {
@@ -172,6 +170,12 @@ export const categoryRouter = createTRPCRouter({
.values({ ...input.category, slug })
.returning({
slug: categories.slug,
})
.onConflictDoUpdate({
target: categories.slug,
set: {
slug: sql`${slug} || '-' || (SELECT COUNT(*) FROM ${categories} WHERE slug LIKE ${slug + "-%"})`,
},
});
}),
update: protectedProcedure
+7 -1
View File
@@ -13,7 +13,7 @@ export const usersRouter = createTRPCRouter({
.update(users)
.set(input.profile)
.where(eq(users.id, ctx.session.user.id))
.returning();
.returning({ id: users.id });
}),
getAll: protectedProcedure.query(async ({ ctx }) => {
@@ -21,6 +21,12 @@ export const usersRouter = createTRPCRouter({
if (!isAdmin) throw new Error("You are not allowed to get all users");
return await ctx.db.query.users.findMany({
orderBy: desc(users.role),
columns: {
name: true,
email: true,
role: true,
id: true,
},
});
}),
+3 -1
View File
@@ -15,6 +15,8 @@ const globalForDb = globalThis as unknown as {
const conn = globalForDb.conn ?? postgres(env.DATABASE_URL);
if (env.NODE_ENV !== "production") globalForDb.conn = conn;
export const db = drizzle(conn, { schema });
export const db = drizzle(conn, {
schema,
});
export type DBType = typeof db;
+7 -8
View File
@@ -1,7 +1,6 @@
import { createId } from "@paralleldrive/cuid2";
import { relations, SQL, sql } from "drizzle-orm";
import { relations, sql } from "drizzle-orm";
import {
AnyPgColumn,
boolean,
index,
integer,
@@ -16,10 +15,6 @@ import { User } from "next-auth";
import { type AdapterAccount } from "next-auth/adapters";
import { JSONContent } from "novel";
export function lower(value: AnyPgColumn): SQL {
return sql`lower(${value})`;
}
export const createTable = pgTableCreator((name) => `wiki-antifa_${name}`);
export const articles = createTable(
@@ -43,7 +38,9 @@ export const articles = createTable(
),
},
(example) => ({
articleTitleIndex: index("article_title_idx").on(example.title),
titleIndex: index("article_title_idx").on(example.title),
slugIndex: index("article_slug_idx").on(example.slug),
createdAtIndex: index("article_created_at_idx").on(example.createdAt),
}),
);
export type Article = typeof articles.$inferSelect & {
@@ -81,7 +78,9 @@ export const categories = createTable(
),
},
(example) => ({
categoryNameIndex: index("category_name_idx").on(example.name),
nameIndex: index("category_name_idx").on(example.name),
slugameIndex: index("category_slug_idx").on(example.slug),
createdAtIndex: index("category_created_at_idx").on(example.createdAt),
}),
);
export type Category = typeof categories.$inferSelect & {