Validierung von Nutzereingaben über mehrere Rules
Wenn Nutzereingaben überprüft werden sollen, bieten sich an, eine Regel zu schreiben, die im Fehlerfall bestimmte Meldungen an kvwmap zurück gibt. Das entsprechende Verfahren der Validierung von Nutzereingaben ist in der Admin-Doku gut erklärt. Was jedoch, wenn Eingaben in mehreren Attributen geprüft werden müssen? Man kann mehrere Regeln schreiben, aber: Nur die letzte der Regeln, die angewendet werden, löst (möglicherweise) den "DO INSTEAD"-Fall aus. Hat aber bereits eine andere Regel vorher ein Problem gemeldet, bekommt kvwmap davon nichts mit.
Lösungsvorschlag: Der Text, der beim "DO INSTEAD" übergeben werden soll, wird in eine "Zwischentabelle" geschrieben. Eine letzte Regel prüft, ob in dieser "Zwischentabelle" was drin steht und übergibt das an kvwmap. Es steht immer nur der zuletzt erzeugte Hinweistext darin. Das macht aber nichts, denn kvwmap kann ja auch nur einen Text ausgeben.
Diese "Zwischentabelle" ist denkbar einfach gestrickt:
CREATE TABLE tabellenpruefung ( tabelle character varying, hinweis character varying, message character varying ) WITH ( OIDS=TRUE );
Diese Tabelle kann in jedem Schema platziert werden und dient allen Tabellen im Schema gemeinsam. Im Attribut "tabelle" muss einfach nur einmalig jeder Tabellenname eingetragen werden, dessen Regeln hierhin schreiben sollen.
Angenommen, es gibt eine Tabelle "tabelle_1" mit zwei Attributen "attribut1" und "attribut2", die bei der Eingabe bzw. bei der Änderung überprüft werden sollen. Damit hätten wir schon mal 2 Rules für INSERT-Prüfungen und 2 Rules für UPDATE-Prüfungen. Diese füllen nun im "DO INSTEAD"-Fall die Tabelle "tabellenpruefung":
Regel 1:
CREATE OR REPLACE RULE insert_pruefung_attribut1 AS ON INSERT TO tabelle_1 WHERE < ... > DO INSTEAD UPDATE tabellenpruefung SET hinweis = 'Das ist bei Attribut 1 nicht erlaubt', message = 'error' WHERE tabellenpruefung.tabelle = 'tabelle_1';
Regel 2:
CREATE OR REPLACE RULE insert_pruefung_attribut2 AS ON INSERT TO tabelle_1 WHERE < ... > DO INSTEAD UPDATE tabellenpruefung SET hinweis = 'Das ist bei Attribut 2 nicht erlaubt', message = 'error' WHERE tabellenpruefung.tabelle = 'tabelle_1';
Regel 3:
CREATE OR REPLACE RULE update_pruefung_attribut1 AS ON UPDATE TO tabelle_1 WHERE < ... > DO INSTEAD UPDATE tabellenpruefung SET hinweis = 'Das ist bei Attribut 1 nicht erlaubt', message = 'error' WHERE tabellenpruefung.tabelle = 'tabelle_1';
Regel 4:
CREATE OR REPLACE RULE update_pruefung_attribut2 AS ON UPDATE TO tabelle_1 WHERE < ... > DO INSTEAD UPDATE tabellenpruefung SET hinweis = 'Das ist bei Attribut 2 nicht erlaubt', message = 'error' WHERE tabellenpruefung.tabelle = 'tabelle_1';
Damit wird die jeweils letzte Meldung festgehalten. Jetzt fehlt noch jeweils eine letzte Regel für INSERT und UPDATE, die den Inhalt der Meldung an kvwmap weitergibt. Da Regeln alphanumerisch sortiert abgearbeitet werden, fangen diese Regeln mit "z" an:
Regel für INSERT:
CREATE OR REPLACE RULE z_hinweis_insert AS ON INSERT TO tabelle_1 WHERE ( SELECT true AS bool FROM tabellenpruefung WHERE tabellenpruefung.tabelle = 'tabelle_1' AND tabellenpruefung.hinweis <> '' ) DO ( SELECT tabellenpruefung.hinweis, tabellenpruefung.message as msg_type FROM tabellenpruefung WHERE tabellenpruefung.tabelle = 'tabelle_1'; UPDATE tabellenpruefung SET hinweis = NULL WHERE tabellenpruefung.tabelle = 'tabelle_1'; );
Regel für UPDATE:
CREATE OR REPLACE RULE z_hinweis_update AS ON UPDATE TO tabelle_1 WHERE ( SELECT true AS bool FROM tabellenpruefung WHERE tabellenpruefung.tabelle = 'tabelle_1' AND tabellenpruefung.hinweis <> '' ) DO ( SELECT tabellenpruefung.hinweis, tabellenpruefung.message as msg_type FROM tabellenpruefung WHERE tabellenpruefung.tabelle = 'tabelle_1'; UPDATE tabellenpruefung SET hinweis = NULL WHERE tabellenpruefung.tabelle = 'tabelle_1'; );
Damit ist der (letzte) Hinweis an kvwmap übergeben und die "tabellenprüfung" wieder leer für den nächsten Versuch des Nutzers.