import { query } from "@/db.ts"; const id = "id uuid primary key default uuid_generate_v4()"; interface TableSpec { columns: string[]; additionalTableStatements?: string[]; additionalStatements?: string[]; prepStatements?: string[]; } const timestamps = [ "created_at timestamptz not null default now()", "updated_at timestamptz not null default now()", ]; const tables: Record = { "note": { columns: [id, "content text not null", ...timestamps], }, "user": { prepStatements: [ "drop type if exists user_status", "create type user_status as enum ('unverified', 'verified', 'owner', 'superadmin')", ], columns: [ id, "username text not null unique", "hashed_password text not null", "status user_status not null", "display_name text", ...timestamps, ], }, "user_token": { columns: [ id, ], }, "team": { columns: [ id, "display_name text not null", ...timestamps, ], additionalStatements: [ 'create index display_name_idx on team ("display_name")', ], }, "team_user": { prepStatements: [ "drop type if exists team_user_status", "create type team_user_status as enum ('invited', 'accepted', 'owner')", ], columns: [ "team_id uuid", "user_id uuid", "status team_user_status not null", ...timestamps, ], additionalTableStatements: [ 'constraint fk_team foreign key(team_id) references "team"(id) on delete cascade', 'constraint fk_user foreign key(user_id) references "user"(id) on delete cascade', ], additionalStatements: [ "create index team_user_idx on team_user (team_id) include (user_id)", "create index team_idx on team_user (team_id)", "create index user_idx on team_user (user_id)", "create index status_idx on team_user (status)", ], }, }; const dropTables = Object.entries(tables).reverse().map(([name, _meta]) => `drop table if exists "${name}";` ).join("\n"); const createTables = Object.entries(tables).map(([name, meta]) => ` -- CREATE TABLE ${name} ${(meta.prepStatements || []).map((s) => `${s};`).join("\n")} create table "${name}" ( ${meta.columns.concat(meta.additionalTableStatements || []).join(",\n ")} ); ${(meta.additionalStatements || []).map((s) => `${s};`).join("\n")} `).map((s) => s.trim()).join("\n\n"); const queryString = ` begin; ${dropTables} create extension if not exists "uuid-ossp"; ${createTables} with new_user as ( insert into "user" (username, hashed_password, status) values ('lytedev', '$2a$10$9fyDAOz6H4a393KHyjbvIe1WFxbhCJhq/CZmlXcEg4d1bE9Ey25WW', 'superadmin') returning id as user_id ), new_team as ( insert into "team" (display_name) values ('superadmins') returning id as team_id ) insert into "team_user" (user_id, team_id, status) values ( (select user_id from new_user), (select team_id from new_team), 'owner' ); commit; `; console.log(queryString); const result = await query(queryString); console.debug(result); console.log(queryString);