Skip to content

Commit 7e33556

Browse files
authored
Migrate to Drizzle ORM (#404)
1 parent 29e20e7 commit 7e33556

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3616
-2228
lines changed

.env.example

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ NEXTAUTH_URL=http://app.localhost:3000
1313
NEXT_PUBLIC_ROOT_DOMAIN=vercel.pub
1414

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

1918
# 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
2019
BLOB_READ_WRITE_TOKEN=

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ This working demo site was built using the Platforms Starter Kit and:
113113

114114
- [Next.js](https://nextjs.org/) as the React framework
115115
- [Tailwind](https://tailwindcss.com/) for CSS styling
116-
- [Prisma](https://prisma.io/) as the ORM for database access
116+
- [Drizzle](https://orm.drizzle.team/) as the ORM for database access
117117
- [Novel](https://novel.sh/) for the WYSIWYG editor
118118
- [Vercel Postgres](https://vercel.com/storage/postgres) for the database
119119
- [Vercel Blob](https://vercel.com/storage/blob) for image uploads

app/[domain]/[slug]/page.tsx

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { notFound } from "next/navigation";
2-
import prisma from "@/lib/prisma";
32
import { getPostData, getSiteData } from "@/lib/fetchers";
43
import BlogCard from "@/components/blog-card";
54
import BlurImage from "@/components/blur-image";
65
import MDX from "@/components/mdx";
76
import { placeholderBlurhash, toDateString } from "@/lib/utils";
7+
import db from "@/lib/db";
8+
import { posts, sites } from "@/lib/schema";
9+
import { eq } from "drizzle-orm";
810

911
export async function generateMetadata({
1012
params,
@@ -47,23 +49,17 @@ export async function generateMetadata({
4749
}
4850

4951
export async function generateStaticParams() {
50-
const allPosts = await prisma.post.findMany({
51-
select: {
52-
slug: true,
52+
const allPosts = await db
53+
.select({
54+
slug: posts.slug,
5355
site: {
54-
select: {
55-
subdomain: true,
56-
customDomain: true,
57-
},
56+
subdomain: sites.subdomain,
57+
customDomain: sites.customDomain,
5858
},
59-
},
60-
// feel free to remove this filter if you want to generate paths for all posts
61-
where: {
62-
site: {
63-
subdomain: "demo",
64-
},
65-
},
66-
});
59+
})
60+
.from(posts)
61+
.leftJoin(sites, eq(posts.siteId, sites.id))
62+
.where(eq(sites.subdomain, "demo")); // feel free to remove this filter if you want to generate paths for all posts
6763

6864
const allPaths = allPosts
6965
.flatMap(({ site, slug }) => [
@@ -98,13 +94,13 @@ export default async function SitePostPage({
9894
<>
9995
<div className="flex flex-col items-center justify-center">
10096
<div className="m-auto w-full text-center md:w-7/12">
101-
<p className="m-auto my-5 w-10/12 text-sm font-light text-stone-500 dark:text-stone-400 md:text-base">
97+
<p className="m-auto my-5 w-10/12 text-sm font-light text-stone-500 md:text-base dark:text-stone-400">
10298
{toDateString(data.createdAt)}
10399
</p>
104-
<h1 className="mb-10 font-title text-3xl font-bold text-stone-800 dark:text-white md:text-6xl">
100+
<h1 className="mb-10 font-title text-3xl font-bold text-stone-800 md:text-6xl dark:text-white">
105101
{data.title}
106102
</h1>
107-
<p className="text-md m-auto w-10/12 text-stone-600 dark:text-stone-400 md:text-lg">
103+
<p className="text-md m-auto w-10/12 text-stone-600 md:text-lg dark:text-stone-400">
108104
{data.description}
109105
</p>
110106
</div>
@@ -133,7 +129,7 @@ export default async function SitePostPage({
133129
</div>
134130
)}
135131
</div>
136-
<div className="text-md ml-3 inline-block align-middle dark:text-white md:text-lg">
132+
<div className="text-md ml-3 inline-block align-middle md:text-lg dark:text-white">
137133
by <span className="font-semibold">{data.site?.user?.name}</span>
138134
</div>
139135
</div>

app/[domain]/page.tsx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
import Link from "next/link";
2-
import prisma from "@/lib/prisma";
32
import { notFound } from "next/navigation";
43
import BlurImage from "@/components/blur-image";
54
import { placeholderBlurhash, toDateString } from "@/lib/utils";
65
import BlogCard from "@/components/blog-card";
76
import { getPostsForSite, getSiteData } from "@/lib/fetchers";
87
import Image from "next/image";
8+
import db from "@/lib/db";
99

1010
export async function generateStaticParams() {
11-
const allSites = await prisma.site.findMany({
12-
select: {
11+
const allSites = await db.query.sites.findMany({
12+
// feel free to remove this filter if you want to generate paths for all sites
13+
where: (sites, { eq }) => eq(sites.subdomain, "demo"),
14+
columns: {
1315
subdomain: true,
1416
customDomain: true,
1517
},
16-
// feel free to remove this filter if you want to generate paths for all sites
17-
where: {
18-
subdomain: "demo",
19-
},
2018
});
2119

2220
const allPaths = allSites
@@ -66,10 +64,10 @@ export default async function SiteHomePage({
6664
/>
6765
</div>
6866
<div className="mx-auto mt-10 w-5/6 lg:w-full">
69-
<h2 className="my-10 font-title text-4xl dark:text-white md:text-6xl">
67+
<h2 className="my-10 font-title text-4xl md:text-6xl dark:text-white">
7068
{posts[0].title}
7169
</h2>
72-
<p className="w-full text-base dark:text-white md:text-lg lg:w-2/3">
70+
<p className="w-full text-base md:text-lg lg:w-2/3 dark:text-white">
7371
{posts[0].description}
7472
</p>
7573
<div className="flex w-full items-center justify-start space-x-4">
@@ -88,11 +86,11 @@ export default async function SiteHomePage({
8886
</div>
8987
)}
9088
</div>
91-
<p className="ml-3 inline-block whitespace-nowrap align-middle text-sm font-semibold dark:text-white md:text-base">
89+
<p className="ml-3 inline-block whitespace-nowrap align-middle text-sm font-semibold md:text-base dark:text-white">
9290
{data.user?.name}
9391
</p>
9492
<div className="h-6 border-l border-stone-600 dark:border-stone-400" />
95-
<p className="m-auto my-5 w-10/12 text-sm font-light text-stone-500 dark:text-stone-400 md:text-base">
93+
<p className="m-auto my-5 w-10/12 text-sm font-light text-stone-500 md:text-base dark:text-stone-400">
9694
{toDateString(posts[0].createdAt)}
9795
</p>
9896
</div>
@@ -124,7 +122,7 @@ export default async function SiteHomePage({
124122

125123
{posts.length > 1 && (
126124
<div className="mx-5 mb-20 max-w-screen-xl lg:mx-24 2xl:mx-auto">
127-
<h2 className="mb-10 font-title text-4xl dark:text-white md:text-5xl">
125+
<h2 className="mb-10 font-title text-4xl md:text-5xl dark:text-white">
128126
More stories
129127
</h2>
130128
<div className="grid w-full grid-cols-1 gap-x-4 gap-y-8 md:grid-cols-2 xl:grid-cols-3">

app/api/migrate/route.ts

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,50 +6,36 @@
66
*/
77

88
import { NextResponse } from "next/server";
9-
// import prisma from "@/lib/prisma";
9+
// import db from "@/lib/db/db";
1010

1111
export async function GET() {
12-
// Download data from old database
13-
// const users = await prisma.user.findMany();
14-
// const accounts = await prisma.account.findMany();
15-
// const sites = await prisma.site.findMany();
16-
// const posts = await prisma.post.findMany();
17-
// const examples = await prisma.example.findMany();
12+
// Download data from old database
13+
// const usersResult = await db.query.users.findMany();
14+
// const accountsResult = await db.query.accounts.findMany();
15+
// const sitesResult = await db.query.sites.findMany();
16+
// const postsResult = await db.query.posts.findMany();;
17+
// const examplesResult = await db.query.examples.findMany();;
1818

19-
// fs.writeFileSync("users.json", JSON.stringify(users));
20-
// fs.writeFileSync("accounts.json", JSON.stringify(accounts));
21-
// fs.writeFileSync("sites.json", JSON.stringify(sites));
22-
// fs.writeFileSync("posts.json", JSON.stringify(posts));
23-
// fs.writeFileSync("examples.json", JSON.stringify(examples));
19+
// fs.writeFileSync("users.json", JSON.stringify(usersResult));
20+
// fs.writeFileSync("accounts.json", JSON.stringify(accountsResult));
21+
// fs.writeFileSync("sites.json", JSON.stringify(sitesResult));
22+
// fs.writeFileSync("posts.json", JSON.stringify(postsResult));
23+
// fs.writeFileSync("examples.json", JSON.stringify(examplesResult));
2424

2525
// Upload data to new database
26-
// const users = JSON.parse(fs.readFileSync("users.json", "utf8"));
27-
// const accounts = JSON.parse(fs.readFileSync("accounts.json", "utf8"));
28-
// const sites = JSON.parse(fs.readFileSync("sites.json", "utf8"));
29-
// const posts = JSON.parse(fs.readFileSync("posts.json", "utf8"));
30-
// const examples = JSON.parse(fs.readFileSync("examples.json", "utf8"));
26+
// const parsedUsers = JSON.parse(fs.readFileSync("users.json", "utf8"));
27+
// const parsedAccounts = JSON.parse(fs.readFileSync("accounts.json", "utf8"));
28+
// const parsedSites = JSON.parse(fs.readFileSync("sites.json", "utf8"));
29+
// const parsedPosts = JSON.parse(fs.readFileSync("posts.json", "utf8"));
30+
// const parsedExamples = JSON.parse(fs.readFileSync("examples.json", "utf8"));
3131

3232
// const response = await Promise.all([
33-
// prisma.user.createMany({
34-
// data: users,
35-
// skipDuplicates: true,
36-
// }),
37-
// prisma.account.createMany({
38-
// data: accounts,
39-
// skipDuplicates: true,
40-
// }),
41-
// prisma.site.createMany({
42-
// data: sites,
43-
// skipDuplicates: true,
44-
// }),
45-
// prisma.post.createMany({
46-
// data: posts,
47-
// skipDuplicates: true,
48-
// }),
49-
// prisma.example.createMany({
50-
// data: examples,
51-
// skipDuplicates: true,
52-
// })
33+
// db.insert(users).values(parsedUsers),
34+
// db.insert(accounts).values(parsedAccounts),
35+
// db.insert(sites).values(parsedSites),
36+
// db.insert(posts).values(parsedPosts),
37+
// db.insert(examples).values(parsedExamples)
38+
// ]);
5339

5440
return NextResponse.json({ response: "ok" });
5541
}

app/app/(auth)/login/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Suspense } from "react";
44

55
export default function LoginPage() {
66
return (
7-
<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">
7+
<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">
88
<Image
99
alt="Platforms Starter Kit"
1010
width={100}

app/app/(dashboard)/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
1010
<Profile />
1111
</Suspense>
1212
</Nav>
13-
<div className="min-h-screen dark:bg-black sm:pl-60">{children}</div>
13+
<div className="min-h-screen sm:pl-60 dark:bg-black">{children}</div>
1414
</div>
1515
);
1616
}

app/app/(dashboard)/post/[id]/page.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
import { getSession } from "@/lib/auth";
2-
import prisma from "@/lib/prisma";
32
import { notFound, redirect } from "next/navigation";
43
import Editor from "@/components/editor";
4+
import db from "@/lib/db";
55

66
export default async function PostPage({ params }: { params: { id: string } }) {
77
const session = await getSession();
88
if (!session) {
99
redirect("/login");
1010
}
11-
const data = await prisma.post.findUnique({
12-
where: {
13-
id: decodeURIComponent(params.id),
14-
},
15-
include: {
11+
12+
const data = await db.query.posts.findFirst({
13+
where: (posts, { eq }) => eq(posts.id, decodeURIComponent(params.id)),
14+
with: {
1615
site: {
17-
select: {
16+
columns: {
1817
subdomain: true,
1918
},
2019
},

app/app/(dashboard)/post/[id]/settings/page.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { getSession } from "@/lib/auth";
2-
import prisma from "@/lib/prisma";
32
import { notFound, redirect } from "next/navigation";
43
import Form from "@/components/form";
54
import { updatePostMetadata } from "@/lib/actions";
65
import DeletePostForm from "@/components/form/delete-post-form";
6+
import db from "@/lib/db";
77

88
export default async function PostSettings({
99
params,
@@ -14,10 +14,8 @@ export default async function PostSettings({
1414
if (!session) {
1515
redirect("/login");
1616
}
17-
const data = await prisma.post.findUnique({
18-
where: {
19-
id: decodeURIComponent(params.id),
20-
},
17+
const data = await db.query.posts.findFirst({
18+
where: (posts, { eq }) => eq(posts.id, decodeURIComponent(params.id)),
2119
});
2220
if (!data || data.userId !== session.user.id) {
2321
notFound();

app/app/(dashboard)/site/[id]/analytics/page.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { getSession } from "@/lib/auth";
2-
import prisma from "@/lib/prisma";
32
import { notFound, redirect } from "next/navigation";
43
import AnalyticsMockup from "@/components/analytics";
4+
import db from "@/lib/db";
55

66
export default async function SiteAnalytics({
77
params,
@@ -12,11 +12,10 @@ export default async function SiteAnalytics({
1212
if (!session) {
1313
redirect("/login");
1414
}
15-
const data = await prisma.site.findUnique({
16-
where: {
17-
id: decodeURIComponent(params.id),
18-
},
15+
const data = await db.query.sites.findFirst({
16+
where: (sites, { eq }) => eq(sites.id, decodeURIComponent(params.id)),
1917
});
18+
2019
if (!data || data.userId !== session.user.id) {
2120
notFound();
2221
}
@@ -27,7 +26,7 @@ export default async function SiteAnalytics({
2726
<>
2827
<div className="flex items-center justify-center sm:justify-start">
2928
<div className="flex flex-col items-center space-x-0 space-y-2 sm:flex-row sm:space-x-4 sm:space-y-0">
30-
<h1 className="font-cal text-xl font-bold dark:text-white sm:text-3xl">
29+
<h1 className="font-cal text-xl font-bold sm:text-3xl dark:text-white">
3130
Analytics for {data.name}
3231
</h1>
3332
<a

0 commit comments

Comments
 (0)