wildlife: schema and migration
All checks were successful
Deploy production / deploy (push) Successful in 1m4s
All checks were successful
Deploy production / deploy (push) Successful in 1m4s
This commit is contained in:
122
drizzle/20261024215408_wildlife/migration.sql
Normal file
122
drizzle/20261024215408_wildlife/migration.sql
Normal file
@@ -0,0 +1,122 @@
|
||||
CREATE SCHEMA "wildlife";
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "wildlife"."groups" (
|
||||
"id" serial PRIMARY KEY,
|
||||
"slug" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"name_nl" text NOT NULL,
|
||||
"emoji" text NOT NULL,
|
||||
"sort_order" smallint DEFAULT 0 NOT NULL,
|
||||
"species_count" integer DEFAULT 0 NOT NULL,
|
||||
"nl_count" integer DEFAULT 0 NOT NULL,
|
||||
"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 "wildlife"."photos" (
|
||||
"id" serial PRIMARY KEY,
|
||||
"species_id" integer NOT NULL,
|
||||
"position" smallint NOT NULL,
|
||||
"kind" text NOT NULL,
|
||||
"photo_id" integer NOT NULL,
|
||||
"url" text NOT NULL,
|
||||
"width" integer,
|
||||
"height" integer,
|
||||
"author" text,
|
||||
"license" text NOT NULL,
|
||||
"page_url" text,
|
||||
"place" text
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "wildlife"."species" (
|
||||
"id" serial PRIMARY KEY,
|
||||
"dex" integer NOT NULL,
|
||||
"group_id" integer NOT NULL,
|
||||
"slug" text NOT NULL,
|
||||
"scientific_name" text NOT NULL,
|
||||
"name_en" text,
|
||||
"name_nl" text,
|
||||
"search" text NOT NULL,
|
||||
"inat_id" integer NOT NULL,
|
||||
"gbif_key" integer,
|
||||
"wikidata" text,
|
||||
"wikipedia_en" text,
|
||||
"wikipedia_nl" text,
|
||||
"class_name" text,
|
||||
"order_name" text,
|
||||
"family_name" text,
|
||||
"iucn" text,
|
||||
"nl_status" text,
|
||||
"nl_establishment" text,
|
||||
"extinct" boolean DEFAULT false NOT NULL,
|
||||
"nl_obs" integer DEFAULT 0 NOT NULL,
|
||||
"europe_obs" integer DEFAULT 0 NOT NULL,
|
||||
"world_obs" integer DEFAULT 0 NOT NULL,
|
||||
"gbif_nl" integer,
|
||||
"scope" text NOT NULL,
|
||||
"summary" text,
|
||||
"summary_nl" text,
|
||||
"facts" text[] DEFAULT '{}'::text[] NOT NULL,
|
||||
"mass_kg" real,
|
||||
"length_m" real,
|
||||
"lifespan_years" real,
|
||||
"named_year" smallint,
|
||||
"named_by" 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 "groups_slug_key" ON "wildlife"."groups" ("slug");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "photos_species_position_key" ON "wildlife"."photos" ("species_id","position");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "photos_species_photo_key" ON "wildlife"."photos" ("species_id","photo_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "species_dex_key" ON "wildlife"."species" ("dex");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "species_inat_key" ON "wildlife"."species" ("inat_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "species_slug_key" ON "wildlife"."species" ("slug");--> statement-breakpoint
|
||||
CREATE INDEX "species_group_idx" ON "wildlife"."species" ("group_id");--> statement-breakpoint
|
||||
CREATE INDEX "species_nl_obs_idx" ON "wildlife"."species" ("nl_obs");--> statement-breakpoint
|
||||
CREATE INDEX "species_search_trgm_idx" ON "wildlife"."species" USING gin ("search" public.gin_trgm_ops);--> statement-breakpoint
|
||||
ALTER TABLE "wildlife"."photos" ADD CONSTRAINT "photos_species_id_species_id_fkey" FOREIGN KEY ("species_id") REFERENCES "wildlife"."species"("id") ON DELETE CASCADE;--> statement-breakpoint
|
||||
ALTER TABLE "wildlife"."species" ADD CONSTRAINT "species_group_id_groups_id_fkey" FOREIGN KEY ("group_id") REFERENCES "wildlife"."groups"("id") ON DELETE CASCADE;--> statement-breakpoint
|
||||
-- Hand-written: updated_at triggers, grants, GUI registration. Data comes from scripts/wildlife-import.ts and scripts/wildlife-photos.ts.
|
||||
DO $$
|
||||
DECLARE t text;
|
||||
BEGIN
|
||||
FOREACH t IN ARRAY ARRAY['groups','species'] LOOP
|
||||
EXECUTE format('CREATE TRIGGER touch_updated_at BEFORE UPDATE ON wildlife.%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 wildlife TO personal_app;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA wildlife TO personal_app;
|
||||
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA wildlife TO personal_app;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA wildlife GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO personal_app;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA wildlife 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 wildlife TO personal_ro;
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA wildlife TO personal_ro;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA wildlife 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 ('wildlife','groups','wildlife-groups','Wildlife groups','core',false,false,1000),
|
||||
('wildlife','species','wildlife-species','Wildlife species','core',false,false,1000),
|
||||
('wildlife','photos','wildlife-photos','Wildlife 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 $$;
|
||||
Reference in New Issue
Block a user