Question
· Jan 15, 2020

How to determine that a package exists?

I need to know if given package exists or not.

Currently found two solution - one doesn't work, another works but I don't like it.

 

Solution 1.

I started, of course, with %Dictionary package - it has PackageDefinition class after all.

However, %ExistsId returned 0 on packages that clearly do exist, so I went to %LoadData, it uses this macro to determine if the package exist:

#define PACKAGE(%package)             ^oddPKG($zcvt(%package,"u"))

And zw ^oddPKG showed the root cause - ^oddPKG global only contains data for packages with tables (or something along these lines).

 

Solution 2.

Using sql to find first class that starts with package name. Seems like an overhead to me.

Query PackageExists(package) As %SQLQuery
{
SELECT TOP 1 1 As "Exists"
FROM %Dictionary.ClassDefinition
WHERE ID %STARTSWITH :package
}

/// write ##class().GetPackageExists("isc")
ClassMethod GetPackageExists(class)
{
    #dim exists As %Boolean
    if class = "" {
        set exists = $$$YES
    } else {
        set package = $case($l(class, "."), 1: class, : $p(class, ".", 1, *-1))
        set rs = ..PackageExistsFunc(package)
        do rs.%Next()
        set exists = (rs.Exists = $$$YES)
    }    
    quit exists
}

Ideas?

Discussion (12)3
Log in or sign up to continue

Create this class:

Class ABC.Try
{

/// w ##class(ABC.Try).PackageExists()
ClassMethod PackageExists(package = "ABC") As %Boolean [ CodeMode = expression ]
{
##class(%Dictionary.PackageDefinition).%ExistsId(package)
}

}

Test:

>w ##class(ABC.Try).PackageExists()
0

It also won't be available in GetPackageList

ABC.Try can also extend registered or persistent to the same effect.

@Julius Kavay got a point.

I will offer two more options:


Class ABC.Try
{

/// d ##class(ABC.Try).PackageExists()
ClassMethod PackageExists(package "ABC")
{
  ; option by Julius Kavay
  list=##class(%Dictionary.PackageDefinition).GetPackageList()
  ''list.Find($zcvt(package,"U")),!
  
  ; option 2
  ##class(%Library.RoutineMgr).Exists($zcvt(package,"U")_".PKG"),!
  
  ; option 3
  list
  d $system.OBJ.GetPackageList(.list,package)
  ''$d(list),!
}

}

USER>##class(ABC.Try).PackageExists("ab")
0
0
0
 
USER>##class(ABC.Try).PackageExists("abc")
1
1
1

UPD:
Take another look at the %Dictionary.PackageDefinitionQuery:SubPackage/FlatPackage, %ZEN.Utils:EnumeratePackages