Subversion Repositories DevTools

Rev

Rev 7382 | Rev 7417 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

<%
'=====================================================
'                COMMON SUBs Part 1
'=====================================================
Const haveCommonSubs = 1
%>
<%
'-----------------------------------------------------------------------------------------------------------------------------
Sub CloseWindow
%>
<SCRIPT language="JavaScript" type="text/javascript">
<!--
self.close();
//-->
</SCRIPT>
<%
Call Destroy_All_Objects
Response.End
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Sub OpenChildWindow ( SStitle, SSurl, SSH, SSW, BBscroll )
   Dim scrlBar
   If BBscroll Then
      scrlBar = "yes"
   Else
      scrlBar = "no"
   End If
%>
   <script language="JavaScript" type="text/javascript">
   <!--
   window.open('<%=SSurl%>','<%=SStitle%>','scrollbars=<%=scrlBar%>,resizable=yes,width=<%=SSW%>,height=<%=SSH%>')
   //-->
   </script>
<%
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
'       Iframes do not have a window.opener
Sub OpenInParentWindow ( SSurl )
%>
   <script language="JavaScript" type="text/javascript">
   <!--
        if (window.opener) {
           window.opener.document.location='<%=SSurl%>';
   } else {
           window.parent.location.href='<%=SSurl%>';
   }
   //-->
   </script>
<%
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
'       Iframes do not have a window.opener
Sub ReloadParentWindow ()
%>
   <script language="JavaScript" type="text/javascript">
   <!--
        if (window.opener) {
           window.opener.location.reload(false);
   } else {
           window.parent.location.reload(false);
   }
   //-->
   </script>
<%
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Sub OpenInWindow ( SSurl )
   Call Destroy_All_Objects
   Response.Redirect ( SSurl )
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Function GetQuery ( sQryName )
   GetQuery = ReadFile( QUERIES_PATH &"\"& sQryName )
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Sub RaiseMsg ( SSerrFile, SSerrDesc )
   ' Usage: enumERROR, parval1 &"|"& parval2 &"|"& parval3 ...
   Session( enum_RELMGR_ERRDESCRIPTION ) = SSerrDesc
   Call Destroy_All_Objects
   Response.Redirect ("messages/"& SSerrFile )
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Sub RaiseMsgInParent ( SSerrFile, SSerrDesc )
   Session( enum_RELMGR_ERRDESCRIPTION ) = SSerrDesc
   Call OpenInParentWindow ("messages/"& SSerrFile )
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Function ReadFile( SSpath )
   Dim filesys, rfile
   Set filesys = CreateObject("Scripting.FileSystemObject")
   Set rfile = filesys.OpenTextFile( SSpath, 1, false)
   ReadFile = rfile.ReadAll
   rfile.close
   Set filesys = nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function HighlightSubstring ( SSstr, SSsubstr )
   Dim leftSTR, startPos
   startPos = InStr( 1, SSstr, SSsubstr, 1 )

   If startPos > 0 Then
      leftSTR = Left ( SSstr, startPos - 1 )
      HighlightSubstring = leftSTR &"<SPAN style='background:#ffff99;'>"& Mid( SSstr, startPos, Len(SSsubstr) ) &"</SPAN>"&  Right ( SSstr, Len(SSstr) - Len(leftSTR) - Len(SSsubstr)  )
   Else
      ' Subtring not found
      HighlightSubstring = SSstr
   End If

End Function
'-----------------------------------------------------------------------------------------------------------------------------
Sub DeleteFile( SSpath )
   Dim filesys
   Set filesys = CreateObject("Scripting.FileSystemObject")
   If filesys.FileExists(SSpath) Then
         filesys.DeleteFile SSpath, TRUE
   End If
   Set filesys = nothing
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Sub DeleteFolder( SSpath )
   Dim  filesys
   Set filesys = CreateObject ("Scripting.FileSystemObject")
   If filesys.FolderExists( SSpath ) Then
      'Set oFolder = filesys.GetFolder( SSpath )
      filesys.DeleteFolder SSpath ,TRUE
   End If
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Sub Create_Folder ( sCreateIn, sFolderName )
   Dim filesys, currfolder, folcoll, subfol
   Set filesys = CreateObject("Scripting.FileSystemObject")
   If filesys.FolderExists( sCreateIn ) Then
      Set currfolder = filesys.GetFolder( sCreateIn )
      Set folcoll = currfolder.SubFolders
      If NOT filesys.FolderExists( sCreateIn &"\"& sFolderName ) Then
         folcoll.Add( sFolderName )
      End If
   End If
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Function Folder_Is_Empty ( sPath )
   Dim filesys, oFolder
   Set filesys = CreateObject("Scripting.FileSystemObject")

   If filesys.FolderExists( sPath ) Then
      Set oFolder = filesys.GetFolder( sPath )
      If ( oFolder.Files.Count + oFolder.SubFolders.Count ) > 0 Then
         Folder_Is_Empty = FALSE
      Else
         Folder_Is_Empty = TRUE
      End If
   Else
      Folder_Is_Empty = TRUE
   End If

End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function InStrPipes ( SSstr, SSsubstr )
   If InStr( SSstr, "|"& SSsubstr &"|") > 0 Then
      InStrPipes = true
   Else
      InStrPipes = false
   End If
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function RemoveFromStrPipes ( SSstr, SSsubstr )
   RemoveFromStrPipes = Replace( SSstr, "|"& SSsubstr &"|", "" )
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function View_Name_Exists ( SSviewname, NNused_id )
   Dim rsTemp, Query_String
   Query_String = _
   " SELECT view_name"&_
   "  FROM views"&_
   " WHERE UPPER(view_name) = UPPER('"& UCase(SSviewname) &"') AND owner_id = "& NNused_id
   Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
   If rsTemp.RecordCount > 0 Then
      View_Name_Exists = TRUE
   Else
      View_Name_Exists = FALSE
   End If
   rsTemp.Close
   Set rsTemp = nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function User_Name_Exists ( SSusername )
   Dim rsTemp, Query_String
   Query_String = _
   " SELECT user_name"&_
   "  FROM users"&_
   " WHERE user_name = '"& SSusername &"'"
   Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
   If rsTemp.RecordCount > 0 Then
      User_Name_Exists = TRUE
   Else
      User_Name_Exists = FALSE
   End If
   rsTemp.Close
   Set rsTemp = nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function This_View_Owner( NNview_id, NNuser_id )
   Dim rsTemp, Query_String
   Query_String = _
   " SELECT owner_id"&_
   "  FROM views"&_
   " WHERE view_id = "& NNview_id
   Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
   If rsTemp.RecordCount > 0 Then
      If CInt(rsTemp.Fields("owner_id")) = CInt(NNuser_id) Then
         This_View_Owner = TRUE
      Else
         This_View_Owner = FALSE
      End If
   Else
      ' view not found
      Session("AdditionalParams") = "$ADMINEMAIL$,"& ADMIN_EMAIL
      Call Destroy_All_Objects
      Response.Redirect("message.asp?msg=400-2")
   End If
   rsTemp.Close
   Set rsTemp = nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function GetReleaseMode ( NNrtag_id )
   GetReleaseInfo NNrtag_id
   GetReleaseMode = releaseInfoHash("official")
End Function
'-----------------------------------------------------------------------------------------------------------------------------
'   Get basic Release Info on global releaseInfoHash
'   List of fields may be extended as required (could use *)
'
'   Cache the results
'       Largely to simplify a code refactor
'       Data will be read early, but may need to be changed
'
Sub GetReleaseInfo ( NNrtag_id )
    Dim rsTemp, Query_String, item
    If NNrtag_id = "" Then NNrtag_id = "-1"

    ' Do we already have the data
    If NOT (releaseInfoHash is Nothing) Then
       If Cdbl(releaseInfoHash("rtag_id") ) = CDbl(NNrtag_id) Then
           Exit Sub
        End If
    End If

   ' Create with case insensitive keys
   Set releaseInfoHash = CreateObject("Scripting.Dictionary")
   releaseInfoHash.CompareMode = VBTextCompare

   ' Handle not logged in
   Dim UserId : UserId = -1
   If objAccessControl.UserLogedIn Then UserId = objAccessControl.UserId

   Query_String = "SELECT rt.RTAG_ID ,rt.rtag_name, proj.proj_id, proj.proj_name,rt.lxr, rt.official, NVL(lx.lxrserver, 'N') as lxrserver, NVL(rt.s3Sync, 'N') as s3Sync," &_
                  "  CASE when (TRUNC(SYSDATE - rt.created_stamp) <= 20) AND rt.creator_id = "& UserId & " THEN 1 ELSE 0 END as userCanDelete" &_
                  "  FROM Release_tags rt, projects proj, lxr_state lx" &_
                  "  WHERE rt.RTAG_ID = lx.RTAG_ID(+)" &_
                  "  AND rt.proj_id = proj.proj_id" &_
                  "  AND rt.RTAG_ID = " & NNrtag_id

    Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
    If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
        For Each item In rsTemp.Fields 
            'Response.Write("<br><pre> item:" & item.name & ":" & item & "</pre>")
            releaseInfoHash.Add  item.name, item.value
        Next
    End If

    rsTemp.Close
    Set rsTemp = nothing
End Sub

'-----------------------------------------------------------------------------------------------------------------------------
Function Get_Devl_Environment
   If Request.Cookies(COOKIE_RELEASEMANAGER_MEMORY)("devl_environment") <> "" Then
      If Request.Cookies(COOKIE_RELEASEMANAGER_MEMORY)("devl_environment") = "clearcase" Then
         Get_Devl_Environment = "jats"      'clear case does not have import
      Else
         Get_Devl_Environment = Request.Cookies(COOKIE_RELEASEMANAGER_MEMORY)("devl_environment")
      End If
   Else
      Get_Devl_Environment = "jats"      'JATS devl enviroment is set by default
   End If
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function Get_From_DUAL ( SSclm )
   Dim rsTemp, Query_String, OraSession2, OraDatabase2
   Set OraSession2 = CreateObject("OracleInProcServer.XOraSession")
   Set OraDatabase2 = OraSession2.OpenDatabase( TNS_NAME, DB_AUTHENTICATION, Cint(0))

   Query_String = _
   " SELECT "& SSclm &" AS result FROM DUAL"
   Set rsTemp = OraDatabase2.DbCreateDynaset( Query_String, cint(0))

   If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
      Get_From_DUAL = (rsTemp.Fields("result"))
   End If

   rsTemp.Close
   Set rsTemp = nothing
   Set OraDatabase2 = nothing
   Set OraSession2 = nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
' Try to replace usage with : DB_PROJ_ID
Function Get_Proj_ID ( SSrtag_id )
   Dim rsTemp, Query_String

   Query_String = _
   " SELECT projects.proj_id"&_
   "   FROM projects projects, release_tags rel"&_
   "  WHERE projects.proj_id = rel.proj_id"&_
   "    AND rel.rtag_id = "& SSrtag_id

   Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))

   If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
      Get_Proj_ID = (rsTemp.Fields("proj_id"))
   End If

   rsTemp.Close
   Set rsTemp = nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
' Try to replace usage with : DB_PROJ_NAME
Function Get_Proj_Name ( NNproj_id )
   Dim rsTemp, Query_String

   Get_Proj_Name = ""

   Query_String = _
   " SELECT proj_name "&_
   "   FROM projects pr "&_
  "  WHERE pr.proj_id = "& NNproj_id

   Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))

   If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
      Get_Proj_Name = (rsTemp.Fields("proj_name"))
   End If

   rsTemp.Close
   Set rsTemp = nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function Get_Release_Name ( NNrtag_id )
   Dim rsTemp, Query_String

   Get_Release_Name = ""

   Query_String = _
   " SELECT rtag_name "&_
   "   FROM release_tags rt "&_
  "  WHERE rt.rtag_id = "& NNrtag_id

   Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))

   If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
      Get_Release_Name = (rsTemp.Fields("rtag_name"))
   End If

   rsTemp.Close
   Set rsTemp = nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function Get_Base_URL ( NNproj_id )
   Dim rsTemp, Query_String

   Query_String = _
   " SELECT base_url "&_
   "   FROM projects pr "&_
  "  WHERE pr.proj_id = "& NNproj_id

   Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))

   Get_Base_URL = rsTemp("base_url")

   rsTemp.Close()
   Set rsTemp = nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function Get_Categories ( NNrtag_id )
   Get_Categories = _
   " SELECT vi.view_id, vi.view_name"&_
   "  FROM release_content rel,"&_
   "       views vi"&_
   " WHERE rel.base_view_id = vi.view_id"&_
   "   AND rtag_id = "& NNrtag_id &_
   " GROUP BY vi.view_id, vi.view_name   "&_
   " ORDER BY vi.view_name ASC "
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function Get_PV_IDs_In_Release ( NNrtag_id )
    Dim rsTemp, Query_String, tempSTR
   tempSTR = "-1"
   Query_String = _
   "SELECT pv_id FROM release_content WHERE rtag_id = "& NNrtag_id

   Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))

   While ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF))
      tempSTR = tempSTR &","& rsTemp.Fields("pv_id")
      rsTemp.MoveNext
   WEnd
   Get_PV_IDs_In_Release = tempSTR
   rsTemp.Close
   Set rsTemp = nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Sub Get_Pkg_Info ( SSpv_id, NNrtag )
    Dim rsTemp, Query_String, isaRelease, isaValidPvId
    Dim opCodeListString, opCodeList, opCodeStr

    OraDatabase.Parameters.Add "PV_ID",         SSpv_id,   ORAPARM_INPUT, ORATYPE_NUMBER
    OraDatabase.Parameters.Add "RTAG_ID",       NNrtag,    ORAPARM_INPUT, ORATYPE_NUMBER
    OraDatabase.Parameters.Add "RETURN_NUMBER", NULL,      ORAPARM_OUTPUT, ORATYPE_NUMBER   
    OraDatabase.Parameters.Add "OP_CODE_LIST",  NULL,      ORAPARM_OUTPUT, ORATYPE_VARCHAR2

    isaRelease = NOT ((NNrtag = "") or (IsNull(NNrtag)))
    pkgInfoHash.Add "isaRelease", isaRelease

    '-- can_unofficial
    '   Limits the ability to unrelease a package version
    pkgInfoHash.Item ("can_unofficial") = "false"

    '--  can_edit_in_project
    '    Property of the release, the user and the package
    '    Limits the ability to add a package to a release
    '        
    pkgInfoHash.Item ("can_edit_in_project") = "0"

    '-- Get Package Details
    Set rsTemp = OraDatabase.DbCreateDynaset( GetQuery("PackageDetails.sql"), cint(0))
    isaValidPvId = (NOT rsTemp.BOF) AND (NOT rsTemp.EOF) 
    pkgInfoHash.Add "isaValidPvId" , isaValidPvId
     
    If isaValidPvId Then
        pkgInfoHash.Add "pv_id", (rsTemp.Fields("pv_id"))
        pkgInfoHash.Add "pkg_id", (rsTemp.Fields("pkg_id"))
        pkgInfoHash.Add "pkg_name", (rsTemp.Fields("pkg_name"))
        pkgInfoHash.Add "pkg_version", (rsTemp.Fields("pkg_version"))
        pkgInfoHash.Add "v_ext", (rsTemp.Fields("v_ext"))
        pkgInfoHash.Add "comments", (rsTemp.Fields("comments"))

        pkgInfoHash.Add "modified_stamp", (rsTemp.Fields("modified_stamp"))
        pkgInfoHash.Add "modifier", (rsTemp.Fields("modifier"))
        pkgInfoHash.Add "modifier_id", (rsTemp.Fields("modifier_id"))
        pkgInfoHash.Add "modifier_email", (rsTemp.Fields("modifier_email"))

        pkgInfoHash.Add "created_stamp", (rsTemp.Fields("created_stamp"))
        pkgInfoHash.Add "creator", (rsTemp.Fields("creator"))
        pkgInfoHash.Add "creator_id", (rsTemp.Fields("creator_id"))
        pkgInfoHash.Add "creator_email", (rsTemp.Fields("creator_email"))

        pkgInfoHash.Add "owner", (rsTemp.Fields("owner"))
        pkgInfoHash.Add "owner_id", (rsTemp.Fields("owner_id"))
        pkgInfoHash.Add "owner_email", (rsTemp.Fields("owner_email"))

        pkgInfoHash.Add "dlocked", (rsTemp.Fields("dlocked"))

        pkgInfoHash.Add "pkg_label", (rsTemp.Fields("pkg_label"))
        pkgInfoHash.Add "src_path", (rsTemp.Fields("src_path"))
        pkgInfoHash.Add "pv_description", (rsTemp.Fields("pv_description"))
        pkgInfoHash.Add "last_pv_id", (rsTemp.Fields("last_pv_id"))
        pkgInfoHash.Add "previous_version", (rsTemp.Fields("previous_version"))
        pkgInfoHash.Add "release_notes_info", (rsTemp.Fields("release_notes_info"))

        pkgInfoHash.Add "is_patch", (rsTemp.Fields("is_patch"))
        pkgInfoHash.Add "is_obsolete", (rsTemp.Fields("is_obsolete"))
        pkgInfoHash.Add "obsolete_comments", (rsTemp.Fields("obsolete_comments"))

        pkgInfoHash.Add "build_type", (rsTemp.Fields("build_type"))
        pkgInfoHash.Add "change_type", (rsTemp.Fields("change_type"))
        pkgInfoHash.Add "bs_id", (rsTemp.Fields("bs_id"))
        pkgInfoHash.Add "is_deployable", (rsTemp.Fields("is_deployable"))
        pkgInfoHash.Add "sbom_priority", (rsTemp.Fields("sbom_priority"))
        pkgInfoHash.Add "ripple_field", (rsTemp.Fields("ripple_field"))

        If (pkgInfoHash.Item ("dlocked") = "Y") OR pkgInfoHash.Item("build_type") = "M" Then
            pkgInfoHash.Add "isInArchive", testArchiveAccessPkg(pkgInfoHash.Item ("pkg_name"), pkgInfoHash.Item ("pkg_version"))
        End If  

       If isaRelease  Then
          '-- Find if package is editable in this project
          '   Not editable if
          '     Imported via a Reference Package
          '     Imported via an SDK
          '     Release is not in Open or Restricted Mode
          '     Project extenstion is project specific - and not within the allowed project
          '     
          OraDatabase.ExecuteSQL "BEGIN  :RETURN_NUMBER := CAN_EDIT_PKG_IN_PROJECT( :PV_ID, :RTAG_ID );  END;"
          pkgInfoHash.Item ("can_edit_in_project") = CStr( OraDatabase.Parameters("RETURN_NUMBER").Value )

           '-- Get Package Release Details
           Set rsTemp = OraDatabase.DbCreateDynaset( GetQuery("PackageReleaseDetails.sql"), cint(0))

           If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
              pkgInfoHash.Add "insert_stamp", (rsTemp.Fields("insert_stamp"))
              pkgInfoHash.Add "insertor", (rsTemp.Fields("insertor"))
              pkgInfoHash.Add "insertor_email", (rsTemp.Fields("insertor_email"))
              pkgInfoHash.Add "used_count", (rsTemp.Fields("used_count"))

              pkgInfoHash.Item ("base_view_id") = (rsTemp.Fields("base_view_id"))
              pkgInfoHash.Item ("view_name") = (rsTemp.Fields("view_name"))
              pkgInfoHash.Item ("pkg_state") = (rsTemp.Fields("pkg_state"))
              pkgInfoHash.Item ("deprecated_state") = (rsTemp.Fields("deprecated_state"))
              pkgInfoHash.Item ("product_state") = (rsTemp.Fields("product_state"))

              pkgInfoHash.Add "proj_id", (rsTemp.Fields("proj_id"))
              pkgInfoHash.Add "rtag_id", (rsTemp.Fields("rtag_id"))
              pkgInfoHash.Add "rtag_name", (rsTemp.Fields("rtag_name"))
              pkgInfoHash.Add "product_state_used", (rsTemp.Fields("product_state_used"))
              pkgInfoHash.Add "sdktag_id", (rsTemp.Fields("sdktag_id"))
              pkgInfoHash.Add "is_sdkpkg", (NOT IsNull(rsTemp.Fields("sdktag_id")))
              pkgInfoHash.Add "is_pegged", (rsTemp.Fields("pegged") <> 0)
              pkgInfoHash.Add "ripple_stop", rsTemp.Fields("ripple_stop")
              pkgInfoHash.Add "persist_ripple_stop", rsTemp.Fields("persist_ripple_stop")
              pkgInfoHash.Add "advisory_ripple", rsTemp.Fields("advisory_ripple") <> 0

           Else
              ' -- Package Version is not a released member of the specified release
              '    Get Basic Release and Project Details
              Query_String = " select pj.PROJ_ID, rt.RTAG_ID,rt.rtag_name " &_
                             " from projects pj, release_tags rt" &_
                             " where rt.rtag_id=:RTAG_ID" &_
                             " and rt.PROJ_ID = pj.PROJ_ID"
              
              Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
              
              If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
                  pkgInfoHash.Add "proj_id",   (rsTemp.Fields("proj_id"))
                  pkgInfoHash.Add "rtag_id",   (rsTemp.Fields("rtag_id"))
                  pkgInfoHash.Add "rtag_name", (rsTemp.Fields("rtag_name"))
              End If

              ' -- Determine if package is a member of this release and determine base view
                  '    May be a WIP or PENDIND or not in the release ( Won't get here if its releases)
              '    Mark as Not in Release
              Query_String = "select wip.pv_id, wip.view_id as view_id, vi.view_name, 0 as env_area from work_in_progress wip, views vi where rtag_id=:RTAG_ID and pv_id=:PV_ID and vi.view_id = wip.view_id" &_
                              " union" &_
                              " select pp.pv_id, pp.view_id  as view_id, vi.view_name, 1 as env_area from planned pp, views vi where rtag_id=:RTAG_ID and pv_id=:PV_ID and vi.view_id = pp.view_id" &_
                              " union" &_
                              " select rc.pv_id, rc.base_view_id as view_id, vi.view_name, 2 as env_area from RELEASE_CONTENT rc, views vi where rtag_id=:RTAG_ID and pv_id=:PV_ID and vi.view_id = rc.base_view_id"
              Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
              If rsTemp.RecordCount < 1 Then
                   pkgInfoHash.Item ("notInRelease") = true
              Else
                pkgInfoHash.Item ("base_view_id") = (rsTemp.Fields("view_id"))
                pkgInfoHash.Item ("view_name") = (rsTemp.Fields("view_name"))
                If rsTemp("env_area") = 0 Then pkgInfoHash.Item ("is_wip") = True
                If rsTemp("env_area") = 1 Then pkgInfoHash.Item ("is_pending") = True
              End If

              '
              ' -- Determine related package that is in the release
              '    Use pkg_id and v_ext to locate package
              If pkgInfoHash.Item ("pkg_id") <> "" Then
                 Query_String = "SELECT pv.PV_ID, vi.view_name" &_
                                          " FROM RELEASE_CONTENT rc, package_versions pv, views vi" &_ 
                                          " WHERE rc.rtag_id = :RTAG_ID" &_
                                          " and rc.PV_ID = pv.pv_id" &_
                                                  " and vi.view_id = rc.base_view_id" &_
                                          " and pv.pkg_id = " & pkgInfoHash.Item ("pkg_id") &_ 
                                          " and NVL(pv.v_ext,'') = NVL('"&pkgInfoHash.Item ("v_ext")&"', '')"
                 Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
                 If rsTemp.RecordCount > 0 Then
                        pkgInfoHash.Item ("pv_id_InRelease") = (rsTemp.Fields("pv_id"))
                    'pkgInfoHash.Remove ("base_view_id")
                    pkgInfoHash.Item ("release_view_name") = (rsTemp.Fields("view_name"))
                 End If
              End If

           End If

           ' Determine if user can make the the package 'unofficial'
           If     (pkgInfoHash.Item ("dlocked") = "Y") _
             AND  (pkgInfoHash.Item ("build_type") = "M") _
             AND  (CDate( FormatDateTime(pkgInfoHash.Item ("modified_stamp"), 2) ) = Date) _
             AND  (pkgInfoHash.Item("can_edit_in_project") = "1" ) _
           Then
                pkgInfoHash.Item ("can_unofficial") = "true"
           End If

          '
          ' Determine if there is a deamon instruction on this package in this release
          ' Also: OraDatabase.ExecuteSQL "BEGIN :OP_CODE_LIST := PK_BUILDAPI.daemon_ops_for_rtag("& nRtag_id & "); END;"
          objEH.TryORA ( OraSession )
          ON ERROR RESUME NEXT
          OraDatabase.ExecuteSQL "BEGIN :OP_CODE_LIST := PK_BUILDAPI.daemon_ops_for_rtag_pvid(:RTAG_ID,:PV_ID); END;"
          objEH.CatchORA ( OraSession )
          ON ERROR GOTO 0
          opCodeListString  = OraDatabase.Parameters("OP_CODE_LIST").Value

          If NOT IsNull(opCodeListString) AND opCodeListString <> "" Then
             opCodeList = Split(opCodeListString, ",")
             For Each opCodeStr In opCodeList
                If opCodeStr = OP_CODE_0_RIPPLE_BUILD_PACKAGE  Then
                    pkgInfoHash.Add "hasRippleInstr", 1
                End If
                If  opCodeStr = OP_CODE_1_TEST_BUILD_PACKAGE  Then
                    pkgInfoHash.Add "hasTestInstr", 1
                End If
                If  opCodeStr = OP_CODE_2_FUTURE_BUILD  Then
                    pkgInfoHash.Add "hasFutureBuild", 1
                End If
             Next
          End If

       Else     ' NOT isaRelease
          If pkgInfoHash.Exists ("modified_stamp") Then
              If NOT IsNull(pkgInfoHash.Item ("modified_stamp").Value) Then
                  If (CDate( FormatDateTime(pkgInfoHash.Item ("modified_stamp"), 2) ) = Date) Then
                     ' Must be not older then a day
                     If (pkgInfoHash.Item ("dlocked") = "A")  OR   NOT IsNull(pkgInfoHash.Item("is_patch")) Then
                        pkgInfoHash.Item ("can_unofficial") = "true"
                     End If
                  End If
              End If
         End If
       End If   ' End isaRelease

       '-- Get Patch Parent
       If pkgInfoHash.Item ("is_patch") = "Y" Then
          Set rsTemp = OraDatabase.DbCreateDynaset( GetQuery("PatchParent.sql"), cint(0))

          If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
             pkgInfoHash.Add "patch_parent_id", (rsTemp.Fields("pv_id"))
          End If
       End If

       ' DEVI-45275 - Check if version is in the planned table and if so get its planned operation type
       ' which denotes whether it is an existing version being added to a release, an existing version
       ' being removed from a release, or a new version being prepared for a release.
       Set rsTemp = OraDatabase.DbCreateDynaset( GetQuery("PlannedPackageVersionDetails.sql"), cint(0))

       If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
          pkgInfoHash.Add "planned_operation", (rsTemp.Fields("operation"))
       Else
          pkgInfoHash.Add "planned_operation", " "
       End If

       ' Determine if we are building this package on any build machine
       '
       pkgInfoHash.Add "isBuilding", isBuilding(SSpv_id)

       'On Error Resume Next
       'On Error Goto 0

       ' check if package is released
       If NOT isaRelease Then
         pkgInfoHash.Add "is_released", False
       Else
         Set rsTemp = OraDatabase.DbCreateDynaset( "SELECT rc.pv_id FROM release_content rc WHERE rc.rtag_id = :RTAG_ID AND rc.pv_id = :PV_ID", cint(0))
         pkgInfoHash.Add "is_released", rsTemp.RecordCount <> 0
       End If

       ' check if package is excluded from build
       pkgInfoHash.Add "is_excluded", False
       pkgInfoHash.Add "has_build_failure", False
       If isaRelease Then
         Set rsTemp = OraDatabase.DbCreateDynaset( "SELECT dnr.pv_id,dnr.root_pv_id FROM do_not_ripple dnr WHERE dnr.rtag_id = :RTAG_ID AND dnr.pv_id = :PV_ID", cint(0))
         If rsTemp.RecordCount <> 0 Then
           pkgInfoHash("is_excluded") = True
           pkgInfoHash("has_build_failure") = IsNull(rsTemp("root_pv_id"))
         End If
       End If

       ' Check if Package is deprecated
       If isaRelease Then
         Set rsTemp = OraDatabase.DbCreateDynaset( "SELECT * FROM DEPRECATED_PACKAGES WHERE RTAG_ID = :RTAG_ID AND "& EmptyToNullString("V_EXT", pkgInfoHash.Item ("v_ext")) &" AND PKG_ID = "& pkgInfoHash.Item ("pkg_id") &"", cint(0))
         If rsTemp.RecordCount > 0 Then
            pkgInfoHash.Add "is_deprecated", True
         End If
       End If

       ' Check if package is a NEW package - only one version in existence
       If pkgInfoHash.Item ("pkg_id") <> "" Then
           Set rsTemp = OraDatabase.DbCreateDynaset( "select count(*) as count from package_versions pv where pkg_id = " & pkgInfoHash.Item ("pkg_id"), cint(0))
           pkgInfoHash.Add "pkg_count" , rsTemp("count")
       End If

       ' Does this package have any dependencies
       Set rsTemp = OraDatabase.DbCreateDynaset( "select count(*) as depCount from package_dependencies where pv_id = :PV_ID", cint(0))
       pkgInfoHash.Add "depCount" , rsTemp("depCount")
        End If

   rsTemp.Close
   Set rsTemp = nothing

   OraDatabase.Parameters.Remove "PV_ID"
   OraDatabase.Parameters.Remove "RTAG_ID"
   OraDatabase.Parameters.Remove "RETURN_NUMBER"
   OraDatabase.Parameters.Remove "OP_CODE_LIST"

End Sub

'-----------------------------------------------------------------------------------------------------------------------------
'       Add information to the pkgInfoHash describing the S3 Sync
'       Added only when required
'       Assumes that Get_Pkg_Info has already been called 
'       Calculate: 
'               s3Sync - This package in this release is marked for S3Sync
'       s3SyncEnabled - This Release has s3 sync enabled
'               s3SyncContent - This version of the package appears to have S3Sync content
Sub Get_Pkg_Info_s3Sync ()
        Dim Query_String, rsTemp, pvidInRelease

        pkgInfoHash.Add "s3Sync", "N"
        pkgInfoHash.Add "s3SyncEnabled", "N"
        pkgInfoHash.Add "s3SyncContent", "N"

        If pkgInfoHash.Item ("isaRelease") Then

                '       Use the base package in a Release if this is a WIP or in Pending
                '       as the property will be inherited when the package is updated
                '
                pvidInRelease = pkgInfoHash.Item ("pv_id_InRelease")
                If pvidInRelease = "" Then
                        pvidInRelease = pkgInfoHash.Item ("pv_id")
                End If

                OraDatabase.Parameters.Add "PV_ID",         pvidInRelease,    ORAPARM_INPUT, ORATYPE_NUMBER
                OraDatabase.Parameters.Add "RTAG_ID",       pkgInfoHash.Item ("rtag_id"),  ORAPARM_INPUT, ORATYPE_NUMBER

                  Query_String = _
                        " SELECT NVL(rc.s3sync, 'N') as s3sync, NVL(rt.s3sync, 'N') AS s3syncenabled, nvl2(s3.file_path, 'Y', 'N') AS s3synccontent" &_
                        " FROM release_content rc, release_tags rt, (" &_
                        "     SELECT rcp.* FROM release_components rcp, release_content rc WHERE rc.rtag_id = :RTAG_ID" &_
                        "           AND rc.pv_id = rcp.pv_id" &_
                        "           AND rcp.file_name IS NULL" &_
                        "           AND rcp.file_path LIKE 'pkg/S3TRANSFER'" &_
                        " ) s3" &_
                        " WHERE rc.rtag_id = rt.rtag_id" &_
                        "       AND rc.pv_id = :PV_ID" &_
                        "       AND rt.rtag_id = :RTAG_ID" &_
                        "       AND s3.pv_id (+) = rc.pv_id"

                  Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
                  If rsTemp.RecordCount > 0 Then
                        pkgInfoHash.Item ("s3Sync") = (rsTemp.Fields("s3Sync"))
                        pkgInfoHash.Item ("s3SyncEnabled") = (rsTemp.Fields("s3SyncEnabled"))
                        pkgInfoHash.Item ("s3SyncContent") = (rsTemp.Fields("s3SyncContent"))
                  End If

                OraDatabase.Parameters.Remove "PV_ID"
                OraDatabase.Parameters.Remove "RTAG_ID"

                rsTemp.Close
                Set rsTemp = nothing
        End If

End Sub

'-----------------------------------------------------------------------------------------------------------------------------
' Get Package Info - when we don't have a package
Sub Get_NoPkg_Info(NNrtag)
        Dim rsTemp, Query_String
        OraDatabase.Parameters.Add "RTAG_ID",           NNrtag,         ORAPARM_INPUT, ORATYPE_NUMBER

        pkgInfoHash.Item ("can_unofficial") = "false"
        pkgInfoHash.Item ("noPackage") = true

        '/* Get Basic Details */
    Query_String = " select pj.PROJ_ID, rt.RTAG_ID,rt.rtag_name " &_
                   " from projects pj, release_tags rt" &_
                   " where rt.rtag_id=:RTAG_ID" &_
                   " and rt.PROJ_ID = pj.PROJ_ID"

        Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))

        If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
                pkgInfoHash.Add "proj_id", (rsTemp.Fields("proj_id"))
                pkgInfoHash.Add "rtag_id", (rsTemp.Fields("rtag_id"))
                pkgInfoHash.Add "rtag_name", (rsTemp.Fields("rtag_name"))
        End If

   OraDatabase.Parameters.Remove "RTAG_ID"
End Sub

'-----------------------------------------------------------------------------------------------------------------------------
Sub Get_Pkg_Short_Info( SSparPv_id, SSpkgID, SSpkgName, SSpkgVersion, SSsrc_path, SSpkgDesc, BBdlocked )
   Dim rsTemp, Query_String
   If IsEmpty(SSparPv_id) Then Exit Sub

   Query_String = _
   " SELECT pkg.pkg_id, pkg.pkg_name, pv.pkg_version, pv.src_path, pv.pv_description, pv.dlocked"&_
   "  FROM packages pkg, package_versions pv"&_
   " WHERE pkg.pkg_id = pv.pkg_id  AND pv.pv_id ="& SSparPv_id

   Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))

   If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
      SSpkgID = rsTemp.Fields("pkg_id")
      SSpkgName = rsTemp.Fields("pkg_name")
      SSpkgVersion = rsTemp.Fields("pkg_version")
      SSsrc_path = rsTemp.Fields("src_path")
      SSpkgDesc = rsTemp.Fields("pv_description")
      BBdlocked = rsTemp.Fields("dlocked")
   End If

   rsTemp.Close
   Set rsTemp = nothing
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Private Function IsDomainAuthOK( SSusername, SSpassword, SSdomainName )
   Dim objLoginAuth, return, tempSTR

   Set objLoginAuth = Server.CreateObject("LoginAdmin.ImpersonateUser")
   return = objLoginAuth.AuthenticateUser ( SSusername, SSpassword, SSdomainName )

   'Response.write "LOGIN"& SSusername &"-"& SSpassword &"-"& SSdomainName &"-"& return

   If (return = 0) OR (return = 1385) Then
      ' From MSDN System Error Codes
      ' 0 - The operation completed successfully.
      ' 1326 - Logon failure: unknown user name or bad password.
      ' 1385 - Logon failure: the user has not been granted the requested logon type at this computer.
      ' 1909 - The referenced account is currently locked out and may not be used to log on.

      'Login ok
      IsDomainAuthOK = True
   Else
      IsDomainAuthOK = False
   End If

   Set objLoginAuth = Nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function ReadUserPreferences ( SSitem )
   'ReadUserPreferences = Request.Cookies("RELEASEMANAGER_USER_PREFERENCES")( SSitem )
   ReadUserPreferences = "0"
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function Requred_Parameters_String ( SScurrent, SSstr )
   'returns "&par1=val1&&parn=valn&"            must use & as it will not be used on parameter name or value
   Dim tempARR, parameter, tempSTR
   tempARR = Split( SSstr, "," )
   tempSTR = SScurrent

   For Each parameter In tempARR
      tempSTR = tempSTR &"&"& parameter &"="& QStrPar( parameter ) &"&"
   Next

   Requred_Parameters_String = tempSTR
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function Quick_Help ( SStipname )
   Quick_Help = "<span onMouseOver=""formTips.show('"& SStipname &"')"" onMouseOut=""formTips.hide()""><img src='images/i_help.gif' width='12' height='12' hspace='2' align='absmiddle' border='0' ></span>"
End Function
Function Quick_HelpImg ( SStipname, SSimage )
   Quick_HelpImg = "<span onMouseOver=""formTips.show('"& SStipname &"')"" onMouseOut=""formTips.hide()""><img src='"&SSimage&"' width='12' height='12' hspace='2' align='absmiddle' border='0' ></span>"
End Function

'-----------------------------------------------------------------------------------------------------------------------------
Function LogError ( SSlog, SSstr )
   '|errstr1||errstr2||errstr3|...
   LogError = SSlog &"|"& SSstr &"|"
End Function
'-----------------------------------------------------------------------------------------------------------------------------
'   Send an email
'   Args:   SSfromName      - Text Name of sender
'           SSfrom          - email address of sender
'           SSto            - email address of receipient. May be comma sep list or a some type of object
'           SSsubject       - email subject
'           SSbody          - Body of the email. Email is sent as html.
'           oAttachments    - email attachments. May be empty, a file or a HashRef of files
'
Sub Send_Email ( SSfromName, SSfrom, SSto, SSsubject, SSbody, oAttachments )
   Dim Mail, Keys, Key, canSend
'Response.write "<pre>Send_Email:SSfromName:" & SSfromName
'Response.write "<br>Send_Email:SSfrom:" & SSfrom
'Response.write "<br>Send_Email:SSto:" & SSto
'Response.write "<br>Send_Email:SSsubject:" & SSsubject
'Response.write "<br>Send_Email:SSbody:" & SSbody

   canSend = FALSE
   Set Mail = Server.CreateObject("Persits.MailSender")
   Mail.Host = MAIL_SERVER
   Mail.From = SSfrom
   Mail.FromName = SSfromName

   ' Send TO:
   ' Handle a Dictionary of names
   If IsObject(SSto) AND (TypeName(SSto) <> "IOraField") Then
      Keys = SSto.Keys
      For Each Key In Keys
         Mail.AddAddress Key, SSto.Item( Key )
      Next

      If SSto.Count > 0 Then canSend = TRUE
   Else

      Mail.AddAddress SSto
      If SSto <> "" Then canSend = TRUE
   End If

   Mail.Subject = SSsubject
   Mail.IsHTML = True
   Mail.Body = SSbody

   If NOT IsEmpty(oAttachments) AND NOT IsNull(oAttachments) Then
       ' Add Attachments     DDDDDDD  Sash,
       ' It appears as if AddEmbededImage is premium functionality that costs money, can we just do a normal add attachment?
       If IsObject( oAttachments ) Then
          Keys = oAttachments.Keys
          For Each Key In Keys
       '      Mail.AddEmbeddedImage rootPath & Key, oAttachments.Item( Key )
              Mail.AddAttachment oAttachments.Item( Key )
          Next
        Else
              Mail.AddAttachment oAttachments
       End If
    End If

   On Error Resume Next
   If canSend Then   Mail.Send   ' send message

End Sub

'-----------------------------------------------------------------------------------------------------------------
'   Record and Report a Release Manager event
'       Record in the machines Event Log
'       Report via email
'   Used to report error conditions that need to be bought to the attention of some sys admin
'   Args:   eventType       - one of enumEVENT_* ( ie:enumEVENT_ERROR)
'           SSlocation      - Indication of location/operation
'           SSvalues        - Values. Will be added into the message
'           SSerror_message - Error message
'
Sub Report_Event ( eventType, SSlocation, SSvalues, SSerror_message  )
    On Error Resume Next
    Dim WshNetwork, SSmsg
    Set WshNetwork = Server.CreateObject("WScript.Network")

   ' Compose Message
   SSmsg = _
   "-- User Info  --"& VBNewLine &_
   "Logged In: " & objAccessControl.UserLogedIn & VBNewLine &_
   "Domain: " & objAccessControl.Domain & VBNewLine &_
   "UserName: " & objAccessControl.UserName & VBNewLine &_
   "FullName: " & objAccessControl.FullName & VBNewLine &_
   "UserEmail: " & objAccessControl.UserEmail & VBNewLine &_
   "UserId: " & objAccessControl.UserId & VBNewLine &_
   VBNewLine &_
   "-- Script Info  --"& VBNewLine &_
   "Host Name: "& Request.ServerVariables("SERVER_NAME") & ":" & Request.ServerVariables("SERVER_PORT") & VBNewLine &_
   "Script Name: "& Request.ServerVariables("SCRIPT_NAME") & VBNewLine &_
   VBNewLine &_
   "-- Error Location --"& VBNewLine &_
   SSlocation & VBNewLine &_
   VBNewLine &_
   "-- Values --"& VBNewLine &_
   SSvalues & VBNewLine &_
   VBNewLine &_
   "-- Error Message --"& VBNewLine &_
   SSerror_message & VBNewLine

    '-- Raise this message at these places...
    '-- Create an event in the system event log
    '-- Send out an email
    Call Send_Event( eventType, SSmsg )
    Call Send_Email ( "Release Manager Notification", _
                       ADMIN_EMAIL, _
                       FAULT_EMAIL_LIST, _
                       "Release Manager Error", _
                       Replace(SSmsg,VBNewLine, "<br>"), _
                       null )

    '----------------------------------------
   Set WshNetwork = Nothing
End Sub

'-----------------------------------------------------------------------------------------------------------------------------
'   Record Event in OS log
'   Create an event in the system event log
'
'   Args:   eventType       - one of enumEVENT_* ( ie:enumEVENT_ERROR)
'           SSmsg           - Message Body
Sub Send_Event( eventType, SSmsg )
    On Error Resume Next
    Dim WshShell
    Set WshShell = Server.CreateObject("WScript.Shell")
    WshShell.LogEvent eventType, SSmsg
    Set WshShell = Nothing
End Sub

'-----------------------------------------------------------------------------------------------------------------------------
Sub Iterate_UP_the_tree ( NNrtag_id, HHstart_with, HHresult )
   Dim rsTemp, Query_String
   Dim seekPKGs, seekNOTpkgs

   seekPKGs = Join(HHstart_with.Keys, ",")
   If seekPKGs = "" Then seekPKGs = "-1"
   seekNOTpkgs = "-1"

   Do While seekPKGs <> "-1"
      Query_String = _
      " SELECT DISTINCT dep.pkg_id"&_
      "    FROM package_dependencies dep, release_content rel"&_
      "   WHERE rel.pv_id = dep.pv_id"&_
      "     AND rel.rtag_id = "& NNrtag_id &_
      "     AND dpkg_id IN ( "& seekPKGs &" ) "&_
      "     AND pkg_id NOT IN ( "& seekNOTpkgs &" )"
      '"     AND dep.dpv_id NOT IN ( SELECT iw.iw_id FROM ignore_warnings iw WHERE iw.rtag_id = "& NNrtag_id &" )"
      Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))

      If rsTemp.RecordCount < 1 Then Exit Do

      seekPKGs = "-1"
      While ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF))
         If NOT HHresult.Exists(Cstr(rsTemp.Fields("pkg_id"))) Then HHresult.Add Cstr(rsTemp.Fields("pkg_id")), ""
         seekPKGs = seekPKGs &","& rsTemp.Fields("pkg_id")
         rsTemp.MoveNext
      WEnd

      seekNOTpkgs = seekNOTpkgs &","& seekPKGs
   Loop

End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Sub Iterate_DOWN_the_tree (   NNrtag_id, HHstart_with, HHresult )
   Dim rsTemp, Query_String
   Dim seekPKGs, seekNOTpkgs

   seekPKGs = Join(HHstart_with.Keys, ",")
   If seekPKGs = "" Then seekPKGs = "-1"
   seekNOTpkgs = "-1"

   Do While seekPKGs <> "-1"
      Query_String = _
      " SELECT DISTINCT dep.dpkg_id"&_
      "    FROM package_dependencies dep, release_content rel"&_
      "   WHERE rel.pv_id = dep.pv_id"&_
      "     AND rel.rtag_id = "& NNrtag_id &_
      "     AND pkg_id IN ( "& seekPKGs &" ) "&_
      "     AND dpkg_id NOT IN ( "& seekNOTpkgs &" )"
      Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))

      If rsTemp.RecordCount < 1 Then Exit Do

      seekPKGs = "-1"
      While ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF))
         If NOT HHresult.Exists(Cstr(rsTemp.Fields("dpkg_id"))) Then HHresult.Add Cstr(rsTemp.Fields("dpkg_id")), ""
         seekPKGs = seekPKGs &","& rsTemp.Fields("dpkg_id")
         rsTemp.MoveNext
      WEnd

      seekNOTpkgs = seekNOTpkgs &","& seekPKGs
   Loop

End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Class TempSession
   Function Value ()
      Value = Session("RELEASEMANAGER_temp")
   End Function

   Sub Add ( SSstr )
      Session("RELEASEMANAGER_temp") = Session("RELEASEMANAGER_temp") & SSstr
   End Sub

   Sub Clean ()
      Session("RELEASEMANAGER_temp") = NULL
   End Sub
End Class
'-----------------------------------------------------------------------------------------------------------------------------
Sub DisplayInfo ( SSmsg, SSwidth )
   Dim msg
   If SSmsg = "" Then Exit Sub

   Select Case UCase( SSmsg )
   Case "ISSUES_IMPORTED"
      msg = "Import is complete. <br>Click on Close button if you are finished."
   Case "MAKE_OFFICIAL_WARNING"
      msg = "Note that making a package official will prevent any further change to it."
   Case "APPLY_LABEL_TO_ALL_WARNING"
      msg = "This will overwrite any existing labels on selected packages."
   Case "BLANK_LABEL_WARNING"
      msg = "Some dependencies in the export list above, do not have a label!"
   Case "PERSONAL_VIEW_NOT_SETUP"
      msg = "<span class='err_alert'><b>Your View is not setup!</b></span><span class='sublbox_txt'><br><br>Either set your view using My&nbsp;Account&nbsp;&gt;&nbsp;Views menu<br><br>OR<br><br>switch to Base view (Full view) by clicking on <img src='images/abtn_personal_view.gif' width='25' height='25' border='0'> icon above.</span>"
   Case "EMPTY_RELEASE_CONTENTS"
      msg = "<span class='err_alert'><b>Release content is empty!</b></span><span class='sublbox_txt'><br><br>Use + button to add packages to a release.</span>"
   Case "PKG_NAME_REQUIRED"
      msg = "<span class='err_alert'><b>Package Name required!</b></span><span class='sublbox_txt'><br>You are required to select at least one package name.</span>"
   Case "ADD_PATCH_WARNING"
      msg = "Note that patches cannot be used in your build dependencies."
   Case "NEW_PATCH_AVAILABLE"
      msg = "<b>New Patch is Required</b><br>One or more Build Dependencies have been patched.<br>Please click Add button to create patch for this package."

   Case "NOT_FOUND_IN_PKG_ARCHIVE_RELEASE_NOTES"
      msg = "<b>Regenerating release notes...</b><br>It may take a minute. Please try refreshing this page a bit later."
   Case "FAILED_GENERATING_RELEASE_NOTES"
      msg = "<span class='err_alert'><b>Failed generating release notes!</b></span>"
   Case "GENERATING_RELEASE_NOTES"
      msg = "<b>Generating release notes...</b><br>It may take a minute. Please try refreshing this page a bit later."
   Case "NO_PREVIOUS_VERSION_RELEASE_NOTES"
       msg = "<b>Previous Version is Unknown</b>!<br>Please specify previous version by clicking on 'Show Details...' above.<br>Release notes are not generated."
   Case "RELEASE_NOTES_PLACEHOLDER_PACKAGE"
       msg = "<b>Place Holding Package</b>!<br>This package is manually built, does not have a build standard and does not exist in dpkg_archive. It is used as a placeholder.<br>Release notes are not generated."

   Case "PACKAGE_FOUND_IN_OTHER_LOCATIONS"
      msg = "This package is also found in other locations."
   Case "DOC_NUMBER_NOTFOUND"
      msg = "<span class='err_alert'>Document number "& Request("doc_num") &" does not correspond to any document!</span>"
   Case "DOC_NUMBER_FOUND"
      msg = "Document found. Click &quot;Import&quot; to link the document."
   Case "UNIT_TEST_NOT_DONE"
      msg = "<b>Unit test is Not Done!</b><br><span href='_wform_reason_for_unit_test_not_done.asp?pv_id="& Request("pv_id") &"&rtag_id="& Request("rtag_id") &"'class='pointer txt_linked vixIframeDialog' title='Edit Reason'>Click here</span> to supply/edit reason."
   Case "PACKAGE_NOT_PART_OF_RELEASE"
      msg = "<b>Package is Not Part of This Release Anymore!</b><br>This package cannot be found in the list on the left-hand side.<br>You can use 'lookup:' on the left-hand side to find the package inside this release. "

   Case "NOT_FOUND_IN_PKG_ARCHIVE_FILE_GENERATE"
      msg = "<b>This package is not found in dpkg_archive!</b><br>Files and folders are not captured."
   Case "NO_PRODUCT_FILES_CAPTURED"
      msg = "<b>Files and Folders not found for this product!</b><br>Capture of product components can only be done during the build time."

   Case "MASS REF REFERENCE"
      msg = "<span class='err_alert'><b>New Version can only be created in the Release's associated MASS REF: <a href=""dependencies.asp?pv_id="& pkgInfoHash.Item("pv_id") &"&rtag_id="& AssocMASSREFValue &""">"& pkgInfoHash.Item("pkg_name") &" "& pkgInfoHash.Item("pkg_version") &"</a></b></span>"

   Case "REPEAT_SCHEDULE_NOT_SELECTED"
      msg = "<span class='err_alert'><b>YOU MUST SELECT A VALUE FOR REPEAT SCHEDULED DOWNTIME</b></span>"

   Case "PKG_NAME_INVALID"
      msg = "<span class='err_alert'><b>Package Name Invalid!</b></span><span class='sublbox_txt'><br>This package name is invalid. Package names must only consist of alpha-numeric characters, underscores and dashes (A-Z 0-9 _ -), and cannot include spaces or any other symbols.</span>"

   Case "PKG_NAME_EXISTS"
      msg = "<span class='err_alert'><b>Package Name Already Exists!</b></span><span class='sublbox_txt'><br>This package name already exists, please try again.</span>"

   End Select
%>
<table width="<%=SSwidth%>" border="0" cellspacing="0" cellpadding="1">
  <tr>
    <td background="images/bg_bage_dark.gif">
     <table width="100%" border="0" cellspacing="0" cellpadding="3">
        <tr class='bg_help'>
          <td width="1%" valign="top"><img src="images/i_qhelp.gif" width="16" height="16"></td>
          <td width="100%" class="form_txt"><%=msg%></td>
        </tr>
      </table></td>
  </tr>
</table>
<br>
<%

End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Sub Messenger ( sMessage, nMessageType, sWidth )
   Dim msgTemplate, Img

   If (sMessage = "") OR IsNull(sMessage) Then Exit Sub

   Select Case CStr(nMessageType)
      Case "1"
         Img = "s_critical.gif"
      Case "2"
         Img = "s_warning.gif"
      Case "3"
         Img = "s_note.gif"
      Case Else
         Img = nMessageType
   End Select


   msgTemplate = ReadFile( APP_ROOT &"\scripts\message_style.html" )
   msgTemplate = Replace( msgTemplate, "%WIDTH%", sWidth )
   msgTemplate = Replace( msgTemplate, "%IMAGE%", Img )
   msgTemplate = Replace( msgTemplate, "%MESSAGE%", sMessage )

   Response.write msgTemplate
End Sub
'-----------------------------------------------------------------------------------------------------------------------------
Function Default_Label ( SSpv_id, SSbuild_type, SSchange_type, SSpkg_name, SSpkg_version, SSv_ext )
    If SSbuild_type = "A" Then
        If  SSchange_type = "F" Then
            Default_Label = SSpkg_name & "_" & SSpkg_version & ".WIP"
        else
            Default_Label = UCase(SSpkg_name & "." & SSpv_id & SSv_ext) & ".WIP"
        End If
    Else
        Default_Label = SSpkg_name & "_" & SSpkg_version
    End If
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function Format_Version ( SSpkg_version, SSv_ext )
   Dim tempArr, tempVersion, patchArr, seg, myVersion
   myVersion = SSpkg_version

   If NOT IsNull(SSv_ext) Then
      myVersion = Left ( myVersion, Len(myVersion) - Len(SSv_ext) )
   End If

   tempArr = Split (myVersion, ".")
   For Each seg In tempArr
      If Len(seg) < 2 Then
         ' single digit number
         tempVersion = tempVersion &"0"& seg

      Else
         seg = Replace(seg, "_", "-")   ' make sure that there is no _ in segment
         If InStr( seg, "-" ) > 0 Then
            ' patch version supplied
            patchArr = Split(seg, "-")
            If Len(patchArr(0)) < 2 Then
               ' single digit number
               tempVersion = tempVersion &"0"& patchArr(0) &"_0"& patchArr(1)
            Else
               ' double digit number
               tempVersion = tempVersion & patchArr(0) &"_0"& patchArr(1)
            End If

         Else
            ' double digit no patch
            tempVersion = tempVersion & seg
         End If

      End If

   Next

   Format_Version = tempVersion
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function DefineStateIcon ( NNpkg_state, CCdlocked, sIgnoreWarnings, cIsPatchIgnore, cBuildType, bForEnvironment )
        
   If IsNull(NNpkg_state) Then
          DefineStateIcon = ""
          Exit Function
   End If

   If NOT IsNull(sIgnoreWarnings) Then
      '-- Ignore Warning is on
      If IsNull(cIsPatchIgnore) Then
         DefineStateIcon = enum_imgIgnoring
      Else
         DefineStateIcon = enum_imgPatchIgnoring
      End If

   Else
      Select Case CInt( NNpkg_state )
         Case enumPKG_STATE_OK
            If (CCdlocked = "N") OR (CCdlocked = "R") Then
               DefineStateIcon = enum_imgBuilding
            ElseIf (CCdlocked = "P") Then
               DefineStateIcon = enum_imgPending
            ElseIf (CCdlocked = "A") Then
               DefineStateIcon = enum_imgApproved
            Else
               DefineStateIcon = enum_imgBlank
            End If

         Case enumPKG_STATE_MAJOR
            DefineStateIcon = enum_imgCritical

         Case enumPKG_STATE_MINOR
            DefineStateIcon = enum_imgWarning

         Case enumPKG_STATE_MAJOR_READY
            DefineStateIcon = enum_imgCReady

         Case enumPKG_STATE_MINOR_READY
            DefineStateIcon = enum_imgWReady

         Case enumPKG_NOT_FOUND
            DefineStateIcon = enum_imgNotFound

         Case enumPKG_STATE_NEW_PATCH
            DefineStateIcon = enum_imgPatchAvailable

         Case enumPKG_STATE_DEPRECATED
            DefineStateIcon = enum_imgDeprecated

         Case enumPKG_STATE_DEPRECATED_DEPENDENT
            DefineStateIcon = enum_imgDeprecatedDependent

         Case enumPKG_ADVISORY_RIPPLE
            DefineStateIcon = enum_imgAR

         Case enumPKG_ADVISORY_RIPPLE_DEPENDENT
            DefineStateIcon = enum_imgARD

         Case enumPKG_PEGGED_VERSION
            DefineStateIcon = enum_imgGreenPin

         Case enumPKG_SDK_IMPORT
            DefineStateIcon = enum_imgSdkImport

         Case enumPKG_SDK_DEPENDENCY
            DefineStateIcon = enum_imgSdkDep

         Case enumPKG_UNBUILDABLE
            DefineStateIcon = enum_imgUnBuildable

         Case enumPKG_BUILDING
             DefineStateIcon = enum_imgCompiling

         Case enumPKG_SCHEDULED
             DefineStateIcon = enum_imgScheduled

        Case enumPKG_BUILDFAIL
             DefineStateIcon = enum_imgBuildFail

        Case enumPKG_BUILDEXCLUDE
             DefineStateIcon = enum_imgBuildExclude

      End Select

      If (NOT bForEnvironment) AND _
         (cBuildType = "A") AND _
         (CCdlocked <> "Y") AND _
         (DefineStateIcon <> enum_imgBlank) AND _
         (DefineStateIcon <> enum_imgBuilding)  AND  _
         (DefineStateIcon <> enum_imgNotFound) OR _
         ( Request("rtag_id") = ""  AND  Request("FRrtag_id") = "")  _
         Then

         DefineStateIcon = ""

       End If
   End If
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function DefineStateIconSimple ( NNpkg_state, CCdlocked)

      DefineStateIconSimple = ""
      Select Case CInt( NNpkg_state )
         Case enumPKG_STATE_OK
            If (CCdlocked = "R") OR (CCdlocked = "A") Then
               DefineStateIconSimple = enum_imgBuilding
            ElseIf (CCdlocked = "P") Then
               DefineStateIconSimple = enum_imgPending
            ElseIf (CCdlocked = "Y") Then
               DefineStateIconSimple = enum_imgReleasedLocked
            ElseIf (CCdlocked = "N") Then
               DefineStateIconSimple = enum_imgReleasedUnlocked
            Else
               DefineStateIconSimple = enum_imgBlank
            End If

         Case enumPKG_STATE_MAJOR
            DefineStateIconSimple = enum_imgCritical

         Case enumPKG_STATE_MINOR
            DefineStateIconSimple = enum_imgWarning

         Case enumPKG_STATE_MAJOR_READY
            DefineStateIconSimple = enum_imgCReady

         Case enumPKG_STATE_MINOR_READY
            DefineStateIconSimple = enum_imgWReady

         Case enumPKG_NOT_FOUND
            DefineStateIconSimple = enum_imgNotFound

         Case enumPKG_STATE_NEW_PATCH
            DefineStateIconSimple = enum_imgPatchAvailable

         Case enumPKG_STATE_DEPRECATED
            DefineStateIconSimple = enum_imgDeprecated

         Case enumPKG_STATE_DEPRECATED_DEPENDENT
            DefineStateIconSimple = enum_imgDeprecatedDependent

         Case enumPKG_ADVISORY_RIPPLE
            DefineStateIconSimple = enum_imgAR

         Case enumPKG_ADVISORY_RIPPLE_DEPENDENT
            DefineStateIconSimple = enum_imgARD

         Case enumPKG_PEGGED_VERSION
            DefineStateIconSimple = enum_imgGreenPin

         Case enumPKG_SDK_IMPORT
            DefineStateIconSimple = enum_imgSdkImport

         Case enumPKG_SDK_DEPENDENCY
            DefineStateIconSimple = enum_imgSdkDep

      End Select
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function DefineStateSmallIcon ( NNpkg_state, CCdlocked )
   Select Case CInt( NNpkg_state )
   Case enumPKG_STATE_OK
      If CCdlocked = "N" Then
         DefineStateSmallIcon = enum_SMALL_imgBuilding
      Else
         DefineStateSmallIcon = enum_SMALL_imgOK
      End If

   Case enumPKG_STATE_MAJOR
      DefineStateSmallIcon = enum_SMALL_imgCritical

   Case enumPKG_STATE_MINOR
      DefineStateSmallIcon = enum_SMALL_imgWarning

   Case enumPKG_STATE_MAJOR_READY
      DefineStateSmallIcon = enum_SMALL_imgCReady

   Case enumPKG_STATE_MINOR_READY
      DefineStateSmallIcon = enum_SMALL_imgWReady

   End Select
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function PatchIcon ( cIsPatch, cIsPatchObsolete )
   If IsNull(cIsPatch) Then
      PatchIcon = "<img src='images/rex_images/ext_blank.gif' width='16' height='16' border='0' align='absmiddle'>"
   Else
      If IsNull(cIsPatchObsolete) Then
         PatchIcon = "<img src='images/i_patch_small.gif' width='16' height='16' border='0' align='absmiddle' >"
      Else
         PatchIcon = "<img src='images/i_patch_small_obsolete.gif' width='16' height='16' border='0' align='absmiddle' title='Patch is obsolete'>"
      End If
   End If
End Function
'-----------------------------------------------------------------------------------------------------------------------------
' Function that returns true of false if the item exists in the array
'-----------------------------------------------------------------------------------------------------------------------------
Function inArray(item, aItems)
   Dim element
   inArray = false
   for each element in aItems
      If element = item Then
         inArray=true
      End If
   next
End Function
'-----------------------------------------------------------------------------------------------------------------------------
' Function:     GetCurrentParameters    
' Description:  Setup some very basic data that is common to (almost) pages
'               Uses Request("proj_id"), Request("rtag_id") and Request("pv_id")
'
'               Given an rtag_id it will determine the enclosing project
'
'               If a valid Release will also fill in releaseInfoHash
'                   Done here as its info we will need any way and its better to have
'                   one database access than two ( or three )
'
' Returns:      nProjId     proj_id of rtag_id
'               sProjName
'               nRtagId     rtag_id
'               sRtagName
'               nPvid       pv_id
'
'               releaseInfoHash - Populates
'
Function GetCurrentParameters( nProjId, sProjName, nRtagId, sRtagName, nPvId )
   Dim rsQry,query

   ' Set defaults
   nProjId    = -1
   sProjName  = ""
   nRtagId    = -1
   sRtagName  = ""
   nPvId      = -1

   ' Set the ID values from the url
   If Request("pv_id") <> ""   Then nPvId   = CDbl(Request("pv_id"))
   If Request("proj_id") <> "" Then nProjId = CDbl(Request("proj_id"))
   If Request("rtag_id") <> "" Then nRtagId = CDbl(Request("rtag_id"))


   ' Get parameters from database

   If Request("rtag_id") <> "" Then
       GetReleaseInfo (nRtagId)
       sProjName = UCase(releaseInfoHash("proj_name"))
       nProjId = CDbl(releaseInfoHash("proj_id")) 
       sRtagName = releaseInfoHash("rtag_name")

   ElseIf Request("proj_id") <> "" Then
      OraDatabase.Parameters.Add "PROJ_ID",       Request("proj_id"),   ORAPARM_INPUT, ORATYPE_VARCHAR2

      query = _
      " SELECT proj.proj_name, proj.proj_id"&_
      " FROM projects proj"&_
      " WHERE proj.proj_id = :PROJ_ID"

      Set rsQry = OraDatabase.DbCreateDynaset( query, cint(0))
      If ((NOT rsQry.BOF) AND (NOT rsQry.EOF)) Then
         sProjName = UCase(rsQry.Fields("proj_name"))
      End If
      rsQry.Close()
      Set rsQry = nothing
      OraDatabase.Parameters.Remove "PROJ_ID"
    
   End If


End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function GetEnvName ( nEnvTab )
   Select Case CInt( nEnvTab )
      Case enumENVTAB_WORK_IN_PROGRESS
         GetEnvName = "Work In Progress"

      Case enumENVTAB_PLANNED
         GetEnvName = "Pending"

      Case enumENVTAB_RELEASED
         GetEnvName = "Released"

   End Select

End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function Title (rtagId)
   Dim rsQry

   If rtagId = "" Then
      Title = "Release Manager"
   Else
      Set rsQry = OraDatabase.DbCreateDynaset( "SELECT RT.RTAG_NAME, P.PROJ_NAME FROM PROJECTS P, RELEASE_TAGS RT WHERE RT.PROJ_ID = P.PROJ_ID AND RT.RTAG_ID="& rtagId, ORADYN_DEFAULT )
      Title = rsQry("proj_name")&">"&rsQry("rtag_name")
      rsQry.Close()
      Set rsQry = Nothing
   End If

End Function
'-------------------------------------------------------------------------------------
Function Check_Package_WIP_Already_Exists(NNrtag_id, NNpv_id)
   Dim Query_String, rsQry

   Query_String = _
   "   SELECT * "&_
   "   FROM planned pl, package_versions pv "&_
   "   WHERE pl.rtag_id = "& NNrtag_id &_
   "   AND pv.pv_id = pl.pv_id "&_
   "   AND pv.dlocked = 'A' "&_
   "   AND pv.pkg_id = (SELECT pkg_id "&_
       "                  FROM package_versions "&_
       "                 WHERE pv_id = "& NNpv_id &") "&_
   "   AND pv.v_ext = (SELECT v_ext "&_
   "                  FROM package_versions "&_
       "                 WHERE pv_id = "& NNpv_id &")"


   Set rsQry = OraDatabase.DbCreateDynaset( Query_String , cint(0) )

   Check_Package_WIP_Already_Exists = rsQry.RecordCount

   rsQry.Close()
   Set rsQry = Nothing
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function ValidateCodeReviewURL ( sCodeReviewURL )
  Dim isValid
  Dim sTempBaseURL
  Dim httpRegEx
   Set httpRegEx = new RegExp

   httpRegEx.Pattern = "^https?:\/\/"

   ' Removes ending slash from project's base URL for ease of comparison.
   sTempBaseURL = Left(baseURL, Len(baseURL)-1)
   ' Removes the project's base URL from the URL specified (if it's present).
   codeReviewURL = Replace(sCodeReviewURL, sTempBaseURL, "")
   ' Removes the slash from the beginning of the resulting URL (if it's present).
   If InStr(codeReviewURL, "/") = 1 Then
     codeReviewURL = Replace(codeReviewURL, "/", "", 1, 1)
   End If

   ' If the URL doesn't contain the http:// prefix, assume that it's correct.
   If NOT httpRegEx.Test(codeReviewURL) AND Len(codeReviewURL) > 0 Then
     isValid = True
   Else
     ' If the URL still contains the http:// prefix and is longer than the base
     ' URL, assume that it is an invalid URL because of a differing base URL.
     If Len(sCodeReviewURL) > Len(baseURL) Then
       Response.Write("<script type='text/javascript'>alert('Incorrect Base URL\n\nMust start with project\'s base url (" & baseURL &") if full URL specified.')</script>")
     Else
     ' If the URL still contains the http:// prefix and is shorter than the base
     ' URL, assume that it is incomplete.
       Response.Write("<script type='text/javascript'>alert('Incomplete Code Review URL')</script>")
     End If
     ' Otherwise, the URL matches the base URL exactly, which is also invalid.
     codeReviewURL = sCodeReviewURL
     isValid = False
   End If
   ValidateCodeReviewURL = isValid
End Function
'----------------------------------------------------------------------------------------------------------------------------------------
Function Is_Page_Editable ( cDlocked )
   ' Editable if (   (unlocked OR rejected)
   '              OR ( NOT released/locked AND EditReleaseNotesInPending allowed)
   '              OR (released/locked AND EditNonCriticalInfoForLockedPackage allowed)
   '             )
   '             AND user logged in
   If (((cDlocked = "N") OR (cDlocked = "R")) OR ((cDlocked <> "Y") AND (canActionControlInProject("EditReleaseNotesInPending"))) OR ((cDlocked = "Y") AND (canActionControlInProject("EditNonCriticalInfoForLockedPackage")))) AND objAccessControl.UserLogedIn Then
      Is_Page_Editable = TRUE
   Else
      Is_Page_Editable = FALSE
   End If
End Function
'----------------------------------------------------------------------------------------------------------------------------------------
Function Is_Section_Editable ( )
   If scriptName = "fixed_issues.asp" AND objAccessControl.UserLogedIn Then
      Is_Section_Editable = TRUE
   Else
      Is_Section_Editable = FALSE
   End If
End Function
'----------------------------------------------------------------------------------------------------------------------------------------
Function Is_Critical_Section_Editable ( cDlocked )
   ' Editable if (   (unlocked OR rejected)
   '              OR ( NOT released/locked AND EditReleaseNotesInPending allowed)
   '              OR (released/locked AND EditCriticalInfoForLockedPackage allowed)
   '             )
   '             AND user logged in
   If (((cDlocked = "N") OR (cDlocked = "R")) OR ((cDlocked <> "Y") AND (canActionControlInProject("EditReleaseNotesInPending"))) OR ((cDlocked = "Y") AND (canActionControlInProject("EditCriticalInfoForLockedPackage")))) AND objAccessControl.UserLogedIn Then
      Is_Critical_Section_Editable = TRUE
   Else
      Is_Critical_Section_Editable = FALSE
   End If
End Function

'---------------------------------------------------------------
' Function: getLastNonRippleVersionPVID
'
' Purpose: returns the last non-ripple version of the package
'
' Arguments: this_pv_id : string
'
' Notes: In the past, users used to manually perform ripple builds.
'        This function does not detect those as ripples. It could be
'        made to do so but it would not be reliable. For example, it
'        could check to see if the word "ripple" appears in the
'        comments field of the record set of the SWL query.  That
'        might catch some of those records, but assumes the user
'        wrote the wor ripple into the comments (reason for version).
'
Function getLastNonRippleVersionPVID( this_pv_id, ByRef rippleBasePvid, ByRef lastNonRipplePvid )
   Dim queryResult
   Dim queryString
   Dim lastNonRipple

   ' default return value in case don't find anything
   getLastNonRippleVersionPVID = this_pv_id
   lastNonRipple = this_pv_id

   ' Get a list of all previous non-ripple builds starting with the current pvid
   '    The first entry will be the base entry of the current ripple
   '    The second entry will be the previous significant entry
   queryString = _
        "SELECT pv_id,last_pv_id,pkg_version,v_ext,build_type " &_
        "FROM " &_
        "  (SELECT build_type,last_pv_id,pv_id,pkg_version,v_ext " &_
        "  FROM " &_
        "    (SELECT pv.build_type,pv.last_pv_id AS raw_last_pvid ,pv_id,pv.pkg_version,pv.v_ext,DECODE(pv.pv_id, pv.last_pv_id, NULL, pv.last_pv_id) AS last_pv_id " &_
        "    FROM release_manager.package_versions pv " &_
        "    WHERE pv.PKG_ID IN " &_
        "      (SELECT pkg_id " &_
        "      FROM release_manager.package_versions pv " &_
        "      WHERE pv.pv_id = " & this_pv_id &_
        "      ) " &_
        "    ) " &_
        "    START WITH pv_id                    = " & this_pv_id &_
        "    CONNECT BY nocycle prior last_pv_id = pv_id " &_
        "  ) " &_
        "WHERE build_type != 'Y' "


   Set queryResult = OraDatabase.DbCreateDynaset( queryString, cint(0))

   ' First entry - Base of the current ripple (may be myself)
   If ((NOT queryResult.BOF) AND (NOT queryResult.EOF)) Then
         getLastNonRippleVersionPVID = queryResult("pv_id")
         lastNonRipple = queryResult("pv_id")

        ' Second entry - Previous Non Ripple Entry
        queryResult.MoveNext
        If ((NOT queryResult.BOF) AND (NOT queryResult.EOF)) Then
            getLastNonRippleVersionPVID = queryResult("pv_id")
        End If
   End If

   queryResult.Close()
   Set queryResult = nothing

   If Not isNull(rippleBasePvid) Then rippleBasePvid = lastNonRipple 
   If Not isNull(lastNonRipplePvid) Then lastNonRipplePvid = getLastNonRippleVersionPVID

End Function


Function getLastNonRippleVersionPVIDLimitedByDate( this_pv_id, limitDate )
   Dim queryResult
   Dim queryString

   ' default return value in case don't find anything
   getLastNonRippleVersionPVIDLimitedByDate = this_pv_id

   ' Get a list of all previous non-ripple builds starting with the cuurent pvid
   '    The first entry will be the base entry of the current ripple
   '    The second entry will be the previous significant entry
   queryString = _
            "SELECT last_pv_id, pv_id, pkg_version, v_ext,MODIFIED_STAMP " &_
            "FROM " &_
            "  (SELECT pv.build_type, pv.last_pv_id, pv_id, pv.pkg_version, pv.v_ext, pv.MODIFIED_STAMP" &_
            "  FROM release_manager.package_versions pv" &_
            "    START WITH pv.pv_id = " + this_pv_id &_
            "    CONNECT BY nocycle prior pv.last_pv_id = pv.pv_id" &_
            "  ) where build_type != 'Y' " &_
            "    AND MODIFIED_STAMP >= TO_DATE('" & limitDate & "','DY DD-MON-YYYY')"

   Set queryResult = OraDatabase.DbCreateDynaset( queryString, cint(0))

   ' First entry - Base of the current ripple (may be myself)
   If ((NOT queryResult.BOF) AND (NOT queryResult.EOF)) Then
         getLastNonRippleVersionPVIDLimitedByDate = queryResult("pv_id")

        ' Second entry - Previous Non Ripple Entry
        queryResult.MoveNext
        If ((NOT queryResult.BOF) AND (NOT queryResult.EOF)) Then
            getLastNonRippleVersionPVIDLimitedByDate = queryResult("pv_id")
        End If
   End If

   queryResult.Close()
   Set queryResult = nothing
End Function

'---------------------------------------------------------------
' Function: getPreviousVersionPVID
'
' Purpose: returns the immediate predecssor version of the given
'          package version
'
' Arguments: this_pv_id : string
'
' Notes:
'
Function getPreviousVersionPVID( this_pv_id )
   Dim queryResult
   Dim queryString

   getPreviousVersionPVID = ""

   queryString = "SELECT last_pv_id FROM package_versions WHERE pv_id = " & this_pv_id

   Set queryResult = OraDatabase.DbCreateDynaset( queryString, cint(0))

    If ((NOT queryResult.BOF) AND (NOT queryResult.EOF)) Then
      getPreviousVersionPVID = queryResult("last_pv_id")
   End If

   queryResult.Close()
   Set queryResult = nothing

End Function

'---------------------------------------------------------------
' Function: getLastSignificantPVID
'
' Purpose: Returns the last significant (man-made) version (PV_ID) that
'          is a predecessor to the specified pv_id
'
' Arguments: pv_id       : Uniquely identifies this package version
'            last_pv_id  : Uniquely identifies the predecssor of this package version
' Notes:
'
Function getLastSignificantPVID (pv_id, last_pv_id)

   getLastSignificantPVID = ""

   If( (NOT IsNull(last_pv_id)) AND (last_pv_id <> pv_id) ) Then

      ' Get the pv_id for the current version, and if necessary, work back through any ripple versions as necessary
      ' to get a non-ripple version ancestor
        pv_id = getLastNonRippleVersionPVID( pv_id , NULL, NULL)
        If (pv_id <> "") Then
            getLastSignificantPVID = pv_id
        End If
   End If

End Function

'---------------------------------------------------------------
' Function: getLastSignificantVersions
'
' Purpose: Returns the last significant (man-made) version (PV_ID) that
'          is a predecessor to the specified pv_id
'
' Arguments: pv_id              : Uniquely identifies this package version
'            RefRippleBase      : Ref to store riple base PVID
'            RefPrevNonRipple   : Ref to store previous non ripple PVID
' Notes:
'
Sub getLastSignificantVersions (pv_id, ByRef RefRippleBase, ByRef RefPrevNonRipple)
    Dim rv
        rv = getLastNonRippleVersionPVID( pv_id , RefRippleBase, RefPrevNonRipple)
End Sub

'---------------------------------------------------------------
' Function: get_Pkg_Label
'
' Purpose: Returns the package label for the specified pv_id
'
' Arguments: pv_id       : Uniquely identifies this package version
'
Function get_Pkg_Label (pv_id)
   Dim queryResult
   Dim queryString

   get_Pkg_Label = ""

   ' Get the package label from the package versions table
   queryString = "SELECT pkg_label FROM package_versions WHERE pv_id = " & pv_id
   Set queryResult = OraDatabase.DbCreateDynaset( queryString, cint(0))
   If ((NOT queryResult.BOF) AND (NOT queryResult.EOF)) Then
      get_Pkg_Label = queryResult("pkg_label")
   End If
   queryResult.Close()
   Set queryResult = nothing
End Function
'---------------------------------------------------------------
' Function: get_Src_Path
'
' Purpose: Returns the source path for the specified pv_id
'
' Arguments: pv_id       : Uniquely identifies this package version
'
Function get_Src_Path (pv_id)
   Dim queryResult
   Dim queryString

   get_Src_Path = ""

   ' Get the source path from package versions table
   queryString = "SELECT src_path FROM package_versions WHERE pv_id = " & pv_id
   Set queryResult = OraDatabase.DbCreateDynaset( queryString, cint(0))
   If ((NOT queryResult.BOF) AND (NOT queryResult.EOF)) Then
      get_Src_Path = queryResult("src_path")
   End If
   queryResult.Close()
   Set queryResult = nothing
End Function

'---------------------------------------------------------------
' Function: getOldLabel
'
' Purpose: Returns the previous label; if none then returns empty string
'
'          Since this operation is designed to fulfil the generation of
'          diff commands, there is no point in considering ripple
'          versions, since the only differences we find there are in
'          the build.pl files (for example). So, this function uses
'          some underlying methods that ignore ripple built versions
'          therefore concentrating on versions that someone has manually
'          gone and labelled, presumably because they changed some
'          source file other than build.pl.
'
' Arguments: pv_id       : Uniquely identifies this package version
'            last_pv_id  : Uniquely identifies the predecssor of this package version
' Notes:
'
Function getOldLabel (pv_id, last_pv_id)
   Dim lastSignificantPVID

   getOldLabel = ""

   lastSignificantPVID = getLastSignificantPVID(pv_id, last_pv_id)
   If (lastSignificantPVID <> "") Then
      getOldLabel = get_Pkg_Label(lastSignificantPVID)
   End If
End Function
'---------------------------------------------------------------
' Function: getOldSrcPath
'
' Purpose: Returns the previous src path; if none then returns empty string
'
'          Since this operation is designed to fulfil the generation of
'          diff commands, there is no point in considering ripple
'          versions, since the only differences we find there are in
'          the build.pl files (for example). So, this function uses
'          some underlying methods that ignore ripple built versions
'          therefore concentrating on versions that someone has manually
'          gone and labelled, presumably because they changed some
'          source file other than build.pl.
'
'          NOTE: With SubVersion, the src_path column in the package_versions
'                table will be used to hold the Subversion tag. This function
'                will therefore be used mostly when a package version is
'                controlled under subversion.
'
' Arguments: pv_id       : Uniquely identifies this package version
'            last_pv_id  : Uniquely identifies the predecssor of this package version
' Notes:
'
Function getOldSrcPath (pv_id, last_pv_id)
   Dim lastSignificantPVID

   getOldSrcPath = ""

   lastSignificantPVID = getLastSignificantPVID(pv_id, last_pv_id)
   If (lastSignificantPVID <> "") Then
      getOldSrcPath = get_Src_Path(lastSignificantPVID)
   End If
End Function
'----------------------------------------------------------------------------------------------------------------------
Sub vcs_info_from_vcs_tag( nVcs_tag, ByRef objDetails )
   Dim rsTemp, Query_String

   Query_String = " SELECT * FROM vcs_type WHERE tag = '"& nVcs_tag &"'"
   Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
   If (NOT rsTemp.BOF ) AND (NOT rsTemp.EOF) Then
      objDetails.Item("vcs_type_id") = rsTemp("vcs_type_id")
      objDetails.Item("vcs_name") = rsTemp("name")
      objDetails.Item("vcs_tag") = rsTemp("tag")
   Else
      Call RaiseMsg(enum_MSG_ERROR, "Database does not contain a record of the VCS tag : " & nVcs_tag )
   End If
   rsTemp.Close()
   set rsTemp = nothing
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub vcs_info_from_vcs_type_id( nVcs_type_id, ByRef objDetails )
   Dim rsTemp, Query_String

   If NOT IsNull(nVcs_type_id) Then
      Query_String = " SELECT * FROM vcs_type WHERE vcs_type_id = "& nVcs_type_id
      Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
      If (NOT rsTemp.BOF ) AND (NOT rsTemp.EOF) Then
         objDetails.Item("vcs_type_id") = rsTemp("vcs_type_id")
         objDetails.Item("vcs_name") = rsTemp("name")
         objDetails.Item("vcs_tag") = rsTemp("tag")
      Else
         Call RaiseMsg(enum_MSG_ERROR, "Database does not contain a record of the VCS type ID : " & nVcs_type_id )
      End If
      rsTemp.Close()
      set rsTemp = nothing
   Else
      ' default to returning Subversion info, assuming it exists in the data
      Call vcs_info_from_vcs_tag( enum_VCS_SUBVERSION_TAG, objDetails )
   End If
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub get_vcs_info_for_package( nPkgLabel, nBuildType, nVcsTypeId, nDLocked, ByRef objDetails )
   ' lots of patch versions exist with N/A as their pkg_label and null as vcs_type_id. These are all uncontrolled
   ' packages published directly into dpkg_archive with no controlled source under clearcase, so we want to treat
   ' them as uncontrolled if possible.
   If nDLocked = "Y" AND ((nPkgLabel = "N/A") OR IsNull(nPkgLabel)) AND nBuildType = "M" AND IsNull(nVcsTypeId) Then
      Call vcs_info_from_vcs_tag( enum_VCS_UNCONTROLLED_TAG, objDetails )
   Else
      ' Otherwise, try and decode the VCS from the package's vcs_type_id entry from the package version table
      ' NOTE: A null vcs_type_id entry will default to ClearCase. That is all we have been using up til now so
      ' it should be safe.
      Call vcs_info_from_vcs_type_id( nVcsTypeId, objDetails )
   End If
End Sub
'----------------------------------------------------------------------------------------------------------------------
Sub get_vcs_info_for_pv_id( nPv_id, ByRef objDetails )
   Dim rsTemp, Query_String

   Query_String = _
   " SELECT pv.pkg_label, pv.build_type, pv.vcs_type_id, pv.dlocked "&_
   "   FROM PACKAGE_VERSIONS pv"&_
   "  WHERE pv.pv_id = "& nPv_id

   Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
   If (NOT rsTemp.BOF ) AND (NOT rsTemp.EOF) Then
      Call get_vcs_info_for_package( rsTemp("pkg_label"), rsTemp("build_type"), rsTemp("vcs_type_id"), rsTemp("dlocked"), objDetails )
   Else
      Call RaiseMsg(enum_MSG_ERROR, "PV_ID (" & nPv_id & ") Not Found")
   End If
   rsTemp.Close()
   set rsTemp = nothing
End Sub
'----------------------------------------------------------------------------------------------------------------------
Function get_vcs_tag( nPv_id )
   Dim tempVcsInfoCollector
   Set tempVcsInfoCollector = CreateObject("Scripting.Dictionary")

   Call get_vcs_info_for_pv_id( nPv_id, tempVcsInfoCollector )
   get_vcs_tag = tempVcsInfoCollector.Item("vcs_tag")

   Set tempVcsInfoCollector = nothing
End Function
'----------------------------------------------------------------------------------------------------------------------
Function isInDoNotRippleTable( NNrtag_id, NNpv_id )
   Dim rsTemp, Query_String

   isInDoNotRippleTable = FALSE

   If NNrtag_id <> "" AND NNpv_id <> "" Then
      Query_String = " SELECT dnr.pv_id FROM DO_NOT_RIPPLE dnr WHERE dnr.RTAG_ID ="& NNrtag_id &" AND dnr.PV_ID ="& NNpv_id

      Set rsTemp = OraDatabase.DbCreateDynaset(Query_String, cint(0))
      If rsTemp.RecordCount <> 0  Then
         isInDoNotRippleTable = TRUE
      End If
      rsTemp.Close()
      set rsTemp = nothing
   End If
End Function
'----------------------------------------------------------------------------------------------------------------------
' Number of active (Not paused, Not Disabled) daemon configured for a given Release 
Function activeDaemonCount ( NNrtag_id )
   Dim rsTemp, Query_String

   activeDaemonCount = 0

   If NNrtag_id <> ""  Then
      Query_String = "SELECT count(*) as Count FROM release_config rc, run_level rl WHERE rc.rtag_id = " & NNrtag_id &  " AND rc.RCON_ID = rl.rcon_id(+) AND NVL(rl.pause, 0 ) = 0"

      Set rsTemp = OraDatabase.DbCreateDynaset(Query_String, cint(0))
      If rsTemp.RecordCount <> 0  Then
         activeDaemonCount = rsTemp("Count")
      End If
      rsTemp.Close()
      set rsTemp = nothing
   End If
End Function
'----------------------------------------------------------------------------------------------------------------------
Function hasFutureBuild( NNrtag_id, NNpv_id )
   Dim rsTemp, Query_String

   hasFutureBuild = FALSE

   If NNrtag_id <> "" AND NNpv_id <> "" Then

      Query_String = " SELECT * FROM DAEMON_INSTRUCTIONS di WHERE di.RTAG_ID ="& NNrtag_id &" AND di.PV_ID ="& NNpv_id & " AND OP_CODE = " & OP_CODE_2_FUTURE_BUILD

      Set rsTemp = OraDatabase.DbCreateDynaset(Query_String, cint(0))
      If rsTemp.RecordCount <> 0  Then
         hasFutureBuild = TRUE
      End If
      rsTemp.Close()
      set rsTemp = nothing
   End If
End Function

'----------------------------------------------------------------------------------------------------------------------
Function isBuilding( NNpv_id )
   Dim rsTemp, Query_String

   isBuilding = FALSE

   If  NNpv_id <> "" Then
      Query_String = _
            "SELECT unique rl.CURRENT_PV_ID" &_
            " FROM RELEASE_CONFIG rc, RELEASE_TAGS rt, RUN_LEVEL rl " &_
            " WHERE rt.RTAG_ID = rc.RTAG_ID " &_
            "   AND rc.bmcon_id is not null" &_
            "   AND rt.OFFICIAL in ( 'N', 'R', 'C')" &_
            "   AND rl.RCON_ID(+) = rc.RCON_ID" &_
            "   AND rl.CURRENT_PKG_ID_BEING_BUILT is not null" &_
            "   AND NVL(rl.PAUSE,0) < 2" &_
            "   AND rl.CURRENT_PV_ID = " & NNpv_id 

      Set rsTemp = OraDatabase.DbCreateDynaset(Query_String, cint(0))
      If rsTemp.RecordCount <> 0  Then
         isBuilding = TRUE
      End If
      rsTemp.Close()
      set rsTemp = nothing
   End If
End Function

'----------------------------------------------------------------------------------------------------------------------
Function pv_id_exists( nPv_id )
   Dim rsTemp, Query_String

   If NOT IsNull( nPv_id ) AND nPv_id <> "" Then
      Query_String = _
      " SELECT pv.pv_id "&_
      "   FROM PACKAGE_VERSIONS pv"&_
      "  WHERE pv.pv_id = "& nPv_id
      Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))
      If (NOT rsTemp.BOF ) AND (NOT rsTemp.EOF) Then
         pv_id_exists = TRUE
      Else
         pv_id_exists = FALSE
      End If
      rsTemp.Close()
      set rsTemp = nothing
   Else
      pv_id_exists = FALSE
   End If
End Function
'----------------------------------------------------------------------------------------------------------------------
Function is_daemon_enabled_release( NNrtag_id, defaultReturnValue )
   Dim rsTemp, Query_String

   If NOT IsNull( NNrtag_id ) AND NNrtag_id <> "" Then

      Query_String = _
      " SELECT rc.bmcon_id "&_
      "   FROM RELEASE_CONFIG rc"&_
      "  WHERE rc.rtag_id = "& NNrtag_id
      Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))

      is_daemon_enabled_release = FALSE
      While ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF) AND (is_daemon_enabled_release = FALSE))
         If (NOT IsNull(rsTemp("bmcon_id"))) AND (rsTemp("bmcon_id") <> "") Then
            is_daemon_enabled_release = TRUE
         End If
         rsTemp.MoveNext
      WEnd

      rsTemp.Close()
      set rsTemp = nothing
   Else
      is_daemon_enabled_release = defaultReturnValue
   End If
End Function
'--------------------------------------------------------------------------------------------------------------------------
' Convert release state into a meaningful string
Function Get_Official( nOfficial )
   If nOfficial = "N" Then
      Get_Official = "Open"
   ElseIf nOfficial = "A" Then
      Get_Official = "Archive"
   ElseIf nOfficial = "C" Then
      Get_Official = "CCB"
   ElseIf nOfficial = "R" Then
      Get_Official = "Restricted"
   ElseIf nOfficial = "Y" Then
      Get_Official = "Closed"
   ElseIf nOfficial = "P" Then
      Get_Official = "Preserved"
   Else
      Get_Official = "?"
   End If
End Function
'-----------------------------------------------------------------------------------------------------------------------------
Function Get_Pkg_Id_For_Pv_Id ( NNpv_id )
   Dim rsTemp, Query_String

   Get_Pkg_Id_For_Pv_Id = ""

   If NOT IsNull(NNpv_id) AND NNpv_id <> "" Then
      Query_String = _
      "SELECT pkg_id FROM package_versions WHERE pv_id = "& NNpv_id

      Set rsTemp = OraDatabase.DbCreateDynaset( Query_String, cint(0))

      If ((NOT rsTemp.BOF) AND (NOT rsTemp.EOF)) Then
         Get_Pkg_Id_For_Pv_Id = rsTemp("pkg_id")
      End If
      rsTemp.Close
      Set rsTemp = nothing
   End If

End Function

'-----------------------------------------------------------------------------------------------------------------------------
Function iif(bFlag, sTrueStr, sFalseStr)
  if bFlag then
    iif = sTrueStr
  else 
    iif = sFalseStr
  end if
End Function

'-----------------------------------------------------------------------------------------------------------------------------
Function EmptyToNull (sVal)
    If isNull(sVal) Then
        EmptyToNull = NULL
    ElseIf sval <> "" Then
        EmptyToNull = sVal
    Else
        EmptyToNull = NULL
    End If
End Function

'-----------------------------------------------------------------------------------------------------------------------------
Function EmptyToNullString ( sName, sVal)
    If isNull(sVal) Then
        EmptyToNullString = sName & " is NULL"
    ElseIf sval <> "" Then
        EmptyToNullString = sName & "='" & sVal & "'"
    Else
        EmptyToNullString = sName & " is NULL"
    End If
End Function

'--------------------------------------------------------------------------------------------------------------------------
' Sets the state of all build daemons of the specified release
Sub SetDaemonStates (artag_id,astate)
        On Error Resume Next
        OraDatabase.Parameters.Add "RTAG_ID",                   artag_id,       ORAPARM_INPUT, ORATYPE_NUMBER 
        OraDatabase.Parameters.Add "NSTATE",                    astate,         ORAPARM_INPUT, ORATYPE_NUMBER 
                
        objEH.TryORA ( OraSession )
        
        OraDatabase.ExecuteSQL _
        "BEGIN PK_BUILDAPI.SET_DAEMON_STATES(:RTAG_ID,:NSTATE);   END;"
                
        objEH.CatchORA ( OraSession )

        OraDatabase.Parameters.Remove "RTAG_ID"
        OraDatabase.Parameters.Remove "NSTATE"  
End Sub

'----------------------------------------------
'Returns true if the specified package version exists in the specified table
Function PackageExists(RtagId, pvId, stable)
  Dim rsTemp
  Dim sqry
  If RtagId = "" Then
    PackageExists = False
  Else
    sqry = "SELECT * FROM " & stable & " WHERE rtag_id = " & RtagId & " AND pv_id = " & pvId
    Set rsTemp = OraDatabase.DbCreateDynaset(sqry,CInt(0))
    PackageExists = rsTemp.RecordCount > 0  
    rsTemp.Close()
    Set rsTemp = Nothing
  End If
End Function

'----------------------------------------------
' Test that specified package/version exists in dpkg_archive
' Can also test presence of the archive
'   Use http interface as it does not require authetication
Function testArchiveAccessPkg(pkgName, pkgVersion)
  Dim oXMLHTTP
  Dim testUrl

  testArchiveAccessPkg = False
  testUrl = HTTP_PKG_ARCHIVE

  testUrl = testUrl & "/cgi-bin/testPackage.pl"
  If pkgName <> "" Then
      testUrl = testUrl & "?path=" &  pkgName & "/" & pkgVersion
  End If
  Set oXMLHTTP = CreateObject("MSXML2.ServerXMLHTTP.3.0")

  ' Use error handling in case dpkg_archive is not available
  ' Use HEAD to test existence
  Err.Clear
  On Error Resume Next
  oXMLHTTP.Open "GET", testUrl, False
  oXMLHTTP.Send

  ' Do not combine the next two If statments - it will not work
  If Err.Number = 0  Then
    If oXMLHTTP.Status = 200 Then 
        If InStr(1,oXMLHTTP.responseText, "::FOUND::", 1) = 1 Then
            testArchiveAccessPkg = True
        End If
    End If
  End If

  On Error Goto 0
End Function

'--------------------------------------------------------------------------------------------------------------------------
' Like Cint, but handles NULL by replacing it with a default value
Function NiceInt( val, def)
   If val <> ""  AND IsNumeric(val) Then
       NiceInt = CInt(val)
   Else
       NiceInt = def
   End If
End Function

'--------------------------------------------------------------------------------------------------------------------------
' Like CLng, but handles NULL by replacing it with a default value
Function NiceCLng( val, def)
   If val <> ""  AND IsNumeric(val) Then
       NiceCLng = CLng(val)
   Else
       NiceCLng = def
   End If
End Function

'--------------------------------------------------------------------------------------------------------------------------
' Like CStr, but handles NULL by replacing it with a default value
Function NiceCStr( val, def)
   If IsNull(val) Then
       NiceCStr = def
   ElseIf IsEmpty(val) Then
       NiceCStr = def
   Else
       NiceCStr = CStr(val)
   End If
End Function

'--------------------------------------------------------------------------------------------------------------------------
' Convert a duration(seconds) into days,hours and seconds. eg 10d 3h 13m 15s
Function NiceDuration(nDuration)
    NiceDuration = ""
    Dim joiner : joiner = ""
    Dim unit
    Dim duration : duration = nDuration
    If duration > (60 * 60 * 24) Then
        unit = Int(duration / (60 * 60 * 24))
        duration = duration MOD (60 * 60 * 24) 
        NiceDuration = NiceDuration & joiner & unit & "d"
        joiner = "&nbsp;"
    End If

    If duration > (60 * 60) Then
        unit = Int(duration / (60 * 60))
        duration = duration MOD (60 * 60) 
        NiceDuration = NiceDuration & joiner & unit & "h"
        joiner = "&nbsp;"
    End If

        If duration > (60) Then
        unit = Int(duration / (60))
        duration = duration MOD (60) 
        NiceDuration = NiceDuration & joiner & unit & "m"
        joiner = "&nbsp;"
    End If

    NiceDuration = NiceDuration & joiner & duration & "s"
End Function

'--------------------------------------------------------------------------------------------------------------------------
' Quick and ugly code to attempt to remove nasty characters from strings
' In particular some unicode characters that mess with the json decoder
Function CleanUpJson (input)
      Dim objRegExp, outputStr
      Set objRegExp = New Regexp

      objRegExp.IgnoreCase = True
      objRegExp.Global = True
      objRegExp.Pattern = "((?![\[\]\(\)\{\}\$-_?/""';:.,a-zA-Z0-9]).)+"
      outputStr = objRegExp.Replace(input, " ")

      CleanUpJson = outputStr
    End Function

'--------------------------------------------------------------------------------------------------------------------------
'   Test if package can be added to a release
'       Really tests if a a package of this packages alias can be
'       manipulated in this release
'   True: Package alias can be added/replaced in release
Function canAddToRelease ( nRtagId, nPvId )

    ' If we don't enough parameters then assume we can add package
    If nRtagId = "" OR nPvId = "" Then
        canAddToRelease = TRUE
        Exit Function
    End If

        On Error Resume Next
        OraDatabase.Parameters.Add "RTAG_ID",                   nRtagId,        ORAPARM_INPUT, ORATYPE_NUMBER 
        OraDatabase.Parameters.Add "PV_ID",                     nPvId,      ORAPARM_INPUT, ORATYPE_NUMBER 
        OraDatabase.Parameters.Add "RETURN_CODE",               null,       ORAPARM_OUTPUT, ORATYPE_NUMBER 
                
        objEH.TryORA ( OraSession )
        
        OraDatabase.ExecuteSQL _
        "BEGIN :RETURN_CODE := PK_RELEASE.CAN_ADD_PKG_TO_RELEASE(:RTAG_ID,:PV_ID);   END;"

    If CInt(OraDatabase.Parameters("RETURN_CODE").Value) = 0 Then
        canAddToRelease = FALSE
    Else
        canAddToRelease = TRUE
    End If
                
        objEH.CatchORA ( OraSession )

        OraDatabase.Parameters.Remove "RETURN_CODE"
        OraDatabase.Parameters.Remove "RTAG_ID"
        OraDatabase.Parameters.Remove "PV_ID"   
End Function
'--------------------------------------------------------------------------------------------------------------------------
'   Returns either the value of the Request('tag') or the default value       
Function RequestDefault(stag, sdefault)
   If Request(stag) <> "" Then
       RequestDefault = Request(stag)
   Else 
       RequestDefault = sdefault
   End If
End Function
'--------------------------------------------------------------------------------------------------------------------------
'   Returns either the value of the Request('tag') or the default value       
Function RequestBool(stag, sdefault)
    Dim val
    If Request(stag) <> "" Then
        RequestBool = FALSE
        val = UCase( Request(stag))
        If val = "Y" or val = "TRUE" Then
            RequestBool = TRUE
        ElseIf IsNumeric(val) Then
            If val > 0 Then
                RequestBool = TRUE
            End If
        End If
   Else 
       RequestBool = sdefault
   End If
End Function

'--------------------------------------------------------------------------------------------------------------------------
'   Data structure to assist in the Release Mode Transition Check
'   Tuples (FromCondition, ToCondition)  '-' == Always
'   Order matches ReleaseModeAccessCheck
'
Dim RMTD_Data
RMTD_Data = Array(Array("-"                        ,"-"), _
                  Array("ChangeModeFromRestrictive","-"), _
                  Array("ChangeModeFromRestrictive","-"), _
                  Array("ChangeModeFromClosed"     ,"ChangeModeToClosed"), _
                  Array("ChangeModeFromClosed"     ,"ChangeModeToPreserved"), _
                  Array("ChangeModeFromArchived"   ,"ChangeModeToArchived") _
                  )
'-------------------------------------------------
' Function: ReleaseMode2Index    
' Description: Convert a enumDB_RELEASE_IN_*** into an index into the above array
'
Function ReleaseMode2Index( eReleaseMode )
    If eReleaseMode = enumDB_RELEASE_IN_OPEN_MODE Then
        ReleaseMode2Index = 0
    ElseIf eReleaseMode = enumDB_RELEASE_IN_RESTRICTIVE_MODE Then
        ReleaseMode2Index = 1
    ElseIf eReleaseMode = enumDB_RELEASE_IN_CCB_MODE Then
        ReleaseMode2Index = 2
    ElseIf eReleaseMode = enumDB_RELEASE_IN_CLOSED_MODE Then
        ReleaseMode2Index = 3
    ElseIf eReleaseMode = enumDB_RELEASE_IN_PRESERVE_MODE Then
        ReleaseMode2Index = 4
    ElseIf eReleaseMode = enumDB_RELEASE_IN_ARCHIVE_MODE Then
        ReleaseMode2Index = 5
    Else
        ReleaseMode2Index = -1
    End If
End Function

'-------------------------------------------------
' Function:     ReleaseModeAccessCheck    
' Description:  Determine if the user can change the Release Mode
'               from - Start at this Release Mode
'               to   - Can the user transition to this mode
' Returns:      True - yes they can
'
Function ReleaseModeAccessCheck( from, toMode )
    Dim fromIndex : fromIndex = ReleaseMode2Index(from)
    Dim toIndex   : toIndex = ReleaseMode2Index(toMode)
    ReleaseModeAccessCheck = False

    ' Can't Change to same mode
    If from = toMode Then
        Exit Function
    End If

    On Error Resume Next
    Dim fromAccess : fromAccess = ""
    Dim toAccess   : toAccess = ""

    ' Get access type from table
    '   ""      - No access (internal error)
    '   "-"     - All Access allowed (if user is logged in )
    '   Else    - Name of a canActionControlInProject
    fromAccess = RMTD_Data(fromIndex)(0)
    toAccess = RMTD_Data(toIndex)(1)

    ' Check From Condition
    If fromAccess = "-" Then
        ReleaseModeAccessCheck = canActionInProject()
    ElseIf fromAccess <> "" Then
        ReleaseModeAccessCheck = canActionControlInProject(fromAccess)
    End If

    If NOT ReleaseModeAccessCheck  Then
        Exit Function
    End If

    ' Check to Condition
    If toAccess = "-" Then
        ReleaseModeAccessCheck = canActionInProject()
    ElseIf toAccess <> "" Then 
        ReleaseModeAccessCheck = canActionControlInProject(toAccess)
    End If

End Function

'-------------------------------------------------
' Function:    releaseIsClosed
' Description: Determine if a release can be modified at all
' Returns:     True: Release cannot be modified
'                    ie: it is NOT in a state that allows modification
'
Function releaseIsClosed(eReleaseMode)
    If eReleaseMode = enumDB_RELEASE_IN_OPEN_MODE Then
        releaseIsClosed = False
    ElseIf eReleaseMode = enumDB_RELEASE_IN_RESTRICTIVE_MODE Then
        releaseIsClosed = False
    ElseIf eReleaseMode = enumDB_RELEASE_IN_CCB_MODE Then
        releaseIsClosed = False
    ElseIf eReleaseMode = enumDB_RELEASE_IN_CLOSED_MODE Then
        releaseIsClosed = True
    ElseIf eReleaseMode = enumDB_RELEASE_IN_PRESERVE_MODE Then
        releaseIsClosed = True
    ElseIf eReleaseMode = enumDB_RELEASE_IN_ARCHIVE_MODE Then
        releaseIsClosed = True
    Else
        releaseIsClosed = True
    End If
End Function

'-------------------------------------------------
' Function:    releaseIsWritable
' Description: Determine if a release can be modified
' Returns:     True: Release can be modified
'                    ie: it is in a state that allows modification
'
Function releaseIsWritable(eReleaseMode)
    If eReleaseMode = enumDB_RELEASE_IN_OPEN_MODE AND canActionInProject() Then
        releaseIsWritable = True
    ElseIf eReleaseMode = enumDB_RELEASE_IN_RESTRICTIVE_MODE AND canActionControlInProject("AlterReleaseContentsInRestrictiveMode") Then
        releaseIsWritable = True
    ElseIf eReleaseMode = enumDB_RELEASE_IN_CCB_MODE AND canActionControlInProject("AlterReleaseContentsInRestrictiveMode")Then
        releaseIsWritable = True
    ElseIf eReleaseMode = enumDB_RELEASE_IN_CLOSED_MODE Then
        releaseIsWritable = False
    ElseIf eReleaseMode = enumDB_RELEASE_IN_PRESERVE_MODE Then
        releaseIsWritable = False
    ElseIf eReleaseMode = enumDB_RELEASE_IN_ARCHIVE_MODE Then
        releaseIsWritable = False
    Else
        releaseIsWritable = False
    End If
End Function

'-------------------------------------------------
' Function:    releaseIsMergable
' Description: Determine if the user can 'Merge' into the release
' Returns:     True: Release can be modified
'                    ie: it is in a state that allows modification
'
Function releaseIsMergable(eReleaseMode)
    If eReleaseMode = enumDB_RELEASE_IN_OPEN_MODE AND canActionInProject() Then
        releaseIsMergable = True
    ElseIf eReleaseMode = enumDB_RELEASE_IN_RESTRICTIVE_MODE AND canActionControlInProject("MergeRelease")  Then
        releaseIsMergable = True
    ElseIf eReleaseMode = enumDB_RELEASE_IN_CCB_MODE AND canActionControlInProject("MergeReleaseForCCB") Then
        releaseIsMergable = True
    Else
        releaseIsMergable = False
    End If
End Function
'-------------------------------------------------
' Function:         RenderLxrStateString   
' Description:      Return a string to show the current LXR state
Function RenderLxrStateString(rtagid, lxr, lxrState, official, txt)
    If lxr = "N" AND lxrState = "N" Then
        RenderLxrStateString = ""
    Else
        Dim lxrUrl : lxrUrl = LXR_URL & "/" & rtagid
        Dim image, hover, isClosed

        If lxrState = "N" Then
            If releaseIsClosed(official) Then lxrState = "A"
        End If

        Select Case lxrState
            Case "I"
                image = "LXRlogo64.jpeg"
                hover = "LXR Index available"
            Case "C"
                image = "LXRlogo64_off.jpeg"
                hover = "LXR Index available, but no longer updated"
            Case "N"
                image = "LXRlogo64_progress.jpeg"
                hover = "LXR Requested, but not yet available"
            Case "A"
                image = "LXRlogo64_off.jpeg"
                hover = "LXR no longer available. Release is no longer open"
            Case Else
                image = "LXRlogo64_progress.jpeg"
                hover = "LXR Requested, unknown State:(" & lxrState &")"
        End Select
        RenderLxrStateString = "<a class=mmItem href='"&lxrUrl&"' title='"&hover&"'><img src=""images/"&image&""" height=16 border=0 vspace=0 hspace=0 style='vertical-align : bottom'>" & txt &"</a>"
    End If
End Function
 
'-------------------------------------------------
' Function:         RenderS3SyncStateString   
' Description:      Return a string to show the current S3 Sync state
Function RenderS3SyncStateString(rtagid, s3Sync, official, txt)
    If s3Sync = "N" Then
        RenderS3SyncStateString = ""
    Else
        Dim image, hover, iClass
                iClass = ""
        If releaseIsClosed(official) Then s3Sync = "A"

        Select Case s3Sync
            Case "Y"
                image = "AmazonS3.png"
                hover = "S3 Sync Active"
            Case "N"
                image = "AmazonS3.png"
                hover = "S3 Sync not enabled"
            Case "A"
                image = "AmazonS3.png"
                hover = "S3 Sync not active. Release is no longer open"
                iClass = "class=lessOpacity"
            Case Else
                image = "LXRlogo64_progress.jpeg"
                hover = "S3Sync unknown State:(" & s3Sync &")"
        End Select
        RenderS3SyncStateString = "<span title='"&hover&"'><img "& iClass &" src=""images/"&image&""" height=16 border=0 vspace=0 hspace=0 style='vertical-align : bottom'>" & txt & "</span>"
    End If
End Function 
 

'-------------------------------------------------
' Function:         rippleFieldName   
' Description:      Return a string to convert a ripple field state to a text name
'                   bFlag is set to false if the state is unknown.
Dim rippleFieldValues
rippleFieldValues = Array ("M", "m", "p", "b", "L")
Function rippleFieldName ( rstate, ByRef bFlag )
    If isNULL(rstate) Then
        rstate = "b"
    End If

    bFlag = TRUE
    Select Case rstate
            Case "M" 
                rippleFieldName = "Major Number"
            Case "m" 
                rippleFieldName = "Minor Number"
            Case "p" 
                rippleFieldName = "Patch Number"
            Case "b" 
                rippleFieldName = "Build Number"
            Case "L" 
                rippleFieldName = "Limited"
            Case Else 
                rippleFieldName = "Invalid State"
                bFlag = FALSE
        End Select
End Function
'----------------------------------------------------
' Function: emailField
' Description: Generate a 'span' with email information
' The mailto class is picked up the jquery for processing
Function emailField(sName, sEmail)
    emailField = "<span title='Select Email Options' class='mailto txt_linked' data-email='" & sEmail & "'>" & sName & "</span>"
End Function
Function emailField3(sName, sEmail,sUname)
    emailField3 = "<span title='Select Email Options' class='mailto txt_linked' data-email='" & sEmail & "' data-uname='" & sUname & "'>" & sName & "</span>"
End Function

'-----------------------------------------------------------------------------------------------------------------------------

Function ReleaseIcon ( cOfficial )
        
        If cOfficial = "N" Then
                ' Open Mode
                ReleaseIcon = LIMG_OPEN_MODE
                
        ElseIf cOfficial = "R" Then
                ' Restrictive Mode
                ReleaseIcon = LIMG_RESTRICTIVE_MODE
        
        ElseIf cOfficial = "C" Then
                'CCB Mode
                ReleaseIcon = LIMG_CCB_MODE
                
        ElseIf cOfficial = "Y" Then
                'Closed Mode
                ReleaseIcon = LIMG_CLOSED_MODE

        ElseIf cOfficial = "O" Then
                'Closed Mode - With warning (aged)
                ReleaseIcon = LIMG_CLOSED_MODE_WARN
                
        ElseIf cOfficial = "P" Then
                'Closed Mode - Archived, but don't purge
                ReleaseIcon = LIMG_PRESERVE_MODE

        ElseIf cOfficial = "A" Then
                'Archive Mode
                ReleaseIcon = LIMG_ARCHIVE_MODE 
        End If
        
End Function
'-----------------------------------------------------------------------------------------------------------------
Function SdkIcon (cState)
    If cState = "R" Then
        ' Released - available for use
        SdkIcon = LIMG_CLOSED_MODE
    ElseIf cState = "D" Then
        ' Deprecated - Cannot be added to a Release any more
        SdkIcon = LIMG_ARCHIVE_MODE
    ElseIf cState = "U" Then
        ' Work in progress - Still being constructed. Cannot be added to a Release yet
        SdkIcon = LIMG_OPEN_MODE
    End If
End Function
'-----------------------------------------------------------------------------------------------------------------
'
'   Helper rountien to create a button that will be wired into JavaScript
'
Sub BuildJsButton (bState, sClass, sTitle, sImage)%>
    <%If bState Then%>
                <span class="<%=sClass%>" title="<%=sTitle%>"><img <%=sImage%>></span>
    <%Else%>
                <span class="abtnItemDis" title="<%=sTitle%>"><img <%=sImage%> class="lessOpacity"></span>
    <%End If%>
<%End Sub
'------------------------------------------------------------------------------
'   Helper routine to create buttons and disabled buttons
'   Treat the action an href - link the user can see and potentially open in another tab
'
Sub BuildActionButtonLink(bState, sText, sTitle, sImage, sRef)
 %>
<td align="center" nowrap valign="bottom" title="<%=sTitle%>">
    <%If bState Then%>
    <a href="<%=sRef%>" class="abtnItem"><img <%=sImage%> ><%=sText%></a>
    <%Else%>
    <span class="abtnItemDis"><img <%=sImage%> class="lessOpacity"><%=sText%></span>
    <%End If%>
</td>
<%End Sub
'------------------------------------------------------------------------------
'   Helper routine to create buttons and disabled buttons
'   Treat the ref as a page to goto, but don't use href
'
Sub BuildActionButton(bState, sText, sTitle, sImage, sRef)
 %>
<td align="center" nowrap valign="bottom" title="<%=sTitle%>">
    <%If bState Then%>
    <span onClick="location.href='<%=sRef%>'" class="pointer abtnItem"><img <%=sImage%> ><%=sText%></span>
    <%Else%>
    <span class="abtnItemDis"><img <%=sImage%> class="lessOpacity"><%=sText%></span>
    <%End If%>
</td>
<%End Sub
'------------------------------------------------------------------------------
'   Helper routine to create buttons and disabled buttons
'   Tack a onClick operation
'
Sub BuildActionButtonClickRaw(bState, sText, sTitle, isBlue, sImage, sClick)
    Dim sStyle : sStyle = ""
    If Left(sImage,4) = "<img" Then sImage = Mid(sImage, 5, Len(sImage)-5)
    If bState Then
    If isBlue Then sStyle = "color:#0000ee; text-decoration:underline"%>
    <span onClick="<%=sClick%>" class="pointer abtnItem" title="<%=sTitle%>" style="<%=sStyle%>"><img <%=sImage%> ><%=sText%></span>
    <%Else%>
    <%If isBlue Then sStyle = "color:#0000ee66; text-decoration:none"%>
    <span class="abtnItemDis" style="<%=sStyle%>"><img <%=sImage%> class="lessOpacity"><%=sText%></span>
    <%End If
End Sub

Sub BuildActionButtonClick(bState, sText, sTitle, isBlue, sImage, sClick)%>
<td align="right" nowrap valign="center" title="<%=sTitle%>">
    <%BuildActionButtonClickRaw bState, sText, sTitle, isBlue, sImage, sClick %>
</td>
<%End Sub

'------------------------------------------------------------------------------
'   Helper routine to create Text with a button that follows
'   Tack a onClick operation
'
Sub BuildEditButtonRaw(bState, sText, sTitle, isBlue, sImage, sClick)
    Dim sStyle : sStyle = "font-weight:bold;"
    Dim sClass : sClass = ""
    If Left(sImage,4) = "<img" Then sImage = Mid(sImage, 5, Len(sImage)-5)
    If bState Then
    If isBlue Then sClass = "txt_linked" : sStyle = ""%>
    <span onClick="<%=sClick%>" class="<%=sClass%> pointer"  style="<%=sStyle%>" title="<%=sTitle%>"><%=sText%>&nbsp;<img <%=sImage%>></span>
    <%Else%>
    <%If isBlue Then sClass = "txt_linked_dis" : sStyle = ""%>
    <span style="<%=sStyle%>" class="<%=sClass%>" title="<%=sTitle%>"><%=sText%>&nbsp;<img <%=sImage%> class="lessOpacity"></span>
    <%End If
End Sub%>