li7y/migrations/20240705104056_create_item_class.up.sql

48 lines
1.6 KiB
MySQL
Raw Permalink Normal View History

2024-07-07 13:48:31 +02:00
-- SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
-- generic is a category of products (like CR2032 3V battery)
-- or a product where details do not matter (like USB-A to USB-Micro-B cable 1m)
-- specific is a concrete model of product (like Panasonic DL2032)
CREATE TYPE item_class_type AS ENUM ('generic', 'specific');
CREATE TABLE item_classes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR NOT NULL,
type item_class_type NOT NULL DEFAULT 'generic',
parent UUID REFERENCES item_classes(id),
CONSTRAINT parent_only_for_specific CHECK (type = 'generic' AND parent IS NULL OR type = 'specific' AND parent IS NOT NULL)
);
INSERT INTO item_classes (id, name) values ('afd0e9bd-c4df-425e-8af4-6b5b0326a4ae', 'Default Item Class');
ALTER TABLE items
ADD class UUID NOT NULL REFERENCES item_classes(id) DEFAULT 'afd0e9bd-c4df-425e-8af4-6b5b0326a4ae';
ALTER TABLE items
ALTER class DROP DEFAULT;
DELETE FROM item_classes
WHERE (id = 'afd0e9bd-c4df-425e-8af4-6b5b0326a4ae'
AND NOT EXISTS (SELECT 1 FROM items WHERE class = 'afd0e9bd-c4df-425e-8af4-6b5b0326a4ae' LIMIT 1));
CREATE FUNCTION check_item_class_parent()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.parent IS NULL THEN
RETURN NEW;
END IF;
IF (SELECT type FROM item_classes WHERE id = NEW.parent) = 'generic' THEN
RETURN NEW;
END IF;
RAISE EXCEPTION 'Specific item classes may only have a generic parent (to avoid recursion)';
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER prevent_item_class_recursion
BEFORE INSERT OR UPDATE ON item_classes
FOR EACH ROW
EXECUTE FUNCTION check_item_class_parent();