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.42 -r1.43 --- openacs-4/packages/acs-content-repository/sql/postgresql/content-item.sql 17 Nov 2003 18:52:02 -0000 1.42 +++ openacs-4/packages/acs-content-repository/sql/postgresql/content-item.sql 11 Dec 2003 21:39:47 -0000 1.43 @@ -13,7 +13,7 @@ create view content_item_globals as select -100 as c_root_folder_id; -create function content_item__get_root_folder (integer) +create or replace function content_item__get_root_folder (integer) returns integer as ' declare get_root_folder__item_id alias for $1; -- default null @@ -39,7 +39,7 @@ return v_folder_id; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; -- new 19 param version of content_item__new create or replace function content_item__new ( @@ -236,7 +236,7 @@ end;' language 'plpgsql'; -- -create function content_item__new (varchar,integer,integer,varchar,timestamptz,integer,integer,varchar,varchar,varchar,varchar,varchar,varchar,varchar,varchar,varchar) +create or replace function content_item__new (varchar,integer,integer,varchar,timestamptz,integer,integer,varchar,varchar,varchar,varchar,varchar,varchar,varchar,varchar,varchar) returns integer as ' declare new__name alias for $1; @@ -392,7 +392,7 @@ end;' language 'plpgsql'; -create function content_item__new (varchar,integer,integer,varchar,timestamptz,integer,integer,varchar,varchar,varchar,varchar,varchar,varchar,varchar,integer) +create or replace function content_item__new (varchar,integer,integer,varchar,timestamptz,integer,integer,varchar,varchar,varchar,varchar,varchar,varchar,varchar,integer) returns integer as ' declare new__name alias for $1; @@ -551,7 +551,7 @@ end;' language 'plpgsql'; -create function content_item__new(varchar,integer,varchar,text,text) +create or replace function content_item__new(varchar,integer,varchar,text,text) returns integer as ' declare new__name alias for $1; @@ -580,7 +580,7 @@ end;' language 'plpgsql'; -create function content_item__new(varchar,integer) returns integer as ' +create or replace function content_item__new(varchar,integer) returns integer as ' declare new__name alias for $1; new__parent_id alias for $2; @@ -594,7 +594,7 @@ -- function new -- sets security_inherit_p to FALSE -DaveB -create function content_item__new ( integer, varchar, integer, varchar, timestamptz, integer, integer, varchar, boolean, varchar, text, varchar, boolean, varchar,varchar,varchar) +create or replace function content_item__new ( integer, varchar, integer, varchar, timestamptz, integer, integer, varchar, boolean, varchar, text, varchar, boolean, varchar,varchar,varchar) returns integer as ' declare @@ -755,7 +755,7 @@ end;' language 'plpgsql'; -create function content_item__is_published (integer) +create or replace function content_item__is_published (integer) returns boolean as ' declare is_published__item_id alias for $1; @@ -772,29 +772,37 @@ and item_id = is_published__item_id; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; -create function content_item__is_publishable (integer) +create or replace function content_item__is_publishable (integer) returns boolean as ' declare is_publishable__item_id alias for $1; v_child_count integer; v_rel_count integer; + v_content_type varchar; v_template_id cr_templates.template_id%TYPE; v_child_type record; v_rel_type record; -- v_pub_wf record; begin + -- check valid item_id + select content_item__get_content_type(is_publishable__item_id) into v_content_type; + if v_content_type is null then + raise exception ''content_item__is_publishable item_id % invalid'',is_publishable__item_id; + end if; + -- validate children -- make sure the # of children of each type fall between min_n and max_n for v_child_type in select child_type, min_n, max_n from cr_type_children where - parent_type = content_item__get_content_type(is_publishable__item_id) + parent_type = v_content_type + and (min_n is not null or max_n is not null) LOOP select count(rel_id) into v_child_count @@ -819,13 +827,14 @@ -- validate relations -- make sure the # of ext links of each type fall between min_n and max_n + -- only check if one of min_n max_n not null for v_rel_type in select target_type, min_n, max_n from cr_type_relations where - content_type = content_item__get_content_type(is_publishable__item_id) - + content_type = v_content_type + and (max_n is not null or min_n is not null) LOOP select count(rel_id) into v_rel_count @@ -879,9 +888,9 @@ return ''t''; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; --- new verson of is_valid_child that checks relation_tag +-- new verson of is_valid_child that checks relation_tag create or replace function content_item__is_valid_child (integer,varchar,varchar) returns boolean as ' @@ -942,9 +951,9 @@ return v_is_valid_child; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; -- -create function content_item__is_valid_child (integer,varchar) +create or replace function content_item__is_valid_child (integer,varchar) returns boolean as ' declare is_valid_child__item_id alias for $1; @@ -995,7 +1004,7 @@ return v_is_valid_child; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; /* delete a content item @@ -1007,7 +1016,7 @@ 6) delete keyword associations 7) delete all associated comments */ -create function content_item__delete (integer) +create or replace function content_item__delete (integer) returns integer as ' declare delete__item_id alias for $1; @@ -1132,7 +1141,7 @@ end;' language 'plpgsql'; -create function content_item__rename (integer,varchar) +create or replace function content_item__rename (integer,varchar) returns integer as ' declare rename__item_id alias for $1; @@ -1167,7 +1176,7 @@ return 0; end;' language 'plpgsql'; -create function content_item__get_id (varchar,integer,boolean) +create or replace function content_item__get_id (varchar,integer,boolean) returns integer as ' declare get_id__item_path alias for $1; @@ -1248,143 +1257,282 @@ return child_id; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; -create sequence content_item_gp_session_id; +-- create sequence content_item_gp_session_id; -create table get_path_cursors ( - rel_cursor_pos integer, - abs_cursor_pos integer -); +-- create table get_path_cursors ( +-- rel_cursor_pos integer, +-- abs_cursor_pos integer +-- ); -insert into get_path_cursors values (0,0); +-- insert into get_path_cursors values (0,0); -create table get_path_abs_cursor ( - sid integer, - pos integer, - name text, - parent_id integer, - tree_level integer, - primary key (sid,pos) -); +-- create table get_path_abs_cursor ( +-- sid integer, +-- pos integer, +-- name text, +-- parent_id integer, +-- tree_level integer, +-- primary key (sid,pos) +-- ); -create table get_path_rel_cursor ( - sid integer, - pos integer, - parent_id integer, - tree_level integer, - primary key (sid,pos) -); +-- create table get_path_rel_cursor ( +-- sid integer, +-- pos integer, +-- parent_id integer, +-- tree_level integer, +-- primary key (sid,pos) +-- ); -create function content_item__create_rel_cursor(integer,integer) -returns integer as ' -declare - v_item_id alias for $1; - v_sid alias for $2; - v_rec record; - v_cur_pos integer default 0; -begin - update get_path_cursors set rel_cursor_pos = 0; - for v_rec in select i2.name, - i2.parent_id, - tree_level(i2.tree_sortkey) as tree_level - from (select * from cr_items where item_id = v_item_id) i1, - cr_items i2 - where i2.parent_id <> 0 - and i1.tree_sortkey between i2.tree_sortkey and tree_right(i2.tree_sortkey) - order by i2.tree_sortkey +-- create or replace function content_item__create_rel_cursor(integer,integer) +-- returns integer as ' +-- declare +-- v_item_id alias for $1; +-- v_sid alias for $2; +-- v_rec record; +-- v_cur_pos integer default 0; +-- begin +-- update get_path_cursors set rel_cursor_pos = 0; +-- for v_rec in select i2.name, +-- i2.parent_id, +-- tree_level(i2.tree_sortkey) as tree_level +-- from (select * from cr_items where item_id = v_item_id) i1, +-- cr_items i2 +-- where i2.parent_id <> 0 +-- and i1.tree_sortkey between i2.tree_sortkey and tree_right(i2.tree_sortkey) +-- order by i2.tree_sortkey - LOOP - insert into get_path_rel_cursor - (sid,pos,parent_id,tree_level) - values - (v_sid,v_cur_pos,v_rec.parent_id,v_rec.tree_level); - v_cur_pos := v_cur_pos + 1; - end LOOP; +-- LOOP +-- insert into get_path_rel_cursor +-- (sid,pos,parent_id,tree_level) +-- values +-- (v_sid,v_cur_pos,v_rec.parent_id,v_rec.tree_level); +-- v_cur_pos := v_cur_pos + 1; +-- end LOOP; - return null; -end;' language 'plpgsql'; +-- return null; +-- end;' language 'plpgsql'; -create function content_item__create_abs_cursor(integer,integer) -returns integer as ' -declare - v_item_id alias for $1; - v_sid alias for $2; - v_rec record; - v_cur_pos integer default 0; -begin - update get_path_cursors set abs_cursor_pos = 0; - for v_rec in select i2.name, - i2.parent_id, - tree_level(i2.tree_sortkey) as tree_level - from (select * from cr_items where item_id = v_item_id) i1, - cr_items i2 - where i2.parent_id <> 0 - and i1.tree_sortkey between i2.tree_sortkey and tree_right(i2.tree_sortkey) - order by i2.tree_sortkey +-- create or replace function content_item__create_abs_cursor(integer,integer) +-- returns integer as ' +-- declare +-- v_item_id alias for $1; +-- v_sid alias for $2; +-- v_rec record; +-- v_cur_pos integer default 0; +-- begin +-- update get_path_cursors set abs_cursor_pos = 0; +-- for v_rec in select i2.name, +-- i2.parent_id, +-- tree_level(i2.tree_sortkey) as tree_level +-- from (select * from cr_items where item_id = v_item_id) i1, +-- cr_items i2 +-- where i2.parent_id <> 0 +-- and i1.tree_sortkey between i2.tree_sortkey and tree_right(i2.tree_sortkey) +-- order by i2.tree_sortkey - LOOP - insert into get_path_abs_cursor - (sid,pos,name,parent_id,tree_level) - values - (v_sid,v_cur_pos,v_rec.name,v_rec.parent_id,v_rec.tree_level); - v_cur_pos := v_cur_pos + 1; - end LOOP; +-- LOOP +-- insert into get_path_abs_cursor +-- (sid,pos,name,parent_id,tree_level) +-- values +-- (v_sid,v_cur_pos,v_rec.name,v_rec.parent_id,v_rec.tree_level); +-- v_cur_pos := v_cur_pos + 1; +-- end LOOP; - return null; -end;' language 'plpgsql'; +-- return null; +-- end;' language 'plpgsql'; -create function content_item__abs_cursor_next_pos() returns integer as ' -declare - v_pos integer; -begin - select abs_cursor_pos into v_pos from get_path_cursors; - update get_path_cursors set abs_cursor_pos = abs_cursor_pos + 1; +-- create or replace function content_item__abs_cursor_next_pos() returns integer as ' +-- declare +-- v_pos integer; +-- begin +-- select abs_cursor_pos into v_pos from get_path_cursors; +-- update get_path_cursors set abs_cursor_pos = abs_cursor_pos + 1; - return v_pos; -end;' language 'plpgsql'; +-- return v_pos; +-- end;' language 'plpgsql'; -create function content_item__rel_cursor_next_pos() returns integer as ' -declare - v_pos integer; -begin - select rel_cursor_pos into v_pos from get_path_cursors; - update get_path_cursors set rel_cursor_pos = rel_cursor_pos + 1; +-- create or replace function content_item__rel_cursor_next_pos() returns integer as ' +-- declare +-- v_pos integer; +-- begin +-- select rel_cursor_pos into v_pos from get_path_cursors; +-- update get_path_cursors set rel_cursor_pos = rel_cursor_pos + 1; - return v_pos; -end;' language 'plpgsql'; +-- return v_pos; +-- end;' language 'plpgsql'; -create function content_item__cleanup_cursors(integer) returns integer as ' -declare - v_sid alias for $1; -begin - delete from get_path_abs_cursor where sid = v_sid; - delete from get_path_rel_cursor where sid = v_sid; +-- -- if called with null its a noop and returns null so strict. +-- create or replace function content_item__cleanup_cursors(integer) returns integer as ' +-- declare +-- v_sid alias for $1; +-- begin +-- delete from get_path_abs_cursor where sid = v_sid; +-- delete from get_path_rel_cursor where sid = v_sid; - return null; -end;' language 'plpgsql'; +-- return null; +-- end;' language 'plpgsql' strict; -create function content_item__get_path (integer,integer) +-- old slow version +-- create or replace function content_item__get_path (integer,integer) +-- returns varchar as ' +-- declare +-- get_path__item_id alias for $1; +-- get_path__root_folder_id alias for $2; -- default null +-- v_count integer; +-- v_name varchar; +-- v_saved_name varchar; +-- v_parent_id integer default 0; +-- v_tree_level integer; +-- v_resolved_root_id integer; +-- v_rel_parent_id integer default 0; +-- v_rel_tree_level integer default 0; +-- v_path text default ''''; +-- v_rec record; +-- v_item_id integer; +-- v_rel_item_id integer; +-- v_session_id integer; +-- v_rel_found_p boolean; +-- v_abs_found_p boolean; +-- v_tmp integer; +-- begin + +-- -- check that the item exists +-- select count(*) into v_count from cr_items where item_id = get_path__item_id; + +-- if v_count = 0 then +-- raise EXCEPTION ''-20000: Invalid item ID: %'', get_path__item_id; +-- end if; + +-- -- begin walking down the path to the item (from the repository root) + +-- -- if the root folder is not null then prepare for a relative path + +-- if get_path__root_folder_id is not null then + +-- -- if root_folder_id is a symlink, resolve it (child items will point +-- -- to the actual folder, not the symlink) + +-- v_resolved_root_id := content_symlink__resolve(get_path__root_folder_id); + +-- v_session_id := nextval(''content_item_gp_session_id''); +-- PERFORM content_item__create_abs_cursor(get_path__item_id, v_session_id); +-- PERFORM content_item__create_rel_cursor(v_resolved_root_id, v_session_id); + +-- -- begin walking down the path to the root folder. Discard +-- -- elements of the item path as long as they are the same as the root +-- -- folder + +-- while v_parent_id = v_rel_parent_id loop +-- v_tmp := content_item__abs_cursor_next_pos(); +-- select name, parent_id, tree_level +-- into v_name, v_parent_id, v_tree_level +-- from get_path_abs_cursor +-- where sid = v_session_id +-- and pos = v_tmp; + +-- if NOT FOUND then +-- v_name := v_saved_name; +-- v_abs_found_p := ''f''; +-- else +-- v_saved_name := v_name; +-- v_abs_found_p := ''t''; +-- end if; + +-- v_tmp := content_item__rel_cursor_next_pos(); +-- select parent_id, tree_level +-- into v_rel_parent_id, v_rel_tree_level +-- from get_path_rel_cursor +-- where sid = v_session_id +-- and pos = v_tmp; + +-- if NOT FOUND then +-- v_rel_found_p := ''f''; +-- else +-- v_rel_found_p := ''t''; +-- end if; + +-- exit when NOT v_rel_found_p or NOT v_abs_found_p; +-- end loop; + + +-- -- walk the remainder of the relative path, add a ''..'' for each +-- -- additional step + +-- LOOP +-- exit when NOT v_rel_found_p; +-- v_path := v_path || ''../''; + +-- v_tmp := content_item__rel_cursor_next_pos(); +-- select parent_id, tree_level +-- into v_rel_parent_id, v_rel_tree_level +-- from get_path_rel_cursor +-- where sid = v_session_id +-- and pos = v_tmp; + +-- if NOT FOUND then +-- v_rel_found_p := ''f''; +-- else +-- v_rel_found_p := ''t''; +-- end if; +-- end loop; +-- -- 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 +-- LOOP + +-- v_path := v_path || v_name; +-- v_tmp := content_item__abs_cursor_next_pos(); +-- select name, parent_id, tree_level +-- into v_name, v_parent_id, v_tree_level +-- from get_path_abs_cursor +-- where sid = v_session_id +-- and pos = v_tmp; + +-- if NOT FOUND then +-- v_abs_found_p := ''f''; +-- else +-- v_abs_found_p := ''t''; +-- end if; + +-- exit when NOT v_abs_found_p; +-- v_path := v_path || ''/''; + +-- end LOOP; +-- PERFORM content_item__cleanup_cursors(v_session_id); +-- else + +-- -- this is an absolute path so prepend a ''/'' +-- -- loop over the absolute path + +-- for v_rec in select i2.name, tree_level(i2.tree_sortkey) as tree_level +-- from cr_items i1, cr_items i2 +-- where i2.parent_id <> 0 +-- and i1.item_id = get_path__item_id +-- and i1.tree_sortkey between i2.tree_sortkey and tree_right(i2.tree_sortkey) +-- order by tree_level +-- LOOP +-- v_path := v_path || ''/'' || v_rec.name; +-- end loop; + +-- end if; + +-- return v_path; + +-- end;' language 'plpgsql'; +create or replace function content_item__get_path (integer,integer) returns varchar as ' declare get_path__item_id alias for $1; get_path__root_folder_id alias for $2; -- default null v_count integer; - v_name varchar; - v_saved_name varchar; - v_parent_id integer default 0; - v_tree_level integer; v_resolved_root_id integer; - v_rel_parent_id integer default 0; - v_rel_tree_level integer default 0; v_path text default ''''; v_rec record; - v_item_id integer; - v_rel_item_id integer; - v_session_id integer; - v_rel_found_p boolean; - v_abs_found_p boolean; - v_tmp integer; begin -- check that the item exists @@ -1405,94 +1553,46 @@ v_resolved_root_id := content_symlink__resolve(get_path__root_folder_id); - v_session_id := nextval(''content_item_gp_session_id''); - PERFORM content_item__create_abs_cursor(get_path__item_id, v_session_id); - PERFORM content_item__create_rel_cursor(v_resolved_root_id, v_session_id); + -- check to see if the item is under or out side the root_id + PERFORM 1 from cr_items i, + (select tree_sortkey from cr_items where item_id = v_resolved_root_id) a + where tree_ancestor_p(a.tree_sortkey, i.tree_sortkey) and i.item_id = get_path__item_id; - -- begin walking down the path to the root folder. Discard - -- elements of the item path as long as they are the same as the root - -- folder + if NOT FOUND then + -- if not found then we need to go up the folder and append ../ until we have common ancestor - while v_parent_id = v_rel_parent_id loop - v_tmp := content_item__abs_cursor_next_pos(); - select name, parent_id, tree_level - into v_name, v_parent_id, v_tree_level - from get_path_abs_cursor - where sid = v_session_id - and pos = v_tmp; + for v_rec in select i1.name, i1.parent_id, tree_level(i1.tree_sortkey) as tree_level + from cr_items i1, (select tree_ancestor_keys(tree_sortkey) as tree_sortkey from cr_items where item_id = v_resolved_root_id) i2, + (select tree_sortkey from cr_items where item_id = get_path__item_id) i3 + where + i1.parent_id <> 0 + and i2.tree_sortkey = i1.tree_sortkey + and not tree_ancestor_p(i2.tree_sortkey, i3.tree_sortkey) + order by tree_level desc + LOOP + v_path := v_path || ''../''; + end loop; + -- lets now assign the new root_id to be the last parent_id on the loop + v_resolved_root_id := v_rec.parent_id; - if NOT FOUND then - v_name := v_saved_name; - v_abs_found_p := ''f''; - else - v_saved_name := v_name; - v_abs_found_p := ''t''; - end if; + end if; - v_tmp := content_item__rel_cursor_next_pos(); - select parent_id, tree_level - into v_rel_parent_id, v_rel_tree_level - from get_path_rel_cursor - where sid = v_session_id - and pos = v_tmp; - - if NOT FOUND then - v_rel_found_p := ''f''; - else - v_rel_found_p := ''t''; + -- go downwards the tree and append the name and / + for v_rec in select i1.name, i1.item_id, tree_level(i1.tree_sortkey) as tree_level + from cr_items i1, (select tree_sortkey from cr_items where item_id = v_resolved_root_id) i2, + (select tree_ancestor_keys(tree_sortkey) as tree_sortkey from cr_items where item_id = get_path__item_id) i3 + where + i1.tree_sortkey = i3.tree_sortkey + and i1.tree_sortkey > i2.tree_sortkey + order by tree_level + LOOP + v_path := v_path || v_rec.name; + if v_rec.item_id <> get_path__item_id then + -- put a / if we are still going down + v_path := v_path || ''/''; end if; - - exit when NOT v_rel_found_p or NOT v_abs_found_p; end loop; - - -- walk the remainder of the relative path, add a ''..'' for each - -- additional step - - LOOP - exit when NOT v_rel_found_p; - v_path := v_path || ''../''; - - v_tmp := content_item__rel_cursor_next_pos(); - select parent_id, tree_level - into v_rel_parent_id, v_rel_tree_level - from get_path_rel_cursor - where sid = v_session_id - and pos = v_tmp; - - if NOT FOUND then - v_rel_found_p := ''f''; - else - v_rel_found_p := ''t''; - end if; - end loop; - -- 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 - LOOP - - v_path := v_path || v_name; - v_tmp := content_item__abs_cursor_next_pos(); - select name, parent_id, tree_level - into v_name, v_parent_id, v_tree_level - from get_path_abs_cursor - where sid = v_session_id - and pos = v_tmp; - - if NOT FOUND then - v_abs_found_p := ''f''; - else - v_abs_found_p := ''t''; - end if; - - exit when NOT v_abs_found_p; - v_path := v_path || ''/''; - - end LOOP; - PERFORM content_item__cleanup_cursors(v_session_id); else -- this is an absolute path so prepend a ''/'' @@ -1515,7 +1615,7 @@ end;' language 'plpgsql'; -create function content_item__get_virtual_path (integer,integer) +create or replace function content_item__get_virtual_path (integer,integer) returns varchar as ' declare get_virtual_path__item_id alias for $1; @@ -1525,6 +1625,7 @@ v_is_folder boolean; v_index cr_items.item_id%TYPE; begin + -- XXX possible bug: root_folder_id arg is ignored. -- first resolve the item v_item_id := content_symlink__resolve(get_virtual_path__item_id); @@ -1544,7 +1645,7 @@ end;' language 'plpgsql'; -create function content_item__write_to_file (integer,varchar) +create or replace function content_item__write_to_file (integer,varchar) returns integer as ' declare item_id alias for $1; @@ -1571,7 +1672,7 @@ end;' language 'plpgsql'; -create function content_item__register_template (integer,integer,varchar) +create or replace function content_item__register_template (integer,integer,varchar) returns integer as ' declare register_template__item_id alias for $1; @@ -1603,7 +1704,7 @@ end;' language 'plpgsql'; -create function content_item__unregister_template (integer,integer,varchar) +create or replace function content_item__unregister_template (integer,integer,varchar) returns integer as ' declare unregister_template__item_id alias for $1; @@ -1643,7 +1744,7 @@ end;' language 'plpgsql'; -create function content_item__get_template (integer,varchar) +create or replace function content_item__get_template (integer,varchar) returns integer as ' declare get_template__item_id alias for $1; @@ -1687,10 +1788,10 @@ return v_template_id; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable strict; -create function content_item__get_content_type (integer) +create or replace function content_item__get_content_type (integer) returns varchar as ' declare get_content_type__item_id alias for $1; @@ -1704,16 +1805,12 @@ where item_id = get_content_type__item_id; - if NOT FOUND then - return null; - end if; - return v_content_type; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable strict; -create function content_item__get_live_revision (integer) +create or replace function content_item__get_live_revision (integer) returns integer as ' declare get_live_revision__item_id alias for $1; @@ -1727,16 +1824,12 @@ where item_id = get_live_revision__item_id; - if NOT FOUND then - return null; - else - return v_revision_id; - end if; + return v_revision_id; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable strict; -create function content_item__set_live_revision (integer) returns integer as ' +create or replace function content_item__set_live_revision (integer) returns integer as ' declare set_live_revision__revision_id alias for $1; set_live_revision__publish_status cr_items.publish_status%TYPE default ''ready''; @@ -1765,7 +1858,7 @@ return 0; end;' language 'plpgsql'; -create function content_item__set_live_revision (integer,varchar) +create or replace function content_item__set_live_revision (integer,varchar) returns integer as ' declare set_live_revision__revision_id alias for $1; @@ -1796,7 +1889,7 @@ end;' language 'plpgsql'; -create function content_item__unset_live_revision (integer) +create or replace function content_item__unset_live_revision (integer) returns integer as ' declare unset_live_revision__item_id alias for $1; @@ -1822,7 +1915,7 @@ return 0; end;' language 'plpgsql'; -create function content_item__set_release_period (integer, timestamptz, timestamptz) +create or replace function content_item__set_release_period (integer, timestamptz, timestamptz) returns integer as ' declare set_release_period__item_id alias for $1; @@ -1854,7 +1947,7 @@ end;' language 'plpgsql'; -create function content_item__get_revision_count (integer) +create or replace function content_item__get_revision_count (integer) returns integer as ' declare get_revision_count__item_id alias for $1; @@ -1870,10 +1963,10 @@ return v_count; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; -create function content_item__get_context (integer) +create or replace function content_item__get_context (integer) returns integer as ' declare get_context__item_id alias for $1; @@ -1890,12 +1983,12 @@ object_id = get_context__item_id; if NOT FOUND then - raise EXCEPTION ''-20000: Content item % does not exist in content_item.get_context'', item_id; + raise EXCEPTION ''-20000: Content item % does not exist in content_item.get_context'', get_context__item_id; end if; return v_context_id; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; -- 1) make sure we are not moving the item to an invalid location: @@ -1904,13 +1997,17 @@ -- to the target folder -- 3) update the parent_id for the item -create function content_item__move (integer,integer) +create or replace function content_item__move (integer,integer) returns integer as ' declare move__item_id alias for $1; move__target_folder_id alias for $2; begin + if move__target_folder_id is null then + raise exception ''attempt to move item_id % to null folder_id'', move__item_id; + end if; + if content_folder__is_folder(move__item_id) = ''t'' then PERFORM content_folder__move(move__item_id, move__target_folder_id); @@ -1936,7 +2033,7 @@ end;' language 'plpgsql'; -create function content_item__copy (integer,integer,integer,varchar) +create or replace function content_item__copy (integer,integer,integer,varchar) returns integer as ' declare item_id alias for $1; @@ -1960,7 +2057,7 @@ -- 3) create a new item with no revisions in the target folder -- 4) copy the latest revision from the original item to the new item (if any) -create function content_item__copy2 (integer,integer,integer,varchar) +create or replace function content_item__copy2 (integer,integer,integer,varchar) returns integer as ' declare copy2__item_id alias for $1; @@ -2086,11 +2183,11 @@ end;' language 'plpgsql'; -create function content_item__get_latest_revision (integer) +create or replace function content_item__get_latest_revision (integer) returns integer as ' declare - get_latest_revision__item_id alias for $1; - v_revision_id integer; + get_latest_revision__item_id alias for $1; + v_revision_id integer; v_rec record; begin for v_rec in @@ -2105,20 +2202,16 @@ order by o.creation_date desc LOOP - v_revision_id := v_rec.revision_id; - exit; + v_revision_id := v_rec.revision_id; + exit; end LOOP; - if NOT FOUND then - return null; - end if; - return v_revision_id; -end;' language 'plpgsql' with (isstrict); +end;' language 'plpgsql' strict stable; -create function content_item__get_best_revision (integer) +create or replace function content_item__get_best_revision (integer) returns integer as ' declare get_best_revision__item_id alias for $1; @@ -2134,16 +2227,12 @@ where item_id = get_best_revision__item_id; - if NOT FOUND then - return null; - end if; - return v_revision_id; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable strict; -create function content_item__get_title (integer,boolean) +create or replace function content_item__get_title (integer,boolean) returns varchar as ' declare get_title__item_id alias for $1; @@ -2185,21 +2274,21 @@ return v_title; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; -create function content_item__get_title (integer) +create or replace function content_item__get_title (integer) returns varchar as ' declare get_title__item_id alias for $1; begin return content_item__get_title(get_title__item_id, ''f''); -end;' language 'plpgsql'; +end;' language 'plpgsql' stable strict; -create function content_item__get_publish_date (integer,boolean) +create or replace function content_item__get_publish_date (integer,boolean) returns timestamptz as ' declare get_publish_date__item_id alias for $1; @@ -2228,43 +2317,32 @@ r.revision_id = i.latest_revision; end if; - if NOT FOUND then - return null; - end if; - return v_publish_date; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; -create function content_item__is_subclass (varchar,varchar) +create or replace function content_item__is_subclass (varchar,varchar) returns boolean as ' declare is_subclass__object_type alias for $1; is_subclass__supertype alias for $2; v_subclass_p boolean; v_inherit_val record; begin + select count(*) > 0 into v_subclass_p where exists ( + select 1 + from acs_object_types o, acs_object_types o2 + where o2.object_type = is_subclass__supertype + and o.object_type = is_subclass__object_type + and o.tree_sortkey between o2.tree_sortkey and tree_right(o2.tree_sortkey)); - v_subclass_p := ''f''; - - for v_inherit_val in select o.object_type - from acs_object_types o, acs_object_types o2 - where o2.object_type = is_subclass__supertype - and o.tree_sortkey between o2.tree_sortkey and tree_right(o2.tree_sortkey) - order by o.tree_sortkey - LOOP - if v_inherit_val.object_type = is_subclass__object_type then - v_subclass_p := ''t''; - end if; - end loop; - return v_subclass_p; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; -create function content_item__relate (integer,integer,varchar,integer,varchar) +create or replace function content_item__relate (integer,integer,varchar,integer,varchar) returns integer as ' declare relate__item_id alias for $1; @@ -2359,7 +2437,7 @@ end;' language 'plpgsql'; -create function content_item__unrelate (integer) +create or replace function content_item__unrelate (integer) returns integer as ' declare unrelate__rel_id alias for $1; @@ -2375,7 +2453,7 @@ end;' language 'plpgsql'; -create function content_item__is_index_page (integer,integer) +create or replace function content_item__is_index_page (integer,integer) returns boolean as ' declare is_index_page__item_id alias for $1; @@ -2387,18 +2465,18 @@ return ''f''; end if; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable; - -create function content_item__get_parent_folder (integer) +create or replace function content_item__get_parent_folder (integer) returns integer as ' declare get_parent_folder__item_id alias for $1; v_folder_id cr_folders.folder_id%TYPE; v_parent_folder_p boolean default ''f''; begin + v_folder_id := get_parent_folder__item_id; - while NOT v_parent_folder_p LOOP + while NOT v_parent_folder_p and v_folder_id is not null LOOP select parent_id, content_folder__is_folder(parent_id) @@ -2407,17 +2485,13 @@ from cr_items where - item_id = get_parent_folder__item_id; + item_id = v_folder_id; - if NOT FOUND then - return null; - end if; - end loop; return v_folder_id; -end;' language 'plpgsql'; +end;' language 'plpgsql' stable strict;