App-Dochazka-REST
view release on metacpan or search on metacpan
config/sql/dbinit_Config.pm view on Meta::CPAN
) AS tblalias
WHERE schedule_changed = 't'
$$ LANGUAGE sql IMMUTABLE#,
q#-- wrapper function to get priv as of current timestamp
CREATE OR REPLACE FUNCTION current_priv (INTEGER)
RETURNS privilege AS $$
SELECT priv_at_timestamp($1, current_timestamp)
$$ LANGUAGE sql IMMUTABLE#,
q#-- wrapper function to get schedule as of current timestamp
CREATE OR REPLACE FUNCTION current_schedule (INTEGER)
RETURNS integer AS $$
SELECT sid_at_timestamp($1, current_timestamp)
$$ LANGUAGE sql IMMUTABLE#,
# the 'activities' table
q/-- activities
CREATE TABLE activities (
aid serial PRIMARY KEY,
code varchar(32) UNIQUE NOT NULL,
long_desc text,
remark text,
disabled boolean NOT NULL,
stamp json,
CONSTRAINT kosher_code CHECK (code ~* '^[[:alnum:]_][[:alnum:]_-]+$')
)/,
q/-- trigger function to make 'aid' field immutable
CREATE OR REPLACE FUNCTION aid_immutable() RETURNS trigger AS $IMM$
BEGIN
IF OLD.aid <> NEW.aid THEN
RAISE EXCEPTION 'activities.aid field is immutable';
END IF;
RETURN NEW;
END;
$IMM$ LANGUAGE plpgsql/,
q/-- trigger the trigger
CREATE TRIGGER no_aid_update BEFORE UPDATE ON activities
FOR EACH ROW EXECUTE PROCEDURE aid_immutable()/,
q/CREATE OR REPLACE FUNCTION code_to_upper() RETURNS trigger AS $$
BEGIN
NEW.code = upper(NEW.code);
RETURN NEW;
END;
$$ LANGUAGE plpgsql IMMUTABLE/,
q/CREATE TRIGGER code_to_upper BEFORE INSERT OR UPDATE ON activities
FOR EACH ROW EXECUTE PROCEDURE code_to_upper()/,
q/CREATE TRIGGER disabled_to_zero BEFORE INSERT OR UPDATE ON activities
FOR EACH ROW EXECUTE PROCEDURE disabled_to_zero()/,
# the 'components' table
q#-- components
CREATE TABLE components (
cid serial PRIMARY KEY,
path varchar(2048) UNIQUE NOT NULL,
source text NOT NULL,
acl varchar(16) NOT NULL,
validations text,
CONSTRAINT kosher_path CHECK (path ~* '^[[:alnum:]_.][[:alnum:]_/.-]+$')
)#,
q/-- trigger function to make 'cid' field immutable
CREATE OR REPLACE FUNCTION cid_immutable() RETURNS trigger AS $IMM$
BEGIN
IF OLD.cid <> NEW.cid THEN
RAISE EXCEPTION 'components.cid field is immutable';
END IF;
RETURN NEW;
END;
$IMM$ LANGUAGE plpgsql/,
q/-- trigger the trigger
CREATE TRIGGER no_cid_update BEFORE UPDATE ON components
FOR EACH ROW EXECUTE PROCEDURE cid_immutable()/,
# the 'intervals' table
q/-- intervals
CREATE TABLE IF NOT EXISTS intervals (
iid serial PRIMARY KEY,
eid integer REFERENCES employees (eid) NOT NULL,
aid integer REFERENCES activities (aid) NOT NULL,
intvl tstzrange NOT NULL,
long_desc text,
remark text,
stamp json,
EXCLUDE USING gist (eid WITH =, intvl WITH &&)
)/,
q#-- trigger function to ensure that a privhistory/schedhistory record
-- does not fall within an existing attendance interval
CREATE OR REPLACE FUNCTION history_policy() RETURNS trigger AS $$
DECLARE
intvl_count integer;
BEGIN
-- the EID is NEW.eid, effective timestamptz is NEW.effective
SELECT count(*) FROM intervals INTO intvl_count
WHERE eid=NEW.eid AND intvl @> NEW.effective;
IF intvl_count > 0 THEN
RAISE EXCEPTION 'effective timestamp conflicts with existing attendance interval';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql IMMUTABLE#,
q/-- trigger the trigger
CREATE TRIGGER no_intvl_conflict BEFORE INSERT OR UPDATE ON privhistory
FOR EACH ROW EXECUTE PROCEDURE history_policy()/,
q/-- trigger the trigger
CREATE TRIGGER no_intvl_conflict BEFORE INSERT OR UPDATE ON schedhistory
FOR EACH ROW EXECUTE PROCEDURE history_policy()/,
q/-- trigger function to enforce policy that an interval cannot come into
-- existence unless the employee has only a single privlevel throughout
-- the entire interval and that privlevel is either 'active' or 'admin'
CREATE OR REPLACE FUNCTION priv_policy() RETURNS trigger AS $$
DECLARE
priv text;
pr_count integer;
BEGIN
-- the EID is NEW.eid, interval is NEW.intvl
-- 1. is there a non-passerbu privilege at the beginning of the interval?
SELECT priv_at_timestamp(NEW.eid, lower(NEW.intvl)) INTO priv;
IF priv = 'passerby' OR priv = 'inactive' THEN
RAISE EXCEPTION 'insufficient privileges: check employee privhistory';
END IF;
-- 2. are there any privhistory records during the interval?
SELECT count(*) FROM privhistory INTO pr_count
WHERE eid=NEW.eid AND effective >= lower(NEW.intvl) AND effective <= upper(NEW.intvl);
IF pr_count > 0 THEN
RAISE EXCEPTION 'ambiguous privilege status: check employee privhistory';
END IF;
RETURN NEW;
( run in 0.397 second using v1.01-cache-2.11-cpan-39bf76dae61 )