diff --git a/README.md b/README.md index 54649a9..bac628b 100644 --- a/README.md +++ b/README.md @@ -104,5 +104,5 @@ Just finished up the database connection, next steps: The database and UI are now connected, some improvements to make: - [x] Change folders to link components, remove all client state -- [ ] Clean up the database and data fetching patterns +- [x] Clean up the database and data fetching patterns - [ ] Real homepage diff --git a/src/app/drive-contents.tsx b/src/app/drive-contents.tsx index c1fa4da..8e66859 100644 --- a/src/app/drive-contents.tsx +++ b/src/app/drive-contents.tsx @@ -4,14 +4,14 @@ import { ChevronRight, Upload } from "lucide-react"; import Link from "next/link"; import { Button } from "~/components/ui/button"; -import type { files, folders } from "~/server/db/schema"; +import type { File, Folder } from "~/server/db/schema"; import { FileRow, FolderRow } from "./file-row"; export default function DriveContents(props: { - files: (typeof files.$inferSelect)[]; - folders: (typeof folders.$inferSelect)[]; - parents: (typeof folders.$inferSelect)[]; + files: File[]; + folders: Folder[]; + parents: Folder[]; }) { const handleUpload = () => { alert("Upload functionality would be implemented here"); diff --git a/src/app/f/[folderId]/page.tsx b/src/app/f/[folderId]/page.tsx index 58d88f6..5c1a3b6 100644 --- a/src/app/f/[folderId]/page.tsx +++ b/src/app/f/[folderId]/page.tsx @@ -1,32 +1,9 @@ -import { eq } from "drizzle-orm"; import { z } from "zod"; -import { db } from "~/server/db"; -import { - files as fileSchema, - folders as folderSchema, -} from "~/server/db/schema"; +import * as queries from "~/server/db/queries"; import DriveContents from "../../drive-contents"; -async function getAllParents(folderId: number) { - const parents = []; - let currentId: number | null = folderId; - while (currentId != null) { - const folders = await db - .selectDistinct() - .from(folderSchema) - .where(eq(folderSchema.id, currentId)); - - if (!folders[0]) throw new Error("parent folder not found"); - - parents.unshift(folders[0]); - currentId = folders[0]?.parent; // parent can be null - } - - return parents; -} - export default async function GoogleDriveClone(props: { params: Promise<{ folderId: number }>; }) { @@ -37,22 +14,10 @@ export default async function GoogleDriveClone(props: { if (!success) return
Invalid Folder ID
; - const folderId = data.folderId; - const parentsPromise = getAllParents(folderId); - - const foldersPromise = db - .select() - .from(folderSchema) - .where(eq(folderSchema.parent, folderId)); - const filesPromise = db - .select() - .from(fileSchema) - .where(eq(fileSchema.parent, folderId)); - const [folders, files, parents] = await Promise.all([ - foldersPromise, - filesPromise, - parentsPromise, + queries.getAllFolders(data.folderId), + queries.getAllFiles(data.folderId), + queries.getAllParentsForFolder(data.folderId), ]); return ; diff --git a/src/app/file-row.tsx b/src/app/file-row.tsx index 5138410..b2802c0 100644 --- a/src/app/file-row.tsx +++ b/src/app/file-row.tsx @@ -1,9 +1,9 @@ import { FileIcon, Folder as FolderIcon } from "lucide-react"; import Link from "next/link"; -import type { files, folders } from "~/server/db/schema"; +import type { File, Folder } from "~/server/db/schema"; -export function FileRow(props: { file: typeof files.$inferSelect }) { +export function FileRow(props: { file: File }) { const { file } = props; return ( @@ -29,7 +29,7 @@ export function FileRow(props: { file: typeof files.$inferSelect }) { ); } -export function FolderRow(props: { folder: typeof folders.$inferSelect }) { +export function FolderRow(props: { folder: Folder }) { const { folder } = props; return ( diff --git a/src/server/db/queries.ts b/src/server/db/queries.ts new file mode 100644 index 0000000..4ba47f7 --- /dev/null +++ b/src/server/db/queries.ts @@ -0,0 +1,38 @@ +import "server-only"; // Ensure this file is only run on the server + +import { eq } from "drizzle-orm"; + +import { db } from "~/server/db"; +import { + files_table as fileSchema, + folders_table as folderSchema, +} from "~/server/db/schema"; + +export async function getAllParentsForFolder(folderId: number) { + const parents = []; + let currentId: number | null = folderId; + while (currentId != null) { + const folders = await db + .selectDistinct() + .from(folderSchema) + .where(eq(folderSchema.id, currentId)); + + if (!folders[0]) throw new Error("parent folder not found"); + + parents.unshift(folders[0]); + currentId = folders[0]?.parent; // parent can be null + } + + return parents; +} + +export function getAllFolders(folderId: number) { + return db + .select() + .from(folderSchema) + .where(eq(folderSchema.parent, folderId)); +} + +export function getAllFiles(folderId: number) { + return db.select().from(fileSchema).where(eq(fileSchema.parent, folderId)); +} diff --git a/src/server/db/schema.ts b/src/server/db/schema.ts index 30b873a..9a67b4e 100644 --- a/src/server/db/schema.ts +++ b/src/server/db/schema.ts @@ -8,7 +8,7 @@ import { const createTable = singlestoreTableCreator((name) => `drive_tutorial_${name}`); -export const files = createTable( +export const files_table = createTable( "files", { id: bigint("id", { mode: "number", unsigned: true }) @@ -22,7 +22,7 @@ export const files = createTable( (table) => [index("parent_index").on(table.parent)], ); -export const folders = createTable( +export const folders_table = createTable( "folders", { id: bigint("id", { mode: "number", unsigned: true }) @@ -33,3 +33,6 @@ export const folders = createTable( }, (table) => [index("parent_index").on(table.parent)], ); + +export type File = typeof files_table.$inferSelect; +export type Folder = typeof folders_table.$inferSelect;