From 90140694a709265205cc2303001c5c15a70ca6e2 Mon Sep 17 00:00:00 2001 From: Hajbo <35660161+Hajbo@users.noreply.github.com> Date: Mon, 25 Sep 2023 18:40:52 +0200 Subject: [PATCH] feat: postgres integration (#35) * Working postgres integration * Remove optional fields from user create * Move credentials to an env file --- .env | 5 ++ bun.lockb | Bin 59060 -> 65160 bytes docker-compose.yaml | 22 +++++++ drizzle.config.ts | 10 +++ package.json | 4 +- src/config.ts | 9 +++ src/db/index.ts | 13 ++++ src/db/migrations/0000_bored_warstar.sql | 10 +++ src/db/migrations/meta/0000_snapshot.json | 75 ++++++++++++++++++++++ src/db/migrations/meta/_journal.json | 13 ++++ src/db/schemas/users.ts | 27 ++++++++ src/db/seed.ts | 22 +++++++ src/index.ts | 2 + 13 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 .env create mode 100644 docker-compose.yaml create mode 100644 drizzle.config.ts create mode 100644 src/config.ts create mode 100644 src/db/index.ts create mode 100644 src/db/migrations/0000_bored_warstar.sql create mode 100644 src/db/migrations/meta/0000_snapshot.json create mode 100644 src/db/migrations/meta/_journal.json create mode 100644 src/db/schemas/users.ts create mode 100644 src/db/seed.ts diff --git a/.env b/.env new file mode 100644 index 0000000..8e1f69e --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres +POSTGRES_DB=medium +POSTGRES_HOST=0.0.0.0 +POSTGRES_PORT=5432 diff --git a/bun.lockb b/bun.lockb index 327260c85cbbf9a088795dc6d0bfeacc8ec0a862..6637b0d0a2918bf58900ff120fc974a15fb64fb9 100755 GIT binary patch delta 16067 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 M>$%hP$s*JL0iASO-2eap diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..5a548c1 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,22 @@ +services: + db: + image: postgres + restart: always + ports: + - 5432:5432 + environment: + PGUSER: ${POSTGRES_USER} + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + healthcheck: + test: ["CMD-SHELL", "pg_isready"] + interval: 1s + timeout: 5s + retries: 10 + volumes: + - pgdata:/var/lib/postgresql/data + env_file: + - .env +volumes: + pgdata: \ No newline at end of file diff --git a/drizzle.config.ts b/drizzle.config.ts new file mode 100644 index 0000000..a9a535d --- /dev/null +++ b/drizzle.config.ts @@ -0,0 +1,10 @@ +import type { Config } from "drizzle-kit"; +import { dbCredentials } from "./src/config"; + +export default { + out: "./src/db/migrations", + schema: "./src/db/schemas/*.ts", + breakpoints: false, + driver: "pg", + dbCredentials: dbCredentials +} satisfies Config; \ No newline at end of file diff --git a/package.json b/package.json index 8f1d9c5..0ec59b5 100644 --- a/package.json +++ b/package.json @@ -11,11 +11,13 @@ }, "dependencies": { "drizzle-orm": "^0.28.6", - "elysia": "latest" + "elysia": "latest", + "postgres": "^3.3.5" }, "devDependencies": { "bun-types": "latest", "drizzle-kit": "^0.19.13", + "pg": "^8.11.3", "vitepress": "^1.0.0-rc.15" }, "peerDependencies": { diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..8be5b43 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,9 @@ +export const dbCredentials = { + host: process.env.POSTGRES_HOST || "0.0.0.0", + port: parseInt(process.env.POSTGRES_PORT || '5432'), + user: process.env.POSTGRES_USER || "postgres", + password: process.env.POSTGRES_PASSWORD || "postgres", + database: process.env.POSTGRES_DB || "medium" +} + +export const dbCredentialsString = `postgres://${dbCredentials.user}:${dbCredentials.password}@${dbCredentials.host}:${dbCredentials.port}/${dbCredentials.database}` \ No newline at end of file diff --git a/src/db/index.ts b/src/db/index.ts new file mode 100644 index 0000000..44183c6 --- /dev/null +++ b/src/db/index.ts @@ -0,0 +1,13 @@ +import { drizzle, PostgresJsDatabase } from 'drizzle-orm/postgres-js'; +import { migrate } from 'drizzle-orm/postgres-js/migrator'; +import postgres from 'postgres'; + +import { dbCredentialsString } from '../config'; + +// for migrations +const migrationClient = postgres(dbCredentialsString, { max: 1 }); +migrate(drizzle(migrationClient), {migrationsFolder: './migrations'}) + +// for query purposes +const queryClient = postgres(dbCredentialsString); +export const db: PostgresJsDatabase = drizzle(queryClient); \ No newline at end of file diff --git a/src/db/migrations/0000_bored_warstar.sql b/src/db/migrations/0000_bored_warstar.sql new file mode 100644 index 0000000..b6c813c --- /dev/null +++ b/src/db/migrations/0000_bored_warstar.sql @@ -0,0 +1,10 @@ +CREATE TABLE IF NOT EXISTS "users" ( + "id" serial PRIMARY KEY NOT NULL, + "email" text NOT NULL, + "bio" text NOT NULL, + "image" text NOT NULL, + "password" text NOT NULL, + "username" text NOT NULL, + "created_at" date DEFAULT CURRENT_DATE, + "updated_at" date DEFAULT CURRENT_DATE +); diff --git a/src/db/migrations/meta/0000_snapshot.json b/src/db/migrations/meta/0000_snapshot.json new file mode 100644 index 0000000..7c09e13 --- /dev/null +++ b/src/db/migrations/meta/0000_snapshot.json @@ -0,0 +1,75 @@ +{ + "version": "5", + "dialect": "pg", + "id": "86aed854-dd08-4bcd-8138-412a71492c24", + "prevId": "00000000-0000-0000-0000-000000000000", + "tables": { + "users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bio": { + "name": "bio", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "date", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_DATE" + }, + "updated_at": { + "name": "updated_at", + "type": "date", + "primaryKey": false, + "notNull": false, + "default": "CURRENT_DATE" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + } +} \ No newline at end of file diff --git a/src/db/migrations/meta/_journal.json b/src/db/migrations/meta/_journal.json new file mode 100644 index 0000000..31eae40 --- /dev/null +++ b/src/db/migrations/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "5", + "dialect": "pg", + "entries": [ + { + "idx": 0, + "version": "5", + "when": 1695584965813, + "tag": "0000_bored_warstar", + "breakpoints": false + } + ] +} \ No newline at end of file diff --git a/src/db/schemas/users.ts b/src/db/schemas/users.ts new file mode 100644 index 0000000..13af4e7 --- /dev/null +++ b/src/db/schemas/users.ts @@ -0,0 +1,27 @@ + +import { sql } from "drizzle-orm"; +import { pgTable, text, date, serial} from "drizzle-orm/pg-core"; +import { createInsertSchema, createSelectSchema } from 'drizzle-typebox'; +import { Type } from '@sinclair/typebox'; + + + +export const users = pgTable('users', { + id: serial('id').primaryKey(), + email: text('email').notNull(), + bio: text('bio').notNull(), + image: text('image').notNull(), + password: text('password').notNull(), + username: text('username').notNull(), + created_at: date('created_at').default(sql`CURRENT_DATE`), + updated_at: date('updated_at').default(sql`CURRENT_DATE`), +}); + + + +// Schema for inserting a user - can be used to validate API requests +const insertUserSchemaRaw = createInsertSchema(users); +export const insertUserSchema = Type.Omit(insertUserSchemaRaw, ['id', 'created_at', 'updated_at']); + +// Schema for selecting a user - can be used to validate API responses +export const selectUserSchema = createSelectSchema(users); \ No newline at end of file diff --git a/src/db/seed.ts b/src/db/seed.ts new file mode 100644 index 0000000..6185b2a --- /dev/null +++ b/src/db/seed.ts @@ -0,0 +1,22 @@ +import { exit } from 'process'; +import { db } from './index'; +import { users } from './schemas/users'; + + +console.log("Migrations complete.") +const data = { + id: users.id.default, + email: 'test@email.com', + username: 'test', + password: 'test', + bio: 'test', + image: 'test', +} +console.log("Inserting user: ", data) +await db.insert(users).values(data) +console.log("User inserted") + +const userResult = await db.select().from(users); +console.log("User result: ", userResult); + +exit(0); \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 9c1f7a1..bb84a52 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,7 @@ import { Elysia } from "elysia"; + + const app = new Elysia().get("/", () => "Hello Elysia").listen(3000); console.log(