Translation of: LUA

calcPILua(n=1000) public { 
  len = 10*n\3,
    nines = 0,
    predigit = 0
  
  j=1:1:len a(j)=2
  
  j=1:1:{
    q=0
    i=len:-1:1 {
      = 10*a(i) + (q*i),
        a(i)=x#(2*i-1),
        q=x\(2*i-1)
    }
    a(1)=q#10,
      q=q\10
    q=9 {
      nines nines + 1
    }elseif q=10 {
      predigit+1
      = 1:1:nines 0
      predigit = 0, nines = 0
    }else{
      predigit
      predigit q
      nines {
        = 1:1:nines 9
        nines = 0
      }
    }
  }
  predigit
}

The result of this example is exactly the same as the result of the program C# (tested at n=10000).

Translation of: BASIC256

calcPI(n=1000) public { 
  len = 10*n\4,
    needdecimal $$$YES,
    nines = 0,
    predigit = 0  ;# {First predigit is a 0}
   
  j=1:1:len a(j-1)=2 ;# {Start with 2s}
  
  j=1:1:{
    q=0
    i=len:-1:1 {
      ;#  {Work backwards}
      = 10*a(i-1) + (q*i),
        a(i-1)=x#(2*i-1),
        q=x\(2*i-1)
    }
    a(0)=q#10,
      q=q\10
    q=9 {
      nines nines + 1
    }elseif q=10 {
      predigit+1 outputd
      nines>0 = 1:1:nines =  0 outputd
      predigit = 0, nines = 0
    }else{
      predigit,predigit outputd
      nines {
        = 1:1:nines = 9 outputd
        nines = 0
      }
    }
  }
  predigit
  q
   
outputd()
  if needdecimal {
     q:d=0
     d_"."
     needdecimal $$$NO
  else {
     d
  }
}

The greater "n", the higher the accuracy.

If there is a lack of RAM, you can easily replace the local array "a" with globals ^||a or ^a.

Try this:

XData Contents [ XMLNamespace "http://www.intersystems.com/zen" ]
{
<page xmlns="http://www.intersystems.com/zen">
  <tableNavigatorBar tablePaneId="tp1"/>
    <tablePane
      id="tp1"
      OnCreateResultSet="CreateRS"
      OnExecuteResultSet="ExecuteRS"
      maxRows="0"
      pageSize="10"
      useSnapshot="true"
    >
    <parameter value="USER1"/>
  </tablePane>
  <tableNavigatorBar tablePaneId="tp2"/>
    <tablePane
      id="tp2"
      OnCreateResultSet="CreateRS"
      OnExecuteResultSet="ExecuteRS"
      maxRows="0"
      pageSize="10"
      useSnapshot="true"
    >
    <parameter value="USER2"/>
  </tablePane>
</page>
}

For example so:

Class dc.test Extends %ZEN.Component.page
{

XData Style
{
<style type="text/css">
</style>
}

XData Contents [ XMLNamespace "http://www.intersystems.com/zen" ]
{
<page xmlns="http://www.intersystems.com/zen">
  <tablePane
    OnCreateResultSet="CreateRS"
    OnExecuteResultSet="ExecuteRS"
  >
    <parameter name="ns" value="USER1"/>
  </tablePane>
  <tablePane
    OnCreateResultSet="CreateRS"
    OnExecuteResultSet="ExecuteRS"
  >
    <parameter name="ns" value="USER2"/>
  </tablePane>
</page>
}

Method ExecuteRS(
  myRS As %ResultSet,
  Output pSC As %Status,
  pInfo As %ZEN.Auxiliary.QueryInfoAs %Boolean
{
  myRS.Prepare("select * from xyz")
  myRS.Execute()
  tSC=$$$OK
  q $$$YES
}

Method CreateRS(
  Output tSC As %Status,
  pInfo As %ZEN.Auxiliary.QueryInfoAs %ResultSet
{
  rs=##class(%RemoteResultSet).%New()
  rs.UserName="_system"
  rs.Password="SYS"
  rs.ConnectionString=$$$FormatText("localhost[%1]:%2",##class(%SQL.Manager.API).GetPort(),pInfo.parms(1))
  tSC=$$$OK
  q rs
}

}

For example so:

Class myapp.jsonProvider Extends %ZEN.Auxiliary.jsonProvider
{

ClassMethod getOrderedProps(
  pClass As %Dictionary.CompiledClass,
  ByRef pList) [ Internal ]
{
  ##super(pClass,.pList)

  key "" key $o(pList(key))  q:""=key
    zk:$lf(^||skipProps,pList(key)) pList(key)
  }
}

}

Class myapp.myclass Extends %RegisteredObject
{

Property property1 As %String;

Property property2 As %String;

Property property3 As %String;

/// d ##class(myapp.myclass).Test()
ClassMethod Test()
{
  myClass = ..%New()
  myClass.property1 "value 1"
  myClass.property2 "value 2"
  myClass.property3 "value 3"
  
  i=$lb("property3"),$lb("property2","property1"{
    ^||skipProps=i
    ##class(myapp.jsonProvider).%WriteJSONStreamFromObject(.tStream,myClass,,,$$$YES,"ed")
    "skip:",$lts(i),?25," -> ",tStream.Read(),!
  }
}

}

USER>##class(myapp.myclass).Test()
skip:property3            -> {"property1":"value 1","property2":"value 2"}
skip:property2,property1  -> {"property3":"value 3"}

Made a small demo with two options.

Include %occResultSet

Class dc.test Abstract ]
{

ClassMethod MultiRS(As %Integer) [ ReturnResultsetsSqlProc ]
{
  i#2 {
    $$$ResultSet("select 'Name1_1' s1,'Name2_1' s2 union all select 'Name1_2','Name2_2'")
  else {
    $$$ResultSet("select 1 i1,4 i2,3 i3 union all select 2,5,6 union all select 3,6,9")
    $$$ResultSet("select '+1' n union all select '-2' union all select '3.1' union all select '4_4'")
  }
}

Query MyCustomQueryCube(pCubeName As %StringAs %Query SqlProc ]
{
}

ClassMethod MyCustomQueryCubeExecute(
  ByRef qHandle As %Binary,
  pCubeName As %StringAs %Status
{
  qHandle("pCubeName")=pCubeName

  pCubeName="a" {
    N=2 i=1:1:qHandle(N+1-i)=$lb("Name1_"_i,"Name2_"_i)
  }else{
    N=3 i=1:1:qHandle(N+1-i)=$lb(i,i+3,i*3)
  }
  qHandle=N
  q $$$OK
}

ClassMethod MyCustomQueryCubeFetch(
  ByRef qHandle As %Binary,
  ByRef Row As %List,
  ByRef AtEnd As %Integer 0As %Status PlaceAfter = MyCustomQueryCubeExecute ]
{
  qHandle=0 {
    Row=""
    AtEnd=1
  }else{
    Row=qHandle(qHandle)
    qHandle=qHandle-1
  }
  q $$$OK
}

ClassMethod MyCustomQueryCubeClose(ByRef qHandle As %BinaryAs %Status PlaceAfter = MyCustomQueryCubeFetch ]
{
  qHandle
  q $$$OK
}

ClassMethod MyCustomQueryCubeGetInfo(
  ByRef colinfo As %List,
  ByRef parminfo As %List,
  ByRef idinfo As %List,
  ByRef qHandle As %Binary,
  extoption As %Integer 0,
  ByRef extinfo As %ListAs %Status
{
  qHandle("pCubeName")="a" {
    colinfo=$lb($lb("s1",10,"s1"),$lb("s2",10,"s2"))
  }else{
    colinfo=$lb($lb("i1",5,"i1"),$lb("i2",5,"i2"),$lb("i3",5,"i3"))
  }
  parminfo=$lb($lb("pCubeName","10"))
  idinfo=$lb(0,"")
  q $$$OK
}

ClassMethod MyCustomQueryCubeGetODBCInfo(
  ByRef colinfo As %List,
  ByRef parminfo As %List,
  ByRef qHandle As %BinaryAs %Status
{
  qHandle("pCubeName")="a" {
    colinfo=$lb(2,
                  "s1",12,50,0,2,"s1","test","dc","",$c(0,0,0,0,0,0,0,0,0,0,0,0),
                  "s2",12,50,0,2,"s2","test","dc","",$c(0,0,0,0,0,0,0,0,0,0,0,0)
                 )
  }else{
    colinfo=$lb(3,
                  "i1",4,10,0,2,"i1","test","dc","",$c(0,0,0,0,0,0,0,0,0,0,0,0),
                  "i2",4,10,0,2,"i2","test","dc","",$c(0,0,0,0,0,0,0,0,0,0,0,0),
                  "i3",4,10,0,2,"i3","test","dc","",$c(0,0,0,0,0,0,0,0,0,0,0,0)
                 )
  }
  parminfo=$lb(1,12,50,0,2,"pCubeName",1)
  q $$$OK
}

/// d ##class(dc.test).Test()
ClassMethod Test()
{
  try{

    rs=##class(%SQL.Statement).%New()

    $$$ThrowOnError(rs.%PrepareClassQuery("dc.test","MyCustomQueryCube"))
    i="a","b" rs.%Execute(i).%Display()
    
    !!,"=============="
    
    $$$ThrowOnError(rs.%Prepare("call dc.test_MultiRS(?)"))
    i=0,1 rs.%Execute(i).%Display()
    
  }catch(ex){
    "Error "ex.DisplayString(),!
  }
}

}

USER>##class(dc.test).Test()
 
 
Dumping result #1
s1      s2
Name1_1 Name2_1
Name1_2 Name2_2
 
2 Rows(s) Affected
 
Dumping result #1
i1      i2      i3
1       4       3
2       5       6
3       6       9
 
3 Rows(s) Affected
 
==============
 
Dumping result #1
i1      i2      i3
1       4       3
2       5       6
3       6       9
 
3 Rows(s) Affected
 
Dumping result #2
n
+1
-2
3.1
4_4
 
4 Rows(s) Affected
 
Dumping result #1
s1      s2
Name1_1 Name2_1
Name1_2 Name2_2
 
2 Rows(s) Affected

Also I'm curious if we can set up and pass a JSON that easily too? Would be great.

Certainly.

Class dc.test Extends %RegisteredObject
{

ClassMethod MethodTest(args As %DynamicObject)
{
 i $IsObject(args{
   args.%ToJSON(),!
   w:args.%IsDefined("arr"args.arr."2",!
 }else{
   "null",!
 }
}

ClassMethod Test()
{
  ;d ##class(dc.test).Test()
  ..MethodTest(),
    ..MethodTest({}),
    ..MethodTest({"arg1":($zts),"arg6":"hello","arr":["a",10,true,2.5674]})
}

}

Result:

USER>##class(dc.test).Test()
null
{}
{"arg1":"65136,19638.022","arg6":"hello","arr":["a",10,true,2.5674]}
1

First, should be so (AttachFile):

status=msg.AttachFile("F:\MyDir","myFirstFile.pdf",1,,.count)

status=msg.AttachFile("F:\MyDir","mySecondFile.pdf",1,,.count)

Second, you did not specify the error text.

Try the following simple MAC-example, replacing the values with your own:

#include %systemInclude
new

try{

  $$$AddAllRoleTemporaryInTry
  new $namespace
  
  set msg=##class(%Net.MailMessage).%New()

  set msg.Subject="Subject"

  set msg.From="from@domain"

  do msg.To.Insert("to@domain")

  do msg.TextData.Write("Hello!")
  
  $$$ThrowOnError(msg.AttachFile("F:\MyDir","myFirstFile.pdf"))
  $$$ThrowOnError(msg.AttachFile("F:\MyDir","mySecondFile.pdf"))

  set smtp=##class(%Net.SMTP).%New()
  set smtp.smtpserver="123.145.167.189"

  $$$ThrowOnError(smtp.Send(msg))
      
}catch(ex){
  write "Error "ex.DisplayString(),!
}

See examples and try "Run It" in JSON_ARRAYAGG.

E.g.:

  1. SELECT JSON_ARRAYAGG(Home_StateFROM Sample.Person WHERE Home_State %STARTSWITH 'A'

    Result:

    ["AR","AL","AR","AL","AL","AR","AK","AL","AR","AK","AK","AZ","AR","AR","AL"]
  2. SELECT JSON_OBJECT('state':Home_StateFROM Sample.Person WHERE Home_State %STARTSWITH 'A'

    Result:

    {"state":"AR"}
    {"state":"AL"}
    {"state":"AR"}
    {"state":"AL"}
    {"state":"AL"}
    {"state":"AR"}
    {"state":"AK"}
    {"state":"AL"}
    {"state":"AR"}
    {"state":"AK"}
    {"state":"AK"}
    {"state":"AZ"}
    {"state":"AR"}
    {"state":"AR"}
    {"state":"AL"}
  3. SELECT JSON_ARRAYAGG(JSON_OBJECT('state':Home_State)) FROM Sample.Person WHERE Home_State %STARTSWITH 'A'

    Result:

    [{"state":"AR"},{"state":"AL"},{"state":"AR"},{"state":"AL"},{"state":"AL"},{"state":"AR"},{"state":"AK"},{"state":"AL"},{"state":"AR"},{"state":"AK"},{"state":"AK"},{"state":"AZ"},{"state":"AR"},{"state":"AR"},{"state":"AL"}]