Index: openacs-4/packages/acs-content-repository/sql/postgresql/content-item.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/sql/postgresql/content-item.sql,v diff -u -r1.7 -r1.8 --- openacs-4/packages/acs-content-repository/sql/postgresql/content-item.sql 2 Apr 2001 05:35:29 -0000 1.7 +++ openacs-4/packages/acs-content-repository/sql/postgresql/content-item.sql 2 Apr 2001 23:14:07 -0000 1.8 @@ -701,12 +701,12 @@ LOOP -- FIXME: this use of instr in oracle code seems incorrect. -- end_pos := instr(v_item_path, ''/'', start_pos); - end_pos := instr(v_item_path, ''/'', 1); + end_pos := instr(v_item_path, ''/'', start_pos); if end_pos = 0 then - item_name := substr(v_item_path, 1); + item_name := substr(v_item_path, start_pos); else - item_name := substr(v_item_path, 1, end_pos - start_pos); + item_name := substr(v_item_path, start_pos, end_pos - start_pos); end if; select @@ -730,7 +730,6 @@ get_id__parent_id := content_symlink__resolve(get_id__parent_id); start_pos := end_pos + 1; - v_item_path := substr(v_item_path, start_pos); end loop; @@ -768,8 +767,12 @@ v_resolved_root_id integer; v_rel_parent_id integer default 0; v_rel_tree_level integer default 0; - v_path varchar default ''''; + v_path text default ''''; v_rec record; + v_item_id integer; + v_rel_item_id integer; + v_exit_p boolean default ''f''; + v_rel_exit_p boolean default ''f''; begin -- check that the item exists @@ -780,8 +783,7 @@ end if; -- begin walking down the path to the item (from the repository root) - open c_abs_cur; - + -- if the root folder is not null then prepare for a relative path if get_path__root_folder_id is not null then @@ -795,42 +797,103 @@ -- elements of the item path as long as they are the same as the root -- folder - open c_rel_cur; + v_item_id := get_path__item_id; + v_rel_item_id := v_resolved_root_id; - while v_parent_id = v_rel_parent_id loop - fetch c_abs_cur into v_name, v_parent_id, v_tree_level; - fetch c_rel_cur into v_rel_parent_id, v_rel_tree_level; - exit when c_abs_cur%NOTFOUND or c_rel_cur%NOTFOUND; - end loop; + -- FIXME: should be replace this cursor emulation with one or two single + -- queries. - -- walk the remainder of the relative path, add a ''..'' for each + while v_parent_id = v_rel_parent_id LOOP + select + name, parent_id, tree_level(tree_sortkey) + into + v_name, v_parent_id, v_tree_level + from + cr_items + where + parent_id <> 0 + and + item_id = v_item_id; + + if NOT FOUND then + v_exit_p = ''t''; + else + v_item_id := v_parent_id; + end if; + + select + parent_id, tree_level(tree_sortkey) as tree_level + into + v_rel_parent_id, v_rel_tree_level + from + cr_items + where + parent_id <> 0 + and + item_id = v_rel_item_id; + + if NOT FOUND then + v_rel_exit_p = ''t''; + else + v_rel_item_id := v_rel_parent_id; + end if; + + if v_rel_exit_p or v_exit_p then + exit; + end if; + end LOOP; + + -- walk the remainder of the relative path, add a .. for each -- additional step - loop - exit when c_rel_cur%NOTFOUND; - v_path := v_path || ''../''; - fetch c_rel_cur into v_rel_parent_id, v_rel_tree_level; - end loop; + if not v_rel_exit_p then + v_path := v_path || ''../''; + for v_rec in select + i2.parent_id, + tree_level(i2.tree_sortkey) as tree_level + from + cr_items i1, cr_items i2 + where + i2.parent_id <> 0 + and + i1.item_id = v_rel_item_id + and + i2.tree_sortkey <= i1.tree_sortkey + and + i1.tree_sortkey like (i2.tree_sortkey || ''%'') + order by i2.tree_sortkey desc + LOOP + v_path := v_path || ''../''; + end LOOP; + end if; - -- an item relative to itself is ''../item'' - if v_resolved_root_id = item_id then + -- an item relative to itself is ../item + if v_resolved_root_id = get_path__item_id then v_path := ''../''; end if; -- loop over the remainder of the absolute path + v_path := v_path || v_name; - loop + for v_rec in select + i2.name, i2.parent_id, + tree_level(i2.tree_sortkey) as tree_level + from + cr_items i1, cr_items i2 + where + i2.parent_id <> 0 + and + i1.item_id = v_item_id + and + i2.tree_sortkey <= i1.tree_sortkey + and + i1.tree_sortkey like (i2.tree_sortkey || ''%'') + order by i2.tree_sortkey desc + + LOOP + v_path := v_path || ''/'' || v_rec.name; + end LOOP; - v_path := v_path || v_name; - - fetch c_abs_cur into v_name, v_parent_id, v_tree_level; - - exit when c_abs_cur%NOTFOUND; - - v_path := v_path || ''/''; - - end loop; - else -- select name, level as tree_level from cr_items where parent_id <> 0