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 -r1.116 -r1.117 --- openacs-4/packages/acs-content-repository/acs-content-repository.info 15 Jun 2018 08:30:12 -0000 1.116 +++ openacs-4/packages/acs-content-repository/acs-content-repository.info 16 Jan 2019 08:06:37 -0000 1.117 @@ -7,7 +7,7 @@ t t - + f t OpenACS @@ -21,7 +21,7 @@ GPL 3 - + 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 -r1.60 -r1.61 --- openacs-4/packages/acs-content-repository/sql/postgresql/content-type.sql 1 Nov 2018 08:43:43 -0000 1.60 +++ openacs-4/packages/acs-content-repository/sql/postgresql/content-type.sql 16 Jan 2019 08:06:37 -0000 1.61 @@ -711,13 +711,12 @@ -- Create or replace a trigger on insert for simplifying addition of -- revisions for any content type -select define_function_args('content_type__refresh_trigger','content_type'); - - -- -- procedure content_type__refresh_trigger/1 -- +select define_function_args('content_type__refresh_trigger','content_type'); + CREATE OR REPLACE FUNCTION content_type__refresh_trigger( refresh_trigger__content_type varchar ) RETURNS integer AS $$ @@ -792,7 +791,7 @@ execute function_text; rule_text := 'create rule ' || v_table_name || '_r as on insert to ' || - v_table_name || 'i do instead SELECT ' || v_table_name || '_f(new); ' ; + v_table_name || 'i do instead SELECT ' || v_table_name || '_f(new) FOR UPDATE; ' ; --================== done building rule code ======================= -- drop the old rule @@ -808,13 +807,14 @@ END; $$ LANGUAGE plpgsql; -select define_function_args('content_type__refresh_view','content_type'); -- -- procedure content_type__refresh_view/1 -- +select define_function_args('content_type__refresh_view','content_type'); + CREATE OR REPLACE FUNCTION content_type__refresh_view( refresh_view__content_type varchar ) RETURNS integer AS $$ Index: openacs-4/packages/acs-content-repository/sql/postgresql/upgrade/upgrade-5.10.0d5-5.10.0d6.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/sql/postgresql/upgrade/upgrade-5.10.0d5-5.10.0d6.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/sql/postgresql/upgrade/upgrade-5.10.0d5-5.10.0d6.sql 16 Jan 2019 08:06:37 -0000 1.1 @@ -0,0 +1,98 @@ +-- +-- add "FOR UPDATE" to call of *_f() function inserting tuples. +-- + +-- +-- procedure content_type__refresh_trigger/1 +-- +select define_function_args('content_type__refresh_trigger','content_type'); + +CREATE OR REPLACE FUNCTION content_type__refresh_trigger( + refresh_trigger__content_type varchar +) RETURNS integer AS $$ +DECLARE + rule_text text default ''; + function_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) + raise NOTICE 'refresh trigger for % ', refresh_trigger__content_type; + + -- Since we allow null table name use object type if table name is null so + -- we still can have a view. + select coalesce(table_name,object_type) + into v_table_name + from acs_object_types + where object_type = refresh_trigger__content_type; + + --=================== start building rule code ======================= + + function_text := function_text || + 'create or replace function ' || v_table_name || '_f (p_new '|| v_table_name || 'i) + returns void as '' + declare + v_revision_id integer; + begin + + select content_revision__new( + p_new.title, + p_new.description, + p_new.publish_date, + p_new.mime_type, + p_new.nls_language, + case when p_new.text is null + then p_new.data + else p_new.text + end, + content_symlink__resolve(p_new.item_id), + p_new.revision_id, + now(), + p_new.creation_user, + p_new.creation_ip, + null, -- content_length + p_new.object_package_id + ) into v_revision_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) + and ot1.table_name is not null + order by level asc + LOOP + function_text := function_text || content_type__trigger_insert_statement(type_rec.object_type) || '; + '; + end loop; + + function_text := function_text || ' + return; + end;'' language plpgsql; + '; + -- end building the rule definition code + + -- create the new function + execute function_text; + + rule_text := 'create rule ' || v_table_name || '_r as on insert to ' || + v_table_name || 'i do instead SELECT ' || v_table_name || '_f(new) FOR UPDATE; ' ; + --================== done building rule code ======================= + + -- drop the old rule + if rule_exists(v_table_name || '_r', v_table_name || 'i') then + execute 'drop rule ' || v_table_name || '_r ' || 'on ' || v_table_name || 'i'; + end if; + + -- create the new rule for inserts on the content type + execute rule_text; + + return null; + +END; +$$ LANGUAGE plpgsql;