Blame | Last modification | View Log | RSS feed
######################################################################### COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.## Module name : rmMerge_suck.pl# Module type : JATS Utility# Compiler(s) : Perl# Environment(s): jats## Description : Insert Extacted package-version data into a different RM instance# This version will simply insert the files and folders data# Kludgy scipt used because this datat was missing on the origibnal placekeeps## Usage : See POD at the end of this file##......................................................................#require 5.008_002;use strict;use warnings;use Pod::Usage;use Getopt::Long;use JatsError;use JatsRmApi;use JatsSystem;use FileUtils;use ConfigurationFile;use File::Copy;use DBI;my $RM_DB;my $VERSION = "1.0";my @testRMCred = ('TST', 'jdbc:oracle:thin:@relmanu3.coidtfba5ouc.ap-southeast-2.rds.amazonaws.com:1521:relmanu3', 'RELEASE_MANAGER', 'MPM0$U74');my @oldRMCred = ('OLD', 'jdbc:oracle:thin:@auawsards001:1521:RELEASEM', 'RELEASE_MANAGER', 'ske2k0se');my @useRmCred;my $defaultRtagId = 6883; # Used when an RRTAG_ID cannot be translatedmy $defaultRtagIdText = 'CORE Software Product Line'; # Could look it up, but ...my $opt_reuse=1;my $opt_help=0;my $opt_verbose=0;my $opt_debug=0;my $opt_live = 1;my $opt_previous = '';my $opt_placeKeeper;my $opt_history = 1;my $opt_toHistory;my $opt_infile;my $opt_newPackage;my $pname;my $pversion;my $pvid;our %rmData;my %keyFieldsData;my %buildIdMap;my @historySummary;my @historyShortSummary;my $nonRipple;#-------------------------------------------------------------------------------# Function : Mainline Entry Point## Description :## Inputs :#my $result = GetOptions ("help:+" => \$opt_help,"manual:3" => \$opt_help,"verbose:+" => \$opt_verbose,"debug:+" => \$opt_debug,"previous:s" => \$opt_previous,"live!" => \$opt_live,"placekeeper!" => \$opt_placeKeeper,"history!" => \$opt_history,"toHistory:s" => \$opt_toHistory,"infile:s" => \$opt_infile,"newPackage" => \$opt_newPackage,);## UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!### Process help and manual options#pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);pod2usage(-verbose => 1) if ( $opt_help == 2 );pod2usage(-verbose => 2) if ( $opt_help > 2 );pod2usage(-verbose => 0, -message => "Version: $VERSION") if ( $#ARGV < 0 );## Configure the error reporting rmMerge_process now that we have the user options#ErrorConfig( 'name' =>'SPIT','verbose' => $opt_verbose,'debug' => $opt_debug,);## Allow comma delemited args$pname = $ARGV[0];if ($pname =~ m~^(.*),(.*)$~) {$pname = $1;$pversion = $2;} else {$pversion = $ARGV[1];}if ($opt_live) {Message("Using Live Database");@useRmCred = @oldRMCred;} else {@useRmCred = @testRMCred;}# Generate the output filename#$opt_infile = join('.', $pname, $pversion, 'rminfo', 'txt') unless $opt_infile;my $localDataStore = "migrate/log/" . $opt_infile;$ENV{GBE_RM_LOCATION} = $useRmCred[1];$ENV{GBE_RM_USERNAME} = $useRmCred[2];$ENV{GBE_RM_PASSWORD} = $useRmCred[3];connectRM(\$RM_DB) unless ( $RM_DB );Message("Insert Release Components for: $pname $pversion");$pvid = GetPvid();Error ("Package Version NOT found: $pname $pversion") unless defined $pvid;## Get the data saved by rmMerge_suck#restoreLocalData();# Check for any existing Release Commponents# This script is only for use in adding data that was missing - thus there should not be any#my $count = CheckReleaseComponents();if ($count) {Message("Package already has released components - ignored");exit 0;}## Potentially massage the data a bit#MassagePlaceKeeper();MassagePreviousPackageVersion();FudgeRtagId();## PV_ID in the origin#my $pvidOrigin = $rmData{METADATA}{PV_ID};$keyFieldsData{PV_ID}{$pvidOrigin} = $pvid;## Generate Cross reference information for the various tables# Need to have all the cross references in place first#GetXrefsUsers(qw(CREATOR_ID MODIFIER_ID OWNER_ID USER_ID));GetXrefsPvid(qw(PV_ID LAST_PV_ID DPV_ID));GetXrefsPkg(qw(PKG_ID DPKG_ID ));GetXrefsActType(qw( ACTTYPE_ID ));GetXrefsRtagId(qw( RTAG_ID ));GetXrefsLicence(qw( LICENCE ));ErrorDoExit();#GetXrefsIgnore(qw( TEST_ID TESTRUN_ID DOC_ID BUILD_ID)); # Primary keys - ignore#GetXrefsIgnore(qw( BE_ID BM_ID BSA_ID BS_ID VCS_TYPE_ID)); # Assume these have not changed## Now insert data into tables in the target database# Need to MAP some fields#CreatePackageData('RELEASE_COMPONENTS');disconnectRM(\$RM_DB);#DebugDumpData("keyFieldsData",\%keyFieldsData);exit 0;#-------------------------------------------------------------------------------# Function : CheckReleaseComponents## Description : See if the package already has released components## Inputs :## Returns : Number of components#sub CheckReleaseComponents{my @row = GetOneSqlRow("select count(*) from release_components where pv_id = $pvid");return $row[0];}#-------------------------------------------------------------------------------# Function : MassagePlaceKeeper## Description : Massage the data for creation of a place keeper## Inputs :#;# Returns :#sub MassagePlaceKeeper{Message("Generate Place Keeper Package Version");# Empty the a few tablesdelete $rmData{ACTION_LOG_DATA};delete $rmData{PACKAGE_DEPENDENCIES_DATA};delete $rmData{PACKAGE_METRICS_DATA};#delete $rmData{RELEASE_COMPONENTS_DATA};delete $rmData{BUILD_INSTANCES_DATA};delete $rmData{UNIT_TESTS_DATA};delete $rmData{TEST_RUN_DATA};delete $rmData{ACTION_LOG_XREF};delete $rmData{PACKAGE_DEPENDENCIES_XREF};delete $rmData{PACKAGE_METRICS_XREF};#delete $rmData{RELEASE_COMPONENTS_XREF};delete $rmData{BUILD_INSTANCES_XREF};delete $rmData{UNIT_TESTS_XREF};delete $rmData{TEST_RUN_XREF};}#-------------------------------------------------------------------------------# Function : MassagePreviousPackageVersion## Description : The previous package version may not exist in the target# release manager## Allow the user to specify the previous package version# The point at which the package will be inserted## Inputs :## Returns :#sub MassagePreviousPackageVersion{my $pvData = $rmData{PACKAGE_VERSIONS_DATA};my $pvMetaData = $rmData{PACKAGE_VERSIONS_NAMES};my $idxPrevVer;my $prevPvid;## Find the 'LAST_PV_ID' index#foreach ( @{$pvMetaData} ) {next unless $_->[0] eq 'LAST_PV_ID';$idxPrevVer = $_->[3] - 1;last;}Error ("Internal: Cannot find index of the LAST_PV_ID field") unless defined $idxPrevVer;$prevPvid = $pvData->[0][$idxPrevVer];Message("Previous version was:" . $prevPvid);## Fudge the 'XREF_PV_ID' entry#Error("No 'XREF_PV_ID' entry for previous version") unless exists $rmData{PACKAGE_VERSIONS_XREF}{PV_ID}{$prevPvid};delete $rmData{PACKAGE_VERSIONS_XREF}{PV_ID}{$prevPvid};$pvData->[0][$idxPrevVer] = '';}#-------------------------------------------------------------------------------# Function : FudgeRtagId## Description : Ensure that the $defaultRtagId is in the RTAG lookup tables# Only used in BUILD_INSTANCES# Could 'look' for all occurences## Inputs :## Returns :#sub FudgeRtagId{my $entry = $rmData{BUILD_INSTANCES_XREF};return unless $entry;$entry = $entry->{RTAG_ID};if ($entry) {unless (exists $entry->{$defaultRtagId}) {$entry->{$defaultRtagId} = $defaultRtagIdText;}} else {Warning ("FudgeRtagId - cannot find expected table - BUILD_INSTANCES_XREF:RTAG_ID","Possibly NULL rtagId");}}#-------------------------------------------------------------------------------# Function : getIndex## Description : Get the index of a data item from specified meta data## Inputs : $table - Name of table to access# $field - Name of field to locate## Returns : Will generte an error if not found#sub getIndex{my ($table,$field) = @_;my $rv;my $tableName = $table . "_NAMES";Error ("Internal: getIndex. Metadata not found for: $table") unless exists $rmData{$tableName};my $pvMetaData = $rmData{$tableName};foreach ( @{$pvMetaData} ) {next unless $_->[0] eq $field;$rv = $_->[3] - 1;last;}Error("Internal: getIndex. Cannot find metadata for field($field) in table($table)") unless $rv;return $rv;}#-------------------------------------------------------------------------------# Function : GetNextSeqNum## Description : Get the next sequence numbber froom a named sequence## Inputs : $seqName## Returns : A number#sub GetNextSeqNum{my ($seqName) = @_;my @row = GetOneSqlRow("SELECT $seqName.NEXTVAL from DUAL");#Debug0("Generate $seqName: $row[0]");return $row[0];}#-------------------------------------------------------------------------------# Function : CreatePackageData## Description : Insert one or more rows into a table# Assumes no data massaging needs to be done## Inputs : $tableName - Not sure it will be used## Returns :#sub CreatePackageData{my ($tableName) = @_;my $tableData = $tableName. '_DATA';Message("Processing: $tableName");## Get one row of data and massage it into a form suitable for insertion#foreach my $data (@{$rmData{$tableData}}) {InsertTableRow($tableName, $data);}}#-------------------------------------------------------------------------------# Function : InsertTableRow## Description : Insert a row into a table## Inputs : $tableName# $data - Ref to data# $metaData - REf to meta data# $callBacks - Hash of FieldNames, functions## Returns :#sub InsertTableRow{my ($tableName, $data, $callBacks) = @_;my $tableMetaData = $tableName. '_NAMES';my $metaData = $rmData{$tableMetaData};my @insertFields;my @insertValues;## Scan the metadata and fiddle the data#foreach my $entry ( @$metaData) {my $fname = $entry->[0];my $ftype = $entry->[1];my $isNullable = $entry->[2] eq 'Y';my $findex = $entry->[3]-1;my $value = $data->[$findex] || '';# Does this field need to be mappedif ($value ne '') {if (exists $rmData{XREF_MAP}{$fname}) {my $mapTable = $rmData{XREF_MAP}{$fname};Error ("Mapping table not found: $mapTable","Need: $value") unless exists $keyFieldsData{$mapTable};unless (exists $keyFieldsData{$mapTable}{$value}) {DebugDumpData("keyFieldsData",\%keyFieldsData);DebugDumpData("Data",$data);Error ("Mapping value not found: $mapTable, $value, while rmMerge_processing $tableName, $fname") ;}my $newValue = $keyFieldsData{$mapTable}{$value};unless (defined $newValue) {DebugDumpData("keyFieldsData",\%keyFieldsData);DebugDumpData("Data",$data);Error("Undefined map for: $tableName, $fname, $value");}if ($newValue ne $value) {Verbose("Mapping $tableName:$mapTable:$fname:$value -> $newValue");$value = $newValue;}}}## Does the field need to be massaged#if (defined $callBacks && $callBacks->{$fname}) {my $newValue = $callBacks->{$fname}->($fname, $value);if ($newValue ne $value) {Verbose("Massage $tableName:$fname:$value -> $newValue");$value = $newValue;}}## Does the field need to be quoted# Assume that the 'suck' rmMerge_process has quoted special characters# %0D -> return# %0A -> newLine# %09 -> Tab# %25 -> As a percent# %27 -> Single Quote# Also need to handle a single quote char#if ($ftype =~ m~CHAR|VARCHAR~) {$value =~ s~'~'||chr(39)||'~g;$value =~ s~%0D~'||chr(13)||'~g;$value =~ s~%0A~'||chr(10)||'~g;$value =~ s~%09~'||chr(9)||'~g;$value =~ s~%27~'||chr(39)||'~g;$value =~ s~%25~%~g;$value = "'" . $value . "'";#print("String Length ($fname):", length($value),"\n");} elsif ($ftype =~ m~DATE|TIMESTAMP~) {$value = "TO_TIMESTAMP('$value','YYYY-MM-DD HH24:MI:SS.FF')"}# Null item if we are allowed toif ($isNullable && length($value) <= 0) {$value = 'null';}push @insertFields, $fname;push @insertValues, $value;}## Generate the SQL#my $m_sqlstr = "insert into $tableName (" . join(',', @insertFields) . ")" . " VALUES (". join(',', @insertValues) .")";Debug("$m_sqlstr");my $sth = $RM_DB->prepare($m_sqlstr);my @row;if ( defined($sth) ){if ( $sth->execute( ) ){if ( $sth->rows ){while ( @row = $sth->fetchrow_array ){print("@row\n");}}$sth->finish();}else{Error("Execute failure: $m_sqlstr", $sth->errstr() );}}else{Error("Prepare failure" );}}#-------------------------------------------------------------------------------# Function : GetXrefCommon## Description : Common code for fetch XREF data from the database## Inputs : $name - Tag name# $sql - sql fragment to do the work# $options - Ref to a hack of options# 'default' - Value to use when not found## Returns :#sub GetXrefCommon{my ($name,$sql, $options) = @_;my (@fields) = @_;my %idList;my %data;$options = {} unless $options;## Generate a hash of items that we need#foreach my $tableName ( keys %rmData ) {next unless $tableName =~ m~_XREF$~;next unless exists $rmData{$tableName}{$name};foreach my $id (keys %{ $rmData{$tableName}{$name} }) {$idList{ $rmData{$tableName}{$name}{$id} } = $id;}}#DebugDumpData("GetXrefCommon, $name", \%idList);return unless %idList;## Get all the table data#my @row;my $m_sqlstr = $sql . " in (". quoteList(keys %idList) .")";#Debug0("GetXrefCommon: $m_sqlstr");my $sth = $RM_DB->prepare($m_sqlstr);if ( defined($sth) ){if ( $sth->execute( ) ){if ( $sth->rows ){while ( @row = $sth->fetchrow_array ){#print("GetXrefCommon: @row\n");$data{$row[1]} = $row[0];}}$sth->finish();}else{Error("Execute failure: $m_sqlstr", $sth->errstr() );}}else{Error("Prepare failure" );}## Check that all required values have been found#foreach my $id (keys %idList) {if (exists $data{$id}) {$keyFieldsData{$name}{$idList{$id}} = $data{$id};} elsif (defined $options->{default}) {$keyFieldsData{$name}{$idList{$id}} = $options->{default};} else {ReportError("No Crossref for $name matching: $id");#DebugDumpData("RmData", \%rmData);}}## Keep the raw data in the output hash - possibly for debugging purposes$keyFieldsData{$name . '_DEBUG'} = \%data;}#-------------------------------------------------------------------------------# Function : GetXrefsLicence## Description : Get cross references to other entites## Inputs : list of keyFieldData keys to rmMerge_process## Returns :#sub GetXrefsLicence{my (@fields) = @_;GetXrefCommon('LICENCE', 'select licence, name from release_manager.licences where name');}#-------------------------------------------------------------------------------# Function : GetXrefsRtagId## Description : Get cross references to other entites## Inputs : list of keyFieldData keys to rmMerge_process## Returns :#sub GetXrefsRtagId{my (@fields) = @_;GetXrefCommon('RTAG_ID', 'select rtag_id, rtag_name from release_tags where rtag_name', {default => $defaultRtagId});}#-------------------------------------------------------------------------------# Function : GetXrefsActType## Description : Get cross references to other entites## Inputs : list of keyFieldData keys to rmMerge_process## Returns :#sub GetXrefsActType{my (@fields) = @_;GetXrefCommon('ACT_TYPE', 'select acttype_id, name from release_manager.action_type where name');}#-------------------------------------------------------------------------------# Function : GetXrefsPkg## Description : Get cross references to other entites## Inputs : list of keyFieldData keys to rmMerge_process## Returns :#sub GetXrefsPkg{my (@fields) = @_;GetXrefCommon('PKG_ID', 'select p.pkg_id, p.pkg_name from release_manager.packages p where p.pkg_name');}#-------------------------------------------------------------------------------# Function : GetXrefsPvid## Description : Get cross references to other entites## Inputs : list of keyFieldData keys to rmMerge_process## Returns :#sub GetXrefsPvid{my (@fields) = @_;## Need to delete my PV_ID from the XREF tables 'PV_ID' tables# as I will never be found#foreach my $tableName ( keys %rmData ) {next unless $tableName =~ m~_XREF$~;next unless exists $rmData{$tableName}{PV_ID};delete $rmData{$tableName}{PV_ID}{$rmData{METADATA}{PV_ID}};}GetXrefCommon('PV_ID', "select pv.pv_id, p.pkg_name || '$;' ||pv.pkg_version from release_manager.packages p, release_manager.package_versions pv" ." where p.pkg_id = pv.pkg_id and p.pkg_name || '$;' || pv.pkg_version");}#-------------------------------------------------------------------------------# Function : GetXrefsUsers## Description : Get cross references to other entites## Inputs : list of keyFieldData keys to rmMerge_process## Returns :#sub GetXrefsUsers{my (@fields) = @_;GetXrefCommon('USER_ID', 'select user_id, user_name from access_manager.users where user_name');}#-------------------------------------------------------------------------------# Function : quoteList## Description : Convert an array of strings into a quoted comma-sep string# Used in sql of the form select ... in ( 'aaa','bbb',ccc')## Inputs : An array of strings## Returns : quoted comma-sep string#sub quoteList{my $rv = '';my $join = '';foreach (@_) {$rv .= $join . "'" . $_ . "'";$join = ',';}return $rv;}#-------------------------------------------------------------------------------# Function : GetOneSqlRow## Description : Execute a simple SQL statement and return to the user the first row of data## Inputs : $sql - statement to execute## Returns : And array of data#sub GetOneSqlRow{my ($m_sqlstr) = @_;#Debug0("GetOneSqlRow: $m_sqlstr");my (@row);my $sth = $RM_DB->prepare($m_sqlstr);if ( defined($sth) ) {if ( $sth->execute( ) ) {if ( $sth->rows ) {#Debug0("GetOneSqlRow: @row");@row = $sth->fetchrow_array;}$sth->finish();} else {Error("Execute failure: $m_sqlstr", $sth->errstr() );}} else {Error("Prepare failure" );}return @row;}#-------------------------------------------------------------------------------# Function : GetPvid## Description : Get the packages pvid## Inputs :## Returns : The pvid#sub GetPvid{my @row = GetOneSqlRow("select pv_id from packages p, package_versions pv where p.pkg_name = '$pname' and pv.pkg_version = '$pversion' and p.pkg_id = pv.pkg_id");return $row[0];}#-------------------------------------------------------------------------------# Function : saveLocalData## Description : Saves a hash of data to disk## Inputs :## Returns :#sub saveLocalData{## Dump out the configuration information#my $fh = ConfigurationFile::New( $localDataStore);$fh->DumpData( "\n# rmData\n#\n", "rmData", \%rmData );$fh->Close();DebugDumpData("rmData", \%rmData);}#-------------------------------------------------------------------------------# Function : restoreLocalData## Description : Read in the locally preserved data## Inputs :## Returns :#sub restoreLocalData{if (-f $localDataStore) {require ( $localDataStore );} else {Error ("Extracted data not found: $localDataStore");}}#-------------------------------------------------------------------------------# Documentation#=pod=for htmltoc GENERAL::ClearCase::=head1 NAMErmMerge_suck - Inject Package-Version info into RM from a previous extraction=head1 SYNOPSISjats rmMerge_spit [options] PackageName PackageVersionOptions:-help - brief help message-help -help - Detailed help message-man - Full documentation-live - Operation on Live data-prev=txt - Prevous package version-[no]placeKeeper - Only partial package creation-[no]history - Append a text summary of the package history-newPackage - Special Handling for a new package-infile=path - Path to input file=head1 OPTIONS=over 8=item B<-help>Print a brief help message and exits.=item B<-help -help>Print a detailed help message with an explanation for each option.=back=head2 OPTIONS=over=item -placeKeeperThis mode will only insert some of the package information. Suffiecient to preserve theversion number.The dependencies are not imported. The package will not build.Used to capture package-versions with some history.=item -historyThis option will cause a textual summary of the packages history to be added created.The summary track non-ripple builds back to the Release Manager split.=item -newPackageEnable special handling of a new package. In particular the Previous version will be set to null.=back=head1 EXAMPLEjats eprog rmMerge_spit PackageName PackageVersion=cut