Index: openacs-4/packages/acs-content-repository/acs-content-repository.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/acs-content-repository.info,v diff -u -N -r1.56 -r1.57 --- openacs-4/packages/acs-content-repository/acs-content-repository.info 12 May 2005 21:35:00 -0000 1.56 +++ openacs-4/packages/acs-content-repository/acs-content-repository.info 8 Jun 2005 20:58:59 -0000 1.57 @@ -7,7 +7,7 @@ t t - + OpenACS The canonical repository for OpenACS content. @@ -21,7 +21,7 @@ other CMS backing functionality. Utilized by Bug Tracker, File Storage, and other packages. - + Index: openacs-4/packages/acs-content-repository/sql/oracle/content-type.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/sql/oracle/content-type.sql,v diff -u -N -r1.6 -r1.7 --- openacs-4/packages/acs-content-repository/sql/oracle/content-type.sql 14 Feb 2005 17:23:10 -0000 1.6 +++ openacs-4/packages/acs-content-repository/sql/oracle/content-type.sql 8 Jun 2005 20:58:59 -0000 1.7 @@ -534,7 +534,8 @@ item_id => content_symlink.resolve(:new.item_id), creation_ip => :new.creation_ip, creation_user => :new.creation_user, - text => :new.text + text => :new.text, + package_id => :new.object_package_id ); else @@ -548,7 +549,8 @@ item_id => content_symlink.resolve(:new.item_id), creation_ip => :new.creation_ip, creation_user => :new.creation_user, - data => :new.data + data => :new.data, + package_id => :new.object_package_id ); end if;'; Index: openacs-4/packages/acs-content-repository/sql/oracle/upgrade/upgrade-5.2.0d16-5.2.0d17.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/sql/oracle/upgrade/upgrade-5.2.0d16-5.2.0d17.sql,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/sql/oracle/upgrade/upgrade-5.2.0d16-5.2.0d17.sql 8 Jun 2005 20:59:00 -0000 1.1 @@ -0,0 +1,914 @@ +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' +) 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; + + 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' ); + 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 objet + where + objet.object_type = drop_type.content_type and + u.table_name = upper(objet.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; + + 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 neccessary + 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 + +-- Refresh the attribute triggers + +begin + + for type_rec in (select object_type from acs_object_types + connect by supertype = prior object_type + start with object_type = 'content_revision') loop + content_type.refresh_trigger(type_rec.object_type); + end loop; + +end; +/ Index: openacs-4/packages/acs-content-repository/sql/postgresql/content-type.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/sql/postgresql/content-type.sql,v diff -u -N -r1.41 -r1.42 --- openacs-4/packages/acs-content-repository/sql/postgresql/content-type.sql 23 May 2005 02:32:43 -0000 1.41 +++ openacs-4/packages/acs-content-repository/sql/postgresql/content-type.sql 8 Jun 2005 20:59:00 -0000 1.42 @@ -594,7 +594,8 @@ new.revision_id, now(), new.creation_user, - new.creation_ip + new.creation_ip, + new.object_package_id )); ''; Index: openacs-4/packages/acs-content-repository/sql/postgresql/upgrade/upgrade-5.2.0d16-5.2.0d17.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/sql/postgresql/upgrade/upgrade-5.2.0d16-5.2.0d17.sql,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/sql/postgresql/upgrade/upgrade-5.2.0d16-5.2.0d17.sql 8 Jun 2005 20:59:01 -0000 1.2 @@ -0,0 +1,102 @@ +-- procedure refresh_trigger +select define_function_args('content_type__refresh_trigger','content_type'); + +create or replace function content_type__refresh_trigger (varchar) +returns integer as ' +declare + refresh_trigger__content_type alias for $1; + rule_text text default ''''; + v_table_name acs_object_types.table_name%TYPE; + type_rec record; +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 rule code ======================= + + rule_text := ''create rule '' || v_table_name || ''_r as on insert to '' || + v_table_name || ''i do instead ( + update cr_dummy set val = ( + select content_revision__new( + new.title, + new.description, + now(), + new.mime_type, + new.nls_language, + case when new.text is null + then new.data + else new.text + end, + content_symlink__resolve(new.item_id), + new.revision_id, + now(), + new.creation_user, + new.creation_ip, + new.object_package_id + )); + ''; + + -- add an insert statement for each subtype in the hierarchy for this type + + for type_rec in select ot2.object_type, tree_level(ot2.tree_sortkey) as level + from acs_object_types ot1, acs_object_types ot2 + where ot2.object_type <> ''acs_object'' + and ot2.object_type <> ''content_revision'' + and ot1.object_type = refresh_trigger__content_type + and ot1.tree_sortkey between ot2.tree_sortkey and tree_right(ot2.tree_sortkey) + order by level desc + LOOP + rule_text := rule_text || '' '' || content_type__trigger_insert_statement(type_rec.object_type) || '';''; + end loop; + + -- end building the rule definition code + + rule_text := rule_text || '' );''; + + --================== done building rule code ======================= + + -- drop the old rule + if rule_exists(v_table_name || ''_r'', v_table_name || ''i'') then + + -- different syntax for dropping a rule in 7.2 and 7.3 so check which + -- version is being used (olah). + if version() like ''%PostgreSQL 7.2%'' then + execute ''drop rule '' || v_table_name || ''_r''; + else + -- 7.3 syntax + execute ''drop rule '' || v_table_name || ''_r '' || ''on '' || v_table_name || ''i''; + end if; + + end if; + + -- create the new rule for inserts on the content type + execute rule_text; + + return null; + +end;' language 'plpgsql'; + + +create function inline_0 () +returns integer as ' +declare + ct RECORD; + v_dummy integer; +begin + for ct in select object_type + from acs_object_type_supertype_map + where ancestor_type = ''content_revision'' + loop + select content_type__refresh_trigger (ct.object_type) into v_dummy; + end loop; + + return null; +end;' language 'plpgsql'; + +select inline_0(); +drop function inline_0(); Index: openacs-4/packages/acs-content-repository/tcl/content-revision-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/tcl/content-revision-procs.tcl,v diff -u -N -r1.10 -r1.11 --- openacs-4/packages/acs-content-repository/tcl/content-revision-procs.tcl 7 Jun 2005 13:07:16 -0000 1.10 +++ openacs-4/packages/acs-content-repository/tcl/content-revision-procs.tcl 8 Jun 2005 20:59:19 -0000 1.11 @@ -25,7 +25,6 @@ {-content_type} {-creation_user} {-creation_ip} - {-context_id} {-package_id} {-attributes} {-is_live "f"} @@ -66,8 +65,6 @@ @param is_live - @param context_id defaults to item_id if not specified. Use empty string for NULL context_id - @param attributes A list of lists of pairs of additional attributes and their values to pass to the constructor. Each pair is a list of two elements: key => value such as @@ -89,9 +86,6 @@ if {![exists_and_not_null content_type]} { set content_type [::content::item::content_type -item_id $item_id] } - if {![info exists context_id]} { - set context_id $item_id - } if {![info exists package_id]} { set package_id [ad_conn package_id] } @@ -134,8 +128,8 @@ set table_name "${table_name}i" set query_text "insert into ${table_name} - (revision_id, object_type, creation_user, creation_date, creation_ip, title, description, item_id, context_id, package_id, mime_type $attribute_names) - values (:revision_id, :content_type, :creation_user, :creation_date, :creation_ip, :title, :description, :item_id, :context_id, :package_id, :mime_type $attribute_values)" + (revision_id, object_type, creation_user, creation_date, creation_ip, title, description, item_id, object_package_id, mime_type $attribute_names) + values (:revision_id, :content_type, :creation_user, :creation_date, :creation_ip, :title, :description, :item_id, :package_id, :mime_type $attribute_values)" db_transaction { if {[string equal "" $revision_id]} { set revision_id [db_nextval "acs_object_id_seq"]