CREATE TABLE IF NOT EXISTS airship_groups (
groupid BIGSERIAL PRIMARY KEY,
name TEXT,
superuser BOOLEAN DEFAULT FALSE,
inherits INTEGER NULL,
created TIMESTAMP DEFAULT NOW(),
modified TIMESTAMP DEFAULT NOW()
);
DROP TRIGGER IF EXISTS update_airship_groups_modtime ON airship_groups;
CREATE TRIGGER update_airship_groups_modtime
BEFORE UPDATE ON airship_groups
FOR EACH ROW EXECUTE PROCEDURE update_modtime();
CREATE TABLE IF NOT EXISTS airship_users_groups (
userid INTEGER NOT NULL,
groupid INTEGER NOT NULL,
created TIMESTAMP DEFAULT NOW(),
modified TIMESTAMP DEFAULT NOW()
);
DROP TRIGGER IF EXISTS update_airship_users_groups_modtime ON airship_users_groups;
CREATE TRIGGER update_airship_users_groups_modtime
BEFORE UPDATE ON airship_users_groups
FOR EACH ROW EXECUTE PROCEDURE update_modtime();
CREATE OR REPLACE FUNCTION group_ancestors(child BIGINT)
RETURNS TABLE (parent BIGINT) AS $$
WITH RECURSIVE parents AS (
(
SELECT
node.groupid,
node.inherits
FROM airship_groups AS node
WHERE
node.groupid = $1
)
UNION ALL
(
SELECT
g.groupid,
g.inherits
FROM airship_groups g
JOIN parents p
ON p.inherits = g.groupid
)
)
SELECT $1
UNION
SELECT groupid
FROM parents;
$$ language 'sql';
-- Get all of a users' group memberships
CREATE OR REPLACE FUNCTION memberOf(user_id BIGINT)
RETURNS TABLE (groupid BIGINT) AS $$
SELECT DISTINCT airship_groups.groupid
FROM airship_groups
LEFT JOIN airship_users_groups
ON airship_groups.groupid = airship_users_groups.groupid
LEFT JOIN airship_users
ON airship_users_groups.userid = airship_users.userid
WHERE airship_users.userid = $1
UNION
SELECT DISTINCT group_ancestors(g.groupid)
FROM (
SELECT airship_groups.groupid
FROM airship_groups
LEFT JOIN airship_users_groups
ON airship_groups.groupid = airship_users_groups.groupid
LEFT JOIN airship_users
ON airship_users_groups.userid = airship_users.userid
WHERE airship_users.userid = $1
) g;
$$ language 'sql';
|