Management Portal: how to view globals in opposite order?
A simple question: View Global Data page shows globals always in ascending subscript order. Very often I need to see latest page, is there any trick for this?
Update: I mean to see last subscripts in Management Portal, not using the code
Comments
just use a single liner from terminal for the last 10 lines or any number you need
Updated my question. I mean to view them in Portal.
I don't know of reverse order
BUT if you have some idea of the last subscript you may enter the starting subscript.
instead of seeing the whole Global ^CONFIG
.png)
just one specific subscript ^CONFIG("Telnet"
.png)
os starting from a specific subscript ^CONFIG("Telnet":
.png)
or from:to subscript ^CONFIG("ECP":"Journal"
.png)
or just the select subscript level with a closing bracket ^CONFIG("ECP":"Journal").png)
Basically it is the same behavior of the ancient (not to say antique) routine ^%G
When it was written traversing a Global in reverse order was not implemented in Caché nor ist'S predecessors.
So no reverse display
It has a help function that tells you it's capabilities DO HELP^%G
displays the global directory. If you enter just the name of a global,
%G displays the entire global. You may also display a portion of the
global at different subscript levels or specific nodes.
A complete global reference, such as ^GLO(3,"BED",5) will display
only that particular node. You may specify a subtree, such as
^GLO(3,"BED", to display all descendants of that node. To display
both the node and its descendants, do not end your entry with a
comma or a right parenthesis.
You can leave a subscript field empty when you specify the subtree and
the %G utility displays any nodes matching the other subscripts:
^GLO(,"BED") will match any nodes with 'BED' as the second subscript.
You can specify a range of subscripts for a particular subscript
level by inserting a colon between the first and last subscript in the
range: ^PT(1,"ACC":"BIRTH"
You can use variables and simple expressions in a subscript
specification by assigning a value to the variable before calling %G.
For example SET ID=214 and enter something like ^PT(ID,0).
Thanks, I'm aware of Search Mask functionality.
>... if you have some idea of the last subscript ...
That's the point: very often when viewing a global on production server via Portal, you just want to see a few latest records, not starting to search for last subscripts.
You don't have a great chance, but you may dig it down like this
And I assume once seen you get your display faster than this cycles where I had no idea on the subscript structure before
.png)
.png)
.png)
.png)
I've huge globals, so this way doesn't work for me.
>to estimate the age of ^%G take a look to copyright
oh ye :)
to estimate the age of ^%G take a look to copyright
.png)
.png)
Thanks for the details! And history ![]()
Implement this behavior and add it as an ad-hoc portal page? Like @Henrique Dias does with his IRIS History Monitor and Interoperability Message Viewer?
What's ad-hoc portal page? Google has no idea
I mean you develop this view by yourself and install every time (e.g. with ZPM). I believe @Eduard Lebedyuk did something like that for Interoperability.
>you develop this view by yourself
yes, that's clear. But what is "ad-hoc portal page"? A way to extent Management Portal with custom pages?
I never did it by myself, but I believe it's just a CSP web-page, right? @Sergei Mihaylenko also did something like that in his iris-app-tools
Yes, this is implemented in my decision, since I also really need to watch the end of the aray.png)
Can you say what min Cache version is supported? My Cache 217.2 fails to parse the xml.
Tested on Ensemle 2016.1 and higher.
And in the file https://github.com/SergeyMi37/cache-iris-app-tools/blob/master/src/xml/apptools.xml
you need to replace
<Export generator = "IRIS" version = "26" with
<Export generator = "Cache" version = "26"
Thanks for the error found.
Yes, now I can import it. But controls Direct View and the filter do not exist. And as just a side note, everything related to Ensable fails to compile on my Cache.
it is an IRIS export
<?xml version="1.0" encoding="UTF-8"?>
<Export generator="IRIS" version="26" zv="IRIS for Windows (x86-64) 2019.1.1 (Build 609U)" ts="2020-03-22 18:56:51">
while for Cache it ooks like this:
<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="25">
it might be sufficient to change 26 to 25 to make your Caché happy
Would be nice to have a way to extend Portal with custom pages. This way colleagues need not to learn and store links to the pages.
The official way is to log an ENHANCEMENT REQUEST at WRC portal.
And wait.
You can store user pages in your favorites, with this command
Set tSC=##class(%SYS.Portal.Users).%AddFavorite("AppTools","/ apptools/App.LogInfo.cls")
Great! Thanks!
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
<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:

Wow! A really nice hack! :) Well done!
And keep the cooking description for your future updates
Make an OEX module from this? Great thing.
I don't think this snippet is suitable to be a standalone app tbqh.