Escrito por

Sales Engineer at InterSystems Iberia
Artículo Ricardo Paiva · ago 28, 2023 3m read

Listado remoto de Global usando NativeAPI para ObjectScript #2

Como se señaló en el artículo anterior, la API nativa tiene algunos límites. Así que investigué un poco sobre una interfaz más parecida a una Terminal. De manera a permitirme una consola al estilo terminal de IRIS para permitir $QUERY y otros comandos útiles que no son compatibles/mapeados a la API nativa para ObjectScript.

Las herramientas básicas están bien preparadas y disponibles

  • Connection()crea una partición estable y completamente operativa
  • Function()permite llamar a cualquier rutina o método que necesite
  • ClassMethodValue y ClassMethodVoid similares

Simplemente no existe un método CommandLine y para ello se necesita algún código

Mi enfoque es simple: enviar el código y dejar que se ejecute. Es solo una línea para imitar una sola línea de comando

;; routine %ZX.intx(%rcc) try {return$xecute(%rcc)} catch%rcc {return%rcc.DisplayString()}

Si no tienes acceso a alguna herramienta de programación puedes usar este procedimiento almacenado desde el Portal de Gestión/SQL para la instalación:

CREATEPROCEDURE %Zrcc.X()
LANGUAGE OBJECTSCRIPT
{
 set %rcc=##class(%Routine).%New("%ZX.int")
 set %rccline="x(%rcc) try {return $xecute(%rcc)} catch %rcc {return %rcc.DisplayString()}"do %rcc.WriteLine(%rccline)
 do %rcc.Save()
 quit %rcc.Compile()
}

Y luego necesitas tu objeto de conexión.

ClassMethod Connect(
    serverIP = "192.168.0.9",
    serverPORT = 1972,
    namespace = "USER",
    username = "_SYSTEM",
    password = "SYS") As%Net.DB.Iris
{
  try {
    set%rccon=##class(%Net.DB.DataSource).CreateConnection(serverIP
                           ,serverPORT,namespace,username,password)
    set%rccdb=%rccon.CreateIris()
    }
  catch { zw  b  }  ;; do some error handlingquit%rccdb
}

Ahora algunos ejemplos preliminares que utilizan el método Function CON en mi objeto de conexión.

USER>write CON.Function("%ZX","","quit $job")
1920

El tercer argumento siempre devolverá algo en %RawString y si algo falla:

USER>write CON.Function("%ZX","","set x=27,y=0 quit x/y ; will fail")
<DIVIDE> 18 x^%ZX

Este es un Lister Global Remoto simple. Hacer una copia o cambiar el nombre es una tarea bastante trivial:

gl ; list remote Globalset global="^dc.MultiD";; adjust as requiredset a=CON.Function("%ZX","","quit $LB($D("_global_",%rcc),%rcc)")
  Write !,global," = ",$li(a,2)," $DATA = ",$li(a),!
  if$li(a)#10 {
    for { 
      set a=CON.Function("%ZX","","q $LB($q(@$zr),@$ZR)")
      quit:$li(a)=""write$li(a), " = "
        ,##class(%Utility).FormatString($li(a,2)),! 
      }
    }
 Write"-------done----------",!

El enfoque es obtener todo el control local y solo 1 llamada por nodo global.

Acción de prueba:

USER>do ^gl
 
^dc.MultiD = 5 $DATA = 11
^dc.MultiD(1) = $lb("Braam,Ted Q.",51353)
^dc.MultiD(1,"mJSON") = "{}"
^dc.MultiD(2) = $lb("Klingman,Uma C.",62459)
^dc.MultiD(2,2,"Multi","a") = 1
^dc.MultiD(2,2,"Multi","rob",1) = "rcc"
^dc.MultiD(2,2,"Multi","rob",2) = 2222
^dc.MultiD(2,"Multi","a") = 1
^dc.MultiD(2,"Multi","rob",1) = "rcc"
^dc.MultiD(2,"Multi","rob",2) = 2222
^dc.MultiD(2,"mJSON") = "{""A"":""ahahah"",""Rob"":""VIP"",""Rob2"":1111,""Rob3"":true}"
^dc.MultiD(3) = $lb("Goldman,Kenny H.",45831)
^dc.MultiD(3,"mJSON") = "{}"
^dc.MultiD(4) = $lb("","")
^dc.MultiD(4,"mJSON") = "{""rcc"":122}"
-------done----------

Por supuesto, hay muchas otras actividades posibles además del listado global. Puede echar un vistazo al antiguo Global ^% para tener una idea, qué puede hacer la programación con XECUTE + $XECUTE().

Por cierto: esto no es una contribución al concurso ePy  😉

Comments