trains: schema and migration
All checks were successful
Deploy production / deploy (push) Successful in 1m5s
All checks were successful
Deploy production / deploy (push) Successful in 1m5s
This commit is contained in:
167
drizzle/20261024232143_trains/migration.sql
Normal file
167
drizzle/20261024232143_trains/migration.sql
Normal file
@@ -0,0 +1,167 @@
|
||||
CREATE SCHEMA "trains";
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "trains"."makers" (
|
||||
"id" serial PRIMARY KEY,
|
||||
"slug" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"full_name" text,
|
||||
"country" text,
|
||||
"wikidata" text,
|
||||
"wikipedia" text,
|
||||
"type_count" integer DEFAULT 0 NOT NULL,
|
||||
"first_year" smallint,
|
||||
"last_year" smallint,
|
||||
"built_total" integer DEFAULT 0 NOT NULL,
|
||||
"sources" text[] DEFAULT '{}'::text[] NOT NULL,
|
||||
"logo" text,
|
||||
"logo_file" text,
|
||||
"logo_author" text,
|
||||
"logo_license" text,
|
||||
"photo" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "trains"."operators" (
|
||||
"id" serial PRIMARY KEY,
|
||||
"slug" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"full_name" text,
|
||||
"country" text,
|
||||
"wikidata" text,
|
||||
"wikipedia" text,
|
||||
"type_count" integer DEFAULT 0 NOT NULL,
|
||||
"logo" text,
|
||||
"logo_file" text,
|
||||
"logo_author" text,
|
||||
"logo_license" text,
|
||||
"photo" text,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "trains"."photos" (
|
||||
"id" serial PRIMARY KEY,
|
||||
"type_id" integer NOT NULL,
|
||||
"position" smallint NOT NULL,
|
||||
"kind" text NOT NULL,
|
||||
"file" text NOT NULL,
|
||||
"caption" text,
|
||||
"thumb" text NOT NULL,
|
||||
"width" integer NOT NULL,
|
||||
"height" integer NOT NULL,
|
||||
"author" text,
|
||||
"license" text,
|
||||
"license_url" text
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "trains"."type_operators" (
|
||||
"type_id" integer,
|
||||
"operator_id" integer,
|
||||
"position" smallint DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT "type_operators_pkey" PRIMARY KEY("type_id","operator_id")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "trains"."types" (
|
||||
"id" serial PRIMARY KEY,
|
||||
"dex" integer NOT NULL,
|
||||
"maker_id" integer NOT NULL,
|
||||
"family_id" integer,
|
||||
"slug" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"full_name" text NOT NULL,
|
||||
"nl_name" text,
|
||||
"search" text NOT NULL,
|
||||
"wikidata" text NOT NULL,
|
||||
"wikipedia" text,
|
||||
"description" text,
|
||||
"summary" text,
|
||||
"category" text NOT NULL,
|
||||
"category_label" text,
|
||||
"traction" text,
|
||||
"country" text,
|
||||
"countries" text[] DEFAULT '{}'::text[] NOT NULL,
|
||||
"makers" text[] DEFAULT '{}'::text[] NOT NULL,
|
||||
"operators" text[] DEFAULT '{}'::text[] NOT NULL,
|
||||
"first_built" smallint,
|
||||
"last_built" smallint,
|
||||
"introduced_year" smallint,
|
||||
"retired_year" smallint,
|
||||
"status" text,
|
||||
"in_service" boolean,
|
||||
"number_built" integer,
|
||||
"max_speed_kmh" smallint,
|
||||
"power_kw" integer,
|
||||
"gauge" text,
|
||||
"gauge_mm" smallint,
|
||||
"electric_system" text,
|
||||
"wheels" text,
|
||||
"length_m" real,
|
||||
"weight_t" real,
|
||||
"capacity" smallint,
|
||||
"formation" text,
|
||||
"designer" text,
|
||||
"nicknames" text,
|
||||
"sources" text[] DEFAULT '{}'::text[] NOT NULL,
|
||||
"photo" text,
|
||||
"photo_count" smallint DEFAULT 0 NOT NULL,
|
||||
"photos_checked_at" timestamp with time zone,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "makers_slug_key" ON "trains"."makers" ("slug");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "operators_slug_key" ON "trains"."operators" ("slug");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "photos_type_position_key" ON "trains"."photos" ("type_id","position");--> statement-breakpoint
|
||||
CREATE INDEX "type_operators_operator_idx" ON "trains"."type_operators" ("operator_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "types_dex_key" ON "trains"."types" ("dex");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "types_wikidata_key" ON "trains"."types" ("wikidata");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "types_maker_slug_key" ON "trains"."types" ("maker_id","slug");--> statement-breakpoint
|
||||
CREATE INDEX "types_number_built_idx" ON "trains"."types" ("number_built");--> statement-breakpoint
|
||||
CREATE INDEX "types_first_built_idx" ON "trains"."types" ("first_built");--> statement-breakpoint
|
||||
CREATE INDEX "types_category_idx" ON "trains"."types" ("category");--> statement-breakpoint
|
||||
CREATE INDEX "types_search_trgm_idx" ON "trains"."types" USING gin ("search" public.gin_trgm_ops);--> statement-breakpoint
|
||||
ALTER TABLE "trains"."photos" ADD CONSTRAINT "photos_type_id_types_id_fkey" FOREIGN KEY ("type_id") REFERENCES "trains"."types"("id") ON DELETE CASCADE;--> statement-breakpoint
|
||||
ALTER TABLE "trains"."type_operators" ADD CONSTRAINT "type_operators_type_id_types_id_fkey" FOREIGN KEY ("type_id") REFERENCES "trains"."types"("id") ON DELETE CASCADE;--> statement-breakpoint
|
||||
ALTER TABLE "trains"."type_operators" ADD CONSTRAINT "type_operators_operator_id_operators_id_fkey" FOREIGN KEY ("operator_id") REFERENCES "trains"."operators"("id") ON DELETE CASCADE;--> statement-breakpoint
|
||||
ALTER TABLE "trains"."types" ADD CONSTRAINT "types_maker_id_makers_id_fkey" FOREIGN KEY ("maker_id") REFERENCES "trains"."makers"("id") ON DELETE CASCADE;--> statement-breakpoint
|
||||
ALTER TABLE "trains"."types" ADD CONSTRAINT "types_family_id_types_id_fkey" FOREIGN KEY ("family_id") REFERENCES "trains"."types"("id") ON DELETE SET NULL;--> statement-breakpoint
|
||||
-- Hand-written: updated_at triggers, grants, GUI registration. Data comes from scripts/trains-import.ts and scripts/trains-photos.ts.
|
||||
DO $$
|
||||
DECLARE t text;
|
||||
BEGIN
|
||||
FOREACH t IN ARRAY ARRAY['makers','operators','types'] LOOP
|
||||
EXECUTE format('CREATE TRIGGER touch_updated_at BEFORE UPDATE ON trains.%I FOR EACH ROW EXECUTE FUNCTION meta.touch_updated_at()', t);
|
||||
END LOOP;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'personal_app') THEN
|
||||
GRANT USAGE ON SCHEMA trains TO personal_app;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA trains TO personal_app;
|
||||
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA trains TO personal_app;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA trains GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO personal_app;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA trains GRANT USAGE, SELECT ON SEQUENCES TO personal_app;
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'personal_ro') THEN
|
||||
GRANT USAGE ON SCHEMA trains TO personal_ro;
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA trains TO personal_ro;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA trains GRANT SELECT ON TABLES TO personal_ro;
|
||||
END IF;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('meta.tables') IS NOT NULL THEN
|
||||
INSERT INTO meta.tables (schema_name, table_name, slug, display_name, kind, editable, has_done, sort_order)
|
||||
VALUES ('trains','makers','trains-makers','Train makers','core',false,false,1000),
|
||||
('trains','operators','trains-operators','Train operators','core',false,false,1000),
|
||||
('trains','types','trains-types','Train types','core',false,false,1000),
|
||||
('trains','photos','trains-photos','Train photos','core',false,false,1000)
|
||||
ON CONFLICT DO NOTHING;
|
||||
IF has_function_privilege('meta.sync(integer)', 'EXECUTE') THEN
|
||||
PERFORM meta.sync();
|
||||
END IF;
|
||||
END IF;
|
||||
END $$;
|
||||
25347
drizzle/20261024232143_trains/snapshot.json
Normal file
25347
drizzle/20261024232143_trains/snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user