-- -- packages/address-book/sql/address-book-create.sql -- -- @author jmileham@arsdigita.com -- @creation_date 2000-12-04 -- @cvs-id $Id: address-book-create.sql,v 1.1 2002/07/09 17:35:01 rmello Exp $ -- ----------------------- -- AB_CONTACT OBJECT -- ----------------------- begin acs_object_type.create_type ( supertype => 'acs_object', object_type => 'ab_contact', pretty_name => 'Address Book Contact', pretty_plural => 'Address Book Contacts', table_name => 'ab_contacts', id_column => 'contact_id', package_name => 'ab_contact', name_method => 'ab_contact.name' ); end; / show errors ----------------------- -- AB_CONTACTS TABLE -- ----------------------- create table ab_contacts ( contact_id not null constraint ab_contacts_contact_id_fk references acs_objects (object_id) constraint ab_contacts_pk primary key, first_names varchar2(200), last_name varchar2(200), title varchar2(200), organization varchar2(200) ); --------------------------------- -- AB_CONTACT_ATTR_TYPE OBJECT -- --------------------------------- begin acs_object_type.create_type ( supertype => 'acs_object', object_type => 'ab_contact_attr_type', pretty_name => 'Address Book Contact Attribute Type', pretty_plural => 'Address Book Contact Attribute Types', table_name => 'ab_contact_attr_types', id_column => 'type_id', package_name => 'ab_contact_attr_type', name_method => 'ab_contact_attr_type.name' ); end; / show errors --------------------------------- -- AB_CONTACT_ATTR_TYPES TABLE -- --------------------------------- create table ab_contact_attr_types ( type_id not null constraint ab_con_attr_tp_type_id_fk references acs_objects (object_id) constraint ab_contact_attr_types_pk primary key, type_name varchar2(100) not null, type_key varchar2(20) not null constraint ab_con_attr_tp_type_key_un unique ); ----------------------------------- -- AB_CONTACT_ATTR_TYPES PACKAGE -- ----------------------------------- create or replace package ab_contact_attr_type as function new ( type_id in ab_contact_attr_types.type_id%TYPE default null, object_type in acs_objects.object_type%TYPE default 'ab_contact_attr_type', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null, type_name in ab_contact_attr_types.type_name%TYPE, type_key in ab_contact_attr_types.type_key%TYPE ) return ab_contact_attr_types.type_id%TYPE; function name ( type_id in ab_contact_attr_types.type_id%TYPE ) return ab_contact_attr_types.type_name%TYPE; procedure delete ( type_id in ab_contact_attr_types.type_id%TYPE ); end ab_contact_attr_type; / show errors create or replace package body ab_contact_attr_type as function new ( type_id in ab_contact_attr_types.type_id%TYPE default null, object_type in acs_objects.object_type%TYPE default 'ab_contact_attr_type', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null, type_name in ab_contact_attr_types.type_name%TYPE, type_key in ab_contact_attr_types.type_key%TYPE ) return ab_contact_attr_types.type_id%TYPE is v_type_id ab_contact_attr_types.type_id%TYPE; begin v_type_id := acs_object.new(object_id => type_id, object_type => object_type, creation_date => creation_date, creation_user => creation_user, creation_ip => creation_ip, context_id => context_id ); insert into ab_contact_attr_types (type_id, type_name, type_key) values (v_type_id, new.type_name, new.type_key); return v_type_id; end new; function name ( type_id in ab_contact_attr_types.type_id%TYPE ) return ab_contact_attr_types.type_name%TYPE is v_type_name ab_contact_attr_types.type_name%TYPE; begin select type_name into v_type_name from ab_contact_attr_types where type_id = name.type_id; return v_type_name; end name; procedure delete ( type_id in ab_contact_attr_types.type_id%TYPE ) is begin acs_object.delete(type_id); end delete; end ab_contact_attr_type; / show errors ---------------------------- -- DEFINE SOME ATTR TYPES -- ---------------------------- -- This may look remarkably similar to the attribute types offered -- by the address book in PalmOS. Not a coincidence. declare tmpval ab_contact_attr_types.type_id%TYPE; begin tmpval := ab_contact_attr_type.new(type_name => 'Work Phone', type_key => 'work_phone'); tmpval := ab_contact_attr_type.new(type_name => 'Home Phone', type_key => 'home_phone'); tmpval := ab_contact_attr_type.new(type_name => 'Fax Number', type_key => 'fax'); tmpval := ab_contact_attr_type.new(type_name => 'Other', type_key => 'other'); tmpval := ab_contact_attr_type.new(type_name => 'E-mail Address', type_key => 'email'); tmpval := ab_contact_attr_type.new(type_name => 'Main', type_key => 'main'); tmpval := ab_contact_attr_type.new(type_name => 'Pager', type_key => 'pager'); tmpval := ab_contact_attr_type.new(type_name => 'Mobile Phone', type_key => 'mobile'); end; / show errors ---------------------------- -- AB_CONTACT_ATTR OBJECT -- ---------------------------- begin acs_object_type.create_type( supertype => 'acs_object', object_type => 'ab_contact_attr', pretty_name => 'Address Book Contact Attribute', pretty_plural => 'Address Book Contact Attributes', table_name => 'ab_contact_attrs', id_column => 'attr_id', package_name => 'ab_contact_attr' ); end; / show errors ---------------------------- -- AB_CONTACT_ATTRS TABLE -- ---------------------------- create table ab_contact_attrs ( attr_id not null constraint ab_con_attrs_attr_id_fk references acs_objects (object_id) constraint ab_con_attrs_pk primary key, contact_id not null constraint ab_con_attrs_contact_id_fk references ab_contacts (contact_id), type_key not null constraint ab_con_attrs_type_key_fk references ab_contact_attr_types (type_key), value varchar2(200), sort_key integer not null ); ----------------------------- -- AB_CONTACT_ATTR PACKAGE -- ----------------------------- create or replace package ab_contact_attr as function new ( attr_id in ab_contact_attrs.attr_id%TYPE default null, object_type in acs_objects.object_type%TYPE default 'ab_contact_attr', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null, contact_id in ab_contact_attrs.contact_id%TYPE, type_key in ab_contact_attrs.type_key%TYPE, value in ab_contact_attrs.value%TYPE, before_attr_id in ab_contact_attrs.attr_id%TYPE default null ) return ab_contact_attrs.attr_id%TYPE; procedure swap_sort ( attr_id_one in ab_contact_attrs.attr_id%TYPE, attr_id_two in ab_contact_attrs.attr_id%TYPE ); procedure delete ( attr_id in ab_contact_attrs.attr_id%TYPE ); end ab_contact_attr; / show errors create or replace package body ab_contact_attr as function new ( attr_id in ab_contact_attrs.attr_id%TYPE default null, object_type in acs_objects.object_type%TYPE default 'ab_contact_attr', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null, contact_id in ab_contact_attrs.contact_id%TYPE, type_key in ab_contact_attrs.type_key%TYPE, value in ab_contact_attrs.value%TYPE, before_attr_id in ab_contact_attrs.attr_id%TYPE default null ) return ab_contact_attrs.attr_id%TYPE is v_attr_id ab_contact_attrs.attr_id%TYPE; begin v_attr_id := acs_object.new ( object_id => attr_id, object_type => object_type, creation_date => creation_date, creation_user => creation_user, creation_ip => creation_ip, context_id => context_id ); if new.before_attr_id is not null then -- Shift the attributes down to accomidate if they specified -- before_attr_id update ab_contact_attrs aca set sort_key = sort_key + 1 where sort_key >= (select sort_key from ab_contact_attrs where attr_id = new.before_attr_id) and exists (select 1 from ab_contact_attrs where attr_id = aca.attr_id and contact_id = new.contact_id); -- Insert into the newly create hole insert into ab_contact_attrs (attr_id, contact_id, type_key, value, sort_key) select new.v_attr_id, new.contact_id, new.type_key, new.value, (sort_key - 1) from ab_contact_attrs where attr_id = new.before_attr_id; else -- Otherwise, tack it on the end insert into ab_contact_attrs (attr_id, contact_id, type_key, value, sort_key) select new.v_attr_id, new.contact_id, new.type_key, new.value, nvl(max(sort_key) + 1, 1) from ab_contact_attrs where contact_id = new.contact_id; end if; return v_attr_id; end new; procedure swap_sort ( attr_id_one in ab_contact_attrs.attr_id%TYPE, attr_id_two in ab_contact_attrs.attr_id%TYPE ) is begin -- The exists clause verifies that the application is trying -- to perform a legal swap (one between two attributes of -- the same contact_id). update ab_contact_attrs aca1 set sort_key = (select sort_key from ab_contact_attrs aca2 where aca1.attr_id = decode(aca2.attr_id, swap_sort.attr_id_one, swap_sort.attr_id_two, swap_sort.attr_id_two, swap_sort.attr_id_one)) where attr_id in (swap_sort.attr_id_one, swap_sort.attr_id_two) and exists (select 1 from ab_contact_attrs aca3, ab_contact_attrs aca4 where aca3.attr_id = swap_sort.attr_id_one and aca4.attr_id = swap_sort.attr_id_two and aca3.contact_id = aca4.contact_id); end swap_sort; procedure delete ( attr_id in ab_contact_attrs.attr_id%TYPE ) is begin acs_object.delete(attr_id); end delete; end ab_contact_attr; / show errors -------------------- -- AB_CONTACT_REL -- -------------------- begin acs_rel_type.create_role('contact'); -- Don't know what to call the object associated with the oontact, -- so I won't define a role for it. Should be ok, seeing as the -- groups system does this too. acs_rel_type.create_type ( rel_type => 'ab_contact_rel', pretty_name => 'Address Book Contact Relation', pretty_plural => 'Address Book Contact Relationships', table_name => 'ab_contact_rels', id_column => 'rel_id', package_name => 'ab_contact_rel', object_type_one => 'acs_object', min_n_rels_one => 0, max_n_rels_one => null, object_type_two => 'ab_contact', role_two => 'contact', min_n_rels_two => 0, max_n_rels_two => null ); end; / show errors create table ab_contact_rels ( rel_id constraint ab_contact_rels_rel_id_fk references acs_rels (rel_id) constraint ab_contact_rels_rel_id_pk primary key, category varchar(30) ); create or replace package ab_contact_rel as function new ( rel_id in ab_contact_rels.rel_id%TYPE default null, rel_type in acs_rels.rel_type%TYPE default 'ab_contact_rel', object_id_one in acs_rels.object_id_one%TYPE, object_id_two in acs_rels.object_id_two%TYPE, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, category in ab_contact_rels.category%TYPE default null ) return ab_contact_rels.rel_id%TYPE; procedure delete ( rel_id in ab_contact_rels.rel_id%TYPE ); end ab_contact_rel; / show errors create or replace package body ab_contact_rel as function new ( rel_id in ab_contact_rels.rel_id%TYPE default null, rel_type in acs_rels.rel_type%TYPE default 'ab_contact_rel', object_id_one in acs_rels.object_id_one%TYPE, object_id_two in acs_rels.object_id_two%TYPE, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, category in ab_contact_rels.category%TYPE default null ) return ab_contact_rels.rel_id%TYPE is v_rel_id ab_contact_rels.rel_id%TYPE; begin v_rel_id := acs_rel.new ( rel_id => rel_id, rel_type => rel_type, object_id_one => object_id_one, object_id_two => object_id_two, context_id => object_id_one, creation_user => creation_user, creation_ip => creation_ip ); insert into ab_contact_rels (rel_id, category) values (v_rel_id, new.category); return v_rel_id; end new; procedure delete ( rel_id in ab_contact_rels.rel_id%TYPE ) is begin acs_object.delete(rel_id); end delete; end ab_contact_rel; / show errors ------------------------ -- AB_CONTACT PACKAGE -- ------------------------ create or replace package ab_contact as function new ( contact_id in ab_contacts.contact_id%TYPE default null, object_type in acs_objects.object_type%TYPE default 'ab_contact', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null, first_names in ab_contacts.first_names%TYPE default null, last_name in ab_contacts.last_name%TYPE default null, title in ab_contacts.title%TYPE default null, organization in ab_contacts.organization%TYPE default null, object_id in acs_objects.object_id%TYPE default null, category in ab_contact_rels.category%TYPE default null ) return ab_contacts.contact_id%TYPE; function name ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2; procedure delete ( contact_id in ab_contacts.contact_id%TYPE, delete_orphan_addresses_p in char default 't' ); function work_phone ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2; function home_phone ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2; function fax ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2; function other ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2; function email ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2; end ab_contact; / show errors create or replace package body ab_contact as function new ( contact_id in ab_contacts.contact_id%TYPE default null, object_type in acs_objects.object_type%TYPE default 'ab_contact', creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, context_id in acs_objects.context_id%TYPE default null, first_names in ab_contacts.first_names%TYPE default null, last_name in ab_contacts.last_name%TYPE default null, title in ab_contacts.title%TYPE default null, organization in ab_contacts.organization%TYPE default null, object_id in acs_objects.object_id%TYPE default null, category in ab_contact_rels.category%TYPE default null ) return ab_contacts.contact_id%TYPE is v_contact_id ab_contacts.contact_id%TYPE; v_rel_id ab_contact_rels.rel_id%TYPE; begin v_contact_id := acs_object.new(object_id => contact_id, object_type => object_type, creation_date => creation_date, creation_user => creation_user, creation_ip => creation_ip, context_id => context_id); -- If they supplied an object_id, relate it: if object_id is not null then v_rel_id := ab_contact_rel.new(object_id_one => object_id, object_id_two => v_contact_id, creation_user => creation_user, creation_ip => creation_ip, category => category); end if; insert into ab_contacts (contact_id, first_names, last_name, title, organization) values (v_contact_id, new.first_names, new.last_name, new.title, new.organization); return v_contact_id; end new; function name ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2 is v_name varchar2(400); begin select first_names||' '||last_name into v_name from ab_contacts where contact_id = name.contact_id; return v_name; end name; procedure delete ( contact_id in ab_contacts.contact_id%TYPE, delete_orphan_addresses_p in char default 't' ) is v_ab_contact_attrs_row ab_contact_attrs%ROWTYPE; v_addresses_located_row pl_addresses_located%ROWTYPE; cursor address_is_orphan_p_cursor (address_id in pl_addresses.address_id%TYPE) is select decode(count(*),0,'t','f') from place_element_map where place_id = address_is_orphan_p_cursor.address_id; v_address_is_orphan_p char(1); cursor subplace_rel_cursor (address_id in pl_addresses.address_id%TYPE) is select sr.rel_id from subplace_rels sr, acs_rels ar where ar.rel_id = sr.rel_id and ar.object_id_two = subplace_rel_cursor.address_id; v_rel_id subplace_rels.rel_id%TYPE; begin -- First blow away attributes for v_ab_contact_attrs_row in (select attr_id from ab_contact_attrs where contact_id = ab_contact.delete.contact_id) loop ab_contact_attr.delete(v_ab_contact_attrs_row.attr_id); end loop; -- Then iterate through address location relations for v_addresses_located_row in (select * from pl_addresses_located where locatee_id = ab_contact.delete.contact_id) loop -- Delete the rel subplace_rel.delete(v_addresses_located_row.rel_id); -- If we're deleting orphans then if delete_orphan_addresses_p = 't' then -- Check if the address is an orphan open address_is_orphan_p_cursor(address_id => v_addresses_located_row.address_id); fetch address_is_orphan_p_cursor into v_address_is_orphan_p; close address_is_orphan_p_cursor; if v_address_is_orphan_p = 't' then -- Delete the address's subplace_relation open subplace_rel_cursor(address_id => v_addresses_located_row.address_id); fetch subplace_rel_cursor into v_rel_id; if not subplace_rel_cursor%NOTFOUND then subplace_rel.delete(v_rel_id); end if; close subplace_rel_cursor; -- Delete the address itself pl_address.delete(v_addresses_located_row.address_id); end if; end if; end loop; acs_object.delete(contact_id); end delete; function work_phone ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2 is v_value ab_contact_attrs.value%TYPE; begin select value into v_value from ab_contact_attrs where contact_id = work_phone.contact_id and sort_key = (select min(sort_key) from ab_contact_attrs where contact_id = work_phone.contact_id and type_key = 'work_phone'); return v_value; end work_phone; function home_phone ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2 is v_value ab_contact_attrs.value%TYPE; begin select value into v_value from ab_contact_attrs where contact_id = home_phone.contact_id and sort_key = (select min(sort_key) from ab_contact_attrs where contact_id = home_phone.contact_id and type_key = 'home_phone'); return v_value; end home_phone; function fax ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2 is v_value ab_contact_attrs.value%TYPE; begin select value into v_value from ab_contact_attrs where contact_id = fax.contact_id and sort_key = (select min(sort_key) from ab_contact_attrs where contact_id = fax.contact_id and type_key = 'fax'); return v_value; end fax; function other ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2 is v_value ab_contact_attrs.value%TYPE; begin select value into v_value from ab_contact_attrs where contact_id = other.contact_id and sort_key = (select min(sort_key) from ab_contact_attrs where contact_id = other.contact_id and type_key = 'other'); return v_value; end other; function email ( contact_id in ab_contacts.contact_id%TYPE ) return varchar2 is v_value ab_contact_attrs.value%TYPE; begin select value into v_value from ab_contact_attrs where contact_id = email.contact_id and sort_key = (select min(sort_key) from ab_contact_attrs where contact_id = email.contact_id and type_key = 'email'); return v_value; end email; end ab_contact; / show errors -------------------------- -- AB_CONTACTS_COMPLETE -- -------------------------- create or replace view ab_contacts_complete as select ac.*, ab_contact.work_phone(contact_id) work_phone, ab_contact.home_phone(contact_id) home_phone, ab_contact.fax(contact_id) fax, ab_contact.other(contact_id) other, ab_contact.email(contact_id) email from ab_contacts ac; create or replace view ab_contacts_related as select acc.*, ar.rel_id, ar.object_id_one as object_id, acrel.category from ab_contacts_complete acc, acs_rels ar, ab_contact_rels acrel where acc.contact_id = ar.object_id_two and ar.rel_id = acrel.rel_id;