fixed build performance issues; optimized queries
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
|
||||
import { createTRPCRouter, publicProcedure } from "../trpc";
|
||||
|
||||
export const authorRouter = createTRPCRouter({
|
||||
getCount: publicProcedure.query(async ({ ctx }) => {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
});
|
||||
}),
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 & {
|
||||
|
||||
Reference in New Issue
Block a user