Eduard Lebedyuk · Mar 27, 2020 go to post

Easy to do that.

Here's how.

First of all let's find out where we do the iteration. If we open UtilExpGlobalView.csp we see that it's essentially a wrapper over %CSP.UI.System.GlobalViewPane.

In %CSP.UI.System.GlobalViewPane there's a LoadGlobal method which has this promising line:

Set tRS = ##class(%ResultSet).%New("%Global:Get")

Next we follow the trail to %Library.Global class implementing  Get query, which has GetFetch method, which actually iterates over the global here:

Set idx=$Order($$$ISCQUERYTEMP(Index,idx),1,Row)

So now we wrap it up back.

We need a new query (GetFetch is copied as is with one change - inverse iteration order, bolded):

 

Test.Global class

 
Class Test.Global Extends %Global
{

ClassMethod GetFetch(ByRef qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status [ Internal, PlaceAfter = GetExecute ]
{
    Set $zt="ERROR"
    Set idx=$p(qHandle,"^",2)
    Set Index=$p(qHandle,"^")
    Set idx=$Order($$$ISCQUERYTEMP(Index,idx),-1,Row)
    If idx="" {
        Set Namespace=qHandle("Namespace")
        Set SearchMask=qHandle("SearchMask")
        Set LastNode=qHandle("LastNode")
        Set NameFormat=qHandle("NameFormat")
        Set ValueFormat=qHandle("ValueFormat")
        Set OldNsp=$zu(5),%UI="CHUI",Count=100
        If Namespace'=OldNsp ZN Namespace
        Set data=$$page^%Wgdisp(SearchMask,LastNode,.Count,0,"","",1,NameFormat,ValueFormat)
        If $zu(5)'=OldNsp ZN OldNsp
        If 'Count Set AtEnd=1,Row="" Quit $$$OK
        ;
        Kill $$$ISCQUERYTEMP(Index)
        For i=1:1:Count {
            Set rec=$p(data,$$$del1,i),subs=$p(rec,$$$del2),val=$p(rec,$$$del2,2)
            Set nf=$p(rec,$$$del2,3),vf=$p(rec,$$$del2,4)
#;SML618+
#;Setup ^CacheTemp with a subroutine in case it overflows the $LB() list.
            d BuildCacheTemp
#;SML618-
        }
        Set qHandle("LastNode")=..Unquote(subs,1)
        Set qHandle=Index_"^"
        Quit ..GetFetch(.qHandle,.Row,.AtEnd)
    } Else {
#;SML618+
#;If there is extension of data then set them to Row array for %ResultSet to get them.
        if $d($$$ISCQUERYTEMP(Index,idx,1)) {
            Set Row(1)=$$$ISCQUERYTEMP(Index,idx,1)
            if $d($$$ISCQUERYTEMP(Index,idx,2)) {
                Set Row(2)=$$$ISCQUERYTEMP(Index,idx,2)
            }
        }
#;SML618-
        Set qHandle=Index_"^"_idx
    }
    Quit $$$OK
ERROR Set $zt=""
    If $g(OldNsp)'="",$zu(5)'=$g(OldNsp) ZN OldNsp
    Quit $$$ERROR($$$CacheError,$ze)
#;SML618+
#;Set the data extension to two or three pieces if it could not fit in one piece.
BuildCacheTemp s $zt="BuildErr1"
    i subs["(" {
        s sub1="("_$p(subs,"(",2,999)
    } else {
        s sub1=""
    }
    s Perm=$s(qHandle("GetPermissions")=0:"",1:$$GetGlobalPermission^%SYS.SECURITY(Namespace,$p(subs,"(",1),sub1,1))
    Set $$$ISCQUERYTEMP(Index,i)=$lb(subs,val,nf,vf,Perm)
    Q
BuildErr1 s $zt="BuildErr2"
    Set $$$ISCQUERYTEMP(Index,i)=$lb(subs,$e(val,1,$l(val)\2),nf,vf,$g(Perm))
    Set $$$ISCQUERYTEMP(Index,i,1)=$lb("",$e(val,$l(val)\2+1,$l(val)),"","","")
    Q
BuildErr2 s $zt=""
    Set $$$ISCQUERYTEMP(Index,i)=$lb(subs,$e(val,1,$l(val)\3),nf,vf,$g(Perm))
    Set $$$ISCQUERYTEMP(Index,i,1)=$lb("",$e(val,$l(val)\3+1,$l(val)\3*2),"","","")
    Set $$$ISCQUERYTEMP(Index,i,2)=$lb("",$e(val,$l(val)\3*2+1,$l(val)),"","","")
    Q
#;SML618-
}

}

Now we wrap it into a pane

 

Test.GlobalViewPane

And finally create a csp page

 

UtilExpGlobalViewR.csp

<AutoPage pagename="View Global Data" parentpage="UtilExpGlobalList.csp" stylesheet="intersystems.css" USENAMESPACE="1">

<Pane name="Title" type="%CSP.Util.SMTitlePane">
    <Text>View Global Data</Text>
</Pane>

<Pane name="Detail" type="Test.GlobalViewPane">
</Pane>

</AutoPage>

And done, add R to URL and see the global in reverse in SMP:

Eduard Lebedyuk · Mar 23, 2020 go to post

During delay activity the process is unloaded from memory, so you can't kill it.

What are you trying to do?

Eduard Lebedyuk · Mar 20, 2020 go to post

What does running this code

write ##class(GraphQL.Utils.Schema).GetSchema().%ToJSON()  

return for you?

Eduard Lebedyuk · Mar 20, 2020 go to post

2. JuliaGateway offers a way to execute Julia code. You can use that to interact with JuliaDB.

Eduard Lebedyuk · Mar 20, 2020 go to post

If you can rebalance later, the easiest way is to run the workload and see how much journals are generated.

Otherwise run workload tests in a DEV environment.

The more write-intensive the system is the more journals you need.

Eduard Lebedyuk · Mar 18, 2020 go to post

No need to init the array object:

Set valueRecived = ["green","yellow","blue"]
Do##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(valueRecived.%ToJSON(),,.array)
Zw array

 

Eduard Lebedyuk · Mar 15, 2020 go to post

Hello!

Can you elaborate on your high-level use case:

  1. What data are you storing?
  2. What do you want to calculate?

Any particular reason you  decided to use globals instead of tables/classes? Article on how globals/tables/classes interact.

In general your task can be solved in two mainstream and one additional way:

  1. Store f. Every time a data point is inserted/updated we calculate and store f(datapoint). Advantage: fast querying and savings on CPU cycles as the calculation work is only performed once. Disadvantage: changing f requires recalculation and time, storage.
  2. Calculate f. Every time data point is accessed we calculate f. Advantage: zero costs to change f, we immediately get new results. No storage required. Disadvantage: potentially CPU intensive load.

Additionally if you need to just check a condition (i.e. that f>0) you may not need an f value as by applying functional analysis, you can solve the issue analytically if f is a continuous function.

Eduard Lebedyuk · Mar 14, 2020 go to post
set in = "1.2.3"
set separator = "."
set separatorOut  = ","
set out = "tmp(" _ $lts($lfs(in, separator), separatorOut) _ ")"

If you're sure that separator length is always equal you can use $replace, and if you're sure that separator is one character long you can use $translate.

Eduard Lebedyuk · Mar 14, 2020 go to post

Open role as an object (note lowercase):

set role = "%db_cachetemp"
set roleObj = ##class(Security.Roles).%OpenId(role)

Create required resource as an object:

set resouceObj = ##class(Security.Resource).%New()
/// set resource

Insert resource into the role and save the role

do roleObj.Resources.Insert(resourceObj)
set sc = roleObj.%Save()

And role has a new resource.

Eduard Lebedyuk · Mar 13, 2020 go to post

Current implementation resolves GraphQL query into SQL, so classes/tables are required.

This is our advantage as we don't need to write resolvers manually.

That said, if you want to provide custom schema - you can, as our GraphQL implementation includes GraphQL parser so you can use parsed AST to write your own resolver.

Eduard Lebedyuk · Mar 12, 2020 go to post

I'm not really sure what do you mean by

if there was a class parameter I had missed that just indicated the extent was temporary  

what do you want to achieve with this?

Eduard Lebedyuk · Mar 12, 2020 go to post

All images are not loaded when privacy protection is enabled in Firefox (which is enabled by default).

Copy them on community maybe?

Eduard Lebedyuk · Mar 9, 2020 go to post

Invoke is the way to go.

ClassMethod CreateWebApp(pVars, pLogLevel, tInstaller) As %Status
{
    Set Namespace=tInstaller.Evaluate("${Namespace}")
    Do tInstaller.PushNS("%SYS")
    Do ##class(Security.System).GetInstallationSecuritySetting(.security)
    If (security="None") {
        Set cspProperties("AutheEnabled") = $$$AutheUnauthenticated
    } Else {
        Set cspProperties("AutheEnabled") = $$$AutheCache // Password
    }
    Set cspProperties("NameSpace") = Namespace
    Set cspProperties("IsNameSpaceDefault") = $$$YES
    Set cspProperties("DispatchClass") = "MDX2JSON.REST"
        Set cspProperties("UseCookies") = $$$YES
    Set tSC = ##class(Security.Applications).Create("/"_Namespace, .cspProperties)
    Do tInstaller.PopNS()
    If $$$ISERR(tSC) Throw ##class(%Installer.Exception).CreateFromStatus(tSC)
    Quit $$$OK
}

And invoke with

<RunInstall Class="MDX2JSON.Installer" Method="CreateWebApp"/>
Eduard Lebedyuk · Mar 6, 2020 go to post

Thank you, Marc!

With Kitty there's even a Put Window on Foreground option:

I've tested with

h 10 w $c(7) 

and it works!

Is there anything similar for cterm/iristerm?

Eduard Lebedyuk · Mar 6, 2020 go to post

IRISList is a wrapper over InterSystems IRIS $lb structure, and it supports these value types: Int16, Int32, Int64, bool, Single, Double, string, byte[], IRISList.

To be more specific the following datatypes are available.

  • ISO/IEC 8859{1 string. The remainder of the $LIST element is a string of ISO/IEC 8859-1 characters.
  • UNICODE string. The remainder of the $LIST element is a string of UNICODE characters in UTF-16 little endian format.
  • Positive integer. The remainder of the $LIST element is an unsigned integer in little endian order with high order zero octet truncated.
  • Negative integer. The remainder of the $LIST element is a negative integer in twos complement little endian order with high order #FF octet truncated.
  • Positive radix 10 number. The next octet is a signed char that serves as an exponent. That is followed by an unsigned integer in little endian order with high order zero octet truncated. The value of the number is integer × 10exponent.
  • Negative radix 10 number. The next octet is a signed char that serves as an exponent. That is followed by a negative integer in twos complement little endian order with high order #FF octet truncated. The value of the number is integer × 10exponent.
  • IEEE floating point number. Length must allow for either 4 or 8 (preferred) octet of data.

In C# Decimal can be constructed from {Int32, Int32, Int32, Boolean, Byte} and you can use GetBits method to retrieve these parts from Decimal   (docs).

Eduard Lebedyuk · Mar 6, 2020 go to post

Depends on the project I guess.

Trivial fixes can be sent via pulls directly.

Bigger fixes usually require time to fix so some discussion can help.

That said, opening empty pull and talking there also works.

Eduard Lebedyuk · Mar 5, 2020 go to post

In most cases just process special variable should be enough:

Set SourceConfigName = process.%PrimaryRequestHeader.SourceConfigName