Refactorization and splitting of schema files
This commit is contained in:
66
schema/triggers/balanceTransfer.sql
Normal file
66
schema/triggers/balanceTransfer.sql
Normal file
@@ -0,0 +1,66 @@
|
||||
CREATE TRIGGER balanceTransfer
|
||||
AFTER INSERT ON Transfer
|
||||
BEGIN
|
||||
|
||||
SELECT RAISE(FAIL, "It is not the debtor who is set to pay")
|
||||
WHERE (SELECT debtor FROM Debit WHERE billId=NEW.billId)
|
||||
!= (SELECT account FROM Credit WHERE credId=NEW.credId)
|
||||
;
|
||||
|
||||
SELECT RAISE(FAIL, "Target of a debit cannot be an incoming payment")
|
||||
FROM Credit c
|
||||
JOIN Debit d ON c.credId = d.targetCredit
|
||||
WHERE c.credId = NEW.credId
|
||||
AND c.value > 0
|
||||
GROUP BY c.credId
|
||||
HAVING count(d.billId) == 0
|
||||
;
|
||||
|
||||
INSERT INTO __DO_NOT_MANIPULATE__trigger_memory
|
||||
SELECT remainingDebt, remainingCredit, min(remainingDebt,remainingCredit)
|
||||
FROM (SELECT
|
||||
(SELECT value - paid FROM Debit WHERE billId=NEW.billId) AS remainingDebt,
|
||||
(SELECT value - spent FROM Credit WHERE credId=NEW.credId) AS remainingCredit
|
||||
)
|
||||
;
|
||||
|
||||
UPDATE Debit
|
||||
SET paid = paid + CASE
|
||||
WHEN (SELECT d FROM __DO_NOT_MANIPULATE__trigger_memory) <= 0
|
||||
THEN RAISE(FAIL, "Debt settled")
|
||||
ELSE
|
||||
(SELECT m FROM __DO_NOT_MANIPULATE__trigger_memory)
|
||||
END
|
||||
WHERE billId=NEW.billId;
|
||||
|
||||
UPDATE Credit
|
||||
SET spent = spent + CASE
|
||||
WHEN (SELECT c FROM __DO_NOT_MANIPULATE__trigger_memory) <= 0
|
||||
THEN RAISE(FAIL, "Credit spent")
|
||||
ELSE IFNULL(
|
||||
(SELECT m FROM __DO_NOT_MANIPULATE__trigger_memory),
|
||||
RAISE(FAIL,"Oops, lost __DO_NOT_MANIPULATE__trigger_memory record before increasing spent")
|
||||
)
|
||||
END
|
||||
WHERE credId=NEW.credId;
|
||||
|
||||
UPDATE Transfer
|
||||
SET amount = (SELECT m FROM __DO_NOT_MANIPULATE__trigger_memory)
|
||||
WHERE billId=NEW.billId AND credId=NEW.credId
|
||||
;
|
||||
|
||||
UPDATE Credit
|
||||
SET value = value + IFNULL(
|
||||
(SELECT m FROM __DO_NOT_MANIPULATE__trigger_memory),
|
||||
RAISE(FAIL, "Oops, lost __DO_NOT_MANIPULATE__trigger_memory record before increasing value")
|
||||
)
|
||||
WHERE credId = (
|
||||
SELECT targetCredit
|
||||
FROM Debit
|
||||
WHERE billId=NEW.billId
|
||||
);
|
||||
|
||||
DELETE FROM __DO_NOT_MANIPULATE__trigger_memory;
|
||||
|
||||
END;
|
||||
|
||||
13
schema/triggers/checkIBANatTransfer.sql
Normal file
13
schema/triggers/checkIBANatTransfer.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
CREATE TRIGGER checkIBANatTransfer
|
||||
BEFORE INSERT ON Debit
|
||||
WHEN NEW.targetCredit IS NULL
|
||||
BEGIN
|
||||
SELECT RAISE(FAIL, "IBAN used does not match IBAN currently stored in account record")
|
||||
FROM (
|
||||
SELECT instr(NEW.purpose, IBAN) AS fnd
|
||||
FROM Account
|
||||
WHERE ID=NEW.debtor
|
||||
) AS matchingIBAN
|
||||
WHERE fnd IS NULL OR fnd = 0;
|
||||
END;
|
||||
|
||||
12
schema/triggers/enforcDebtImmutableOutsideTrigger.sql
Normal file
12
schema/triggers/enforcDebtImmutableOutsideTrigger.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
-- Prevent modification of paid value outside triggers which must adjust it exclusively
|
||||
-- when new transfer records are inserted
|
||||
CREATE TRIGGER enforceDebtImmutableOutsideTrigger
|
||||
BEFORE UPDATE OF paid ON Debit
|
||||
WHEN NOT EXISTS (SELECT * FROM Transfer t WHERE NEW.billId=t.billId AND amount IS NULL)
|
||||
BEGIN
|
||||
SELECT RAISE(FAIL, "paid is set and adjusted automatically according to added Transfer records")
|
||||
WHERE (NEW.paid + IFNULL(
|
||||
(SELECT m FROM __DO_NOT_MANIPULATE__trigger_memory WHERE c IS NULL AND d IS NULL), 0
|
||||
) ) <> OLD.paid;
|
||||
END;
|
||||
|
||||
8
schema/triggers/enforceFixedCredit.sql
Normal file
8
schema/triggers/enforceFixedCredit.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
CREATE TRIGGER enforceFixedCredit
|
||||
BEFORE UPDATE OF account, value ON Credit
|
||||
WHEN EXISTS (SELECT * FROM Transfer WHERE credId=NEW.credId)
|
||||
AND NOT EXISTS (SELECT * FROM __DO_NOT_MANIPULATE__trigger_memory)
|
||||
BEGIN
|
||||
SELECT RAISE(FAIL, "Credit involved in transactions to revoke at first");
|
||||
END;
|
||||
|
||||
7
schema/triggers/enforceFixedDebit.sql
Normal file
7
schema/triggers/enforceFixedDebit.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
CREATE TRIGGER enforceFixedDebit
|
||||
BEFORE UPDATE OF debtor, transferCredit, value ON Debit
|
||||
WHEN EXISTS (SELECT * FROM Transfer WHERE billId=NEW.billId)
|
||||
BEGIN
|
||||
SELECT RAISE(FAIL, "Debt is involved in transfers to revoke at first");
|
||||
END;
|
||||
|
||||
7
schema/triggers/enforceImmutableTransfer.sql
Normal file
7
schema/triggers/enforceImmutableTransfer.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
CREATE TRIGGER enforceImmutableTransfer
|
||||
BEFORE UPDATE ON Transfer
|
||||
WHEN OLD.amount IS NOT NULL
|
||||
BEGIN
|
||||
SELECT RAISE(FAIL, "Transfer cannot be updated, but needs to be replaced to make triggers run");
|
||||
END;
|
||||
|
||||
12
schema/triggers/enforceSpentImmutableOutsideTrigger.sql
Normal file
12
schema/triggers/enforceSpentImmutableOutsideTrigger.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
-- Prevent modification of spent value outside triggers which must adjust it exclusively
|
||||
-- when new transfer records are inserted
|
||||
CREATE TRIGGER enforceSpentImmutableOutsideTrigger
|
||||
BEFORE UPDATE OF spent ON Credit
|
||||
WHEN NOT EXISTS (SELECT * FROM Transfer t WHERE NEW.credId=t.credId AND amount IS NULL)
|
||||
BEGIN
|
||||
SELECT RAISE(FAIL, "spent is set and adjusted automatically according to added Transfer records")
|
||||
WHERE (NEW.spent + IFNULL(
|
||||
(SELECT m FROM __DO_NOT_MANIPULATE__trigger_memory WHERE c IS NULL AND d IS NULL), 0
|
||||
) ) <> OLD.spent;
|
||||
END;
|
||||
|
||||
7
schema/triggers/enforceZeroPaidAtStart.sql
Normal file
7
schema/triggers/enforceZeroPaidAtStart.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
CREATE TRIGGER enforceZeroPaidAtStart
|
||||
BEFORE INSERT ON Debit
|
||||
BEGIN
|
||||
SELECT RAISE(FAIL, "Debt must be initially unpaid")
|
||||
WHERE NEW.paid <> 0;
|
||||
END;
|
||||
|
||||
7
schema/triggers/enforceZeroSpentAtStart.sql
Normal file
7
schema/triggers/enforceZeroSpentAtStart.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
CREATE TRIGGER enforceZeroSpentAtStart
|
||||
BEFORE INSERT ON Credit
|
||||
BEGIN
|
||||
SELECT RAISE(FAIL, "credit must be initially unused")
|
||||
WHERE NEW.spent != 0;
|
||||
END;
|
||||
|
||||
16
schema/triggers/rebalanceIncreasedCredit.sql
Normal file
16
schema/triggers/rebalanceIncreasedCredit.sql
Normal file
@@ -0,0 +1,16 @@
|
||||
-- When we enter a transfer, the targetCredit of the associated bill might already be the credId
|
||||
-- of a transfer for other dues itself. We can update (replace) the transfer for an unfullfilled one.
|
||||
-- That way, a transfer may issue recursively chained transfers.
|
||||
CREATE TRIGGER rebalanceIncreasedCredit
|
||||
AFTER UPDATE OF value ON Credit
|
||||
WHEN NEW.value > OLD.spent
|
||||
BEGIN
|
||||
|
||||
REPLACE INTO Transfer (credId, billId)
|
||||
SELECT OLD.credId, t.billId
|
||||
FROM Transfer t
|
||||
JOIN CurrentArrears ca ON t.billId = ca.billId
|
||||
WHERE OLD.credId = t.credId
|
||||
;
|
||||
|
||||
END;
|
||||
43
schema/triggers/rebalanceReducedCredit.sql
Normal file
43
schema/triggers/rebalanceReducedCredit.sql
Normal file
@@ -0,0 +1,43 @@
|
||||
-- When a transfer is revoked, the targetCredit of the associated bill is reduced. Hence we must
|
||||
-- check if we can still have paid the debts linked to this transfer in an "is paid from" relation,
|
||||
-- otherwise we have to revoke these transfers as well.
|
||||
CREATE TRIGGER rebalanceReducedCredit
|
||||
AFTER UPDATE OF value ON Credit
|
||||
WHEN NEW.value < OLD.spent
|
||||
BEGIN
|
||||
|
||||
REPLACE INTO __DO_NOT_MANIPULATE__trigger_memory (d, m)
|
||||
SELECT
|
||||
'from_' || NEW.credId,
|
||||
billId
|
||||
FROM Transfer
|
||||
WHERE credId = NEW.credId
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT 1
|
||||
;
|
||||
|
||||
DELETE
|
||||
FROM Transfer
|
||||
WHERE credId = NEW.credId
|
||||
AND billId IN (
|
||||
SELECT billId
|
||||
FROM __DO_NOT_MANIPULATE__trigger_memory
|
||||
WHERE c = 'from_' || NEW.credId
|
||||
)
|
||||
;
|
||||
|
||||
INSERT INTO Transfer (credId, billId)
|
||||
SELECT NEW.credId, m
|
||||
FROM __DO_NOT_MANIPULATE__trigger_memory
|
||||
WHERE d = 'from_' || NEW.credId
|
||||
AND NEW.value > (
|
||||
SELECT spent
|
||||
FROM Credit
|
||||
WHERE credId = NEW.credId
|
||||
)
|
||||
;
|
||||
|
||||
DELETE FROM __DO_NOT_MANIPULATE__trigger_memory WHERE d = 'from_' || NEW.credId;
|
||||
|
||||
END;
|
||||
|
||||
27
schema/triggers/revokeTransfer.sql
Normal file
27
schema/triggers/revokeTransfer.sql
Normal file
@@ -0,0 +1,27 @@
|
||||
CREATE TRIGGER revokeTransfer
|
||||
BEFORE DELETE ON Transfer
|
||||
BEGIN
|
||||
|
||||
INSERT INTO __DO_NOT_MANIPULATE__trigger_memory VALUES (null,null,OLD.amount);
|
||||
|
||||
UPDATE Debit
|
||||
SET paid = paid - OLD.amount
|
||||
WHERE billId=OLD.billId
|
||||
;
|
||||
|
||||
UPDATE Credit
|
||||
SET value = value - OLD.amount
|
||||
WHERE credId = (
|
||||
SELECT targetCredit
|
||||
FROM Debit
|
||||
WHERE billId=OLD.billId
|
||||
);
|
||||
|
||||
UPDATE Credit
|
||||
SET spent = spent - OLD.amount
|
||||
WHERE credId = OLD.credId;
|
||||
|
||||
DELETE FROM __DO_NOT_MANIPULATE__trigger_memory;
|
||||
|
||||
END;
|
||||
|
||||
Reference in New Issue
Block a user