57 lines
1.4 KiB
JavaScript
Executable File
57 lines
1.4 KiB
JavaScript
Executable File
const team_size_trigger = `
|
|
CREATE OR REPLACE FUNCTION enforce_team_size() RETURNS trigger AS $$
|
|
DECLARE
|
|
team_size INTEGER := 3;
|
|
team_count INTEGER := 0;
|
|
BEGIN
|
|
IF (TG_OP = 'UPDATE' OR TG_OP = 'INSERT') THEN
|
|
SELECT INTO team_count COUNT(id)
|
|
FROM constructs
|
|
WHERE account = NEW.account
|
|
AND team = true;
|
|
ELSIF (TG_OP = 'DELETE') THEN
|
|
SELECT INTO team_count COUNT(id)
|
|
FROM constructs
|
|
WHERE account = OLD.account
|
|
AND team = true;
|
|
END IF;
|
|
|
|
IF team_count != team_size THEN
|
|
RAISE EXCEPTION 'You must have exactly % constructs in your team.', team_size;
|
|
END IF;
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE CONSTRAINT TRIGGER check_team_size
|
|
AFTER INSERT OR UPDATE OR DELETE
|
|
ON constructs
|
|
DEFERRABLE INITIALLY DEFERRED
|
|
FOR EACH ROW
|
|
EXECUTE PROCEDURE enforce_team_size();
|
|
`;
|
|
|
|
exports.up = async knex => {
|
|
await knex.schema.createTable('constructs', table => {
|
|
table.uuid('id').primary();
|
|
table.timestamps(true, true);
|
|
table.uuid('account').notNullable()
|
|
table.foreign('account')
|
|
.references('id')
|
|
.inTable('accounts')
|
|
.onDelete('CASCADE');
|
|
table.binary('data').notNullable();
|
|
|
|
table.boolean('team')
|
|
.notNullable()
|
|
.defaultTo(false);
|
|
});
|
|
|
|
await knex.raw(team_size_trigger);
|
|
|
|
return true;
|
|
};
|
|
|
|
exports.down = async () => {};
|