Vitaliy Serdtsev · Dec 17, 2025 go to post

My current code size is 74 (where alphabetical characters only a-z,A-Z).

 

size = 74

ClassMethod Encode(mAs %String
{
 j=65,97{i=0:1:25 m=$tr(m,$c(j+i),i#2)$re($e(m,1,*-1))_$e(m,*)
}

"Hello World µÝ Привет Мир!" -> "риМ тевирП Ýµ 11100 01101!"

PS: why is the correct result in the testNumbers method 321 and not 213?

Vitaliy Serdtsev · Dec 8, 2025 go to post

Wow!

By the way, if you remove the second brackets, the query works:

<FONT COLOR="#0000ff">SELECT </FONT><FONT COLOR="#000000">1 </FONT><FONT COLOR="#000080">WHERE </FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">''</FONT><FONT COLOR="#000000">) = </FONT><FONT COLOR="#008080">'_㉸^'</FONT>
It requires Java 17, and InterSystems IRIS Enterprise (it uses many connections).
Do I understand correctly that with the built-in Community Edition license, the SQLancer tool cannot be fully used?
Vitaliy Serdtsev · Dec 8, 2025 go to post

One of the options for Caché 2018.1:

<FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">xmlStream</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%Stream.FileBinary</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">%New</FONT><FONT COLOR="#000000">()
</FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">xmlStream</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Filename</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"C:\test_from.xml"

</FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">jsonStream</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%Stream.FileBinary</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">%New</FONT><FONT COLOR="#000000">() </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">jsonStream</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Filename</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"C:\test_to.json"

</FONT><FONT COLOR="#0000ff">#dim </FONT><FONT COLOR="#808000">d </FONT><FONT COLOR="#0000ff">As </FONT><FONT COLOR="#008080">%Document.Object </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%Document.Object</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">XML</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">xmlStream</FONT><FONT COLOR="#000000">)

</FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#808000">d</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">%ToJSONStream</FONT><FONT COLOR="#000000">(.</FONT><FONT COLOR="#808000">jsonStream</FONT><FONT COLOR="#000000">)

</FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#808000">jsonStream</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">%Save</FONT><FONT COLOR="#000000">()</FONT>

Vitaliy Serdtsev · Dec 8, 2025 go to post
For = 1:1:maxRow {
Set cel pySheet.cell(i,y)
If cel."is_date" {
  Set val = cel.value.date().isoformat() ; ODBC Date  Set MolDatum $zdh(val,3) ; LOGICAL Date
  Write $zd(MolDatum),! ; DISPLAY Date
}
}
Vitaliy Serdtsev · Dec 1, 2025 go to post
Class dc.test Abstract ]
{

ClassMethod Test()
{
  #dim ex As %Exception.AbstractException
  #dim xDataStream As %Stream.Object
  #dim mydoc As %XML.XPATH.Document

  try{

    set xDataStream=##class(%Dictionary.CompiledXData).IDKEYOpen(..%ClassName(1),"ClinicalDocXData").Data

    $$$ThrowOnError(##class(%XML.XPATH.Document).CreateFromStream(xDataStream, .mydoc,,,,,"s urn:hl7-org:v3"))
    $$$ThrowOnError(mydoc.EvaluateExpression("//s:entry/s:Id""text()", .tRes))

    for =1:1:tRes.Count() {
      write tRes.GetAt(i).Value,!
    }    

  }catch(ex{
    write "Error "ex.DisplayString(),!
  }
}

XData ClinicalDocXData
{
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MainDocument xmlns="urn:hl7-org:v3">
  <realmCode code="IT"/>
  <title>kjbkjkjbkjb</title>
  <effectiveTime value="20090905150716"/>
  <versionNumber value="1"/>
  <component>
    <body>mhvjhjkvhj</body>
    <component>
      <section>content</section>
      <ID>5</ID>
      <title>Certificato</title>
      <text/>
      <entry>
        <Id>5</Id>
      </entry>
      <entry>
        <Id>6</Id>
      </entry>
    </component>
  </component>
</MainDocument>
}

}
Result:
USER>do ##class(dc.test).Test()

5 6

Vitaliy Serdtsev · Nov 27, 2025 go to post
 

TEST.TEST.cls

Class TEST.TEST Extends %Persistent
{

Property userActionone As %Boolean SqlColumnNumber ];

Property userActiontwo As %Boolean SqlColumnNumber ];

Property userActionthree As %Boolean SqlColumnNumber ];

Property userActionfour As %Boolean SqlColumnNumber ];

Property userActionfive As %Boolean SqlColumnNumber ];

Property userActionsix As %Boolean SqlColumnNumber ];

Property userActionseven As %Boolean SqlColumnNumber ];

Property userActioneigth As %Boolean SqlColumnNumber ];

Property userActionnine As %Boolean SqlColumnNumber 10 ];

Property userActionten As %Boolean SqlColumnNumber 11 ];

Property userActioneleven As %Boolean SqlColumnNumber 12 ];

Property userActiontwelve As %Boolean SqlColumnNumber 13 ];

Property userActionthirteen As %Boolean SqlColumnNumber 14 ];

Property userActionfourteen As %Boolean SqlColumnNumber 15 ];

ClassMethod Fill()
{
  &sql(truncate table TEST.TEST)
  &sql(insert into TEST.TEST
  (userActionone,
  userActiontwo,
  userActionthree,
  userActionfour,
  userActionfive,
  userActionsix,
  userActionseven,
  userActioneigth,
  userActionnine,
  userActionten,
  userActioneleven,
  userActiontwelve,
  userActionthirteen,
  userActionfourteen)
  select 0,0,0,0,0,0,0,0,0,0,0,0,0,0
  union all
  select 1,0,0,0,0,0,0,0,0,0,0,0,0,0
  union all
  select 0,1,0,0,0,0,0,0,0,0,0,0,0,0
  union all
  select 0,0,1,0,0,0,0,0,0,0,0,0,0,0
  union all
  select 0,0,0,1,0,0,0,0,0,0,0,0,0,0
  union all
  select 0,0,0,0,1,0,0,0,0,0,0,0,0,0
  union all
  select 0,0,0,0,0,1,0,0,0,0,0,0,0,0
  union all
  select 0,0,0,0,0,0,1,0,0,0,0,0,0,0
  union all
  select 0,0,0,0,0,0,0,1,0,0,0,0,0,0
  union all
  select 0,0,0,0,0,0,0,0,1,0,0,0,0,0
  union all
  select 0,0,0,0,0,0,0,0,0,1,0,0,0,0
  union all
  select 0,0,0,0,0,0,0,0,0,0,1,0,0,0
  union all
  select 0,0,0,0,0,0,0,0,0,0,0,1,0,0
  union all
  select 0,0,0,0,0,0,0,0,0,0,0,0,1,0
  union all
  select 0,0,0,0,0,0,0,0,0,0,0,0,0,1
  )
}

}

That's what I get:

  

PS: Have youtriedrebuilding the cube?

Vitaliy Serdtsev · Nov 27, 2025 go to post

As you can see, the author asked two questions:

  1. In some cases, it's necessary to manipulate data from one namespace to another. For example, a routine in the "N1" namespace needs data from the "N2" namespace.
  2. In the same context, how could I make a persistent class global for all namespaces? The only way I know is by putting it in %SYS.
What would be the best practices for these use cases?
I answered the second question, and the other participants answered the first.
Vitaliy Serdtsev · Nov 27, 2025 go to post
Both.
Just for understanding. Will the result change if the conditions are reversed? For example:
$SELECT(
%source.userActionfourteen=1:"User action fourteen",
%source.userActionthirteen=1:"User action thirteen",
%source.userActiontwelve=1:"User action twelve"%source.userActioneleven=1:"User action eleven"%source.userActionten=1:"User action ten"%source.userActionnine=1:"User action nine"%source.userActioneigth=1:"User action eigth"%source.userActionseven=1:"User action seven"%source.userActionsix=1:"User action six"%source.userActionfive=1:"User action five"%source.userActionfour=1:"User action four"%source.userActionthree=1:"User action three",
%source.userActiontwo=1:"User action two",
%source.userActionone=1:"User action one", 1:"Other")
Vitaliy Serdtsev · Nov 26, 2025 go to post

I agree.

<FONT COLOR="#0000ff">$CASE</FONT><FONT COLOR="#000000">(1,
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActionone</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action one"</FONT><FONT COLOR="#000000">, 
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActiontwo</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action two"</FONT><FONT COLOR="#000000">,
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActionthree</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action three"</FONT><FONT COLOR="#000000">,
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActionfour</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action four"</FONT><FONT COLOR="#000000">, 
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActionfive</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action five"</FONT><FONT COLOR="#000000">, 
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActionsix</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action six"</FONT><FONT COLOR="#000000">, 
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActionseven</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action seven"</FONT><FONT COLOR="#000000">, 
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActioneigth</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action eigth"</FONT><FONT COLOR="#000000">, 
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActionnine</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action nine"</FONT><FONT COLOR="#000000">, 
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActionten</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action ten"</FONT><FONT COLOR="#000000">, 
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActioneleven</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action eleven"</FONT><FONT COLOR="#000000">, 
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActiontwelve</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action twelve"</FONT><FONT COLOR="#000000">, 
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActionthirteen</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action thirteen"</FONT><FONT COLOR="#000000">,
</FONT><FONT COLOR="#800000">%source</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">userActionfourteen</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"User action fourteen"</FONT><FONT COLOR="#000000">, :</FONT><FONT COLOR="#008000">"Other"</FONT><FONT COLOR="#000000">)</FONT>
But the result will still be only one value, even if all %source.userActionXXX=1.
Vitaliy Serdtsev · Nov 26, 2025 go to post

What result should $select return if the conditions %source.userActionone=1 AND %source.userActiontwo=1 are true ?

Vitaliy Serdtsev · Nov 24, 2025 go to post

Strange. I just checked on Caché Studio 2014.1.5 and Caché 2014.1.5 (logged in under superuser) - output

CSTUDIO.EXE

 

Vitaliy Serdtsev · Nov 20, 2025 go to post
json=[
{"s":"iPhone1"},
{"s":"iPhone2"},
{"s":"IPHONE3"},
{"s":"IPHONE4"},
{"s":"Phone5"}
]

##class(%ASQ.SetUtils).pp(json.apply("$[*]?(@.s like_regex '\p{LL}\w+')"))

Output (IRIS 2025.3CE):

[
  {
    "s": "iPhone1"
  },
  {
    "s": "iPhone2"
  }
]
Vitaliy Serdtsev · Nov 20, 2025 go to post

Check the result outputs of the following code from Studio and from Terminal:

<FONT COLOR="#0000ff">w $zu</FONT><FONT COLOR="#000000">(67,13,</FONT><FONT COLOR="#0000ff">$j</FONT><FONT COLOR="#000000">)</FONT>
Vitaliy Serdtsev · Nov 13, 2025 go to post

A long time ago, back in the days of Caché, I made a series of articles on creating a web application based on REST and CSP with my own static file processing. Try it, maybe you can use something from there.

Vitaliy Serdtsev · Nov 13, 2025 go to post

I will assume that you are using "Normal" (in which the user _SYSTEM is turned off) or even "Locked Down" (the user "UnknownUser" has no roles at all): Initial User Security SettingsDOC

I'm using "Locked Down", IRIS 2025.2CE and ran into a lot of different bugs when using WebTerminal v4.9.5:

  • <PROTECT>endSession+25^%SYS.cspServer
  • <LICENSE LIMIT EXCEEDED>
  • etc.
Fortunately, the WebTerminal source code is available for analysis and editing.

The problem can be solved in two ways: either fix the source code or add the missing role. I chose the latter.

In my case, it is enough for the web application /terminalsocket to add the %Admin_Secure role in addition to the existing roles. After that, it doesn't hurt to clean up all existing sessions:

kill ^WebTerminal("AuthUser")

If the <LICENSE LIMIT EXCEEDED> error persists after this, restart the IRIS instance.

PS: Advisory for IRISSECURITY in InterSystems IRIS 2025.2

Vitaliy Serdtsev · Nov 13, 2025 go to post

Credentials are not requested, as most likely your existing session has not expired yet. By default, the timeout is 1 hour (see the "WebTerminal.Engine:WSKEYEXPIRES" class parameter).

Vitaliy Serdtsev · Nov 5, 2025 go to post

I would venture to assume that this difference is due to the overhead of calling the class method. In other words:

  • ##class(%DynamicArray).%New() -> ..%OnNew() -> $ZU()
  • [] -> $ZU()
There was a similar topic: Shared code execution speed
Vitaliy Serdtsev · Oct 31, 2025 go to post
"Real life" *.inc entry is to execute macro routine "Entry^HS.Local.VA.Util.Log(%arr,,"D")" if Global ^GlFSL("Debug") is >0 by calling from a classmethod as $$$TestIf(arr) - no return value is required.
#define TestIf(%arr) if (^GlFSL("Debug")>0) {do Entry^HS.Local.VA.Util.Log(%arr,,"D")};or#define TestIf(%arr) do:^GlFSL("Debug")>0 Entry^HS.Local.VA.Util.Log(%arr,,"D")
Usage:
$$$TestIf(5)
Vitaliy Serdtsev · Oct 31, 2025 go to post
Statement "set a = $$$TestIf(3)" is included into a classmethod with no other code in. Expected output 5
What is the expected result for the next operator?
set $$$TestIf(-3)
Vitaliy Serdtsev · Oct 30, 2025 go to post

You have two mistakes.

  • Instead
    for {i=1:1:%count set x=
    should be
    for i=1:1:%count {set x=
  • Macros ≠ Function

A working example:

  #define MyLoop(%count,%result) set ref="",%result="" for i=1:1:%count set ref=$order(^%SYS("JOURNAL",ref),-1),%result=%result_$listbuild(ref)

  $$$MyLoop(5,x)
  write $listtostring(x)
Vitaliy Serdtsev · Oct 30, 2025 go to post

Example of @Robert Cemper compiles without errors for me (even on Caché 2018.xxx):

Class dc.a Abstract ]
{

ClassMethod Test()
{
  #define MyLoop(%count) set x="" for i=1:1:%count set x=$order(^%SYS("JOURNAL",x),-1) write x,! 
  $$$MyLoop(5)
}

}
Vitaliy Serdtsev · Oct 30, 2025 go to post

If the array is multidimensional, then you can't do without loops (the code is without error handling):

  #define ArrayToStr(%arr,%str) set ref=$name(%arr),%str="s " for  {set ref=$query(@ref,1,val) quit:ref=""  set %str=%str_$$FormatName^%qcr(ref,1)_"="_##class(%Utility).FormatString(val)_","} set $extract(%str,*)=""
  #define StrToArray(%str) xecute %str

Usage:

  set a(0)=7
  set a(1,"color")="green"
  set a(1,"color","green")=""
  set a("color",$listbuild($double(3)))=$listbuild("red","blue")

  $$$ArrayToStr(a,str)
  zwrite str
  kill a
  $$$StrToArray(str)
  zwrite a
Vitaliy Serdtsev · Oct 30, 2025 go to post
I would like to have *inc file entry to convert an array into a string and string into an array.
If the array is one-dimensional, then you can do without cycles altogether. I'll give you a small example below:
  #define Array1ToJSONString(%arr,%json)##continue
  s ##unique(new)=##class(%ZEN.proxyObject).%New()##continue
  d ##unique(old).%CopyFromArray(.%arr),##continue
    ##class(%ZEN.Auxiliary.altJSONProvider).%WriteJSONStreamFromObject(.%json,##unique(old))##continue
  s %json=%json.Read(3641144)
  
  #define JSONStringToArray1(%json,%arr)##continue
  d ##class(%ZEN.Auxiliary.altJSONProvider).%ConvertJSONToObject(%json,,.##unique(new)),##continue
    ##unique(old).%CopyToArray(.%arr)

Usage:

  set a("color")=$listbuild("red","blue")
  set a("price")="expensive"
  set a("size")=$listbuild("large","small")
    
  $$$Array1ToJSONString(a,jsonStr)
  zwrite jsonStr
  $$$JSONStringToArray1(jsonStr,b)
  zwrite b