-- Package jr_names -- Author: Patrick Lorrimer -- -- This package provides the PL/SQL naming service API. -- It allows the IVID of an object to be determined from -- a path of common repository names (CRN). -- A CRN can have two formats: -- name{branch;version} -- or name{vlabel} -- version can either be a version number, or 'LATEST' -- and CRNs are only valid within the context of a folder -- To identify an object, the full pathname must be given. -- a pathname consits of CRNs delimited by '/', '\' or '.' -- -- e.g. FOL1{MAIN;LATEST}/MY_FOL{MAIN;3}/MY_FILE.EXE{MAIN;LATEST} -- FOL1{MY_LABEL}/MY_FOL{BUG123}/MY_FILE.EXE{BUG123} -- -- Pathnames can consist of a mixture of the two formats of CRN, -- and contain a mixture of '/' , '\' and '.'. -- NOte that the naming service can cope with filenames like -- 'my_file.ext' at the end of a dot-seperated path... -- -- If a workarea context is set, the path can consist of just -- the names of the folders and object - -- -- e.g. FOL1/MY_FOL/MY_FILE.EXE -- -- and the ivid returned will depend on the current context. -- Alternatively, a list of all the objects making up a -- path can be obtained. -- -- The IVID of an object in the context of a configuration -- can be determined from the ivid of the configuration -- and the path of the object (using object name only). -- -- Can also recover the full path of an object version from -- its IVID -- -- Can also determine the contents of a folder(and its sub folders) -- from a given folder IVID or path. -- --prompt PACKAGE BODY: jr_names CREATE OR REPLACE PACKAGE BODY Jr_Name IS -------------------------------------- -- Special Characters used in all CRNs -------------------------------------- escape_char char(1) := '^'; file_seperator1 char(1) := '\'; file_seperator2 char(1) := '/'; sac_seperator char(1) := '.'; branch_seperator char(1) := ';'; version_start char(1) := '{'; version_end char(1) := '}'; type_seperator char(1) := '='; wildcard_char char(1) := '*'; single_wildcard_char char(1) := '?'; -------------------------------------- -- Flag to indicate case sensitivity -------------------------------------- case_sensitive_flag varchar2(1) := 'Y'; -------------------------------------- -- logical_type_id for APP and FOL -------------------------------------- app_type_id number := 5009; fol_type_id number := 4844; ------------------------------------------------- -- Private method declarations ------------------------------------------------- FUNCTION is_root_fol(i_ivid IN number) RETURN boolean; PROCEDURE get_folder(el_irid IN number ,fol_irid OUT number ,fol_ivid OUT number); PROCEDURE get_folder_no_context(el_irid IN number ,branch IN varchar2 ,brnch_id IN number ,fol_irid OUT number ,fol_ivid OUT number); FUNCTION get_descriptor(el_id IN number ,el_type IN number) RETURN varchar2; FUNCTION get_descr_and_pac(el_id IN number ,el_type IN number ,format IN varchar2 ,add_escapes IN number ,pac_irid OUT number) RETURN varchar2; PROCEDURE get_id_props(el_id IN number ,el_type IN number ,elem_irid OUT number ,elem_ivid OUT number ,pac_irid OUT number ,pac_ivid OUT number); FUNCTION get_descr_prop(el_id IN number ,descr_col IN varchar2 ,view_name IN varchar2 ,elem_primary IN varchar2) RETURN varchar2; FUNCTION get_ref_descr_prop(el_id IN number ,el_type IN number ,prop_id IN number ,col_name IN varchar2 ,view_name IN varchar2 ,elem_primary IN varchar2)RETURN varchar2; FUNCTION get_generic_ref_type(el_id IN number ,el_type IN number ,prop_id IN number ,view_name IN varchar2 ,elem_primary IN varchar2) RETURN number; FUNCTION is_des_el_name_unique(con_irid IN number ,pac_irid IN number ,elem_type IN varchar2 ,clash_irid OUT number ,clash_type_id OUT number) RETURN boolean; FUNCTION is_reg_el_name_unique(con_irid IN number ,pac_irid IN number ,elem_type IN varchar2 ,clash_irid OUT number ,clash_type_id OUT number) RETURN boolean; FUNCTION is_versioned(el_irid number ,view_name varchar2 ,elem_primary varchar2) RETURN boolean; FUNCTION remove_escapes(string IN varchar2) RETURN varchar2; ---------------------------------------------------- -- Global declarations of standard SQL ----------------------------------------------------- ver_res_primary varchar2(300) := ' and el.ivid=(select va.to_ivid'|| ' from sdd_version_associations va'|| ' ,I$SDD_BRANCHES br'|| ' where va.irid=el.irid'|| ' and va.edge_kind=''T'''|| ' and va.branch_id=br.branch_id'|| ' and br.name=''MAIN'')'; ver_res_secondary varchar2(300) := ' and el.parent_ivid=(select va.to_ivid'|| ' from sdd_version_associations va'|| ' ,I$SDD_BRANCHES br'|| ' where va.irid=el.pac_ref'|| ' and va.edge_kind=''T'''|| ' and va.branch_id=br.branch_id'|| ' and br.name=''MAIN'')'; ver_res_optional varchar2(300) := ' and NVL(el.parent_ivid,el.ivid)=(select va.to_ivid'|| ' from sdd_version_associations va'|| ' ,I$SDD_BRANCHES br'|| ' where va.irid=NVL(el.pac_ref,el.irid)'|| ' and va.edge_kind=''T'''|| ' and va.branch_id=br.branch_id'|| ' and br.name=''MAIN'')'; ----------------------------------------------------- -- Case_Sensitive() -- Returns TRUE if naming service is in case -- sensitive mode, otherwise returns FALSE. ----------------------------------------------------- FUNCTION case_sensitive RETURN boolean IS BEGIN RETURN case_sensitive_flag='Y'; END; ----------------------------------------------------- -- Enable_Case_Sensitivity() -- Puts the naming service into case -- sensitive mode. ----------------------------------------------------- PROCEDURE enable_case_sensitivity IS BEGIN case_sensitive_flag:='Y'; END; ----------------------------------------------------- -- Disable_Case_Sensitivity() -- Puts the naming service into case -- insensitive mode. ----------------------------------------------------- PROCEDURE disable_case_sensitivity IS BEGIN case_sensitive_flag:='N'; END; ----------------------------------------------------- -- Get_Case_Sensitive_Flag() -- Returns value of case_sensitive_flag -- 'Y' - case sensitive -- 'N' - case insensitive ----------------------------------------------------- FUNCTION get_case_sensitive_flag RETURN varchar2 IS BEGIN RETURN case_sensitive_flag; END; ----------------------------------------------------- -- Initialize() -- Sets up non-default values for special characters -- used in naming service... ----------------------------------------------------- PROCEDURE initialize(i_escape_char IN char ,i_file_seperator1 IN char ,i_file_seperator2 IN char ,i_sac_seperator IN char ,i_branch_seperator IN char ,i_version_start IN char ,i_version_end IN char ,i_type_seperator IN char ,i_wildcard_char IN char ,i_single_wildcard_char IN char) IS BEGIN IF i_escape_char IS NOT NULL THEN escape_char := i_escape_char; END IF; IF i_file_seperator1 IS NOT NULL THEN file_seperator1 := i_file_seperator1; END IF; IF i_file_seperator2 IS NOT NULL THEN file_seperator2 := i_file_seperator2; END IF; IF i_sac_seperator IS NOT NULL THEN sac_seperator := i_sac_seperator; END IF; IF i_branch_seperator IS NOT NULL THEN branch_seperator := i_branch_seperator; END IF; IF i_version_end IS NOT NULL THEN version_end := i_version_end; END IF; IF i_version_start IS NOT NULL THEN version_start := i_version_start; END IF; IF i_type_seperator IS NOT NULL THEN type_seperator := i_type_seperator; END IF; IF i_wildcard_char IS NOT NULL THEN wildcard_char := i_wildcard_char; END IF; IF i_single_wildcard_char IS NOT NULL THEN single_wildcard_char := i_single_wildcard_char; END IF; END; ----------------------------------------------------- -- Special_Chars() -- Returns the values for the special characters -- used in naming service... ----------------------------------------------------- PROCEDURE Special_Chars(o_escape_char OUT char ,o_file_seperator1 OUT char ,o_file_seperator2 OUT char ,o_sac_seperator OUT char ,o_branch_seperator OUT char ,o_version_start OUT char ,o_version_end OUT char ,o_type_seperator OUT char ,o_wildcard_char OUT char ,o_single_wildcard_char OUT char) IS BEGIN o_escape_char := escape_char; o_file_seperator1 := file_seperator1; o_file_seperator2 := file_seperator2; o_sac_seperator := sac_seperator; o_branch_seperator := branch_seperator; o_version_start := version_start; o_version_end := version_end; o_type_seperator := type_seperator; o_wildcard_char := wildcard_char; o_single_wildcard_char := single_wildcard_char; END; ----------------------------------------------------- --GetWildCardLocation() --PRIVATE HELPER FUNCTION --Find any non-escaped Oracle Wildcard Characters ----------------------------------------------------- FUNCTION GetWildCardLocation(p_str IN varchar2) RETURN integer IS l_esc_pos integer := INSTR(p_str, escape_char); l_und_pos integer := INSTR(p_str, '_'); l_pct_pos integer := INSTR(p_str, '%'); l_wc_pos integer := 0; l_str varchar2(2000); BEGIN IF l_und_pos > 0 THEN l_wc_pos := l_und_pos; END IF; IF l_pct_pos > 0 THEN IF l_wc_pos = 0 THEN l_wc_pos := l_pct_pos; ELSIF l_pct_pos < l_wc_pos THEN l_wc_pos := l_pct_pos; END IF; END IF; IF l_esc_pos > 0 THEN IF l_esc_pos + 1 = l_wc_pos THEN -- recurse to next wc RETURN l_esc_pos + 1 + GetWildCardLocation(SUBSTR(p_str,l_wc_pos+1)); END IF; END IF; RETURN l_wc_pos; END; ----------------------------------------------------- --find_root_by_name() --Find a root folder in the current workarea context, --given its name ----------------------------------------------------- FUNCTION find_root_by_name(i_name IN varchar2, type_id IN number) RETURN objver_list IS object_set objver_list := objver_list(); l_name varchar2(400); l_wc_pos pls_integer; cfg_etid number; --No wild cards, case sensitve CURSOR no_wcs_cs IS SELECT fol.irid fol_irid,fol.ivid fol_ivid FROM CI_ROOT_CONTAINER_ELEMENTS fol WHERE fol.name = l_name AND ( (type_id IS NULL) OR (type_id = fol.types) ); --No wild cards, case insensitive CURSOR no_wcs_ci IS SELECT fol.irid fol_irid,fol.ivid fol_ivid FROM CI_ROOT_CONTAINER_ELEMENTS fol WHERE NLS_UPPER(fol.name) = NLS_UPPER(l_name) AND ( (type_id IS NULL) OR (type_id = fol.types) ); --Wild cards at start, case sensitive CURSOR wcs_at_start_cs IS SELECT fol.irid fol_irid,fol.ivid fol_ivid FROM CI_ROOT_CONTAINER_ELEMENTS fol WHERE fol.name LIKE l_name escape escape_char AND ( (type_id IS NULL) OR (type_id = fol.types) ); --Wild cards at start, case insensitive CURSOR wcs_at_start_ci IS SELECT fol.irid fol_irid,fol.ivid fol_ivid FROM CI_ROOT_CONTAINER_ELEMENTS fol WHERE NLS_UPPER(fol.name) LIKE NLS_UPPER(l_name) escape escape_char AND ( (type_id IS NULL) OR (type_id = fol.types) ); CURSOR configs IS SELECT cf.irid cf_irid,cf.ivid cf_ivid FROM SDD_CONFIGURATIONS cf ,I$SDD_OBJECT_VERSIONS ov WHERE cf.name LIKE l_name escape escape_char AND ov.IVID=cf.ivid AND ov.state!='I'; --Can only identify checked out/non-versioned configs --by name alone. CURSOR configs_no_case IS SELECT cf.irid cf_irid,cf.ivid cf_ivid FROM SDD_CONFIGURATIONS cf ,I$SDD_OBJECT_VERSIONS ov WHERE NLS_UPPER(cf.name) LIKE NLS_UPPER(l_name) escape escape_char AND ov.IVID=cf.ivid AND ov.state!='I'; --Can only identify checked out/non-versioned configs --by name alone. BEGIN --Get hold of type id for configurations BEGIN SELECT et.id INTO cfg_etid FROM RM_ELEMENT_TYPES et WHERE et.short_name='CFG'; EXCEPTION WHEN NO_DATA_FOUND THEN cfg_etid := -1; END; l_name:=i_name; -- Is there a wildcard in the string l_wc_pos := GetWildCardLocation(l_name); IF l_wc_pos = 0 THEN --Name does not contain any non-escaped wild cards. --We need to strip any escape characters from the name --as we will attempt to do an exact match. l_name:=remove_escapes(l_name); END IF; IF ((type_id IS NULL) OR (type_id!=cfg_etid)) THEN --Not looking specifically for a configuration IF case_sensitive THEN --Case sensitive, no wild cards IF l_wc_pos = 0 THEN FOR obj IN no_wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.fol_irid; object_set(object_set.last).ivid:=obj.fol_ivid; END LOOP; ELSE --Case sensitive, wild cards FOR obj IN wcs_at_start_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.fol_irid; object_set(object_set.last).ivid:=obj.fol_ivid; END LOOP; END IF; ELSE --Case insensitve, no wild cards IF l_wc_pos = 0 THEN FOR obj IN no_wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.fol_irid; object_set(object_set.last).ivid:=obj.fol_ivid; END LOOP; ELSE --Case insensitive, wild cards FOR obj IN wcs_at_start_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.fol_irid; object_set(object_set.last).ivid:=obj.fol_ivid; END LOOP; END IF;--Wild cards END IF; --Case Sensitive END IF; --Not a config IF (type_id IS NULL) OR (type_id=cfg_etid) THEN --Either specifically looking for a configuration, or --looking for any element type - may be config IF case_sensitive THEN FOR cfg IN configs LOOP object_set.extend(); object_set(object_set.last).irid:=cfg.cf_irid; object_set(object_set.last).ivid:=cfg.cf_ivid; END LOOP; ELSE FOR cfg IN configs_no_case LOOP object_set.extend(); object_set(object_set.last).irid:=cfg.cf_irid; object_set(object_set.last).ivid:=cfg.cf_ivid; END LOOP; END IF; END IF; RETURN object_set; END; -------------------------------------------------------- --find_by_name() --Find an object/folder in the current workarea context, --given its name, and owning folder -------------------------------------------------------- FUNCTION find_by_name(prev_ivid IN number ,i_name IN varchar2 ,type_id IN number) RETURN objver_list IS l_wc_pos integer; l_name varchar2(400); object_set objver_list := objver_list(); -- No Wild Cards, Case Sensitive CURSOR no_wcs_cs IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE ov.name = l_name AND ( type_id IS NULL OR type_id = ov.logical_type_id ) AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; -- No Wild Cards, Case Insensitive CURSOR no_wcs_ci IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE NLS_UPPER(ov.name) = NLS_UPPER(l_name) AND ( type_id IS NULL OR type_id = ov.logical_type_id ) AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; -- Wild Cards, Case Sensitive CURSOR wc_at_start_cs IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM sdd_object_versions ov ,I$SDD_FOLDER_MEMBERS fm WHERE ov.name LIKE l_name escape escape_char AND ( type_id IS NULL OR type_id = ov.logical_type_id ) AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; -- Wild Cards, Case Insensitive CURSOR wc_at_start_ci IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND ( type_id IS NULL OR type_id = ov.logical_type_id ) AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; -- Oracle8i only wc_mid varchar2(2000):= 'select ov.irid,ov.ivid FROM SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE ( :type_id IS NULL OR :type_id = ov.logical_type_id) AND ov.irid=fm.member_object AND fm.parent_ivid=:prev_ivid AND '; -- BEGIN l_name:=i_name; -- Is there a wildcard in the string l_wc_pos := GetWildCardLocation(l_name); IF l_wc_pos = 0 THEN --Name does not contain any non-escaped wild cards. --We need to strip any escape characters from the name --as we will attempt to do an exact match. l_name:=remove_escapes(l_name); END IF; IF case_sensitive THEN IF l_wc_pos = 0 THEN --No wildcards, case sensitive FOR obj IN no_wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; /* Oracle8i only - DBMS_SQL breaks WNDS pragmas elsif l_wc_pos > 5 then declare l_ivid number; l_irid number; dummy integer; csr integer := dbms_sql.open_cursor; begin -- worth using index for first 4 characters wc_mid := wc_mid || 'ov.name like ''' || replace(l_name,'''','''''') || ''' escape ''' || escape_char ||''''; dbms_sql.parse(csr,wc_mid,dbms_sql.NATIVE); dbms_sql.define_column(csr,1,l_irid); dbms_sql.define_column(csr,2,l_ivid); dbms_sql.bind_variable(csr,'type_id',type_id); dbms_sql.bind_variable(csr,'prev_ivid',prev_ivid); dummy:=dbms_sql.execute(csr); --Fetch the data back while dbms_sql.fetch_rows(csr) > 0 loop --Get the values dbms_sql.column_value(csr,1,l_irid); dbms_sql.column_value(csr,2,l_ivid); object_set.extend(); object_set(object_set.last).irid:=l_irid; object_set(object_set.last).ivid:=l_ivid; end loop; dbms_sql.close_cursor(csr); exception when others then dbms_sql.close_cursor(csr); end; */ ELSE --Have wild card, case sensitive FOR obj IN wc_at_start_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; ELSE -- Case insensitive IF l_wc_pos = 0 THEN -- No wildcards, case sensitive FOR obj IN no_wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; /* Oracle8i only - DBMS_SQL breaks WNDS pragmas... elsif l_wc_pos > 5 then -- -- Its still worth using index for first 4 characters -- declare l_ivid number; l_irid number; dummy integer; csr integer := dbms_sql.open_cursor; begin -- Assume that we have a function based index on NLS_UPPER(ov.name) -- wc_mid := wc_mid || 'NLS_UPPER(ov.name) like ''' || replace(NLS_UPPER(l_name),'''','''''') || ''' escape ''' || escape_char ||''''; dbms_sql.parse(csr,wc_mid,dbms_sql.NATIVE); dbms_sql.define_column(csr,1,l_irid); dbms_sql.define_column(csr,2,l_ivid); dbms_sql.bind_variable(csr,'type_id',type_id); dbms_sql.bind_variable(csr,'prev_ivid',prev_ivid); dummy:=dbms_sql.execute(csr); --Fetch the data back while dbms_sql.fetch_rows(csr) > 0 loop --Get the values dbms_sql.column_value(csr,1,l_irid); dbms_sql.column_value(csr,2,l_ivid); object_set.extend(); object_set(object_set.last).irid:=l_irid; object_set(object_set.last).ivid:=l_ivid; end loop; dbms_sql.close_cursor(csr); exception when others then dbms_sql.close_cursor(csr); end; */ ELSE --Have wildcards, case sensitive FOR obj IN wc_at_start_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; END IF; RETURN object_set; END; ----------------------------------------------------- --find_root_by_vlabel() --Find a root folder given its name and version label ----------------------------------------------------- FUNCTION find_root_by_vlabel(i_name IN varchar2 ,l_vlabel IN varchar2 ,type_id IN number) RETURN objver_list IS l_name varchar2(400); l_wc_pos pls_integer; object_set objver_list := objver_list(); CURSOR wcs_cs IS --Check root containers... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDERS fol WHERE ov.name LIKE l_name escape escape_char AND ov.vlabel=l_vlabel AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.wastebasket=Jr_Context.wastebasket AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,SDD_CONFIGURATIONS cfg WHERE ov.name LIKE l_name escape escape_char AND ov.vlabel=l_vlabel AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR no_wcs_cs IS --Check root containers... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDERS fol WHERE ov.name = l_name AND ov.vlabel=l_vlabel AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.wastebasket=Jr_Context.wastebasket AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,SDD_CONFIGURATIONS cfg WHERE ov.name= l_name AND ov.vlabel=l_vlabel AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR wcs_ci IS --Check root containers... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDERS fol WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND NLS_UPPER(ov.vlabel)=NLS_UPPER(l_vlabel) AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.wastebasket=Jr_Context.wastebasket AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,SDD_CONFIGURATIONS cfg WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND NLS_UPPER(ov.vlabel)=NLS_UPPER(l_vlabel) AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR no_wcs_ci IS --Check root containers... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDERS fol WHERE NLS_UPPER(ov.name) = NLS_UPPER(l_name) AND NLS_UPPER(ov.vlabel)=NLS_UPPER(l_vlabel) AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.wastebasket=Jr_Context.wastebasket AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,SDD_CONFIGURATIONS cfg WHERE NLS_UPPER(ov.name) = NLS_UPPER(l_name) AND NLS_UPPER(ov.vlabel)=NLS_UPPER(l_vlabel) AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR new_objects IS --Check root containers.... SELECT ov.irid ov_irid, ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDERS fol WHERE ov.name LIKE l_name escape escape_char AND ov.state='N' AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.wastebasket=Jr_Context.wastebasket AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid, ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,SDD_CONFIGURATIONS cfg WHERE ov.name LIKE l_name escape escape_char AND ov.state='N' AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR new_objects_no_case IS --Check root containers.... SELECT ov.irid ov_irid, ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDERS fol WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND ov.state='N' AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.wastebasket=Jr_Context.wastebasket AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid, ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,SDD_CONFIGURATIONS cfg WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND ov.state='N' AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; BEGIN l_name:=i_name; --User specified NEW, then look for new objects matching the specified name... IF l_vlabel ='NEW' THEN IF case_sensitive THEN FOR obj IN new_objects LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE FOR obj IN new_objects_no_case LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; END IF; -- Is there a wildcard in the string l_wc_pos := GetWildCardLocation(l_name); IF l_wc_pos = 0 THEN --Name does not contain any non-escaped wild cards. --We need to strip any escape characters from the name --as we will attempt to do an exact match. l_name:=remove_escapes(l_name); END IF; IF case_sensitive THEN IF l_wc_pos=0 THEN --No wild cards, case sensive FOR obj IN no_wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Has wild cards, case sensitive FOR obj IN wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; ELSE IF l_wc_pos=0 THEN --No wild cards, case insensitive FOR obj IN no_wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Has wild cards, case insensitive FOR obj IN wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; END IF; RETURN object_set; END; ----------------------------------------------------- --find_by_vlabel() --Find an object/folder given its name, version label --and owning folder ----------------------------------------------------- FUNCTION find_by_vlabel(prev_ivid IN number ,i_name IN varchar2 ,l_vlabel IN varchar2 ,type_id IN number) RETURN objver_list IS l_name varchar2(400); l_wc_pos pls_integer; object_set objver_list := objver_list(); CURSOR wcs_cs IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE ov.name LIKE l_name escape escape_char AND ov.vlabel = l_vlabel AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; CURSOR no_wcs_cs IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE ov.name = l_name AND ov.vlabel = l_vlabel AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; CURSOR wcs_ci IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND NLS_UPPER(ov.vlabel) = NLS_UPPER(l_vlabel) AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; CURSOR no_wcs_ci IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE NLS_UPPER(ov.name) =NLS_UPPER(l_name) AND NLS_UPPER(ov.vlabel) = NLS_UPPER(l_vlabel) AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; BEGIN l_name:=i_name; -- Is there a wildcard in the string l_wc_pos := GetWildCardLocation(l_name); IF l_wc_pos = 0 THEN --Name does not contain any non-escaped wild cards. --We need to strip any escape characters from the name --as we will attempt to do an exact match. l_name:=remove_escapes(l_name); END IF; IF case_sensitive THEN IF l_wc_pos=0 THEN --No wild cards, case sesnitive FOR obj IN no_wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Has wild cards, case sensitive FOR obj IN wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; ELSE IF l_wc_pos=0 THEN --No wild cards, case insensitive FOR obj IN no_wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Has wild cards, case insensitive FOR obj IN wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; END IF; RETURN object_set; END; ------------------------------------------------ --find_root_by_vernum() --Find a root folder given its name, branch --and version number ------------------------------------------------ FUNCTION find_root_by_vernum(i_name IN varchar2 ,l_branch_id IN number ,l_version IN number ,type_id IN number) RETURN objver_list IS object_set objver_list := objver_list(); l_name varchar2(400); l_wc_pos pls_integer; CURSOR latest_wcs_cs IS --Check root folders... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,I$SDD_FOLDERS fol WHERE ov.name LIKE l_name escape escape_char AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,SDD_CONFIGURATIONS cfg WHERE ov.name LIKE l_name escape escape_char AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR latest_no_wcs_cs IS --Check root folders... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,I$SDD_FOLDERS fol WHERE ov.name = l_name AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,SDD_CONFIGURATIONS cfg WHERE ov.name = l_name AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR latest_wcs_ci IS --Check root folders... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,I$SDD_FOLDERS fol WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,SDD_CONFIGURATIONS cfg WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR latest_no_wcs_ci IS --Check root folders... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,I$SDD_FOLDERS fol WHERE NLS_UPPER(ov.name) = NLS_UPPER(l_name) AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,SDD_CONFIGURATIONS cfg WHERE NLS_UPPER(ov.name) = NLS_UPPER(l_name) AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR wcs_cs IS --Check root containers... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDERS fol WHERE ov.name LIKE l_name escape escape_char AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,SDD_CONFIGURATIONS cfg WHERE ov.name LIKE l_name escape escape_char AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR no_wcs_cs IS --Check root containers... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDERS fol WHERE ov.name = l_name AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,SDD_CONFIGURATIONS cfg WHERE ov.name = l_name AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR wcs_ci IS --Check root containers... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDERS fol WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,SDD_CONFIGURATIONS cfg WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; CURSOR no_wcs_ci IS --Check root containers... SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDERS fol WHERE NLS_UPPER(ov.name) = NLS_UPPER(l_name) AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND fol.ivid=ov.ivid AND fol.root_flag='Y' UNION --...and configurations SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,SDD_CONFIGURATIONS cfg WHERE NLS_UPPER(ov.name) = NLS_UPPER(l_name) AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND cfg.ivid=ov.ivid; BEGIN l_name:=i_name; -- Is there a wildcard in the string l_wc_pos := GetWildCardLocation(l_name); IF l_wc_pos = 0 THEN --Name does not contain any non-escaped wild cards. --We need to strip any escape characters from the name --as we will attempt to do an exact match. l_name:=remove_escapes(l_name); END IF; IF (l_version=0) THEN -- Get the latest version on the branch IF case_sensitive THEN IF l_wc_pos = 0 THEN --No wildcards, case sensitive, latest version FOR obj IN latest_no_wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Has wildcards, case sensitive, latest version FOR obj IN latest_wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; ELSE IF l_wc_pos = 0 THEN --No wildcards, case insensitive, latest version FOR obj IN latest_no_wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Has wildcards, case insensitive, latest version FOR obj IN latest_wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF;--Has wild cards END IF;--Case sensitive ELSE -- Get the specified version on the branch IF case_sensitive THEN IF l_wc_pos = 0 THEN --No wildcards, case sensitive FOR obj IN no_wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Has wildcards, case sensitive FOR obj IN wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; ELSE IF l_wc_pos = 0 THEN --No wildcards, case insensitive FOR obj IN no_wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Has wildcards, case insensitive FOR obj IN wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF;--Has wildcards END IF;--Case sensitive END IF; --Latest versions RETURN object_set; END; --------------------------------------------------- -- find_by_vernum() -- Find an object/folder given its name, branch, -- version number and owning folder --------------------------------------------------- FUNCTION find_by_vernum(prev_ivid IN number ,i_name IN varchar2 ,l_branch_id IN number ,l_version IN number ,type_id IN number) RETURN objver_list IS object_set objver_list := objver_list(); l_name varchar2(400); l_wc_pos pls_integer; CURSOR latest_wcs_cs IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,I$SDD_FOLDER_MEMBERS fm WHERE ov.name LIKE l_name escape escape_char AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; CURSOR latest_no_wcs_cs IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,I$SDD_FOLDER_MEMBERS fm WHERE ov.name = l_name AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; CURSOR latest_wcs_ci IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,I$SDD_FOLDER_MEMBERS fm WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; CURSOR latest_no_wcs_ci IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va ,I$SDD_FOLDER_MEMBERS fm WHERE NLS_UPPER(ov.name) = NLS_UPPER(l_name) AND va.branch_id=l_branch_id AND va.edge_kind='T' AND ov.ivid=va.to_ivid AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; CURSOR wcs_cs IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE ov.name LIKE l_name escape escape_char AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; CURSOR no_wcs_cs IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE ov.name = l_name AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; CURSOR wcs_ci IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; CURSOR no_wcs_ci IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE NLS_UPPER(ov.name) = NLS_UPPER(l_name) AND ov.branch_id=l_branch_id AND ov.sequence_in_branch=l_version AND ov.wastebasket=Jr_Context.wastebasket AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND Jr_Acc_Rights.can_sel(ov.ivid)='Y' AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; BEGIN l_name:=i_name; -- Is there a wildcard in the string l_wc_pos := GetWildCardLocation(l_name); IF l_wc_pos = 0 THEN --Name does not contain any non-escaped wild cards. --We need to strip any escape characters from the name --as we will attempt to do an exact match. l_name:=remove_escapes(l_name); END IF; IF (l_version=0) THEN -- Get the latest version on the branch IF case_sensitive THEN IF l_wc_pos = 0 THEN --Latest, case sensitive, no wildcards FOR obj IN latest_no_wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Latest, case sensitive, wildcards FOR obj IN latest_wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; ELSE IF l_wc_pos = 0 THEN --Latest, case insesnitve, no wildcards FOR obj IN latest_no_wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Latest, case insesnitve, wildcards FOR obj IN latest_wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; END IF; ELSE -- Get the specified version on the branch IF case_sensitive THEN IF l_wc_pos = 0 THEN --Case sensitive, no wildcards FOR obj IN no_wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Case sensitive, has wildcards FOR obj IN wcs_cs LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF; ELSE IF l_wc_pos = 0 THEN --Case insensitive, no wildcards FOR obj IN no_wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; ELSE --Case insensitive, has wildcards FOR obj IN wcs_ci LOOP object_set.extend(); object_set(object_set.last).irid:=obj.ov_irid; object_set(object_set.last).ivid:=obj.ov_ivid; END LOOP; END IF;--Wildcards END IF;--Case sensitive END IF;--Latest RETURN object_set; END; -------------------------------------------------------- --find_SAC() --Find a secondary element, given it's name, it's --predecessor, and the type irid for it's predecessor. -------------------------------------------------------- FUNCTION find_SAC(prev_irid IN number ,l_name IN varchar2 ,prev_type_id IN number ,types_found OUT jr_num_list ,this_type_id IN number) RETURN objver_list IS l_prev_type_id number; csr integer; query varchar2(1000); curr_type number; curr_irid number; curr_ivid number; dummy integer; table_name varchar2(1000); object_set objver_list := objver_list(); CURSOR build_query IS SELECT this_tab.table_name ,this_tab.name_column ,this_col.column_name ,this_type.irid type_id FROM RM_SQL_CONS_COLUMNS this_col ,RM_SQL_TABLES this_tab ,RM_SQL_CONSTRAINTS this_con ,RM_SQL_ROW_TYPES this_srt ,RM_ELEMENT_TYPES this_type ,RM_SQL_CONSTRAINTS own_con ,RM_SQL_ROW_TYPES own_srt ,RM_ELEMENT_TYPES own_type WHERE this_tab.irid=this_con.table_irid AND this_col.constraint_irid=this_con.irid AND this_tab.name_column IS NOT NULL AND this_con.is_owning_fk='Y' AND this_srt.table_mapped=this_tab.irid AND this_type.primary_row_type=this_srt.id AND ( (this_type_id IS NULL) OR (this_type_id=this_type.irid) ) AND this_con.r_constraint_name=own_con.constraint_name AND own_con.table_irid=own_srt.table_mapped AND own_srt.id=own_type.primary_row_type AND own_type.id=l_prev_type_id; BEGIN --At present, we can only get SACs in the context of a workarea IF Jr_Context.workarea IS NULL THEN RAISE NULL_CONTEXT; END IF; l_prev_type_id:=prev_type_id; types_found:=jr_num_list(); --If the prev_type_id is null, then the previous element was a pac, --so find out what the type_id was IF l_prev_type_id IS NULL THEN SELECT ov.logical_type_id INTO l_prev_type_id FROM SDD_OBJECT_VERSIONS ov WHERE ov.irid=prev_irid; END IF; --open a cursor csr:=dbms_sql.open_cursor; --Build up and execute base-table queries for all possible child elements --of the predecessor. BEGIN FOR sac IN build_query LOOP IF case_sensitive THEN query:='select sac.irid, sac.ivid'|| ' from '||sac.table_name||' sac'|| ' where sac.'||sac.name_column||' like '''||l_name||''' escape '''||escape_char||''''|| ' and sac.'||sac.column_name||' = '||TO_CHAR(prev_irid); ELSE query:='select sac.irid, sac.ivid'|| ' from '||sac.table_name||' sac'|| ' where NLS_UPPER(sac.'||sac.name_column||') like '''||NLS_UPPER(l_name)||''' escape '''||escape_char||''''|| ' and sac.'||sac.column_name||' = '||TO_CHAR(prev_irid); END IF; curr_type:=sac.type_id; dbms_sql.parse(csr,query,dbms_sql.NATIVE); dbms_sql.define_column(csr,1,curr_irid); dbms_sql.define_column(csr,2,curr_ivid); dummy:=dbms_sql.execute(csr); --Fetch the data back WHILE dbms_sql.fetch_rows(csr) > 0 LOOP --Get the values dbms_sql.column_value(csr,1,curr_irid); dbms_sql.column_value(csr,2,curr_ivid); object_set.extend(); object_set(object_set.last).irid:=curr_irid; object_set(object_set.last).ivid:=curr_ivid; types_found.extend(); types_found(types_found.last):=curr_type; END LOOP; END LOOP; --Close the cursor dbms_sql.close_cursor(csr); EXCEPTION WHEN OTHERS THEN --If exception left cursor open, then close it... IF dbms_sql.is_open(csr) THEN dbms_sql.close_cursor(csr); END IF; RETURN objver_list(); END; --Return the objects found RETURN object_set; END; -------------------------------------------------------- --find_in_config() --Find an object/folder in the specified configuration, --given its name, and owning folder -------------------------------------------------------- FUNCTION find_in_config(l_name IN varchar2 ,config_ivid IN number ,prev_ivid IN number ,type_id IN number) RETURN objver_list IS object_set objver_list := objver_list(); CURSOR root IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_CONFIGURATION_MEMBERS cm WHERE ov.name LIKE l_name escape escape_char AND cm.config_ivid=config_ivid AND cm.object_ivid=ov.ivid AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND NOT EXISTS (SELECT 1 FROM SDD_FOLDER_MEMBERS WHERE member_object=ov.IRID); CURSOR root_no_case IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_CONFIGURATION_MEMBERS cm WHERE NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char AND cm.config_ivid=config_ivid AND cm.object_ivid=ov.ivid AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND NOT EXISTS (SELECT 1 FROM SDD_FOLDER_MEMBERS WHERE member_object=ov.IRID); CURSOR members IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm ,I$SDD_CONFIGURATION_MEMBERS cm WHERE ( (fm.name_in_context IS NOT NULL AND fm.name_in_context LIKE l_name escape escape_char) OR (ov.name LIKE l_name escape escape_char) ) AND cm.config_ivid=config_ivid AND cm.object_ivid=ov.ivid AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; CURSOR members_no_case IS SELECT ov.irid ov_irid,ov.ivid ov_ivid FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm ,I$SDD_CONFIGURATION_MEMBERS cm WHERE ( (fm.name_in_context IS NOT NULL AND NLS_UPPER(fm.name_in_context) LIKE NLS_UPPER(l_name) escape escape_char) OR (NLS_UPPER(ov.name) LIKE NLS_UPPER(l_name) escape escape_char) ) AND cm.config_ivid=config_ivid AND cm.object_ivid=ov.ivid AND ( (type_id IS NULL) OR (type_id = ov.logical_type_id) ) AND ov.irid=fm.member_object AND fm.parent_ivid=prev_ivid; BEGIN IF (prev_ivid IS NULL) THEN --Find root object in configuration IF case_sensitive THEN FOR mem IN root LOOP object_set.extend(); object_set(object_set.last).irid:=mem.ov_irid; object_set(object_set.last).ivid:=mem.ov_ivid; END LOOP; ELSE FOR mem IN root_no_case LOOP object_set.extend(); object_set(object_set.last).irid:=mem.ov_irid; object_set(object_set.last).ivid:=mem.ov_ivid; END LOOP; END IF; ELSE --Not root object IF case_sensitive THEN FOR mem IN members LOOP object_set.extend(); object_set(object_set.last).irid:=mem.ov_irid; object_set(object_set.last).ivid:=mem.ov_ivid; END LOOP; ELSE FOR mem IN members_no_case LOOP object_set.extend(); object_set(object_set.last).irid:=mem.ov_irid; object_set(object_set.last).ivid:=mem.ov_ivid; END LOOP; END IF; END IF; RETURN object_set; END; -------------------------------------------------------------- -- REMOVE_NAME_ESCAPES() -- Internal function to remove escape characters from the -- supplied name part of a CRN. -- Do not remove escapes in front of wildcard characters, -- or escape characters, as the Oracle SQL will handle this... -------------------------------------------------------------- FUNCTION remove_name_escapes(string IN varchar2) RETURN varchar2 IS left_str varchar2(500); right_str varchar2(500); next_char varchar2(4);--Allocate four bytes so we cope with multibyte --character sets. escape_pos number; BEGIN right_str:=string; --get the first occurance of an escape character escape_pos:=INSTR(right_str,escape_char); --Loop through each occurance of an escape character,and remove it. WHILE escape_pos > 0 LOOP --Get character after the escape next_char:=SUBSTR(right_str,escape_pos+1,1); --If character is not the wildcard or an escape, --or escape was the last char, remove the escape IF (next_char IS NULL) OR ((next_char != wildcard_char) AND (next_char != single_wildcard_char) AND (next_char != escape_char)) THEN --Everything to left of escape char... left_str:=left_str||SUBSTR(right_str,1,escape_pos-1); --Otherwise leave the escape intact ELSE --Everything on left, including escape char left_str:=left_str||SUBSTR(right_str,1,escape_pos); END IF; --Everything to right of escape char... right_str:=SUBSTR(right_str,escape_pos+1); --Find next escape character, but ignore leading --character... escape_pos:=INSTR(right_str,escape_char,2); END LOOP; left_str:=left_str||right_str; RETURN left_str; END; -------------------------------------------------------------- -- REMOVE_ESCAPES() -- Internal function to remove escape characters from the -- supplied string. -------------------------------------------------------------- FUNCTION remove_escapes(string IN varchar2) RETURN varchar2 IS left_str varchar2(500); right_str varchar2(500); escape_pos number; BEGIN right_str:=string; --get the first occurance of an escape character escape_pos:=INSTR(right_str,escape_char); --Loop through each occurance of an escape character,and remove it. WHILE escape_pos > 0 LOOP --Everything to left of escape char... left_str:=left_str||SUBSTR(right_str,1,escape_pos-1); --Everything to right of escape char... right_str:=SUBSTR(right_str,escape_pos+1); --Find next escape character, but ignore leading --character... escape_pos:=INSTR(right_str,escape_char,2); END LOOP; left_str:=left_str||right_str; RETURN left_str; END; -------------------------------------------------------------- -- CONVERT_STRING() -- Function converts all non-escaped occurence of old_char into -- new_char -------------------------------------------------------------- FUNCTION convert_string(string IN varchar2 ,old_char IN varchar2 ,new_char IN varchar2) RETURN varchar2 IS left_str varchar2(500); right_str varchar2(500); char_pos number; BEGIN right_str:=string; char_pos := INSTR(right_str,old_char); WHILE char_pos > 0 LOOP --Non-escaped old_char IF (SUBSTR(right_str,char_pos-1,1) != escape_char) --(make sure escape before char is not escaped!) OR ((SUBSTR(right_str,char_pos-1,1) = escape_char) AND (SUBSTR(right_str,char_pos-2,1) = escape_char)) THEN --Convert to new_char left_str:=left_str||SUBSTR(right_str,1,char_pos-1)||new_char; ELSE --Leaved escaped old_char as it was... left_str:=left_str||SUBSTR(right_str,1,char_pos); END IF; --Everything after the old_char right_str:=SUBSTR(right_str,char_pos+1); char_pos:=INSTR(right_str,old_char); END LOOP; --Put the string back together. left_str:=left_str||right_str; RETURN left_str; END; -------------------------------------------------------------- -- CONVERT_WILDCARDS() -- Function converts all non-escaped wildcard characters into -- the Oracle wildcards '%' and '_' -------------------------------------------------------------- FUNCTION convert_wildcards(string IN varchar2) RETURN varchar2 IS convert_str varchar2(500); BEGIN --Convert non-escaped wildcards to '%' convert_str:=convert_string(string,wildcard_char,'%'); --Convert non-excaped single wildcards to '_' convert_str:=convert_string(convert_str,single_wildcard_char,'_'); RETURN convert_str; END; -------------------------------------------------------------- -- FIND_WILDCARDS() -- Internal function to find any non-escaped wildcard characters -- in the supplied string. -------------------------------------------------------------- FUNCTION find_wildcards(string IN varchar2) RETURN boolean IS l_string varchar2(500); wildcard_pos number; found_wildcard boolean := FALSE; BEGIN --Now look for non-escaped wildcards wildcard_pos := INSTR(l_string,wildcard_char); WHILE (wildcard_pos > 0 AND NOT found_wildcard)LOOP --Wildcard not preceded by escape char IF SUBSTR(l_string,wildcard_pos-1,1) != escape_char THEN found_wildcard := TRUE; END IF; wildcard_pos := INSTR(l_string,wildcard_char,wildcard_pos+1); END LOOP; --Now look for non-escaped single wildcards wildcard_pos := INSTR(l_string,single_wildcard_char); WHILE (wildcard_pos > 0 AND NOT found_wildcard)LOOP --Wildcard not preceded by escape char IF SUBSTR(l_string,wildcard_pos-1,1) != escape_char THEN found_wildcard := TRUE; END IF; wildcard_pos := INSTR(l_string,single_wildcard_char,wildcard_pos+1); END LOOP; RETURN found_wildcard; END; -------------------------------------------------------------- -- ESCAPE_CHARACTERS() -- Adds an escape charater in front of any occurences of the -- specified characters in a string - used to escape SQL -- wildcard characters, and to recover paths that are suitable -- for use by the naming service. -------------------------------------------------------------- FUNCTION escape_characters(string IN varchar2 ,character IN varchar2) RETURN varchar2 IS convert_string varchar2(500); left_string varchar2(500); right_string varchar2(500); character_pos pls_integer; BEGIN convert_string:=string; left_string:=''; right_string := convert_string; character_pos:= INSTR(right_string,character); WHILE character_pos > 0 LOOP --Get everything before the character, and append an escape left_string:=left_string||SUBSTR(right_string,1,character_pos-1)||escape_char; --Get the remainder right_string:=SUBSTR(right_string,character_pos); --Get NEXT character to be escaped character_pos:=INSTR(right_string,character,2); END LOOP; --Append the remaing part of the string convert_string:=left_string||right_string; RETURN convert_string; END; -------------------------------------------------------------- -- ESCAPE_SQLwildcards() -- Internal function add escape character in front of any -- underscores or percents in the supplied string. -- Necessary, as Oracle treats the characters as wildcards in -- pattern matching. -------------------------------------------------------------- FUNCTION escape_SQLwildcards(string IN varchar2) RETURN varchar2 IS convert_string varchar2(500); left_string varchar2(500); right_string varchar2(500); underscore_pos number; percent_pos number; BEGIN convert_string:=string; --If the naming service is using an underscore as the single --wildcard character, then we don't need to do this... IF (single_wildcard_char != '_') THEN --Escape underscores convert_string:=escape_characters(convert_string,'_'); END IF; --If the naming service is using a percent as the --wildcard character, then we don't need to do this... IF (wildcard_char != '%') THEN --Escape percents convert_string:=escape_characters(convert_string,'%'); END IF; RETURN convert_string; END; -------------------------------------------------------------- -- parse_path() -- strip an object name from the left hand end of the path. -- Pass back the name and the remainder of the path. -- A path is a number of common repository names delimited by -- one of two standard seperators (the defaults are foward slashses (/), -- back slashes (\)) -------------------------------------------------------------- PROCEDURE parse_path(CRPath IN OUT varchar2 ,CRName IN OUT varchar2 ,seperator IN char) IS after_escape boolean; in_version_info boolean; first_seperator number; last_dot number; curr_char varchar2(4);--Allocate four bytes so we cope with multibyte --character sets. BEGIN --Find the first seperator in the path, --ignoring escaped characters, and anything --between version info seperators ('{' and '}') first_seperator:=0; in_version_info:=FALSE; after_escape:=FALSE; FOR i IN 1..LENGTH(CRPath) LOOP curr_char:=SUBSTR(CRPath,i,1); IF ((NOT in_version_info) AND (NOT after_escape) AND ((seperator IS NOT NULL AND curr_char = seperator) OR (curr_char = file_seperator1 OR curr_char = file_seperator2)) )THEN --Found the first seperator - stop looking! first_seperator:=i; EXIT; END IF; IF (NOT after_escape) AND (curr_char = version_start) THEN in_version_info:=TRUE; ELSIF (NOT after_escape) AND (curr_char = version_end) THEN in_version_info:=FALSE; ELSIF (NOT after_escape) AND (curr_char = escape_char) THEN after_escape:=TRUE; ELSE after_escape:=FALSE; END IF; END LOOP; IF (first_seperator > 0) THEN --Get the part of the path before the first seperator - this is the name CRName := SUBSTR(CRPath,1,first_seperator-1); --Get the remainder of the path (minus the seperator) --Note that we pass back the untranslated path... CRPath := SUBSTR(CRPath,first_seperator+1); ELSE --Last part of path. CRName := CRPath; CRPath := NULL; END IF; END; ----------------------------------------------------------------------------- -- get_version_info() -- extract the version information from a CRN - version info is either -- VLABEL or BRANCH;VERSION_SEQ, and is contained between { + } ----------------------------------------------------------------------------- PROCEDURE get_version_info(CRName IN OUT varchar2 ,o_branch OUT number ,o_version OUT number ,o_vlabel OUT varchar2 ,o_find_by_label OUT boolean) IS open_bracket number; close_bracket number; semicolon_pos number; branch_name varchar2(128); version_seq varchar2(256); version_info varchar2(400); BEGIN --Find the first, non-escaped '{' open_bracket := INSTR(CRName,version_start); WHILE (open_bracket > 0) AND (SUBSTR(CRName,open_bracket-1,1)=escape_char) LOOP open_bracket := INSTR(CRName,version_start,open_bracket+1); END LOOP; --Find the first, non-escaped '}' close_bracket := INSTR(CRName,version_end); WHILE (close_bracket > 0) AND (SUBSTR(CRName,close_bracket-1,1)=escape_char) LOOP close_bracket := INSTR(CRName,version_end,close_bracket+1); END LOOP; IF (open_bracket > close_bracket) THEN --Missing close bracket, or close bracket before open... RAISE INVALID_CRN; END IF; IF open_bracket = 0 THEN --No version info supplied, pass back the CRName untouched... o_branch:=NULL; o_vlabel:=NULL; o_find_by_label:=FALSE; RETURN; END IF; --Extract the version info from between the brackets in the CRName version_info:=SUBSTR(CRName ,open_bracket+1 ,(close_bracket-open_bracket)-1); --Reconstruct CRName with version info removed CRName:=SUBSTR(CRName ,1 ,open_bracket-1) ||SUBSTR(CRName ,close_bracket+1 ,LENGTH(CRName)-close_bracket); --Look for a branch seperator ';' in the version info semicolon_pos := INSTR(version_info,branch_seperator); --Ignore seperators preceded by an escape character... WHILE (semicolon_pos > 0) AND (SUBSTR(version_info,semicolon_pos-1,1)=escape_char) LOOP semicolon_pos := INSTR(version_info,branch_seperator,semicolon_pos+1); END LOOP; IF semicolon_pos > 0 THEN --Get hold of branch and version seq from version info o_find_by_label:=FALSE; --Check valid format IF semicolon_pos=1 THEN -- No branch_name RAISE INVALID_CRN; END IF; IF semicolon_pos=LENGTH(version_info) THEN -- No version seq RAISE INVALID_CRN; END IF; branch_name:=SUBSTR(version_info,1,semicolon_pos-1); --Check for non-escaped wild cards in BRANCH IF find_wildcards(branch_name) THEN --Wildcards not allowed in BRANCHes RAISE INVALID_WILDCARD; END IF; --Remove any escape chars from branch name branch_name:=remove_escapes(branch_name); --Get hold of the branch id IF case_sensitive THEN SELECT branch_id INTO o_branch FROM I$SDD_BRANCHES WHERE name=branch_name; ELSE SELECT branch_id INTO o_branch FROM I$SDD_BRANCHES WHERE NLS_UPPER(name)=NLS_UPPER(branch_name); END IF; version_seq := UPPER(SUBSTR(version_info ,semicolon_pos+1)); IF version_seq='LATEST' THEN o_version:=0; ELSE o_version:=TO_NUMBER(version_seq); END IF; o_vlabel := NULL; ELSE --Get hold of version label from version info o_find_by_label:=TRUE; o_branch:=0; o_version:=0; o_vlabel := version_info; --Check for non-escaped wild cards in VLABEL IF find_wildcards(o_vlabel) THEN --Wildcards not allowed in VLABELs RAISE INVALID_WILDCARD; END IF; --Remove any escape chars from the vlabel o_vlabel:=remove_escapes(o_vlabel); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN -- INVALID_BRANCH_NAME; RAISE INVALID_BRANCH_NAME; END; ----------------------------------------------------------------------------- -- parse_name() -- split a CRN name up. Descide if they want a version or a label identity. -- If no version or label provided, then raise error if we don't have a -- workarea context. -- Get hold of the type id if an element type is supplied -- Returns: -- TRUE if we are locating by name only in the current workarea context -- FALSE locating specific version of object in the repository ----------------------------------------------------------------------------- FUNCTION parse_name(CRName IN varchar2 ,o_obj_name OUT varchar2 ,o_branch OUT number ,o_version OUT number ,o_vlabel OUT varchar2 ,o_type_id OUT number ,o_find_by_label OUT boolean ,o_is_primary OUT varchar2 ,allow_null_context IN boolean DEFAULT FALSE) RETURN boolean IS no_version_info boolean; type_seperator_pos number; l_CRName varchar2(400); l_type_name varchar(256); BEGIN l_CRName := CRName; --Strip the version info (if any) from the CRName... get_version_info(l_CRName,o_branch,o_version,o_vlabel,o_find_by_label); IF ((o_branch IS NULL) AND (o_vlabel IS NULL)) THEN no_version_info := TRUE; END IF; --Get hold of the type specifier (if any) type_seperator_pos := INSTR(l_CRName,type_seperator); --Ignore type seperators preceded by an escape character... WHILE (type_seperator_pos > 0) AND (SUBSTR(l_CRName,type_seperator_pos-1,1)=escape_char) LOOP type_seperator_pos := INSTR(l_CRName,branch_seperator,type_seperator_pos+1); END LOOP; IF (type_seperator_pos > 0) THEN BEGIN --Strip the '=TYPE' from the end of the CRN... l_type_name:=SUBSTR(l_CRName,type_seperator_pos+1); l_CRName:=SUBSTR(l_CRName,1,type_seperator_pos-1); --Remove any escape characters from the type name l_type_name:=remove_escapes(l_type_name); BEGIN --Look up type id using short name IF case_sensitive THEN SELECT et.id , et.is_primary INTO o_type_id , o_is_primary FROM rm_element_types et WHERE et.short_name=l_type_name; ELSE SELECT et.id , et.is_primary INTO o_type_id , o_is_primary FROM rm_element_types et WHERE NLS_UPPER(et.short_name)=NLS_UPPER(l_type_name); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN --User might have used NLS name to specifiy type instead ... IF case_sensitive THEN SELECT nls.for_type , et.is_primary INTO o_type_id , o_is_primary FROM rm_element_type_extensions nls , rm_element_types et WHERE nls.nls_name = l_type_name AND nls.for_type = et.id; ELSE SELECT nls.for_type , et.is_primary INTO o_type_id , o_is_primary FROM rm_element_type_extensions nls , rm_element_types et WHERE NLS_UPPER(nls.nls_name) = NLS_UPPER(l_type_name) AND nls.for_type = et.id; END IF; END; --Look up type id EXCEPTION WHEN NO_DATA_FOUND THEN RAISE INVALID_TYPE; END; END IF; --We've now stripped everything apart from the object name from the CRName o_obj_name:=l_CRName; --Remove escapes apart from those in front of wildcards... o_obj_name:=remove_name_escapes(o_obj_name); --Use escape character to prevent Oracle treating '_' and '%' as wildcards. o_obj_name:=escape_SQLwildcards(o_obj_name); --Convert any non-escaped wildcards to Oracle wildcards ('%','_') o_obj_name:=convert_wildcards(o_obj_name); --No version info - just name of object supplied IF no_version_info THEN --Check that we can use just the object name IF ((Jr_Context.workarea IS NULL) AND(NOT allow_null_context)) AND(l_type_name!='CFG') --Can look for configs outside of workarea context... AND(l_type_name!='Configuration') THEN -- Error: no workarea context set, can't find object with just its name RAISE NULL_CONTEXT; ELSE -- No more parsing required. Return TRUE to indicate we are in workarea context. RETURN TRUE; END IF; END IF; --Return FALSE - we have version info, and can look outside workarea context. RETURN FALSE; END; ------------------------------------------------------------------ -- Objects_from_CRName() -- Get a set of objects IVID from an objects CRN, and the IVID of -- its owning folder. (Wildcards in name may result in more than -- one object matching...). -- Accepts both version number format and version label format. -- If a workarea context is set can just specify the name. ----------------------------------------------------------------- FUNCTION Objects_From_CRName(CRName IN varchar2 ,prev_ivids IN objver_list) RETURN objver_list IS l_name varchar2(400); l_branch_id number; l_version number; i number; j number; prev_ivid number; l_vlabel varchar2(255); l_type_id number; l_find_by_label boolean; l_is_primary rm_element_types.is_primary%TYPE; in_wka_context boolean; object_set objver_list; ret_obj_set objver_list:=objver_list(); BEGIN in_wka_context:=parse_name(CRName ,l_name ,l_branch_id ,l_version ,l_vlabel ,l_type_id ,l_find_by_label ,l_is_primary); j := prev_ivids.first; --If we have no prev ivids, then find the root object IF j IS NULL THEN IF (in_wka_context) THEN object_set:=find_root_by_name(l_name,l_type_id); ELSIF (l_find_by_label) THEN object_set:=find_root_by_vlabel(l_name,l_vlabel,l_type_id); ELSE object_set:=find_root_by_vernum(l_name,l_branch_id,l_version,l_type_id); END IF; i:=object_set.first; -- Add the objects we found to the set we will return... WHILE i IS NOT NULL LOOP ret_obj_set.extend(); ret_obj_set(ret_obj_set.last).irid:=object_set(i).irid; ret_obj_set(ret_obj_set.last).ivid:=object_set(i).ivid; i:=object_set.next(i); END LOOP; END IF; --Otherwise, loop over each of the previous objects, and add any objects that belong --to them that match the current CRName to the return object set. WHILE j IS NOT NULL LOOP prev_ivid := prev_ivids(j).ivid; j := prev_ivids.next(j); IF (in_wka_context) THEN object_set:=find_by_name(prev_ivid,l_name,l_type_id); ELSIF (l_find_by_label) THEN object_set:=find_by_vlabel(prev_ivid,l_name,l_vlabel,l_type_id); ELSE object_set:=find_by_vernum(prev_ivid,l_name,l_branch_id,l_version,l_type_id); END IF; i:=object_set.first; -- Add the objects we found to the set we will return... WHILE i IS NOT NULL LOOP ret_obj_set.extend(); ret_obj_set(ret_obj_set.last).irid:=object_set(i).irid; ret_obj_set(ret_obj_set.last).ivid:=object_set(i).ivid; i:=object_set.next(i); END LOOP; END LOOP; RETURN ret_obj_set; END; ------------------------------------------------------------------ -- Objects_from_SACName() -- Get a set of secondary objects IVIDs from its name, and the IVID -- and type of its parent. (Wildcards in name may result in more than -- one object matching...). ----------------------------------------------------------------- FUNCTION Objects_From_SACName(CRName IN varchar2 ,prev_irids IN objver_list ,prev_types IN OUT jr_num_list) RETURN objver_list IS l_name varchar2(255); l_branch_id number; l_version number; i number; j number; k number; l number; prev_irid number; prev_type_id number; l_vlabel varchar2(255); l_type_id number; l_find_by_label boolean; l_is_primary rm_element_types.is_primary%TYPE; in_wka_context boolean; object_set objver_list:=objver_list(); types_found jr_num_list:=jr_num_list(); ret_types jr_num_list:=jr_num_list(); ret_obj_set objver_list:=objver_list(); BEGIN in_wka_context:=parse_name(CRName ,l_name ,l_branch_id ,l_version ,l_vlabel ,l_type_id ,l_find_by_label ,l_is_primary); if (l_is_primary = 'Y') then -- we have entered this procedure unnecessarily so just return return ret_obj_set; end if; j := prev_irids.first; k := prev_types.first; --Loop over each of the previous objects, and add any objects that belong --to them that match the current SACName to the return object set. WHILE j IS NOT NULL LOOP --Get hold of the type and ivid for the current predecessor prev_irid := prev_irids(j).irid; j := prev_irids.next(j); --If predecessor was a PAC, then we wont have any prev_types... IF k IS NOT NULL THEN prev_type_id:=prev_types(k); k:=prev_types.next(k); ELSE prev_type_id:=NULL; END IF; object_set:=find_SAC(prev_irid,l_name,prev_type_id,types_found,l_type_id); i:=object_set.first; l:=types_found.first; -- Add the objects we found to the set we will return... WHILE i IS NOT NULL LOOP ret_obj_set.extend(); ret_obj_set(ret_obj_set.last).irid:=object_set(i).irid; ret_obj_set(ret_obj_set.last).ivid:=object_set(i).ivid; i:=object_set.next(i); ret_types.extend(); ret_types(ret_types.last):=types_found(l); l:=types_found.next(l); END LOOP; END LOOP; --Only update list of prev_types if we found something IF object_set.first IS NOT NULL THEN prev_types:=ret_types; END IF; RETURN ret_obj_set; END; ------------------------------------------------------------------ -- IVID_from_CRName() -- Get an IVID from an objects CRN, and the IVID of its owning folder -- Accepts both version number format and version label format. -- If a workarea context is set can just specify the name. ----------------------------------------------------------------- FUNCTION IVID_From_CRName(CRName IN varchar2 ,prev_irid IN OUT number ,prev_ivid IN number) RETURN number IS l_ivid number; i number; object_set objver_list; prev_ivids objver_list:=objver_list(); BEGIN --Set up the prev_ivids list to contain the previous ivid IF prev_ivid IS NOT NULL THEN prev_ivids.extend(); prev_ivids(prev_ivids.last).irid:=prev_irid; prev_ivids(prev_ivids.last).ivid:=prev_ivid; END IF; --Get the object object_set:=Objects_from_CRName(CRName,prev_ivids); i:=object_set.COUNT; IF (i > 1) THEN RAISE TOO_MANY_ELEMENTS; ELSIF (i = 0) THEN --Object set is empty l_ivid:=NULL; --Pass back prev irid as the one that was passed in ELSE prev_irid:=object_set(1).irid; l_ivid:=object_set(1).ivid; END IF; RETURN l_ivid; END; ------------------------------------------------------------------ -- IVID_from_SACName() -- Get an IVID from an secondary objects name, and the IVID and -- type of its owner. Also pass back the irid and type ----------------------------------------------------------------- FUNCTION IVID_From_SACName(SACName IN varchar2 ,prev_irid IN OUT number ,prev_type IN OUT number) RETURN number IS l_ivid number; i number; object_set objver_list; prev_irids objver_list:=objver_list(); prev_types jr_num_list:=jr_num_list(); BEGIN --Set up the prev_ivids list to contain the previous ivid prev_irids.extend(); prev_irids(prev_irids.last).irid:=prev_irid; --Set up the prev_types list to containt the previous type (if any) IF prev_type IS NOT NULL THEN prev_types.extend(); prev_types(prev_types.last):=prev_type; END IF; --Get the object object_set:=Objects_from_SACName(SACName,prev_irids,prev_types); i:=object_set.COUNT; IF (i > 1) THEN RAISE TOO_MANY_ELEMENTS; ELSIF (i = 0) THEN --Object set is empty l_ivid:=NULL; --Pass back prev_irid and prev_ivid with the same values that were passed in ELSE l_ivid:=object_set(1).ivid; prev_irid:=object_set(1).irid; prev_type:=prev_types(1); END IF; RETURN l_ivid; END; ----------------------------------------------------------------------------- -- get_RID() -- Transition function. Take a ivid and return an irid. -- This is to support the old ID system of rid and vid before vid was unique. ----------------------------------------------------------------------------- FUNCTION get_RID(i_ivid IN number) RETURN number IS o_irid number; BEGIN SELECT irid INTO o_irid FROM I$SDD_OBJECT_VERSIONS WHERE ivid=i_ivid; RETURN o_irid; END; ----------------------------------------------------------------------------- -- get_IVID() -- Convert CRN Path into an IVID -- Path is delimited by either '/' or '\', or by user specified seperator. -- Accepts both version nmumber format and version label format. -- If a workarea context is set can just specify the name of each path member. -- No errors raised, and exceptions not handled - allows function to be called -- directly from SQL. ----------------------------------------------------------------------------- FUNCTION get_IVID(CRPath IN varchar2, seperator IN char:=NULL) RETURN number IS CRName varchar2(400); isSAC boolean :=FALSE; path varchar2(4000); l_ivid number; prev_irid number :=NULL; prev_ivid number :=NULL; l_seperator char; BEGIN path := CRPath; l_seperator:=seperator; WHILE (path IS NOT NULL) LOOP parse_path(path,CRName,l_seperator); IF NOT isSAC THEN l_ivid:=IVID_from_CRName(CRName,prev_irid,prev_ivid); IF path IS NULL AND l_ivid IS NULL THEN --Couldn't locate final part of path as PAC - it might be --PAC and SAC names seperated by SAC_seperator... path:=CRName; parse_path(path,CRName,SAC_seperator); IF path IS NOT NULL THEN --remainder of path was split by SAC_seperator l_ivid:=IVID_from_CRName(CRName,prev_irid,prev_ivid); END IF; IF l_ivid IS NOT NULL THEN --We successfully located the PAC part, remainder of path --is made up of SACs isSAC:=TRUE; l_seperator:=SAC_seperator; --We need to parse the path again to get the first SAC Part parse_path(path,CRName,l_seperator); END IF; END IF; --If we can't find the element as a PAC, maybe it's a SAC... IF l_ivid IS NULL THEN --We can't look for SACs because of WNDS pragma blocking --use of dynaminc SQL, so do nothing till 8i NULL; END IF; ELSE --Currently, use of dynamic SQL to find SAC breaks WNDS pragma, so --can't get SACs with this function (should be fixed with 8i) l_ivid:=NULL; END IF; prev_ivid:=l_ivid; -- Couldn't locate path member... IF (l_ivid IS NULL) THEN EXIT; END IF; END LOOP; RETURN l_ivid; END; ----------------------------------------------------------------------------- -- get_VID() -- Convert CRN Path into an IVID -- Path is delimited by either '/' or '\' -- Accepts both version nmumber format and version label format. -- If a workarea context is set can just specify the name of each path member. -- Handles exceptions and raises errors, can be used for SACs ----------------------------------------------------------------------------- PROCEDURE get_RID_VID(CRPath IN varchar2 ,o_irid OUT number ,o_ivid OUT number ,seperator IN char:=NULL) IS l_ivid number; path varchar2(4000); CRName varchar2(400); old_CRName varchar2(400); isSAC boolean:=FALSE; prev_ivid number := NULL; prev_irid number := NULL; prev_type number := NULL; l_seperator char; BEGIN path:=CRPath; l_seperator:=seperator; --Get the IVID of the object WHILE (path IS NOT NULL) LOOP parse_path(path,CRName,l_seperator); IF NOT isSAC THEN l_ivid:=IVID_from_CRName(CRName,prev_irid,prev_ivid); IF path IS NULL AND l_ivid IS NULL THEN --Couldn't locate final part of path as PAC - it might be --PAC and SAC names seperated by SAC_seperator... path:=CRName; old_CRName:=CRName; parse_path(path,CRName,SAC_seperator); IF path IS NOT NULL THEN --remainder of path was split by SAC_seperator l_ivid:=IVID_from_CRName(CRName,prev_irid,prev_ivid); END IF; IF l_ivid IS NOT NULL THEN --We successfully located the PAC part, remainder of path --is made up of SACs isSAC:=TRUE; l_seperator:=SAC_seperator; --We need to parse the path again to get the first SAC Part parse_path(path,CRName,l_seperator); ELSE --Couldn't locate PAC part - put things back as they were CRName:=old_CRName; path :=NULL; END IF; END IF; --If we still can't find the element as a PAC, and it's not the --first in the path (prev_ivid not null) maybe it's a SAC... IF (l_ivid IS NULL) AND (prev_ivid IS NOT NULL) THEN isSAC := TRUE; END IF; END IF; IF isSAC THEN IF prev_irid IS NULL THEN prev_irid:=get_rid(prev_ivid); END IF; l_ivid:=IVID_from_SACName(CRName,prev_irid,prev_type); IF l_ivid IS NULL AND path IS NULL AND l_seperator!=SAC_seperator THEN --Maybe remainder of SAC path is seperated by SAC seperators path:=CRName; parse_path(path,CRName,SAC_seperator); IF path IS NOT NULL THEN --remainder of path was split by SAC_seperator l_ivid:=IVID_from_SACName(CRName,prev_irid,prev_type); END IF; IF l_ivid IS NOT NULL THEN --We successfully located the SAC part, remainder of path --is assumed to be seperated with SAC seperators l_seperator:=SAC_seperator; END IF; END IF; END IF; prev_ivid:=l_ivid; -- Couldn't locate path member... IF (l_ivid IS NULL) THEN EXIT; END IF; END LOOP; IF l_ivid IS NULL THEN --ERROR: Object not found Rmmes.post('CDR',1000,CRPath); o_irid:=NULL; o_ivid:=NULL; RETURN; END IF; o_irid:= prev_irid; o_ivid:= l_ivid; EXCEPTION --Handle exceptions raised by parsing of path WHEN INVALID_CRN THEN Rmmes.post('CDR',1001,CRPath); o_irid:=NULL; o_ivid:=NULL; WHEN INVALID_WILDCARD THEN Rmmes.post('CDR',1031,CRPath); o_irid:=NULL; o_ivid:=NULL; WHEN INCORRECTLY_PARSED_PATH THEN Rmmes.post('CDR',1002,CRPath); o_irid:=NULL; o_ivid:=NULL; WHEN NULL_CONTEXT THEN Rmmes.post('CDR',1003,CRPath); o_irid:=NULL; o_ivid:=NULL; WHEN INVALID_BRANCH_NAME THEN Rmmes.post('CDR',1004,CRPath); o_irid:=NULL; o_ivid:=NULL; WHEN INVALID_TYPE THEN Rmmes.post('CDR',1034,CRPath); o_irid:=NULL; o_ivid:=NULL; WHEN TOO_MANY_ELEMENTS THEN Rmmes.post('CDR',1035,CRPath); o_irid:=NULL; o_ivid:=NULL; END; ----------------------------------------------------------------------------- -- get_objects() -- Convert CRN Path into a list of objects (may be more than one, as wildcards -- may be used for final path member) -- Path is delimited by either '/' or '\' -- Accepts both version nmumber format and version label format. -- If a workarea context is set can just specify the name of each path member ----------------------------------------------------------------------------- FUNCTION get_objects(CRPath IN varchar2,seperator IN char := NULL) RETURN objver_list IS CRName varchar2(400); old_CRName varchar2(400); path varchar2(4000); object_set objver_list:=objver_list(); prev_objects objver_list:=objver_list(); prev_types jr_num_list:=jr_num_list(); isSAC boolean:=FALSE; l_seperator char; BEGIN path := CRPath; l_seperator := seperator; WHILE (path IS NOT NULL) LOOP parse_path(path,CRName,l_seperator); IF NOT isSac THEN object_set:=Objects_from_CRName(CRName,prev_objects); IF path IS NULL AND object_set.last IS NULL THEN --Couldn't locate final part of path as PAC - it might be --PAC and SAC names seperated by SAC_seperator... path:=CRName; -- store CRName as this may get reset later old_CRName:=CRName; parse_path(path,CRName,SAC_seperator); IF path IS NOT NULL THEN --remainder of path was split by SAC_seperator object_set:=Objects_from_CRName(CRName,prev_objects); END IF; IF object_set.last IS NOT NULL THEN --We successfully located the PAC part, remainder of path --is made up of SACs isSAC:=TRUE; l_seperator:=SAC_seperator; --We need to parse the path again to get the first SAC Part parse_path(path,CRName,l_seperator); ELSE --Couldn't locate PAC part - put things back as they were CRName:=old_CRName; path :=NULL; END IF; END IF; --If we still can't find the element as a PAC, maybe it's a SAC... IF object_set.last IS NULL THEN isSAC := TRUE; END IF; END IF; IF isSAC THEN object_set:=Objects_from_SACName(CRName,prev_objects,prev_types); IF object_set.last IS NULL AND path IS NULL AND l_seperator!=SAC_seperator THEN --Maybe remainder of SAC path is seperated by SAC seperators path:=CRName; parse_path(path,CRName,SAC_seperator); IF path IS NOT NULL THEN --remainder of path was split by SAC_seperator object_set:=Objects_from_SACName(CRName,prev_objects,prev_types); END IF; IF object_set.last IS NOT NULL THEN --We successfully located the SAC part, remainder of path --is assumed to be seperated with SAC seperators l_seperator:=SAC_seperator; END IF; END IF; END IF; IF object_set.last IS NULL THEN --ERROR:Couldn't find path member Rmmes.post('CDR',1000,CRPath); EXIT; END IF; prev_objects:=object_set; END LOOP; --Return list of objects we recovered for the last path member. RETURN object_set; EXCEPTION --Handle exceptions raised by parsing of path WHEN INVALID_CRN THEN Rmmes.post('CDR',1001,CRPath); RETURN objver_list(); WHEN INVALID_WILDCARD THEN Rmmes.post('CDR',1031,CRPath); RETURN objver_list(); WHEN INCORRECTLY_PARSED_PATH THEN Rmmes.post('CDR',1002,CRPath); RETURN objver_list(); WHEN NULL_CONTEXT THEN Rmmes.post('CDR',1003,CRPath); RETURN objver_list(); WHEN INVALID_BRANCH_NAME THEN Rmmes.post('CDR',1004,CRPath); RETURN objver_list(); WHEN INVALID_TYPE THEN Rmmes.post('CDR',1034,CRPath); RETURN objver_list(); END; ----------------------------------------------------------------------------- -- get_VID_in_config() -- Convert Path into an IVID in the context of a configuration. -- Use just the object names to specify path members. ----------------------------------------------------------------------------- FUNCTION get_VID_in_config(CRPath IN varchar2, config_ivid IN number, seperator IN char := NULL) RETURN number IS CRName varchar2(400); path varchar2(4000); isFileName boolean; findbyVLABEL boolean; dummy boolean; l_vlabel varchar2(255); l_branch number; l_version number; l_ivid number; prev_ivid number; type_id number; l_is_primary rm_element_types.is_primary%TYPE; object_set objver_list; BEGIN path := CRPath; prev_ivid:=NULL; WHILE (path IS NOT NULL) LOOP parse_path(path,CRName,seperator); dummy:=parse_name(CRName ,CRName ,l_branch ,l_version ,l_vlabel ,type_id ,findbyVLABEL ,l_is_primary ,TRUE); --Get objects matching name (user may have specified wildcards) object_set:=find_in_config(CRName,config_ivid,prev_ivid,type_id); IF object_set.last IS NULL THEN --ERROR: Couldn't locate path member... Rmmes.post('CDR',1000,CRPath); EXIT; ELSIF (object_set.COUNT > 1) THEN --ERROR: too many objects found RAISE TOO_MANY_ELEMENTS; ELSE --Only want one object, so get the last in the set l_ivid:=object_set(object_set.last).ivid; END IF; prev_ivid:=l_ivid; END LOOP; RETURN l_ivid; EXCEPTION --Handle exceptions raised by parsing of path or name... WHEN INVALID_CRN THEN Rmmes.post('CDR',1001,CRPath); RETURN NULL; WHEN INVALID_WILDCARD THEN Rmmes.post('CDR',1031,CRPath); RETURN NULL; WHEN INCORRECTLY_PARSED_PATH THEN Rmmes.post('CDR',1002,CRPath); RETURN NULL; WHEN NULL_CONTEXT THEN Rmmes.post('CDR',1003,CRPath); RETURN NULL; WHEN INVALID_BRANCH_NAME THEN Rmmes.post('CDR',1004,CRPath); RETURN NULL; WHEN INVALID_TYPE THEN Rmmes.post('CDR',1034,CRPath); RETURN NULL; WHEN TOO_MANY_ELEMENTS THEN Rmmes.post('CDR',1035,CRPath); RETURN NULL; END; ---------------------------------------------------------------- -- path_members() -- Convert CRN Path into a list of IRIDs + IVIDs -- corresponding to the path members. -- Accepts wildcards, so each path member may return multiple -- objects - but wildcards only valid for the last path member -- so get the last object in the set for other path members. -- Accepts both version number format and version label format. ---------------------------------------------------------------- FUNCTION path_members(CRPath IN varchar2,seperator IN char := NULL) RETURN objver_list IS CRName varchar2(400); old_CRName varchar2(400); path varchar2(4000); i number; isSAC boolean:=FALSE; path_mem objver_list:=objver_list(); object_set objver_list:=objver_list(); prev_objects objver_list:=objver_list(); prev_types jr_num_list:=jr_num_list(); l_seperator char; BEGIN path := CRPath; l_seperator:=seperator; WHILE (path IS NOT NULL) LOOP parse_path(path,CRName,l_seperator); IF NOT isSAC THEN object_set:=Objects_from_CRName(CRName,prev_objects); IF path IS NULL AND object_set.last IS NULL THEN --Couldn't locate final part of path as PAC - it might be --PAC and SAC names seperated by SAC_seperator... path:=CRName; -- store CRName as this may get reset later old_CRName:=CRName; parse_path(path,CRName,SAC_seperator); IF path IS NOT NULL THEN --remainder of path was split by SAC_seperator object_set:=Objects_from_CRName(CRName,prev_objects); END IF; IF object_set.last IS NOT NULL THEN --We successfully located the PAC part, remainder of path --is made up of SACs isSAC:=TRUE; l_seperator:=SAC_seperator; --We need to parse the path again to get the first SAC Part parse_path(path,CRName,l_seperator); ELSE --Couldn't locate PAC part - put things back as they were CRName:=old_CRName; path :=NULL; END IF; END IF; --If we still can't find the element as a PAC, maybe it's a SAC... IF object_set.last IS NULL THEN isSAC := TRUE; END IF; END IF; IF isSAC THEN object_set:=Objects_from_SACName(CRName,prev_objects,prev_types); IF object_set.last IS NULL AND path IS NULL AND l_seperator!=SAC_seperator THEN --Maybe remainder of SAC path is seperated by SAC seperators path:=CRName; parse_path(path,CRName,SAC_seperator); IF path IS NOT NULL THEN --remainder of path was split by SAC_seperator object_set:=Objects_from_SACName(CRName,prev_objects,prev_types); END IF; IF object_set.last IS NOT NULL THEN --We successfully located the SAC part, remainder of path --is assumed to be seperated with SAC seperators l_seperator:=SAC_seperator; END IF; END IF; END IF; --If we still can't find anything, then post an error and stop looking. IF (object_set.first IS NULL) THEN --ERROR:No path members found. Rmmes.post('CDR',1000,CRPath); path_mem:=objver_list(); EXIT; END IF; --Add the objects we just found to the list of path members i:=object_set.first; WHILE (i IS NOT NULL) LOOP path_mem.extend(); path_mem(path_mem.last).irid:=object_set(i).irid; path_mem(path_mem.last).ivid:=object_set(i).ivid; i:=object_set.next(i); END LOOP; prev_objects:=object_set; END LOOP; RETURN path_mem; EXCEPTION --Handle exceptions raised by parsing of path WHEN INVALID_CRN THEN Rmmes.post('CDR',1001,CRPath); RETURN objver_list(); WHEN INVALID_WILDCARD THEN Rmmes.post('CDR',1031,CRPath); RETURN objver_list(); WHEN INCORRECTLY_PARSED_PATH THEN Rmmes.post('CDR',1002,CRPath); RETURN objver_list(); WHEN NULL_CONTEXT THEN Rmmes.post('CDR',1003,CRPath); RETURN objver_list(); WHEN INVALID_BRANCH_NAME THEN Rmmes.post('CDR',1004,CRPath); RETURN objver_list(); WHEN INVALID_TYPE THEN Rmmes.post('CDR',1034,CRPath); RETURN objver_list(); END; ----------------------------------------------------------------------------- -- Convert Path into an IVID and IRID in the context of a configuration. -- Use just the object names to specify path members. ----------------------------------------------------------------------------- PROCEDURE get_RID_VID_in_config(CRPath IN varchar2 ,config_ivid IN number ,irid OUT number ,ivid OUT number ,seperator IN char := NULL) IS BEGIN ivid := get_VID_in_config(CRPath,config_ivid,seperator); IF ivid IS NOT NULL THEN irid := get_RID(ivid); ELSE irid := NULL; END IF; END; ----------------------------------------------------------------------------- -- Get IVID for a configuration from its name. -- Neccessary, as get_VID will fail for checked out or new configurations. -- (These are not visible through version resolved views!) ----------------------------------------------------------------------------- FUNCTION get_config_IVID(config_name IN varchar2) RETURN number IS config_ivid number; BEGIN --Function has been deprecated RAISE_APPLICATION_ERROR(-20000,'Deprecated Function'); END; ----------------------------------------------------------------------------- -- Get IRID and IVID for a configuration from its name. -- Neccessary, as get_VID will fail for checked out or new configurations. -- (These are not visible through version resolved views!) ----------------------------------------------------------------------------- PROCEDURE get_config_IRID_IVID(config_name IN varchar2 ,config_irid OUT number ,config_ivid OUT number) IS BEGIN --Function has been deprecated RAISE_APPLICATION_ERROR(-20000,'Deprecated Function'); END; ---------------------------------------------------------------- -- Convert CRN Path into IVID -- Accepts both version nmumber format and version label format. ---------------------------------------------------------------- FUNCTION get_VID(CRPath IN varchar2,seperator IN char := NULL) RETURN number IS l_irid number; l_ivid number; BEGIN get_RID_VID(CRPath ,l_irid ,l_ivid ,seperator); RETURN l_ivid; END; ---------------------------------------------------------------- -- add_escapes() -- Adds escape characters in front of any 'special' characters -- being used in the string - ensures that the string can be -- passed back into the naming service without a problem -- FUNCTION add_escape_chars(string IN varchar2) RETURN varchar2 IS convert_string varchar2(500); BEGIN convert_string:=string; convert_string:=escape_characters(convert_string,escape_char); convert_string:=escape_characters(convert_string,file_seperator1); convert_string:=escape_characters(convert_string,file_seperator2); convert_string:=escape_characters(convert_string,branch_seperator); convert_string:=escape_characters(convert_string,version_start); convert_string:=escape_characters(convert_string,version_end); convert_string:=escape_characters(convert_string,type_seperator); convert_string:=escape_characters(convert_string,wildcard_char); convert_string:=escape_characters(convert_string,single_wildcard_char); --Also convert brackets and commas - not needed for naming service, --but non-escaped brackets will cause problems for parsing of workarea specs... convert_string:=escape_characters(convert_string,Jr_Rule.params_start); convert_string:=escape_characters(convert_string,Jr_Rule.params_end); convert_string:=escape_characters(convert_string,Jr_Rule.params_sep); RETURN convert_string; END; ---------------------------------------------------------------- -- get_CRN_from_IVID() -- Convert IVID into CRN. -- Uses the specified format: -- NAME - just the name of object/folder -- VLABEL - name;vlabel -- BRANCH - name;branch;version_seq -- No errors put onto stack, so can call directly from SQL. ---------------------------------------------------------------- FUNCTION get_CRN_from_IVID(i_ivid IN number ,format IN varchar2 ,add_escapes IN number := 0) RETURN varchar2 IS l_name varchar2(400); l_branch_id number; l_branch_name varchar2(128); l_version number; l_state varchar2(1); l_vlabel varchar2(255); l_type varchar2(240); o_CRN varchar(400); l_format varchar2(10); BEGIN l_format:=UPPER(format); SELECT ov.name,ov.vlabel,ov.state,ov.branch_id,ov.sequence_in_branch INTO l_name,l_vlabel,l_state,l_branch_id,l_version FROM I$SDD_OBJECT_VERSIONS ov WHERE ivid=i_ivid; IF add_escapes=1 THEN l_name:=add_escape_chars(l_name); END IF; IF (l_format='NAME' OR l_format='NAMETYPE')THEN o_CRN := l_name; END IF; IF (l_format='VLABEL' OR l_format='VLABELTYPE') THEN o_CRN := l_name; --Only add version label if we found one (new objects have no version label) IF l_vlabel IS NOT NULL THEN IF add_escapes=1 THEN l_vlabel:=add_escape_chars(l_vlabel); END IF; o_CRN := o_CRN||version_start||l_vlabel||version_end; ELSIF l_vlabel IS NULL AND l_state!='N' THEN --If no vlabel, get branch info instead IF l_format='VLABEL' THEN l_format:='BRANCH'; ELSE l_format:='BRANCHTYPE'; END IF; END IF; END IF; IF (l_format='BRANCH' OR l_format='BRANCHTYPE') THEN BEGIN SELECT name INTO l_branch_name FROM I$SDD_BRANCHES WHERE branch_id=l_branch_id; IF add_escapes=1 THEN l_branch_name:=add_escape_chars(l_branch_name); END IF; IF l_state='O' THEN --For checked out objects, get sequence number --from corresponding checked in version SELECT ov.sequence_in_branch INTO l_version FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va WHERE ov.ivid=va.from_ivid AND va.to_ivid=i_ivid AND va.edge_kind!='M'; END IF; o_CRN := l_name ||version_start||l_branch_name ||branch_seperator||l_version||version_end; EXCEPTION WHEN NO_DATA_FOUND THEN --If could not find branch, then just return name --(new objects are not on any branch) o_CRN := l_name; END; END IF; --Add the element type if required IF ( UPPER(format)='NAMETYPE' OR UPPER(format)='VLABELTYPE' OR UPPER(format)='BRANCHTYPE') THEN SELECT nls.nls_name INTO l_type FROM I$SDD_OBJECT_VERSIONS ov ,rm_element_type_extensions nls WHERE ov.ivid=i_ivid AND nls.for_type = ov.logical_type_id; --Add escape characters if required if add_escapes=1 then l_type:=add_escape_chars(l_type); end if; o_CRN := o_CRN||type_seperator||l_type; END IF; RETURN o_CRN; END; ---------------------------------------------------------------- -- get_crn_from_irid() -- Wrapper for get_crn_from_ivid(). -- Uses version selected by current workarea context -- If no workarea set, or object not in current wa, uses latest -- version on main. ---------------------------------------------------------------- FUNCTION get_CRN_from_IRID(i_irid IN number ,format IN varchar2 ,add_escapes IN number := 0) RETURN varchar2 IS l_ivid number; check_in_ctxt boolean:=TRUE; BEGIN IF Jr_Context.workarea IS NULL THEN check_in_ctxt:=FALSE; ELSE --Get ivid from current wa context BEGIN SELECT ov.ivid INTO l_ivid FROM SDD_OBJECT_VERSIONS ov WHERE ov.irid=i_irid; EXCEPTION WHEN NO_DATA_FOUND THEN --Not is current workarea check_in_ctxt:=FALSE; END; END IF; IF NOT check_in_ctxt THEN BEGIN --Get ivid from latest on MAIN branch SELECT ov.ivid INTO l_ivid FROM I$SDD_OBJECT_VERSIONS ov ,SDD_VERSION_ASSOCIATIONS va ,I$SDD_BRANCHES br WHERE va.irid=i_irid AND va.edge_kind='T' AND va.branch_id=br.branch_id AND br.name='MAIN' AND ov.ivid=va.to_ivid; EXCEPTION WHEN NO_DATA_FOUND THEN --Not checked in - must be non-versioned --(only one entry in I$SDD_OBJECT_VERSIONS for this irid). SELECT ov.ivid INTO l_ivid FROM I$SDD_OBJECT_VERSIONS ov WHERE ov.irid=i_irid; END; END IF; --Now get the CRN RETURN get_CRN_from_IVID(l_ivid,format,add_escapes); END; ---------------------------------------------------------------- -- get_version_info() -- Gets version info (either the VLABEL or BRANCH;VERSION_NUM) -- for an object, from its ivid. -- May be called directly from SQL statements ---------------------------------------------------------------- FUNCTION get_version_info(i_ivid IN number ,format varchar2 ,add_escapes IN number := 0) RETURN varchar2 IS version_info varchar2(140); l_vlabel varchar2(32); l_branch varchar2(128); l_format varchar2(6); ov_state varchar2(1); l_vernum number; dummy number; BEGIN l_format:=UPPER(format); IF l_format='VLABEL' THEN SELECT vlabel INTO l_vlabel FROM I$SDD_OBJECT_VERSIONS WHERE ivid=i_ivid; IF l_vlabel IS NOT NULL THEN IF add_escapes=1 THEN l_vlabel:=add_escape_chars(l_vlabel); END IF; RETURN l_vlabel; ELSE --Null vlabel, so return BRANCH info instead l_format:='BRANCH'; END IF; END IF; IF l_format='BRANCH' THEN BEGIN SELECT br.name,ov.sequence_in_branch,ov.state INTO l_branch,l_vernum,ov_state FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_BRANCHES br WHERE ov.ivid=i_ivid AND br.branch_id=ov.branch_id; IF ov_state='O' THEN --For checked out elements, get checked-in version's seq SELECT ov.sequence_in_branch INTO l_vernum FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_VERSION_ASSOCIATIONS va WHERE ov.ivid=va.from_ivid AND va.to_ivid=i_ivid AND va.edge_kind!='M'; END IF; IF add_escapes=1 THEN l_branch:=add_escape_chars(l_branch); END IF; --Test if this version is the latest on the branch. SELECT COUNT(1) INTO dummy FROM sdd_version_associations va WHERE va.to_ivid = i_ivid AND va.edge_kind = 'T'; IF (dummy > 0) THEN --Latest on branch version_info:=l_branch||branch_seperator||'LATEST'; ELSE --Not latest, so use version sequence version_info:=l_branch||branch_seperator||TO_CHAR(l_vernum); END IF; RETURN version_info; EXCEPTION WHEN NO_DATA_FOUND THEN --Return NULL if we can't locate object RETURN NULL; END; END IF; END; ---------------------------------------------------------------- -- get_CRN() -- Convert IVID into CRN. -- Wrapper that handles NO_DATA_FOUND exception and posts error -- onto stack CANNOT be called from SQL statement. ---------------------------------------------------------------- FUNCTION get_CRN(i_ivid IN number ,format varchar2 ,add_escapes IN number := 0) RETURN varchar2 IS l_CRN varchar2(400); BEGIN l_CRN:=get_CRN_from_IVID(i_ivid,format,add_escapes); RETURN l_CRN; EXCEPTION WHEN NO_DATA_FOUND THEN --ERROR: Couldn't locate object with given IVID Rmmes.post('CDR',101,TO_CHAR(i_ivid)); RETURN NULL; END; ---------------------------------------------------------------- -- get_CRN() -- Convert IRID,IVID into CRN - IVID may be null ---------------------------------------------------------------- FUNCTION get_CRN(i_irid IN number ,i_ivid IN number ,format varchar2 ,add_escapes IN number := 0) RETURN varchar2 IS BEGIN IF i_ivid IS NULL THEN RETURN get_CRN_from_IRID(i_irid,format,add_escapes); ELSE RETURN get_CRN_from_IVID(i_ivid,format,add_escapes); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN --ERROR: Couldn't locate object with given IVID Rmmes.post('CDR',101,TO_CHAR(i_ivid)); RETURN NULL; END; ---------------------------------------------------------------- -- get_Path -- Convert IRID or IVID into path of CRNs. -- Posts no errors to stack, so can be called from SQL statement -- Valid format is 'NAME','VLABEL' or 'BRANCH'. -- CAN ONLY BE USED IN CONTEXT OF WORKAREA WITH AN IRID. ---------------------------------------------------------------- FUNCTION get_Path(id IN number ,format IN varchar2 ,seperator IN varchar2 := NULL ,add_escapes IN number := 0) return varchar2 is root_irid number; root_ivid number; begin return get_path(id,root_irid,root_ivid,format,seperator,add_escapes); end; ---------------------------------------------------------------- -- get_Path -- Convert IRID or IVID into path of CRNs. -- Posts no errors to stack, so can be called from SQL statement -- Valid format is 'NAME','VLABEL' or 'BRANCH'. -- CAN ONLY BE USED IN CONTEXT OF WORKAREA WITH AN IRID. ---------------------------------------------------------------- FUNCTION get_Path(id IN number ,root_irid OUT number ,root_ivid OUT number ,format IN varchar2 ,seperator IN varchar2 := NULL ,add_escapes IN number := 0) RETURN varchar2 IS current_ivid number; current_irid number; finished boolean; l_format varchar2(40); l_seperator varchar2(10); path varchar2(4000); CRName varchar2(400); root_fol varchar2(4); BEGIN l_format:=format; --Will only work in the context of a workarea IF Jr_Context.workarea IS NULL THEN RETURN get_path_no_context(id,'MAIN',format,seperator,add_escapes); END IF; BEGIN SELECT ov.irid,ov.ivid INTO current_irid,current_ivid FROM sdd_object_versions ov WHERE ov.irid=id OR ov.ivid=id; EXCEPTION WHEN NO_DATA_FOUND THEN --If we can't find the object, give up --gracefully! RETURN NULL; END; path := get_CRN_from_IVID(current_ivid,format,add_escapes); --Only display the element type for the last member of the path.... IF (UPPER(format)='NAMETYPE') THEN l_format:='NAME'; ELSIF (UPPER(format)='VLABELTYPE') THEN l_format:='VLABEL'; ELSIF (UPPER(format)='BRANCHTYPE') THEN l_format:='BRANCH'; END IF; --If we're already at the root, we've finished already! IF is_root_fol(current_ivid) THEN finished := TRUE; ELSE finished := FALSE; END IF; WHILE NOT finished LOOP get_folder(current_irid,current_irid,current_ivid); IF current_ivid IS NULL THEN finished:=TRUE; EXIT; END IF; CRName:=get_CRN_from_IVID(current_ivid,l_format,add_escapes); IF (CRName IS NOT NULL) THEN --Work out which seperator to use IF (seperator IS NULL) THEN l_seperator:=file_seperator2; ELSE l_seperator:=seperator; END IF; --Add Name and seperator to path path := CRName||l_seperator||path; ELSE --Couldn't find object with current_ivid path:=NULL; finished:=TRUE; END IF; --Have we reached the root folder? --If we have, then we can finish finished:=is_root_fol(current_ivid); END LOOP; --Set the root_ivid, and return the path root_irid:=current_irid; root_ivid:=current_ivid; RETURN path; END; ---------------------------------------------- -- Returns TRUE if specified object is a -- root folder ---------------------------------------------- FUNCTION is_root_fol(i_ivid IN number) RETURN boolean IS root_fol varchar2(4); BEGIN SELECT root_flag INTO root_fol FROM I$SDD_FOLDERS WHERE ivid=i_ivid; IF root_fol='Y' THEN RETURN TRUE; ELSE RETURN FALSE; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN --Object may not be folder RETURN FALSE; END; ---------------------------------------------- -- Get folder for element in current workarea -- context. ---------------------------------------------- PROCEDURE get_folder(el_irid IN number ,fol_irid OUT number ,fol_ivid OUT number) IS BEGIN --Look for the owning folder in this workarea... SELECT fol.ivid, fol.irid INTO fol_ivid, fol_irid FROM I$SDD_FOLDER_MEMBERS fm ,SDD_FOLDERS fol WHERE fm.member_object = el_irid AND fm.ownership_flag = 'Y' AND fol.ivid=fm.parent_ivid; EXCEPTION WHEN NO_DATA_FOUND THEN --Couldn't find owning folder, so pick a referencing folder... --(may be more than one, so arbitrarily pick one the most recent). SELECT MAX(fol.ivid) INTO fol_ivid FROM I$SDD_FOLDER_MEMBERS fm ,SDD_FOLDERS fol WHERE fm.member_object = el_irid AND fol.ivid=fm.parent_ivid AND NVL(fm.date_changed,fm.date_created)=(SELECT MAX(NVL(fm2.date_changed ,fm2.date_created)) FROM I$SDD_FOLDER_MEMBERS fm2 WHERE fm2.member_object=el_irid AND fm2.parent_ivid=fol.ivid); IF fol_ivid IS NULL THEN --Still couldn't find folder... fol_irid:=NULL; fol_ivid:=NULL; END IF; END; ---------------------------------------------------------------- -- get_Path_in_Config -- Convert IVID into path of CRNs in the context of a configuration -- Posts no errors to stack, so can be called from SQL statement -- Valid format is 'NAME','VLABEL' or 'BRANCH'. ---------------------------------------------------------------- FUNCTION get_Path_in_config(ivid IN number ,config_id IN number ,format varchar2 ,seperator IN varchar2 := NULL ,add_escapes IN number := 0) RETURN varchar2 IS current_ivid number; current_irid number; current_type varchar2(3); finished boolean; l_format varchar2(40); l_seperator varchar2(10); path varchar2(4000); CRName varchar2(400); root_fol varchar2(4); BEGIN l_format:=format; --Will only work in the context of a config IF config_id IS NULL THEN RETURN NULL; END IF; current_ivid := ivid; path := get_CRN_from_IVID(current_ivid,format,add_escapes); --Only display the element type for the last member of the path.... IF (UPPER(format)='NAMETYPE') THEN l_format:='NAME'; ELSIF (UPPER(format)='VLABELTYPE') THEN l_format:='VLABEL'; ELSIF (UPPER(format)='BRANCHTYPE') THEN l_format:='BRANCH'; END IF; --If we're already at the root, we've finished already! IF is_root_fol(current_ivid) THEN finished := TRUE; ELSE --We've not finished, we'll need to irid as well as the ivid. current_irid := get_RID(current_ivid); finished := FALSE; END IF; WHILE NOT finished LOOP BEGIN --Look for the owning folder in this config SELECT fm.parent_ivid, fm.folder_reference INTO current_ivid, current_irid FROM I$SDD_FOLDER_MEMBERS fm ,I$SDD_CONFIGURATION_MEMBERS cm WHERE fm.parent_ivid = cm.object_ivid AND fm.member_object = current_irid AND fm.ownership_flag = 'Y' AND cm.config_ivid = config_id; EXCEPTION WHEN NO_DATA_FOUND THEN --Couldn't find owning folder, so pick a referencing folder... --(may be more than one, so pick the most recent). SELECT MAX(fm.parent_ivid) INTO current_ivid FROM I$SDD_FOLDER_MEMBERS fm ,I$SDD_CONFIGURATION_MEMBERS cm WHERE fm.parent_ivid = cm.object_ivid AND fm.member_object = current_irid AND cm.config_ivid = config_id AND NVL(fm.date_changed ,fm.date_created)=(SELECT MAX(NVL(fm2.date_changed ,fm2.date_created)) FROM I$SDD_FOLDER_MEMBERS fm2 WHERE fm.parent_ivid = cm.object_ivid AND fm.member_object = current_irid); IF current_ivid IS NOT NULL THEN current_irid:=get_RID(current_ivid); ELSE --Still couldn't find folder... finished:=TRUE; EXIT; END IF; END; CRName:=get_CRN_from_IVID(current_ivid,l_format,add_escapes); IF (CRName IS NOT NULL) THEN --Work out which seperator to use IF (seperator IS NULL) THEN l_seperator:=file_seperator2; ELSE l_seperator:=seperator; END IF; --Add Name and seperator to path path := CRName||l_seperator||path; ELSE --Couldn't find object with current_ivid path:=NULL; finished:=TRUE; END IF; --Have we reached the root folder? --If we have, then we can finish finished:=is_root_fol(current_ivid); END LOOP; RETURN path; END; ---------------------------------------------------------------- -- get_Path_no_context() -- Convert IVID into path of CRNs outside of a context. -- latest versions from the specified branch are used. -- If an owning folder cannot be found on the specified branch, -- look for latest version on main branch, and failing that -- look for the version of the owning folder with the greatest -- IVID on any branch. -- Posts no errors to stack, so can be called from SQL statement -- Valid format is 'NAME','VLABEL' or 'BRANCH'. ---------------------------------------------------------------- FUNCTION get_Path_no_context(el_id IN number ,branch IN varchar2 ,format IN varchar2 ,seperator IN varchar2 := NULL ,add_escapes IN number := 0) RETURN varchar2 IS current_ivid number; current_irid number; finished boolean; l_format varchar2(40); l_seperator varchar2(10); path varchar2(4000); CRName varchar2(400); root_fol varchar2(4); brnch_id number; BEGIN l_format:=format; SELECT br.branch_id INTO brnch_id FROM I$SDD_BRANCHES br WHERE br.name=branch; BEGIN SELECT ov.irid INTO current_irid FROM I$SDD_OBJECT_VERSIONS ov WHERE ov.ivid=el_id; current_ivid:=el_id; EXCEPTION WHEN NO_DATA_FOUND THEN --User has supplied irid, not ivid, get --ivid for tip version on specified branch SELECT MIN(va.to_ivid) INTO current_ivid FROM sdd_version_associations va WHERE va.irid=el_id AND va.edge_kind='T' AND va.branch_id=brnch_id; IF current_ivid IS NULL AND branch != 'MAIN' THEN --Object not on specified branch, try on MAIN SELECT MIN(va.to_ivid) INTO current_ivid FROM sdd_version_associations va ,I$SDD_BRANCHES br WHERE va.irid=el_id AND va.edge_kind='T' AND va.branch_id=br.branch_id AND br.name='MAIN'; END IF; IF current_ivid IS NULL THEN --Object not on any branch, it must be non-versioned SELECT MIN(ov.ivid) INTO current_ivid FROM I$SDD_OBJECT_VERSIONS ov WHERE ov.irid=el_id AND ov.state='N' AND ov.wastebasket='N'; END IF; IF current_ivid IS NULL THEN --Object STILL not found - must be invalid ID, so return NULL RETURN NULL; END IF; current_irid:=el_id; END; path := get_CRN_from_IVID(current_ivid,format,add_escapes); --Only display the element type for the last member of the path.... IF (UPPER(format)='NAMETYPE') THEN l_format:='NAME'; ELSIF (UPPER(format)='VLABELTYPE') THEN l_format:='VLABEL'; ELSIF (UPPER(format)='BRANCHTYPE') THEN l_format:='BRANCH'; END IF; --If we're already at the root, we've finished already! IF is_root_fol(current_ivid) THEN finished := TRUE; ELSE finished := FALSE; END IF; WHILE NOT finished LOOP --Get folder irid and ivid get_folder_no_context(current_irid,branch,brnch_id,current_irid,current_ivid); IF current_ivid IS NULL THEN --Couldn't find folder so exit the loop. finished:=TRUE; EXIT; END IF; CRName:=get_CRN_from_IVID(current_ivid,l_format,add_escapes); IF (CRName IS NOT NULL) THEN --Work out which seperator to use IF (seperator IS NULL) THEN l_seperator:=file_seperator2; ELSE l_seperator:=seperator; END IF; --Add Name and seperator to path path := CRName||l_seperator||path; ELSE --Couldn't find object with current_ivid path:=NULL; finished:=TRUE; END IF; --Have we reached the root folder? --If we have, then we can finish finished:=is_root_fol(current_ivid); END LOOP; RETURN path; END; ------------------------------------------------ -- PRIVATE HELPER METHOD -- Gets the folder for the specified PAC element -- (from elements irid), when no WA context is -- set. ------------------------------------------------ PROCEDURE get_folder_no_context(el_irid IN number ,branch IN varchar2 ,brnch_id IN number ,fol_irid OUT number ,fol_ivid OUT number) IS CURSOR find_owning_fol(br_id IN number) IS SELECT ov.ivid,ov.irid FROM I$SDD_FOLDER_MEMBERS fm ,I$SDD_OBJECT_VERSIONS ov WHERE fm.member_object=el_irid AND fm.ownership_flag='Y' AND ov.ivid=fm.parent_ivid AND ov.branch_id=br_id AND ov.wastebasket='N' ORDER BY ov.sequence_in_branch DESC; main_id number; BEGIN BEGIN --Look for owning folder at tip of this branch.... SELECT fm.parent_ivid, fm.folder_reference INTO fol_ivid, fol_irid FROM I$SDD_FOLDER_MEMBERS fm ,SDD_VERSION_ASSOCIATIONS va WHERE fm.member_object = el_irid AND fm.parent_ivid = va.to_ivid AND fm.ownership_flag = 'Y' AND va.branch_id = brnch_id AND va.edge_kind = 'T'; EXCEPTION WHEN NO_DATA_FOUND THEN --Couldn't find owning folder as latest version, look for most recent --version on branch... FOR fol IN find_owning_fol(brnch_id) LOOP --First row back from cursor is most recent fol_irid:=fol.irid; fol_ivid:=fol.ivid; EXIT; END LOOP; IF fol_irid IS NULL AND branch != 'MAIN' THEN --Couldn't find on specified branch, so look on MAIN instead SELECT br.branch_id INTO main_id FROM I$SDD_BRANCHES br WHERE br.name='MAIN'; FOR fol IN find_owning_fol(main_id) LOOP --First row back from cursor is most recent fol_irid:=fol.irid; fol_ivid:=fol.ivid; EXIT; END LOOP; END IF; END; IF fol_irid IS NULL THEN --Can't find owning folder on specified branch or MAIN --Folder may be non-versioned, or not on specified branch --so arbitarily pick most recent version of owning folder (by date) select MAX(fm.parent_ivid) into fol_ivid from I$SDD_FOLDER_MEMBERS fm where fm.member_object = el_irid and fm.ownership_flag= 'Y' and NVL(fm.DATE_CHANGED,fm.DATE_CREATED) in (select MAX(NVL(fm2.date_changed,fm2.date_created)) from I$SDD_FOLDER_MEMBERS fm2 ,I$SDD_OBJECT_VERSIONS ov where fm2.member_object=fm.member_object and ov.IVID=fm.parent_ivid and ov.WASTEBASKET='N'); IF fol_ivid IS NOT NULL THEN fol_irid:=get_RID(fol_ivid); ELSE fol_irid:=NULL; END IF; END IF; END; -------------------------------------------------- -- Get descriptor (as defined in logical model) -- for an element. -- Accepts IRID or IVID, and works with or without -- workarea context. ELEM_TYPE is the short name -- for the element type, and PRODUCT is the product -- code for the element type (as defined in logical -- model). ---------------------------------------------------- FUNCTION get_descriptor(el_id IN number ,elem_type IN varchar2 ,product IN varchar2 ,format IN varchar2 ,add_escapes IN number := 0) RETURN varchar2 IS el_type_id number; BEGIN --Get the type id from the supplied type_name and product SELECT et.id INTO el_type_id FROM rm_element_types et WHERE (et.name=get_descriptor.elem_type OR et.short_name=get_descriptor.elem_type) AND et.product=get_descriptor.product; RETURN get_descriptor(el_id ,el_type_id ,format ,add_escapes); END; -------------------------------------------------------- -- Gets the descriptor (as defined in logical model) -- for a PAC or SAC. -- Adds version info and type info if requested. -- Works with IRID or IVID, and can be used with or -- without a workarea context set. -------------------------------------------------------- FUNCTION get_descriptor(el_id IN number ,el_type IN number ,format IN varchar2 ,add_escapes IN number := 0) RETURN varchar2 IS dummy number; BEGIN RETURN get_descr_and_pac(el_id ,el_type ,format ,add_escapes ,dummy); END; ------------------------------------------------ -- Get path for element with specified id (irid -- or ivid) and of specified type short name and -- product. Works for SACs and PACs -- and uses elements descriptor properties for -- the element name. -- Cannot be used in SQL statment, and should -- be used in context of workarea. ------------------------------------------------ FUNCTION get_path(el_id IN number ,elem_type IN varchar2 ,product IN varchar2 ,format IN varchar2 ,seperator IN varchar2 := NULL ,add_escapes IN number := 0) RETURN varchar2 IS type_id number; BEGIN --Get the type id from the supplied type_name and product SELECT et.id INTO type_id FROM rm_element_types et WHERE et.name=elem_type OR et.short_name=elem_type AND et.product=get_path.product; --Get the path RETURN get_path(el_id ,type_id ,format ,seperator ,add_escapes); END; ------------------------------------------------ -- Get path for element with specified id -- and of specified type. Works for SACs and PACs -- and uses elements descriptor properties for -- the element name. -- Cannot be used in SQL statment, and should -- be used in context of workarea. ------------------------------------------------ FUNCTION get_path(el_id IN number ,el_type IN number ,format IN varchar2 ,seperator IN varchar2 := NULL ,add_escapes IN number := 0) RETURN varchar2 IS path varchar2(4000); pac_irid number; br_id number; fol_irid number; fol_ivid number; l_seperator varchar2(10); l_format varchar2(10); BEGIN --Get hold of descriptor, together with any version and type info requested --also get hold of PAC for element. path:=get_descr_and_pac(el_id ,el_type ,format ,add_escapes ,pac_irid); --If we couldn't find the element, give up IF path IS NULL THEN RETURN NULL; END IF; -- Get hold of folder for this element IF Jr_Context.workarea IS NOT NULL THEN get_folder(pac_irid,fol_irid,fol_ivid); ELSE SELECT br.branch_id INTO br_id FROM I$SDD_BRANCHES br WHERE br.name='MAIN'; get_folder_no_context(pac_irid,'MAIN',br_id,fol_irid,fol_ivid); END IF; --Work out which seperator to use IF (seperator IS NULL) THEN l_seperator:=file_seperator2; ELSE l_seperator:=seperator; END IF; --Don't display the element type for the rest of the path.... l_format:=format; IF (UPPER(format)='NAMETYPE') THEN l_format:='NAME'; ELSIF (UPPER(format)='VLABELTYPE') THEN l_format:='VLABEL'; ELSIF (UPPER(format)='BRANCHTYPE') THEN l_format:='BRANCH'; END IF; --Add the rest of the path IF fol_ivid IS NOT NULL THEN path:=get_path(fol_ivid,l_format,seperator)||l_seperator||path; END IF; RETURN path; END; -------------------------------------------------- -- Get hold of descriptor for element (PAC or SAC) -- and return the PAC irid. -- Adds version info for PAC, and type info for SAC -- if required. ---------------------------------------------------- FUNCTION get_descr_and_pac(el_id IN number ,el_type IN number ,format IN varchar2 ,add_escapes IN number ,pac_irid OUT number) RETURN varchar2 IS descr varchar(1000); elem_irid number; elem_ivid number; pac_ivid number; elem_nls_name rm_element_type_extensions.nls_name%TYPE; version_info varchar2(300):=NULL; BEGIN --Get hold of elements irid, ivid, pac_ref and parent_ivid from the --supplied 'id' (which is either irid or ivid) get_id_props(el_id ,el_type ,elem_irid ,elem_ivid ,pac_irid ,pac_ivid); --If we couldn't find the element, give up IF elem_irid IS NULL THEN RETURN NULL; END IF; --Get the simple descriptor for the element descr:=get_descriptor(elem_irid,el_type); IF add_escapes=1 THEN descr:=add_escape_chars(descr); END IF; --Add version info if required IF UPPER(format) IN ('BRANCH','BRANCHTYPE') THEN version_info:=get_version_info(pac_ivid,'BRANCH',add_escapes); ELSIF UPPER(format) IN ('VLABEL','VLABELTYPE') THEN version_info:=get_version_info(pac_ivid,'VLABEL',add_escapes); END IF; IF version_info IS NOT NULL THEN descr:=descr||version_start||version_info||version_end; END IF; --Add type info if required IF UPPER(format) IN ('NAMETYPE','BRANCHTYPE','VLABELTYPE') THEN SELECT nls.nls_name INTO elem_nls_name FROM rm_element_types et ,rm_element_type_extensions nls WHERE et.id=el_type AND nls.for_type=et.id; descr:=descr||type_seperator||elem_nls_name; END IF; RETURN descr; END; ----------------------------------------------------- -- Get hold of the irid and ivid, and PAC irid -- for an element type with specified ID -- ID is either IRID or IVID. -- Workarea context must be set. ----------------------------------------------------- PROCEDURE get_id_props(el_id IN number ,el_type IN number ,elem_irid OUT number ,elem_ivid OUT number ,pac_irid OUT number ,pac_ivid OUT number) IS view_name rm_sql_tables.name%TYPE; elem_primary rm_element_types.is_primary%TYPE; sql_stmt varchar2(1000); csr number; exec number; BEGIN --Get hold of info on element type SELECT et.is_primary, tab.name INTO elem_primary, view_name FROM rm_sql_tables tab ,rm_sql_row_types rt ,rm_element_types et WHERE tab.id=rt.table_mapped AND rt.id=et.primary_row_type AND et.id=el_type; --Build appropriate SQL statement... IF elem_primary='Y' THEN --Primary element sql_stmt:='select el.irid, el.ivid, el.irid, el.ivid'|| ' from '||view_name||' el'|| ' where el.ivid = :EL_ID'; IF Jr_Context.workarea IS NOT NULL THEN sql_stmt:=sql_stmt|| ' or el.irid = :EL_ID'; ELSE --Null workarea context - need to pick a specific version of an object --arbitarily pick latest version on MAIN sql_stmt:=sql_stmt|| ' or (el.ivid = (select va.to_ivid'|| ' from sdd_version_associations va'|| ' ,I$SDD_BRANCHES br'|| ' where va.irid=:EL_ID'|| ' and va.edge_kind=''T'''|| ' and va.branch_id=br.branch_id'|| ' and br.name=''MAIN''))'; END IF; ELSIF elem_primary='OPTIONAL' THEN --Optional primary sql_stmt:='select el.irid, el.ivid'|| ' ,NVL(el.pac_ref,el.irid),NVL(el.parent_ivid,el.ivid)'|| ' from '||view_name||' el'|| ' where el.ivid = :EL_ID'; IF Jr_Context.workarea IS NOT NULL THEN sql_stmt:=sql_stmt|| ' or el.irid = :EL_ID'; ELSE --Null workarea context - need to pick a specific version of an object --arbitarily pick latest version on MAIN sql_stmt:=sql_stmt|| ' or ( el.irid = :EL_ID'|| ' AND NVL(el.parent_ivid,el.ivid) = (select va.to_ivid'|| ' from sdd_version_associations va'|| ' ,I$SDD_BRANCHES br'|| ' where va.irid=NVL(el.pac_ref,el.irid)'|| ' and va.edge_kind=''T'''|| ' and va.branch_id=br.branch_id'|| ' and br.name=''MAIN''))'; END IF; ELSIF elem_primary='N' THEN --Secondary sql_stmt:='select el.irid, el.ivid, el.pac_ref, el.parent_ivid'|| ' from '||view_name||' el'|| ' where el.ivid = :EL_ID'; IF Jr_Context.workarea IS NOT NULL THEN sql_stmt:=sql_stmt|| ' or el.irid = :EL_ID'; ELSE --Null workarea context - need to pick a specific version of an object --arbitarily pick latest version on MAIN sql_stmt:=sql_stmt|| ' or ( el.irid = :EL_ID'|| ' AND el.parent_ivid = (select va.to_ivid'|| ' from sdd_version_associations va'|| ' ,I$SDD_BRANCHES br'|| ' where va.irid=el.pac_ref'|| ' and va.edge_kind=''T'''|| ' and va.branch_id=br.branch_id'|| ' and br.name=''MAIN''))'; END IF; ELSE RETURN; END IF; --Set up cursor and execute SQL statement csr:=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(csr,sql_stmt,DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE(csr,'EL_ID',el_id); DBMS_SQL.DEFINE_COLUMN(csr,1,elem_irid); DBMS_SQL.DEFINE_COLUMN(csr,2,elem_ivid); DBMS_SQL.DEFINE_COLUMN(csr,3,pac_irid); DBMS_SQL.DEFINE_COLUMN(csr,4,pac_ivid); exec:=DBMS_SQL.EXECUTE(csr); --Get the values back from the cursor IF DBMS_SQL.FETCH_ROWS(csr) > 0 THEN DBMS_SQL.COLUMN_VALUE(csr,1,elem_irid); DBMS_SQL.COLUMN_VALUE(csr,2,elem_ivid); DBMS_SQL.COLUMN_VALUE(csr,3,pac_irid); DBMS_SQL.COLUMN_VALUE(csr,4,pac_ivid); ELSIF jr_context.workarea is null then --Failed to get values from cursor. If we have a null workarea --context set, it may be that the object we are looking for --is non-versioned, or exists only as a SAC on a checked out object --Simply look for a single instance of the object, no version resolution if elem_primary='Y' then --Primary element sql_stmt:='select el.irid, el.ivid, el.irid, el.ivid'|| ' from '||view_name||' el'|| ' where el.irid = :EL_ID'; elsif elem_primary='OPTIONAL' then --Optional primary sql_stmt:='select el.irid, el.ivid'|| ' ,NVL(el.pac_ref,el.irid),NVL(el.parent_ivid,el.ivid)'|| ' from '||view_name||' el'|| ' where el.irid = :EL_ID'; elsif elem_primary='N' then --Secondary sql_stmt:='select el.irid, el.ivid, el.pac_ref, el.parent_ivid'|| ' from '||view_name||' el'|| ' where el.irid = :EL_ID'; end if; DBMS_SQL.PARSE(csr,sql_stmt,DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE(csr,'EL_ID',el_id); DBMS_SQL.DEFINE_COLUMN(csr,1,elem_irid); DBMS_SQL.DEFINE_COLUMN(csr,2,elem_ivid); DBMS_SQL.DEFINE_COLUMN(csr,3,pac_irid); DBMS_SQL.DEFINE_COLUMN(csr,4,pac_ivid); exec:=DBMS_SQL.EXECUTE(csr); --Get the values back from the cursor if DBMS_SQL.FETCH_ROWS(csr) > 0 then DBMS_SQL.COLUMN_VALUE(csr,1,elem_irid); DBMS_SQL.COLUMN_VALUE(csr,2,elem_ivid); DBMS_SQL.COLUMN_VALUE(csr,3,pac_irid); DBMS_SQL.COLUMN_VALUE(csr,4,pac_ivid); end if; END IF; --Close the cursor DBMS_SQL.CLOSE_CURSOR(csr); EXCEPTION WHEN OTHERS THEN IF DBMS_SQL.IS_OPEN(csr) THEN DBMS_SQL.CLOSE_CURSOR(csr); END IF; RAISE; END; ------------------------------------------------------ -- Get hold of descriptor for element with specified -- irid and type ------------------------------------------------------ FUNCTION get_descriptor(el_id IN number ,el_type IN number) RETURN varchar2 IS CURSOR get_descr_info(elem_type number) IS SELECT prop.descriptor_sequence seq ,prop.id prop_id ,col.column_name col_name ,dat.name prop_type_name ,dat.data_type data_type FROM rm_properties prop ,rm_property_maps map ,rm_sql_columns col ,rm_data_types dat WHERE dat.id=prop.of_domain AND map.property=prop.id AND col.id=map.in_column AND map.context=elem_type AND prop.descriptor_sequence > 0 ORDER BY seq; view_name rm_sql_tables.name%TYPE; elem_primary rm_element_types.is_primary%TYPE; descr_col varchar2(50); descriptor varchar2(400); descr_prop varchar2(300); BEGIN --Get hold of the SDD_XXX view for the element type SELECT tab.name ,et.is_primary INTO view_name ,elem_primary FROM rm_sql_tables tab ,rm_sql_row_types rt ,rm_element_types et WHERE tab.id=rt.table_mapped AND rt.id=et.primary_row_type AND et.id=el_type; --Get each of the descriptors in turn FOR descr IN get_descr_info(el_type) LOOP IF descr.prop_type_name='REFERENCE' THEN --Get hold of referenced element descriptor descr_prop:=get_ref_descr_prop(el_id ,el_type ,descr.prop_id ,descr.col_name ,view_name ,elem_primary); ELSIF descr.data_type = 'NUMBER' THEN --Get hold of sequence number descr_col:='TO_CHAR('||descr.col_name||')'; descr_prop:=get_descr_prop(el_id ,descr_col ,view_name ,elem_primary); ELSE --Simple descriptor property descr_col:=descr.col_name; descr_prop:=get_descr_prop(el_id ,descr_col ,view_name ,elem_primary); END IF; --Build up the descriptor string IF descr_prop IS NOT NULL THEN IF descriptor IS NOT NULL THEN --Add a seperator (use SAC seperator ('.') descriptor:=descriptor||SAC_seperator; END IF; descriptor:=descriptor||descr_prop; END IF; END LOOP; RETURN descriptor; END; ------------------------------------------ -- Get hold of descriptor property ------------------------------------------ FUNCTION get_descr_prop(el_id IN number ,descr_col IN varchar2 ,view_name IN varchar2 ,elem_primary IN varchar2) RETURN varchar2 IS sql_stmt varchar2(1000); csr number; exec number; descr_prop varchar2(300):=NULL; BEGIN --Build SQL statement to get descriptor property sql_stmt:='select '||descr_col|| ' from '||view_name||' el'|| ' where el.IRID = :EL_ID'; --If we have no workarea context set, then add arbitary version resolving --SQL to the SQL statement (we always pick the latest version on MAIN) IF Jr_Context.workarea IS NULL THEN --Only need to do this if element is versioned... IF is_versioned(el_id,view_name,elem_primary) THEN IF elem_primary = 'Y' THEN sql_stmt:=sql_stmt||ver_res_primary; ELSIF elem_primary = 'N' THEN sql_stmt:=sql_stmt||ver_res_secondary; ELSIF elem_primary = 'OPTIONAL' THEN sql_stmt:=sql_stmt||ver_res_optional; END IF; END IF; END IF; --Execute the SQL statement csr:=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(csr,sql_stmt,DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE(csr,'EL_ID',el_id); DBMS_SQL.DEFINE_COLUMN(csr,1,descr_prop,300); exec:=DBMS_SQL.EXECUTE(csr); --Get the descriptor property (should only be one row returned) if DBMS_SQL.FETCH_ROWS(csr) > 0 then DBMS_SQL.COLUMN_VALUE(csr,1,descr_prop); elsif jr_context.workarea is null then --If we failed to find the descriptor property, and there is no workarea --context, it is possible the object we are looking for is a SAC which --does not exist on MAIN, or exists only in a checked out PAC version. --Look for a single instance. sql_stmt:='select '||descr_col|| ' from '||view_name||' el'|| ' where el.IRID = :EL_ID'; DBMS_SQL.PARSE(csr,sql_stmt,DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE(csr,'EL_ID',el_id); DBMS_SQL.DEFINE_COLUMN(csr,1,descr_prop,300); exec:=DBMS_SQL.EXECUTE(csr); if DBMS_SQL.FETCH_ROWS(csr) > 0 then DBMS_SQL.COLUMN_VALUE(csr,1,descr_prop); end if; end if; --Close the cursor DBMS_SQL.CLOSE_CURSOR(csr); RETURN descr_prop; EXCEPTION WHEN OTHERS THEN --Ensure cursor is closed DBMS_SQL.CLOSE_CURSOR(csr); RAISE; END; ------------------------------------------------- --Get hold of the descriptor for a referenced --element. ------------------------------------------------- FUNCTION get_ref_descr_prop(el_id IN number ,el_type IN number ,prop_id IN number ,col_name IN varchar2 ,view_name IN varchar2 ,elem_primary IN varchar2)RETURN varchar2 IS ref_type number; ref_irid number; ref_type_name rm_element_types.name%TYPE; sql_stmt varchar2(1000); csr number; exec number; BEGIN --Get the element type being referenced SELECT et.id,et.name INTO ref_type,ref_type_name FROM rm_element_types et ,rm_link_properties link1 ,rm_link_properties link2 WHERE et.id=link2.defined_against AND link2.link_type=link1.link_type AND link1.id!=link2.id AND link1.id=prop_id; --Get the irid of the instance being referneced --Build SQL statement to get value of reference prop sql_stmt:='select '||col_name|| ' from '||view_name||' el'|| ' where el.IRID = :EL_ID'; --If we have no workarea context set, then add arbitary version resolving --SQL to the SQL statement (we always pick the latest version on MAIN) IF Jr_Context.workarea IS NULL THEN --Only need to do this if element is versioned... IF is_versioned(el_id,view_name,elem_primary) THEN IF elem_primary = 'Y' THEN sql_stmt:=sql_stmt||ver_res_primary; ELSIF elem_primary = 'N' THEN sql_stmt:=sql_stmt||ver_res_secondary; ELSIF elem_primary = 'OPTIONAL' THEN sql_stmt:=sql_stmt||ver_res_optional; END IF; END IF; END IF; --Execute the SQL statement csr:=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(csr,sql_stmt,DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE(csr,'EL_ID',el_id); DBMS_SQL.DEFINE_COLUMN(csr,1,ref_irid); exec:=DBMS_SQL.EXECUTE(csr); --Get the descriptor property (should only be one row returned) if DBMS_SQL.FETCH_ROWS(csr) > 0 then DBMS_SQL.COLUMN_VALUE(csr,1,ref_irid); elsif jr_context.workarea is null then --If we failed to find the descriptor property, and there is no workarea --context, it is possible the object we are looking for is a SAC which --does not exist on MAIN, or exists only in a checked out PAC version. --Look for a single instance. sql_stmt:='select '||col_name|| ' from '||view_name||' el'|| ' where el.IRID = :EL_ID'; DBMS_SQL.PARSE(csr,sql_stmt,DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE(csr,'EL_ID',el_id); DBMS_SQL.DEFINE_COLUMN(csr,1,ref_irid); exec:=DBMS_SQL.EXECUTE(csr); if DBMS_SQL.FETCH_ROWS(csr) > 0 then DBMS_SQL.COLUMN_VALUE(csr,1,ref_irid); end if; end if; --Close the cursor DBMS_SQL.CLOSE_CURSOR(csr); --If reference is to a 'generic' type (e.g. a 'CIELEMENT') --then we need to find out what type this instance is pointing at IF ref_type_name IN ('CIELEMENT','ACCESS_CONTROLLED_ELEMENT' ,'PRIMARY_ACCESS_ELEMENT') THEN ref_type:=get_generic_ref_type(el_id,el_type,prop_id ,view_name,elem_primary); END IF; IF ref_irid IS NOT NULL THEN --Get descriptor for referenced element RETURN get_descriptor(ref_irid,ref_type); ELSE --Element reference was null, so return null RETURN NULL; END IF; EXCEPTION WHEN OTHERS THEN IF DBMS_SQL.IS_OPEN(csr) THEN DBMS_SQL.CLOSE_CURSOR(csr); END IF; RAISE; END; --------------------------------------------------- -- is_versioned() -- PRIVATE HELPER FUNCTION -- Determines whether a particular PAC or SAC -- has ever been versioned. --------------------------------------------------- FUNCTION is_versioned(el_irid number ,view_name varchar2 ,elem_primary varchar2) RETURN boolean IS sql_stmt varchar2(300); ov_ivid number; csr pls_integer; exec pls_integer; versioned boolean; BEGIN IF elem_primary='Y' THEN sql_stmt:='select ov.ivid'|| ' from I$SDD_OBJECT_VERSIONS ov'|| ' where ov.irid=:EL_IRID'|| ' and ov.state=''N'''; ELSIF elem_primary='N' THEN sql_stmt:='select ov.ivid'|| ' from I$SDD_OBJECT_VERSIONS ov'|| ' ,I$'||view_name||' el'|| ' where ov.ivid=el.parent_ivid'|| ' and ov.state=''N'''|| ' and el.irid=:EL_IRID'; ELSE sql_stmt:='select ov.ivid'|| ' from I$SDD_OBJECT_VERSIONS ov'|| ' ,I$'||view_name||' el'|| ' where ov.ivid=NVL(el.parent_ivid,el.ivid)'|| ' and ov.state=''N'''|| ' and el.irid=:EL_IRID'; END IF; --Execute the SQL statement csr:=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(csr,sql_stmt,DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE(csr,'EL_IRID',el_irid); DBMS_SQL.DEFINE_COLUMN(csr,1,ov_ivid); exec:=DBMS_SQL.EXECUTE(csr); IF DBMS_SQL.FETCH_ROWS(csr) > 0 THEN versioned:=FALSE; ELSE versioned:=TRUE; END IF; DBMS_SQL.CLOSE_CURSOR(csr); RETURN versioned; EXCEPTION WHEN OTHERS THEN --Ensure cursor is closed DBMS_SQL.CLOSE_CURSOR(csr); RAISE; END; --------------------------------------------------- -- get_generic_ref_types() -- PRIVATE HELPER FUNCTION -- For reference properties which can point at a -- number of different element types, determines -- what element type is being referenced for a -- specific element instance --------------------------------------------------- FUNCTION get_generic_ref_type(el_id IN number ,el_type IN number ,prop_id IN number ,view_name IN varchar2 ,elem_primary IN varchar2) RETURN number IS ref_type number; ref_type_name varchar2(30); col_name rm_sql_columns.name%TYPE; sql_stmt varchar2(1000); csr number; exec number; BEGIN --Get the column which acts as a discriminator for --this reference property SELECT col.name INTO col_name FROM rm_sql_columns col ,rm_link_properties ref_prop ,rm_properties disc_prop ,rm_property_maps map WHERE col.id=map.in_column AND map.property=disc_prop.id AND map.context=el_type AND disc_prop.arc_no=ref_prop.arc_no AND ref_prop.id=prop_id AND ref_prop.defined_against=el_type; --Build SQL statement to get value of discrminator sql_stmt:= 'select '||col_name|| ' from '||view_name||' el'|| ' where el.irid = :EL_ID'; --If we have no workarea context set, then add arbitary version resolving --SQL to the SQL statement (we always pick the latest version on MAIN) IF Jr_Context.workarea IS NULL THEN IF elem_primary = 'Y' THEN sql_stmt:=sql_stmt||ver_res_primary; ELSIF elem_primary = 'N' THEN sql_stmt:=sql_stmt||ver_res_secondary; ELSIF elem_primary = 'OPTIONAL' THEN sql_stmt:=sql_stmt||ver_res_optional; END IF; END IF; --Execute the SQL csr:=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(csr,sql_stmt,DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE(csr,'EL_ID',el_id); DBMS_SQL.DEFINE_COLUMN(csr,1,ref_type_name,30); exec:=DBMS_SQL.EXECUTE(csr); --Get the descriptor property (should only be one row returned) IF DBMS_SQL.FETCH_ROWS(csr) > 0 THEN DBMS_SQL.COLUMN_VALUE(csr,1,ref_type_name); END IF; --Close the cursor DBMS_SQL.CLOSE_CURSOR(csr); --Get the type id for the referenced element SELECT et.id INTO ref_type FROM rm_element_types et WHERE et.short_name=ref_type_name AND et.product = 'CI';--We only reference designer type elements. RETURN ref_type; EXCEPTION WHEN OTHERS THEN IF DBMS_SQL.IS_OPEN(csr) THEN DBMS_SQL.CLOSE_CURSOR(csr); END IF; RAISE; END; ---------------------------------------------------------- --- folder_latest_contents() --- Get the latest versions of a folders contents --- from the IVID of the folder. If RECURSE is TRUE, then --- recurse through all subfolders in the hiearchy. ---------------------------------------------------------- FUNCTION folder_latest_contents(fol_ivid IN number ,branch_id number ,recurse IN boolean ,filter IN varchar2 DEFAULT NULL) RETURN objver_list IS contents objver_list:=objver_list(); sub_contents objver_list; prev_ivids objver_list:=objver_list(); prev_types jr_num_list:=jr_num_list(); i integer; wbasket_flag varchar2(1):=NULL; irid number; ivid number; --Should now work as logical_type_id is populated for folders in 4.0.4(a) -- Changed dual to sys.dual to fix bug 1311500 -- -- Bug 2348525 - try to improve performance of this statement -- Remove outer join as not required -- Remove exists and check access rights before executing cursor -- Replace jr_context.wastebasket with literal CURSOR get_contents (fol_ivid number, branch_id number) IS SELECT ov.irid AS ov_irid,ov.ivid AS ov_ivid, ov.logical_type_id AS ov_type FROM I$SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm ,I$SDD_VERSION_ASSOCIATIONS va WHERE va.edge_kind='T' AND va.branch_id=get_contents.branch_id AND va.irid = fm.member_object AND fm.parent_ivid = get_contents.fol_ivid AND ov.ivid=va.to_ivid AND ov.wastebasket=wbasket_flag; BEGIN --If user specified a CRN as a filter, then populate the contents list --using it... IF filter IS NOT NULL THEN --Set up the prev_ivids list to contain the folder ivid prev_ivids.extend(); prev_ivids(prev_ivids.last).ivid:=fol_ivid; contents:=objects_from_CRName(filter,prev_ivids); END IF; IF (wbasket_flag IS NULL) THEN wbasket_flag := jr_context.wastebasket; END IF; -- Ignore folder if user does not have select access rights on it IF (Jr_Acc_Rights.can_sel(fol_ivid)='Y') THEN FOR fold_mem IN get_contents(fol_ivid,branch_id) LOOP IF filter IS NULL THEN --If no filter specified, then add irid and ivid for --each member of the folder to the list contents.extend(); contents(contents.last).irid:=fold_mem.ov_irid; contents(contents.last).ivid:=fold_mem.ov_ivid; END IF; --Recurse through any sub-folders IF (recurse ) AND (fold_mem.ov_type=app_type_id OR fold_mem.ov_type=fol_type_id) THEN sub_contents:=folder_latest_contents(fold_mem.ov_ivid ,branch_id ,recurse ,filter); i:=sub_contents.first; -- Add the sub-folder contents to our list WHILE i IS NOT NULL LOOP contents.extend(); contents(contents.last).irid:=sub_contents(i).irid; contents(contents.last).ivid:=sub_contents(i).ivid; i:=sub_contents.next(i); END LOOP; END IF; END LOOP; END IF; RETURN contents; EXCEPTION --Handle exceptions raised by parsing of filter WHEN INVALID_CRN THEN Rmmes.post('CDR',1001,filter); RETURN objver_list(); WHEN INVALID_WILDCARD THEN Rmmes.post('CDR',1031,filter); RETURN objver_list(); WHEN INCORRECTLY_PARSED_PATH THEN Rmmes.post('CDR',1002,filter); RETURN objver_list(); WHEN NULL_CONTEXT THEN Rmmes.post('CDR',1003,filter); RETURN objver_list(); WHEN INVALID_BRANCH_NAME THEN Rmmes.post('CDR',1004,filter); RETURN objver_list(); WHEN INVALID_TYPE THEN Rmmes.post('CDR',1034,filter); RETURN objver_list(); END; ---------------------------------------------------------- --- folder_contents_before() --- Get the latest versions (before a specified date, and -- on the specified branch) of a folders contents --- from the IVID of the folder. If RECURSE is TRUE, then --- recurse through all subfolders in the hiearchy. ---------------------------------------------------------- FUNCTION folder_contents_before(fol_ivid IN number ,branch_id number ,before_date IN DATE ,recurse IN boolean ,filter IN varchar2 DEFAULT NULL) RETURN objver_list IS contents objver_list:=objver_list(); sub_contents objver_list; prev_ivids objver_list:=objver_list(); prev_types jr_num_list:=jr_num_list(); i integer; wbasket_flag varchar2(1):=NULL; irid number; ivid number; -- Changed dual to sys.dual to fix bug 1311500 -- -- Bug 2348525 - try to improve performance of this statement -- Remove exists and check access rights before executing cursor -- Replace jr_context.wastebasket with literal CURSOR get_contents (fol_ivid number, branch_id number, before_date DATE) IS SELECT ov.irid AS ov_irid,ov.ivid AS ov_ivid, ov.logical_type_id AS ov_type FROM I$SDD_OBJECT_VERSIONS ov ,SDD_VERSION_ASSOCIATIONS va1 ,I$SDD_FOLDER_MEMBERS fm WHERE va1.edge_kind NOT IN ('T','M') AND va1.branch_id=get_contents.branch_id AND va1.irid = fm.member_object AND va1.edge_sequence = (SELECT MAX(va2.edge_sequence) FROM SDD_VERSION_ASSOCIATIONS va2 WHERE va2.irid = va1.irid AND va2.branch_id=va1.branch_id AND NVL(va2.date_changed,va2.date_created) < get_contents.before_date) AND fm.parent_ivid = fol_ivid AND ov.ivid=va1.to_ivid AND ov.wastebasket=wbasket_flag; BEGIN --If user specified a CRN as a filter, then populate the contents list --using it... IF filter IS NOT NULL THEN --Set up the prev_ivids list to contain the folder ivid prev_ivids.extend(); prev_ivids(prev_ivids.last).ivid:=fol_ivid; contents:=objects_from_CRName(filter,prev_ivids); END IF; IF (wbasket_flag IS NULL) THEN wbasket_flag := jr_context.wastebasket; END IF; -- Ignore folder if user does not have select access rights on it IF (Jr_Acc_Rights.can_sel(fol_ivid)='Y') THEN FOR fold_mem IN get_contents(fol_ivid,branch_id,before_date) LOOP IF filter IS NULL THEN --If no filter specified, then add irid and ivid for --each member of the folder to the list contents.extend(); contents(contents.last).irid:=fold_mem.ov_irid; contents(contents.last).ivid:=fold_mem.ov_ivid; END IF; --Recurse through any sub-folders IF (recurse ) AND (fold_mem.ov_type=app_type_id OR fold_mem.ov_type=fol_type_id) THEN sub_contents:=folder_contents_before(fold_mem.ov_ivid ,branch_id ,before_date ,recurse ,filter); i:=sub_contents.first; -- Add the sub-folder contents to our list WHILE i IS NOT NULL LOOP contents.extend(); contents(contents.last).irid:=sub_contents(i).irid; contents(contents.last).ivid:=sub_contents(i).ivid; i:=sub_contents.next(i); END LOOP; END IF; --recurse END LOOP; --get_contents END IF; -- access rights on folder RETURN contents; EXCEPTION --Handle exceptions raised by parsing of filter WHEN INVALID_CRN THEN Rmmes.post('CDR',1001,filter); RETURN objver_list(); WHEN INVALID_WILDCARD THEN Rmmes.post('CDR',1031,filter); RETURN objver_list(); WHEN INCORRECTLY_PARSED_PATH THEN Rmmes.post('CDR',1002,filter); RETURN objver_list(); WHEN NULL_CONTEXT THEN Rmmes.post('CDR',1003,filter); RETURN objver_list(); WHEN INVALID_BRANCH_NAME THEN Rmmes.post('CDR',1004,filter); RETURN objver_list(); WHEN INVALID_TYPE THEN Rmmes.post('CDR',1034,filter); RETURN objver_list(); END; ---------------------------------------------------------- --- folder_contents_between() --- Get the latest versions (between specified dates, and -- on the specified branch) of a folders contents --- from the IVID of the folder. If RECURSE is TRUE, then --- recurse through all subfolders in the hiearchy. ---------------------------------------------------------- FUNCTION folder_contents_between(fol_ivid IN number ,branch_id number ,start_date IN DATE ,end_date IN DATE ,recurse IN boolean ,filter IN varchar2 DEFAULT NULL) RETURN objver_list IS contents objver_list:=objver_list(); sub_contents objver_list; prev_ivids objver_list:=objver_list(); prev_types jr_num_list:=jr_num_list(); i integer; wbasket_flag varchar2(1):=NULL; irid number; ivid number; -- Changed dual to sys.dual to fix bug 1311500 -- -- Bug 2348525 - try to improve performance of this statement -- Remove exists and check access rights before executing cursor -- Replace jr_context.wastebasket with literal CURSOR get_contents (fol_ivid number, branch_id number ,start_date DATE,end_date DATE) IS SELECT ov.irid AS ov_irid,ov.ivid AS ov_ivid, ov.logical_type_id AS ov_type FROM I$SDD_OBJECT_VERSIONS ov ,SDD_VERSION_ASSOCIATIONS va1 ,I$SDD_FOLDER_MEMBERS fm WHERE va1.edge_kind NOT IN ('T','M') AND va1.branch_id=get_contents.branch_id AND va1.irid = fm.member_object AND va1.edge_sequence = (SELECT MAX(va2.edge_sequence) FROM SDD_VERSION_ASSOCIATIONS va2 WHERE va2.irid = va1.irid AND va2.branch_id=va1.branch_id AND NVL(va2.date_changed,va2.date_created) < get_contents.end_date AND NVL(va2.date_changed,va2.date_created) > get_contents.start_date) AND fm.parent_ivid = fol_ivid AND ov.ivid=va1.to_ivid AND ov.wastebasket=wbasket_flag; BEGIN --If user specified a CRN as a filter, then populate the contents list --using it... IF filter IS NOT NULL THEN --Set up the prev_ivids list to contain the folder ivid prev_ivids.extend(); prev_ivids(prev_ivids.last).ivid:=fol_ivid; contents:=objects_from_CRName(filter,prev_ivids); END IF; IF (wbasket_flag IS NULL) THEN wbasket_flag := jr_context.wastebasket; END IF; -- Ignore folder if user does not have select access rights on it IF (Jr_Acc_Rights.can_sel(fol_ivid)='Y') THEN FOR fold_mem IN get_contents(fol_ivid,branch_id,start_date,end_date) LOOP IF filter IS NULL THEN --If no filter specified, then add irid and ivid for --each member of the folder to the list contents.extend(); contents(contents.last).irid:=fold_mem.ov_irid; contents(contents.last).ivid:=fold_mem.ov_ivid; END IF; --Recurse through any sub-folders IF (recurse ) AND (fold_mem.ov_type=app_type_id OR fold_mem.ov_type=fol_type_id) THEN sub_contents:=folder_contents_between(fold_mem.ov_ivid ,branch_id ,start_date ,end_date ,recurse ,filter); i:=sub_contents.first; -- Add the sub-folder contents to our list WHILE i IS NOT NULL LOOP contents.extend(); contents(contents.last).irid:=sub_contents(i).irid; contents(contents.last).ivid:=sub_contents(i).ivid; i:=sub_contents.next(i); END LOOP; END IF; --recurse END LOOP; --get_contents END IF; -- access rights on folder RETURN contents; EXCEPTION --Handle exceptions raised by parsing of filter WHEN INVALID_CRN THEN Rmmes.post('CDR',1001,filter); RETURN objver_list(); WHEN INVALID_WILDCARD THEN Rmmes.post('CDR',1031,filter); RETURN objver_list(); WHEN INCORRECTLY_PARSED_PATH THEN Rmmes.post('CDR',1002,filter); RETURN objver_list(); WHEN NULL_CONTEXT THEN Rmmes.post('CDR',1003,filter); RETURN objver_list(); WHEN INVALID_BRANCH_NAME THEN Rmmes.post('CDR',1004,filter); RETURN objver_list(); WHEN INVALID_TYPE THEN Rmmes.post('CDR',1034,filter); RETURN objver_list(); END; FUNCTION folder_contents_int(fol_ivid IN number ,recurse IN boolean ,filter IN varchar2 ) RETURN objver_list IS contents objver_list:=objver_list(); prev_ivids objver_list:=objver_list(); sub_contents objver_list; -- INEALL checked in a 4.0.18 repos and RM_ELEMENT_TYPES is ALWAYS -- populated -- Bug 2348525 - remove join to rm_element_types CURSOR get_contents (fol_ivid number) IS SELECT ov.irid AS ov_irid,ov.ivid AS ov_ivid, ov.logical_type_id AS ov_type FROM SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE ov.irid = fm.member_object AND fm.parent_ivid = fol_ivid; CURSOR get_folders (fol_ivid number) IS -- Yes this is a biazze query but it performs better than the -- SDD_OBJECT_VERSION view. /* select ov.ivid ov_ivid from i$sdd_object_versions ov where ov.logical_type_id in( 4842, 4844, 5009 ) and ov.irid in ( select fm.member_object from i$sdd_folder_members fm where fm.parent_ivid = fol_ivid ) and exists (select null from sys.dual where jr_vn.context(ov.ivid) > 0); */ -- Staggering, this query is faster than one above! SELECT ov.ivid ov_ivid FROM SDD_OBJECT_VERSIONS ov ,SDD_FOLDER_MEMBERS fm ,RM_ELEMENT_TYPES et WHERE ov.irid = fm.member_object AND fm.parent_ivid = fol_ivid AND et.id = ov.logical_type_id AND et.short_name IN ('FOL','APP','PCK'); CURSOR root_folders IS SELECT fol.irid AS fol_irid, fol.ivid AS fol_ivid FROM CI_ROOT_CONTAINER_ELEMENTS fol; PROCEDURE MoveList IS i integer; BEGIN i:=sub_contents.first; -- Add the sub-folder contents to our list WHILE i IS NOT NULL LOOP contents.extend(); contents(contents.last).irid:=sub_contents(i).irid; contents(contents.last).ivid:=sub_contents(i).ivid; i:=sub_contents.next(i); END LOOP; sub_contents.DELETE; END MoveList; BEGIN --If user specified a CRN as a filter, then populate the contents list --using it and do the recurse if required IF filter IS NOT NULL THEN --Set up the prev_ivids list to contain the folder ivid IF fol_ivid IS NOT NULL THEN prev_ivids.extend(); prev_ivids(prev_ivids.last).ivid:=fol_ivid; END IF; contents:=objects_from_CRName(filter,prev_ivids); -- If we are not recusring then we have finished IF recurse THEN IF fol_ivid IS NOT NULL THEN FOR fold_mem IN get_folders(fol_ivid) LOOP sub_contents:=folder_contents_int(fold_mem.ov_ivid,recurse,filter); MoveList; END LOOP; ELSE FOR fol IN root_folders LOOP sub_contents:=folder_contents_int(fol.fol_ivid,recurse,filter); MoveList; END LOOP; END IF; END IF; ELSE -- No filter specified IF fol_ivid IS NOT NULL THEN --Looking in specified folder... FOR fold_mem IN get_contents(fol_ivid) LOOP --If no filter specified, then add irid and ivid for --each member of the folder to the list contents.extend(); contents(contents.last).irid:=fold_mem.ov_irid; contents(contents.last).ivid:=fold_mem.ov_ivid; --Recurse through any sub-folders IF (recurse ) AND (fold_mem.ov_type=app_type_id OR fold_mem.ov_type=fol_type_id) THEN sub_contents:=folder_contents_int(fold_mem.ov_ivid,recurse,filter); MoveList; END IF; END LOOP; ELSE --Looking at root folders... FOR fol IN root_folders LOOP --If no filter specified, then add irid and ivid for --each member of the folder to the list contents.extend(); contents(contents.last).irid:=fol.fol_irid; contents(contents.last).ivid:=fol.fol_ivid; --Recurse through any sub-folders IF recurse THEN sub_contents:=folder_contents_int(fol.fol_ivid,recurse,filter); MoveList; END IF; END LOOP; END IF; END IF; RETURN contents; EXCEPTION --Handle exceptions raised by parsing of filter WHEN INVALID_CRN THEN Rmmes.post('CDR',1001,filter); RETURN objver_list(); WHEN INVALID_WILDCARD THEN Rmmes.post('CDR',1031,filter); RETURN objver_list(); WHEN INCORRECTLY_PARSED_PATH THEN Rmmes.post('CDR',1002,filter); RETURN objver_list(); WHEN NULL_CONTEXT THEN Rmmes.post('CDR',1003,filter); RETURN objver_list(); WHEN INVALID_BRANCH_NAME THEN Rmmes.post('CDR',1004,filter); RETURN objver_list(); WHEN INVALID_TYPE THEN Rmmes.post('CDR',1034,filter); RETURN objver_list(); END; -------------------------------------------------------- --find_all_SAC() --Find all secondary elements, given name, type and owning folder -------------------------------------------------------- FUNCTION find_all_SAC(fol_ivid IN number ,l_name IN varchar2 ,l_type_id IN number) RETURN objver_list IS query varchar2(1000); table_name varchar2(30); name_column varchar2(35); r_irids jr_num_list; r_ivids jr_num_list; i boolean; object_set objver_list := objver_list(); BEGIN --At present, we can only get SACs in the context of a workarea IF Jr_Context.workarea IS NULL THEN RAISE NULL_CONTEXT; END IF; -- get SAC table name and name column from meta model SELECT this_tab.table_name , this_tab.name_column INTO table_name , name_column FROM RM_SQL_TABLES this_tab ,RM_SQL_ROW_TYPES this_srt ,RM_ELEMENT_TYPES this_type WHERE this_tab.name_column IS NOT NULL AND this_srt.table_mapped = this_tab.irid AND this_type.primary_row_type = this_srt.id AND this_type.irid = l_type_id; --WORKAROUND for 8.1.7 .... --There is no direct support for bulk operations in native dynamic SQL in 8.1.7 --so simulate a native dynamic bulk SQL statement by placing the bulk SQL --statement in a 'BEGIN ... END' block and executing the block dynamically. IF case_sensitive THEN query:='begin select sac.irid, sac.ivid '|| ' bulk collect into :irs, :ivs '|| ' from '||table_name||' sac'|| ' ,sdd_folder_members fm '|| ' where sac.'||name_column||' like '''||l_name||''' escape '''||escape_char||''''|| ' and sac.pac_ref = fm.member_object '|| ' and fm.parent_ivid = '||fol_ivid||'; end;'; ELSE query:='begin select sac.irid, sac.ivid'|| ' bulk collect into :irs, :ivs '|| ' from '||table_name||' sac'|| ' ,sdd_folder_members fm '|| ' where NLS_UPPER(sac.'||name_column||') like '''||NLS_UPPER(l_name)||''' escape '''||escape_char||''''|| ' and sac.pac_ref = fm.member_object '|| ' and fm.parent_ivid = '||fol_ivid ||'; end;'; END IF; execute immediate query using out r_irids, out r_ivids; -- Copy objects to record because can't bulk collect into it directly .... if (r_irids.first IS NOT NULL) then object_set.extend(r_irids.count); FOR i IN r_irids.FIRST..r_irids.LAST LOOP object_set(i).irid:=r_irids(i); object_set(i).ivid:=r_ivids(i); END LOOP; end if; --Return the objects found RETURN object_set; EXCEPTION WHEN NO_DATA_FOUND THEN rmdbg.trace('No data found error in find_all_SAC'); --Return the empty object set RETURN object_set; END; ------------------------------------------------------------------ -- Similar to Objects_from_CRName() except that it checks -- if filter refers to a SAC and if so, calls find_all_SAC -- Get a set of objects IVID from an objects CRN, and the IVID of -- its owning folder. (Wildcards in name may result in more than -- one object matching...). -- Accepts both version number format and version label format. -- If a workarea context is set can just specify the name. ----------------------------------------------------------------- FUNCTION all_objects_from_CRName(CRName IN varchar2 ,prev_ivids IN objver_list) RETURN dpnd_objver_list IS l_name varchar2(400); l_branch_id number; l_version number; i number; j number; k number; prev_ivid number; l_vlabel varchar2(255); l_type_id number; l_fol_irid number; l_find_by_label boolean; l_is_primary rm_element_types.is_primary%TYPE; in_wka_context boolean; object_set objver_list; ret_obj_set dpnd_objver_list:=dpnd_objver_list(); BEGIN in_wka_context:=parse_name(CRName ,l_name ,l_branch_id ,l_version ,l_vlabel ,l_type_id ,l_find_by_label ,l_is_primary); j := prev_ivids.first; --Otherwise, loop over each of the previous objects, and add any objects that belong --to them that match the current CRName to the return object set. WHILE j IS NOT NULL LOOP prev_ivid := prev_ivids(j).ivid; l_fol_irid := jr_name.get_rid(prev_ivid); j := prev_ivids.next(j); IF (in_wka_context) THEN IF (l_is_primary = 'N') THEN object_set := find_all_SAC(prev_ivid,l_name,l_type_id); ELSIF (l_is_primary = 'OPTIONAL') THEN -- Find all PACs of this type object_set:=find_by_name(prev_ivid,l_name,l_type_id); k := object_set.first; -- Add the PAC objects we found to the set we will return... WHILE k IS NOT NULL LOOP ret_obj_set.extend(); ret_obj_set(ret_obj_set.last).irid:=object_set(k).irid; ret_obj_set(ret_obj_set.last).ivid:=object_set(k).ivid; ret_obj_set(ret_obj_set.last).type_id:=l_type_id; ret_obj_set(ret_obj_set.last).fol_irid:=l_fol_irid; k:=object_set.next(k); END LOOP; -- Now find all SACs of this type object_set := find_all_SAC(prev_ivid,l_name,l_type_id); ELSE object_set:=find_by_name(prev_ivid,l_name,l_type_id); END IF; ELSIF (l_find_by_label) THEN object_set:=find_by_vlabel(prev_ivid,l_name,l_vlabel,l_type_id); ELSE object_set:=find_by_vernum(prev_ivid,l_name,l_branch_id,l_version,l_type_id); END IF; i:=object_set.first; -- Add the objects we found to the set we will return... WHILE i IS NOT NULL LOOP ret_obj_set.extend(); ret_obj_set(ret_obj_set.last).irid:=object_set(i).irid; ret_obj_set(ret_obj_set.last).ivid:=object_set(i).ivid; ret_obj_set(ret_obj_set.last).type_id:=l_type_id; ret_obj_set(ret_obj_set.last).fol_irid:=l_fol_irid; i:=object_set.next(i); END LOOP; END LOOP; RETURN ret_obj_set; END; ---------------------------------------------------------- --- dpnd_folder_contents() --- Bug 2552095 --- New function written for the dependancy manager which --- copes with SAC filters and also returns the type id --- for each element added to the set. --- Get the folder contents from the IVID of the folder, --- from within the context of a workarea. --- If RECURSE is TRUE, then recurse through all --- subfolders in the hiearchy. --- If a NULL value for fol_ivid is supplied, then the --- root folders are retrieved (and recursed through if --- required). ---------------------------------------------------------- FUNCTION dpnd_folder_contents(fol_ivid IN number ,recurse IN boolean ,filter IN varchar2) RETURN dpnd_objver_list IS contents dpnd_objver_list:=dpnd_objver_list(); prev_ivids objver_list:=objver_list(); sub_contents dpnd_objver_list; i integer; irid number; ivid number; CURSOR get_contents (fol_ivid number) IS SELECT ov.irid AS ov_irid ,ov.ivid AS ov_ivid ,ov.logical_type_id AS ov_type ,fm.folder_reference AS ov_fol_irid FROM SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE ov.irid = fm.member_object AND fm.parent_ivid = fol_ivid; CURSOR get_folders (fol_ivid number) IS SELECT ov.ivid ov_ivid FROM SDD_OBJECT_VERSIONS ov ,SDD_FOLDER_MEMBERS fm ,RM_ELEMENT_TYPES et WHERE ov.irid = fm.member_object AND fm.parent_ivid = fol_ivid AND et.id = ov.logical_type_id AND et.short_name IN ('FOL','APP'); CURSOR root_folders IS SELECT fol.irid AS fol_irid , fol.ivid AS fol_ivid , fol.types AS fol_type FROM CI_ROOT_CONTAINER_ELEMENTS fol; PROCEDURE MoveList IS i integer; BEGIN i:=sub_contents.first; -- Add the sub-folder contents to our list WHILE i IS NOT NULL LOOP contents.extend(); contents(contents.last).irid:=sub_contents(i).irid; contents(contents.last).ivid:=sub_contents(i).ivid; contents(contents.last).type_id:=sub_contents(i).type_id; contents(contents.last).fol_irid:=sub_contents(i).fol_irid; i:=sub_contents.next(i); END LOOP; sub_contents.DELETE; END MoveList; BEGIN --If user specified a CRN as a filter, then populate the contents list --using it and do the recurse if required IF filter IS NOT NULL THEN --Set up the prev_ivids list to contain the folder ivid IF fol_ivid IS NOT NULL THEN prev_ivids.extend(); prev_ivids(prev_ivids.last).ivid:=fol_ivid; contents := all_objects_from_CRName(filter, prev_ivids); -- no folder specified, in this case NULL means all root folders ELSE FOR fol IN root_folders LOOP sub_contents:=dpnd_folder_contents(fol.fol_ivid,recurse,filter); MoveList; END LOOP; END IF; -- If we are not recursing then we have finished IF (recurse AND fol_ivid IS NOT NULL) THEN FOR fold_mem IN get_folders(fol_ivid) LOOP sub_contents:=dpnd_folder_contents(fold_mem.ov_ivid,recurse,filter); MoveList; END LOOP; END IF; -- end filter specified processing ELSE -- No filter specified IF fol_ivid IS NOT NULL THEN --Looking in specified folder... FOR fold_mem IN get_contents(fol_ivid) LOOP --If no filter specified, then add irid and ivid for --each member of the folder to the list contents.extend(); contents(contents.last).irid:=fold_mem.ov_irid; contents(contents.last).ivid:=fold_mem.ov_ivid; contents(contents.last).type_id:=fold_mem.ov_type; contents(contents.last).fol_irid:=fold_mem.ov_fol_irid; --Recurse through any sub-folders IF (recurse ) AND (fold_mem.ov_type = app_type_id OR fold_mem.ov_type = fol_type_id) THEN sub_contents := dpnd_folder_contents(fold_mem.ov_ivid,recurse,filter); MoveList; END IF; END LOOP; ELSE --Looking at root folders... FOR fol IN root_folders LOOP --No filter specified, get contents of each root folder sub_contents:=dpnd_folder_contents(fol.fol_ivid,recurse,filter); MoveList; END LOOP; END IF; END IF; -- no filter specified RETURN contents; EXCEPTION --Handle exceptions raised by parsing of filter WHEN INVALID_CRN THEN Rmmes.post('CDR',1001,filter); RETURN dpnd_objver_list(); WHEN INVALID_WILDCARD THEN Rmmes.post('CDR',1031,filter); RETURN dpnd_objver_list(); WHEN INCORRECTLY_PARSED_PATH THEN Rmmes.post('CDR',1002,filter); RETURN dpnd_objver_list(); WHEN NULL_CONTEXT THEN Rmmes.post('CDR',1003,filter); RETURN dpnd_objver_list(); WHEN INVALID_BRANCH_NAME THEN Rmmes.post('CDR',1004,filter); RETURN dpnd_objver_list(); WHEN INVALID_TYPE THEN Rmmes.post('CDR',1034,filter); RETURN dpnd_objver_list(); END; ---------------------------------------------------------- --- folder_contents() --- Get the folder contents from the IVID of the folder, --- from within the context of a workarea. --- If RECURSE is TRUE, then recurse through all --- subfolders in the hiearchy. --- If a NULL value for fol_ivid is supplied, then the --- root folders are retrieved (and recursed through if --- required). ---------------------------------------------------------- FUNCTION folder_contents(fol_ivid IN number ,recurse IN boolean ,filter IN varchar2) RETURN objver_list IS contents objver_list:=objver_list(); prev_ivids objver_list:=objver_list(); prev_types jr_num_list:=jr_num_list(); sub_contents objver_list; i integer; irid number; ivid number; -- Bug 2348525 - remove join to rm_element_types CURSOR get_contents (fol_ivid number) IS SELECT ov.irid AS ov_irid,ov.ivid AS ov_ivid, ov.logical_type_id AS ov_type FROM SDD_OBJECT_VERSIONS ov ,I$SDD_FOLDER_MEMBERS fm WHERE ov.irid = fm.member_object AND fm.parent_ivid = fol_ivid; CURSOR get_folders (fol_ivid number) IS SELECT ov.ivid ov_ivid FROM SDD_OBJECT_VERSIONS ov ,SDD_FOLDER_MEMBERS fm ,RM_ELEMENT_TYPES et WHERE ov.irid = fm.member_object AND fm.parent_ivid = fol_ivid AND et.id = ov.logical_type_id AND et.short_name IN ('FOL','APP','PCK'); CURSOR root_folders IS SELECT fol.irid AS fol_irid, fol.ivid AS fol_ivid FROM CI_ROOT_CONTAINER_ELEMENTS fol; PROCEDURE MoveList IS i integer; BEGIN i:=sub_contents.first; -- Add the sub-folder contents to our list WHILE i IS NOT NULL LOOP contents.extend(); contents(contents.last).irid:=sub_contents(i).irid; contents(contents.last).ivid:=sub_contents(i).ivid; i:=sub_contents.next(i); END LOOP; sub_contents.DELETE; END MoveList; BEGIN --If user specified a CRN as a filter, then populate the contents list --using it and do the recurse if required IF filter IS NOT NULL THEN --Set up the prev_ivids list to contain the folder ivid IF fol_ivid IS NOT NULL THEN prev_ivids.extend(); prev_ivids(prev_ivids.last).ivid:=fol_ivid; END IF; contents:=objects_from_CRName(filter,prev_ivids); -- If we are not recusring then we have finished IF recurse THEN IF fol_ivid IS NOT NULL THEN FOR fold_mem IN get_folders(fol_ivid) LOOP sub_contents:=folder_contents(fold_mem.ov_ivid,recurse,filter); MoveList; END LOOP; ELSE FOR fol IN root_folders LOOP sub_contents:=folder_contents(fol.fol_ivid,recurse,filter); MoveList; END LOOP; END IF; END IF; ELSE -- No filter specified IF fol_ivid IS NOT NULL THEN --Looking in specified folder... FOR fold_mem IN get_contents(fol_ivid) LOOP --If no filter specified, then add irid and ivid for --each member of the folder to the list contents.extend(); contents(contents.last).irid:=fold_mem.ov_irid; contents(contents.last).ivid:=fold_mem.ov_ivid; --Recurse through any sub-folders IF (recurse ) AND (fold_mem.ov_type=app_type_id OR fold_mem.ov_type=fol_type_id) THEN sub_contents:=folder_contents(fold_mem.ov_ivid,recurse,filter); MoveList; END IF; END LOOP; ELSE --Looking at root folders... FOR fol IN root_folders LOOP --If no filter specified, then add irid and ivid for --each member of the folder to the list contents.extend(); contents(contents.last).irid:=fol.fol_irid; contents(contents.last).ivid:=fol.fol_ivid; --Recurse through any sub-folders IF recurse THEN sub_contents:=folder_contents(fol.fol_ivid,recurse,filter); MoveList; END IF; END LOOP; END IF; END IF; RETURN contents; EXCEPTION --Handle exceptions raised by parsing of filter WHEN INVALID_CRN THEN Rmmes.post('CDR',1001,filter); RETURN objver_list(); WHEN INVALID_WILDCARD THEN Rmmes.post('CDR',1031,filter); RETURN objver_list(); WHEN INCORRECTLY_PARSED_PATH THEN Rmmes.post('CDR',1002,filter); RETURN objver_list(); WHEN NULL_CONTEXT THEN Rmmes.post('CDR',1003,filter); RETURN objver_list(); WHEN INVALID_BRANCH_NAME THEN Rmmes.post('CDR',1004,filter); RETURN objver_list(); WHEN INVALID_TYPE THEN Rmmes.post('CDR',1034,filter); RETURN objver_list(); END; -------------------------------------------------------------- --- folder_contents() --- Given the path of a folder (or app sys), return the --- irids and ivids of its contents. --- If RECURSE is true, then recurse through any sub-folders. --- If LATEST is true, return the latest versions of --- the contents on the same branch as the folder, --- otherwise return contents for current workarea context. -------------------------------------------------------------- FUNCTION folder_contents(path IN varchar2 ,latest IN boolean DEFAULT TRUE ,recurse IN boolean DEFAULT TRUE ,filter IN varchar2 DEFAULT NULL ,seperator IN char DEFAULT NULL) RETURN objver_list IS branch number; fol_ivid number; fol_contents objver_list; BEGIN IF (path IS NULL AND latest=FALSE) THEN --In a workarea context, allow NULL path --to indicate folders at root level fol_ivid:=NULL; ELSE --Get irid,ivid of folder fol_ivid:=get_VID(path,seperator); IF fol_ivid IS NULL THEN --Couln't find folder... Rmmes.post('CDR',1000,path); RETURN objver_list(); END IF; END IF; IF (NOT latest) THEN IF (Jr_Context.workarea IS NULL) THEN --ERROR: no workarea context set, so can't find folder members other than latest... Rmmes.post('CDR',100); RETURN objver_list(); ELSE fol_contents:=folder_contents(fol_ivid,recurse,filter); END IF; ELSE --Get the id of the branch SELECT branch_id INTO branch FROM I$SDD_VERSION_ASSOCIATIONS WHERE to_ivid=fol_ivid AND edge_kind IN ('N','R','B'); --Don't double count tips or merges... --Get the contents fol_contents:=folder_latest_contents(fol_ivid,branch,recurse,filter); END IF; RETURN fol_contents; EXCEPTION --Handle exceptions raised by parsing of path WHEN INVALID_CRN THEN Rmmes.post('CDR',1001,path); RETURN objver_list(); WHEN INVALID_WILDCARD THEN Rmmes.post('CDR',1031,path); RETURN objver_list(); WHEN INCORRECTLY_PARSED_PATH THEN Rmmes.post('CDR',1002,path); RETURN objver_list(); WHEN NULL_CONTEXT THEN Rmmes.post('CDR',1003,path); RETURN objver_list(); WHEN INVALID_BRANCH_NAME THEN Rmmes.post('CDR',1004,path); RETURN objver_list(); WHEN INVALID_TYPE THEN Rmmes.post('CDR',1034,path); WHEN TOO_MANY_ELEMENTS THEN Rmmes.post('CDR',1035,path); END; ------------------------------------------------------------------------- --Checks the name uniqueness of the given primary element in the context --of the given folder and current application system. --If the element does not have a unique name, the irid and type id --of the conflicting element are passed back, and the function returns --FALSE. For Oracle Designer elements, the appropriate CDAPI checks are --called. -------------------------------------------------------------------------- FUNCTION is_el_name_unique(con_irid IN number ,pac_irid IN number ,clash_irid OUT number ,clash_type_id OUT number) RETURN boolean IS elem_prod rm_element_types.product%TYPE; elem_type rm_element_types.short_name%TYPE; designer_repos RM$REPOSITORIES.supports_designer%TYPE; name_unique boolean:= FALSE; BEGIN --Can only check uniqueness in the context of a workarea IF Jr_Context.workarea IS NULL THEN --Workarea context must be set Rmmes.post('CDR',100); RAISE NULL_CONTEXT; END IF; --Need to do seperate checking for Designer and registered types. SELECT repos.supports_designer INTO designer_repos FROM RM$REPOSITORIES repos; SELECT et.product,et.short_name INTO elem_prod,elem_type FROM rm_element_types et ,sdd_object_versions ov WHERE et.id=ov.logical_type_id AND ov.irid=pac_irid; IF designer_repos='Y' AND elem_prod='CI' THEN --Dynamic SQL callout to CDAPI code name_unique:=is_des_el_name_unique(con_irid ,pac_irid ,elem_type ,clash_irid ,clash_type_id); ELSE --Helper method for registered types name_unique:=is_reg_el_name_unique(con_irid ,pac_irid ,elem_type ,clash_irid ,clash_type_id); END IF; RETURN name_unique; END; ---------------------------------------------------------------------------- -- Private helper method -- Generates call to CDAPI method CIMAPPCON.IS_PAC_NAME_UNIQUE() ---------------------------------------------------------------------------- FUNCTION is_des_el_name_unique(con_irid IN number ,pac_irid IN number ,elem_type IN varchar2 ,clash_irid OUT number ,clash_type_id OUT number) RETURN boolean IS is_unique varchar2(1):='N'; name_unique boolean; sql_stmt varchar2(1000); csr number; exec number; BEGIN IF elem_type IN ('APP','FOL','PCK','PRJ') THEN --Containers are a special case, not handled by CDAPI name_unique:=is_reg_el_name_unique(con_irid ,pac_irid ,elem_type ,clash_irid ,clash_type_id); RETURN name_unique; END IF; --Need to generate call dynamically, as the CDAPI method is only present --in designer repositories! sql_stmt:='DECLARE '|| ' name_unique boolean;'|| 'BEGIN '|| ' name_unique:=cimappcon.is_pac_name_unique(:app_id'|| ',:pac_id'|| ',:pac_type'|| ',:clash_id'|| ',:clash_types);'|| ' if name_unique then '|| ' :is_unique:=''Y''; '|| ' else '|| ' :is_unique:=''N''; '|| ' end if; '|| 'END;'; --Set up cursor csr:=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(csr,sql_stmt,DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE(csr,':app_id',con_irid); DBMS_SQL.BIND_VARIABLE(csr,':pac_id',pac_irid); DBMS_SQL.BIND_VARIABLE(csr,':pac_type',elem_type); DBMS_SQL.BIND_VARIABLE(csr,':clash_id',clash_irid); DBMS_SQL.BIND_VARIABLE(csr,':clash_types',clash_type_id); DBMS_SQL.BIND_VARIABLE(csr,':is_unique',is_unique); exec:=DBMS_SQL.EXECUTE(csr); --Recover the bind variables DBMS_SQL.VARIABLE_VALUE(csr,':clash_id',clash_irid); DBMS_SQL.VARIABLE_VALUE(csr,':clash_types',clash_type_id); DBMS_SQL.VARIABLE_VALUE(csr,':is_unique',is_unique); --Close the cursor DBMS_SQL.CLOSE_CURSOR(csr); IF is_unique='Y' THEN RETURN TRUE; ELSE RETURN FALSE; END IF; EXCEPTION WHEN OTHERS THEN --Close the cursor DBMS_SQL.CLOSE_CURSOR(csr); RAISE; END; ---------------------------------------------------------------------------- -- Private helper method -- Checks uniqueness against name in SDD_OBJECT_VERSIONS ---------------------------------------------------------------------------- FUNCTION is_reg_el_name_unique(con_irid IN number ,pac_irid IN number ,elem_type IN varchar2 ,clash_irid OUT number ,clash_type_id OUT number) RETURN boolean IS is_root_fol varchar2(1):='N'; BEGIN --Root containers are a special case IF elem_type IN ('FOL','APP','PCK','PRJ') THEN SELECT fol.root_flag INTO is_root_fol FROM SDD_FOLDERS fol WHERE fol.irid=pac_irid; END IF; IF is_root_fol='Y' THEN SELECT MAX(other_el.irid),MAX(other_el.types) INTO clash_irid,clash_type_id FROM SDD_FOLDERS other_el ,SDD_FOLDERS this_el WHERE this_el.irid=pac_irid AND other_el.name=this_el.name AND other_el.root_flag='Y' AND other_el.irid!=this_el.irid; ELSE SELECT MAX(other_el.irid),MAX(other_el.logical_type_id) INTO clash_irid,clash_type_id FROM sdd_object_versions other_el ,sdd_object_versions this_el ,sdd_folder_members fm WHERE this_el.irid=pac_irid AND fm.folder_reference=con_irid AND other_el.irid=fm.member_object AND other_el.table_irid=this_el.table_irid --Catch elem of diff type sharing same tab. AND other_el.name=this_el.name AND other_el.irid!=this_el.irid; END IF; IF clash_irid IS NULL THEN --No clash was found RETURN TRUE; ELSE RETURN FALSE; END IF; END; ----------------------------------------------------------------------------- -- Wrappers to return jr_num_list rather than objver_list, -- as OCI can only handle collections of primitive types. -- Eventually, will replace interfaces for original methods -- with ones that look like these wrappers, but need to modify exsisting -- server code that calls naming service first... ----------------------------------------------------------------------------- --------------------------------------------------------- --Helper function to convert objver_list to jr_num_lists --------------------------------------------------------- PROCEDURE convert_obj_list(objects IN Jr_Name.objver_list ,IRIDS OUT jr_num_list ,IVIDS OUT jr_num_list) IS i int; BEGIN IRIDS:=jr_num_list(); IVIDS:=jr_num_list(); i:=objects.first; WHILE i IS NOT NULL LOOP IRIDS.extend(); IVIDS.extend(); IRIDS(IRIDS.last):=objects(i).irid; IVIDS(IVIDS.last):=objects(i).ivid; i:=objects.next(i); END LOOP; END convert_obj_list; PROCEDURE get_objects(CRPath IN varchar2 ,irids OUT jr_num_list ,ivids OUT jr_num_list ,seperator IN char := NULL) IS BEGIN convert_obj_list(get_objects(CRPath,seperator),IRIDS,IVIDS); END; PROCEDURE path_members(CRPath IN varchar2 ,irids OUT jr_num_list ,ivids OUT jr_num_list ,seperator IN char := NULL) IS BEGIN convert_obj_list(path_members(CRPath,seperator),IRIDS,IVIDS); END; PROCEDURE folder_contents(fol_ivid IN number ,recurse IN boolean ,irids OUT jr_num_list ,ivids OUT jr_num_list ,filter IN varchar2 DEFAULT NULL) IS BEGIN convert_obj_list(folder_contents(fol_ivid,recurse,filter),IRIDS,IVIDS); END; PROCEDURE folder_latest_contents(fol_ivid IN number ,branch_id number ,recurse IN boolean ,irids OUT jr_num_list ,ivids OUT jr_num_list ,filter IN varchar2 DEFAULT NULL) IS BEGIN convert_obj_list(folder_latest_contents(fol_ivid,branch_id,recurse,filter),IRIDS,IVIDS); END; PROCEDURE folder_contents(path IN varchar2 ,latest IN boolean ,recurse IN boolean ,irids OUT jr_num_list ,ivids OUT jr_num_list ,filter IN varchar2 DEFAULT NULL ,seperator IN char := NULL) IS BEGIN convert_obj_list(folder_contents(path,latest,recurse,filter,seperator),IRIDS,IVIDS); END; ---------------------------------------------------------- -- Following methods are for dealing with the -- global object set, and allow irids and ivids to be -- removed from the list one at a time ---------------------------------------------------------- ----------------------------------------------------------------------------- -- Wrappers for functions that return objver_lists - to get around JDBC -- limitations for dealing with arrays. -- Each procedure passes back the number of objects -- found for given path, and populates the global object list -- with the set of objects found. Objects can then be retrieved from -- this list one at a time. ----------------------------------------------------------------------------- PROCEDURE get_objects(CRPath IN varchar2, found OUT number,seperator IN char := NULL) IS BEGIN global_obj_set:=get_objects(CRPath,seperator); found:= global_obj_set.COUNT; END; PROCEDURE path_members(CRPath IN varchar2, found OUT number,seperator IN char := NULL) IS BEGIN global_obj_set:=path_members(CRPath,seperator); found:= global_obj_set.COUNT; END; PROCEDURE folder_contents(fol_ivid IN number ,recurse IN boolean ,filter IN varchar2 DEFAULT NULL ,found OUT number) IS BEGIN global_obj_set:=folder_contents(fol_ivid,recurse,filter); found:= global_obj_set.COUNT; END; PROCEDURE folder_latest_contents(fol_ivid IN number ,branch_id number ,recurse IN boolean ,filter IN varchar2 DEFAULT NULL ,found OUT number) IS BEGIN global_obj_set:=folder_latest_contents(fol_ivid,branch_id,recurse,filter); found:= global_obj_set.COUNT; END; PROCEDURE folder_contents(path IN varchar2, latest IN boolean, recurse IN boolean, found OUT number, filter IN varchar2 DEFAULT NULL, seperator IN char DEFAULT NULL) IS BEGIN global_obj_set:=folder_contents(path,latest,recurse,filter,seperator); found:= global_obj_set.COUNT; END; -------------------------------------------------------------- --get_first() --Gets the first element in the global_obj_set. --Returns irid, ivid and index. -------------------------------------------------------------- PROCEDURE get_first(irid OUT number ,ivid OUT number ,el_index OUT number) IS BEGIN el_index:= global_obj_set.first; irid:=global_obj_set(el_index).irid; ivid:=global_obj_set(el_index).ivid; END; -------------------------------------------------------------- --get_next() --Gets the next element in global_obj_set, after the specified index --If the specified index is null, then it gets the first in the --list. The index is passed pack as the next index value (ie the --index of the element just recovered). -------------------------------------------------------------- PROCEDURE get_next(irid OUT number ,ivid OUT number ,el_index IN OUT number) IS BEGIN IF el_index IS NULL THEN --Get the first in the list el_index:=global_obj_set.first; ELSIF el_index>=global_obj_set.last THEN --We're at the last in the list, return NULLs el_index:=NULL; irid:=NULL; ivid:=NULL; RETURN; ELSE --Get the next in the list el_index:=global_obj_set.next(el_index); END IF; irid:=global_obj_set(el_index).irid; ivid:=global_obj_set(el_index).ivid; END; ---------------------------------------------------------- -- latest_diagram_contents() -- Get the Diagram contents from the IVID of the diagram, -- from within the context of a workarea. -- Added to Fix US BUGS 1969465 -- 1969487 ---------------------------------------------------------- FUNCTION latest_diagram_contents (diagram_ivid IN number ,branch_id number ) RETURN objver_list IS contents objver_list:=objver_list(); sub_contents objver_list; prev_ivids objver_list:=objver_list(); prev_types jr_num_list:=jr_num_list(); i integer; irid number; ivid number; CURSOR get_contents (diagram_ivid number, p_branch_id number) IS select va.irid ov_irid, va.to_ivid ov_ivid from SDD_VERSION_ASSOCIATIONS va ,I$SDD_DEU deu ,I$SDD_BRANCHES br where deu.parent_ivid = diagram_ivid and va.irid = deu.cielement_ref and va.edge_kind = ('T') and va.branch_id = br.branch_id and br.branch_id=p_branch_id ORDER BY OV_IVID; BEGIN FOR fold_mem IN get_contents(diagram_ivid,branch_id) LOOP contents.extend(); contents(contents.last).irid:=fold_mem.ov_irid; contents(contents.last).ivid:=fold_mem.ov_ivid; END LOOP; RETURN contents; END latest_diagram_contents; END; /