From 1eb8e028624ad111d737f1ff3192b6b2a445c632 Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 6 Jun 2025 07:34:36 +0200 Subject: [PATCH 1/6] Better Names for Schema --- src/app/drive-contents.tsx | 8 ++++---- src/app/f/[folderId]/page.tsx | 4 ++-- src/app/file-row.tsx | 8 +++++--- src/server/db/schema.ts | 4 ++-- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/app/drive-contents.tsx b/src/app/drive-contents.tsx index c1fa4da..86ebc54 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 { files_table, folders_table } 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: (typeof files_table.$inferSelect)[]; + folders: (typeof folders_table.$inferSelect)[]; + parents: (typeof folders_table.$inferSelect)[]; }) { 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..d37ebc3 100644 --- a/src/app/f/[folderId]/page.tsx +++ b/src/app/f/[folderId]/page.tsx @@ -3,8 +3,8 @@ import { z } from "zod"; import { db } from "~/server/db"; import { - files as fileSchema, - folders as folderSchema, + files_table as fileSchema, + folders_table as folderSchema, } from "~/server/db/schema"; import DriveContents from "../../drive-contents"; diff --git a/src/app/file-row.tsx b/src/app/file-row.tsx index 5138410..8b7411b 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 { files_table, folders_table } from "~/server/db/schema"; -export function FileRow(props: { file: typeof files.$inferSelect }) { +export function FileRow(props: { file: typeof files_table.$inferSelect }) { const { file } = props; return ( @@ -29,7 +29,9 @@ export function FileRow(props: { file: typeof files.$inferSelect }) { ); } -export function FolderRow(props: { folder: typeof folders.$inferSelect }) { +export function FolderRow(props: { + folder: typeof folders_table.$inferSelect; +}) { const { folder } = props; return ( diff --git a/src/server/db/schema.ts b/src/server/db/schema.ts index 30b873a..d9d518c 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 }) From b24686259f558fb77aefa13da6a58c2d430075aa Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 6 Jun 2025 07:39:33 +0200 Subject: [PATCH 2/6] Using Database Schema Types --- src/app/drive-contents.tsx | 8 ++++---- src/app/file-row.tsx | 8 +++----- src/server/db/schema.ts | 3 +++ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/app/drive-contents.tsx b/src/app/drive-contents.tsx index 86ebc54..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_table, folders_table } 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_table.$inferSelect)[]; - folders: (typeof folders_table.$inferSelect)[]; - parents: (typeof folders_table.$inferSelect)[]; + files: File[]; + folders: Folder[]; + parents: Folder[]; }) { const handleUpload = () => { alert("Upload functionality would be implemented here"); diff --git a/src/app/file-row.tsx b/src/app/file-row.tsx index 8b7411b..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_table, folders_table } from "~/server/db/schema"; +import type { File, Folder } from "~/server/db/schema"; -export function FileRow(props: { file: typeof files_table.$inferSelect }) { +export function FileRow(props: { file: File }) { const { file } = props; return ( @@ -29,9 +29,7 @@ export function FileRow(props: { file: typeof files_table.$inferSelect }) { ); } -export function FolderRow(props: { - folder: typeof folders_table.$inferSelect; -}) { +export function FolderRow(props: { folder: Folder }) { const { folder } = props; return ( diff --git a/src/server/db/schema.ts b/src/server/db/schema.ts index d9d518c..9a67b4e 100644 --- a/src/server/db/schema.ts +++ b/src/server/db/schema.ts @@ -33,3 +33,6 @@ export const folders_table = createTable( }, (table) => [index("parent_index").on(table.parent)], ); + +export type File = typeof files_table.$inferSelect; +export type Folder = typeof folders_table.$inferSelect; From 939bfce43e336c7a3ed7fd9486947919231482bb Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 6 Jun 2025 07:58:39 +0200 Subject: [PATCH 3/6] Cleanup Data Access Pattern --- src/app/f/[folderId]/page.tsx | 43 ++++++----------------------------- src/server/db/queries.ts | 36 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 36 deletions(-) create mode 100644 src/server/db/queries.ts diff --git a/src/app/f/[folderId]/page.tsx b/src/app/f/[folderId]/page.tsx index d37ebc3..efd268c 100644 --- a/src/app/f/[folderId]/page.tsx +++ b/src/app/f/[folderId]/page.tsx @@ -1,32 +1,13 @@ -import { eq } from "drizzle-orm"; import { z } from "zod"; -import { db } from "~/server/db"; import { - files_table as fileSchema, - folders_table as folderSchema, -} from "~/server/db/schema"; + getAllFiles, + getAllFolders, + getAllParentsForFolder, +} 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 }>; }) { @@ -38,21 +19,11 @@ 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, + getAllFolders(folderId), + getAllFiles(folderId), + getAllParentsForFolder(folderId), ]); return ; diff --git a/src/server/db/queries.ts b/src/server/db/queries.ts new file mode 100644 index 0000000..e2fd462 --- /dev/null +++ b/src/server/db/queries.ts @@ -0,0 +1,36 @@ +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)); +} From bdf70478b38e0157d8ee18b53aa5198a5fd04dea Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 6 Jun 2025 08:15:59 +0200 Subject: [PATCH 4/6] Making Things very Clear! --- src/app/f/[folderId]/page.tsx | 12 ++++-------- src/server/db/queries.ts | 2 ++ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/app/f/[folderId]/page.tsx b/src/app/f/[folderId]/page.tsx index efd268c..ac04e65 100644 --- a/src/app/f/[folderId]/page.tsx +++ b/src/app/f/[folderId]/page.tsx @@ -1,10 +1,6 @@ import { z } from "zod"; -import { - getAllFiles, - getAllFolders, - getAllParentsForFolder, -} from "~/server/db/queries"; +import * as queries from "~/server/db/queries"; import DriveContents from "../../drive-contents"; @@ -21,9 +17,9 @@ export default async function GoogleDriveClone(props: { const folderId = data.folderId; const [folders, files, parents] = await Promise.all([ - getAllFolders(folderId), - getAllFiles(folderId), - getAllParentsForFolder(folderId), + queries.getAllFolders(folderId), + queries.getAllFiles(folderId), + queries.getAllParentsForFolder(folderId), ]); return ; diff --git a/src/server/db/queries.ts b/src/server/db/queries.ts index e2fd462..4ba47f7 100644 --- a/src/server/db/queries.ts +++ b/src/server/db/queries.ts @@ -1,3 +1,5 @@ +import "server-only"; // Ensure this file is only run on the server + import { eq } from "drizzle-orm"; import { db } from "~/server/db"; From 1957cfeb824322b19222a63ba929defd5f495587 Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 6 Jun 2025 08:22:52 +0200 Subject: [PATCH 5/6] Checking Things Off!! --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From ad47e2ac5a122f65446ce5229898c0c40685c42f Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 6 Jun 2025 08:28:09 +0200 Subject: [PATCH 6/6] Small Code Cleanup --- src/app/f/[folderId]/page.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/app/f/[folderId]/page.tsx b/src/app/f/[folderId]/page.tsx index ac04e65..5c1a3b6 100644 --- a/src/app/f/[folderId]/page.tsx +++ b/src/app/f/[folderId]/page.tsx @@ -14,12 +14,10 @@ export default async function GoogleDriveClone(props: { if (!success) return
Invalid Folder ID
; - const folderId = data.folderId; - const [folders, files, parents] = await Promise.all([ - queries.getAllFolders(folderId), - queries.getAllFiles(folderId), - queries.getAllParentsForFolder(folderId), + queries.getAllFolders(data.folderId), + queries.getAllFiles(data.folderId), + queries.getAllParentsForFolder(data.folderId), ]); return ;