-
-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
db: add postgresql + drizzle support
- Loading branch information
1 parent
1822783
commit 1c8a606
Showing
16 changed files
with
339 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { env } from "$utils/env.ts"; | ||
import { type Config, defineConfig } from "drizzle-kit"; | ||
|
||
// biome-ignore lint/style/noDefaultExport: Config file | ||
export default defineConfig({ | ||
out: "./drizzle", | ||
schema: "./src/db/schema/*", | ||
dialect: "postgresql", | ||
dbCredentials: { | ||
host: env.POSTGRES_HOST, | ||
port: Number.parseInt(env.POSTGRES_PORT), | ||
user: env.POSTGRES_USER, | ||
password: env.POSTGRES_PASSWORD, | ||
database: env.POSTGRES_DB, | ||
}, | ||
verbose: true, | ||
strict: true, | ||
}) satisfies Config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
CREATE TABLE IF NOT EXISTS "guild_config" ( | ||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, | ||
"guild_id" text NOT NULL | ||
); | ||
--> statement-breakpoint | ||
CREATE TABLE IF NOT EXISTS "user_config" ( | ||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, | ||
"user_id" text NOT NULL | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
{ | ||
"id": "3e0e4620-044b-4dc8-afa3-6628db6c803b", | ||
"prevId": "00000000-0000-0000-0000-000000000000", | ||
"version": "7", | ||
"dialect": "postgresql", | ||
"tables": { | ||
"public.guild_config": { | ||
"name": "guild_config", | ||
"schema": "", | ||
"columns": { | ||
"id": { | ||
"name": "id", | ||
"type": "uuid", | ||
"primaryKey": true, | ||
"notNull": true, | ||
"default": "gen_random_uuid()" | ||
}, | ||
"guild_id": { | ||
"name": "guild_id", | ||
"type": "text", | ||
"primaryKey": false, | ||
"notNull": true | ||
} | ||
}, | ||
"indexes": {}, | ||
"foreignKeys": {}, | ||
"compositePrimaryKeys": {}, | ||
"uniqueConstraints": {} | ||
}, | ||
"public.user_config": { | ||
"name": "user_config", | ||
"schema": "", | ||
"columns": { | ||
"id": { | ||
"name": "id", | ||
"type": "uuid", | ||
"primaryKey": true, | ||
"notNull": true, | ||
"default": "gen_random_uuid()" | ||
}, | ||
"user_id": { | ||
"name": "user_id", | ||
"type": "text", | ||
"primaryKey": false, | ||
"notNull": true | ||
} | ||
}, | ||
"indexes": {}, | ||
"foreignKeys": {}, | ||
"compositePrimaryKeys": {}, | ||
"uniqueConstraints": {} | ||
} | ||
}, | ||
"enums": {}, | ||
"schemas": {}, | ||
"sequences": {}, | ||
"_meta": { | ||
"columns": {}, | ||
"schemas": {}, | ||
"tables": {} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"version": "7", | ||
"dialect": "postgresql", | ||
"entries": [ | ||
{ | ||
"idx": 0, | ||
"version": "7", | ||
"when": 1724922837098, | ||
"tag": "0000_cold_grey_gargoyle", | ||
"breakpoints": true | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,11 +9,15 @@ | |
"packageManager": "[email protected]", | ||
"scripts": { | ||
"check": "tsc --noEmit", | ||
"db:generate": "drizzle-kit generate", | ||
"db:migrate": "drizzle-kit migrate", | ||
"db:push": "drizzle-kit push", | ||
"db:studio": "bun run db:generate && drizzle-kit studio", | ||
"deps:update": "bunx npm-check-updates --target latest --root --upgrade", | ||
"dev": "NODE_ENV=development bun run --hot ./src/index.ts", | ||
"dev": "NODE_ENV=development bun run db:generate && bun run db:push && bun run --hot ./src/index.ts", | ||
"lint": "biome check .", | ||
"lint:fix": "biome check --apply .", | ||
"start": "NODE_ENV=production bun run ./src/index.ts", | ||
"start": "NODE_ENV=production bun run db:generate && bun run ./src/index.ts", | ||
"test": "bun run check && bun run lint", | ||
"format": "biome format --write ." | ||
}, | ||
|
@@ -24,16 +28,20 @@ | |
"date-fns": "^3.6.0", | ||
"discord-api-types": "^0.37.98", | ||
"discord.js": "^14.15.3", | ||
"drizzle-orm": "^0.33.0", | ||
"i18next": "^23.14.0", | ||
"i18next-fs-backend": "^2.3.2", | ||
"pino": "^9.3.2", | ||
"pino-pretty": "^11.2.2", | ||
"postgres": "^3.4.4", | ||
"tslib": "^2.7.0", | ||
"zod": "^3.23.8" | ||
}, | ||
"devDependencies": { | ||
"@biomejs/biome": "^1.8.3", | ||
"bun-types": "^1.1.26", | ||
"drizzle-kit": "^0.24.2", | ||
"typescript": "^5.5.4" | ||
} | ||
}, | ||
"trustedDependencies": ["@biomejs/biome", "esbuild"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import path from "node:path"; | ||
import { env } from "$utils/env.ts"; | ||
import { drizzle } from "drizzle-orm/postgres-js"; | ||
import { migrate } from "drizzle-orm/postgres-js/migrator"; | ||
import postgres from "postgres"; | ||
|
||
// biome-ignore lint/style/noNamespaceImport: Drizzle requies a namespace export | ||
import * as guildConfig from "$db/schema/guild_config.ts"; | ||
// biome-ignore lint/style/noNamespaceImport: Drizzle requies a namespace export | ||
import * as userConfig from "$db/schema/user_config.ts"; | ||
|
||
// __dirname replacement in ESM | ||
const pathDirname = path.dirname(Bun.fileURLToPath(import.meta.url)); | ||
const DRIZZLE_DIRECTORY = path.join(pathDirname, "../../drizzle"); | ||
|
||
const pg = postgres({ | ||
max: 1, | ||
host: env.POSTGRES_HOST, | ||
port: Number.parseInt(env.POSTGRES_PORT), | ||
user: env.POSTGRES_USER, | ||
password: env.POSTGRES_PASSWORD, | ||
database: env.POSTGRES_DB, | ||
|
||
// Sends annoying notices to the shadow realm | ||
onnotice: () => { | ||
return; | ||
}, | ||
}); | ||
|
||
const db = drizzle(pg, { | ||
schema: { | ||
...userConfig, | ||
...guildConfig, | ||
}, | ||
}); | ||
|
||
// Runs migrations | ||
await migrate(db, { | ||
migrationsFolder: DRIZZLE_DIRECTORY, | ||
}); | ||
|
||
export { db }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { db } from "$db/db.ts"; | ||
import { guildConfig } from "$db/schema/guild_config.ts"; | ||
import type { HibikiGuildConfig } from "$db/typings/index.d.ts"; | ||
import { eq } from "drizzle-orm"; | ||
|
||
// Gets a guild config | ||
export async function getGuildConfig(guild: string) { | ||
try { | ||
const config = await db.query.guildConfig.findFirst({ | ||
where: (guildConfig, { eq }) => eq(guildConfig.guild_id, guild), | ||
}); | ||
|
||
if (!config?.guild_id) { | ||
return; | ||
} | ||
|
||
return config; | ||
} catch (error) { | ||
throw new Error(Bun.inspect(error)); | ||
} | ||
} | ||
|
||
// Deletes a guild config | ||
export async function deleteGuildConfig(guild: string) { | ||
try { | ||
await db.transaction(async (query) => { | ||
await query.delete(guildConfig).where(eq(guildConfig.guild_id, guild)); | ||
}); | ||
} catch (error) { | ||
throw new Error(Bun.inspect(error)); | ||
} | ||
} | ||
|
||
// Updates or inserts a guild config | ||
export async function updateGuildConfig(guild: string, config: HibikiGuildConfig) { | ||
try { | ||
// Checks for an existing config | ||
const existingConfig = await getGuildConfig(guild); | ||
|
||
// Update if exists, else insert | ||
await (existingConfig?.guild_id | ||
? db.update(guildConfig).set(config).where(eq(guildConfig.guild_id, guild)) | ||
: db.insert(guildConfig).values(config).onConflictDoNothing()); | ||
} catch (error) { | ||
throw new Error(Bun.inspect(error)); | ||
} | ||
} | ||
|
||
// Creates a blank guild config | ||
export async function createBlankGuildConfig(guild: string) { | ||
try { | ||
await db.insert(guildConfig).values({ guild_id: guild }).onConflictDoNothing(); | ||
} catch (error) { | ||
throw new Error(Bun.inspect(error)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { db } from "$db/db.ts"; | ||
import { userConfig } from "$db/schema/user_config.ts"; | ||
import type { HibikiUserConfig } from "$db/typings/index.d.ts"; | ||
import { eq } from "drizzle-orm"; | ||
|
||
// Gets a user config | ||
export async function getUserConfig(user: string) { | ||
try { | ||
const config = await db.query.userConfig.findFirst({ | ||
where: (userConfig, { eq }) => eq(userConfig.user_id, user), | ||
}); | ||
|
||
if (!config?.user_id) { | ||
return; | ||
} | ||
|
||
return config; | ||
} catch (error) { | ||
throw new Error(Bun.inspect(error)); | ||
} | ||
} | ||
|
||
// Deletes a user config | ||
export async function deleteUserConfig(user: string) { | ||
try { | ||
await db.transaction(async (query) => { | ||
await query.delete(userConfig).where(eq(userConfig.user_id, user)); | ||
}); | ||
} catch (error) { | ||
throw new Error(Bun.inspect(error)); | ||
} | ||
} | ||
|
||
// Updates or inserts a user config | ||
export async function updateUserConfig(user: string, config: HibikiUserConfig) { | ||
try { | ||
// Checks for an existing config | ||
const existingConfig = await getUserConfig(user); | ||
|
||
// Update if exists, else insert | ||
await (existingConfig?.user_id | ||
? db.update(userConfig).set(config).where(eq(userConfig.user_id, user)) | ||
: db.insert(userConfig).values(config).onConflictDoNothing()); | ||
} catch (error) { | ||
throw new Error(Bun.inspect(error)); | ||
} | ||
} | ||
|
||
// Creates a blank user config | ||
export async function createBlankUserConfig(user: string) { | ||
try { | ||
await db.insert(userConfig).values({ user_id: user }).onConflictDoNothing(); | ||
} catch (error) { | ||
throw new Error(Bun.inspect(error)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { pgTable, text, uuid } from "drizzle-orm/pg-core"; | ||
|
||
export const guildConfig = pgTable("guild_config", { | ||
id: uuid("id").primaryKey().defaultRandom(), | ||
guild_id: text("guild_id").notNull(), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { pgTable, text, uuid } from "drizzle-orm/pg-core"; | ||
|
||
export const userConfig = pgTable("user_config", { | ||
id: uuid("id").primaryKey().defaultRandom(), | ||
user_id: text("user_id").notNull(), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export interface HibikiGuildConfig { | ||
guild_id: string; | ||
} | ||
|
||
export interface HibikiUserConfig { | ||
user_id: string; | ||
locale?: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.