I just wrote up a quick sample to help a colleague load data into IRIS from R using RJDBC, and figured it's worth sharing here for future reference.

Ultimately it was pretty simple, aside from IRIS not liking "." in column names; the workaround is to just rename the columns. Someone better at R than me could probably provide some generic approach. smiley

4 2
0 162

When you have more than ten thousand users in your database, it becomes time-consuming and inconvenient to assign group access rights through the standard IRIS interface. In this artilce I want to introduce you an application to automate this process.

I’ll show you how to assign and change the role lists for the users, selecting them by context, and I will also show you how to expand this application’s functionality. you know how to apply your work as an administrator and developer to the new features of the well-proven apptools software complex. With the addition of an adminLTE template, you can now quickly and easily create interface interactions for any entity and many functional modules.
The goal while developing this toolkit is to write as little JavaScript as possible as well as transfer and implement all the dynamics as much as possible in the ObjectScript.

4 0
0 321
Article
· Mar 17, 2021 3m read
Making the most of $Query

I ran into an interesting ObjectScript use case today with a general solution that I wanted to share.

Use case:

I have a JSON array (specifically, in my case, an array of issues from Jira) that I want to aggregate over a few fields - say, category, priority, and issue type. I then want to flatten the aggregates into a simple list with the total for each of the groups. Of course, for the aggregation, it makes sense to use a local array in the form:

agg(category, priority, type) = total

Such that for each record in the input array I can just:

14 10
4 773

Recently I wanted to get a list of all cached queries and their texts. Here's how to do that.

First create an SQL Procedure returning Cache Query text from a Cached Query routine name:

Class test.CQ
{

/// SELECT test.CQ_GetText()
ClassMethod GetText(routine As %String) As %String [ CodeMode = expression, SqlProc ]
{
##class(%SQLCatalog).GetCachedQueryInfo(routine)
}

}

And after that you can execute this query:

4 3
0 482

Good day, developers!

The "apptools-admin" project is not only a set of tools for the administrator, but a platform for the rapid creation of a prototype of any solution.
For example, Photo Album, Music Player, and Personal Library all come together in a user-friendly treasure chest design.

Load http:// your-host:your-port/apptoolsrest/a/infochest

Change the path to your treasure files and start viewing, listening or reading from any convenient device: desktop, tablet or smartphone.

2 0
0 218
Article
· May 1, 2020 1m read
Code sample to concatenate JSON arrays

ObjectScript doesn't include any built-in method for appending one JSON dynamic array to another. Here's a code snippet I use that's equivalent to the JavaScript concat() method.

Call it with any number of arguments to concatenate them into a new array. If an argument is a dynamic array, its elements will be added. Otherwise the argument itself will be added.

5 2
2 542
Article
· Apr 25, 2020 2m read
Semi-Persistent Classes and Tables

If you define a Persistent Class / Table the class compiler generates for you an appropriate Storage definition.
A different option is to define a SQL mapping for an already existing Global storage. This has been excellently
explained already in a different series of articles. The Art of Mapping Globals to Classes 1 of 3

10 7
1 425
Article
· Dec 12, 2019 2m read
Creating Portlets in DeepSee

What is a portlet?

The simple answer is: a custom widget. A portlet can exist by itself on a DeepSee dashboard, it can be used along side standard DeepSee widgets, or along side other portlets. The rendering of the custom widget is completely user defined. This means you can embed a web page, create a form to perform any sort of action needed based on the data on your dashboard, use third party charting libraries, or simply display data from outside of a DeepSee cube.

How to get started

6 1
0 392

A few years ago, I was teaching the basics of our %UnitTest framework during Caché Foundations class (now called Developing Using InterSystems Objects and SQL). A student asked if it was possible to collect performance statistics while running unit tests. A few weeks later, I added some additional code to the %UnitTest examples to answer this question. I’m finally sharing it on the Community.

5 2
2 509
Article
· Aug 1, 2019 3m read
Nested set model for ObjectScript

In many projects I was faced with storing hierarchical data (tree) in classes.
By tree, I mean such data, where each node has a parent node — an object of the same class.
Many examples of such data can be given. For example, a catalog in the online store. Suppose that this online store sells books, in this case, the category tree might look like this:

6 1
1 762
Article
· Jul 26, 2019 3m read
Dynamic SQL to Dynamic Object

Hello community! I have to work with queries using all kinds of methods like embedded sql and class queries. But my favorite is dynamic sql, simply because of how easy it is to manipulate them at runtime. The downside to writing a lot of these is the maintenance of the code and interacting with the output in a meaningful way.

7 7
1 753

Hi guys!

Portrait of Madame X, Gustave Caillebotte.

One of the features I like in InterSystems ObjectScript is how you can process array transformations in a specific method or a function.

Usually when we say "process an array" we assume a very straightforward algorithm which loops through an array and does something with its entries upon a certain rule.

The trick is how you transfer an array to work with into a function.

One of the nice approaches on how to pass the information about an array is using $Name and Indirection operator.

Below you can find a very simple example which illustrates the thing.

3 2
1 504

Hello

I made for fun a bash script that creates csv files from a %GOGEN exported file.
%GOGEN, the utility for exporting globals for Cache 5.xx

First I thought it would be very simply with bash, but ...
- if I want a header in the csv file
- if you export with GOGEN more globals together not only one
- if I want a csv file for every global/indexes has the global ..

The simply bash script goes up 100 lines of code. If I will start again with this, I would use Python or Go, not bash.

Example:

For a EXPORTED.GLO file

0 5
0 562
Article
· Mar 28, 2019 2m read
ObjectScript error handling snippets

ObjectScript has at least three ways of handling errors (status codes, exceptions, SQLCODE, etc.). Most of the system code uses statuses but exceptions are easier to handle for a number of reasons. Working with legacy code you spend some time translating between the different techniques. I use these snippets a lot for reference. Hopefully they're useful to others as well.

21 5
18 2,462

Recently I needed a classmethod that returns annotation value based on a name of a activity.

As doing it at runtime seemed inefficient, I wrote compile-time utility that iterates over all business process activities and generates relevant code.

This code could be used in a variety of situations when you need to iterate over business process activities, just add it as a secondary superclass to your BPL processes.

1 2
1 311

This code snippet sends an XML request to a server and saves the response to a file. The class method "test" runs the code:


Class objectscript.postXML
{
    classmethod test() {
        Set HTTPRequest = ##class(%Net.HttpRequest).%New()
        Set HTTPRequest.ContentType = "text/xml"
        Set HTTPRequest.NoDefaultContentCharset = 1
        Set HTTPRequest.Location = "ITOMCZ"
        Set HTTPRequest.Server = "wph.foactive.com"
        Do HTTPRequest.RemoveHeader("User-Agent")  
        Do HTTPRequest.RemoveHeader("Accept-Encoding") 
        Do HTTPRequest.RemoveHeader("Connection")
        Do HTTPRequest.SetHeader("Expect","100-continue")
     
        Set RequestXML = ##class(%Library.File).%New("c:\test.xml")
        Do RequestXML.Open("RS")
        Do HTTPRequest.EntityBody.CopyFrom(RequestXML)
        Do RequestXML.%Close()
     
        Do HTTPRequest.Post(HTTPRequest.Location)
     
        Do $System.OBJ.Dump(HTTPRequest)
        Do $System.OBJ.Dump(HTTPRequest.HttpResponse)
     
        Write HTTPRequest.HttpResponse.Data.Size
        Write HTTPRequest.ContentLength
     
        Set ResponseStream = ##class(%Stream.FileBinary).%New()
        // Second part is typically the file extension, i.e.: application/pdf -> pdf
        Set FileType = $Piece(HTTPRequest.HttpResponse.GetHeader("CONTENT-TYPE"),"/",2)
        Set ResponseStream.Filename = "C:\test."_FileType
     
        Write ResponseStream.CopyFrom(HTTPRequest.HttpResponse.Data)
     
        Write ResponseStream.%Save()
        Do ResponseStream.%Close()
    }
}

Here's a link to the code on GitHub

0 0
0 701
Article
· Dec 27, 2018 2m read
Use %XML.Node to walk a DOM

The following code walks a DOM using %XML.Node. It also prevents %XML.Writer to change whitespace. Run the code using the class method "test":


Class objectscript.walkDOM Extends %Persistent
{
    ClassMethod dfs(node As %XML.Node)
    {
        s entrynode=node.NodeId
        do {
        //element nodes with one whitespacetyped child are the ones we want to change
        if (node.NodeType=$$$xmlELEMENTNODE){
            s snode=node.NodeId     
            if (node.MoveToFirstChild())            
                {
                    i ('node.MoveToNextSibling()){
                        i (node.NodeType=$$$xmlWHITESPACENODE){
                            s node.NodeType=$$$xmlTEXTNODE
                            s node.NodeId=snode
                        }
                    }
            }
            s node.NodeId=snode     
        }   
        if (node.HasChildNodes()){
            d node.MoveToFirstChild()
            d ..dfs(node)
        }
        } while (node.NodeType'="" && node.MoveToNextSibling())
        s node.NodeId=entrynode
         
    }
     
    ClassMethod test()
    {
      set xml = "abcdefg"
     
      s reader=##class(%XML.Reader).%New()
      do reader.OpenString(xml)  
      set writer = ##class(%XML.Writer).%New()
      //do some magic
      d ..dfs(reader.Document)
       
      w !,"with indent=1:",!
      set writer.Indent = 1
      do writer.OutputToString()
      do writer.Document(reader.Document)
      w writer.GetXMLString()
      set writer.Indent = 0
      w !,"with indent=0:",!
      do writer.OutputToString()
      do writer.Document(reader.Document)
      w writer.GetXMLString()
    }
}

Here's a link to the code on GitHub: https://github.com/intersystems-community/code-snippets/blob/master/src/...

0 0
0 277

(Originally posted by @Ben Spead on June 25, 2014)

This code snippet generates a list of Ensemble Lookup Tables and Schema documents in the user's current namespace. Run the code by running the class method "test":


Class benspead.EnsTablesSchema
{
    classmethod test() {
        If ##class(%Dictionary.CompiledClass).%ExistsId("Ens.Util.LookupTableDocument") {
            // only supported in Ensemble 2012.1+
            Write !,!,"Exporting Ensemble Lookup Tables..."
            Set sc = $$$OK
            Set rs = ##class(%ResultSet).%New("Ens.Util.LookupTableDocument:List")
            Do rs.Execute()
            While rs.Next() {
                Set item=rs.Data("name")
                Write "document found: "_ item,!
            }
            Do rs.Close()
            Set rs=""
        }
        If ##class(%Dictionary.CompiledClass).%ExistsId("EnsLib.HL7.SchemaDocument") {
            Write !,!,"Exporting Ensemble HL7 Schemas..."
            Set sc = $$$OK
            Set rs = ##class(%ResultSet).%New("EnsLib.HL7.SchemaDocument:List")
            Do rs.Execute()
            While rs.Next() {
                Set item=rs.Data("name")
                Continue:$listfind($lb("2.1.HL7","2.2.HL7","2.3.HL7","2.4.HL7","2.5.HL7","2.6.HL7","2.7.HL7","2.3.1.HL7","2.5.1.HL7","2.7.1.HL7","ITK.HL7")
                                    ,item)
                Write "document found: "_ item,!
            }
            Do rs.Close()
            Set rs=""
        }
    }
}

Here's a link to the code on GitHub: https://github.com/intersystems-community/code-snippets/blob/master/src/...

0 3
0 668