prompt Package Body: jr_copy create or replace package body jr_copy is ----------------------------------------------------------------------------------- -- *** Private data declarations *** ----------------------------------------------------------------------------------- stmt_cpy dbms_sql.varchar2s; -- complete plsql copy statement stmt_cpy_idx pls_integer := 0; cpy_fun_stmt_a dbms_sql.varchar2s; -- 1, declare section of plsql copy statement cpy_fun_stmt_b dbms_sql.varchar2s; -- 2, begin...end section of plsql copy statement type plsi_arr is varray (2) of integer; stmt_idxs plsi_arr := plsi_arr(0, 0); CPY_FUN_A constant pls_integer := 1; CPY_FUN_B constant pls_integer := 2; -- Globals to store details about the old and new objects old_object_irid number; old_parent_ivid number; new_pac_ref number; new_parent_ivid number; copying_within_same_object boolean; RELATIONSHIP_ENDS_TABLE constant varchar2(10) := 'SDD_RELEND'; OTHER_RELEND_REF_COLUMN constant varchar2(26) := 'OTHER_RELATIONSHIP_END_REF'; EXTENDED_STUCT_ELS_TABLE constant varchar2(7) := 'SDD_UES'; PART_OF_REF_COLUMN constant varchar2(11) := 'PART_OF_REF'; MAPPING_ELEMENTS_TABLE constant varchar2(7) := 'SDD_MAP'; SOURCE_CIELEMENT_COLUMN constant varchar2(20) := 'SOURCE_CIELEMENT_REF'; TARGET_CIELEMENT_COLUMN constant varchar2(20) := 'TARGET_CIELEMENT_REF'; CIELEMENT_REF_COLUMN constant varchar2(15) := 'CIELEMENT_REF'; ELEMENT_REF_COLUMN constant varchar2(11) := 'ELEMENT_REF'; ----------------------------------------------------------------------------------- -- *** Private method definitions *** ----------------------------------------------------------------------------------- ----------------------------------------------------------------------------------- -- Procedure : put_line -- Write line to debug output or file ----------------------------------------------------------------------------------- procedure put_line(msg varchar2) is begin jr_reg_io.put_line(msg); rmdbg.trace(msg); end put_line; ----------------------------------------------------------------------------------- -- Function : get_time ----------------------------------------------------------------------------------- function get_time return varchar2 is begin return to_char(sysdate, 'DD-Mon-YYYY HH24:MI:SS'); end get_time; ----------------------------------------------------------------------------------- -- Procedure : init_copy_stmt -- Initialize package variables ----------------------------------------------------------------------------------- procedure init_copy_stmt is begin stmt_cpy.delete; stmt_cpy_idx := 0; cpy_fun_stmt_a.delete; cpy_fun_stmt_b.delete; for n in 1..stmt_idxs.count loop stmt_idxs(n) := 0; end loop; end init_copy_stmt; ----------------------------------------------------------------------------------- -- Procedure : add_line -- Add a line of code to copy statement (definition or implementation) ----------------------------------------------------------------------------------- procedure add_line (stmt_num pls_integer, stmt_line varchar2) is begin stmt_idxs(stmt_num) := stmt_idxs(stmt_num) + 1; if stmt_num = CPY_FUN_A then cpy_fun_stmt_a (stmt_idxs(stmt_num)) := stmt_line; elsif stmt_num = CPY_FUN_B then cpy_fun_stmt_b (stmt_idxs(stmt_num)) := stmt_line; end if; end add_line; ----------------------------------------------------------------------------------- -- Procedure : build_common_stmt -- Initialize package variables ----------------------------------------------------------------------------------- procedure build_common_stmt (cpycopy_deps_policy boolean) is begin init_copy_stmt; -- Initialize package variables for storing PL/SQL add_line(CPY_FUN_A, 'declare'); add_line(CPY_FUN_A, ' old_irid number;'); add_line(CPY_FUN_A, ' old_ivid number;'); add_line(CPY_FUN_A, ' old_parent_ivid number;'); add_line(CPY_FUN_A, ' new_irid number;'); add_line(CPY_FUN_A, ' new_ivid number;'); add_line(CPY_FUN_A, ' new_pac_ref number;'); add_line(CPY_FUN_A, ' new_parent_ivid number;'); add_line(CPY_FUN_A, ' cpycopy_deps_policy boolean;'); add_line(CPY_FUN_B, 'begin'); add_line(CPY_FUN_B, ' old_parent_ivid := ' || old_parent_ivid || ';'); add_line(CPY_FUN_B, ' new_pac_ref := ' || new_pac_ref || ';'); add_line(CPY_FUN_B, ' new_parent_ivid := ' || new_parent_ivid || ';'); if cpycopy_deps_policy then add_line(CPY_FUN_B, ' cpycopy_deps_policy := true;'); else add_line(CPY_FUN_B, ' cpycopy_deps_policy := false;'); end if; end build_common_stmt; ----------------------------------------------------------------------------------- -- Procedure : exec_copy_stmt -- Build and execute a copy statement ----------------------------------------------------------------------------------- procedure exec_copy_stmt is begin for n in 1..cpy_fun_stmt_a.count loop put_line(cpy_fun_stmt_a(n)); stmt_cpy_idx := stmt_cpy_idx + 1; stmt_cpy(stmt_cpy_idx) := cpy_fun_stmt_a(n); end loop; for n in 1..cpy_fun_stmt_b.count loop put_line(cpy_fun_stmt_b(n)); stmt_cpy_idx := stmt_cpy_idx + 1; stmt_cpy(stmt_cpy_idx) := cpy_fun_stmt_b(n); end loop; if stmt_cpy.count > 0 then stmt_cpy_idx := stmt_cpy_idx + 1; stmt_cpy(stmt_cpy_idx) := jr_reg_io.END_OF_STATEMENT; end if; -- Execute the copy statement jr_reg_io.exec(stmt_cpy, true); end exec_copy_stmt; ----------------------------------------------------------------------------------- -- Procedure : init_id_mappings -- Initialize id_mappings table ----------------------------------------------------------------------------------- procedure init_id_mappings is begin id_mappings.delete; id_mappings_idx := 0; end init_id_mappings; ----------------------------------------------------------------------------------- -- Function : id_mapping_exists -- Does irid mapping already exist ? ----------------------------------------------------------------------------------- function id_mapping_exists (irid number) return boolean is begin for i in 1..id_mappings.count loop if id_mappings(i).irid = id_mapping_exists.irid then return true; end if; end loop; -- irid mapping does not exist return false; end id_mapping_exists; ----------------------------------------------------------------------------------- -- Procedure : populate_id_mappings -- Populate id_mappings table with an irid, ivid value pair ----------------------------------------------------------------------------------- procedure populate_id_mappings ( irid number , ivid number , new_irid number default null , new_ivid number default null ) is begin --DBMS_OUTPUT.PUT_LINE('Populate ID Mappings:'); --DBMS_OUTPUT.PUT_LINE('IRID:'||to_char(irid)); --DBMS_OUTPUT.PUT_LINE('IVID:'||to_char(ivid)); --DBMS_OUTPUT.PUT_LINE('NEW_IRID:'||to_char(new_irid)); --DBMS_OUTPUT.PUT_LINE('NEW_IVID:'||to_char(new_ivid)); if not id_mapping_exists (populate_id_mappings.irid) then -- Only add irid if not already added id_mappings_idx := id_mappings_idx + 1; id_mappings.extend(); --DBMS_OUTPUT.PUT_LINE('Adding mapping at: '||to_char(id_mappings_idx)); id_mappings(id_mappings_idx).irid := populate_id_mappings.irid; id_mappings(id_mappings_idx).ivid := populate_id_mappings.ivid; if new_irid is not null then id_mappings(id_mappings_idx).new_irid := populate_id_mappings.new_irid; else if copying_within_same_object then -- Ensure old and new irids are the same if copying between different -- versions of the same object id_mappings(id_mappings_idx).new_irid := id_mappings(id_mappings_idx).irid; else id_mappings(id_mappings_idx).new_irid := jr_util.get_new_irid; end if; end if; if new_ivid is not null then id_mappings(id_mappings_idx).new_ivid := populate_id_mappings.new_ivid; else id_mappings(id_mappings_idx).new_ivid := jr_system_util.get_new_ivid; end if; end if; end populate_id_mappings; ------------------------------------------------------------------------------ -- Procedure : add_id_mappings -- Adds the supplied lists of irid/ivid pairs to the id_mappings table ------------------------------------------------------------------------------ procedure add_id_mappings(curr_irids in jr_num_list ,curr_ivids in jr_num_list ,copy_irids in jr_num_list ,copy_ivids in jr_num_list) is i pls_integer; begin i:=curr_irids.first; while i is not null loop if not id_mapping_exists (curr_irids(i)) then id_mappings.extend(); id_mappings_idx := id_mappings_idx + 1; --DBMS_OUTPUT.PUT_LINE('Adding ID Mapping at:'||to_char(id_mappings.last)); --DBMS_OUTPUT.PUT_LINE('IRID:'||to_char(curr_irids(i))); --DBMS_OUTPUT.PUT_LINE('IVID:'||to_char(curr_ivids(i))); --DBMS_OUTPUT.PUT_LINE('NEW_IRID:'||to_char(copy_irids(i))); --DBMS_OUTPUT.PUT_LINE('NEW_IVID:'||to_char(copy_ivids(i))); id_mappings(id_mappings.last).irid := curr_irids(i); id_mappings(id_mappings.last).ivid := curr_ivids(i); id_mappings(id_mappings.last).new_irid := copy_irids(i); id_mappings(id_mappings.last).new_ivid := copy_ivids(i); end if; i:=curr_irids.next(i); end loop; end add_id_mappings; ------------------------------------------------------------------------------ -- Function : get_new_irid -- Return new irid value corresponding to an old irid value ------------------------------------------------------------------------------ function get_new_irid (old_irid number) return number is begin --DBMS_OUTPUT.PUT_LINE('Getting new irid for '||to_char(old_irid)); if old_irid is null then return null; end if; for i in 1..id_mappings.count loop if id_mappings(i).irid = old_irid then --DBMS_OUTPUT.PUT_LINE('new irid is '||to_char(id_mappings(i).new_irid)); return id_mappings(i).new_irid; end if; end loop; --DBMS_OUTPUT.PUT_LINE('no new irid, so return '||old_irid); -- irid not re-mapped, return old value return old_irid; end ; ----------------------------------------------------------------------------------- -- Function : get_new_ivid -- Return new ivid value corresponding to an old ivid value ----------------------------------------------------------------------------------- function get_new_ivid (old_ivid number) return number is begin --DBMS_OUTPUT.PUT_LINE('Getting new ivid for '||to_char(old_ivid)); if old_ivid is null then return null; end if; for i in 1..id_mappings.count loop if id_mappings(i).ivid = old_ivid then --DBMS_OUTPUT.PUT_LINE('new ivid is '||to_char(id_mappings(i).new_ivid)); return id_mappings(i).new_ivid; end if; end loop; --DBMS_OUTPUT.PUT_LINE('no new ivid, so return '||old_ivid); -- ivid not re-mapped, return old value return old_ivid; end get_new_ivid; ------------------------------------------------------------------ -- Procedure : set_copied -- Indicate that row has been copied ------------------------------------------------------------------ procedure set_copied (irid number) is begin for i in 1..id_mappings.count loop if id_mappings(i).irid = set_copied.irid then id_mappings(i).copied := true; return; end if; end loop; end set_copied; ------------------------------------------------------------------ -- Function : is_copied -- Has this row been copied ? ------------------------------------------------------------------ function is_copied (irid number) return boolean is i number; begin for i in 1..id_mappings.count loop if id_mappings(i).irid = is_copied.irid and id_mappings(i).copied = true then return true; end if; end loop; -- Not found irid mappings with copied flag set return false; end is_copied; ----------------------------------------------------------------------------------- -- Procedure : copy_owned_types -- -- Copy all owned types of a type (recursive) ----------------------------------------------------------------------------------- procedure copy_owned_types ( i_type_irid number , i_type_ivid number , i_old_owner_pk_col varchar2 , i_pass_number number , cpycopy_deps_policy boolean default true , recursive_call boolean default false , i_cursor_index in out number ) is e_irid number; e_ivid number; e_name varchar2(40); linkprop_irid number; linkprop_name varchar2(40); type_irid number; type_ivid number; type_name varchar2(40); view_name varchar2(30); table_irid number; table_ivid number; table_name varchar2(30); table_type varchar2(1); table_prefix varchar2(2); maintain_dependent_objects boolean; ofk_irid number; ofk_ivid number; ofk_name varchar2(30); i pls_integer; old_owned_pk_col varchar2(40); bFKColumn boolean := false; cursor_name varchar2(30); record_name varchar2(30); comment_str varchar2(120); FOLDER_MEMBERS_TABLE constant varchar2(18) := 'SDD_FOLDER_MEMBERS'; OWNERSHIP_FLAG_COLUMN constant varchar2(14) := 'OWNERSHIP_FLAG'; -- Cursor to query all the '1' end of owning associations, owned -- by this type or any supertype of this type -- -- CW 19-May-2000 Fix bug 1304446, copy fails if there id an association -- to a UE element. This is because there is no (owning) foreign key from the -- UE tables to any other tables. This causes a no_data_found error from -- jr_meta.get_owning_fk which causes copy to not copy the correct elements. -- Adding : and lp.user_extension != 'YYY' -- to the query ignores UE elements -- Note, UE elements are copied by the call to jr_reg_ver.cpycopy_dependent_objects -- CW 14-May-2002 Fix bug 2191782 COPYING AN APPLICATION OMITS THE STORAGE INFORMATION -- It is actually the copying of a Database that fails, and it is Table Partitions -- that are not copied. -- The cursor here (owning_assocs_cur) was returning REFSET_CST as an owned -- type of Table Implementations. -- However, the 'many' end query (inside the for loop below) explicitly did -- not return a row for the type 'COLUMN_STORAGE', which caused an unhandled -- NO_DATA_FOUND exception, this would terminate the procedure call (and stop the -- owning_assocs_cur loop from ever processing Table Partitions). -- This exception must be being ignored by the caller. -- -- COLUMN_STORAGE was explicitly excluded as it is not a supported type (it was -- modelled then de-supported) and there are others. -- -- Fixing this by excluding these de-supported types in the owning_assocs_cur -- cursor instead so that unnecessary processing is prevented. -- The de-supported Designer model types are identified as having a null -- user_extension column value cursor owning_assocs_cur (type_irid number, type_ivid number) is select lp.name , lp.link_type from rm_link_properties lp , rm_link_properties lp2 , rm_element_types otherend where lp.defined_against in (select e.id from rm_element_types e start with e.id = owning_assocs_cur.type_irid connect by prior supertypes = id ) and lp.is_owning_association in ('Y', 'O') and lp.max_cardinality = -1 and lp.user_extension != 'YYY' and lp2.link_type = lp.link_type and lp2.max_cardinality = 1 and otherend.id = lp2.defined_against and otherend.product = 'CI' and otherend.user_extension is not null ; -- Cursor to query all the leaf types (lowest subtypes) of a type cursor leaf_types_cur (type_irid number, type_ivid number) is select e.irid , e.ivid , e.name , decode ( e.product , 'JR' , null , e.product || '_' ) || e.plural_name view_name from rm_element_types e where e.abstract != 'Y' start with e.irid = leaf_types_cur.type_irid connect by prior id = supertypes ; begin -- For each owning association for owning_assocs_rec in owning_assocs_cur (i_type_irid, i_type_ivid) loop -- Query the 'many' end of the association begin select e.irid, e.ivid, e.name, lp.irid, lp.name into e_irid, e_ivid, e_name, linkprop_irid, linkprop_name from rm_link_properties lp , rm_element_types e where lp.link_type = owning_assocs_rec.link_type and lp.max_cardinality = 1 and e.irid = lp.defined_against and e.name not in ( 'COLUMN_STORAGE' , 'NESTED_TABLE_STORAGE' , 'LOB_COLUMN_STORAGE' ) ; exception when TOO_MANY_ROWS then -- TODO raise error on error stack put_line('Failed to query M end of association'); raise; end; -- The element at the other end may be a supertype, need to return it's instantiable subtypes (ie. leafs) for leaf_types_rec in leaf_types_cur (e_irid, e_ivid) loop type_irid := leaf_types_rec.irid; type_ivid := leaf_types_rec.ivid; type_name := leaf_types_rec.name; view_name := leaf_types_rec.view_name; -- Find the table implementing the owned type jr_meta.get_table ( type_irid , table_irid , table_ivid , table_name , table_type , table_prefix , maintain_dependent_objects ); -- Find the owning foreign key which contains the column which implements the owned association jr_meta.get_owning_fk ( table_irid , table_ivid , type_irid , linkprop_irid , ofk_irid , ofk_ivid , ofk_name ); -- Cursors required for pass 1 and pass 2 -- Increment index to ensure generation of unique cursor name i_cursor_index := i_cursor_index + 1; -- Define cursor to return all rows in owned table belonging to the object being copied -- eg. Query all Attributes owned by an instance of an Entity -- Note that we may need to trim table and column names so that the -- generated identifiers do not exceed the maximum permitted length of 30 characters cursor_name := substr(table_name,1,23) || '_cur' || i_cursor_index; record_name := substr(table_name,1,23) || '_rec' || i_cursor_index; -- CW 28-Feb-2000 -- Fix bug 960764, generate several smaller plsql blocks to avoid Oracle error PLS-00123: program too large -- The actual copy statement block (pass 2) is by far the largest -- Generate a new plsql block for each top level copy -- For example, consider the structure of element type Entity : -- ATT } Copy ATT and ATV in a single block -- ATV } -- BUNENT ) Copy in a single block -- RELEND ) Copy in a single block -- UID ) Copy UID and ENTUIE in a single block -- ENTUIE ) -- if i_pass_number = 2 and not recursive_call then -- Define anonymous plsql block to implement copy -- Build declare block common to all copy statements build_common_stmt (cpycopy_deps_policy); add_line(CPY_FUN_A, ' ' || i_old_owner_pk_col || ' number;'); add_line(CPY_FUN_B, ' ' || i_old_owner_pk_col || ' := ' || old_object_irid || ';'); end if; -- Define variables to store the values of old and new primary key column values -- eg. SDD_ATT_old_IRID, SDD_ATT_new_IRID for fk_col_rec in jr_rm_cur.fk_col_cur (ofk_irid, ofk_ivid) loop old_owned_pk_col := substr(table_name,1,17) || '_old' || substr(fk_col_rec.pk_column_name,1,6) || i_cursor_index; add_line(CPY_FUN_A, ' ' || old_owned_pk_col || ' number;'); end loop; comment_str := '-- Query ' || type_name || ' via ' || linkprop_name; add_line(CPY_FUN_A, comment_str); add_line(CPY_FUN_A, ' cursor ' || cursor_name || ' ('); for fk_col_rec in jr_rm_cur.fk_col_cur (ofk_irid, ofk_ivid) loop add_line(CPY_FUN_A, ' ' || fk_col_rec.fk_column_name || ' ' || jr_meta.column_datatype(fk_col_rec.fk_column_name, table_irid, table_ivid)); end loop; add_line(CPY_FUN_A, ' ) is'); add_line(CPY_FUN_A, ' select *'); -- Bug 2319558, relends still not copying correctly once an entity -- has been versioned. -- Problem caused by the code to retrieve the other_relationship_end -- which was returning an irid which was then querying the non-version -- resolved table and returning multiple rows -- Changed code to use version resolved views for relends if table_name = RELATIONSHIP_ENDS_TABLE then add_line(CPY_FUN_A, ' from ' || table_name||' the_tab'); else add_line(CPY_FUN_A, ' from ' || table_prefix || table_name||' the_tab'); end if; add_line(CPY_FUN_A, ' where ( the_tab.parent_ivid = old_parent_ivid'); for fk_col_rec in jr_rm_cur.fk_col_cur (ofk_irid, ofk_ivid) loop add_line(CPY_FUN_A, ' and the_tab.' || fk_col_rec.fk_column_name || ' = ' || cursor_name || '.' || fk_col_rec.fk_column_name); end loop; -- B2021170 CW - 10-Dec-2001 if table_name = RELATIONSHIP_ENDS_TABLE then -- -- Make sure we copy the other end of the relationship even though -- its owned by another PAC -- -- CW 14-Dec-2001 relA relB -- Previous fix fails for example copy of EntA ------------ EntB -- because of the following sequence of events : -- 1) Mappings are populated (by Extended Copy) for EntA and EntB -- 2) cdapi copies EntA -- 3) jr_copy copies content of EntA, Attributes etc and RELENDs... -- 3) relA copied first, this is fine -- 4) relB copied next -- trigger sdd_relend_br fires and calls... -- jr_secondary_object.check_access_rights(:new.parent_ivid, 'SDD_RELEND'); -- which calls... -- jr_version.is_checked_in(NULL, parent_ivid) -- which fails because it queries object versions for the owning Entity -- which is the copy of EntB which hasn't been copied yet -- Note, this raises a no_data_found exception but this is not handled -- anywhere higher up the stack. -- Added handler in the trigger sdd_relend_br to catch this and raise -- application error -- -- ONLY copy both ends if the Entity at the TO end of the Relationship -- is NOT being copied (ie. it doesn't have a new irid value in the mapping -- set, the new value is the same as the current value). -- add_line(CPY_FUN_A,' ) or the_tab.irid in ' ); add_line(CPY_FUN_A,' ( select inn.' || OTHER_RELEND_REF_COLUMN ); add_line(CPY_FUN_A,' from ' || table_prefix || table_name||' inn' ); -- ONLY copy both ends if the Entity at the TO end of the Relationship -- is NOT being copied (ie. it doesn't have a new irid value in the mapping -- set, the new value is the same as the current value). --add_line(CPY_FUN_A,' where inn.parent_ivid = old_parent_ivid'); add_line(CPY_FUN_A,' where (jr_copy.get_new_irid(inn.TO_ENTITY_REF) = inn.TO_ENTITY_REF'); -- Bug 2820381 MK 1/4/03 -- In the case where a relationship is remapped, we also need to copy both ends. -- However, in this situation, there will be a new irid value in the mapping set for -- the entity at the TO end of the relationship, and so the previous fix (bug 2021170) -- does not work correctly. -- So the comment above is extended .... -- ONLY copy both ends if the Entity at the TO end of the Relationship is -- (1) NOT being copied (ie the 'TO' Entity doesn't have a new irid value in the -- mapping set, the new value is the same as the current value) -- OR (2) the relationship to the TO entity is being remapped (ie the 'TO' Entity -- does have a new irid value in the mapping set, but that new irid value -- corresponds to an entity that already exists add_line(CPY_FUN_A,' or'); add_line(CPY_FUN_A,' (jr_copy.get_new_irid(inn.to_entity_ref) <> inn.to_entity_ref'); add_line(CPY_FUN_A,' and exists'); add_line(CPY_FUN_A,' (select 1'); add_line(CPY_FUN_A,' from sdd_ent ent'); add_line(CPY_FUN_A,' where ent.irid = jr_copy.get_new_irid(inn.to_entity_ref)'); add_line(CPY_FUN_A,' )'); add_line(CPY_FUN_A,' ))'); add_line(CPY_FUN_A,' and inn.parent_ivid = old_parent_ivid'); for fk_col_rec in jr_rm_cur.fk_col_cur (ofk_irid, ofk_ivid) loop add_line(CPY_FUN_A, ' and inn.' || fk_col_rec.fk_column_name || ' = ' || cursor_name || '.' || fk_col_rec.fk_column_name); end loop; add_line(CPY_FUN_A,' )' ); else add_line(CPY_FUN_A,')' ); end if; add_line(CPY_FUN_A, ' ;'); if i_pass_number = 1 then comment_str := '-- Populate id mappings for ' || type_name || ' via ' || linkprop_name; else comment_str := '-- Copy ' || type_name || ' via ' || linkprop_name; end if; add_line(CPY_FUN_B, comment_str); add_line(CPY_FUN_B, ' for ' || record_name || ' in ' || cursor_name || ' ('); for fk_col_rec in jr_rm_cur.fk_col_cur (ofk_irid, ofk_ivid) loop add_line(CPY_FUN_B, ' ' || i_old_owner_pk_col); end loop; add_line(CPY_FUN_B, ' ) loop'); add_line(CPY_FUN_B, ' ' || old_owned_pk_col || ' := ' || record_name || '.irid;'); if i_pass_number = 1 then add_line(CPY_FUN_B, ' jr_copy.populate_id_mappings(' || record_name || '.irid, ' || record_name || '.ivid);'); else -- Pass 2 Perform the copy using id mappings add_line(CPY_FUN_B, ' if not jr_copy.is_copied(' || record_name || '.irid) then'); add_line(CPY_FUN_B, ' old_irid := ' || record_name || '.irid;'); add_line(CPY_FUN_B, ' old_ivid := ' || record_name || '.ivid;'); add_line(CPY_FUN_B, ' new_irid := jr_copy.get_new_irid(' || record_name || '.irid);'); add_line(CPY_FUN_B, ' new_ivid := jr_copy.get_new_ivid(' || record_name || '.ivid);'); add_line(CPY_FUN_B, ' insert into ' || table_name); add_line(CPY_FUN_B, ' values ('); -- TODO : if IRID is pk column then add_line(CPY_FUN_B, ' new_irid'); add_line(CPY_FUN_B, ' ,new_ivid'); -- B2021170 CW - 10-Dec-2001 if table_name = RELATIONSHIP_ENDS_TABLE then add_line(CPY_FUN_B, ' ,decode(' || record_name || '.TO_ENTITY_REF, SDD_ENT_old_irid' || ', jr_copy.get_new_irid(' || record_name || '.pac_ref)' || ', jr_copy.get_new_irid(new_pac_ref))'); add_line(CPY_FUN_B, ' ,decode(' || record_name || '.TO_ENTITY_REF, SDD_ENT_old_irid' || ', jr_copy.get_new_ivid(' || record_name || '.parent_ivid)' || ', jr_copy.get_new_ivid(new_parent_ivid))'); else add_line(CPY_FUN_B, ' ,new_pac_ref'); add_line(CPY_FUN_B, ' ,new_parent_ivid'); end if; if table_prefix = 'l$' then -- nls table add_line(CPY_FUN_B, ' ,' || record_name || '.lid'); add_line(CPY_FUN_B, ' ,' || record_name || '.slid'); end if; for owned_col_rec in jr_rm_cur.col_cur (table_irid, table_ivid) loop if owned_col_rec.column_name = 'PAC_REF' or owned_col_rec.column_name = 'PARENT_IVID' then null; -- 'Special' columns already added in processing above, ignore them here elsif table_name = FOLDER_MEMBERS_TABLE and owned_col_rec.column_name = OWNERSHIP_FLAG_COLUMN then -- When a Folder is copied, its folder members are copied (but not the objects in the folder) -- Only one folder member can be owning, so any new ones must be non-owning add_line(CPY_FUN_B, ' ,' || '''N''' || ' -- ' || owned_col_rec.column_name); elsif (table_name = RELATIONSHIP_ENDS_TABLE and owned_col_rec.column_name = OTHER_RELEND_REF_COLUMN) or(table_name = EXTENDED_STUCT_ELS_TABLE and owned_col_rec.column_name = PART_OF_REF_COLUMN) or(table_name = MAPPING_ELEMENTS_TABLE and owned_col_rec.column_name = SOURCE_CIELEMENT_COLUMN) or(table_name = MAPPING_ELEMENTS_TABLE and owned_col_rec.column_name = TARGET_CIELEMENT_COLUMN) or(owned_col_rec.column_name = CIELEMENT_REF_COLUMN) or(owned_col_rec.column_name = ELEMENT_REF_COLUMN) then -- sdd_relend.other_relationship_end_ref is a column for a reference property but is not in a -- foreign key. -- Columns for reference properties to generic element types (such as CIELEMENT_REF) are not -- in a foreign key. -- Look up its old value to see if it has been re-mapped add_line(CPY_FUN_B, ' ,jr_copy.get_new_irid(' || record_name || '.' || owned_col_rec.column_name || ')'); elsif jr_meta.is_fk_column(owned_col_rec.column_name, table_irid, table_ivid) then -- Column is in a foreign key -- Look up its old value to see if it has been re-mapped add_line(CPY_FUN_B, ' ,jr_copy.get_new_irid(' || record_name || '.' || owned_col_rec.column_name || ')'); else -- Just copy the previous value add_line(CPY_FUN_B, ' ,' || record_name || '.' || owned_col_rec.column_name); end if; end loop; -- Columns add_line(CPY_FUN_B, ' );'); if maintain_dependent_objects then -- Copy dependent objects with no ofk (eg. preferences, applog) *and* text add_line(CPY_FUN_B, ' jr_reg_ver.cpycopy_dependent_objects(old_irid, old_parent_ivid, new_irid, new_pac_ref, new_parent_ivid);'); end if; -- Copy dependencies add_line(CPY_FUN_B, ' jr_reg_ver.cpycopy_dependencies(old_irid, old_ivid, new_irid, new_ivid, new_parent_ivid, cpycopy_deps_policy);'); add_line(CPY_FUN_B, ' jr_copy.set_copied(' || record_name || '.irid);'); add_line(CPY_FUN_B, ' end if; -- not copied'); end if; -- Pass 1 or 2 -- Now copy types owned by this type... copy_owned_types ( leaf_types_rec.irid , leaf_types_rec.ivid , old_owned_pk_col , i_pass_number , cpycopy_deps_policy , true -- a recursive call , i_cursor_index ); if i_pass_number = 1 then comment_str := '-- End populate id mappings for ' || type_name || ' via ' || linkprop_name; else comment_str := '-- End copy ' || type_name || ' via ' || linkprop_name; end if; add_line(CPY_FUN_B, ' end loop; ' || comment_str); if i_pass_number = 2 and not recursive_call then -- Execute block to do copy add_line(CPY_FUN_B, 'end;'); exec_copy_stmt; end if; end loop; -- owned subtypes end loop; -- owning associations exception when NO_DATA_FOUND then -- Just return when a table owns no others null; end copy_owned_types; ------------------------------------------------------------------------------ -- Procedure : copy_object -- -- Copies the specified object itself (but not any of its children, or -- associated dependencies, text etc- they are copied using copy_owned_types). ------------------------------------------------------------------------------ procedure copy_object ( curr_object_irid in number , curr_object_ivid in number , new_object_irid in number , new_object_ivid in number , elem_type_id in number ) is table_name varchar2(30); table_prefix varchar2(2); table_type varchar2(1); table_irid number; table_ivid number; maintain_dependent_objects boolean; constraints_mode jr_context.constraints_mode; begin put_line('Executing copy_object...'); init_copy_stmt; --Initialize variables used to store generated PL/SQL --Get hold of info on table for element type jr_meta.get_table ( elem_type_id , table_irid , table_ivid , table_name , table_type , table_prefix , maintain_dependent_objects ); -- Defer constraints as we may not be copying in the correct order -- Remember the current constraints mode constraints_mode := jr_context.constraints; jr_context.set_constraints(jr_context.CONSTRAINTS_DEFERRED); -- Build up PL/SQL block to perform copy add_line(CPY_FUN_B,'declare'); add_line(CPY_FUN_B,' old_irid number;'); add_line(CPY_FUN_B,' old_ivid number;'); add_line(CPY_FUN_B,' new_irid number;'); add_line(CPY_FUN_B,' new_ivid number;'); if table_type != 'P' then --Secondary/optional primary objects add_line(CPY_FUN_B,' new_pac_ref number;'); add_line(CPY_FUN_B,' new_parent_ivid number;'); end if; add_line(CPY_FUN_B,' cursor get_original is'); add_line(CPY_FUN_B,' select * '); add_line(CPY_FUN_B,' from '||table_prefix||table_name||' the_tab'); add_line(CPY_FUN_B,' where the_tab.ivid=old_ivid;'); add_line(CPY_FUN_B,' begin'); add_line(CPY_FUN_B,' old_ivid:='||curr_object_ivid||';'); add_line(CPY_FUN_B,' for org in get_original loop'); add_line(CPY_FUN_B,' if not jr_copy.is_copied(org.irid) then'); add_line(CPY_FUN_B,' old_irid := org.irid; '); add_line(CPY_FUN_B,' new_irid := jr_copy.get_new_irid(old_irid);'); add_line(CPY_FUN_B,' new_ivid := jr_copy.get_new_ivid(old_ivid);'); if table_type != 'P' then --Secondary/optional primary objects add_line(CPY_FUN_B,' new_pac_ref := jr_copy.get_new_irid(org.pac_ref);'); if copying_within_same_object then -- Let trigger determine correct parent_ivid value add_line(CPY_FUN_B,' new_parent_ivid := null;'); else add_line(CPY_FUN_B,' new_parent_ivid := jr_copy.get_new_ivid(org.parent_ivid);'); end if; end if; add_line(CPY_FUN_B,' insert into '||table_name); add_line(CPY_FUN_B,' values ('); add_line(CPY_FUN_B,' new_irid --irid'); add_line(CPY_FUN_B,' ,new_ivid --ivid'); if table_type != 'P' then --Secondary/optional primary objects add_line(CPY_FUN_B,' ,new_pac_ref --pac_ref'); add_line(CPY_FUN_B,' ,new_parent_ivid --parent_ivid'); end if; if table_prefix = 'l$' then -- nls table add_line(CPY_FUN_B,' ,org.lid'); add_line(CPY_FUN_B,' ,org.slid'); end if; --Get the columns belonging to the table for col_rec in jr_rm_cur.col_cur (table_irid, table_ivid) loop if col_rec.column_name = 'PAC_REF' or col_rec.column_name = 'PARENT_IVID' then null; -- 'Special' columns already added in processing above, ignore them here elsif table_name = RELATIONSHIP_ENDS_TABLE and col_rec.column_name = OTHER_RELEND_REF_COLUMN then -- sdd_relend.other_relationship_end_ref is a column for a reference property but is not in a -- foreign key. -- Look up its old value to see if it has been re-mapped add_line(CPY_FUN_B,' ,jr_copy.get_new_irid(org.'||col_rec.column_name||')'); elsif jr_meta.is_fk_column(col_rec.column_name,table_irid,table_ivid) then -- Column is in a foreign key -- Look up its old value to see if it has been re-mapped add_line(CPY_FUN_B,' ,jr_copy.get_new_irid(org.'||col_rec.column_name||')'); else -- Just copy the previous value add_line(CPY_FUN_B, ' ,org.'||col_rec.column_name); end if; end loop; -- Columns add_line(CPY_FUN_B,' );'); add_line(CPY_FUN_B,' jr_copy.set_copied(old_irid);'); add_line(CPY_FUN_B,' end if;'); add_line(CPY_FUN_B,' end loop;'); add_line(CPY_FUN_B,' end;'); --Now execute the PL/SQL - this will copy the element, --remapping any reference properties where appropriate. --Its children and any associated text etc. is not copied. exec_copy_stmt; -- Reset the constraints mode jr_context.set_constraints(constraints_mode); end copy_object; ------------------------------------------------------------------------------ -- Procedure : update_object -- -- Updates any reference properties on the specified object to the values -- specified in the mapping set (but not any of its children, or -- associated dependencies, text etc- they are copied using copy_owned_types). ------------------------------------------------------------------------------ procedure update_object ( curr_object_irid in number , curr_object_ivid in number , new_object_irid in number , new_object_ivid in number , elem_type_id in number ) is table_name varchar2(30); table_prefix varchar2(2); table_type varchar2(1); table_irid number; table_ivid number; maintain_dependent_objects boolean; bHasRefProp boolean; constraints_mode jr_context.constraints_mode; begin put_line('Executing update_object...'); init_copy_stmt; --Initialize variables used to store generated PL/SQL --Get hold of info on table for element type jr_meta.get_table ( elem_type_id , table_irid , table_ivid , table_name , table_type , table_prefix , maintain_dependent_objects ); -- Defer constraints as we may not be copying in the correct order -- Remember the current constraints mode constraints_mode := jr_context.constraints; jr_context.set_constraints(jr_context.CONSTRAINTS_DEFERRED); --Build up PL/SQL block to perform copy add_line(CPY_FUN_B,'declare'); add_line(CPY_FUN_B,' old_irid number;'); add_line(CPY_FUN_B,' old_ivid number;'); add_line(CPY_FUN_B,' new_irid number;'); add_line(CPY_FUN_B,' new_ivid number;'); if table_type != 'P' then --Secondary/optional primary objects add_line(CPY_FUN_B,' new_pac_ref number;'); add_line(CPY_FUN_B,' new_parent_ivid number;'); end if; add_line(CPY_FUN_B,' cursor get_original is'); add_line(CPY_FUN_B,' select * '); add_line(CPY_FUN_B,' from '||table_prefix||table_name||' the_tab'); add_line(CPY_FUN_B,' where the_tab.ivid=old_ivid;'); add_line(CPY_FUN_B,'begin'); add_line(CPY_FUN_B,' old_ivid:='||curr_object_ivid||';'); add_line(CPY_FUN_B,' for org in get_original loop'); add_line(CPY_FUN_B,' old_irid := org.irid; '); add_line(CPY_FUN_B,' new_irid := jr_copy.get_new_irid(old_irid);'); add_line(CPY_FUN_B,' new_ivid := jr_copy.get_new_ivid(old_ivid);'); if table_type != 'P' then --Secondary/optional primary objects add_line(CPY_FUN_B,' new_pac_ref := jr_copy.get_new_irid(org.pac_ref);'); add_line(CPY_FUN_B,' new_parent_ivid := jr_copy.get_new_ivid(org.parent_ivid);'); end if; add_line(CPY_FUN_B,' update '||table_name||' cpy'); add_line(CPY_FUN_B,' set'); add_line(CPY_FUN_B,' '); if table_type != 'P' then --Secondary/optional primary objects add_line(CPY_FUN_B,' cpy.PAC_REF=new_pac_ref --pac_ref'); add_line(CPY_FUN_B,' ,cpy.PARENT_IVID=new_parent_ivid --parent_ivid'); bHasRefProp :=TRUE; end if; --Get the columns belonging to the table for col_rec in jr_rm_cur.col_cur (table_irid, table_ivid) loop if col_rec.column_name = 'PAC_REF' or col_rec.column_name = 'PARENT_IVID' then null; -- 'Special' columns already added in processing above, ignore them here elsif table_name = RELATIONSHIP_ENDS_TABLE and col_rec.column_name = OTHER_RELEND_REF_COLUMN then -- sdd_relend.other_relationship_end_ref is a column for a reference property but is not in a -- foreign key. -- Look up its old value to see if it has been re-mapped if (bHasRefProp) then add_line(CPY_FUN_B,' ,cpy.'||col_rec.column_name||'=jr_copy.get_new_irid(org.'||col_rec.column_name||')'); else add_line(CPY_FUN_B,' cpy.'||col_rec.column_name||'=jr_copy.get_new_irid(org.'||col_rec.column_name||')'); bHasRefProp:=TRUE; end if; elsif jr_meta.is_fk_column(col_rec.column_name,table_irid,table_ivid) then -- Column is in a foreign key -- Look up its old value to see if it has been re-mapped if (bHasRefProp) then add_line(CPY_FUN_B,' ,cpy.'||col_rec.column_name||'=jr_copy.get_new_irid(org.'||col_rec.column_name||')'); else add_line(CPY_FUN_B,' cpy.'||col_rec.column_name||'=jr_copy.get_new_irid(org.'||col_rec.column_name||')'); bHasRefProp:=TRUE; end if; end if; end loop; -- Columns add_line(CPY_FUN_B,' where cpy.ivid=new_ivid;'); add_line(CPY_FUN_B,' end loop;'); add_line(CPY_FUN_B,' end;'); --Now execute the PL/SQL - this will update any ref props of the element, --remapping to the new values (if any) in the reference set. if bHasRefProp then exec_copy_stmt; end if; -- Reset the constraints mode jr_context.set_constraints(constraints_mode); end update_object; ----------------------------------------------------------------------------------- -- *** Public method definitions *** ----------------------------------------------------------------------------------- ------------------------------------------------------------------------------ -- Procedure : setup_id_mappings -- -- Pre-populate the id mappings table with an element an all its -- children. May be called from COPY itself, or by a user prior -- to calling COPY on an element (eg, if copying an element as part -- of a set). The id mappings table IS NOT CLEARED prior to population, -- in order to allow multiple calls. The user MUST clear the table -- themselves using jr_copy.init_id_mappings ------------------------------------------------------------------------------ procedure setup_id_mappings ( curr_object_irid in number , curr_object_ivid in number , new_object_irid in out number , new_object_ivid in out number , curr_object_types number default null , copy_deep boolean default true ) is element_type_irid number; curr_pac_ref number; curr_parent_ivid number; cursor_index pls_integer; table_name varchar2(30); old_owner_pk_col varchar2(40); begin put_line('Executing setup_id_mappings...'); init_copy_stmt; --Initialize variables used to store generated PL/SQL -- Assign ids for new object, if not supplied if new_object_irid is null then new_object_irid := jr_util.get_new_irid; end if; if new_object_ivid is null then new_object_ivid := jr_system_util.get_new_ivid; end if; jr_copy.populate_id_mappings ( curr_object_irid , curr_object_ivid , new_object_irid , new_object_ivid ); if new_object_irid = curr_object_irid then copying_within_same_object := true; else copying_within_same_object := false; end if; if not copy_deep then --If we're not doing a deep copy, then we only need to put the --element itself into the mapping set - can now return... return; end if; --We're doing a deep copy - we now need to add entries into the id mappings --table for all the children of the element. if curr_object_types is null then -- Don't know what type of object is being added to mapping set, -- so query object versions. MUST specify object type for secondary -- objects. begin select ov.logical_type_id into element_type_irid from i$sdd_object_versions ov where ov.ivid = curr_object_ivid ; exception when NO_DATA_FOUND then -- TODO : use errror stack put_line('Attempting to copy a non-versionable object, *must* specify element type explicitly'); raise; end; else element_type_irid:=curr_object_types; end if; --Get table name for element type select tab.table_name into table_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 = element_type_irid ; old_owner_pk_col := table_name || '_old_irid'; --Get hold of pac ref and parent ivid for current object jr_reg_ver.populate_parent_info_by_ivid ( curr_object_ivid , element_type_irid , curr_pac_ref , curr_parent_ivid ); put_line(get_time() || ' : Started building plsql to populate id mappings'); -- Can now build anonymous PL/SQL block add_line(CPY_FUN_A, 'declare'); add_line(CPY_FUN_A, ' old_parent_ivid number;'); add_line(CPY_FUN_A, ' '|| old_owner_pk_col || ' number;'); add_line(CPY_FUN_B, 'begin'); add_line(CPY_FUN_B, ' old_parent_ivid := ' || curr_parent_ivid || ';'); add_line(CPY_FUN_B, ' ' || old_owner_pk_col || ' := ' || curr_object_irid || ';'); --Copy_owned types will add code for all children of the element cursor_index := 0; copy_owned_types ( element_type_irid , 1 -- element type ivid, always 1 at the moment , old_owner_pk_col , 1 -- Pass 1 sets up ID mappings , null -- cpycopy_deps_policy not used in pass 1 , false -- not a recursive call , cursor_index ); add_line(CPY_FUN_B, 'end;'); put_line(get_time() || ' : Finished building plsql to populate id mappings'); put_line(get_time() || ' : Started executing plsql to populate id mappings'); -- Now execute the PL/SQL - this will populate the id mappings table for all children exec_copy_stmt; put_line(get_time() || ' : Finished executing plsql to populate id mappings'); end setup_id_mappings; --------------------------------------------------------------------------------- -- Procedure : copy -- -- Copy an element and optionally copy all its owned objects -- -- CW 27-Mar-2000 -- Fix bug 1247864, preserve irids of elements when copy is used to merge -- elements from one version of an object to another version of the same object -- This is so that (as far as diff is concerned) the copied elements in one -- version of the pac are the same as in another version of the pac. -- Note, the code is going to *assume* that : -- if curr_object_irid = new_object_irid then -- preserve *all* irid values of all elements owned by the element being copied --------------------------------------------------------------------------------- procedure copy ( curr_object_irid number , curr_object_ivid number , new_object_irid in out number , new_object_ivid in out number , curr_object_types number default null , copy_deep boolean default true , copy_current_object boolean default true , cpycopy_deps_policy boolean default true , id_mappings_pre_populated boolean default false ) is element_type_irid number; table_irid number; table_ivid number; table_name varchar2(30); table_type varchar2(1); table_prefix varchar2(2); maintain_dependent_objects boolean; copy_deps varchar2(1); old_pac_ref number; old_owner_pk_col varchar2(40); cursor_index number := 0; mappings_pre_populated boolean := false; dummy varchar2(1); do_copy_deep boolean := copy_deep; constraints_mode jr_context.constraints_mode; begin if copy_current_object = false and new_object_irid = null then -- TODO : use errror stack return; -- Error, being asked to a deep copy for a new object which has not been supplied end if; if use_curr_id_mappings or id_mappings_pre_populated then mappings_pre_populated := true; end if; -- TODO : Call function in i$sdd_version_registry to copy element, if there is one, -- else generate a default copy routine here and execute it if curr_object_types is null then -- Don't know what type of object is being copied, query object versions -- Note, only copy of primary objects supported, unless using the cdapi, or -- copying and specifying the type of the object explicitly (as below) since -- there is nowhere that we can find the type of a secondary object, given -- only its irid, ivid begin select ov.logical_type_id into element_type_irid from i$sdd_object_versions ov where ov.ivid = curr_object_ivid; exception when NO_DATA_FOUND then -- TODO : use errror stack put_line('Attempting to copy a non-versionable object, *must* specify element type explicitly'); raise; end; else -- The element type is known. -- Note, it *must* be specified for copy of secondary objects since we cannot query object versions to work it out element_type_irid := curr_object_types; end if; put_line('ElementType irid is : ' || element_type_irid); -- Now we know the type of the element being copied, get its implementing table details jr_meta.get_table ( element_type_irid , table_irid , table_ivid , table_name , table_type , table_prefix , maintain_dependent_objects ); put_line('Object type is : ' || table_type); put_line('Table is : ' || table_name); -- If element type is a DIAGRAM, force deep copy // bug 1197943 if table_name = jr_meta.DIAGRAM_TABLE then do_copy_deep := true; end if; if not mappings_pre_populated then --Caller has not set up the ID mappings, so do that here init_id_mappings; setup_id_mappings( curr_object_irid , curr_object_ivid , new_object_irid , new_object_ivid , curr_object_types , do_copy_deep ); elsif ((new_object_irid is null) or (new_object_ivid is null)) then --Caller has set up ID mappings, but not given new irid/ivid values --Recover these from ID mappings. new_object_irid:=get_new_irid(curr_object_irid); new_object_ivid:=get_new_ivid(curr_object_ivid); end if; put_line('new_object_irid is : ' || new_object_irid); put_line('new_object_ivid is : ' || new_object_ivid); if (not copy_current_object) and mappings_pre_populated then --The current object has been copied by caller, but --we may need to remap some of it IDs update_object (curr_object_irid ,curr_object_ivid ,new_object_irid ,new_object_ivid ,element_type_irid); end if; if copy_current_object then --Copy the current object, not just its children copy_object (curr_object_irid ,curr_object_ivid ,new_object_irid ,new_object_ivid ,element_type_irid); end if; -- Current object is now copied (by caller or by this method) -- Fix bug 993715 copy across audit columns on object versions, if primary object -- -- B3296706 : Bug 993715 seems to be about maintaining the NOTM columns. It doesn't mention the date_created, -- date_changed, created_by or changed_by columns so I don't know why they are included here. -- It also implies that the maintenance is only required when a new version is created, not -- a new object, as in the case of copying an object : -- 1.1) For new objects (new IRID), OBJ_NOTM should be set to the notm the object is created with. -- To fix 3296706, I'm adding a check to ensure that this code is only executed if the IRID of the -- original object and new object are the same, i.e. a new version rather than a new object is being -- created. -- if ( (table_type = 'P' or table_type = 'O') and curr_object_irid = new_object_irid ) then if cpycopy_deps_policy then copy_deps := 'Y'; else copy_deps := 'N'; end if; -- Primary object or optional primary/secondary object begin select null into dummy from i$sdd_object_versions old where old.ivid = curr_object_ivid ; -- If there is no row in object versions we will jump to the exception handler -- This can happen if we are copying the children of a specific MCO to a reusable MCO -- because the specific MCO has no row in object versions. -- In this scenario, the inner select below does not find a row and returns *nulls* to the -- outer update, which then fails. -- Hence the select was added above to detect whether or not there is an old version update i$sdd_object_versions set (notm, obj_notm, date_created, created_by, date_changed, changed_by, obj_notm_when_analyzed) = (select old.notm , old.obj_notm , old.date_created , old.created_by , old.date_changed , old.changed_by , decode( copy_deps , 'Y', old.obj_notm_when_analyzed , null ) from i$sdd_object_versions old where old.ivid = curr_object_ivid ) where ivid = new_object_ivid ; exception -- If the object is optional primary/secondary and the instance is actually secondary then there -- will be no row in object versions when NO_DATA_FOUND then if table_type = 'O' then null; else raise; end if; end; end if; -- Need to determine pac_ref and parent_ivid values for text or child tables to be copied jr_reg_ver.populate_parent_info_by_ivid ( curr_object_ivid , element_type_irid , old_pac_ref , old_parent_ivid ); put_line('old_pac_ref : ' || old_pac_ref); put_line('old_parent_ivid : ' || old_parent_ivid); jr_reg_ver.populate_parent_info_by_ivid ( new_object_ivid , element_type_irid , new_pac_ref , new_parent_ivid ); put_line('new_pac_ref : ' || new_pac_ref); put_line('new_parent_ivid : ' || new_parent_ivid); -- Fix bug 1272572, pac_ref not set correctly when copying a secondary object jr_copy.populate_id_mappings ( old_pac_ref , old_parent_ivid , new_pac_ref , new_parent_ivid ); put_line(get_time() || ' : Started executing copy...'); -- Defer constraints as we may not be copying in the correct order -- Remember the current constraints mode constraints_mode := jr_context.constraints; jr_context.set_constraints(jr_context.CONSTRAINTS_DEFERRED); -- Copy text (regardless of deep copy or not) jr_reg_ver.cpycopy_text(curr_object_irid, old_parent_ivid, new_object_irid, new_pac_ref, new_parent_ivid); if do_copy_deep then if maintain_dependent_objects then -- Copy dependent objects with no ofk (eg. preferences, applog), but *not* text as already done above (regardless of deep copy) if table_type = 'P' or table_type = 'O' then -- parent_ivid not applicable jr_reg_ver.cpycopy_dependent_objects(curr_object_irid, old_parent_ivid, new_object_irid, new_pac_ref, null, false); else jr_reg_ver.cpycopy_dependent_objects(curr_object_irid, old_parent_ivid, new_object_irid, new_pac_ref, new_parent_ivid, false); end if; end if; -- Copy dependencies jr_reg_ver.cpycopy_dependencies(curr_object_irid, curr_object_ivid, new_object_irid, new_object_ivid, new_parent_ivid, cpycopy_deps_policy); -- eg. if copying an Entity, SDD_ENT_old_irid, SDD_ENT_new_irid -- Note, this is hardcoded and will only work for Designer elements -- TODO : remove this restriction old_owner_pk_col := table_name || '_old_irid'; old_object_irid := curr_object_irid; -- Call recursive method to copy all owned objects -- (previously called this with pass set to 1 to generate id mappings cursor_index := 0; copy_owned_types ( element_type_irid , 1 -- element type ivid, always 1 at the moment , old_owner_pk_col , 2 -- Pass 2 actually writes the copy PL/SQL , cpycopy_deps_policy , false -- not a recursive call , cursor_index ); end if; -- Reset the constraints mode jr_context.set_constraints(constraints_mode); put_line(get_time() || ' : Finished executing copy operation'); exception when OTHERS then -- If copy failed, ensure we set use_curr_id_mappings to FALSE use_curr_id_mappings := false; raise; end copy; -- Package instantiation begin id_mappings := id_mapping_list(); id_mappings_idx := 0; use_curr_id_mappings := false; end jr_copy; /