App-Dochazka-REST
view release on metacpan or search on metacpan
config/sql/dbinit_Config.pm view on Meta::CPAN
FOR EACH ROW EXECUTE PROCEDURE valid_intvl()/,
q/CREATE TRIGGER a2_interval_not_too_future BEFORE INSERT OR UPDATE ON intervals
FOR EACH ROW EXECUTE PROCEDURE not_too_future()/,
q/CREATE TRIGGER a3_no_iid_update BEFORE UPDATE ON intervals
FOR EACH ROW EXECUTE PROCEDURE iid_immutable()/,
# the 'locks' table
q/-- locks
CREATE TABLE locks (
lid serial PRIMARY KEY,
eid integer REFERENCES Employees (EID),
intvl tstzrange NOT NULL,
remark text,
stamp json,
EXCLUDE USING gist (eid WITH =, intvl WITH &&)
)/,
q/-- trigger function to make 'lid' field immutable
CREATE OR REPLACE FUNCTION lid_immutable() RETURNS trigger AS $IMM$
BEGIN
IF OLD.lid <> NEW.lid THEN
RAISE EXCEPTION 'locks.lid field is immutable';
END IF;
RETURN NEW;
END;
$IMM$ LANGUAGE plpgsql/,
q/CREATE TRIGGER a1_lock_valid_intvl BEFORE INSERT OR UPDATE ON locks
FOR EACH ROW EXECUTE PROCEDURE valid_intvl()/,
q/CREATE TRIGGER a2_lock_not_too_future BEFORE INSERT OR UPDATE ON locks
FOR EACH ROW EXECUTE PROCEDURE not_too_future()/,
q/-- trigger the trigger
CREATE TRIGGER a3_no_lid_update BEFORE UPDATE ON locks
FOR EACH ROW EXECUTE PROCEDURE lid_immutable()/,
q/-- lock lookup trigger for intervals table
CREATE OR REPLACE FUNCTION no_lock_conflict() RETURNS trigger AS $IMM$
DECLARE
this_eid integer;
this_intvl tstzrange;
lock_count integer;
BEGIN
IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
-- EID and tsrange are NEW.eid and NEW.intvl, respectively
this_eid := NEW.eid;
this_intvl := NEW.intvl;
ELSE
-- TG_OP = 'DELETE'
this_eid := OLD.eid;
this_intvl := OLD.intvl;
END IF;
SELECT count(*) INTO lock_count FROM locks WHERE eid=this_eid AND intvl && this_intvl;
IF lock_count > 0 THEN
RAISE EXCEPTION 'interval is locked';
END IF;
IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
RETURN NEW;
ELSE
RETURN OLD;
END IF;
END;
$IMM$ LANGUAGE plpgsql/,
q/CREATE TRIGGER intvl_not_locked BEFORE INSERT OR UPDATE OR DELETE ON intervals
FOR EACH ROW EXECUTE PROCEDURE no_lock_conflict()/,
# the 'tempintvls' table and associated plumbing
q/CREATE SEQUENCE temp_intvl_seq/,
q/COMMENT ON SEQUENCE temp_intvl_seq IS 'sequence guaranteeing that each set of temporary intervals will have a unique identifier'/,
q/-- tempintvls
-- for staging fillup intervals
CREATE TABLE IF NOT EXISTS tempintvls (
int_id serial PRIMARY KEY,
tiid integer NOT NULL,
intvl tstzrange NOT NULL
)/,
q/CREATE TRIGGER a2_interval_not_too_future BEFORE INSERT OR UPDATE ON tempintvls
FOR EACH ROW EXECUTE PROCEDURE not_too_future()/,
# create 'root' and 'demo' employees
q/-- insert root employee into employees table and grant admin
-- privilege to the resulting EID
WITH cte AS (
INSERT INTO employees (nick, fullname, email, passhash, salt, remark)
VALUES ('root', 'Root Immutable', 'root@site.org', '82100e9bd4757883b4627b3bafc9389663e7be7f76a1273508a7a617c9dcd917428a7c44c6089477c8e1d13e924343051563d2d426617b695f3a3bff74e7c003', '341755e03e1f163f829785d1d19eab9dee5135c0', 'dbinit')
RETURNING eid
)
INSERT INTO privhistory (eid, priv, effective, remark)
SELECT eid, 'admin', '1892-01-01', 'IMMUTABLE' FROM cte
/,
q/-- insert demo employee into employees table
INSERT INTO employees (nick, fullname, email, passhash, salt, remark)
VALUES ('demo', 'Demo Employee', 'demo@dochazka.site', '4962cc89c646261a887219795083a02b899ea960cd84a234444b7342e2222eb22dc06f5db9c71681074859469fdc0abd53e3f1f47a381617b59f4b31608e24b1', '82702be8d9810d8fba774dcb7c9f68f39d0933e8', 'dbinit')
RETURNING eid
/,
# DEFAULT schedule
q/-- insert DEFAULT schedule into schedules table
INSERT INTO schedules (scode, schedule)
VALUES ('DEFAULT', '[{"high_dow":"MON","high_time":"12:00","low_dow":"MON","low_time":"08:00"},{"high_dow":"MON","high_time":"16:30","low_dow":"MON","low_time":"12:30"},{"high_dow":"TUE","high_time":"12:00","low_dow":"TUE","low_time":"08:00"},{...
/,
]);
# DBINIT_SELECT_EID_OF
# after create_tables (REST.pm) executes the above list of SQL
# statements, it needs to find the EID of the root and demo employees
#
set('DBINIT_SELECT_EID_OF', q/
SELECT eid FROM employees WHERE nick = ?/);
# DBINIT_MAKE_ROOT_IMMUTABLE
# after finding the EID of the root employee, create_tables executes
# another batch of SQL statements to make root immutable
# (for more information, see t/002-root.t)
#
set('DBINIT_MAKE_ROOT_IMMUTABLE', [
( run in 0.691 second using v1.01-cache-2.11-cpan-e93a5daba3e )