diff --git a/store/deno.json b/store/deno.json index 637a2cd..0249790 100644 --- a/store/deno.json +++ b/store/deno.json @@ -12,6 +12,7 @@ "@hono/zod-openapi": "npm:@hono/zod-openapi@^0.18.3", "@std/assert": "jsr:@std/assert@1", "@types/pg": "npm:@types/pg@^8.11.10", + "drizzle-kit": "npm:drizzle-kit@^0.30.1", "drizzle-orm": "npm:drizzle-orm@^0.38.2", "hono": "npm:hono@^4.6.14", "pg": "npm:pg@^8.13.1", diff --git a/store/deno.lock b/store/deno.lock index 47a0517..4a82646 100644 --- a/store/deno.lock +++ b/store/deno.lock @@ -15,6 +15,7 @@ "npm:@types/node@*": "22.5.4", "npm:@types/pg@^8.11.10": "8.11.10", "npm:drizzle-kit@*": "0.30.1_esbuild@0.19.12", + "npm:drizzle-kit@~0.30.1": "0.30.1_esbuild@0.19.12", "npm:drizzle-orm@~0.38.2": "0.38.2_@types+pg@8.11.10_pg@8.13.1", "npm:hono@^4.6.14": "4.6.14", "npm:pg@^8.13.1": "8.13.1", @@ -871,6 +872,7 @@ "npm:@hono/swagger-ui@0.5", "npm:@hono/zod-openapi@~0.18.3", "npm:@types/pg@^8.11.10", + "npm:drizzle-kit@~0.30.1", "npm:drizzle-orm@~0.38.2", "npm:hono@^4.6.14", "npm:pg@^8.13.1", diff --git a/store/drizzle/0000_clever_odin.sql b/store/drizzle/0000_clever_odin.sql new file mode 100644 index 0000000..95af691 --- /dev/null +++ b/store/drizzle/0000_clever_odin.sql @@ -0,0 +1,23 @@ +CREATE TABLE "users" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "name" text NOT NULL, + CONSTRAINT "users_name_unique" UNIQUE("name") +); +--> statement-breakpoint +CREATE TABLE "nodes" ( + "id" serial PRIMARY KEY NOT NULL, + "userId" varchar NOT NULL, + "systemId" varchar NOT NULL, + "nodeId" varchar NOT NULL, + "content" "bytea" NOT NULL, + "definition" json NOT NULL, + "hash" varchar(8) NOT NULL, + "previous" varchar(8) +); +--> statement-breakpoint +ALTER TABLE "nodes" ADD CONSTRAINT "nodes_userId_users_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "nodes" ADD CONSTRAINT "node_previous_fk" FOREIGN KEY ("previous") REFERENCES "public"."nodes"("hash") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +CREATE INDEX "user_id_idx" ON "nodes" USING btree ("userId");--> statement-breakpoint +CREATE INDEX "system_id_idx" ON "nodes" USING btree ("systemId");--> statement-breakpoint +CREATE INDEX "node_id_idx" ON "nodes" USING btree ("nodeId");--> statement-breakpoint +CREATE INDEX "hash_idx" ON "nodes" USING btree ("hash"); \ No newline at end of file diff --git a/store/drizzle/0000_dark_squirrel_girl.sql b/store/drizzle/0000_dark_squirrel_girl.sql deleted file mode 100644 index 6b3b31b..0000000 --- a/store/drizzle/0000_dark_squirrel_girl.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE "nodes" ( - "id" serial NOT NULL, - "content" "bytea" NOT NULL, - "definition" json NOT NULL -); ---> statement-breakpoint -CREATE TABLE "users" ( - "id" serial PRIMARY KEY NOT NULL, - "name" text -); diff --git a/store/drizzle/0001_damp_captain_midlands.sql b/store/drizzle/0001_damp_captain_midlands.sql deleted file mode 100644 index 58f595f..0000000 --- a/store/drizzle/0001_damp_captain_midlands.sql +++ /dev/null @@ -1,14 +0,0 @@ -ALTER TABLE "nodes" ADD PRIMARY KEY ("id");--> statement-breakpoint -ALTER TABLE "users" ALTER COLUMN "id" SET DATA TYPE uuid;--> statement-breakpoint -ALTER TABLE "users" ALTER COLUMN "id" SET DEFAULT gen_random_uuid();--> statement-breakpoint -ALTER TABLE "users" ALTER COLUMN "name" SET NOT NULL;--> statement-breakpoint -ALTER TABLE "nodes" ADD COLUMN "userId" varchar NOT NULL;--> statement-breakpoint -ALTER TABLE "nodes" ADD COLUMN "systemId" varchar NOT NULL;--> statement-breakpoint -ALTER TABLE "nodes" ADD COLUMN "nodeId" varchar NOT NULL;--> statement-breakpoint -ALTER TABLE "nodes" ADD COLUMN "hash" varchar(8) NOT NULL;--> statement-breakpoint -ALTER TABLE "nodes" ADD COLUMN "previous" integer;--> statement-breakpoint -CREATE INDEX "user_id_idx" ON "nodes" USING btree ("userId");--> statement-breakpoint -CREATE INDEX "system_id_idx" ON "nodes" USING btree ("systemId");--> statement-breakpoint -CREATE INDEX "node_id_idx" ON "nodes" USING btree ("nodeId");--> statement-breakpoint -CREATE INDEX "hash_idx" ON "nodes" USING btree ("hash");--> statement-breakpoint -ALTER TABLE "users" ADD CONSTRAINT "users_name_unique" UNIQUE("name"); \ No newline at end of file diff --git a/store/drizzle/0002_chemical_whiplash.sql b/store/drizzle/0002_chemical_whiplash.sql deleted file mode 100644 index f1b6f04..0000000 --- a/store/drizzle/0002_chemical_whiplash.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE "nodes" ALTER COLUMN "previous" SET DATA TYPE varchar(8);--> statement-breakpoint -ALTER TABLE "nodes" ADD CONSTRAINT "nodes_userId_users_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "nodes" ADD CONSTRAINT "node_previous_fk" FOREIGN KEY ("previous") REFERENCES "public"."nodes"("hash") ON DELETE no action ON UPDATE no action; \ No newline at end of file diff --git a/store/drizzle/meta/0000_snapshot.json b/store/drizzle/meta/0000_snapshot.json index e584fd9..c458c6e 100644 --- a/store/drizzle/meta/0000_snapshot.json +++ b/store/drizzle/meta/0000_snapshot.json @@ -1,9 +1,43 @@ { - "id": "53dea8d7-01be-4983-ac75-9de9c9a7f592", + "id": "91f8730d-dd5a-4a25-b840-e42b0ef1bc72", "prevId": "00000000-0000-0000-0000-000000000000", "version": "7", "dialect": "postgresql", "tables": { + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_name_unique": { + "name": "users_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, "public.nodes": { "name": "nodes", "schema": "", @@ -11,6 +45,24 @@ "id": { "name": "id", "type": "serial", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "systemId": { + "name": "systemId", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "nodeId": { + "name": "nodeId", + "type": "varchar", "primaryKey": false, "notNull": true }, @@ -25,35 +77,110 @@ "type": "json", "primaryKey": false, "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.users": { - "name": "users", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, + }, + "hash": { + "name": "hash", + "type": "varchar(8)", + "primaryKey": false, "notNull": true }, - "name": { - "name": "name", - "type": "text", + "previous": { + "name": "previous", + "type": "varchar(8)", "primaryKey": false, "notNull": false } }, - "indexes": {}, - "foreignKeys": {}, + "indexes": { + "user_id_idx": { + "name": "user_id_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "system_id_idx": { + "name": "system_id_idx", + "columns": [ + { + "expression": "systemId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "node_id_idx": { + "name": "node_id_idx", + "columns": [ + { + "expression": "nodeId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "hash_idx": { + "name": "hash_idx", + "columns": [ + { + "expression": "hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "nodes_userId_users_id_fk": { + "name": "nodes_userId_users_id_fk", + "tableFrom": "nodes", + "tableTo": "users", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "node_previous_fk": { + "name": "node_previous_fk", + "tableFrom": "nodes", + "tableTo": "nodes", + "columnsFrom": [ + "previous" + ], + "columnsTo": [ + "hash" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, "compositePrimaryKeys": {}, "uniqueConstraints": {}, "policies": {}, diff --git a/store/drizzle/meta/0001_snapshot.json b/store/drizzle/meta/0001_snapshot.json deleted file mode 100644 index b403bf0..0000000 --- a/store/drizzle/meta/0001_snapshot.json +++ /dev/null @@ -1,175 +0,0 @@ -{ - "id": "3c2af8b1-1824-4003-a4f0-d3bfc27c235d", - "prevId": "53dea8d7-01be-4983-ac75-9de9c9a7f592", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.users": { - "name": "users", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "users_name_unique": { - "name": "users_name_unique", - "nullsNotDistinct": false, - "columns": [ - "name" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.nodes": { - "name": "nodes", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "userId": { - "name": "userId", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "systemId": { - "name": "systemId", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "nodeId": { - "name": "nodeId", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "content": { - "name": "content", - "type": "bytea", - "primaryKey": false, - "notNull": true - }, - "definition": { - "name": "definition", - "type": "json", - "primaryKey": false, - "notNull": true - }, - "hash": { - "name": "hash", - "type": "varchar(8)", - "primaryKey": false, - "notNull": true - }, - "previous": { - "name": "previous", - "type": "integer", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "user_id_idx": { - "name": "user_id_idx", - "columns": [ - { - "expression": "userId", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "system_id_idx": { - "name": "system_id_idx", - "columns": [ - { - "expression": "systemId", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "node_id_idx": { - "name": "node_id_idx", - "columns": [ - { - "expression": "nodeId", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "hash_idx": { - "name": "hash_idx", - "columns": [ - { - "expression": "hash", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/store/drizzle/meta/0002_snapshot.json b/store/drizzle/meta/0002_snapshot.json deleted file mode 100644 index 76fe849..0000000 --- a/store/drizzle/meta/0002_snapshot.json +++ /dev/null @@ -1,202 +0,0 @@ -{ - "id": "d950b459-4e3e-4a24-82d8-918eee2d8379", - "prevId": "3c2af8b1-1824-4003-a4f0-d3bfc27c235d", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.users": { - "name": "users", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "users_name_unique": { - "name": "users_name_unique", - "nullsNotDistinct": false, - "columns": [ - "name" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.nodes": { - "name": "nodes", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "userId": { - "name": "userId", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "systemId": { - "name": "systemId", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "nodeId": { - "name": "nodeId", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "content": { - "name": "content", - "type": "bytea", - "primaryKey": false, - "notNull": true - }, - "definition": { - "name": "definition", - "type": "json", - "primaryKey": false, - "notNull": true - }, - "hash": { - "name": "hash", - "type": "varchar(8)", - "primaryKey": false, - "notNull": true - }, - "previous": { - "name": "previous", - "type": "varchar(8)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "user_id_idx": { - "name": "user_id_idx", - "columns": [ - { - "expression": "userId", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "system_id_idx": { - "name": "system_id_idx", - "columns": [ - { - "expression": "systemId", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "node_id_idx": { - "name": "node_id_idx", - "columns": [ - { - "expression": "nodeId", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "hash_idx": { - "name": "hash_idx", - "columns": [ - { - "expression": "hash", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "nodes_userId_users_id_fk": { - "name": "nodes_userId_users_id_fk", - "tableFrom": "nodes", - "tableTo": "users", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "node_previous_fk": { - "name": "node_previous_fk", - "tableFrom": "nodes", - "tableTo": "nodes", - "columnsFrom": [ - "previous" - ], - "columnsTo": [ - "hash" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/store/drizzle/meta/_journal.json b/store/drizzle/meta/_journal.json index 0cd75e0..ba74048 100644 --- a/store/drizzle/meta/_journal.json +++ b/store/drizzle/meta/_journal.json @@ -5,22 +5,8 @@ { "idx": 0, "version": "7", - "when": 1734446124519, - "tag": "0000_dark_squirrel_girl", - "breakpoints": true - }, - { - "idx": 1, - "version": "7", - "when": 1734693909872, - "tag": "0001_damp_captain_midlands", - "breakpoints": true - }, - { - "idx": 2, - "version": "7", - "when": 1734694545302, - "tag": "0002_chemical_whiplash", + "when": 1734694927055, + "tag": "0000_clever_odin", "breakpoints": true } ] diff --git a/store/src/db/db.ts b/store/src/db/db.ts index 417bb87..ae6992a 100644 --- a/store/src/db/db.ts +++ b/store/src/db/db.ts @@ -2,6 +2,8 @@ import { drizzle } from "drizzle-orm/node-postgres"; import pg from "pg"; import * as schema from "./schema.ts"; +import { migrate } from "drizzle-orm/node-postgres/migrator"; + // Use pg driver. const { Pool } = pg; @@ -13,3 +15,7 @@ export const db = drizzle({ }), schema, }); + +export function migrateDb() { + return migrate(db, { migrationsFolder: "drizzle" }); +} diff --git a/store/src/server.ts b/store/src/server.ts index 5144bf0..da042ea 100644 --- a/store/src/server.ts +++ b/store/src/server.ts @@ -5,6 +5,7 @@ import { cors } from "hono/cors"; import { OpenAPIHono } from "@hono/zod-openapi"; import { nodeRouter } from "./routes/node/node.controller.ts"; import { userRouter } from "./routes/user/user.controller.ts"; +import { migrateDb } from "./db/db.ts"; const router = new OpenAPIHono(); @@ -26,10 +27,11 @@ router.get("/ui", swaggerUI({ url: "/openapi.json" })); Deno.serve(router.fetch); async function init() { + await migrateDb(); + await createUser("max"); + const openapi = await router.request("/openapi.json"); const json = await openapi.text(); Deno.writeTextFile("openapi.json", json); - - await createUser("max"); } await init();