-- -- bcms/sql/postgresql/bcms-create.sql -- -- @author -- @create-date 10 Aug 2002 -- @cvs-id $Id: bcms-create.sql,v 1.9 2003/10/30 15:08:11 juny Exp $ -- -- creates bcms content types -- TODO look into if we need to define the extra content types -- this content type are just for convinience, bcms_page are the text pages, bcms_file are binary files -- bcms_images are for images --select content_type__create_type ('bcms_page', 'content_revision', 'BCMS Page', 'BCMS Pages', 'cr_bcms_pages', 'page_id', null); --select content_type__create_type ('bcms_file', 'content_revision', 'BCMS File', 'BCMS Files', 'cr_bcms_files', 'file_id', null); -- bcms_links are external links... href values --select content_type__create_type ('bcms_link', 'content_revision', 'BCMS Link', 'BCMS Links', 'cr_bcms_links', 'link_id', null); -- bcms_nav nav links are used to build the navigation --select acs_object_type__create_type ('bcms_navlink', 'BCMS Navigation Link', 'BCMS Navigation Links', 'content_item', 'cr_bcms_navlinks', 'navlink_id', null, 'f', null, null); --select acs_attribute__create_attribute ('bcms_navlink', 'nav_object_id', 'integer', 'Navigation Object ID', 'Navigation Object IDs', null, null, null, 1, 1, null, 'type_specific', 'f'); --select acs_attribute__create_attribute ('bcms_navlink', 'sort_key', 'integer', 'Sort Key', 'Sort Keys', null, null, null, 1, 1, null, 'type_specific', 'f'); -- create the relations, bcms_page may relate to another page, file, image select content_type__register_relation_type ('content_revision', 'content_revision', 'pages', '0', null); select content_type__register_relation_type ('content_revision', 'image', 'images', '0', null); create or replace function bcms__get_title(integer, varchar) returns varchar as ' declare p_item_id alias for $1; p_revision alias for $2; -- either live or latest v_title cr_revisions.title%TYPE; v_content_type acs_objects.object_type%TYPE; begin -- lets determine the content type select object_type from acs_objects into v_content_type where object_id = p_item_id; -- as of now only content_folder is treated differently if v_content_type = ''content_folder'' then -- lets get the revision_id of what we are interested in -- live or latest if p_revision = ''live'' then select r.title into v_title from cr_items i, cr_revisions r where i.parent_id = p_item_id and i.name = ''index'' and r.revision_id = i.live_revision; return v_title; end if; if p_revision = ''latest'' then select r.title into v_title from cr_items i, cr_revisions r where i.parent_id = p_item_id and i.name = ''index'' and r.revision_id = i.latest_revision; return v_title; end if; end if; -- lets get the revision_id of what we are interested in -- live or latest if p_revision = ''live'' then select r.title into v_title from cr_items i, cr_revisions r where i.item_id = p_item_id and r.revision_id = i.live_revision; return v_title; end if; if p_revision = ''latest'' then select r.title into v_title from cr_items i, cr_revisions r where i.item_id = p_item_id and r.revision_id = i.latest_revision; return v_title; end if; end; ' language 'plpgsql'; -- patched function create or replace function content_item__delete (integer) returns integer as ' declare delete__item_id alias for $1; -- v_wf_cases_val record; v_symlink_val record; v_revision_val record; v_rel_val record; begin -- Removed this as having workflow stuff in the CR is just plain wrong. -- DanW, Aug 25th, 2001. -- raise NOTICE ''Deleting associated workflows...''; -- 1) delete all workflow cases associated with this item -- for v_wf_cases_val in select -- case_id -- from -- wf_cases -- where -- object_id = delete__item_id -- LOOP -- PERFORM workflow_case__delete(v_wf_cases_val.case_id); -- end loop; raise NOTICE ''Deleting symlinks...''; -- 2) delete all symlinks to this item for v_symlink_val in select symlink_id from cr_symlinks where target_id = delete__item_id LOOP PERFORM content_symlink__delete(v_symlink_val.symlink_id); end loop; raise NOTICE ''Unscheduling item...''; delete from cr_release_periods where item_id = delete__item_id; raise NOTICE ''Deleting associated revisions...''; -- 3) delete all revisions of this item delete from cr_item_publish_audit where item_id = delete__item_id; for v_revision_val in select revision_id from cr_revisions where item_id = delete__item_id LOOP PERFORM acs_object__delete(v_revision_val.revision_id); end loop; raise NOTICE ''Deleting associated item templates...''; -- 4) unregister all templates to this item delete from cr_item_template_map where item_id = delete__item_id; raise NOTICE ''Deleting item relationships...''; -- Delete all relations on this item for v_rel_val in select rel_id from cr_item_rels where item_id = delete__item_id or related_object_id = delete__item_id LOOP PERFORM acs_rel__delete(v_rel_val.rel_id); end loop; raise NOTICE ''Deleting child relationships...''; for v_rel_val in select rel_id from cr_child_rels where child_id = delete__item_id LOOP PERFORM acs_rel__delete(v_rel_val.rel_id); end loop; raise NOTICE ''Deleting parent relationships...''; for v_rel_val in select rel_id, child_id from cr_child_rels where parent_id = delete__item_id LOOP PERFORM acs_rel__delete(v_rel_val.rel_id); PERFORM content_item__delete(v_rel_val.child_id); end loop; raise NOTICE ''Deleting associated permissions...''; -- 5) delete associated permissions delete from acs_permissions where object_id = delete__item_id; raise NOTICE ''Deleting keyword associations...''; -- 6) delete keyword associations delete from cr_item_keyword_map where item_id = delete__item_id; raise NOTICE ''Deleting associated comments...''; -- 7) delete associated comments PERFORM journal_entry__delete_for_object(delete__item_id); -- context_id debugging loop --for v_error_val in c_error_cur loop -- raise NOTICE ''ID='' || v_error_val.object_id || '' TYPE='' -- || v_error_val.object_type); --end loop; raise NOTICE ''Deleting content item...''; delete from cr_items where item_id = delete__item_id; PERFORM acs_object__delete(delete__item_id); return 0; end;' language 'plpgsql'; create or replace function content_keyword__get_path_id (integer) returns text as ' declare get_path__keyword_id alias for $1; v_path text default ''''; v_is_found boolean default ''f''; v_keyword_id cr_keywords.keyword_id%TYPE; v_rec record; begin for v_rec in select keyword_id from (select k2.keyword_id, tree_level(k2.tree_sortkey) as tree_level from cr_keywords k1, cr_keywords k2 where k1.keyword_id = get_path__keyword_id and k1.tree_sortkey between k2.tree_sortkey and tree_right(k2.tree_sortkey)) k order by tree_level LOOP v_keyword_id := v_rec.keyword_id; v_is_found := ''t''; v_path := v_path || ''/'' || v_keyword_id; end LOOP; if v_is_found = ''f'' then return null; else return v_path; end if; end;' language 'plpgsql'; -- patched root folder with resolve_index fixed create or replace function content_item__get_id (varchar,integer,boolean) returns integer as ' declare get_id__item_path alias for $1; get_id__root_folder_id alias for $2; -- default null get_id__resolve_index alias for $3; -- default ''f'' v_item_path varchar; v_root_folder_id cr_items.item_id%TYPE; get_id__parent_id integer; child_id integer; start_pos integer default 1; end_pos integer; counter integer default 1; item_name varchar; begin v_root_folder_id := coalesce(get_id__root_folder_id, content_item_globals.c_root_folder_id); -- If the request path is the root, then just return the root folder if get_id__item_path = ''/'' then if get_id__resolve_index = ''t'' then -- if the item is a folder and has an index page, then return if content_folder__is_folder(v_root_folder_id) = ''t'' and content_folder__get_index_page(v_root_folder_id) is not null then v_root_folder_id := content_folder__get_index_page(v_root_folder_id); end if; end if; return v_root_folder_id; end if; -- Remove leading, trailing spaces, leading slashes v_item_path := rtrim(ltrim(trim(get_id__item_path), ''/''), ''/''); get_id__parent_id := v_root_folder_id; -- if parent_id is a symlink, resolve it get_id__parent_id := content_symlink__resolve(get_id__parent_id); LOOP end_pos := instr(v_item_path, ''/'', 1, counter); if end_pos = 0 then item_name := substr(v_item_path, start_pos); else item_name := substr(v_item_path, start_pos, end_pos - start_pos); counter := counter + 1; end if; select item_id into child_id from cr_items where parent_id = get_id__parent_id and name = item_name; if NOT FOUND then return null; end if; exit when end_pos = 0; get_id__parent_id := child_id; -- if parent_id is a symlink, resolve it get_id__parent_id := content_symlink__resolve(get_id__parent_id); start_pos := end_pos + 1; end loop; if get_id__resolve_index = ''t'' then -- if the item is a folder and has an index page, then return if content_folder__is_folder(child_id ) = ''t'' and content_folder__get_index_page(child_id) is not null then child_id := content_folder__get_index_page(child_id); end if; end if; return child_id; end;' language 'plpgsql'; -- patched, there is a big problem when this function is called many times in a short time. 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_resolved_root_id integer; v_path text default ''''; v_rec record; 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); -- 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; if NOT FOUND then -- if not found then we need to go up the folder and append ../ until we have common ancestor 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; end if; -- 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; end loop; 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';