Mercurial > gemma
changeset 4044:f42f7f7eb81f historization_ng
WIP: Finished remove references to gauge validity in DB schema.
author | Sascha Wilde <wilde@intevation.de> |
---|---|
date | Wed, 24 Jul 2019 13:00:37 +0200 |
parents | fbd7c012f10c |
children | 12e3933b2050 |
files | schema/gemma.sql schema/updates/1100/01.remove_gauge_validity_refs.sql |
diffstat | 2 files changed, 79 insertions(+), 132 deletions(-) [+] |
line wrap: on
line diff
--- a/schema/gemma.sql Wed Jul 24 11:16:38 2019 +0200 +++ b/schema/gemma.sql Wed Jul 24 13:00:37 2019 +0200 @@ -113,84 +113,7 @@ $$ LANGUAGE plpgsql; --- Trigger functions to be used as statement-level AFTER triggers, --- associating time-based referencing objects to matching version -CREATE OR REPLACE FUNCTION move_gauge_referencing() RETURNS trigger AS -$$ -DECLARE - new_bn int; - new_bns int[]; -BEGIN - -- Avoid unnecessary execution ON UPDATE if validity did not change - IF OLD IS NULL OR NEW.validity <> OLD.validity THEN - UPDATE waterway.gauge_measurements - SET validity = NEW.validity - WHERE location = NEW.location - AND measure_date <@ NEW.validity; - - -- build bottleneck validities from intersections with gauge validities - FOR new_bn IN - INSERT INTO waterway.bottlenecks ( - bottleneck_id, - validity, - gauge_location, - gauge_validity, - objnam, - nobjnm, - stretch, - area, - rb, - lb, - responsible_country, - revisiting_time, - limiting, - date_info, - source_organization, - staging_done - ) SELECT - b.bottleneck_id, - -- Anticipate non-intersecting gauge validities: - b.validity * CASE WHEN g.validity = NEW.validity - THEN NEW.validity ELSE g.validity - NEW.validity END, - b.gauge_location, - g.validity, - b.objnam, - b.nobjnm, - b.stretch, - b.area, - b.rb, - b.lb, - b.responsible_country, - b.revisiting_time, - b.limiting, - b.date_info, - b.source_organization, - b.staging_done - FROM waterway.bottlenecks b JOIN waterway.gauges g - ON b.gauge_location = g.location - WHERE b.gauge_location = NEW.location - AND b.validity && NEW.validity - -- Avoid duplicate intersection results: - AND NOT (b.validity <@ NEW.validity - AND g.validity <> NEW.validity) - ON CONFLICT (bottleneck_id, validity) DO UPDATE SET - -- Associate to new matching gauge version - gauge_validity = EXCLUDED.gauge_validity - RETURNING id - LOOP - new_bns = new_bns || new_bn; - END LOOP; - -- Delete bottleneck versions superseded by new intersections: - DELETE FROM waterway.bottlenecks - WHERE gauge_location = NEW.location - AND validity && NEW.validity - AND id <> ALL(new_bns); - END IF; - RETURN NULL; -- ignored -END; -$$ -LANGUAGE plpgsql; - +-- REMOVE ME: CREATE OR REPLACE FUNCTION move_bottleneck_referencing() RETURNS trigger AS $$ BEGIN @@ -485,9 +408,6 @@ CREATE UNIQUE INDEX gauges_erased_unique_constraint ON gauges (location) WHERE NOT erased - -- Associate referencing objects to matching gauge version - CREATE TRIGGER move_referencing AFTER INSERT OR UPDATE OF validity - ON gauges FOR EACH ROW EXECUTE FUNCTION move_gauge_referencing() CREATE TABLE gauges_reference_water_levels ( location isrs NOT NULL, @@ -503,12 +423,7 @@ CREATE TABLE gauge_measurements ( id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, location isrs NOT NULL, - validity tstzrange NOT NULL, - CONSTRAINT gauge_key - FOREIGN KEY (location, validity) REFERENCES gauges - ON UPDATE CASCADE, measure_date timestamp with time zone NOT NULL, - CHECK (measure_date <@ validity), country_code char(2) NOT NULL REFERENCES countries, sender varchar NOT NULL, -- "from" element from NtS response language_code varchar NOT NULL REFERENCES language_codes, @@ -526,12 +441,7 @@ CREATE TABLE gauge_predictions ( location isrs NOT NULL, - validity tstzrange NOT NULL, - CONSTRAINT gauge_key - FOREIGN KEY (location, validity) REFERENCES gauges - ON UPDATE CASCADE, measure_date timestamp with time zone NOT NULL, - CHECK (measure_date >= lower(validity)), country_code char(2) NOT NULL REFERENCES countries, sender varchar NOT NULL, -- "from" element from NtS response language_code varchar NOT NULL REFERENCES language_codes,
--- a/schema/updates/1100/01.remove_gauge_validity_refs.sql Wed Jul 24 11:16:38 2019 +0200 +++ b/schema/updates/1100/01.remove_gauge_validity_refs.sql Wed Jul 24 13:00:37 2019 +0200 @@ -11,6 +11,54 @@ -- Author(s): -- * Sascha Wilde <sascha.wilde@intevation.de> +-- +-- CONSTRAINT FUNCTIONS +-- + +-- We still want to ensure, that there is at least a valid gauge at +-- any time of the referencing objects validity. To ensure this we +-- need a trigger constraint: +CREATE OR REPLACE FUNCTION check_valid_gauge() RETURNS trigger AS +$$ +DECLARE + -- FIXME: I'm using text for the isrs code and cast it on demand. + -- If someone is able to get it to work with isrs or isrs_base as + -- type, feel free to show me how its done... ;-) [sw] + referenced_gauge text; + new_validity tstzrange; +BEGIN + EXECUTE format('SELECT $1.%I', TG_ARGV[0]) + INTO referenced_gauge + USING NEW; + EXECUTE format('SELECT $1.%I', TG_ARGV[1]) + INTO new_validity + USING NEW; + IF EXISTS ( SELECT * FROM waterway.gauges + WHERE location = referenced_gauge::isrs + AND validity && new_validity ) + THEN + RETURN NEW; + ELSE + RAISE EXCEPTION + 'new row for relation "%" violates constraint trigger "%"', + TG_TABLE_NAME, TG_NAME + USING + DETAIL = format('No matching gauge %s found.', + isrs_AsText(referenced_gauge::isrs)), + ERRCODE = 23505, + SCHEMA = TG_TABLE_SCHEMA, + TABLE = TG_TABLE_NAME, + COLUMN = TG_ARGV[0], + CONSTRAINT = TG_NAME; + END IF; +END; +$$ +LANGUAGE plpgsql; + + +-- +-- BOTTLENECKS +-- -- Dynamic version of bottlenecks_geoserver view: -- Instead of a static reference to a specific gauge data set via @@ -63,48 +111,37 @@ -- hard reference to the gauges vaidity: ALTER TABLE waterway.bottlenecks DROP IF EXISTS gauge_validity; --- We still want to ensure, that there is at least a valid gauge at --- any time of the bottleneck validity. To ensure this we need a --- trigger constraint: -CREATE OR REPLACE FUNCTION check_valid_gauge() RETURNS trigger AS -$$ -DECLARE - -- FIXME: I'm using text for the isrs code and cast it on demand. - -- If someone is able to get it to work with isrs or isrs_base as - -- type, feel free to show me how its done... ;-) [sw] - referenced_gauge text; - new_validity tstzrange; -BEGIN - EXECUTE format('SELECT $1.%I', TG_ARGV[0]) - INTO referenced_gauge - USING NEW; - EXECUTE format('SELECT $1.%I', TG_ARGV[1]) - INTO new_validity - USING NEW; - IF EXISTS ( SELECT * FROM waterway.gauges - WHERE location = referenced_gauge::isrs - AND validity && new_validity ) - THEN - RETURN NEW; - ELSE - RAISE EXCEPTION - 'new row for relation "%" violates constraint trigger "%"', - TG_TABLE_NAME, TG_NAME - USING - DETAIL = format('No matching gauge %s found.', - isrs_AsText(referenced_gauge::isrs)), - ERRCODE = 23505, - SCHEMA = TG_TABLE_SCHEMA, - TABLE = TG_TABLE_NAME, - COLUMN = TG_ARGV[0], - CONSTRAINT = TG_NAME; - END IF; -END; -$$ -LANGUAGE plpgsql; - DROP TRIGGER IF EXISTS waterway_bottlenecks_reference_gauge ON waterway.bottlenecks; CREATE CONSTRAINT TRIGGER waterway_bottlenecks_reference_gauge AFTER INSERT OR UPDATE OF gauge_location ON waterway.bottlenecks - FOR EACH ROW EXECUTE FUNCTION check_valid_gauge('gauge_location','validity') + FOR EACH ROW EXECUTE FUNCTION check_valid_gauge('gauge_location','validity'); + + +-- +-- GAUGE MEASUREMENTS +-- + +-- As we resolve the correct gauge data to use on runtime, we drop the +-- hard reference to the gauges vaidity: +ALTER TABLE waterway.gauge_measurements DROP IF EXISTS validity; +ALTER TABLE waterway.gauge_predictions DROP IF EXISTS validity; + + +-- +-- DROP NO LONGER NEEDED TRIGGER FUNCTION +-- + +-- This used to update foreign key references. As these references no +-- longer exist we dont need this magic any more... +DROP TRIGGER IF EXISTS move_referencing ON waterway.gauges; +DROP FUNCTION IF EXISTS move_gauge_referencing(); + + +-- +-- ADDITIONAL NOTES +-- +-- waterway.gauges_reference_water_levels still has a hard foreign key +-- reference to waterway.gauges. As this data actually is part of the +-- gauges data and the seperation in two tables is exclusively due to +-- schema modeling we leave it alone!