Skip to content

Commit

Permalink
feat: support postgres
Browse files Browse the repository at this point in the history
  • Loading branch information
nichenqin committed Jan 14, 2025
1 parent 86d24b1 commit dbf81f5
Show file tree
Hide file tree
Showing 79 changed files with 3,226 additions and 131 deletions.
277 changes: 277 additions & 0 deletions apps/backend/drizzle/postgres/0000_low_jimmy_woo.sql

Large diffs are not rendered by default.

2,130 changes: 2,130 additions & 0 deletions apps/backend/drizzle/postgres/meta/0000_snapshot.json

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions apps/backend/drizzle/postgres/meta/_journal.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "7",
"dialect": "postgresql",
"entries": [
{
"idx": 0,
"version": "7",
"when": 1736487832119,
"tag": "0000_low_jimmy_woo",
"breakpoints": true
}
]
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
"@elysiajs/trpc": "^1.1.0",
"@json2csv/plainjs": "^7.0.6",
"@kitajs/ts-html-plugin": "latest",
"@lucia-auth/adapter-drizzle": "^1.1.0",
"@lucia-auth/adapter-postgresql": "^3.1.2",
"@lucia-auth/adapter-sqlite": "^3.0.2",
"@oslojs/otp": "^1.1.0",
"@types/pg": "^8.11.10",
"@undb/audit": "workspace:*",
"@undb/authz": "workspace:*",
"@undb/base": "workspace:*",
Expand Down Expand Up @@ -54,6 +57,7 @@
"nanoid": "^5.0.9",
"nodemailer": "^6.9.16",
"oslo": "^1.2.1",
"pg": "^8.13.1",
"radash": "^12.1.0",
"reflect-metadata": "^0.2.2",
"uuid": "^11.0.5",
Expand Down
27 changes: 22 additions & 5 deletions apps/backend/src/modules/auth/auth.provider.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { DrizzlePostgreSQLAdapter } from "@lucia-auth/adapter-drizzle"
import { BunSQLiteAdapter, LibSQLAdapter } from "@lucia-auth/adapter-sqlite"
import { container, inject, instanceCachingFactory } from "@undb/di"
import { env } from "@undb/env"
import { Client, DATABASE_CLIENT } from "@undb/persistence/server"
import { Client, DATABASE_CLIENT, DB_PROVIDER, pgSessionTable, pgUsers } from "@undb/persistence/server"
import Database from "bun:sqlite"
import { drizzle } from "drizzle-orm/node-postgres"
import { Adapter, Lucia } from "lucia"
import pg from "pg"

export const LUCIA_PROVIDER = Symbol.for("LUCIA_PROVIDER")
export const injectLucia = () => inject(LUCIA_PROVIDER)
Expand All @@ -19,12 +21,12 @@ const createLuciaWithAdapter = (adapter: Adapter) => {
},
getSessionAttributes: (attributes) => {
return {
spaceId: attributes.space_id,
spaceId: attributes.space_id ?? attributes.spaceId,
}
},
getUserAttributes: (attributes) => {
return {
emailVerified: Boolean(attributes.email_verified),
emailVerified: Boolean(attributes.email_verified || attributes.emailVerified),
email: attributes.email,
username: attributes.username,
avatar: attributes.avatar,
Expand Down Expand Up @@ -53,28 +55,43 @@ const createSqliteLucia = (sqlite: Database) => {
return createLuciaWithAdapter(adapter)
}

const createPostgresLucia = (pool: pg.Pool) => {
const db = drizzle(pool)

const adapter = new DrizzlePostgreSQLAdapter(db, pgSessionTable, pgUsers)

return createLuciaWithAdapter(adapter)
}

declare module "lucia" {
interface Register {
Lucia: ReturnType<typeof createTursoLucia>
DatabaseSessionAttributes: DatabaseSessionAttributes
DatabaseUserAttributes: {
email: string
email_verified: boolean
emailVerified: boolean
username: string
avatar?: string
}
}
interface DatabaseSessionAttributes {
space_id: string
spaceId: string
}
}

container.register(LUCIA_PROVIDER, {
useFactory: instanceCachingFactory((c) => {
if (env.UNDB_DB_PROVIDER === "sqlite" || !env.UNDB_DB_PROVIDER) {
const dbProvider = c.resolve<string>(DB_PROVIDER)
if (dbProvider === "sqlite" || !dbProvider) {
const sqlite = c.resolve<Database>(DATABASE_CLIENT)
return createSqliteLucia(sqlite)
} else if (dbProvider === "postgres") {
const pool = c.resolve<pg.Pool>(DATABASE_CLIENT)
return createPostgresLucia(pool)
}

const sqlite = c.resolve<Client>(DATABASE_CLIENT)
return createTursoLucia(sqlite)
}),
Expand Down
13 changes: 8 additions & 5 deletions apps/backend/src/modules/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ export class Auth {
})
}

const session = await this.lucia.createSession(userId, { space_id: spaceId })
const session = await this.lucia.createSession(userId, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)

response.headers.set("Set-Cookie", sessionCookie.serialize())
Expand Down Expand Up @@ -434,7 +434,8 @@ export class Auth {
space = Some(await this.spaceService.createSpace({ name: user.username }))
await this.spaceMemberService.createMember(user.id, space.unwrap().id.value, "owner")
}
const session = await this.lucia.createSession(user.id, { space_id: space.unwrap().id.value })
const spaceId = space.unwrap().id.value
const session = await this.lucia.createSession(user.id, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)

return new Response(null, {
Expand Down Expand Up @@ -548,7 +549,8 @@ export class Auth {
"User should have a space",
)

const session = await this.lucia.createSession(token.user_id, { space_id: space.id.value })
const spaceId = space.id.value
const session = await this.lucia.createSession(token.user_id, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)
return new Response(null, {
status: 302,
Expand Down Expand Up @@ -609,7 +611,8 @@ export class Auth {
.where("id", "=", user.id)
.execute()

const session = await this.lucia.createSession(user.id, { space_id: validatedSession.spaceId })
const spaceId = validatedSession.spaceId
const session = await this.lucia.createSession(user.id, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)
return new Response(null, {
status: 302,
Expand Down Expand Up @@ -666,7 +669,7 @@ export class Auth {
return redirectToSignupOrLogin("signup", email)
} else {
await this.spaceMemberService.createMember(user.id, spaceId, role)
const session = await this.lucia.createSession(user.id, { space_id: spaceId })
const session = await this.lucia.createSession(user.id, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)
return redirectToSignupOrLogin("login", email, sessionCookie)
}
Expand Down
10 changes: 7 additions & 3 deletions apps/backend/src/modules/auth/oauth/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ export class GithubOAuth {

if (existingUser) {
const space = (await this.spaceService.getSpace({ userId: existingUser.user_id })).expect("space not found")
const session = await this.lucia.createSession(existingUser.user_id, { space_id: space.id.value })
const spaceId = space.id.value
const session = await this.lucia.createSession(existingUser.user_id, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)
return new Response(null, {
status: 302,
Expand Down Expand Up @@ -136,7 +137,8 @@ export class GithubOAuth {
})
.execute()

const session = await this.lucia.createSession(existingGithubUser.id, { space_id: space.id.value })
const spaceId = space.id.value
const session = await this.lucia.createSession(existingGithubUser.id, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)
return new Response(null, {
status: 302,
Expand Down Expand Up @@ -182,7 +184,9 @@ export class GithubOAuth {

return space
})
const session = await this.lucia.createSession(userId, { space_id: space.id.value })

const spaceId = space.id.value
const session = await this.lucia.createSession(userId, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)
return new Response(null, {
status: 302,
Expand Down
10 changes: 7 additions & 3 deletions apps/backend/src/modules/auth/oauth/google.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ export class GoogleOAuth {

if (existingUser) {
const space = (await this.spaceService.getSpace({ userId: existingUser.user_id })).expect("Space not found")
const session = await this.lucia.createSession(existingUser.user_id, { space_id: space.id.value })

const spaceId = space.id.value
const session = await this.lucia.createSession(existingUser.user_id, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)
return new Response(null, {
status: 302,
Expand Down Expand Up @@ -124,7 +126,8 @@ export class GoogleOAuth {
})
.execute()

const session = await this.lucia.createSession(existingGoogleUser.id, { space_id: space.id.value })
const spaceId = space.id.value
const session = await this.lucia.createSession(existingGoogleUser.id, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)
return new Response(null, {
status: 302,
Expand Down Expand Up @@ -170,7 +173,8 @@ export class GoogleOAuth {

return space
})
const session = await this.lucia.createSession(userId, { space_id: space.id.value })
const spaceId = space.id.value
const session = await this.lucia.createSession(userId, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)
return new Response(null, {
status: 302,
Expand Down
3 changes: 2 additions & 1 deletion apps/backend/src/modules/auth/otp.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ export class OtpService implements IOtpService {

await this.qb.updateTable("undb_user").set({ otp_secret: null }).where("undb_user.email", "=", email).execute()

const session = await this.lucia.createSession(id, { space_id: space.unwrap().id.value })
const spaceId = space.unwrap().id.value
const session = await this.lucia.createSession(id, { space_id: spaceId, spaceId })
const sessionCookie = this.lucia.createSessionCookie(session.id)

return sessionCookie.serialize()
Expand Down
6 changes: 4 additions & 2 deletions apps/backend/src/modules/space/space.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ export class SpaceModule {
})
}
await this.lucia.invalidateUserSessions(user.id)
const updatedSession = await this.lucia.createSession(user.id, { space_id: space.id.value })
const sid = space.id.value
const updatedSession = await this.lucia.createSession(user.id, { space_id: sid, spaceId: sid })
const sessionCookie = this.lucia.createSessionCookie(updatedSession.id)
return new Response(null, {
status: 302,
Expand All @@ -74,7 +75,8 @@ export class SpaceModule {
await this.lucia.invalidateSession(userId)
const space = (await this.spaceService.getSpace({ userId })).expect("Space not found")

const updatedSession = await this.lucia.createSession(userId, { space_id: space.id.value })
const sid = space.id.value
const updatedSession = await this.lucia.createSession(userId, { space_id: sid, spaceId: sid })
const sessionCookie = this.lucia.createSessionCookie(updatedSession.id)
return new Response(null, {
status: 200,
Expand Down
21 changes: 17 additions & 4 deletions apps/backend/src/registry/db.registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {
BaseQueryRepository,
BaseRepository,
Client,
createPostgresClient,
createPostgresQueryBuilder,
createSqliteClient,
createSqliteQueryBuilder,
createTursoClient,
Expand All @@ -32,6 +34,7 @@ import {
DashboardQueryRepository,
DashboardRepository,
DATABASE_CLIENT,
DB_PROVIDER,
InvitationQueryRepository,
InvitationRepository,
QUERY_BUILDER,
Expand Down Expand Up @@ -71,31 +74,41 @@ import { USER_QUERY_REPOSITORY, USER_REPOSITORY, USER_SERVICE, UserService } fro
import { WEBHOOK_QUERY_REPOSITORY, WEBHOOK_REPOSITORY } from "@undb/webhook"
import Database from "bun:sqlite"
import { AsyncLocalStorage } from "node:async_hooks"
import pg from "pg"

const txContext = new AsyncLocalStorage<TxContext>()

export const registerDb = () => {
container.register(DB_PROVIDER, { useValue: env.UNDB_DB_PROVIDER || "sqlite" })
container.register(CTX, { useValue: txContext })
container.register(TX_CTX, TxContextImpl)

container.register(DATABASE_CLIENT, {
useFactory: instanceCachingFactory(() => {
if (env.UNDB_DB_PROVIDER === "sqlite" || !env.UNDB_DB_PROVIDER) {
const dbProvider = container.resolve<string>(DB_PROVIDER)
if (dbProvider === "sqlite" || !dbProvider) {
return createSqliteClient("undb.sqlite")
}
if (dbProvider === "postgres") {
return createPostgresClient(env.UNDB_DB_POSTGRES_URL!)
}
return createTursoClient(env.UNDB_DB_TURSO_URL!, env.UNDB_DB_TURSO_AUTH_TOKEN)
}),
})
container.register(QUERY_BUILDER, {
useFactory: instanceCachingFactory((c) => {
if (env.UNDB_DB_PROVIDER === "sqlite" || !env.UNDB_DB_PROVIDER) {
const dbProvider = container.resolve<string>(DB_PROVIDER)
if (dbProvider === "sqlite" || !dbProvider) {
const sqlite = c.resolve<Database>(DATABASE_CLIENT)
return createSqliteQueryBuilder(sqlite)
} else if (dbProvider === "postgres") {
const pg = c.resolve<pg.Pool>(DATABASE_CLIENT)
return createPostgresQueryBuilder(pg)
}

const sqlite = c.resolve<Client>(DATABASE_CLIENT)
return createTursoQueryBuilder(sqlite)
}),
})
container.register(TX_CTX, TxContextImpl)

container.register(CONTEXT_TOKEN, ServerContext)
container.register(SPACE_REPOSITORY, SpaceRepostitory)
Expand Down
10 changes: 6 additions & 4 deletions apps/frontend/src/lib/registry.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ISpaceMemberService,SPACE_MEMBER_SERVICE } from "@undb/authz"
import { ISpaceMemberService, SPACE_MEMBER_SERVICE } from "@undb/authz"
import {
AddDashboardWidgetCommandHandler,
BulkDeleteRecordsCommandHandler,
Expand Down Expand Up @@ -27,10 +27,11 @@ import {
UpdateTableFieldCommandHandler,
UpdateViewCommandHandler,
} from "@undb/command-handlers"
import { CONTEXT_TOKEN,IContext } from "@undb/context"
import { CommandBus,QueryBus } from "@undb/cqrs"
import { DataService,registerDataService,TRPC_CLIENT } from "@undb/data-service"
import { CONTEXT_TOKEN, IContext } from "@undb/context"
import { CommandBus, QueryBus } from "@undb/cqrs"
import { DataService, registerDataService, TRPC_CLIENT } from "@undb/data-service"
import { container } from "@undb/di"
import { DB_PROVIDER } from "@undb/persistence/client"
import {
GetAggregatesQueryHandler,
GetBaseQueryHandler,
Expand Down Expand Up @@ -91,6 +92,7 @@ export class Registry {
async register(isLocal: boolean, isPlayground: boolean): Promise<DataService> {
const childContainer = container.createChildContainer()

childContainer.register(DB_PROVIDER, { useValue: "sqlite" })
childContainer.register(TRPC_CLIENT, { useValue: trpc })
await registerDataService(childContainer, isLocal, isPlayground)

Expand Down
Binary file modified bun.lockb
Binary file not shown.
8 changes: 8 additions & 0 deletions drizzle.postgres.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "drizzle-kit"

export default defineConfig({
schema: "./packages/persistence/src/schema/postgres.ts",
out: "./apps/backend/drizzle/postgres",
dialect: "postgresql",
tablesFilter: ["undb_*"],
})
4 changes: 2 additions & 2 deletions drizzle.config.ts → drizzle.sqlite.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { defineConfig } from "drizzle-kit"

export default defineConfig({
schema: "./packages/persistence/src/tables.ts",
out: "./apps/backend/drizzle",
schema: "./packages/persistence/src/schema/sqlite.ts",
out: "./apps/backend/drizzle/sqlite",
dialect: "sqlite",
tablesFilter: ["undb_*"],
dbCredentials: {
Expand Down
4 changes: 2 additions & 2 deletions drizzle.turso.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { defineConfig } from "drizzle-kit"

export default defineConfig({
schema: "./packages/persistence/src/tables.ts",
out: "./apps/backend/drizzle",
schema: "./packages/persistence/src/schema/sqlite.ts",
out: "./apps/backend/drizzle/sqlite",
dialect: "turso",
tablesFilter: ["undb_*"],
dbCredentials: {
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
"dev": "bun --bun turbo dev",
"lint": "turbo lint",
"format": "prettier --write \"**/*.{ts,tsx,md,svelte}\"",
"studio": "drizzle-kit studio --config drizzle.config.ts",
"studio": "drizzle-kit studio --config drizzle.sqlite.config.ts",
"studio:turso": "drizzle-kit studio --config drizzle.turso.config.ts",
"generate": "run-s generate:db migrate:deploy",
"generate:db": "drizzle-kit generate --config drizzle.config.ts",
"migrate:db": "drizzle-kit push --config drizzle.config.ts",
"generate:db": "run-p generate:db:*",
"generate:db:postgres": "drizzle-kit generate --config drizzle.postgres.config.ts",
"generate:db:sqlite": "drizzle-kit generate --config drizzle.sqlite.config.ts",
"migrate:db": "drizzle-kit push --config drizzle.sqlite.config.ts",
"move-assets": "bun run ./scripts/move-assets.ts",
"migrate:deploy": "bun run ./scripts/migrate.ts",
"prepare": "husky || echo 1",
Expand Down
Loading

0 comments on commit dbf81f5

Please sign in to comment.