Article
· Nov 23, 2017 12m read

Where is my global stored?

It's well-known that namespace global mapping helps us to write code independent on database storage details (Caché instance name, directory path). But sometimes we can face problems accessing an unsubscripted global which has subscript level mapping (SLM) defined. Most of such cases are evident and associated with administrative tasks that should be done on database level, but some of them can confuse even an experienced developer. Just to start:

  • We can't export such a global using Caché Block format (a.k.a. GOF).
  • We can't kill such a global.

Maybe you can continue this list.

Each of these problems can be easily solved could we get a list of databases where the parts of a given global reside. Here is my quick solution:

map(pNsp, pGlb) Public ; list all maps of SLMapped globals, searching the given (unsubscripted) one
{
  new $namespace
  try {
    set $namespace="%SYS"
    set sc=1
    set:$extract(pGlb)="^" $extract(pGlb)=""
    ; query List(Namespace As %String, Names As %String = "*", CPFFile As %String = "", Flags As %Integer = 0)
    set rset=##class(%Library.ResultSet).%New("Config.MapGlobals:List") 
    ; Selects Name As %String, Global As %String, Subscript As %String, Database As %String, Collation As %Integer, LockDatabase As %String 
    set sc = rset.Execute(pNsp,pGlb_","_pGlb_"(*")
    while rset.Next() 
      if (rset.Data("Global")=pGlb) {
         write !,rset.Data("Name")," ",rset.Data("Global")," ",rset.Data("Subscript")," ",rset.Data("Database"),!
         set sc1=##Class(Config.Databases).Get(rset.Data("Database"),.prop)
         if sc1 {
             set dir=prop("Directory")
             set ref="^|""^"_prop("Server")_"^"_dir_"""|"_pGlb
             try {
                 write ref," ... ",$data(@ref),!
             catch {
                 write $zerror,!
                   set sc=$$$ADDSC(sc,$$$ERROR($$$CacheError,$zerror))
             }
         else {
             set sc=$$$ADDSC(sc,sc1)
         }
      }
    }
  catch {
      write $zerror,!
      set sc=$$$ADDSC(sc,$$$ERROR($$$CacheError,$zerror))
  }
  if $isobject($get(rset)) do rset.Close()
  quit sc
}

E.g., for global mapping defined as follows:

The global mappings for namespace QMSTEST8 are displayed below:
     
 Filter:  Page size:  Max rows:  Results: 2  Page: |‹‹‹1›››|of 1  
   Global Subscript Database     
 zQ QMSDEVELDBEditDelete
 zQ("0!"):(END)CACHETEMPEditDelete

my procedure gives a result:

USER>d map^db.82U("QMSTEST8","^zQ")

zQ zQ  QMSDEVELDB
^|"^DEVEL^D:\InterSystems\devel\mgr\qms\"|zQ ... 10

zQ("0!"):(END) zQ ("0!"):(END) CACHETEMP
^|"^^D:\InterSystems\test\mgr\cachetemp\"|zQ ... 10

HTH somebody. Happy coding!

Discussion (8)2
Log in or sign up to continue