Skip to content

Commit ca98046

Browse files
committed
feat: switch to postgresql
1 parent 07951db commit ca98046

File tree

16 files changed

+3829
-4015
lines changed

16 files changed

+3829
-4015
lines changed

app/pages/optimistic-todos.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const { mutate: addTodo } = useMutation({
2020
method: 'POST',
2121
body: {
2222
title,
23-
completed: 0
23+
completed: false
2424
}
2525
}) as Promise<Todo>
2626
},
@@ -31,7 +31,7 @@ const { mutate: addTodo } = useMutation({
3131
const oldTodos = queryCache.getQueryData(todosQuery.key) || []
3232
const newTodoItem = {
3333
title,
34-
completed: 0,
34+
completed: false,
3535
// a negative id to differentiate them from the server ones
3636
id: -Date.now(),
3737
createdAt: new Date(),
@@ -97,7 +97,7 @@ const { mutate: toggleTodo } = useMutation({
9797
$fetch(`/api/todos/${todo.id}`, {
9898
method: 'PATCH',
9999
body: {
100-
completed: Number(!todo.completed)
100+
completed: !todo.completed
101101
}
102102
}),
103103
@@ -108,7 +108,7 @@ const { mutate: toggleTodo } = useMutation({
108108
if (todoIndex >= 0) {
109109
newTodos = oldTodos.toSpliced(todoIndex, 1, {
110110
...todo,
111-
completed: Number(!todo.completed)
111+
completed: !todo.completed
112112
})
113113
queryCache.setQueryData(todosQuery.key, newTodos)
114114
}

app/pages/todos.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const { mutate: toggleTodo } = useMutation({
6363
$fetch(`/api/todos/${todo.id}`, {
6464
method: 'PATCH',
6565
body: {
66-
completed: Number(!todo.completed)
66+
completed: !todo.completed
6767
}
6868
}),
6969

drizzle.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineConfig } from 'drizzle-kit'
22

33
export default defineConfig({
4-
dialect: 'sqlite',
4+
dialect: 'postgresql',
55
schema: './server/database/schema.ts',
66
out: './server/database/migrations'
77
})

package.json

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,37 @@
99
"postinstall": "nuxt prepare"
1010
},
1111
"dependencies": {
12-
"@iconify-json/lucide": "^1.2.49",
13-
"@iconify-json/simple-icons": "^1.2.38",
14-
"@nuxt/ui": "^3.1.3",
12+
"@electric-sql/pglite": "^0.3.8",
13+
"@iconify-json/lucide": "^1.2.68",
14+
"@iconify-json/simple-icons": "^1.2.52",
15+
"@nuxt/ui": "^3.3.4",
1516
"@nuxthub/core": "^0.9.0",
16-
"@pinia/colada": "^0.17.1",
17-
"@pinia/colada-nuxt": "^0.2.1",
18-
"@pinia/nuxt": "^0.11.1",
19-
"drizzle-kit": "^0.31.1",
20-
"drizzle-orm": "0.44.2",
21-
"h3-zod": "^0.5.3",
22-
"nuxt": "^3.17.5",
23-
"nuxt-auth-utils": "^0.5.20",
17+
"@pinia/colada": "^0.17.5",
18+
"@pinia/colada-nuxt": "^0.2.2",
19+
"@pinia/nuxt": "^0.11.2",
20+
"@types/pg": "^8.15.5",
21+
"drizzle-kit": "^0.31.4",
22+
"drizzle-orm": "0.44.5",
23+
"nuxt": "^4.1.2",
24+
"nuxt-auth-utils": "^0.5.25",
25+
"pg": "^8.16.3",
2426
"pinia": "^3.0.3",
25-
"zod": "^3.25.67"
27+
"zod": "^4.1.9"
2628
},
2729
"devDependencies": {
28-
"@nuxt/devtools": "^2.5.0",
29-
"@nuxt/eslint": "^1.4.1",
30-
"eslint": "^9.29.0",
31-
"typescript": "^5.8.3",
32-
"wrangler": "^4.20.1"
30+
"@nuxt/devtools": "^2.6.3",
31+
"@nuxt/eslint": "^1.9.0",
32+
"eslint": "^9.35.0",
33+
"typescript": "^5.9.2"
3334
},
34-
"packageManager": "pnpm@10.12.1",
35+
"packageManager": "pnpm@10.17.0",
3536
"pnpm": {
3637
"onlyBuiltDependencies": [
38+
"@parcel/watcher",
3739
"@tailwindcss/oxide",
40+
"better-sqlite3",
3841
"esbuild",
42+
"libpq",
3943
"sharp",
4044
"unrs-resolver",
4145
"vue-demi",

pnpm-lock.yaml

Lines changed: 3669 additions & 3913 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/api/todos/[id].delete.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
import { eq, and } from 'drizzle-orm'
2-
import { useValidatedParams, zh } from 'h3-zod'
1+
import { z } from 'zod'
2+
3+
const ParamsSchema = z.object({
4+
id: z.coerce.number().int()
5+
})
36

47
export default eventHandler(async (event) => {
5-
const { id } = await useValidatedParams(event, {
6-
id: zh.intAsString
7-
})
8+
const { id } = await getValidatedQuery(event, ParamsSchema.parse)
89
const { user } = await requireUserSession(event)
910

10-
// List todos for the current user
11-
const deletedTodo = await useDB().delete(tables.todos).where(and(
11+
// Delete todo for the current user
12+
const db = await useDB()
13+
const deletedTodos = await db.delete(tables.todos).where(and(
1214
eq(tables.todos.id, id),
1315
eq(tables.todos.userId, user.id)
14-
)).returning().get()
16+
)).returning()
1517

18+
const deletedTodo = deletedTodos[0]
1619
if (!deletedTodo) {
1720
throw createError({
1821
statusCode: 404,

server/api/todos/[id].patch.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,37 @@
1-
import { eq, and } from 'drizzle-orm'
2-
import { useValidatedParams, useValidatedBody, z, zh } from 'h3-zod'
1+
import { z } from 'zod'
2+
3+
const ParamsSchema = z.object({
4+
id: z.coerce.number().int()
5+
})
6+
7+
const BodySchema = z.object({
8+
completed: z.boolean()
9+
})
310

411
export default eventHandler(async (event) => {
5-
const { id } = await useValidatedParams(event, {
6-
id: zh.intAsString
7-
})
8-
const { completed } = await useValidatedBody(event, {
9-
completed: z.number().int().min(0).max(1)
10-
})
12+
const { id } = await getValidatedQuery(event, ParamsSchema.parse)
13+
const { completed } = await readValidatedBody(event, BodySchema.parse)
1114
const { user } = await requireUserSession(event)
1215

13-
// List todos for the current user
14-
const todo = await useDB().update(tables.todos).set({
15-
completed
16+
// SQlite:
17+
// const isCompleted = completed ? 1 : 0
18+
const isCompleted = completed
19+
20+
// Update todo for the current user
21+
const db = await useDB()
22+
const updatedTodos = await db.update(tables.todos).set({
23+
completed: isCompleted
1624
}).where(and(
1725
eq(tables.todos.id, id),
1826
eq(tables.todos.userId, user.id)
19-
)).returning().get()
27+
)).returning()
2028

29+
const todo = updatedTodos[0]
30+
if (!todo) {
31+
throw createError({
32+
statusCode: 404,
33+
message: 'Todo not found'
34+
})
35+
}
2136
return todo
2237
})

server/api/todos/index.get.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { eq } from 'drizzle-orm'
2-
31
export default eventHandler(async (event) => {
42
const { user } = await requireUserSession(event)
53

64
// List todos for the current user
7-
const todos = await useDB().select().from(tables.todos).where(eq(tables.todos.userId, user.id)).all()
5+
const db = await useDB()
6+
const todos = await db.select().from(tables.todos).where(eq(tables.todos.userId, user.id))
87

98
return todos as Todo[]
109
})

server/api/todos/index.post.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
import { useValidatedBody, z } from 'h3-zod'
1+
import { z } from 'zod'
2+
3+
const BodySchema = z.object({
4+
title: z.string().min(1).max(100)
5+
})
26

37
export default eventHandler(async (event) => {
4-
const { title } = await useValidatedBody(event, {
5-
title: z.string().min(1).max(100)
6-
})
8+
const { title } = await readValidatedBody(event, body => BodySchema.parse(body))
79
const { user } = await requireUserSession(event)
810

911
// Insert todo for the current user
10-
const todo = await useDB().insert(tables.todos).values({
12+
const db = await useDB()
13+
const todos = await db.insert(tables.todos).values({
1114
userId: user.id,
1215
title,
1316
createdAt: new Date()
14-
}).returning().get()
17+
}).returning()
1518

16-
return todo
19+
return todos[0]
1720
})

server/api/todos/stats.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { sql } from 'drizzle-orm'
2-
31
export default eventHandler(async () => {
42
// Count the total number of todos
5-
return await useDB().select({
3+
const db = await useDB()
4+
const result = await db.select({
65
todos: sql<number>`count(*)`,
76
users: sql<number>`count(distinct(${tables.todos.userId}))`
8-
}).from(tables.todos).get()
7+
}).from(tables.todos)
8+
9+
return result[0]
910
})

0 commit comments

Comments
 (0)