Skip to content

Commit

Permalink
Migrate to Drizzle ORM (#404)
Browse files Browse the repository at this point in the history
  • Loading branch information
realmikesolo authored Jun 8, 2024
1 parent 29e20e7 commit 7e33556
Show file tree
Hide file tree
Showing 45 changed files with 3,616 additions and 2,228 deletions.
3 changes: 1 addition & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ NEXTAUTH_URL=http://app.localhost:3000
NEXT_PUBLIC_ROOT_DOMAIN=vercel.pub

# PostgreSQL database URL – get one here: https://vercel.com/docs/storage/vercel-postgres/quickstart
POSTGRES_PRISMA_URL=
POSTGRES_URL_NON_POOLING=
POSTGRES_URL=

# Vercel Blob Storage for image uploads – currently in beta, please fill out this form for access: https://tally.so/r/nPDMNd. Setup instructions: https://vercel.com/docs/storage/vercel-blob/quickstart
BLOB_READ_WRITE_TOKEN=
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ This working demo site was built using the Platforms Starter Kit and:

- [Next.js](https://nextjs.org/) as the React framework
- [Tailwind](https://tailwindcss.com/) for CSS styling
- [Prisma](https://prisma.io/) as the ORM for database access
- [Drizzle](https://orm.drizzle.team/) as the ORM for database access
- [Novel](https://novel.sh/) for the WYSIWYG editor
- [Vercel Postgres](https://vercel.com/storage/postgres) for the database
- [Vercel Blob](https://vercel.com/storage/blob) for image uploads
Expand Down
36 changes: 16 additions & 20 deletions app/[domain]/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { notFound } from "next/navigation";
import prisma from "@/lib/prisma";
import { getPostData, getSiteData } from "@/lib/fetchers";
import BlogCard from "@/components/blog-card";
import BlurImage from "@/components/blur-image";
import MDX from "@/components/mdx";
import { placeholderBlurhash, toDateString } from "@/lib/utils";
import db from "@/lib/db";
import { posts, sites } from "@/lib/schema";
import { eq } from "drizzle-orm";

export async function generateMetadata({
params,
Expand Down Expand Up @@ -47,23 +49,17 @@ export async function generateMetadata({
}

export async function generateStaticParams() {
const allPosts = await prisma.post.findMany({
select: {
slug: true,
const allPosts = await db
.select({
slug: posts.slug,
site: {
select: {
subdomain: true,
customDomain: true,
},
subdomain: sites.subdomain,
customDomain: sites.customDomain,
},
},
// feel free to remove this filter if you want to generate paths for all posts
where: {
site: {
subdomain: "demo",
},
},
});
})
.from(posts)
.leftJoin(sites, eq(posts.siteId, sites.id))
.where(eq(sites.subdomain, "demo")); // feel free to remove this filter if you want to generate paths for all posts

const allPaths = allPosts
.flatMap(({ site, slug }) => [
Expand Down Expand Up @@ -98,13 +94,13 @@ export default async function SitePostPage({
<>
<div className="flex flex-col items-center justify-center">
<div className="m-auto w-full text-center md:w-7/12">
<p className="m-auto my-5 w-10/12 text-sm font-light text-stone-500 dark:text-stone-400 md:text-base">
<p className="m-auto my-5 w-10/12 text-sm font-light text-stone-500 md:text-base dark:text-stone-400">
{toDateString(data.createdAt)}
</p>
<h1 className="mb-10 font-title text-3xl font-bold text-stone-800 dark:text-white md:text-6xl">
<h1 className="mb-10 font-title text-3xl font-bold text-stone-800 md:text-6xl dark:text-white">
{data.title}
</h1>
<p className="text-md m-auto w-10/12 text-stone-600 dark:text-stone-400 md:text-lg">
<p className="text-md m-auto w-10/12 text-stone-600 md:text-lg dark:text-stone-400">
{data.description}
</p>
</div>
Expand Down Expand Up @@ -133,7 +129,7 @@ export default async function SitePostPage({
</div>
)}
</div>
<div className="text-md ml-3 inline-block align-middle dark:text-white md:text-lg">
<div className="text-md ml-3 inline-block align-middle md:text-lg dark:text-white">
by <span className="font-semibold">{data.site?.user?.name}</span>
</div>
</div>
Expand Down
22 changes: 10 additions & 12 deletions app/[domain]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import Link from "next/link";
import prisma from "@/lib/prisma";
import { notFound } from "next/navigation";
import BlurImage from "@/components/blur-image";
import { placeholderBlurhash, toDateString } from "@/lib/utils";
import BlogCard from "@/components/blog-card";
import { getPostsForSite, getSiteData } from "@/lib/fetchers";
import Image from "next/image";
import db from "@/lib/db";

export async function generateStaticParams() {
const allSites = await prisma.site.findMany({
select: {
const allSites = await db.query.sites.findMany({
// feel free to remove this filter if you want to generate paths for all sites
where: (sites, { eq }) => eq(sites.subdomain, "demo"),
columns: {
subdomain: true,
customDomain: true,
},
// feel free to remove this filter if you want to generate paths for all sites
where: {
subdomain: "demo",
},
});

const allPaths = allSites
Expand Down Expand Up @@ -66,10 +64,10 @@ export default async function SiteHomePage({
/>
</div>
<div className="mx-auto mt-10 w-5/6 lg:w-full">
<h2 className="my-10 font-title text-4xl dark:text-white md:text-6xl">
<h2 className="my-10 font-title text-4xl md:text-6xl dark:text-white">
{posts[0].title}
</h2>
<p className="w-full text-base dark:text-white md:text-lg lg:w-2/3">
<p className="w-full text-base md:text-lg lg:w-2/3 dark:text-white">
{posts[0].description}
</p>
<div className="flex w-full items-center justify-start space-x-4">
Expand All @@ -88,11 +86,11 @@ export default async function SiteHomePage({
</div>
)}
</div>
<p className="ml-3 inline-block whitespace-nowrap align-middle text-sm font-semibold dark:text-white md:text-base">
<p className="ml-3 inline-block whitespace-nowrap align-middle text-sm font-semibold md:text-base dark:text-white">
{data.user?.name}
</p>
<div className="h-6 border-l border-stone-600 dark:border-stone-400" />
<p className="m-auto my-5 w-10/12 text-sm font-light text-stone-500 dark:text-stone-400 md:text-base">
<p className="m-auto my-5 w-10/12 text-sm font-light text-stone-500 md:text-base dark:text-stone-400">
{toDateString(posts[0].createdAt)}
</p>
</div>
Expand Down Expand Up @@ -124,7 +122,7 @@ export default async function SiteHomePage({

{posts.length > 1 && (
<div className="mx-5 mb-20 max-w-screen-xl lg:mx-24 2xl:mx-auto">
<h2 className="mb-10 font-title text-4xl dark:text-white md:text-5xl">
<h2 className="mb-10 font-title text-4xl md:text-5xl dark:text-white">
More stories
</h2>
<div className="grid w-full grid-cols-1 gap-x-4 gap-y-8 md:grid-cols-2 xl:grid-cols-3">
Expand Down
60 changes: 23 additions & 37 deletions app/api/migrate/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,36 @@
*/

import { NextResponse } from "next/server";
// import prisma from "@/lib/prisma";
// import db from "@/lib/db/db";

export async function GET() {
// Download data from old database
// const users = await prisma.user.findMany();
// const accounts = await prisma.account.findMany();
// const sites = await prisma.site.findMany();
// const posts = await prisma.post.findMany();
// const examples = await prisma.example.findMany();
// Download data from old database
// const usersResult = await db.query.users.findMany();
// const accountsResult = await db.query.accounts.findMany();
// const sitesResult = await db.query.sites.findMany();
// const postsResult = await db.query.posts.findMany();;
// const examplesResult = await db.query.examples.findMany();;

// fs.writeFileSync("users.json", JSON.stringify(users));
// fs.writeFileSync("accounts.json", JSON.stringify(accounts));
// fs.writeFileSync("sites.json", JSON.stringify(sites));
// fs.writeFileSync("posts.json", JSON.stringify(posts));
// fs.writeFileSync("examples.json", JSON.stringify(examples));
// fs.writeFileSync("users.json", JSON.stringify(usersResult));
// fs.writeFileSync("accounts.json", JSON.stringify(accountsResult));
// fs.writeFileSync("sites.json", JSON.stringify(sitesResult));
// fs.writeFileSync("posts.json", JSON.stringify(postsResult));
// fs.writeFileSync("examples.json", JSON.stringify(examplesResult));

// Upload data to new database
// const users = JSON.parse(fs.readFileSync("users.json", "utf8"));
// const accounts = JSON.parse(fs.readFileSync("accounts.json", "utf8"));
// const sites = JSON.parse(fs.readFileSync("sites.json", "utf8"));
// const posts = JSON.parse(fs.readFileSync("posts.json", "utf8"));
// const examples = JSON.parse(fs.readFileSync("examples.json", "utf8"));
// const parsedUsers = JSON.parse(fs.readFileSync("users.json", "utf8"));
// const parsedAccounts = JSON.parse(fs.readFileSync("accounts.json", "utf8"));
// const parsedSites = JSON.parse(fs.readFileSync("sites.json", "utf8"));
// const parsedPosts = JSON.parse(fs.readFileSync("posts.json", "utf8"));
// const parsedExamples = JSON.parse(fs.readFileSync("examples.json", "utf8"));

// const response = await Promise.all([
// prisma.user.createMany({
// data: users,
// skipDuplicates: true,
// }),
// prisma.account.createMany({
// data: accounts,
// skipDuplicates: true,
// }),
// prisma.site.createMany({
// data: sites,
// skipDuplicates: true,
// }),
// prisma.post.createMany({
// data: posts,
// skipDuplicates: true,
// }),
// prisma.example.createMany({
// data: examples,
// skipDuplicates: true,
// })
// db.insert(users).values(parsedUsers),
// db.insert(accounts).values(parsedAccounts),
// db.insert(sites).values(parsedSites),
// db.insert(posts).values(parsedPosts),
// db.insert(examples).values(parsedExamples)
// ]);

return NextResponse.json({ response: "ok" });
}
2 changes: 1 addition & 1 deletion app/app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Suspense } from "react";

export default function LoginPage() {
return (
<div className="mx-5 border border-stone-200 py-10 dark:border-stone-700 sm:mx-auto sm:w-full sm:max-w-md sm:rounded-lg sm:shadow-md">
<div className="mx-5 border border-stone-200 py-10 sm:mx-auto sm:w-full sm:max-w-md sm:rounded-lg sm:shadow-md dark:border-stone-700">
<Image
alt="Platforms Starter Kit"
width={100}
Expand Down
2 changes: 1 addition & 1 deletion app/app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
<Profile />
</Suspense>
</Nav>
<div className="min-h-screen dark:bg-black sm:pl-60">{children}</div>
<div className="min-h-screen sm:pl-60 dark:bg-black">{children}</div>
</div>
);
}
13 changes: 6 additions & 7 deletions app/app/(dashboard)/post/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { getSession } from "@/lib/auth";
import prisma from "@/lib/prisma";
import { notFound, redirect } from "next/navigation";
import Editor from "@/components/editor";
import db from "@/lib/db";

export default async function PostPage({ params }: { params: { id: string } }) {
const session = await getSession();
if (!session) {
redirect("/login");
}
const data = await prisma.post.findUnique({
where: {
id: decodeURIComponent(params.id),
},
include: {

const data = await db.query.posts.findFirst({
where: (posts, { eq }) => eq(posts.id, decodeURIComponent(params.id)),
with: {
site: {
select: {
columns: {
subdomain: true,
},
},
Expand Down
8 changes: 3 additions & 5 deletions app/app/(dashboard)/post/[id]/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getSession } from "@/lib/auth";
import prisma from "@/lib/prisma";
import { notFound, redirect } from "next/navigation";
import Form from "@/components/form";
import { updatePostMetadata } from "@/lib/actions";
import DeletePostForm from "@/components/form/delete-post-form";
import db from "@/lib/db";

export default async function PostSettings({
params,
Expand All @@ -14,10 +14,8 @@ export default async function PostSettings({
if (!session) {
redirect("/login");
}
const data = await prisma.post.findUnique({
where: {
id: decodeURIComponent(params.id),
},
const data = await db.query.posts.findFirst({
where: (posts, { eq }) => eq(posts.id, decodeURIComponent(params.id)),
});
if (!data || data.userId !== session.user.id) {
notFound();
Expand Down
11 changes: 5 additions & 6 deletions app/app/(dashboard)/site/[id]/analytics/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getSession } from "@/lib/auth";
import prisma from "@/lib/prisma";
import { notFound, redirect } from "next/navigation";
import AnalyticsMockup from "@/components/analytics";
import db from "@/lib/db";

export default async function SiteAnalytics({
params,
Expand All @@ -12,11 +12,10 @@ export default async function SiteAnalytics({
if (!session) {
redirect("/login");
}
const data = await prisma.site.findUnique({
where: {
id: decodeURIComponent(params.id),
},
const data = await db.query.sites.findFirst({
where: (sites, { eq }) => eq(sites.id, decodeURIComponent(params.id)),
});

if (!data || data.userId !== session.user.id) {
notFound();
}
Expand All @@ -27,7 +26,7 @@ export default async function SiteAnalytics({
<>
<div className="flex items-center justify-center sm:justify-start">
<div className="flex flex-col items-center space-x-0 space-y-2 sm:flex-row sm:space-x-4 sm:space-y-0">
<h1 className="font-cal text-xl font-bold dark:text-white sm:text-3xl">
<h1 className="font-cal text-xl font-bold sm:text-3xl dark:text-white">
Analytics for {data.name}
</h1>
<a
Expand Down
10 changes: 4 additions & 6 deletions app/app/(dashboard)/site/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { getSession } from "@/lib/auth";
import prisma from "@/lib/prisma";
import { notFound, redirect } from "next/navigation";
import Posts from "@/components/posts";
import CreatePostButton from "@/components/create-post-button";
import db from "@/lib/db";

export default async function SitePosts({
params,
Expand All @@ -13,10 +13,8 @@ export default async function SitePosts({
if (!session) {
redirect("/login");
}
const data = await prisma.site.findUnique({
where: {
id: decodeURIComponent(params.id),
},
const data = await db.query.sites.findFirst({
where: (sites, { eq }) => eq(sites.id, decodeURIComponent(params.id)),
});

if (!data || data.userId !== session.user.id) {
Expand All @@ -29,7 +27,7 @@ export default async function SitePosts({
<>
<div className="flex flex-col items-center justify-between space-y-4 sm:flex-row sm:space-y-0">
<div className="flex flex-col items-center space-y-2 sm:flex-row sm:space-x-4 sm:space-y-0">
<h1 className="w-60 truncate font-cal text-xl font-bold dark:text-white sm:w-auto sm:text-3xl">
<h1 className="w-60 truncate font-cal text-xl font-bold sm:w-auto sm:text-3xl dark:text-white">
All Posts for {data.name}
</h1>
<a
Expand Down
8 changes: 3 additions & 5 deletions app/app/(dashboard)/site/[id]/settings/appearance/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import prisma from "@/lib/prisma";
import Form from "@/components/form";
import { updateSite } from "@/lib/actions";
import db from "@/lib/db";

export default async function SiteSettingsAppearance({
params,
}: {
params: { id: string };
}) {
const data = await prisma.site.findUnique({
where: {
id: decodeURIComponent(params.id),
},
const data = await db.query.sites.findFirst({
where: (sites, { eq }) => eq(sites.id, decodeURIComponent(params.id)),
});

return (
Expand Down
Loading

0 comments on commit 7e33556

Please sign in to comment.