initial commit
This commit is contained in:
17 files changed
+1277
No files matched your search
@@ -0,0 +1,147 @@
|
||||
SET search_path TO lab5;
|
||||
|
||||
-- TASK 1 – Enforce Section Capacity
|
||||
|
||||
-- 1. Trigger function: ensure no course offering exceeds capacity
|
||||
CREATE OR REPLACE FUNCTION check_offering_capacity()
|
||||
RETURNS TRIGGER AS $$
|
||||
DECLARE
|
||||
v_capacity INTEGER;
|
||||
v_current INTEGER;
|
||||
BEGIN
|
||||
SELECT off_capacity
|
||||
INTO v_capacity
|
||||
FROM course_offering
|
||||
WHERE off_id = NEW.off_id;
|
||||
|
||||
SELECT COUNT(*)
|
||||
INTO v_current
|
||||
FROM enrollment
|
||||
WHERE off_id = NEW.off_id
|
||||
AND enr_status = 'Active';
|
||||
|
||||
IF v_current >= v_capacity THEN
|
||||
RAISE EXCEPTION
|
||||
'Cannot enroll student %. Section % is full (capacity=%).',
|
||||
NEW.stu_num, NEW.off_id, v_capacity;
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
||||
-- 2. Trigger
|
||||
CREATE OR REPLACE TRIGGER trg_check_capacity
|
||||
BEFORE INSERT ON enrollment
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION check_offering_capacity();
|
||||
|
||||
-- TASK 2 – Enrollment Audit Logging
|
||||
|
||||
CREATE TABLE IF NOT EXISTS enrollment_audit (
|
||||
audit_id SERIAL PRIMARY KEY,
|
||||
enr_id_stu VARCHAR(20),
|
||||
enr_id_off INTEGER,
|
||||
action_type VARCHAR(10),
|
||||
old_status VARCHAR(8),
|
||||
new_status VARCHAR(8),
|
||||
action_ts TIMESTAMP DEFAULT NOW(),
|
||||
action_user TEXT DEFAULT current_user
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION audit_enrollment_changes()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
IF TG_OP = 'INSERT' THEN
|
||||
INSERT INTO enrollment_audit(
|
||||
enr_id_stu,
|
||||
enr_id_off,
|
||||
action_type,
|
||||
new_status
|
||||
)
|
||||
VALUES (
|
||||
NEW.stu_num,
|
||||
NEW.off_id,
|
||||
'INSERT',
|
||||
NEW.enr_status
|
||||
);
|
||||
|
||||
ELSIF TG_OP = 'UPDATE' THEN
|
||||
INSERT INTO enrollment_audit(
|
||||
enr_id_stu,
|
||||
enr_id_off,
|
||||
action_type,
|
||||
old_status,
|
||||
new_status
|
||||
)
|
||||
VALUES (
|
||||
NEW.stu_num,
|
||||
NEW.off_id,
|
||||
'UPDATE',
|
||||
OLD.enr_status,
|
||||
NEW.enr_status
|
||||
);
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER trg_enrollment_audit
|
||||
AFTER INSERT OR UPDATE ON enrollment
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION audit_enrollment_changes();
|
||||
|
||||
-- TASK 3 – Validate Enrollment Status
|
||||
|
||||
ALTER TABLE enrollment DROP CONSTRAINT IF EXISTS enr_status_ck;
|
||||
|
||||
ALTER TABLE enrollment
|
||||
ADD CONSTRAINT enr_status_ck
|
||||
CHECK (enr_status IN ('Active', 'Dropped', 'Completed', 'Failed'));
|
||||
|
||||
CREATE OR REPLACE FUNCTION validate_enrollment_status()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
IF NEW.enr_status NOT IN ('Active','Dropped','Completed','Failed') THEN
|
||||
RAISE EXCEPTION 'Invalid enrollment status: %', NEW.enr_status;
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE TRIGGER trg_validate_status
|
||||
BEFORE INSERT OR UPDATE OF enr_status ON enrollment
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION validate_enrollment_status();
|
||||
|
||||
-- TESTS
|
||||
|
||||
INSERT INTO enrollment VALUES ('S100', 1, 'Active');
|
||||
INSERT INTO enrollment VALUES ('S101', 1, 'Active');
|
||||
INSERT INTO enrollment VALUES ('S102', 1, 'Active');
|
||||
|
||||
INSERT INTO enrollment VALUES ('S200', 2, 'Active');
|
||||
UPDATE enrollment SET enr_status = 'Dropped'
|
||||
WHERE stu_num = 'S200' AND off_id = 2;
|
||||
|
||||
UPDATE enrollment
|
||||
SET enr_status = 'Potato'
|
||||
WHERE stu_num = 'S200' AND off_id = 2;
|
||||
|
||||
-- OUTPUT
|
||||
|
||||
-- SELECT * FROM enrollment;
|
||||
|
||||
|
||||
-- SELECT * FROM enrollment_audit;
|
||||
|
||||
|
||||
-- REFLECTION
|
||||
-- Storing business rules directly inside the database ensures that
|
||||
-- data remains correct and consistent no matter what application
|
||||
-- or user interacts with it. Trigger-based validation centralizes
|
||||
-- logic so errors are prevented at the source instead of being caught
|
||||
-- later in the application.
|
||||
Reference in new issue
Block a user