Rev 295 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
################################################################################ CLASS RmPkgInfo# Gathers information about package from the Release Manager Database## By convention all members/methods that begin with an '_' are private.################################################################################=head1 NAMERmPkgInfo: Class to allow package details to be collected from release manager=head1 DATABy default will load details about the provided package.The following information is gathered and stored in a hash with the following keyspkg_id => The ID Number of the packagepkg_name => The Name of the packagepv_id => The ID number of the package versionpkg_version => The Version number of the packagepv_description => The package Version description (or default if not available)pv_reason => The package Version reason or default if not available)pv_label => The package Version label (or default if not available)pv_dlocked => Flag to indicate package Version is locked (or default if not available)pv_source_path => Package source patch (or undefined if not available) )pv_modified_time => DateTime the package was createdWill also gather optional information if requestedAttached issues will be collected if called, will gather the following in a multi level hashkeyed by database (TDSE or DEVI) and issue numberiss_numStr => The Issue Number as a stringiss_state => The Issue State flagiss_id => The Issue database numberiss_summary => The Issue summaryiss_status => The Issue Status flagiss_priority => The Issue priorityiss_type => The Issue TypeThe package runtime dependencies are also gathered and stored in a hash if called upon.The following details are collected in a hash keyed by dependency name.rt_name => The Runtime Dependency Namert_version => The Runtime Dependency Versionrt_comments => The Runtime Dependency CommentsThe package dependencies can also be retrieved. For each dependency found it will createa new RmPkgInfo object and stores it in the object. Information about a dependency can beretrieved from the objects themselves=head1 SYNOPSISuse DeployUtils::RmPkgInfomy $pkg = DeployUtils::RmPkgInfo->new({ PKG_NAME => "name", PKG_VERSION => "ver" })ormy $pkg = DeployUtils::RmPkgInfo->new({ PV_ID => "1234" })ormy $pkg = DeployUtils::RmPkgInfo->new({ PKG_NAME => "name", RTAG_ID => "ver", WIP => 1 })Instantiates the object, connects to RM and tries to load details about the package.Will always return the class object (unless invalid args which will abort).Failure to connect or retrieve package information will still succeed. Use the foundPkg() & foundDetails()members to verify the appropriate data has been collectedSynopsis 1Will try to locate pkg_id for the name supplied, foundPkg() will return true or false depending on result.If successfull will use pkg_id & supplied version to get package details, foundDetails() willreturn true or false depending on result.In this case foundDetails() implies foundPkg()Synopsis 2Will locate package details by supplied pv_id, both foundPkg() & foundDetails() will return trueor false depending on result.Synopsis 3Will try to locate the current version of PkgName in Release rTagId.If WIP is set to non 0 then will look for the latest version is release managers Work In Progress view.If not defined or set to 0 then it will look in the standard release view.$rv = $pkg->foundPkg()Returns true if package information is found ie pkg_id is non 0 (see new above)$rv = $pkg->foundDetails()Returns true if package version information is found ie pv_id is non 0 (see new above)$str = $pkg->pkg_id()$str = $pkg->pkg_name()$str = $pkg->pv_id()$str = $pkg->pkg_version()$str = $pkg->pv_description()$str = $pkg->pv_reason()$str = $pkg->pv_label()$str = $pkg->pv_dlocked()$str = $pkg->pv_source_path()$str = $pkg->pv_modified_time()Details Accessor members, returns the associated field from the package detailsThe following calls are used to access associated Issue details$rv = $pkg->getPkgIssues()Will connect to RM & CQ to get details about issues attached to current package.First gets a list of issue number attached from RM and then gets the issue details from CQ.Returns 1 for success and 0 for failure, however foundIssues() can be used to determineif issues have been found.$rv = $pkg->foundIssues()Returns true if Issues details for package have been retrieved.$typelist = $pkg->getIssueTypes()Returns as a list of strings, the issue types found. This will be one or both of( "tdse", "devi" ). This will call getPkgIssues if foundIssues() is false.$issuelist = $pkg->getIssueNumbers(issuetype)Returns as a list of strings, the issue numbers (iss_id) found for the passed issue type.This will call getPkgIssues if foundIssues() is false.Will abort if parameter not passedexampleforeach $i ( $pkg->getIssueTypes() )print $pkg->getIssueNumbers($i)$str = $pkg->iss_numStr(issuetype, issueId)$str = $pkg->iss_state(issuetype, issueId)$str = $pkg->iss_id(issuetype, issueId)$str = $pkg->iss_summary(issuetype, issueId)$str = $pkg->iss_status(issuetype, issueId)$str = $pkg->iss_priority(issuetype, issueId)$str = $pkg->iss_type(issuetype, issueId)Details Accessor members, returns the associated field from the issues details for the issuetype & issueIdThis will call getPkgIssues if foundIssues() is false. Will abort if parameters not passedThe following calls are used to access associated Runtime Dependencies$rv = getRtDeps()Will Connect to RM to get details about associated RunTime dependencies.Returns 1 for success and 0 for failure, however foundRtDeps() can be used to determineif issues have been found.$rv = $pkg->foundRtDeps()Returns true if Runtime dependencies details for package have been retrieved.@rtlist = $pkg->getRtDepNames()Returns as a list of strings, the dependency names of all dependenciesThis will call getRtDeps if foundRtDeps() is false.$str = $pkg->rt_name(RtDepName)$str = $pkg->rt_version(RtDepName)$str = $pkg->rt_comments(RtDepName)Details Accessor members, returns the associated field from the runtime dependencies for the dependency nameThis will call getRtDeps if foundRtDeps() is false. Will abort if parameters not passedThe following calls are used to access associated Dependencies$rv = $getDependenciesHash()Will return a hash containing package name and versions for all the dependantpackages, without extracting all the package information.This function corrects a problem in other function where multiple packages of the samename are mistreated.$rv = $pkg->getDependencies()Will Connect to RM to get details about associated dependencies. For each dependency will instantiatea new RmPkgInfo object and stores it in this object. By default the new object will automatically tryto retrieve details about its package.Returns 1 if fetched dependencies from RM, returns 0 if problems retieving data from RM. Use foundDependencies()to determine if these have been found.The new objects created should be checked with foundPkg() &/or foundDetails() to see if they got thepackage details.$rv = $pkg->foundDependencies()Returns true if dependencies details for package have been retrieved.@list = $pkg->getDependencyNames()Returns as a list of strings, the names of all dependencies found.$depPkg = $pkg->getDependencyObject(DepNam)Returns the RmPkgInfo object for the supplied Dependency name.Global Parameter modification functions$str = DeployUtils::RmPkgInfo->DefaultDescription(str)DeployUtils::RmPkgInfo->DefaultOverview(str)DeployUtils::RmPkgInfo->DefaultReason(str)DeployUtils::RmPkgInfo->DefaultLabel(str)DeployUtils::RmPkgInfo->DefaultDlocked(str)=cutpackage DeployUtils::RmPkgInfo;use strict;use DBI;use DeployUtils::Logger;use JatsRmApi;# The eponymous meta object is a hash that stores class global data# It has the same name as the package with the ":" replaced by "_".# All keys that dont begin with a _ have accessor membersour %DeployUtils__RmPkgInfo = (_RM_CONN => undef,_CQ_DB => "dbi:ODBC:DEVI", # SHOULD BE USED !!!!!_CQ_USER => "release_manager",_CQ_PASS => "release_manager",_CQ_CONN => undef,# This should match the entries in the _DETAILS hash element so accessors can be constructed._DetailsKeys => [ "pkg_id", "pkg_name", "pv_id", "pkg_version", "pv_description", "pv_overview", "pv_reason", "pv_label", "pv_dlocked", "pv_source_path", "pv_modified_time" ],# This should match the keys used for DEVI & TDSE issue hashes so accessors can be constructed_IssueKeys => [ "iss_numStr", "iss_state", "iss_id", "iss_summary", "iss_status", "iss_priority", "iss_type" ],# This should match the keys in the _RTDEPS hash for each package name so accessors can be created_RtDepKeys => [ "rt_name", "rt_version", "rt_comments" ],# Constants for Clearquest issues_enumCLEARQUEST_MASSI_ID => 1,_enumCLEARQUEST_DPGIM_ID => 2,_enumCLEARQUEST_TDSE_ID => 3,_enumCLEARQUEST_DEVI_ID => 4,_enumISSUES_STATE_FIXED => 1,# Default strings for missing itemsDefaultDescription => "No description available.",DefaultOverview => "No overview available.",DefaultReason => "No reason available.",DefaultLabel => "No label available.",DefaultDlocked => "N",);#==============================================================================# Constructor# Parameter is a hash that must contain the following# PKG_NAME = X & PKG_VERSION = X or# PV_ID = X#==============================================================================sub new{my $obclass = shift;my $class = ref($obclass) || $obclass;my $args = shift;LogError("RmPkgInfo::new Must supply Hash with PKG_NAME & PKG_VERSION keys or PKG_NAME & RTAG_ID or PV_ID key to instatiate object")unless ( ( defined($args->{PKG_NAME}) && defined($args->{PKG_VERSION}) ) ||( defined($args->{PKG_NAME}) && defined($args->{RTAG_ID}) ) ||( defined($args->{PV_ID}) ) );my $globals = _classobj();my $nowarn = $args->{NO_WARN} || 0;LogDebug("RmPkgInfo::new Instantiating new object of class $class");bless my $self = {_ARG_PKGNAME => $args->{PKG_NAME},_ARG_PKGVER => $args->{PKG_VERSION},_ARG_PV_ID => $args->{PV_ID},_ARG_RTAG_ID => $args->{RTAG_ID},_ARG_WIP => $args->{WIP},_DETAILS => {pkg_id => 0,pkg_name => "",pv_id => 0,pkg_version => 0,pv_description => $globals->{DefaultDescription},pv_overview => $globals->{DefaultOverview},pv_reason => $globals->{DefaultReason},pv_label => $globals->{DefaultLabel},pv_dlocked => $globals->{DefaultDlocked},pv_modified_time => undef,pv_source_path => undef},# Contains the issue information in multi level hashs# The main hash is keyed on issue type, currently devi & tdse# The issue type hash contains another hash that is keyed on issue ID# and those issue id hashes are keyed on items defined in _IssueKeys in global hash_ISSUES => { },# Records if getPkgIssues has been run_GETPKGISSUES => 0,# Stores the runtime dependencies# The hash is keyed on package name and contains another hash with keys defined by _RTKeys_RTDEPS => { },# Records if getRtDeps has been run_GETRTDEPS => 0,# A hash of this packages dependencies, the key is the dependency package name and the value is a RmPkgInfo object_DEPOBJECTS => { },# Records if getDependencies has been run_GETDEPENDENCIES => 0} => ( $class );if ( $self->_connectRM() ){# PVID is the minimum so if we have it use it.if ( defined($self->{_ARG_PV_ID}) ){if ( ! $self->_getPkgDetailsByPVID() ){LogWarn("RmPkgInfo::new Unable to get Package Details By PVID From Release Manager") unless $nowarn;}}# else we need to try to use name, ver oand/or rtag IDelse{# if we have Name & RTAG but no version then get version from name & rtagif ( defined($self->{_ARG_RTAG_ID}) && defined($self->{_ARG_PKGNAME}) && ! defined($self->{_ARG_PKGVER}) ){$self->{_ARG_PKGVER} = $self->_getLatestPkgVersion();}# now we should have name & ver if not report soif ( defined($self->{_ARG_PKGNAME}) && defined($self->{_ARG_PKGVER}) ){if ( ! $self->_getPkgDetailsByName() ){LogWarn("RmPkgInfo::new Unable to get Package Details By Name From Release Manager")unless $nowarn;}}else{LogWarn("RmPkgInfo::new Dont have enough info to get any information")unless $nowarn;}}}return($self);} # new#==============================================================================# _connectRM# Connects the DBI to release Manager if not connected#==============================================================================sub _connectRM{my $self = shift;my $globals = _classobj();connectRM (\$globals->{_RM_CONN} ) if ( ! defined($globals->{_RM_CONN}));return 1;} # _connectRM#==============================================================================# _connectCQ# Connects the DBI to Clear Quest if not connected#==============================================================================sub _connectCQ{my $self = shift;my $globals = _classobj();if ( ! defined($globals->{_CQ_CONN}) ){$globals->{_CQ_CONN} = DBI->connect($globals->{_CQ_DB}, $globals->{_CQ_USER}, $globals->{_CQ_PASS});if ( ! defined($globals->{_CQ_CONN}) ){LogError("-x", "RmPkgInfo::_connectCQ Failed to connect to database [$globals->{_CQ_DB}]. [$DBI::errstr].");return 0;}else{LogDebug("RmPkgInfo::_connectCQ Connected to database [$globals->{_CQ_DB}].");}}return 1;} # _connectCQ#------------------------------------------------------------------------------# _getPkgDetailsByName# This function retrieves the package version comment from the# release manager database, given the RM package id and version.#------------------------------------------------------------------------------sub _getPkgDetailsByName{my $self = shift;my $globals = _classobj();my $foundPkg = 0;my (@row);# if we are not or cannot connect then return 0 as we have not found anythingreturn 0 if ( ! $self->_connectRM() );# First get the pkg_id from the namemy ($m_sqlstr ) = "SELECT pkg_id, pkg_name FROM RELEASE_MANAGER.PACKAGES WHERE pkg_name=?";my ($sth ) = $globals->{_RM_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( $sth->execute( $self->{_ARG_PKGNAME}) ){if ( $sth->rows ){while ( @row = $sth->fetchrow_array ){$self->{_DETAILS}{pkg_id} = $row[0];$self->{_DETAILS}{pkg_name} = $row[1];LogDebug("RmPkgInfo::_getPkgDetailsByName Found PkgID & Name [$self->{_DETAILS}{pkg_id}] [$self->{_DETAILS}{pkg_name}]");$foundPkg = 1;last;}}$sth->finish();if ( ! $foundPkg ){LogWarn("RmPkgInfo::_getPkgDetailsByName Unable to find Package [$self->{_ARG_PKGNAME}]");return 0;}}else{LogError("-x", "RmPkgInfo::_getPkgDetailsByName Error executing query [$m_sqlstr] : " . $sth->errstr);return 0;}}else{LogError("-x", "RmPkgInfo::_getPkgDetailsByName Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return 0;}# Now get details using found pkg_id & version$m_sqlstr = "SELECT pkg_id, pv_id, pv_description, pv_overview, comments, pkg_label, dlocked, pkg_version, SRC_PATH, TO_CHAR(MODIFIED_STAMP, 'DD-MON-YYYY') AS MODIFIED_STAMP" ." FROM RELEASE_MANAGER.PACKAGE_VERSIONS" ." WHERE pkg_id=? AND pkg_version=?";$sth = $globals->{_RM_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( $sth->execute( $self->{_DETAILS}{pkg_id}, $self->{_ARG_PKGVER} ) ){if ( $sth->rows ){while ( @row = $sth->fetchrow_array ){$self->{_DETAILS}{pkg_id} = $row[0];$self->{_DETAILS}{pv_id} = $row[1];$self->{_DETAILS}{pv_description} = $row[2] if ( $row[2] );$self->{_DETAILS}{pv_overview} = $row[3] if ( $row[3] );$self->{_DETAILS}{pv_reason} = $row[4] if ( $row[4] );$self->{_DETAILS}{pv_label} = $row[5] if ( $row[5] );$self->{_DETAILS}{pv_dlocked} = $row[6] if ( $row[6] );$self->{_DETAILS}{pkg_version} = $row[7] if ( $row[7] );$self->{_DETAILS}{pv_source_path} = $row[8] if ( $row[8] );$self->{_DETAILS}{pv_modified_time}= $row[9] if ( $row[9] );LogDebug("RmPkgInfo::_getPkgDetailsByName Found Details for Package");return 1;}LogWarn("RmPkgInfo::_getPkgDetailsByName Unable to find Package Details for [$self->{_ARG_PKGNAME}, $self->{_ARG_PKGVER}]");}}else{LogError("-x", "RmPkgInfo::_getPkgDetailsByName Error executing query [$m_sqlstr] : " . $sth->errstr);return 0;}}else{LogError("-x", "RmPkgInfo::_getPkgDetailsByName Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return 0;}return 0;}#------------------------------------------------------------------------------# _getPkgDetailsByPVID# This function retrieves the package version comment from the# release manager database, given the Package Version id PVID.#------------------------------------------------------------------------------sub _getPkgDetailsByPVID{my $self = shift;my $globals = _classobj();my $foundDetails = 0;my (@row);# if we are not or cannot connect then return 0 as we have not found anythingreturn 0 if ( ! $self->_connectRM() );# First get details from pv_idmy $m_sqlstr = "SELECT pkg_id, pv_id, pv_description, pv_overview, comments, pkg_label, dlocked, pkg_version, SRC_PATH, TO_CHAR(MODIFIED_STAMP, 'DD-MON-YYYY') AS MODIFIED_STAMP" ." FROM RELEASE_MANAGER.PACKAGE_VERSIONS" ." WHERE pv_id=?";my $sth = $globals->{_RM_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( $sth->execute( $self->{_ARG_PV_ID} ) ){if ( $sth->rows ){while ( @row = $sth->fetchrow_array ){$self->{_DETAILS}{pkg_id} = $row[0];$self->{_DETAILS}{pv_id} = $row[1];$self->{_DETAILS}{pv_description} = $row[2] if ( $row[2] );$self->{_DETAILS}{pv_overview} = $row[3] if ( $row[3] );$self->{_DETAILS}{pv_reason} = $row[4] if ( $row[4] );$self->{_DETAILS}{pv_label} = $row[5] if ( $row[5] );$self->{_DETAILS}{pv_dlocked} = $row[6] if ( $row[6] );$self->{_DETAILS}{pkg_version} = $row[7] if ( $row[7] );$self->{_DETAILS}{pv_source_path} = $row[8] if ( $row[8] );$self->{_DETAILS}{pv_modified_time}= $row[9] if ( $row[9] );LogDebug("RmPkgInfo::_getPkgDetailsByPVID Found Details for Package");$foundDetails = 1;last;}}$sth->finish();if ( ! $foundDetails ){LogWarn("RmPkgInfo::_getPkgDetailsByPVID Unable to find Package [$self->{_ARG_PV_ID}]");return 0;}}else{LogError("-x", "RmPkgInfo::_getPkgDetailsByPVID Error executing query [$m_sqlstr] : " . $sth->errstr);return 0;}}else{LogError("-x", "RmPkgInfo::_getPkgDetailsByPVID Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return 0;}# now get pkgName from found pkg_id$m_sqlstr = "SELECT pkg_id, pkg_name FROM RELEASE_MANAGER.PACKAGES WHERE pkg_id=?";$sth = $globals->{_RM_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( $sth->execute( $self->{_DETAILS}{pkg_id} ) ){if ( $sth->rows ){while ( @row = $sth->fetchrow_array ){$self->{_DETAILS}{pkg_id} = $row[0];$self->{_DETAILS}{pkg_name} = $row[1];LogDebug("RmPkgInfo::_getPkgDetailsByPVID Found PkgID & Name [$self->{_DETAILS}{pkg_id}] [$self->{_DETAILS}{pkg_name}]");return 1;}}}else{LogError("-x", "RmPkgInfo::_getPkgDetailsByPVID Error executing query [$m_sqlstr] : " . $sth->errstr);return 0;}}else{LogError("-x", "RmPkgInfo::_getPkgDetailsByPVID Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return 0;}return 0;}sub _getLatestPkgVersion{my ( $self ) = shift;my $globals = _classobj();my $foundPkg = 0;my $pkgver = undef;my (@row);# if we are not or cannot connect then return 0 as we have not found anythingreturn undef if ( ! $self->_connectRM() );# First get the pkg_id from the namemy ($m_sqlstr );if ( defined($self->{_ARG_WIP}) && $self->{_ARG_WIP} != 0 ){LogDebug("RmPkgInfo::_getLatestPkgVersion Using Work In Progress View");$m_sqlstr = "SELECT pv.pkg_version FROM RELEASE_MANAGER.work_in_progress wip, RELEASE_MANAGER.package_versions pv, RELEASE_MANAGER.PACKAGES pkg WHERE ( wip.pv_id=pv.pv_id AND pv.pkg_id=pkg.pkg_id AND wip.rtag_id=? AND pkg.pkg_name=? )";}else{LogDebug("RmPkgInfo::_getLatestPkgVersion Using Released View");$m_sqlstr = "SELECT pv.pkg_version FROM RELEASE_MANAGER.release_content rel, RELEASE_MANAGER.package_versions pv, RELEASE_MANAGER.PACKAGES pkg WHERE ( rel.pv_id=pv.pv_id AND pv.pkg_id=pkg.pkg_id AND rel.rtag_id=? AND pkg.pkg_name=? )";}my ($sth ) = $globals->{_RM_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( $sth->execute( $self->{_ARG_RTAG_ID}, $self->{_ARG_PKGNAME}) ){if ( $sth->rows ){while ( @row = $sth->fetchrow_array ){$pkgver = $row[0];LogDebug("RmPkgInfo::_getLatestPkgVersion Found Latest PVID [$pkgver]");$foundPkg++;}}$sth->finish();if ( ! $foundPkg ){LogWarn("RmPkgInfo::_getLatestPkgVersion Unable to find Latest Version for [$self->{_ARG_PKGNAME}] in [$self->{_ARG_RTAG_ID}]");return undef;}elsif ( $foundPkg > 1 ){LogWarn("RmPkgInfo::_getLatestPkgVersion Found more than 1 version of [$self->{_ARG_PKGNAME}] in [$self->{_ARG_RTAG_ID}]");return undef;}}else{LogError("-x", "RmPkgInfo::_getPkgDetailsByName Error executing query [$m_sqlstr] : " . $sth->errstr);return undef;}}else{LogError("-x", "RmPkgInfo::_getPkgDetailsByName Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return undef;}return $pkgver;}#------------------------------------------------------------------------------# getPkgIssues# Updates the ISSUES hash containing information about assigned issues.#------------------------------------------------------------------------------sub getPkgIssues{my $self = shift;my $globals = _classobj();my ($sth);my (@row);my ($m_sqlstr);my ($TDSEissues) = "-1";my ($DEVIiss ) = "-1";# if we are not or cannot connect then return 0 as we have not found anythingreturn 0 if ( ! $self->_connectRM() );$m_sqlstr = "SELECT iss_db, iss_id, iss_state, notes FROM RELEASE_MANAGER.CQ_ISSUES WHERE pv_id=?";$sth = $globals->{_RM_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( $sth->execute( $self->{_DETAILS}{pv_id} ) ){if ( $sth->rows ){while ( @row = $sth->fetchrow_array ){if ( $row[0] == $globals->{_enumCLEARQUEST_DEVI_ID} ){$DEVIiss = "$DEVIiss" . "," . $row[1];$self->{_ISSUES}{devi}{$row[1]}{iss_numStr} = $row[1];$self->{_ISSUES}{devi}{$row[1]}{iss_state} = $row[2];}elsif ( $row[0] == $globals->{_enumCLEARQUEST_TDSE_ID} ){$TDSEissues = "$TDSEissues" . "," . $row[1];$self->{_ISSUES}{tdse}{$row[1]}{iss_numStr} = $row[1];$self->{_ISSUES}{tdse}{$row[1]}{iss_state} = $row[2];}else{LogWarn("RmPkgInfo::getPkgIssues Issue type [$row[0]] not supported.");}}}$sth->finish();}else{LogError("-x", "RmPkgInfo::getPkgIssues Error executing query [$m_sqlstr] : " . $sth->errstr);return 0;}}else{LogError("-x", "RmPkgInfo::getPkgIssues Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return 0;}LogInfo($self->pkg_name() . ":" . $self->pkg_version() . "DEVIiss =[$DEVIiss]");LogInfo($self->pkg_name() . ":" . $self->pkg_version() . "TDSEiss =[$TDSEissues]");# if we are not or cannot connect then return 0 as we have not found anythingreturn 0 if ( ! $self->_connectCQ() );# now we create the SQL statement to get the detaisl from the CQ databaseif ( "$DEVIiss" ne "" || "$TDSEissues" ne "" ){$m_sqlstr = "\n" ."SELECT * FROM ( \n" ." SELECT " . $globals->{_enumCLEARQUEST_DEVI_ID} . " AS iss_db,\n" ." si.dbid AS iss_id, \n" ." si.new_num AS iss_num, \n" ." si.headline AS summary, \n" ." sdef.name AS status, \n" ." si.priority AS priority,\n" ." si.issue_type AS issue_type\n"." FROM DEVI_PROD.admin.software_issue si INNER JOIN DEVI_PROD.admin.statedef sdef ON si.state = sdef.id\n" ." WHERE si.dbid IN ( $DEVIiss )\n" ." UNION ALL\n" ." SELECT " . $globals->{_enumCLEARQUEST_TDSE_ID} . " AS iss_db,\n" ." si.dbid AS iss_id, \n" ." si.job_number AS iss_num, \n" ." si.problem_summary AS summary, \n" ." sdef.name AS status, \n" ." si.priority AS priority,\n" ." NULL AS issue_type\n" ." FROM TDSE_2002.admin.request si INNER JOIN TDSE_2002.admin.statedef sdef ON si.state = sdef.id\n" ." WHERE si.dbid IN ( $TDSEissues )\n" ." ) AS issues ORDER BY iss_num ASC";undef($sth);$sth = $globals->{_CQ_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( $sth->execute() ){while ( @row = $sth->fetchrow_array ){if ( $row[0] == $globals->{_enumCLEARQUEST_DEVI_ID} ){$self->{_ISSUES}{devi}{$row[1]}{iss_id} = $row[1];$self->{_ISSUES}{devi}{$row[1]}{iss_numStr} = $row[2];$self->{_ISSUES}{devi}{$row[1]}{iss_summary} = $row[3];$self->{_ISSUES}{devi}{$row[1]}{iss_status} = $row[4];$self->{_ISSUES}{devi}{$row[1]}{iss_priority} = $row[5];if ( $row[6] ){$self->{_ISSUES}{devi}{$row[1]}{iss_type} = $row[6];}else{$self->{_ISSUES}{devi}{$row[1]}{iss_type} = "Not Known";}}elsif ( $row[0] == $globals->{_enumCLEARQUEST_TDSE_ID} ){$self->{_ISSUES}{tdse}{$row[1]}{iss_id} = $row[1];$self->{_ISSUES}{tdse}{$row[1]}{iss_numStr} = $row[2];$self->{_ISSUES}{tdse}{$row[1]}{iss_summary} = $row[3];$self->{_ISSUES}{tdse}{$row[1]}{iss_status} = $row[4];$self->{_ISSUES}{tdse}{$row[1]}{iss_priority} = $row[5];if ( $row[6] ){$self->{_ISSUES}{tdse}{$row[1]}{iss_type} = $row[6];}else{$self->{_ISSUES}{tdse}{$row[1]}{iss_type} = "Not Known";}}else{LogWarn("RmPkgInfo::getPkgIssues Issue type [$row[0]] not supported.");}}}else{LogError("-x", "RmPkgInfo::getPkgIssues Error executing query [$m_sqlstr] : " . $sth->errstr);return 0;}}else{LogError("-x", "RmPkgInfo::getPkgIssues Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return 0;}}$self->{_GETPKGISSUES} = 1;return 1;}#------------------------------------------------------------------------------# getRtDeps# Populates the RTDeps Hash with runtime dependencies#------------------------------------------------------------------------------sub getRtDeps{my $self = shift;my $globals = _classobj();my ($sth );my (@row);my ($m_sqlstr);# if we are not or cannot connect then return 0 as we have not found anythingreturn 0 if ( ! $self->_connectRM() );$m_sqlstr = "SELECT pkg.pkg_name, pv.pkg_version, rd.rtd_comments, rd.rtd_url, rd.mod_date, \n" ."usr.full_name, usr.user_email \n" ."FROM RELEASE_MANAGER.runtime_dependencies rd, RELEASE_MANAGER.package_versions pv, RELEASE_MANAGER.PACKAGES pkg, RELEASE_MANAGER.users usr \n"."WHERE pv.pkg_id = pkg.pkg_id \n" ."AND rd.rtd_id = pv.pv_id \n" ."AND rd.mod_user = usr.user_id \n" ."AND rd.pv_id = ?\n" ."ORDER BY UPPER(pkg.pkg_name) ASC";$sth = $globals->{_RM_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( $sth->execute( $self->{_DETAILS}{pv_id} ) ){if ( $sth->rows ){while ( @row = $sth->fetchrow_array ){$self->{_RTDEPS}{$row[0]}{rt_name} = $row[0];$self->{_RTDEPS}{$row[0]}{rt_version} = $row[1];if ( $row[2] ){$self->{_RTDEPS}{$row[0]}{rt_comments} = $row[2];}else{$self->{_RTDEPS}{$row[0]}{rt_comments} = "None";}}}}else{LogError("-x", "RmPkgInfo::getRtDeps Error executing query [$m_sqlstr] : " . $sth->errstr);return 0;}}else{LogError("-x", "RmPkgInfo::getRtDeps Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return 0;}$self->{_GETRTDEPS} = 1;return 1;}#------------------------------------------------------------------------------# zapProductContents## This function ZAPs the contents of a product.## The contents are determined by 'pv_id' and a 'machtype' both of which are# set during build time and are globally accessible.##------------------------------------------------------------------------------sub zapProductContents{my $self = shift;my $globals = _classobj();my ( $platform ) = shift;# if we are not or cannot connect then return 0 as we have not found anythingreturn 0 if ( ! $self->_connectRM() );LogNorm("RmPkgInfo::zapProductContents Removing Contents for [$self->{_DETAILS}{pv_id}], [$platform]");my ($sth );my ($m_sqlstr);$m_sqlstr = "BEGIN PK_BUILDAPI.Remove_All_Product_Components(?,?); END;";$sth = $globals->{_RM_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( ! $sth->execute( $self->{_DETAILS}{pv_id}, $platform ) ){LogError("-x", "RmPkgInfo::zapProductContents Error executing query [$m_sqlstr] : " . $sth->errstr);return 0;}}else{LogError("-x", "RmPkgInfo::zapProductContents Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return 0;}# donereturn 1;}#------------------------------------------------------------------------------# insertProductContentItem## This function inserts and item into the product contents table.## The 'pv_id' and a 'machtype' are set during build time and are globally accessible.# ans are not required to be passed.##------------------------------------------------------------------------------sub insertProductContentItem{my $self = shift;my $globals = _classobj();my ($platform, $sOrigFilePath, $sFileName, $sDestFilePath, $nByteSize, $sCRCcksum) = @_;# if we are not or cannot connect then return 0 as we have not found anythingreturn 0 if ( ! $self->_connectRM() );LogNorm ("RmPkgInfo::insertProductContentItem: [$self->{_DETAILS}{pv_id}], [$platform], [$sOrigFilePath], [$sFileName], [$sDestFilePath], [$nByteSize], [$sCRCcksum]");my ($sth );my ($m_sqlstr);$m_sqlstr = "BEGIN PK_BUILDAPI.Add_Product_Component( ?, ?, ?, ?, ?, ?, ?); END;";$sth = $globals->{_RM_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( ! $sth->execute( $self->{_DETAILS}{pv_id}, $platform, $sOrigFilePath, $sFileName, $sDestFilePath, $nByteSize, $sCRCcksum ) ){LogError("-x", "RmPkgInfo::insertProductContentItem Error executing query [$m_sqlstr] : " . $sth->errstr);return 0;}}else{LogError("-x", "RmPkgInfo::insertProductContentItem Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return 0;}# donereturn 1;}#==============================================================================# getDependencies#==============================================================================sub getDependencies{my $self = shift;my $globals = _classobj();my ($obj, $name);my ($m_sqlstr);my ($sth);my (@row);# First we get the list of dependenciy pvid's and use them to create new objects$m_sqlstr = "select dpv_id from RELEASE_MANAGER.package_dependencies where pv_id=?";$sth = $globals->{_RM_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( $sth->execute( $self->{_DETAILS}{pv_id} ) ){if ( $sth->rows ){while ( @row = $sth->fetchrow_array ){$obj = DeployUtils::RmPkgInfo->new( { PV_ID => $row[0] } );if ( $obj->foundDetails() ){$name = $obj->pkg_name();$self->{_DEPOBJECTS}{$name} = $obj;LogDebug("RmPkgInfo::getDependencies Created Dependency object for $name");}}}}else{LogError("-x", "RmPkgInfo::getDependencies Error executing query [$m_sqlstr] : " . $sth->errstr);return 0;}}else{LogError("-x", "RmPkgInfo::getDependencies Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return 0;}$self->{_GETDEPENDENCIES} = 1;return 1;} # getDependencies#==============================================================================# getDependenciesHash#==============================================================================sub getDependenciesHash{my $self = shift;my $globals = _classobj();my ($obj, $name);my ($m_sqlstr);my ($sth);my (@row);my %result;# First we get the list of dependenciy pvid's$m_sqlstr = "SELECT pkg.PKG_NAME, pv.PKG_VERSION FROM RELEASE_MANAGER.PACKAGE_DEPENDENCIES pd, RELEASE_MANAGER.PACKAGE_VERSIONS pv, RELEASE_MANAGER.PACKAGES pkg WHERE pd.PV_ID=? AND pd.DPV_ID = pv.PV_ID AND pv.PKG_ID = pkg.PKG_ID";$sth = $globals->{_RM_CONN}->prepare($m_sqlstr);if ( defined($sth) ){if ( $sth->execute( $self->{_DETAILS}{pv_id} ) ){if ( $sth->rows ){while ( @row = $sth->fetchrow_array ){$result{$row[0]}{$row[1]} = 1;}}}else{LogError("-x", "RmPkgInfo::getDependenciesHash Error executing query [$m_sqlstr] : " . $sth->errstr);return 0;}}else{LogError("-x", "RmPkgInfo::getDependenciesHash Unable to prepare SQL Statement [$m_sqlstr] : " . $globals->{_RM_CONN}->errstr);return 0;}return \%result;} # getDependenciesHash#==============================================================================# getDependencyNames# Returns the keys from the _DEPOBJECTS hash that are the names of the dependencies#==============================================================================sub getDependencyNames{my $self = shift;$self->getDependencies() if ( ! $self->foundDependencies() );return sort keys %{$self->{_DEPOBJECTS}};} # getDependencyNames#==============================================================================# getDependencyObject# Returns the RmPkgInfo object for name#==============================================================================sub getDependencyObject{my $self = shift;my $name = shift;LogError("RmPkgInfo::getDependencyObject Must supply Dependency name") if ( ! defined($name) );$self->getDependencies() if ( ! $self->foundDependencies() );return $self->{_DEPOBJECTS}{$name};} # getDependencyObject#==============================================================================# getIssueTypes# Returns the issues types stored in the ISSUES array, should be devi and/or tdse#==============================================================================sub getIssueTypes{my $self = shift;# Call getPkgIssues if not already$self->getPkgIssues() if ( ! $self->foundIssues() );return keys %{$self->{_ISSUES}};} # getIssueTypes#==============================================================================# getIssueNumbers# Returns a list of the issue numbers for the associated issue type passed#==============================================================================sub getIssueNumbers{my $self = shift;my $issType = shift;LogError("RmPkgInfo::getIssueNumbers Must supply issue type") if ( ! defined($issType) );# Call getPkgIssues if not already$self->getPkgIssues() if ( ! $self->foundIssues() );return sort keys %{$self->{_ISSUES}{$issType}};} # getIssueNumbers#==============================================================================# getRtDepNames# Returns a list of the Runtime Dependencies found#==============================================================================sub getRtDepNames{my $self = shift;$self->getRtDeps() if ( ! $self->foundRtDeps() );return keys %{$self->{_RTDEPS}};} # getRtDepNames#==============================================================================# foundPkg# Returns TRUE if the package has been found in RM otherwise FALSE.# A pkg is found if the pkg_id is non 0#==============================================================================sub foundPkg{my $self = shift;return ( $self->{_DETAILS}{pkg_id} != 0 ) ? 1 : 0;} # foundPkg#==============================================================================# foundDetails# Returns TRUE if the package details has been found in RM otherwise FALSE.# A pkg is found if the pv_id is non 0#==============================================================================sub foundDetails{my $self = shift;return ( $self->{_DETAILS}{pv_id} != 0 ) ? 1 : 0;} # foundDetails#==============================================================================# foundIssues# Returns TRUE if the package Issues has been found in RM otherwise FALSE.#==============================================================================sub foundIssues{my $self = shift;return $self->{_GETPKGISSUES};} # foundIssues#==============================================================================# foundRtDeps# Returns TRUE if the package RtDeps has been found in RM otherwise FALSE.#==============================================================================sub foundRtDeps{my $self = shift;return $self->{_GETRTDEPS};} # foundRtDeps#==============================================================================# foundDependencies# Returns TRUE if the package Dependencies has been found in RM otherwise FALSE.#==============================================================================sub foundDependencies{my $self = shift;return $self->{_GETDEPENDENCIES};} # foundDependencies#==============================================================================# _classobj# Internal member that is tri-natured: can be called as function, class method,# or object method.# It returns a reference to the eponymous hash for access to class global data#==============================================================================sub _classobj{my $obclass = shift || __PACKAGE__;my $class = ref($obclass) || $obclass;$class =~ s/:/_/g; # Replace all ": with "_" to get the name of the hashno strict "refs"; # to convert sym ref to real onereturn \%$class;}#==============================================================================# dumpSelf, debugging member to dump selfs hash#==============================================================================sub dumpSelf{use Data::Dumper;my $self = shift;print Data::Dumper->Dump([$self, $self->_classobj()], [ref($self), "Globals"]);} # dumpSelf# This code is executed when the package is included and generates accessor methods for accessing# global vars in the eponymous objectfor my $datum (grep(!/^_/, keys %{ _classobj() }) ){# turn off strict refs so that we can# register a method in the symbol tableno strict "refs";*$datum = sub {use strict "refs";my $self = shift->_classobj();$self->{$datum} = shift if @_;return $self->{$datum};}}# This code is executed when the package is included and generates accessor methods for accessing# self data from the details hashfor my $datum ( @{_classobj()->{_DetailsKeys}} ){# turn off strict refs so that we can# register a method in the symbol tableno strict "refs";*$datum = sub {use strict "refs";my $self = shift;return $self->{_DETAILS}{$datum};}}# This code is executed when the package is included and generates accessor methods for accessing# self data from the Issues Hashfor my $datum ( @{_classobj()->{_IssueKeys}} ){# turn off strict refs so that we can# register a method in the symbol tableno strict "refs";*$datum = sub {use strict "refs";my $self = shift;my $issType = shift;my $issId = shift;LogError("RmPkgInfo::$datum Must supply IssueType & Issue ID as parameters") if ( ! defined($issId) );# Call getPkgIssues if not already$self->getPkgIssues() if ( ! $self->foundIssues() );return $self->{_ISSUES}{$issType}{$issId}{$datum};}}# This code is executed when the package is included and generates accessor methods for accessing# self data from the RTDEPS Hashfor my $datum ( @{_classobj()->{_RtDepKeys}} ){# turn off strict refs so that we can# register a method in the symbol tableno strict "refs";*$datum = sub {use strict "refs";my $self = shift;my $RtName = shift;LogError("RmPkgInfo::$datum Must supply Runtime Dependency Name as parameter") if ( ! defined($RtName) );# Call getRtDeps if not already$self->getRtDeps() if ( ! $self->foundRtDeps() );return $self->{_RTDEPS}{$RtName}{$datum};}}1;