Forum OpenACS Development: Response to Reordering tree_sortkeys again

Collapse
Posted by Patrick McNeill on
I'm using tree_sortkeys as a normal sort key as well, and have written the following function to swap two positions.  It swaps the two nodes, as well as any children.  I'm not a plpgsql expert (only a couple months experience with it), so YMMV, but here it is:

create function brk_class_dev_nodes__swap(integer, integer)
returns integer as '
declare
    p_node_id_1            alias for $1;
    p_node_id_2            alias for $2;

    v_sortkey_1            varbit;
    v_sortkey_2            varbit;
begin
    select tree_sortkey into v_sortkey_1
    from brk_class_dev_nodes
    where node_id = p_node_id_1;

    select tree_sortkey into v_sortkey_2
    from brk_class_dev_nodes
    where node_id = p_node_id_2;

    if length(v_sortkey_1) != length(v_sortkey_2) then
        raise exception ''cannot reorder nodes at different tree levels'';
    end if;

    -- swap the initial part of any sortkeys that match the
    -- above (hence are the nodes themselves or child nodes
    update brk_class_dev_nodes
      set tree_sortkey =
            case when substring(tree_sortkey from 1 for length(v_sortkey_2)) = v_sortkey_2
                then v_sortkey_1 || substring(tree_sortkey from length(v_sortkey_1) + 1 for length(tree_sortkey))
                when substring(tree_sortkey from 1 for length(v_sortkey_1)) = v_sortkey_1
                then v_sortkey_2 || substring(tree_sortkey from length(v_sortkey_2) + 1 for length(tree_sortkey))
                else tree_sortkey
            end;

    return 0;
end;' language 'plpgsql';