sipher/supabase/sql_snippets/User Management Functions.sql
Nixyi 8b27c6b140 Stable Release (I think)
Added all SQL scripts by using a python script to fetch them.

Also added a "About" page and a skeleton to the chat page.

Fixed the register function that was not setting the public_key on the database
2024-12-18 16:08:06 -03:00

1 line
No EOL
3.1 KiB
PL/PgSQL

-- For generate_short_uuid
CREATE
OR REPLACE FUNCTION public.generate_short_uuid () RETURNS TEXT AS $$
DECLARE
chars TEXT := 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
result
TEXT := '';
i
INTEGER := 0;
max_attempts
INTEGER := 10;
current_attempt
INTEGER := 0;
is_unique
BOOLEAN := false;
BEGIN
WHILE
NOT is_unique AND current_attempt < max_attempts LOOP
result := '';
FOR i IN 1..8 LOOP
result := result || substr(chars, floor(random() * length(chars) + 1)::integer, 1);
END LOOP;
SELECT COUNT(*) = 0
INTO is_unique
FROM public.users
WHERE suuid = result;
current_attempt
:= current_attempt + 1;
END LOOP;
IF
NOT is_unique THEN
RAISE EXCEPTION 'Could not generate unique short UUID after % attempts', max_attempts;
END IF;
RETURN result;
END;
$$
LANGUAGE plpgsql;
CREATE
OR REPLACE FUNCTION public.search_users(search_term TEXT)
RETURNS TABLE (
uuid UUID,
suuid TEXT,
username TEXT,
indexable BOOLEAN
) AS $$
BEGIN
RETURN QUERY
SELECT u.uuid,
u.suuid::TEXT,
-- Simplified CASE logic: show username if SUUID match OR (username match AND indexable) CASE
WHEN u.suuid = search_term OR u.indexable THEN u.username
ELSE NULL
END,
u.indexable
FROM public.users u
WHERE u.suuid = search_term -- Case 1: SUUID match (always show)
OR (
u.indexable = true AND -- Case 2: Username match + indexable
u.username ILIKE '%' || search_term || '%'
);
END;
$$
LANGUAGE plpgsql;
-- For is_thread_participant
CREATE
OR REPLACE FUNCTION public.is_thread_participant (thread_uuid UUID) RETURNS BOOLEAN AS $$
BEGIN
RETURN EXISTS (SELECT 1
FROM public.thread_participants
WHERE thread_id = thread_uuid
AND user_uuid = auth.uid());
END;
$$
LANGUAGE plpgsql SECURITY DEFINER;
-- For get_user_threads
CREATE
OR REPLACE FUNCTION public.get_user_threads (user_id UUID) RETURNS TABLE (
thread_id UUID,
participants TEXT[],
messages JSON[]
) AS $$
BEGIN
IF
NOT EXISTS (
SELECT 1
FROM public.thread_participants
WHERE user_uuid = user_id
) THEN
-- Return empty result if user has no threads
RETURN;
END IF;
RETURN QUERY
SELECT mt.id,
array_agg(DISTINCT u.username),
COALESCE(array_agg(
CASE
WHEN m.id IS NOT NULL THEN
json_build_object(
'id', m.id,
'content', m.content,
'created_at', m.created_at
)
ELSE NULL END
) FILTER(WHERE m.id IS NOT NULL), ARRAY[] ::JSON[])
FROM public.message_threads mt
JOIN public.thread_participants tp ON mt.id = tp.thread_id
JOIN public.users u ON tp.user_uuid = u.uuid
LEFT JOIN public.messages m ON mt.id = m.thread_id
WHERE mt.id IN (SELECT thread_id
FROM public.thread_participants
WHERE user_uuid = user_id)
GROUP BY mt.id;
END;
$$
LANGUAGE plpgsql SECURITY DEFINER;