Skip to content

Instantly share code, notes, and snippets.

@edoves
Last active November 11, 2024 03:59
Show Gist options
  • Save edoves/0d60a1427d8962bdaac3e03e391c4737 to your computer and use it in GitHub Desktop.
Save edoves/0d60a1427d8962bdaac3e03e391c4737 to your computer and use it in GitHub Desktop.
PostgreSQL Stored Function

PostgreSQL Stored Function

create or replace function post_todo() 
returns setof table_sample as $$
begin
    -- SQL statements go here
end;
$$ language plpgsql;

This SQL code is defining a PostgreSQL stored function named post_todo. Let’s break it down step by step:

Explanation

  1. Function Definition and Return Type:

    • create or replace function post_todo() – This line is defining a function named post_todo. The create or replace clause ensures that if the function already exists, it will be replaced by this new definition.
    • returns setof table_sample – This function is set to return a set (i.e., multiple rows) of data from a table or table type called table_sample. The setof keyword means that the function will return a set of records rather than a single record.
  2. Function Body:

    • as $$ ... $$ – The $$ symbols are used to define the function body without needing to escape single quotes. This is often used in PostgreSQL to make code easier to read.
    • begin ... end; – This marks the start and end of the function body. Currently, there is no code within this body, which means the function does nothing yet.
  3. Language Specification:

    • language plpgsql; – This specifies that the function is written in PL/pgSQL, which is PostgreSQL’s procedural language. It allows for control structures like loops and conditionals, making it more versatile than plain SQL.

Summary

This function template is prepared to return a set of rows from table_sample, but it currently has no operational code inside. To make it functional, you would need to add SQL statements or logic in the begin ... end block. For example, you might use RETURN QUERY statements to return data from table_sample.

create table todos (
    id bigint generated by default as identity primary key,
    user_id uuid references auth.users not null,
    task text check (char_length(task) > 3),
    is_complete boolean default false,
    inserted_at timestamp with time zone default timezone('utc'::text, now()) not null
);

alter table todos enable row level security;

create policy "Individuals can create todos." on todos for
    insert with check (auth.uid() = user_id);

create policy "Individuals can view their own todos." on todos for
    select using ((select auth.uid()) = user_id);

create policy "Individuals can update their own todos." on todos for
    update using ((select auth.uid()) = user_id);

create policy "Individuals can delete their own todos." on todos for
    delete using ((select auth.uid()) = user_id);

This PostgreSQL SQL script creates a table for managing "to-do" items with row-level security policies for access control. Let's break down each part of the script:

Table Definition

  1. Creating the todos Table
    create table todos (
        id bigint generated by default as identity primary key,
        user_id uuid references auth.users not null,
        task text check (char_length(task) > 3),
        is_complete boolean default false,
        inserted_at timestamp with time zone default timezone('utc'::text, now()) not null
    );
    • id: A bigint column that serves as a unique identifier for each todo item. The generated by default as identity clause auto-generates sequential IDs, acting as a primary key.
    • user_id: A uuid column that references a user ID from the auth.users table, indicating ownership of each todo item. The not null constraint ensures every todo must be associated with a user.
    • task: A text column storing the description of the task. The check (char_length(task) > 3) constraint ensures that the task description has more than three characters.
    • is_complete: A boolean column to indicate whether the task is complete, defaulting to false.
    • inserted_at: A timestamp with time zone column that automatically stores the creation time of each todo in UTC, using timezone('utc', now()).

Enabling Row-Level Security (RLS)

alter table todos enable row level security;

This command enables Row-Level Security (RLS) on the todos table. With RLS, access to rows in the table can be restricted based on conditions set by policies.

Defining Row-Level Security Policies

  1. Insert Policy

    create policy "Individuals can create todos." on todos for
        insert with check (auth.uid() = user_id);

    This policy allows users to insert rows into the todos table, with a check to ensure that the user_id matches the currently authenticated user's ID (auth.uid()).

  2. Select Policy

    create policy "Individuals can view their own todos." on todos for
        select using ((select auth.uid()) = user_id);

    This policy allows users to view (select) only their own todo items. The condition using ((select auth.uid()) = user_id) ensures users can only see rows where their user ID matches the user_id in the row.

  3. Update Policy

    create policy "Individuals can update their own todos." on todos for
        update using ((select auth.uid()) = user_id);

    This policy allows users to update only their own todos by ensuring the row's user_id matches the current user’s ID.

  4. Delete Policy

    create policy "Individuals can delete their own todos." on todos for
        delete using ((select auth.uid()) = user_id);

    This policy allows users to delete only their own todos. The condition (select auth.uid()) = user_id restricts deletions to rows where the user_id matches the current user.

Summary

This setup creates a secure, user-specific to-do list system where each user can manage only their own tasks. RLS policies enforce that users can only insert, view, update, and delete rows that belong to them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment