select acs_object_type__create_type ( 'acs_sc_msg_type', -- object_type 'ACS SC Message Type', -- pretty_name 'ACS SC Message Types', -- pretty_plural 'acs_object', -- supertype 'acs_sc_msg_types', -- table_name 'msg_type_id', -- id_column null, -- package_name 'f', -- abstract_p null, -- type_extension_table null -- name_method ); create table acs_sc_msg_types ( msg_type_id integer constraint acs_sc_msg_types_id_fk references acs_objects(object_id) on delete cascade constraint acs_sc_msg_types_pk primary key, msg_type_name varchar(100) constraint acs_sc_msg_types_name_un unique ); create table acs_sc_msg_type_elements ( msg_type_id integer constraint acs_sc_msg_type_el_mtype_id_fk references acs_sc_msg_types(msg_type_id) on delete cascade, element_name varchar(100), element_msg_type_id integer constraint acs_sc_msg_type_el_emti_id_fk references acs_sc_msg_types(msg_type_id), element_msg_type_isset_p boolean, element_pos integer ); -- register function record select define_function_args('acs_sc_msg_type__new','msg_type_name,msg_type_spec'); -- declare function -- -- procedure acs_sc_msg_type__new/2 -- CREATE OR REPLACE FUNCTION acs_sc_msg_type__new( p_msg_type_name varchar, p_msg_type_spec varchar ) RETURNS integer AS $$ DECLARE v_msg_type_id integer; BEGIN v_msg_type_id := acs_object__new( null, 'acs_sc_msg_type', now(), null, null, null, 't', p_msg_type_name, null ); insert into acs_sc_msg_types ( msg_type_id, msg_type_name ) values ( v_msg_type_id, p_msg_type_name ); perform acs_sc_msg_type__parse_spec(p_msg_type_name,p_msg_type_spec); return v_msg_type_id; END; $$ LANGUAGE plpgsql; -- register function record select define_function_args('acs_sc_msg_type__get_id','msg_type_name'); -- declare function -- -- procedure acs_sc_msg_type__get_id/1 -- CREATE OR REPLACE FUNCTION acs_sc_msg_type__get_id( p_msg_type_name varchar ) RETURNS integer AS $$ DECLARE v_msg_type_id integer; BEGIN select msg_type_id into v_msg_type_id from acs_sc_msg_types where msg_type_name = p_msg_type_name; return v_msg_type_id; END; $$ LANGUAGE plpgsql stable strict; -- register function record select define_function_args('acs_sc_msg_type__get_name','msg_type_id'); -- declare function -- -- procedure acs_sc_msg_type__get_name/1 -- CREATE OR REPLACE FUNCTION acs_sc_msg_type__get_name( p_msg_type_id integer ) RETURNS varchar AS $$ DECLARE v_msg_type_name varchar; BEGIN select msg_type_name into v_msg_type_name from acs_sc_msg_types where msg_type_id = p_msg_type_id; return v_msg_type_name; END; $$ LANGUAGE plpgsql stable strict; -- -- procedure acs_sc_msg_type__delete/1 -- CREATE OR REPLACE FUNCTION acs_sc_msg_type__delete( p_msg_type_id integer ) RETURNS integer AS $$ DECLARE BEGIN delete from acs_sc_msg_types where msg_type_id = p_msg_type_id; return 0; END; $$ LANGUAGE plpgsql; -- XXX: this might be a bug that it does not return 0 as the above does. -- anyway now it is strict as being called with null is a noop and returns null -- register function record -- old define_function_args('acs_sc_msg_type__delete','msg_type_name') -- new select define_function_args('acs_sc_msg_type__delete','msg_type_id'); -- declare function -- -- procedure acs_sc_msg_type__delete/1 -- CREATE OR REPLACE FUNCTION acs_sc_msg_type__delete( p_msg_type_name varchar ) RETURNS integer AS $$ DECLARE v_msg_type_id integer; BEGIN v_msg_type_id := acs_sc_msg_type__get_id(p_msg_type_name); perform acs_sc_msg_type__delete(v_msg_type_id); return v_msg_type_id; END; $$ LANGUAGE plpgsql strict; -- register function record select define_function_args('acs_sc_msg_type__new_element','msg_type_name,element_name,element_msg_type_name,element_msg_type_isset_p;f,element_pos'); -- declare function -- -- procedure acs_sc_msg_type__new_element/5 -- CREATE OR REPLACE FUNCTION acs_sc_msg_type__new_element( p_msg_type_name varchar, p_element_name varchar, p_element_msg_type_name varchar, p_element_msg_type_isset_p boolean, -- default 'f' p_element_pos integer ) RETURNS integer AS $$ DECLARE v_msg_type_id integer; v_element_msg_type_id integer; BEGIN v_msg_type_id := acs_sc_msg_type__get_id(p_msg_type_name); if v_msg_type_id is null then raise exception 'Unknown Message Type: %', p_msg_type_name; end if; v_element_msg_type_id := acs_sc_msg_type__get_id(p_element_msg_type_name); if v_element_msg_type_id is null then raise exception 'Unknown Message Type: %', p_element_msg_type_name; end if; insert into acs_sc_msg_type_elements ( msg_type_id, element_name, element_msg_type_id, element_msg_type_isset_p, element_pos ) values ( v_msg_type_id, p_element_name, v_element_msg_type_id, p_element_msg_type_isset_p, p_element_pos ); return v_msg_type_id; END; $$ LANGUAGE plpgsql; -- register function record select define_function_args('acs_sc_msg_type__parse_spec','msg_type_name,msg_type_spec'); -- declare function -- -- procedure acs_sc_msg_type__parse_spec/2 -- CREATE OR REPLACE FUNCTION acs_sc_msg_type__parse_spec( p_msg_type_name varchar, p_msg_type_spec varchar ) RETURNS integer AS $$ DECLARE v_element varchar; v_element_type varchar; v_str_pos integer; v_element_name varchar; v_element_msg_type_name varchar; v_element_msg_type_isset_p boolean; v_element_pos integer; BEGIN v_element_pos := 1; v_element := split(p_msg_type_spec, ',', v_element_pos); while v_element is not null loop v_str_pos = instr(v_element, ':', 1, 1); if v_str_pos > 0 then v_element_name := trim(substr(v_element, 1, v_str_pos-1)); v_element_type := trim(substr(v_element, v_str_pos+1, length(v_element) - v_str_pos)); if (instr(v_element_type, '[',1,1) = length(v_element_type)-1) and (instr(v_element_type, ']',1,1) = length(v_element_type)) then v_element_msg_type_isset_p := 't'; v_element_msg_type_name := trim(substr(v_element_type,1,length(v_element_type)-2)); if v_element_msg_type_name = '' then raise exception 'Wrong Format: Message Type Specification'; end if; else v_element_msg_type_isset_p := 'f'; v_element_msg_type_name := v_element_type; end if; else raise exception 'Wrong Format: Message Type Specification'; end if; perform acs_sc_msg_type__new_element( p_msg_type_name, -- msg_type_id v_element_name, -- element_name v_element_msg_type_name, -- element_msg_type_id v_element_msg_type_isset_p, -- element_msg_type_isset_p v_element_pos -- element_pos ); v_element_pos := v_element_pos + 1; v_element := split(p_msg_type_spec, ',', v_element_pos); end loop; return v_element_pos-1; END; $$ LANGUAGE plpgsql; -- -- Primitive Message Types -- select acs_sc_msg_type__new('integer',''); select acs_sc_msg_type__new('string',''); select acs_sc_msg_type__new('boolean',''); select acs_sc_msg_type__new('timestamp',''); select acs_sc_msg_type__new('uri',''); select acs_sc_msg_type__new('version',''); select acs_sc_msg_type__new('float',''); select acs_sc_msg_type__new('bytearray','');