Lorenzo Scalese · May 21, 2019 go to post

Great!

There, a version with multidimensional array support until 4 subscripts level : 

ClassMethod GetPrivateProp(   oref,   propName,   ByRef result As %Binary) As %String{   Do ##class(%Studio.General).DumpObjectExecute(.arr,.oref)   Set key = $o(arr(propName),1,value), @propName = arr(propName)
   For  {
      Quit:(key="")||($Qs(key,0)'=propName)
      Set subscriptLevel = $Ql(key)
      If subscriptLevel=1 {
         Set @propName@($Qs(key,1))=value
      }ElseIf subscriptLevel=2 {
         Set @propName@($Qs(key,1),$Qs(key,2))=value
      }ElseIf subscriptLevel=3 {
         Set @propName@($Qs(key,1),$Qs(key,2),$Qs(key,3))=value
      }ElseIf subscriptLevel=4 {
         Set @propName@($Qs(key,1),$Qs(key,2),$Qs(key,3),$Qs(key,4))=value
      }
      Set key = $o(arr(key),1,value)   }   Merge result=@propName   Kill @propName
   Quit:$Quit arr(propName) Quit}
Lorenzo Scalese · Mar 9, 2019 go to post

Hello,

I think, you should simply append your own error message like that : 

Set obj = ##class(User.tApplications).%OpenId(YourTApplicationId,"4",.errors)
Set:$$$ISERR(errors) errors = $$$ADDSC(errors,$$$ERROR($$$GeneralError,$$$FormatText("%OpenId failed for User.tApplications with id %1",YourTApplicationId)))

If an error occurs, variable "errors" will contain 2 errors.

NS>d $System.Status.DecomposeStatus(error,.b)
 
NS>zw b

Your error is in the subscript b(2).

Add #include %occStatus if you are in a routine (for macro usage).

Regards.

Lorenzo Scalese · Mar 22, 2019 go to post

Hello,

We are using this procedure in order to reduce the dowtime during software update. 

In short :

  • Create a temp namespace. 
  • import and compile code.
  • stopping application.
  • switch DB code on target namespace.
  • Execute a script for data update (if needed).
  • starting application.

It work fine for Caché.

Coming soon, we will do that for production with HealthShare Health connect.

It should be work fine also for a production, but  I don't done a test yet.

If you have a translate file, don't forget import your traductions because ^CacheMsg and ^CacheMsgNames are in CODE database.

Regards.

Lorenzo Scalese · May 18, 2019 go to post

Hello Eduard,

For debug purpose , you can try this :

Set obj = {Your test.ABC instance}

Set res = ##class(%Studio.General).DumpObjectFunc(obj)

While res.%Next() { Write !,"Property : ",res.%Get("Name"), !," Value : ",res.%Get("Value") }

Or just perform a zw obj

Regards.

Lorenzo.

EDIT : I tested with ##class(%Studio.General).DumpObjectFunc(obj)

We can get value if "myProp" is not an object.

Lorenzo Scalese · Aug 23, 2019 go to post

Hello @Rodolfo Moreira dos Santos,

For retrieve the task ID, I wrote this : 

ClassMethod getTaskId(
    ByRef sc As %Status = {$$$OK},
    className As %String = {..%ClassName(1)}) As %String
{
    Set id = ""
    Set rs = ##class(%Library.ResultSet).%New("%SYS.Task:TaskListDetail")
    Set sc = rs.Execute()
    Quit:$$$ISERR(sc) ""
    While (rs.Next(.sc)) {
        Quit:$$$ISERR(sc)
        if (rs.Get("TaskClass")=className){
            Set id = rs.Get("ID")
            Quit
        }
    }
    Quit id
} 

Hope this help you.

Regards.

Edit : modify this code for your needs (ex : return a list of Id, namespace filter...)

Lorenzo Scalese · Mar 11, 2020 go to post

Hello @Dmitry Maslennikov ,

I've modified a 'legacy method' in order to implement a timeout.

May be the following code could help you : 

/// Run a command line<BR/>/// Echos of command are stored in result argument <br/>
/// Return 0 if a timeout occurs.ClassMethod runCmdWithTimeout(command As %String,ByRef result As %Binary,timeout As %Integer) As %Boolean{end = $zh+timeout, timeout = 0
    a=$zu(69,40) $et $et="s a=$zu(68,40,"_a_")" 
    command:"qr" a=$zu(68,40,1)
    command i=1:1 line:1 s:line'="" result(i)=line s:$zh>end timeout=1 q:$zeof||timeout
    command
    $et
    'timeout}
Lorenzo Scalese · Mar 17, 2020 go to post

Hello @Mario.Sanchez-Macias ,


I think it's not a correct usage of %ConvertJSONToObject, the third argument must be a target object instance.

Depending on your need,  you should use "%Array of %String".  It's more flexible for SQL that "%List".

If "valueRecived" variable is a dynamic array like ["green","yellow","blue"], you can test this code :

Set valueRecived = ["green","yellow","blue"]
Set array = ##class(%ArrayOfDataTypes).%New()
Do ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(valueRecived.%ToJSON(),,.array)
Zw array
Lorenzo Scalese · Mar 22, 2020 go to post

Hello @Evgeny Shvarov ,

I tested the following code in an Iris terminal to add %DB_%DEFAULT role, It seems to work :

Write !,"Current user roles : ",$Roles
Zn "%SYS"
Set tSc = ##class(Security.Applications).Get("/csp/user",.p)
Write !,"Get application : ",$SYSTEM.Status.GetOneErrorText(tSc)
Set p("MatchRoles")=p("MatchRoles")_":%DB_%DEFAULT"
Set tSc = ##class(Security.Applications).Modify("/csp/user",.p)
Write !,"Modify application : ",$SYSTEM.Status.GetOneErrorText(tSc)
Kill p
Lorenzo Scalese · Apr 9, 2020 go to post

Hello @Timothy Leavitt
Thank you for this great article!

I tried to add "UnitTest" tag to my module.xml but something wrong during the publish process.
<UnitTest Name="tests" Package="UnitTest.Isc.JSONFiltering.Services" Phase="test"/>

tests directory contain a directory tree UnitTest/Isc/JSONFiltering/Services/ with a %UnitTest.TestCase sublcass.

Exported 'tests' to /tmp/dirLNgC2s/json-filter-1.2.0/tests/.tests
ERROR #5018: Routine 'tests' does not exist
[json-filter]   Package FAILURE - ERROR #5018: Routine 'tests' does not exist
ERROR #5018: Routine 'tests' does not exist


I also tried with objectscript-math project.  This is the output of objectscript-math publish -v :
Exported 'src/cls/UnitTests' to /tmp/dir7J1Fhz/objectscript-math-0.0.4/src/cls/unittests/.src/cls/unittests
ERROR #5018: Routine 'src/cls/UnitTests' does not exist
[objectscript-math]     Package FAILURE - ERROR #5018: Routine 'src/cls/UnitTests' does not exist
ERROR #5018: Routine 'src/cls/UnitTests' does not exist

Did I miss something or is a package manager issue ?
Thank you.

Lorenzo Scalese · Apr 28, 2020 go to post

Interesting @Robert Cemper  !

I wrote a similar code the last year in order to have storage compatible Caché\healthshare and Iris.

We have a legacy persistent class mapped on ^CacheMsg global, my solution : 

<SQLMap name="CacheMsg">
<Data name="msg">
<Delimiter>"^"</Delimiter>
<Piece>1</Piece>
</Data>
<Global>@($s($zv'["IRIS":"^CacheMsg",1:"^IRIS.Msg"))@</Global>

It works very well, but perhaps a little bit slow due to indirection usage.

I'll keep this code until a complete migration to Iris and then It will be removed.

Lorenzo Scalese · Apr 28, 2020 go to post

Thank you for your feedback @Robert Cemper 
I didn't run a benchmark, because in my case it's a deprecated class without intensive usage.

It's good to know the indirection performance is not bad. smiley

Lorenzo Scalese · Apr 29, 2020 go to post

Hello @Arto Alatalo 

If there is no overload on production server,  perhaps can you perform a D ^%BENCHLANG on production and dev machine?

It's benchmark CPU against ObjectScript language.

Compare the COSMark result.

Lorenzo Scalese · Apr 29, 2020 go to post

Hi @lw wei,

I don't know if an API exists to do this, but if nothing exists you can use the job command with an input file.
example :

JOB ^STURECOV:("%SYS"::infile:outfile):3

"infile" is the path to your input file that contains all entries for each read.
"outfile" optional, but interesting to know what happened.

Lorenzo Scalese · Nov 23, 2020 go to post

What an exciting contest!   

So happy to win in experts votes and third in community votes.

Congrats to all participants for your great apps. 

Thanks to experts and community for your support!

Also special thanks to the OEX Team and all members behind the scene.  

Lorenzo Scalese · Nov 24, 2020 go to post

Hi @Yuri Marx ,

I don't know.

If nothing exists:

Perhaps we can write a script to call CSP.Documatic.PrintClass.cls and dump the html response into file.

ex : /csp/documatic/%25CSP.Documatic.PrintClass.cls?PAGE=CLASS&LIBRARY=%25SYS&CLASSNAME=%25Library.Integer

A %Net.HttpRequest is not required.   I guess we can create a %request object,  redirect the IO and calling OnPage method.