Eduard Lebedyuk · Aug 18, 2019 go to post

Enjoy.

#define ForAll(%in,%gn) s gn%in=$na(%gn) s %in="" f { s %in=$o(@gn%in@(%in)) q:%in=""
#define EndFor  }

set glvn = "^MyGlobal"
$$$ForAll(value, @glvn)
    write value,!
$$$EndFor
Eduard Lebedyuk · Aug 18, 2019 go to post

Metrics can store history, i.e.:

Property MetricProperty As Ens.DataType.Metric (AUTOHISTORY=50) [MultiDimensional];

Docs.

Eduard Lebedyuk · Aug 12, 2019 go to post

Extend %Fileman class:

Class MyFilemanDate Extends %FilemanDate {

Parameter STRICTDATA = 1;

}

And call it:

##class(MyFilemanDate).LogicalToDate()
Eduard Lebedyuk · Aug 12, 2019 go to post

Two ways I know how to add your page:

1. To DeepSee User Portal (from Analyze This):

Set tItem=##class(%DeepSee.UserLibrary.Link).%New()
Set tItem.fullName="Analyze This"
Set tPage="AnalyzeThis.UI.CSVImport.zen"
Set tItem.href=$system.CSP.GetPortalApp($namespace,tPage) _ tPage
Set tItem.title="Analyze This"
Set tSC=tItem.%Save()

2. To Favorites:

set sc = ##class(%SYS.Portal.Users).%AddFavorite("Name", "URL")

Eduard Lebedyuk · Aug 12, 2019 go to post

Datatype parameters can be set as properties parameters.

In your case you have a property somewhere:

Property myDate %FilemanDate;

You need to modify it like this:

Property myDate %FilemanDate(STRICTDATA=1);

And recompile the class.

Eduard Lebedyuk · Aug 9, 2019 go to post

Documentation states there's an argument SubDir As %Boolean = 0 in ExportAllClassesIndividual  method.

Description: If SubDir is true then it will export sub-packages as subdirectories.

Try setting it to 1.

Eduard Lebedyuk · Aug 8, 2019 go to post

Classes extending %Persistent with default Storage have GetStored method for persistent properties.

SYS.Database in your case has custom storage, that's why this method does not exist.

Eduard Lebedyuk · Aug 7, 2019 go to post

Here's a way without indirection:

Class MyPackage.MyClass
{

ClassMethod MyMethod(p1 = 1, p2 = 2, p3 = 3)
{
    Write p1,"-",p2,"-",p3,!
}

/// do ##class(MyPackage.MyClass).Test()
ClassMethod Test()
{
    Do ..FromJson({})
    Do ..FromJson({"p1":"first value", "p2":"second value"})
    Do ..FromJson({"p1":"first value", "p3":"third value"})
    Do ..FromJson({"p2":"second value"})
}

/// do ##class(MyPackage.MyClass).ArgPosMapping("MyPackage.MyClass", "MyMethod")
ClassMethod ArgPosMapping(class, method, Output map)
{
    kill map
    set formalspec = $$$comMemberKeyGet(class,$$$cCLASSmethod,method,$$$cMETHformalspecparsed)
    for i=1:1:$ll(formalspec) {
        set arg = $lg(formalspec, i)
        set map($lg(arg, 1)) =  i
    }
    
    set map = $ll(formalspec)
}

ClassMethod FromJson(json)
{
    Do ..ArgPosMapping($classname(), "MyMethod", .map)
    Set iterator = json.%GetIterator()
    Set position = 0
    While iterator.%GetNext(.key, .value) {
        Set position = position + 1
        Set arguments(map(key)) = value
    }
    
    Set arguments = map

    Do ..MyMethod(arguments...)
}

}
Eduard Lebedyuk · Aug 6, 2019 go to post

Is it service or operation? Please elaborate on your configuration.

Because you have XML error, I think there are some additional transformation(s) taking place.

Have you tried checking Stream at line 3 offset 120?

Eduard Lebedyuk · Aug 5, 2019 go to post

You need both Package mapping and global mappings.

In package mapping you add package containing your table from routine database for original namespace.

In global mapping you add data, index, stream and id globals from global database for original namespace.

Eduard Lebedyuk · Jul 31, 2019 go to post

Doesn't CORS exist to prevent exactly that?

Check that origin/referer headers in your OnHandleCorsRequest are what you expect them to be and all would be good.

Eduard Lebedyuk · Jul 30, 2019 go to post

E=D should work.

You don't need to throw an exception, just return error %Status from handler method.

Eduard Lebedyuk · Jul 29, 2019 go to post

The problem with JSON_OBJECT is that you need to write each field twice for each query.

It's good for one-off things, but for generalized solution authors approach looks better.

Eduard Lebedyuk · Jul 29, 2019 go to post

I use Pycharm  for complicated projects and debugging and bash for quick scripting.

Also check PythonGateway - it comes with integrated Python interpreter right in your IRIS terminal.

Eduard Lebedyuk · Jul 29, 2019 go to post

If you don't need statistics, this should help

kill ^rINDEXSQL("sqlidx")

or with macros

kill $$$SQLIndexRoot

Untested but should help.

Maybe backup the global just in case.

Eduard Lebedyuk · Jul 27, 2019 go to post

Tip.

Metadata does not change from one row to the other and accessing it takes time, so removing it from the row loop would improve the execution speed:

Class User.Test
{

Query TestQuery() As %SQLQuery
{
SELECT * FROM Sample.Person
}

/// do ##class(User.Test).Test()
ClassMethod Test()
{
    for method = "EveryRow", "Once" {
        set rSet = ..TestQueryFunc()
        
        set start = $zh
        do $classmethod(, method, rSet)
        set end = $zh
        
        write $$$FormatText("Method %1 took %2 sec.", method, end - start), !
    }
}

ClassMethod EveryRow(rSet As %SQL.ISelectResult)
{
    
    set tResults = []
    while rSet.%Next() {
        set tRow = {}
        set tMetadata = rSet.%GetMetadata()
        set tColumnCount = tMetadata.columns.Count()
        for x=1:1:tColumnCount {
            set tColumn = tMetadata.columns.GetAt(x)
            set tColumnName = tColumn.colName
            //do tRow.%Set(tColumnName, rSet.%GetData(x) )
            set $PROPERTY(tRow,tColumnName) = $PROPERTY(rSet,tColumnName)
        }
        do tResults.%Push(tRow)
    }
}

ClassMethod Once(rSet As %SQL.ISelectResult)
{
    set tResults = []
    set tColumns = ""
    
    set tMetadata = rSet.%GetMetadata()
    set tColumnCount = tMetadata.columns.Count()
    for x=1:1:tColumnCount {
        set tColumn = tMetadata.columns.GetAt(x)
        set tColumnName = tColumn.colName
        set tColumns = tColumns _ $lb(tColumnName)
    }

    while rSet.%Next() {
        set tRow = {}
        for x=1:1:tColumnCount {
            do tRow.%Set($lg(tColumns, x), rSet.%GetData(x) )
        }
        do tResults.%Push(tRow)
    }
}

}

Results for me:

>do ##class(User.Test).Test()
Method EveryRow took .017803 sec.
Method Once took .01076 sec.
Eduard Lebedyuk · Jul 25, 2019 go to post

By default Ensemble service is run under System account, which does not have user environment variables.

You can either specify system variables or run Ensemble service from a user account.

Eduard Lebedyuk · Jul 21, 2019 go to post

This really helps when you have several running containers simultaneously and don't know what port of Management Portal relates to a certain terminal.

Wouldn't help, as terminals would report internal container port, which is always 52773.