-- sql/api-create.sql -- -- Portal PL/SQL API. -- -- Ian Baker -- $Id: api-create.sql,v 1.1 2002/07/09 17:35:10 rmello Exp $ -- -- -- The Oracle Relational Database Management System was designed -- by a horde of gnomes whose alignment is chaotic good, and -- implemented by a second horde who were all lawful evil. -- Their marketing staff, on the other hand... -- portal is an acs_object. create or replace package portal as function new ( portal_id in portals.portal_id%TYPE default null, template_id in portals.template_id%TYPE default null, name in portals.name%TYPE default null, package_id in apm_packages.package_id%TYPE default 0, target_object_id in portals.target_object_id%TYPE default 0, owner_id in persons.person_id%TYPE default 0, parent_portal_id in portals.parent_portal_id%TYPE default null, copy_portal_id in portals.portal_id%TYPE default null, object_type in acs_object_types.object_type%TYPE default 'portal', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null ) return portals.portal_id%TYPE; procedure delete ( portal_id in portals.portal_id%TYPE ); function id_for_user ( package_id in portals.package_id%TYPE, user_id in portals.owner_id%TYPE ) return portals.portal_id%TYPE; function parent ( portal_id in portals.portal_id%TYPE ) return portals.portal_id%TYPE; function root_p ( portal_id in portals.portal_id%TYPE ) return char; function url ( -- **/ Returns the URL at which this portal is mounted. If -- * this portal is not mounted, returns null. If this portal -- * is mounted in more than one place, returns the first url -- * encountered. -- * -- * @author Michael Bryzek (mbryzek@arsdigita.com) -- * @creation-date 2001-02-09 -- **/ portal_id in portals.portal_id%TYPE ) return varchar; end portal; / show errors create or replace package body portal as function new ( portal_id in portals.portal_id%TYPE default null, template_id in portals.template_id%TYPE default null, name in portals.name%TYPE default null, package_id in apm_packages.package_id%TYPE default 0, target_object_id in portals.target_object_id%TYPE default 0, owner_id in persons.person_id%TYPE default 0, parent_portal_id in portals.parent_portal_id%TYPE default null, copy_portal_id in portals.portal_id%TYPE default null, object_type in acs_object_types.object_type%TYPE default 'portal', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null ) return portals.portal_id%TYPE is v_portal_id portals.portal_id%TYPE; v_child_p char(1); v_target_object portals.target_object_id%TYPE; begin v_portal_id := acs_object.new ( object_id => portal_id, object_type => object_type, creation_date => creation_date, creation_user => creation_user, creation_ip => creation_ip, context_id => context_id ); if new.target_object_id = 0 then v_target_object := new.package_id; else v_target_object := new.target_object_id; end if; if parent_portal_id is not null then -- create the child portal -- the passed-in values take precedence. -- -- package_id and owner_id default to zero, since null is a legal -- value for them. insert into portals ( portal_id, name, template_id, package_id, target_object_id, owner_id, parent_portal_id ) select new.v_portal_id, nvl(new.name, p.name), nvl(new.template_id, p.template_id), decode(new.package_id, 0, p.package_id, new.package_id), decode(new.v_target_object, 0, p.package_id, new.v_target_object), decode(new.owner_id, 0, p.owner_id, new.owner_id), new.parent_portal_id from portals p where portal_id = new.parent_portal_id; -- copy the portal_element_map entries insert into portal_element_map (portal_id, element_id, region, sort_key) select new.v_portal_id, m.element_id, m.region, m.sort_key from portal_element_map m where portal_id = new.parent_portal_id; elsif copy_portal_id is not null then -- copy the portal, using the source's parent_portal_id. insert into portals ( portal_id, name, template_id, package_id, target_object_id, owner_id, parent_portal_id ) select new.v_portal_id, nvl(new.name, p.name), nvl(new.template_id, p.template_id), decode(new.package_id, 0, p.package_id, new.package_id), decode(new.v_target_object, 0, p.package_id, new.v_target_object), decode(new.owner_id, 0, p.owner_id, new.owner_id), p.parent_portal_id from portals p where portal_id = new.copy_portal_id; -- copy the portal_element_map entries insert into portal_element_map (portal_id, element_id, region, sort_key) select new.v_portal_id, m.element_id, m.region, m.sort_key from portal_element_map m where portal_id = new.copy_portal_id; -- copy the available template and available element map entries, if necessary. select decode(p.parent_portal_id, NULL, 'f', 't') into v_child_p from portals p where portal_id = new.v_portal_id; if new.v_child_p = 'f' then insert into portal_available_element_map (portal_id, element_id) select new.v_portal_id, m.element_id from portal_available_element_map m where portal_id = new.copy_portal_id; insert into portal_available_template_map (portal_id, template_id) select new.v_portal_id, m.template_id from portal_available_template_map m where portal_id = new.copy_portal_id; end if; else -- it's all new. just insert the thing. insert into portals ( portal_id, template_id, name, package_id, target_object_id, owner_id, parent_portal_id ) values ( v_portal_id, template_id, name, decode(package_id, 0, NULL, package_id), v_target_object, decode(owner_id, 0, NULL, owner_id), parent_portal_id ); end if; return v_portal_id; end new; procedure delete ( portal_id in portals.portal_id%TYPE ) is begin acs_object.delete(portal_id); end delete; -- determine what the appropriate portal to present is within an -- instance of portal for a particular user. function id_for_user ( package_id in portals.package_id%TYPE, user_id in portals.owner_id%TYPE ) return portals.portal_id%TYPE is v_portal_id portals.portal_id%TYPE; begin -- I have a way to do this in a single query, but for some -- reason, PL/SQL's parser wouldn't accept it. select portal_id into v_portal_id from portals where package_id = id_for_user.package_id and owner_id = id_for_user.user_id; return v_portal_id; exception when no_data_found then select portal_id into v_portal_id from portals where package_id = id_for_user.package_id and owner_id is null; return v_portal_id; end id_for_user; -- find a portal's ultimate parent. -- only iterate a few times, since circular refs are a posibility. function parent ( portal_id in portals.portal_id%TYPE ) return portals.portal_id%TYPE is i integer(5); parent_portal_id portals.portal_id%TYPE; current_portal_id portals.portal_id%TYPE; too_many_refs exception; begin parent.current_portal_id := parent.portal_id; for i in 1..5 loop select p.parent_portal_id into parent.parent_portal_id from portals p where portal_id = parent.current_portal_id; if parent.parent_portal_id is null then return parent.current_portal_id; end if; parent.current_portal_id := parent.parent_portal_id; end loop; raise too_many_refs; exception when too_many_refs then -- this error number was picked at random. do we have -- a way to coordinate these? will there be conflicts? raise_application_error(-20304, 'Found more than 5 parent portal references (circular ref?)'); end parent; function root_p ( portal_id in portals.portal_id%TYPE ) return char is is_root_p char(1); begin select decode(p.parent_portal_id, NULL, 't', 'f') into root_p.is_root_p from portals p where p.portal_id = root_p.portal_id; return is_root_p; end root_p; function url ( portal_id in portals.portal_id%TYPE ) return varchar is v_url varchar(350); begin begin select site_node.url(n.node_id) into v_url from site_nodes n, portals, apm_packages p where n.object_id = p.package_id and p.package_id = portals.package_id and portals.portal_id = url.portal_id and rownum = 1; exception when others then return null; end; return v_url; end url; end portal; / show errors -- Templates... create or replace package portal_template as function new ( template_id in portal_templates.template_id%TYPE default null, name in portal_templates.name%TYPE, description in portal_templates.description%TYPE default null, type in portal_templates.type%TYPE default null, filename in portal_templates.filename%TYPE, resource_dir in portal_templates.resource_dir%TYPE, object_type in acs_object_types.object_type%TYPE default 'portal_template', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null ) return portal_templates.template_id%TYPE; procedure delete ( template_id in portal_templates.template_id%TYPE ); procedure add_type ( template_id in portal_templates.template_id%TYPE, mime_type in portal_mime_types.name%TYPE ); procedure add_region ( template_id in portal_supported_regions.template_id%TYPE, region in portal_supported_regions.region%TYPE, immutable_p in portal_supported_regions.immutable_p%TYPE default 'f' ); end portal_template; / show errors create or replace package body portal_template as function new ( template_id in portal_templates.template_id%TYPE default null, name in portal_templates.name%TYPE, description in portal_templates.description%TYPE default null, type in portal_templates.type%TYPE default null, filename in portal_templates.filename%TYPE, resource_dir in portal_templates.resource_dir%TYPE, object_type in acs_object_types.object_type%TYPE default 'portal_template', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null ) return portal_templates.template_id%TYPE is v_template_id portal_templates.template_id%TYPE; begin v_template_id := acs_object.new ( object_id => template_id, object_type => object_type, creation_date => creation_date, creation_user => creation_user, creation_ip => creation_ip, context_id => context_id ); insert into portal_templates (template_id, name, description, type, filename, resource_dir) values (v_template_id, name, description, type, filename, resource_dir); return v_template_id; end new; procedure delete ( template_id in portal_templates.template_id%TYPE ) is begin acs_object.delete(template_id); end delete; procedure add_type ( template_id in portal_templates.template_id%TYPE, mime_type in portal_mime_types.name%TYPE ) is begin insert into portal_available_mime_type_map (template_id, mime_type) values (template_id, mime_type); end add_type; procedure add_region ( template_id in portal_supported_regions.template_id%TYPE, region in portal_supported_regions.region%TYPE, immutable_p in portal_supported_regions.immutable_p%TYPE default 'f' ) is begin insert into portal_supported_regions (template_id, region, immutable_p) values (template_id, region, immutable_p); end add_region; end portal_template; / show errors -- element configs... create or replace package portal_element_config as function new ( config_id in portal_element_configs.config_id%TYPE default null, portal_id in acs_objects.object_id%TYPE default null, object_type in acs_object_types.object_type%TYPE default 'portal_element_config', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null ) return portal_element_configs.config_id%TYPE; procedure delete ( config_id in portal_element_configs.config_id%TYPE ); procedure assign ( config_id in portal_element_configs.config_id%TYPE default null, to_element in portal_elements.element_id%TYPE default null, from_element in portal_elements.element_id%TYPE default null, to_datasource in portal_datasources.datasource_id%TYPE default null, from_datasource in portal_datasources.datasource_id%TYPE default null ); end portal_element_config; / show errors create or replace package body portal_element_config as function new ( config_id in portal_element_configs.config_id%TYPE default null, portal_id in acs_objects.object_id%TYPE default null, object_type in acs_object_types.object_type%TYPE default 'portal_element_config', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null ) return portal_element_configs.config_id%TYPE is v_config_id portal_element_configs.config_id%TYPE; begin v_config_id := acs_object.new ( object_id => config_id, object_type => object_type, creation_date => creation_date, creation_user => creation_user, creation_ip => creation_ip, context_id => context_id ); insert into portal_element_configs (config_id, portal_id) values (config_id, portal_id); return v_config_id; end new; procedure delete ( config_id in portal_element_configs.config_id%TYPE ) is begin acs_object.delete(config_id); end delete; procedure assign ( config_id in portal_element_configs.config_id%TYPE default null, to_element in portal_elements.element_id%TYPE default null, from_element in portal_elements.element_id%TYPE default null, to_datasource in portal_datasources.datasource_id%TYPE default null, from_datasource in portal_datasources.datasource_id%TYPE default null ) is v_config_id portal_element_configs.config_id%TYPE; begin if config_id is not null then v_config_id := config_id; elsif from_element is not null then select config_id into v_config_id from portal_elements where element_id = assign.from_element; elsif from_datasource is not null then select config_id into v_config_id from portal_datasources where datasource_id = assign.from_datasource; else v_config_id := null; end if; if to_element is not null then update portal_elements set config_id = v_config_id where element_id = assign.to_element; end if; if to_datasource is not null then update portal_datasources set default_config_id = v_config_id where datasource_id = assign.to_datasource; end if; end assign; end portal_element_config; / show errors -- datasources create or replace package portal_datasource as function new ( datasource_id in portal_datasources.datasource_id%TYPE default null, data_type in portal_datasources.data_type%TYPE default null, mime_type in portal_datasources.mime_type%TYPE default null, default_config_id in portal_datasources.default_config_id%TYPE default null, name in portal_datasources.name%TYPE default null, description in portal_datasources.description%TYPE default null, configurable_p in portal_datasources.configurable_p%TYPE default null, content in portal_datasources.content%TYPE default null, content_varchar varchar default null, package_key apm_package_types.package_key%TYPE default null, object_type in acs_object_types.object_type%TYPE default 'portal_datasource', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null ) return portal_datasources.datasource_id%TYPE; procedure delete ( datasource_id in portal_datasources.datasource_id%TYPE ); end portal_datasource; / show errors create or replace package body portal_datasource as function new ( datasource_id in portal_datasources.datasource_id%TYPE default null, data_type in portal_datasources.data_type%TYPE default null, mime_type in portal_datasources.mime_type%TYPE default null, default_config_id in portal_datasources.default_config_id%TYPE default null, name in portal_datasources.name%TYPE default null, description in portal_datasources.description%TYPE default null, configurable_p in portal_datasources.configurable_p%TYPE default null, content in portal_datasources.content%TYPE default null, content_varchar varchar default null, package_key apm_package_types.package_key%TYPE default null, object_type in acs_object_types.object_type%TYPE default 'portal_datasource', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null ) return portal_datasources.datasource_id%TYPE is v_datasource_id portal_datasources.datasource_id%TYPE; v_content_loc portal_datasources.content%TYPE; begin v_datasource_id := acs_object.new ( object_id => datasource_id, object_type => object_type, creation_date => creation_date, creation_user => creation_user, creation_ip => creation_ip, context_id => context_id ); if content_varchar is not null then dbms_lob.createtemporary(v_content_loc, TRUE); dbms_lob.write(v_content_loc, length(new.content_varchar), 1, new.content_varchar); else v_content_loc := content; end if; insert into portal_datasources (datasource_id, data_type, mime_type, default_config_id, name, description, configurable_p, content, package_key) values (v_datasource_id, data_type, mime_type, default_config_id, name, description, configurable_p, v_content_loc, package_key); return v_datasource_id; end new; procedure delete ( datasource_id in portal_datasources.datasource_id%TYPE ) is begin acs_object.delete(datasource_id); end delete; end portal_datasource; / show errors -- elements create or replace package portal_element as function new ( element_id in portal_elements.element_id%TYPE default null, name in portal_elements.name%TYPE, description in portal_elements.description%TYPE default null, exportable_p in portal_elements.exportable_p%TYPE default null, datasource_id in portal_elements.datasource_id%TYPE, controlling_portal_id in portal_elements.controlling_portal_id%TYPE, template_id in portal_elements.template_id%TYPE default null, config_id in portal_elements.config_id%TYPE default null, default_config_id in portal_elements.default_config_id%TYPE default null, object_type in acs_object_types.object_type%TYPE default 'portal_element', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null ) return portal_elements.element_id%TYPE; procedure delete ( element_id in portal_elements.element_id%TYPE ); procedure make_available ( element_id in portal_available_element_map.element_id%TYPE, portal_id in portal_available_element_map.portal_id%TYPE ); procedure move ( portal_id in portal_element_map.portal_id%TYPE, sort_key in portal_element_map.sort_key%TYPE, region in portal_element_map.region%TYPE, direction varchar ); end portal_element; / show errors create or replace package body portal_element as function new ( element_id in portal_elements.element_id%TYPE default null, name in portal_elements.name%TYPE, description in portal_elements.description%TYPE default null, exportable_p in portal_elements.exportable_p%TYPE default null, datasource_id in portal_elements.datasource_id%TYPE, controlling_portal_id in portal_elements.controlling_portal_id%TYPE, template_id in portal_elements.template_id%TYPE default null, config_id in portal_elements.config_id%TYPE default null, default_config_id in portal_elements.default_config_id%TYPE default null, object_type in acs_object_types.object_type%TYPE default 'portal_element', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null ) return portal_elements.element_id%TYPE is v_element_id portal_elements.element_id%TYPE; v_config_id portal_elements.config_id%TYPE; begin v_element_id := acs_object.new ( object_id => element_id, object_type => object_type, creation_date => creation_date, creation_user => creation_user, creation_ip => creation_ip, context_id => context_id ); -- use the default configuration if none was supplied. if config_id is null then select default_config_id into v_config_id from portal_datasources where datasource_id = new.datasource_id; else v_config_id := config_id; end if; insert into portal_elements (element_id, name, description, datasource_id, template_id, config_id, default_config_id, exportable_p, controlling_portal_id) values (v_element_id, name, description, datasource_id, template_id, v_config_id, default_config_id, exportable_p, controlling_portal_id); return v_element_id; end new; procedure delete ( element_id in portal_elements.element_id%TYPE ) is begin acs_object.delete(element_id); end delete; procedure make_available ( element_id in portal_available_element_map.element_id%TYPE, portal_id in portal_available_element_map.portal_id%TYPE ) is v_exists_p char(1); begin select 't' into v_exists_p from portal_available_element_map m where m.element_id = make_available.element_id and m.portal_id = make_available.portal_id; exception when no_data_found then insert into portal_available_element_map (element_id, portal_id) values (element_id, portal_id); end make_available; -- a procedure to swap an element in one position with the adjacent element, either -- up or down. This is so strange because the sort_key column is constrained to -- be unique, the keys are not guaranteed to be contiguous, and a single element can -- occur more than once in a region. procedure move ( portal_id in portal_element_map.portal_id%TYPE, sort_key in portal_element_map.sort_key%TYPE, region in portal_element_map.region%TYPE, direction varchar ) is v_other_key portal_element_map.sort_key%TYPE; v_element_id portal_element_map.element_id%TYPE; invalid_direction exception; begin if direction = 'up' then -- get the previous sort key. select sort_key into v_other_key from ( select sort_key from portal_element_map where portal_id = move.portal_id and region = move.region and sort_key < move.sort_key order by sort_key desc ) where rownum = 1; elsif direction = 'down' then -- get the next sort key. select sort_key into v_other_key from ( select sort_key from portal_element_map where portal_id = move.portal_id and region = move.region and sort_key > move.sort_key order by sort_key ) where rownum = 1; else raise invalid_direction; end if; -- get the element_id in that position. select element_id into v_element_id from portal_element_map where portal_id = move.portal_id and region = move.region and sort_key = move.sort_key; -- remove the one we know everything about. delete from portal_element_map where portal_id = move.portal_id and region = move.region and sort_key = move.sort_key; -- move the other one into its position. update portal_element_map set sort_key = move.sort_key where portal_id = move.portal_id and region=move.region and sort_key = v_other_key; -- reinsert the original entry. insert into portal_element_map ( portal_id, element_id, region, sort_key ) values ( move.portal_id, v_element_id, move.region, v_other_key ); exception -- there was no previous sort key, or something like that. when no_data_found then null; when invalid_direction then null; end move; end portal_element; / show errors