--
-- add extended attribute to rel types
--
-- make the upgrade script loadable multiple times
DO $$
DECLARE
v_found boolean;
BEGIN
SELECT exists(
SELECT 1 FROM information_schema.columns WHERE table_name='acs_rel_types' and column_name='composable_p'
) INTO v_found;
if v_found IS FALSE then
ALTER TABLE acs_rel_types ADD COLUMN composable_p boolean DEFAULT true NOT NULL;
UPDATE acs_rel_types SET composable_p = false WHERE rel_type = 'admin_rel';
end if;
END$$;
drop trigger membership_rels_in_tr on membership_rels;
drop function membership_rels_in_tr ();
--
-- procedure membership_rels_in_tr/0
--
CREATE OR REPLACE FUNCTION membership_rels_in_tr(
) RETURNS trigger AS $$
DECLARE
v_object_id_one acs_rels.object_id_one%TYPE;
v_object_id_two acs_rels.object_id_two%TYPE;
v_rel_type acs_rels.rel_type%TYPE;
v_composable_p acs_rel_types.composable_p%TYPE;
v_error text;
map record;
BEGIN
-- First check if added this relation violated any relational constraints
v_error := rel_constraint__violation(new.rel_id);
if v_error is not null then
raise EXCEPTION '-20000: %', v_error;
end if;
select object_id_one, object_id_two, r.rel_type, composable_p
into v_object_id_one, v_object_id_two, v_rel_type, v_composable_p
from acs_rels r
join acs_rel_types t on (r.rel_type = t.rel_type)
where rel_id = new.rel_id;
-- Insert a row for me in the group_element_index.
insert into group_element_index
(group_id, element_id, rel_id, container_id,
rel_type, ancestor_rel_type)
values
(v_object_id_one, v_object_id_two, new.rel_id, v_object_id_one,
v_rel_type, 'membership_rel');
if new.member_state = 'approved' then
perform party_approved_member__add(v_object_id_one, v_object_id_two, new.rel_id, v_rel_type);
end if;
-- If this rel_type composable...
if v_composable_p = 't' then
-- For all groups of which I am a component, insert a
-- row in the group_element_index.
for map in select distinct group_id
from group_component_map
where component_id = v_object_id_one
loop
insert into group_element_index
(group_id, element_id, rel_id, container_id,
rel_type, ancestor_rel_type)
values
(map.group_id, v_object_id_two, new.rel_id, v_object_id_one,
v_rel_type, 'membership_rel');
if new.member_state = 'approved' then
perform party_approved_member__add(map.group_id, v_object_id_two, new.rel_id, v_rel_type);
end if;
end loop;
end if;
return new;
END;
$$ LANGUAGE plpgsql;
create trigger membership_rels_in_tr after insert on membership_rels
for each row execute procedure membership_rels_in_tr ();
drop trigger composition_rels_in_tr on composition_rels;
drop function composition_rels_in_tr ();
--
-- procedure composition_rels_in_tr/0
--
CREATE OR REPLACE FUNCTION composition_rels_in_tr(
) RETURNS trigger AS $$
DECLARE
v_object_id_one acs_rels.object_id_one%TYPE;
v_object_id_two acs_rels.object_id_two%TYPE;
v_rel_type acs_rels.rel_type%TYPE;
v_error text;
map record;
BEGIN
-- First check if added this relation violated any relational constraints
v_error := rel_constraint__violation(new.rel_id);
if v_error is not null then
raise EXCEPTION '-20000: %', v_error;
end if;
select object_id_one, object_id_two, rel_type
into v_object_id_one, v_object_id_two, v_rel_type
from acs_rels
where rel_id = new.rel_id;
-- Insert a row for me in group_element_index
insert into group_element_index
(group_id, element_id, rel_id, container_id,
rel_type, ancestor_rel_type)
values
(v_object_id_one, v_object_id_two, new.rel_id, v_object_id_one,
v_rel_type, 'composition_rel');
-- Add to the denormalized party_approved_member_map
perform party_approved_member__add(v_object_id_one, member_id, rel_id, rel_type)
from group_approved_member_map m
where group_id = v_object_id_two
and not exists (select 1
from group_element_map
where group_id = v_object_id_one
and element_id = m.member_id
and rel_id = m.rel_id);
-- Make my composable elements be elements of my new composite group
insert into group_element_index
(group_id, element_id, rel_id, container_id,
rel_type, ancestor_rel_type)
select distinct
v_object_id_one, element_id, rel_id, container_id,
m.rel_type, ancestor_rel_type
from group_element_map m
join acs_rel_types t on (m.rel_type = t.rel_type)
where group_id = v_object_id_two
and t.composable_p = 't'
and not exists (select 1
from group_element_map
where group_id = v_object_id_one
and element_id = m.element_id
and rel_id = m.rel_id);
-- For all direct or indirect containers of my new composite group,
-- add me and add my elements
for map in select distinct group_id
from group_component_map
where component_id = v_object_id_one
LOOP
-- Add a row for me
insert into group_element_index
(group_id, element_id, rel_id, container_id,
rel_type, ancestor_rel_type)
values
(map.group_id, v_object_id_two, new.rel_id, v_object_id_one,
v_rel_type, 'composition_rel');
-- Add to party_approved_member_map
perform party_approved_member__add(map.group_id, member_id, rel_id, m.rel_type)
from group_approved_member_map m
join acs_rel_types t on (m.rel_type = t.rel_type)
where group_id = v_object_id_two
and t.composable_p = 't'
and not exists (select 1
from group_element_map
where group_id = map.group_id
and element_id = m.member_id
and rel_id = m.rel_id);
-- Add rows for my composable elements
insert into group_element_index
(group_id, element_id, rel_id, container_id,
rel_type, ancestor_rel_type)
select distinct
map.group_id, element_id, rel_id, container_id,
m.rel_type, ancestor_rel_type
from group_element_map m
join acs_rel_types t on (m.rel_type = t.rel_type)
where group_id = v_object_id_two
and t.composable_p = 't'
and not exists (select 1
from group_element_map
where group_id = map.group_id
and element_id = m.element_id
and rel_id = m.rel_id);
end loop;
return new;
END;
$$ LANGUAGE plpgsql;
create trigger composition_rels_in_tr after insert on composition_rels
for each row execute procedure composition_rels_in_tr ();
select define_function_args('acs_rel_type__create_type','rel_type,pretty_name,pretty_plural,supertype;relationship,table_name,id_column,package_name,object_type_one,role_one;null,min_n_rels_one,max_n_rels_one,object_type_two,role_two;null,min_n_rels_two,max_n_rels_two,composable_p;t');
drop function if exists acs_rel_type__create_type(
varchar,
varchar,
varchar,
varchar, -- default 'relationship'
varchar,
varchar,
varchar,
varchar,
varchar, -- default null
integer,
integer,
varchar,
varchar, -- default null
integer,
integer
);
--
-- procedure acs_rel_type__create_type/16
--
CREATE OR REPLACE FUNCTION acs_rel_type__create_type(
create_type__rel_type varchar,
create_type__pretty_name varchar,
create_type__pretty_plural varchar,
create_type__supertype varchar, -- default 'relationship'
create_type__table_name varchar,
create_type__id_column varchar,
create_type__package_name varchar,
create_type__object_type_one varchar,
create_type__role_one varchar, -- default null
create_type__min_n_rels_one integer,
create_type__max_n_rels_one integer,
create_type__object_type_two varchar,
create_type__role_two varchar, -- default null
create_type__min_n_rels_two integer,
create_type__max_n_rels_two integer,
create_type__composable_p boolean default true
) RETURNS integer AS $$
DECLARE
type_extension_table acs_object_types.type_extension_table%TYPE default null;
abstract_p acs_object_types.abstract_p%TYPE default 'f';
name_method acs_object_types.name_method%TYPE default null;
BEGIN
PERFORM acs_object_type__create_type(
create_type__rel_type,
create_type__pretty_name,
create_type__pretty_plural,
create_type__supertype,
create_type__table_name,
create_type__id_column,
create_type__package_name,
abstract_p,
type_extension_table,
name_method
);
insert into acs_rel_types
(rel_type,
object_type_one, role_one,
min_n_rels_one, max_n_rels_one,
object_type_two, role_two,
min_n_rels_two, max_n_rels_two,
composable_p)
values
(create_type__rel_type,
create_type__object_type_one, create_type__role_one,
create_type__min_n_rels_one, create_type__max_n_rels_one,
create_type__object_type_two, create_type__role_two,
create_type__min_n_rels_two, create_type__max_n_rels_two,
create_type__composable_p);
return 0;
END;
$$ LANGUAGE plpgsql;
-- procedure create_type
DROP FUNCTION IF EXISTS acs_rel_type__create_type(
varchar,
varchar,
varchar,
varchar, -- default 'relationship'
varchar,
varchar,
varchar,
varchar, -- default null
varchar,
integer,
integer,
varchar,
integer,
integer
);
--
-- procedure acs_rel_type__create_type/15
--
CREATE OR REPLACE FUNCTION acs_rel_type__create_type(
create_type__rel_type varchar,
create_type__pretty_name varchar,
create_type__pretty_plural varchar,
create_type__supertype varchar, -- default 'relationship'
create_type__table_name varchar,
create_type__id_column varchar,
create_type__package_name varchar,
create_type__type_extension_table varchar, -- default null
create_type__object_type_one varchar,
create_type__min_n_rels_one integer,
create_type__max_n_rels_one integer,
create_type__object_type_two varchar,
create_type__min_n_rels_two integer,
create_type__max_n_rels_two integer,
create_type__composable_p boolean default true
) RETURNS integer AS $$
DECLARE
abstract_p acs_object_types.abstract_p%TYPE default 'f';
name_method acs_object_types.name_method%TYPE default null;
create_type__role_one acs_rel_types.role_one%TYPE default null;
create_type__role_two acs_rel_types.role_two%TYPE default null;
BEGIN
PERFORM acs_object_type__create_type(
create_type__rel_type,
create_type__pretty_name,
create_type__pretty_plural,
create_type__supertype,
create_type__table_name,
create_type__id_column,
create_type__package_name,
abstract_p,
create_type__type_extension_table,
name_method
);
insert into acs_rel_types
(rel_type,
object_type_one, role_one,
min_n_rels_one, max_n_rels_one,
object_type_two, role_two,
min_n_rels_two, max_n_rels_two,
composable_p)
values
(create_type__rel_type,
create_type__object_type_one, create_type__role_one,
create_type__min_n_rels_one, create_type__max_n_rels_one,
create_type__object_type_two, create_type__role_two,
create_type__min_n_rels_two, create_type__max_n_rels_two,
create_type__composable_p);
return 0;
END;
$$ LANGUAGE plpgsql;