CREATE EXTENSION IF NOT EXISTS postgis; CREATE TABLE IF NOT EXISTS bands ( id BIGSERIAL PRIMARY KEY, ma_id BIGINT UNIQUE NOT NULL, name TEXT NOT NULL, country TEXT, location_text TEXT, status TEXT, genre TEXT, formed_year INT, lat DOUBLE PRECISION, lon DOUBLE PRECISION, geom GEOGRAPHY(Point, 4326), data JSONB NOT NULL DEFAULT '{}'::jsonb, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE OR REPLACE FUNCTION bands_set_geom() RETURNS trigger AS $$ BEGIN IF NEW.lat IS NOT NULL AND NEW.lon IS NOT NULL THEN NEW.geom := ST_SetSRID(ST_MakePoint(NEW.lon, NEW.lat), 4326)::geography; ELSE NEW.geom := NULL; END IF; NEW.updated_at := now(); RETURN NEW; END; $$ LANGUAGE plpgsql; DROP TRIGGER IF EXISTS trg_bands_set_geom ON bands; CREATE TRIGGER trg_bands_set_geom BEFORE INSERT OR UPDATE OF lat, lon ON bands FOR EACH ROW EXECUTE FUNCTION bands_set_geom(); CREATE INDEX IF NOT EXISTS idx_bands_country ON bands (country); CREATE INDEX IF NOT EXISTS idx_bands_status ON bands (status); CREATE INDEX IF NOT EXISTS idx_bands_genre ON bands (genre); CREATE INDEX IF NOT EXISTS idx_bands_geom ON bands USING GIST (geom); CREATE INDEX IF NOT EXISTS idx_bands_data_gin ON bands USING GIN (data);