-- migrate:up -- A unit (an AGEPoly committee or commission) is a row of its own rather than a -- string repeated on every membership: it can be renamed, and per-unit data can -- be hung off it later without touching anything else. `name` is the Whiskey -- group name and stays the key we match the provider on. CREATE TABLE units ( id SERIAL PRIMARY KEY, name TEXT NOT NULL UNIQUE ); -- Everything that already named a unit becomes a row INSERT INTO units ("name") SELECT DISTINCT unit_name FROM units_users UNION SELECT DISTINCT unit FROM reservations ON CONFLICT ("name") DO NOTHING; -- units_users: unit_name -> unit_id ALTER TABLE units_users ADD COLUMN unit_id INTEGER REFERENCES units (id) ON DELETE CASCADE; UPDATE units_users uu SET unit_id = u.id FROM units u WHERE u."name" = uu.unit_name; ALTER TABLE units_users ALTER COLUMN unit_id SET NOT NULL; ALTER TABLE units_users DROP CONSTRAINT units_users_pkey; ALTER TABLE units_users DROP COLUMN unit_name; ALTER TABLE units_users ADD PRIMARY KEY (unit_id, user_id); CREATE INDEX units_users_user_id_idx ON units_users (user_id); -- reservations: unit -> unit_id ALTER TABLE reservations ADD COLUMN unit_id INTEGER REFERENCES units (id); UPDATE reservations r SET unit_id = u.id FROM units u WHERE u."name" = r.unit; ALTER TABLE reservations ALTER COLUMN unit_id SET NOT NULL; DROP INDEX reservations_unit_idx; ALTER TABLE reservations DROP COLUMN unit; CREATE INDEX reservations_unit_id_idx ON reservations (unit_id); -- migrate:down ALTER TABLE reservations ADD COLUMN unit TEXT; UPDATE reservations r SET unit = u."name" FROM units u WHERE u.id = r.unit_id; ALTER TABLE reservations ALTER COLUMN unit SET NOT NULL; DROP INDEX reservations_unit_id_idx; ALTER TABLE reservations DROP COLUMN unit_id; CREATE INDEX reservations_unit_idx ON reservations (unit); ALTER TABLE units_users ADD COLUMN unit_name TEXT; UPDATE units_users uu SET unit_name = u."name" FROM units u WHERE u.id = uu.unit_id; ALTER TABLE units_users ALTER COLUMN unit_name SET NOT NULL; ALTER TABLE units_users DROP CONSTRAINT units_users_pkey; DROP INDEX units_users_user_id_idx; ALTER TABLE units_users DROP COLUMN unit_id; ALTER TABLE units_users ADD PRIMARY KEY (user_id, unit_name); CREATE INDEX units_users_unit_name_idx ON units_users (unit_name); DROP TABLE units;