Functions & Triggers
Create database functions and triggers for automated logic.
Note: This is mock/placeholder content for demonstration purposes.
Database functions and triggers enable server-side logic and automation.
Database Functions
Creating a Function
CREATE OR REPLACE FUNCTION get_user_projects(user_id UUID) RETURNS TABLE ( id UUID, name TEXT, created_at TIMESTAMPTZ ) LANGUAGE plpgsql SECURITY DEFINER AS $$ BEGIN RETURN QUERY SELECT p.id, p.name, p.created_at FROM projects p INNER JOIN accounts_memberships am ON am.account_id = p.account_id WHERE am.user_id = get_user_projects.user_id; END; $$;
Calling from TypeScript
const { data, error } = await client.rpc('get_user_projects', {
user_id: userId,
});
Common Function Patterns
Get User Accounts
CREATE OR REPLACE FUNCTION get_user_accounts(user_id UUID) RETURNS TABLE (account_id UUID) LANGUAGE sql SECURITY DEFINER AS $$ SELECT account_id FROM accounts_memberships WHERE user_id = $1; $$;
Check Permission
CREATE OR REPLACE FUNCTION has_permission(
user_id UUID,
account_id UUID,
required_role TEXT
)
RETURNS BOOLEAN
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
user_role TEXT;
BEGIN
SELECT role INTO user_role
FROM accounts_memberships
WHERE user_id = has_permission.user_id
AND account_id = has_permission.account_id;
RETURN user_role = required_role OR user_role = 'owner';
END;
$$;
Search Function
CREATE OR REPLACE FUNCTION search_projects(
search_term TEXT,
account_id UUID
)
RETURNS TABLE (
id UUID,
name TEXT,
description TEXT,
relevance REAL
)
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
BEGIN
RETURN QUERY
SELECT
p.id,
p.name,
p.description,
ts_rank(
to_tsvector('english', p.name || ' ' || COALESCE(p.description, '')),
plainto_tsquery('english', search_term)
) AS relevance
FROM projects p
WHERE p.account_id = search_projects.account_id
AND (
to_tsvector('english', p.name || ' ' || COALESCE(p.description, ''))
@@ plainto_tsquery('english', search_term)
)
ORDER BY relevance DESC;
END;
$$;
Triggers
Auto-Update Timestamp
-- Create trigger function CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$; -- Attach to table CREATE TRIGGER update_projects_updated_at BEFORE UPDATE ON projects FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
Audit Log Trigger
-- Create audit log table
CREATE TABLE audit_log (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
table_name TEXT NOT NULL,
record_id UUID NOT NULL,
action TEXT NOT NULL,
old_data JSONB,
new_data JSONB,
user_id UUID,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Create trigger function
CREATE OR REPLACE FUNCTION log_changes()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
INSERT INTO audit_log (table_name, record_id, action, new_data, user_id)
VALUES (TG_TABLE_NAME, NEW.id, 'INSERT', to_jsonb(NEW), auth.uid());
RETURN NEW;
ELSIF TG_OP = 'UPDATE' THEN
INSERT INTO audit_log (table_name, record_id, action, old_data, new_data, user_id)
VALUES (TG_TABLE_NAME, NEW.id, 'UPDATE', to_jsonb(OLD), to_jsonb(NEW), auth.uid());
RETURN NEW;
ELSIF TG_OP = 'DELETE' THEN
INSERT INTO audit_log (table_name, record_id, action, old_data, user_id)
VALUES (TG_TABLE_NAME, OLD.id, 'DELETE', to_jsonb(OLD), auth.uid());
RETURN OLD;
END IF;
END;
$$;
-- Attach to table
CREATE TRIGGER audit_projects
AFTER INSERT OR UPDATE OR DELETE ON projects
FOR EACH ROW
EXECUTE FUNCTION log_changes();