Skip to content

Commit

Permalink
feat: add prisma
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreBerger committed Jan 28, 2024
1 parent 4791667 commit c77bbba
Show file tree
Hide file tree
Showing 16 changed files with 183 additions and 3 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
PORT=3000
DATABASE_URL="file:./prisma/data.db"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,5 @@ dist

# env
.env

*.db
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Fastify starter template with Typescript, Prisma and Vitest

### Getting started

#### 1. Download starter and install dependencies

Run the following command on your local environment:

```shell
Expand All @@ -16,21 +18,34 @@ cd my-project-name
bun install
```

Set the environment variables:
#### 2. Set the environment variables:

```shell
cp .env.example .env

# open .env and modify the environment variables (if needed)
```

Then, you can run locally in development mode with live reload:
#### 3. Create and seed the database

Run the following command to create your SQLite database file. This also creates
the `User` and `Post` tables that are defined in
[`prisma/schema.prisma`](./prisma/schema.prisma):

```shell
bun prisma migrate dev --name init
```

#### 4. Start the Fastify server

Launch your Fastify server in development mode with live reload:

```shell
bun run dev
```

Open http://localhost:3000 with your favorite browser to see your project.
Navigate to [http://localhost:3000/](http://localhost:3000/) in your favorite
browser to explore the API of your Fastify server.

### Commands

Expand All @@ -54,4 +69,5 @@ come with these default values:
```bash
# Port number
PORT=3000
DATABASE_URL="./prisma/data.db"
```
Binary file modified bun.lockb
Binary file not shown.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@
"build": "tsc",
"dev": "ts-node-dev --log-error --files ./src/server.ts"
},
"prisma": {
"seed": "ts-node prisma/seed.ts"
},
"keywords": [],
"author": "@pierreberger",
"license": "ISC",
"dependencies": {
"@fastify/autoload": "^5.0.0",
"@fastify/helmet": "^11.1.1",
"@fastify/sensible": "^5.5.0",
"@prisma/client": "^5.8.1",
"fastify": "^4.0.0",
"fastify-cli": "^6.0.1",
"fastify-plugin": "^4.0.0",
Expand All @@ -39,6 +43,7 @@
"fastify-tsconfig": "^2.0.0",
"pino-pretty": "^10.3.1",
"prettier": "^3.2.4",
"prisma": "^5.8.1",
"ts-node": "^10.4.0",
"ts-node-dev": "^2.0.0",
"typescript": "^5.2.2",
Expand Down
20 changes: 20 additions & 0 deletions prisma/migrations/20240128200759_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL PRIMARY KEY,
"email" TEXT NOT NULL,
"name" TEXT
);

-- CreateTable
CREATE TABLE "Post" (
"id" TEXT NOT NULL PRIMARY KEY,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"title" TEXT NOT NULL,
"content" TEXT,
"authorId" TEXT,
CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
3 changes: 3 additions & 0 deletions prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "sqlite"
25 changes: 25 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}

model User {
id String @id @default(cuid())
email String @unique
name String?
posts Post[]
}

model Post {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String
content String?
author User? @relation(fields: [authorId], references: [id])
authorId String?
}
61 changes: 61 additions & 0 deletions prisma/seed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { Prisma } from '@prisma/client'
import { PrismaClient } from '@prisma/client'
import { cleanupDb } from '../test/utils/db.util'

const prisma = new PrismaClient()

const users: Prisma.UserCreateInput[] = [
{
name: 'Pierre',
email: 'pierre@example.com',
posts: {
create: [
{
title: 'First Post',
content: 'This is an example post generated from `prisma/seed.ts`',
},
],
},
},
{
name: 'John',
email: 'john@example.io',
posts: {
create: [
{
title: 'Second Post',
content:
'This is an other example post generated from `prisma/seed.ts`',
},
],
},
},
]

async function seed() {
console.log('🌱 Seeding...')
console.time(`🌱 Database has been seeded`)

console.time('🧹 Cleaned up the database...')
await cleanupDb(prisma)
console.timeEnd('🧹 Cleaned up the database...')

console.time(`👤 Created ${users.length} users...`)
for (const user of users) {
await prisma.user.create({
data: user,
})
}
console.timeEnd(`👤 Created ${users.length} users...`)

console.timeEnd(`🌱 Database has been seeded`)
}

seed()
.catch(e => {
console.error(e)
process.exit(1)
})
.finally(async () => {
await prisma.$disconnect()
})
File renamed without changes.
21 changes: 21 additions & 0 deletions src/plugins/prisma.plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { PrismaClient } from '@prisma/client'
import type { FastifyPluginAsync } from 'fastify'
import fp from 'fastify-plugin'

declare module 'fastify' {
interface FastifyInstance {
prisma: PrismaClient
}
}

export default fp<FastifyPluginAsync>(async (fastify, _opts) => {
const prisma = new PrismaClient()

await prisma.$connect()

fastify.decorate('prisma', prisma)

fastify.addHook('onClose', async fastify => {
await fastify.prisma.$disconnect()
})
})
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 9 additions & 0 deletions src/routes/users/users.route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { FastifyPluginAsync } from 'fastify'

const users: FastifyPluginAsync = async (fastify, _opts) => {
fastify.get('/', async (_request, _reply) => {
return fastify.prisma.user.findMany()
})
}

export default users
17 changes: 17 additions & 0 deletions test/utils/db.util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { PrismaClient } from '@prisma/client'

export async function cleanupDb(prisma: PrismaClient) {
const tables = await prisma.$queryRaw<
{ name: string }[]
>`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma_migrations';`

await prisma.$transaction([
// Disable FK constraints to avoid relation conflicts during deletion
prisma.$executeRawUnsafe(`PRAGMA foreign_keys = OFF`),
// Delete all rows from each table, preserving table structures
...tables.map(({ name }) =>
prisma.$executeRawUnsafe(`DELETE from "${name}"`),
),
prisma.$executeRawUnsafe(`PRAGMA foreign_keys = ON`),
])
}

0 comments on commit c77bbba

Please sign in to comment.