69 lines
2.3 KiB
PL/PgSQL
69 lines
2.3 KiB
PL/PgSQL
BEGIN;
|
|
|
|
CREATE OR REPLACE FUNCTION public.reorder_custom_instruction(
|
|
instruction_id uuid,
|
|
direction text
|
|
)
|
|
RETURNS SETOF public.custom_instructions
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
SET search_path = ''
|
|
AS $$
|
|
DECLARE
|
|
current_user_id uuid := auth.uid();
|
|
ordered_ids uuid[];
|
|
current_index integer;
|
|
target_index integer;
|
|
swapped_id uuid;
|
|
BEGIN
|
|
IF current_user_id IS NULL THEN
|
|
RAISE EXCEPTION 'authentication_required' USING ERRCODE = '42501';
|
|
END IF;
|
|
IF direction NOT IN ('up', 'down') THEN
|
|
RAISE EXCEPTION 'invalid_direction' USING ERRCODE = '22023';
|
|
END IF;
|
|
|
|
PERFORM pg_advisory_xact_lock(hashtextextended(current_user_id::text, 73036));
|
|
SELECT array_agg(instruction.id ORDER BY instruction.sort_order, instruction.created_at, instruction.id)
|
|
INTO ordered_ids
|
|
FROM public.custom_instructions AS instruction
|
|
WHERE instruction.user_id = current_user_id
|
|
AND instruction.builtin_key IS NULL;
|
|
|
|
current_index := array_position(ordered_ids, instruction_id);
|
|
IF current_index IS NULL THEN
|
|
RAISE EXCEPTION 'instruction_not_found' USING ERRCODE = 'P0002';
|
|
END IF;
|
|
target_index := current_index + CASE direction WHEN 'up' THEN -1 ELSE 1 END;
|
|
IF target_index < 1 OR target_index > coalesce(array_length(ordered_ids, 1), 0) THEN
|
|
RETURN QUERY
|
|
SELECT instruction.*
|
|
FROM public.custom_instructions AS instruction
|
|
WHERE instruction.user_id = current_user_id
|
|
ORDER BY instruction.sort_order, instruction.created_at, instruction.id;
|
|
RETURN;
|
|
END IF;
|
|
|
|
swapped_id := ordered_ids[target_index];
|
|
ordered_ids[target_index] := ordered_ids[current_index];
|
|
ordered_ids[current_index] := swapped_id;
|
|
|
|
UPDATE public.custom_instructions AS instruction
|
|
SET sort_order = (ordering.ordinality * 10 + 1000)::integer
|
|
FROM unnest(ordered_ids) WITH ORDINALITY AS ordering(id, ordinality)
|
|
WHERE instruction.id = ordering.id
|
|
AND instruction.user_id = current_user_id
|
|
AND instruction.builtin_key IS NULL;
|
|
|
|
RETURN QUERY
|
|
SELECT instruction.*
|
|
FROM public.custom_instructions AS instruction
|
|
WHERE instruction.user_id = current_user_id
|
|
ORDER BY instruction.sort_order, instruction.created_at, instruction.id;
|
|
END;
|
|
$$;
|
|
|
|
REVOKE ALL ON FUNCTION public.reorder_custom_instruction(uuid, text) FROM PUBLIC;
|
|
GRANT EXECUTE ON FUNCTION public.reorder_custom_instruction(uuid, text) TO authenticated;
|
|
|
|
COMMIT;
|