New post

Find

Article
· Aug 15, 2023 2m read

Using NativeAPI Extension from Python

In my previous articles, I described my Command Line Extension to NativeAPI.
Of course, this is also available for any other NativeAPI package.
So I created this example in Python as a demo.

The package contains also an IRIS server in Docker for the demo
It is evident that it also works with any remote IRIS server.
You just have to provide it with my NativeAPI CommandLine Extension.

I think this demo is easy to follow and shows the essential features.

  • First, you install the package and start the container
  • then you start the demo
    docker-compose exec iris python3 src/rcc.py
  • Next, you connect  to your IRIS server defaults refer to the ádde IRIS server in the container
    >>> serverIP [127.0.0.1]:
    >>> serverPORT [1972]:
    >>> namespace [USER]:
    >>> username [_SYSTEM]:
    >>> password [SYS]:
    Connected to Instance IRIS on Server 1C09927CAE60 
  • Now, you get into the demo menu
    Select Demo to exercise 
     0 = free ObjectScript
     1 = $ZV from Server
     2 = Actual Time in Server
     3 = TimeZone Offset of Server
     4 = Server ArchitectureVendorModel
     5 = List Global in ZWRITE style
     * = Terminate demo
    >>> take a choice [1]:  
  • And this is the result when you run through all 5 examples
    >>> take a choice [1]:
     IRIS for UNIX (Ubuntu Server LTS for x86-64 Containers) 2023.2 (Build 227U) Mon Jul 31 2023 18:04:28 EDT 
    
    >>> take a choice [1]: 2
     2023-08-15 07:42:16 
    
    >>> take a choice [1]: 3
     0 
    
    >>> take a coice [1]: 4
     x86_64 * Intel * Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz 
    
    >>> take a choice [1]: 0 
    >>> Your ObjectScript [ quit "?"]: quit $ZTS
     66701,27813.678790226 
    
    >>> take a choice [1]: 0 
    >>> Your ObjectScript [ quit "?"]: quit 17/4
     4.250000000000000000 
    
    >>> take a choice [1]: 0 
    >>> Your ObjectScript [ quit "?"]: quit 17/0
     <DIVIDE> 18 x^%ZX 
    
    >>> take a choice [1]: 5 
    >>> Your Global [^dc.MultiD]:
     ^dc.MultiD = 5
     ^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}"
     ^dc.MultiD(5) = $lb("","")
     ^dc.MultiD(5,"mJSON") = "{}"
     **** done ***
    
     >>> take a choice [1]: *
       Thank you for trying the demo

If you prefer to test it with embedded Python use

docker-compose exec iris iris session iris "##class(nacl.rcc).py()"

 

Video

3 Comments
Discussion (3)2
Log in or sign up to continue
Article
· Aug 10, 2023 3m read

Remote Global Listing using NativeAPI for ObjectScript #2

As noted in the previous article Native API has some limits.
So I did some research on a more Terminal-like interface that
provides me with access like a console or the IRIS terminal
to allow my  $QUERY over a global and other nice commands
that are not supported/mapped in NativeAPI for ObjectScript.

The basic tools are well-prepared and available.

  • Connection() creates a fully operational and stable partition for me
  • Function() allows calling any routine or method I need
  • similar ClassMethodValue and ClassMethodVoid

There is just no method CommandLine and some already prepared code is needed.

My simple approach: Send the  code and let it eXECUTE
It is just a 1-liner to mimic a single command line

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

If you don't have access to some programming tool you may use this
Stored Procedure from MgmtPortal/SQL for installation:

CREATE PROCEDURE %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()
}

And next you need your connection object

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 handling
  quit %rccdb
}

Now a few preliminary examples using method Function
CON is my CommectionObject

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

The 3rd argument will always return something as %RawString
And if something fails:

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

and this is a simple Remote Global Lister.
Then making a copy or renaming is a rather trivial task:

gl ; list remote Global
  set global="^dc.MultiD"  ;; adjust as required
  set 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----------",!

The focus is on getting all control local and just 1 call by Global node
Test action:

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----------

Of course, there are a lot of other activities than just Global listing possible
You may take a look into the ages-old Global ^% to get a feeling,
what programming with XECUTE + $XECUTE() can do.


BTW:
this is not a contribution to ePy contest
  😉
 

1 Comment
Discussion (1)1
Log in or sign up to continue
Article
· Aug 10, 2023 3m read

Remote Global Listing using NativeAPI for ObjectScript #1

This question originally appeared in the comments of the post: Download globals from a particular server
 

This article was inspired by a recent question from @Evgeny Shvarov 
Download globals from a particular server

It is not a click-and-run code but a draft that requires adjustments for your special needs
you have  to add 

  • your credentials for server access
  • your level of error handling
  • Global name
  • the first set of subscripts as  %LB() block default=""
  • the last set of subscripts as  %LB() block default=""
  • a new global name if required default="" >> name not changed

If nothing than the global name is provided the result is a pure copy.

Warning: 
This code runs rather slowly and creates a lot of network traffic
Background As $QUERY is not supported by Native API  it is a rather
long and boring workaround with IsDefined (aka $DATA) and GetNext (aka $ORDER)

Advantage:
With this approach, there is NO need for any other code or adjustment on the remote server.
And that's my only reason to publish this example

An improvement is a "work in progress". Stay tuned for #2

Class nacl.GVC
{

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 handling
  quit %rccdb
}

/// tosubscript stops loop
ClassMethod View(
  global As %String = "",
  fromsubscript As %List = "",
  tosubscript As %List = "")
{
  quit ..Copy(global,fromsubscript,tosubscript,"")
}

/// rename also works to local variable array
ClassMethod Copy(
  global As %String = "",
  fromsubscript As %List = "",
  tosubscript As %List = "",
  rename As %String = "*")
{
#dim %rccdb as %Net.DB.Iris
 set subs=..Args(fromsubscript)
 set stop=..Args(tosubscript)
 set:rename="*" rename="^"_global 
loop
 if $l(subs),$l(stop),$p(subs,stop)="" quit 1
 set gx=""""_global_""""
#; write !?20,gx_subs   just for debug
 set x1="quit %rccdb.IsDefined("_gx_subs_")"
   , dd=$xecute(x1)
 if $l(stop),subs]]stop quit 1
 if dd#10 { 
   set x2="quit %rccdb.Get("_gx_subs_")"
     , val=$xecute(x2)
     , tx=rename_$s($l(subs):"("_$e(subs,2,*)_")",1:"")
     , tv=##class(%Utility).FormatString(val)
     , x3="(val) set "_tx_"=val q 1 "
   if $l(rename),$xecute(x3,val) write tx," = ",tv,!    
   else  write "^",global,tx," = ",tv,!  
   }
up
 set down=$s(dd\10:",""""",1:"")
 set x4="quit %rccdb.GetNext(1,0,0,"_gx_subs_down_")"
   , nxsub=$xecute(x4)
 if nxsub="" {
   set dd=0
   if down="" set subs=$p(subs,",",1,*-1)
   goto up
   } 
 if '$isvalidnum(nxsub) set nxsub=""""_nxsub_""""
 set $p(subs,",",*+(dd\10))=nxsub   
 if $l(subs,",")<2 quit 1
 goto loop
}

ClassMethod Args(list As %List = "") As %String
{
  if '$listvalid(list) set list=$lb(list)
  set ll=$ll(list),subs=""
  for i=1:1:ll {
    set sub=$li(list,i)
      , subs=subs_","_$s($isvalidnum(sub):sub,1:""""_sub_"""")
  }
  quit subs
}
}
Discussion (1)1
Log in or sign up to continue
Question
· Aug 9, 2023

VS Code : unable to save file to server

When I open a class in VS Code and I want to save it I'm getting the following error : Non-JSON response to /api/atelier/v7/DEV/doc/API.Mollie.Execute.cls?ignoreConflict=0 request. Is the web server suppressing detailed errors?

Also I always get a popup when I open VS Code "The extension wants to sign in using InterSystems Server Credentials."

3 Comments
Discussion (3)4
Log in or sign up to continue
Question
· Aug 4, 2023

Azure Databricks JDBC connection to Intersystems

We encountered difficulties while attempting to establish a JDBC connection to Intersystems using AZURE Databricks, resulting in an inability to retrieve data. The JDBC version utilized was intersystems-jdbc-3.3.1.jar. If anyone has successfully employed Databricks for establishing a connection, we would appreciate information regarding the libraries you used

 

Error Message:
org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 0.0 failed 4 times, most recent failure: Lost task 0.3 in stage 0.0 (TID 3) (10.140.70.71 executor driver): java.sql.SQLException: [SQLCODE: <-25>:<Input encountered after end of query>]

7 Comments
Discussion (7)3
Log in or sign up to continue