-- package specification
create or replace package content_type AUTHID CURRENT_USER as
--/** This package is used to manipulate content types and attributes
--
--*/
procedure create_type (
--/** Create a new content type. Automatically create the attribute table
-- for the type if the table does not already exist.
-- @author Karl Goldstein
-- @param content_type The name of the new type
-- @param supertype The supertype, defaults to content_revision
-- @param pretty_name Pretty name for the type, singular
-- @param pretty_plural Pretty name for the type, plural
-- @param table_name The name for the attribute table, defaults to
-- the name of the supertype
-- @param id_column The primary key for the table, defaults to 'XXX'
-- @param name_method As in acs_object_type.create_type
-- @see {acs_object_type.create_type}
--*/
content_type in acs_object_types.object_type%TYPE,
supertype in acs_object_types.object_type%TYPE
default 'content_revision',
pretty_name in acs_object_types.pretty_name%TYPE,
pretty_plural in acs_object_types.pretty_plural%TYPE,
table_name in acs_object_types.table_name%TYPE default null,
id_column in acs_object_types.id_column%TYPE default 'XXX',
name_method in acs_object_types.name_method%TYPE default null
);
procedure drop_type (
--/** First drops all attributes related to a specific type, then drops type
-- the given type.
-- @author Simon Huynh
-- @param content_type The content type to be dropped
-- @param drop_children_p If 't', then the sub-types
-- of the given content type and their associated tables
-- are also dropped.
--*/
content_type in acs_object_types.object_type%TYPE,
drop_children_p in char default 'f',
drop_table_p in char default 'f',
drop_objects_p in char default 'f'
);
function create_attribute (
--/** Create a new attribute for the specified type. Automatically create
-- the column for the attribute if the column does not already exist.
-- @author Karl Goldstein
-- @param content_type The name of the type to alter
-- @param attribute_name The name of the attribute to create
-- @param pretty_name Pretty name for the new attribute, singular
-- @param pretty_plural Pretty name for the new attribute, plural
-- @param default_value The default value for the attribute, defaults to null
-- @return The id of the newly created attribute
-- @see {acs_object_type.create_attribute}, {content_type.create_type}
--*/
content_type in acs_attributes.object_type%TYPE,
attribute_name in acs_attributes.attribute_name%TYPE,
datatype in acs_attributes.datatype%TYPE,
pretty_name in acs_attributes.pretty_name%TYPE,
pretty_plural in acs_attributes.pretty_plural%TYPE default null,
sort_order in acs_attributes.sort_order%TYPE default null,
default_value in acs_attributes.default_value%TYPE default null,
column_spec in varchar2 default 'varchar2(4000)'
) return acs_attributes.attribute_id%TYPE;
procedure drop_attribute (
--/** Drop an existing attribute. If you are using CMS, make sure to
-- call cm_form_widget.unregister_attribute_widget before calling
-- this function.
-- @author Karl Goldstein
-- @param content_type The name of the type to alter
-- @param attribute_name The name of the attribute to drop
-- @param drop_column If 't', will also alter the table and remove
-- the column where the attribute is stored. The default is 'f'
-- (leaves the table untouched).
-- @see {acs_object.drop_attribute}, {content_type.create_attribute},
-- {cm_form_widget.unregister_attribute_widget}
--*/
content_type in acs_attributes.object_type%TYPE,
attribute_name in acs_attributes.attribute_name%TYPE,
drop_column in varchar2 default 'f'
);
procedure register_template (
--/** Register a template for the content type. This template may be used
-- to render all items of that type.
-- @author Karl Goldstein
-- @param content_type The type for which the template is to be registered
-- @param template_id The ID of the template to register
-- @param use_context The context in which the template is appropriate, such
-- as 'admin' or 'public'
-- @param is_default If 't', this template becomes the default template for
-- the type, default is 'f'.
-- @see {content_item.register_template}, {content_item.unregister_template},
-- {content_item.get_template}, {content_type.unregister_template},
-- {content_type.set_default_template}, {content_type.get_template}
--*/
content_type in cr_type_template_map.content_type%TYPE,
template_id in cr_templates.template_id%TYPE,
use_context in cr_type_template_map.use_context%TYPE,
is_default in cr_type_template_map.is_default%TYPE default 'f'
);
procedure set_default_template (
--/** Make the registered template a default template. The default template
-- will be used to render all items of the type for which no individual
-- template is registered.
-- @author Karl Goldstein
-- @param content_type The type for which the template is to be made default
-- @param template_id The ID of the template to make default
-- @param use_context The context in which the template is appropriate, such
-- as 'admin' or 'public'
-- @see {content_item.register_template}, {content_item.unregister_template},
-- {content_item.get_template}, {content_type.unregister_template},
-- {content_type.register_template}, {content_type.get_template}
--*/
content_type in cr_type_template_map.content_type%TYPE,
template_id in cr_templates.template_id%TYPE,
use_context in cr_type_template_map.use_context%TYPE
);
function get_template (
--/** Retrieve the appropriate template for rendering items of the specified type.
-- @author Karl Goldstein
-- @param content_type The type for which the template is to be retrieved
-- @param use_context The context in which the template is appropriate, such
-- as 'admin' or 'public'
-- @return The ID of the template to use
-- @see {content_item.register_template}, {content_item.unregister_template},
-- {content_item.get_template}, {content_type.unregister_template},
-- {content_type.register_template}, {content_type.set_default_template}
--*/
content_type in cr_type_template_map.content_type%TYPE,
use_context in cr_type_template_map.use_context%TYPE
) return cr_templates.template_id%TYPE;
procedure unregister_template (
--/** Unregister a template. If the unregistered template was the default template,
-- the content_type can no longer be rendered in the use_context,
-- @author Karl Goldstein
-- @param content_type The type for which the template is to be unregistered
-- @param template_id The ID of the template to unregister
-- @param use_context The context in which the template is to be unregistered
-- @see {content_item.register_template}, {content_item.unregister_template},
-- {content_item.get_template}, {content_type.set_default_template},
-- {content_type.register_template}, {content_type.get_template}
--*/
content_type in cr_type_template_map.content_type%TYPE default null,
template_id in cr_templates.template_id%TYPE,
use_context in cr_type_template_map.use_context%TYPE default null
);
procedure refresh_view (
--/** Create a view for the type which joins all attributes of the type,
-- including the inherited attributes. The view is named
-- "
X"
-- Called by create_attribute and create_type.
-- @author Karl Goldstein
-- @param content_type The type for which the view is to be created.
-- @see {content_type.create_type}
--*/
content_type in cr_type_template_map.content_type%TYPE
);
procedure register_relation_type (
--/** Register a relationship between a content type and another object
-- type. This may then be used by the content_item.is_valid_relation
-- function to validate any relationship between an item and another
-- object.
-- @author Karl Goldstein
-- @param content_type The type of the item from which the relationship
-- originated.
-- @param target_type The type of the item to which the relationship
-- is targeted.
-- @param relation_tag A simple token used to identify a set of
-- relations.
-- @param min_n The minimum number of relationships of this type
-- which an item must have to go live.
-- @param max_n The minimum number of relationships of this type
-- which an item must have to go live.
-- @see {content_type.unregister_relation_type}
--*/
content_type in cr_type_relations.content_type%TYPE,
target_type in cr_type_relations.target_type%TYPE,
relation_tag in cr_type_relations.relation_tag%TYPE default 'generic',
min_n in integer default 0,
max_n in integer default null
);
procedure unregister_relation_type (
--/** Unregister a relationship between a content type and another object
-- type.
-- @author Karl Goldstein
-- @param content_type The type of the item from which the relationship
-- originated.
-- @param target_type The type of the item to which the relationship
-- is targeted.
-- @param relation_tag A simple token used to identify a set of
-- relations.
-- @see {content_type.register_relation_type}
--*/
content_type in cr_type_relations.content_type%TYPE,
target_type in cr_type_relations.target_type%TYPE,
relation_tag in cr_type_relations.relation_tag%TYPE default null
);
procedure register_child_type (
--/** Register a parent-child relationship between a content type
-- and another object
-- type. This may then be used by the content_item.is_valid_relation
-- function to validate the relationship between an item and a potential
-- child.
-- @author Karl Goldstein
-- @param content_type The type of the item from which the relationship
-- originated.
-- @param child_type The type of the child item.
-- @param relation_tag A simple token used to identify a set of
-- relations.
-- @param min_n The minimum number of parent-child
-- relationships of this type
-- which an item must have to go live.
-- @param max_n The minimum number of relationships of this type
-- which an item must have to go live.
-- @see {content_type.register_relation_type}, {content_type.register_child_type}
--*/
parent_type in cr_type_children.parent_type%TYPE,
child_type in cr_type_children.child_type%TYPE,
relation_tag in cr_type_children.relation_tag%TYPE default 'generic',
min_n in integer default 0,
max_n in integer default null
);
procedure unregister_child_type (
--/** Register a parent-child relationship between a content type
-- and another object
-- type. This may then be used by the content_item.is_valid_relation
-- function to validate the relationship between an item and a potential
-- child.
-- @author Karl Goldstein
-- @param parent_type The type of the parent item.
-- @param child_type The type of the child item.
-- @param relation_tag A simple token used to identify a set of
-- relations.
-- @see {content_type.register_relation_type}, {content_type.register_child_type}
--*/
parent_type in cr_type_children.parent_type%TYPE,
child_type in cr_type_children.child_type%TYPE,
relation_tag in cr_type_children.relation_tag%TYPE default null
);
procedure register_mime_type (
content_type in cr_content_mime_type_map.content_type%TYPE,
mime_type in cr_content_mime_type_map.mime_type%TYPE
);
procedure unregister_mime_type (
content_type in cr_content_mime_type_map.content_type%TYPE,
mime_type in cr_content_mime_type_map.mime_type%TYPE
);
function is_content_type (
object_type in acs_object_types.object_type%TYPE
) return char;
procedure rotate_template (
--/** Sets the default template for a content type and registers all the
-- previously existing items of that content type to the original
-- template
-- @author Michael Pih
-- @param template_id The template that will become the default
-- registered template for the specified content type and use context
-- @param v_content_type The content type
-- @param use_context The context in which the template will be used
--*/
template_id in cr_templates.template_id%TYPE,
v_content_type in cr_items.content_type%TYPE,
use_context in cr_type_template_map.use_context%TYPE
);
-- Create or replace a trigger on insert for simplifying addition of
-- revisions for any content type
procedure refresh_trigger (
content_type in acs_object_types.object_type%TYPE
);
end content_type;
/
show errors;
-- package body
create or replace package body content_type is
procedure create_type (
content_type in acs_object_types.object_type%TYPE,
supertype in acs_object_types.object_type%TYPE
default 'content_revision',
pretty_name in acs_object_types.pretty_name%TYPE,
pretty_plural in acs_object_types.pretty_plural%TYPE,
table_name in acs_object_types.table_name%TYPE default null,
id_column in acs_object_types.id_column%TYPE default 'XXX',
name_method in acs_object_types.name_method%TYPE default null
) is
table_exists integer;
v_supertype_table acs_object_types.table_name%TYPE;
v_count integer;
begin
if (supertype != 'content_revision') and (content_type != 'content_revision') then
select count(*)
into v_count
from acs_object_type_supertype_map
where object_type = create_type.supertype
and ancestor_type = 'content_revision';
if v_count = 0 then
raise_application_error(-20000, 'Content types can only be created as subclasses of content_revision or a derivation thereof. ' || supertype || ' is not a subclass oc content_revision.');
end if;
end if;
-- create the attribute table if not already created
select decode(count(*),0,0,1) into table_exists from user_tables
where table_name = upper(create_type.table_name);
if table_exists = 0 then
select table_name into v_supertype_table from acs_object_types
where object_type = create_type.supertype;
execute immediate 'create table ' || table_name || ' (' ||
id_column || ' integer primary key references ' ||
v_supertype_table || ')';
end if;
acs_object_type.create_type (
supertype => create_type.supertype,
object_type => create_type.content_type,
pretty_name => create_type.pretty_name,
pretty_plural => create_type.pretty_plural,
table_name => create_type.table_name,
id_column => create_type.id_column,
name_method => create_type.name_method
);
refresh_view(content_type);
end create_type;
procedure drop_type (
content_type in acs_object_types.object_type%TYPE,
drop_children_p in char default 'f',
drop_table_p in char default 'f',
drop_objects_p in char default 'f'
) is
cursor attribute_cur is
select
attribute_name
from
acs_attributes
where
object_type = drop_type.content_type;
cursor child_type_cur is
select
object_type
from
acs_object_types
where
supertype = drop_type.content_type;
cursor revision_cur is
select revision_id
from cr_revisions, acs_objects
where revision_id = object_id
and object_type = drop_type.content_type;
cursor item_cur is
select item_id
from cr_items
where content_type = drop_type.content_type;
table_exists integer;
v_table_name varchar2(50);
is_subclassed_p char;
begin
-- first we'll rid ourselves of any dependent child types, if any , along with their
-- own dependent grandchild types
select
decode(count(*),0,'f','t') into is_subclassed_p
from
acs_object_types
where supertype = drop_type.content_type;
-- this is weak and will probably break;
-- to remove grand child types, the process will probably
-- require some sort of querying for drop_type
-- methods within the children's packages to make
-- certain there are no additional unanticipated
-- restraints preventing a clean drop
if drop_children_p = 't' and is_subclassed_p = 't' then
for child_rec in child_type_cur loop
drop_type(
content_type => child_rec.object_type,
drop_children_p => 't',
drop_table_p => drop_table_p,
drop_objects_p => drop_objects_p );
end loop;
end if;
-- now drop all the attributes related to this type
for attr_row in attribute_cur loop
drop_attribute(
content_type => drop_type.content_type,
attribute_name => attr_row.attribute_name
);
end loop;
-- we'll remove the associated table if it exists
select
decode(count(*),0,0,1) into table_exists
from
user_tables u, acs_object_types object
where
object.object_type = drop_type.content_type and
u.table_name = upper(object.table_name);
if table_exists = 1 and drop_table_p = 't' then
select
table_name into v_table_name
from
acs_object_types
where
object_type = drop_type.content_type;
-- drop the input/output views for the type
-- being dropped.
-- FIXME: does the trigger get dropped when the
-- view is dropped? This did not exist in the 4.2 release,
-- and it needs to be tested.
execute immediate 'drop view ' || v_table_name || 'x';
execute immediate 'drop view ' || v_table_name || 'i';
execute immediate 'drop table ' || v_table_name;
end if;
if drop_objects_p = 't' then
for revision_row in revision_cur loop
content_revision.del(
revision_id => revision_row.revision_id
);
end loop;
for item_row in item_cur loop
content_item.del(
item_id => item_row.item_id
);
end loop;
end if;
acs_object_type.drop_type(
object_type => drop_type.content_type
);
end drop_type;
function create_attribute (
content_type in acs_attributes.object_type%TYPE,
attribute_name in acs_attributes.attribute_name%TYPE,
datatype in acs_attributes.datatype%TYPE,
pretty_name in acs_attributes.pretty_name%TYPE,
pretty_plural in acs_attributes.pretty_plural%TYPE default null,
sort_order in acs_attributes.sort_order%TYPE default null,
default_value in acs_attributes.default_value%TYPE default null,
column_spec in varchar2 default 'varchar2(4000)'
) return acs_attributes.attribute_id%TYPE is
v_attr_id acs_attributes.attribute_id%TYPE;
v_table_name acs_object_types.table_name%TYPE;
v_column_exists integer;
begin
-- add the appropriate column to the table
begin
select upper(table_name) into v_table_name from acs_object_types
where object_type = create_attribute.content_type;
exception when no_data_found then
raise_application_error(-20000, 'Content type ''' || content_type ||
''' does not exist in content_type.create_attribute');
end;
select decode(count(*),0,0,1) into v_column_exists from user_tab_columns
where table_name = v_table_name
and column_name = upper(attribute_name);
if v_column_exists = 0 then
execute immediate 'alter table ' || v_table_name || ' add ' ||
attribute_name || ' ' || column_spec;
end if;
v_attr_id := acs_attribute.create_attribute (
object_type => create_attribute.content_type,
attribute_name => create_attribute.attribute_name,
datatype => create_attribute.datatype,
pretty_name => create_attribute.pretty_name,
pretty_plural => create_attribute.pretty_plural,
sort_order => create_attribute.sort_order,
default_value => create_attribute.default_value
);
refresh_view(content_type);
return v_attr_id;
end create_attribute;
procedure drop_attribute (
content_type in acs_attributes.object_type%TYPE,
attribute_name in acs_attributes.attribute_name%TYPE,
drop_column in varchar2 default 'f'
)
is
v_attr_id acs_attributes.attribute_id%TYPE;
v_table acs_object_types.table_name%TYPE;
begin
-- Get attribute information
begin
select
upper(t.table_name), a.attribute_id
into
v_table, v_attr_id
from
acs_object_types t, acs_attributes a
where
t.object_type = drop_attribute.content_type
and
a.object_type = drop_attribute.content_type
and
a.attribute_name = drop_attribute.attribute_name;
exception when no_data_found then
raise_application_error(-20000, 'Attribute ' || content_type || ':' ||
attribute_name || ' does not exist in content_type.drop_attribute');
end;
-- Drop the attribute
acs_attribute.drop_attribute(content_type, attribute_name);
-- Drop the column if necessary
if drop_column = 't' then
begin
execute immediate 'alter table ' || v_table || ' drop column ' ||
attribute_name;
exception when others then
raise_application_error(-20000, 'Unable to drop column ' ||
v_table || '.' || attribute_name || ' in content_type.drop_attribute');
end;
end if;
refresh_view(content_type);
end drop_attribute;
procedure register_template (
content_type in cr_type_template_map.content_type%TYPE,
template_id in cr_templates.template_id%TYPE,
use_context in cr_type_template_map.use_context%TYPE,
is_default in cr_type_template_map.is_default%TYPE default 'f'
) is
v_template_registered integer;
begin
select
count(*) into v_template_registered
from
cr_type_template_map
where
content_type = register_template.content_type
and
use_context = register_template.use_context
and
template_id = register_template.template_id;
-- register the template
if v_template_registered = 0 then
insert into cr_type_template_map (
template_id, content_type, use_context, is_default
) values (
template_id, content_type, use_context, is_default
);
-- update the registration status of the template
else
-- unset the default template before setting this one as the default
if register_template.is_default = 't' then
update cr_type_template_map
set is_default = 'f'
where content_type = register_template.content_type
and use_context = register_template.use_context;
end if;
update cr_type_template_map
set is_default = register_template.is_default
where template_id = register_template.template_id
and content_type = register_template.content_type
and use_context = register_template.use_context;
end if;
end register_template;
procedure set_default_template (
content_type in cr_type_template_map.content_type%TYPE,
template_id in cr_templates.template_id%TYPE,
use_context in cr_type_template_map.use_context%TYPE
) is
begin
update cr_type_template_map
set is_default = 't'
where template_id = set_default_template.template_id
and content_type = set_default_template.content_type
and use_context = set_default_template.use_context;
-- make sure there is only one default template for
-- any given content_type/use_context pair
update cr_type_template_map
set is_default = 'f'
where template_id ^= set_default_template.template_id
and content_type = set_default_template.content_type
and use_context = set_default_template.use_context
and is_default = 't';
end set_default_template;
function get_template (
content_type in cr_type_template_map.content_type%TYPE,
use_context in cr_type_template_map.use_context%TYPE
) return cr_templates.template_id%TYPE
is
v_template_id cr_templates.template_id%TYPE;
begin
select
template_id
into
v_template_id
from
cr_type_template_map
where
content_type = get_template.content_type
and
use_context = get_template.use_context
and
is_default = 't';
return v_template_id;
exception
when NO_DATA_FOUND then
return null;
end get_template;
procedure unregister_template (
content_type in cr_type_template_map.content_type%TYPE default null,
template_id in cr_templates.template_id%TYPE,
use_context in cr_type_template_map.use_context%TYPE default null
) is
begin
if unregister_template.use_context is null and
unregister_template.content_type is null then
delete from cr_type_template_map
where template_id = unregister_template.template_id;
elsif unregister_template.use_context is null then
delete from cr_type_template_map
where template_id = unregister_template.template_id
and content_type = unregister_template.content_type;
elsif unregister_template.content_type is null then
delete from cr_type_template_map
where template_id = unregister_template.template_id
and use_context = unregister_template.use_context;
else
delete from cr_type_template_map
where template_id = unregister_template.template_id
and content_type = unregister_template.content_type
and use_context = unregister_template.use_context;
end if;
end unregister_template;
-- Helper function for refresh_trigger (below) to generate the
-- insert statement for a particular content type;
function trigger_insert_statement (
content_type in acs_object_types.object_type%TYPE
) return varchar2 is
v_table_name acs_object_types.table_name%TYPE;
v_id_column acs_object_types.id_column%TYPE;
cursor attr_cur is
select
attribute_name
from
acs_attributes
where
object_type = trigger_insert_statement.content_type;
cols varchar2(2000) := '';
vals varchar2(2000) := '';
begin
select table_name, id_column into v_table_name, v_id_column
from acs_object_types where
object_type = trigger_insert_statement.content_type;
for attr_rec in attr_cur loop
cols := cols || ', ' || attr_rec.attribute_name;
vals := vals || ', :new.' || attr_rec.attribute_name;
end loop;
return 'insert into ' || v_table_name ||
' ( ' || v_id_column || cols || ' ) values ( new_revision_id' ||
vals || ')';
end trigger_insert_statement;
-- Create or replace a trigger on insert for simplifying addition of
-- revisions for any content type
procedure refresh_trigger (
content_type in acs_object_types.object_type%TYPE
) is
tr_text varchar2(10000) := '';
v_table_name acs_object_types.table_name%TYPE;
cursor type_cur is
select
object_type
from
acs_object_types
where
object_type ^= 'acs_object'
and
object_type ^= 'content_revision'
connect by
prior supertype = object_type
start with
object_type = refresh_trigger.content_type
order by
level desc;
begin
-- get the table name for the content type (determines view name)
select table_name into v_table_name
from acs_object_types where object_type = refresh_trigger.content_type;
-- start building trigger code
tr_text := '
create or replace trigger ' || v_table_name || 't
instead of insert on ' || v_table_name || 'i
for each row
declare
new_revision_id integer;
begin
if :new.item_id is null then
raise_application_error(-20000, ''item_id is required when inserting into ' ||
v_table_name || 'i '');
end if;
if :new.text is not null then
new_revision_id := content_revision.new(
revision_id => :new.revision_id,
title => :new.title,
description => :new.description,
mime_type => :new.mime_type,
nls_language => :new.nls_language,
item_id => content_symlink.resolve(:new.item_id),
creation_ip => :new.creation_ip,
creation_user => :new.creation_user,
text => :new.text,
package_id => :new.object_package_id
);
else
new_revision_id := content_revision.new(
revision_id => :new.revision_id,
title => :new.title,
description => :new.description,
mime_type => :new.mime_type,
nls_language => :new.nls_language,
item_id => content_symlink.resolve(:new.item_id),
creation_ip => :new.creation_ip,
creation_user => :new.creation_user,
data => :new.data,
package_id => :new.object_package_id
);
end if;';
-- add an insert statement for each subtype in the hierarchy for this type
for type_rec in type_cur loop
tr_text := tr_text || '
' || trigger_insert_statement(type_rec.object_type) || ';
';
end loop;
-- end building the trigger code
tr_text := tr_text || '
end ' || v_table_name || 't;';
-- (Re)create the trigger
execute immediate tr_text;
end refresh_trigger;
-- Create or replace a view joining all attribute tables
procedure refresh_view (
content_type in cr_type_template_map.content_type%TYPE
) is
-- exclude the BLOB column because it will make it impossible
-- to do a select *
cursor join_cur is
select
distinct lower(table_name) as table_name,
id_column, level
from
acs_object_types
where
object_type <> 'acs_object'
and
object_type <> 'content_revision'
and lower(table_name) <> 'acs_objects'
and lower(table_name) <> 'cr_revisions'
start with
object_type = refresh_view.content_type
connect by
object_type = prior supertype;
cols varchar2(1000);
tabs varchar2(1000);
joins varchar2(1000) := '';
v_table_name varchar2(40);
begin
for join_rec in join_cur loop
cols := cols || ', ' || join_rec.table_name || '.*';
tabs := tabs || ', ' || join_rec.table_name;
joins := joins || ' and acs_objects.object_id = ' ||
join_rec.table_name || '.' || join_rec.id_column;
end loop;
select table_name into v_table_name from acs_object_types
where object_type = content_type;
-- create the input view (includes content columns)
execute immediate 'create or replace view ' || v_table_name ||
'i as select acs_objects.object_id,
acs_objects.object_type,
acs_objects.title as object_title,
acs_objects.package_id as object_package_id,
acs_objects.context_id,
acs_objects.security_inherit_p,
acs_objects.creation_user,
acs_objects.creation_date,
acs_objects.creation_ip,
acs_objects.last_modified,
acs_objects.modifying_user,
acs_objects.modifying_ip,
cr.revision_id, cr.title, cr.item_id,
cr.content as data, cr_text.text,
cr.description, cr.publish_date, cr.mime_type, cr.nls_language' ||
cols ||
' from acs_objects, cr_revisions cr, cr_text' || tabs || ' where
acs_objects.object_id = cr.revision_id ' || joins;
-- create the output view (excludes content columns to enable SELECT *)
execute immediate 'create or replace view ' || v_table_name ||
'x as select acs_objects.object_id,
acs_objects.object_type,
acs_objects.title as object_title,
acs_objects.package_id as object_package_id,
acs_objects.context_id,
acs_objects.security_inherit_p,
acs_objects.creation_user,
acs_objects.creation_date,
acs_objects.creation_ip,
acs_objects.last_modified,
acs_objects.modifying_user,
acs_objects.modifying_ip,
cr.revision_id, cr.title, cr.item_id,
cr.description, cr.publish_date, cr.mime_type, cr.nls_language,
i.name, i.parent_id' ||
cols ||
' from acs_objects, cr_revisions cr, cr_items i, cr_text' || tabs ||
' where acs_objects.object_id = cr.revision_id
and cr.item_id = i.item_id' || joins;
refresh_trigger(content_type);
exception
when others then
dbms_output.put_line('Error creating attribute view or trigger for ' ||
content_type);
end refresh_view;
procedure register_child_type (
parent_type in cr_type_children.parent_type%TYPE,
child_type in cr_type_children.child_type%TYPE,
relation_tag in cr_type_children.relation_tag%TYPE default 'generic',
min_n in integer default 0,
max_n in integer default null
) is
v_exists integer;
begin
select decode(count(*),0,0,1) into v_exists
from cr_type_children
where parent_type = register_child_type.parent_type
and child_type = register_child_type.child_type
and relation_tag = register_child_type.relation_tag;
if v_exists = 0 then
insert into cr_type_children (
parent_type, child_type, relation_tag, min_n, max_n
) values (
parent_type, child_type, relation_tag, min_n, max_n
);
else
update cr_type_children set
min_n = register_child_type.min_n,
max_n = register_child_type.max_n
where
parent_type = register_child_type.parent_type
and
child_type = register_child_type.child_type
and
relation_tag = register_child_type.relation_tag;
end if;
end register_child_type;
procedure unregister_child_type (
parent_type in cr_type_children.parent_type%TYPE,
child_type in cr_type_children.child_type%TYPE,
relation_tag in cr_type_children.relation_tag%TYPE default null
) is
begin
delete from
cr_type_children
where
parent_type = unregister_child_type.parent_type
and
child_type = unregister_child_type.child_type
and
relation_tag = unregister_child_type.relation_tag;
end unregister_child_type;
procedure register_relation_type (
content_type in cr_type_relations.content_type%TYPE,
target_type in cr_type_relations.target_type%TYPE,
relation_tag in cr_type_relations.relation_tag%TYPE default 'generic',
min_n in integer default 0,
max_n in integer default null
) is
v_exists integer;
begin
-- check if the relation type exists
select
decode(count(*),0,0,1) into v_exists
from
cr_type_relations
where
content_type = register_relation_type.content_type
and
target_type = register_relation_type.target_type
and
relation_tag = register_relation_type.relation_tag;
-- if the relation type does not exist, insert a row into cr_type_relations
if v_exists = 0 then
insert into cr_type_relations (
content_type, target_type, relation_tag, min_n, max_n
) values (
content_type, target_type, relation_tag, min_n, max_n
);
-- otherwise, update the row in cr_type_relations
else
update cr_type_relations set
min_n = register_relation_type.min_n,
max_n = register_relation_type.max_n
where
content_type = register_relation_type.content_type
and
target_type = register_relation_type.target_type
and
relation_tag = register_relation_type.relation_tag;
end if;
end register_relation_type;
procedure unregister_relation_type (
content_type in cr_type_relations.content_type%TYPE,
target_type in cr_type_relations.target_type%TYPE,
relation_tag in cr_type_relations.relation_tag%TYPE default null
) is
begin
delete from
cr_type_relations
where
content_type = unregister_relation_type.content_type
and
target_type = unregister_relation_type.target_type
and
relation_tag = unregister_relation_type.relation_tag;
end unregister_relation_type;
procedure register_mime_type (
content_type in cr_content_mime_type_map.content_type%TYPE,
mime_type in cr_content_mime_type_map.mime_type%TYPE
) is
v_valid_registration integer;
begin
-- check if this type is already registered
select
count(*) into v_valid_registration
from
cr_mime_types
where
not exists ( select 1
from
cr_content_mime_type_map
where
mime_type = register_mime_type.mime_type
and
content_type = register_mime_type.content_type )
and
mime_type = register_mime_type.mime_type;
if v_valid_registration = 1 then
insert into cr_content_mime_type_map (
content_type, mime_type
) values (
register_mime_type.content_type, register_mime_type.mime_type
);
end if;
end register_mime_type;
procedure unregister_mime_type (
content_type in cr_content_mime_type_map.content_type%TYPE,
mime_type in cr_content_mime_type_map.mime_type%TYPE
) is
begin
delete from cr_content_mime_type_map
where content_type = unregister_mime_type.content_type
and mime_type = unregister_mime_type.mime_type;
end unregister_mime_type;
function is_content_type (
object_type in acs_object_types.object_type%TYPE
) return char is
v_is_content_type char(1) := 'f';
begin
if object_type = 'content_revision' then
v_is_content_type := 't';
else
select decode(count(*),0,'f','t') into v_is_content_type
from acs_object_type_supertype_map
where object_type = is_content_type.object_type
and ancestor_type = 'content_revision';
end if;
return v_is_content_type;
end is_content_type;
procedure rotate_template (
template_id in cr_templates.template_id%TYPE,
v_content_type in cr_items.content_type%TYPE,
use_context in cr_type_template_map.use_context%TYPE
) is
v_template_id cr_templates.template_id%TYPE;
-- items that have an associated default template but not at the item level
cursor c_items_cursor is
select
item_id
from
cr_items i, cr_type_template_map m
where
i.content_type = rotate_template.v_content_type
and
m.use_context = rotate_template.use_context
and
i.content_type = m.content_type
and
not exists ( select 1
from
cr_item_template_map
where
item_id = i.item_id
and
use_context = rotate_template.use_context );
begin
-- get the default template
select
template_id into v_template_id
from
cr_type_template_map
where
content_type = rotate_template.v_content_type
and
use_context = rotate_template.use_context
and
is_default = 't';
if v_template_id is not null then
-- register an item-template to all items without an item-template
for v_items_val in c_items_cursor loop
content_item.register_template (
item_id => v_items_val.item_id,
template_id => v_template_id,
use_context => rotate_template.use_context
);
end loop;
end if;
-- register the new template as the default template of the content type
if v_template_id ^= rotate_template.template_id then
content_type.register_template(
content_type => rotate_template.v_content_type,
template_id => rotate_template.template_id,
use_context => rotate_template.use_context,
is_default => 't'
);
end if;
end rotate_template;
end content_type;
/
show errors