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
1 line
No EOL
3.1 KiB
PL/PgSQL
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;
|