Evgeny Shvarov · Aug 2, 2020 1m read
Application Errors Analytics

Hi Developers!

As you know the application errors live in ^ERRORS global. They appear there if you call:

d e.Log() 

in a Catch section of Try-Catch.

With @Robert Cemper's approach, you can now use SQL to examine it.

Inspired by Robert's module I introduced a simple IRIS Analytics module which shows these errors in a dashboard:

3 5
1 252
Robert Cemper · Jul 21, 2020 2m read
Un-Typical persistence
This is a coding example working on Caché 2018.1.3 and IRIS 2020.2 
It will not be kept in sync with new versions 
It is also NOT serviced by InterSystems Support !

During my search for a snapshot of a persistent object,
I met a feature that I would like tho share as it could be useful in some special situations.
My trigger was to have a before- and an after-image during unit testing.

13 4
4 449
Robert Cemper · Jul 20, 2020 1m read

This is a follow-up to my previous article WebSocket Client JS with IRIS Native API as Docker Micro Server

Installation is now much simpler as all pieces are now assembled in a single Docker image.
That makes life easier. But of course, the principle of the Micro Service is not so obvious anymore.
An All-in-1 bundled package. Therefore compact.

8 0
0 489
Robert Cemper · Jul 20, 2020 2m read
SPOOL as SQL Table

Device #2 named SPOOL dates back to the predecessors of Caché and IRIS
It was the first "%Stream" like option to buffer output before printing.
It is also the first and still today the most simple way of output redirection.


This is also an example of a mapped Global. USE 2 write "actual date: ",$ZDT($h,3),!
redirects the output into the Global ^SPOOL

You can read the global manually or with some ancient utilities
or use this mapping to access it as class or a table with SQL.

11 0
0 278

Wrap JSON to multi lines / Test ISJSON


install and usage

Packed Pretty.xml installs routine ZPretty in any namespace.
calling $$Do^ZPretty(input,[filler],[newline]) returns a wrapped JSON string.
filler is the optional string for the indent, default = " "
newline is optional, default = $C(13,10)
input accepts: JSON_String, JSON_Stream, %DynamicAbstractObject

6 0
0 255
Timothy Leavitt · Jul 8, 2020 7m read
Tips for debugging with %Status


If you're solving complex problems in ObjectScript, you probably have a lot of code that works with %Status values. If you have interacted with persistent classes from an object perspective (%Save, %OpenId, etc.), you have almost certainly seen them. A %Status provides a wrapper around a localizable error message in InterSystems' platforms. An OK status ($$$OK) is just equal to 1, whereas a bad status ($$$ERROR(errorcode,arguments...)) is represented as a 0 followed by a space followed by a $ListBuild list with structured information about the error. $System.Status (see class reference) provides several handy APIs for working with %Status values; the class reference is helpful and I won't bother duplicating it here. There have been a few other useful articles/questions on the topic as well (see links at the end). My focus in this article will be on a few debugging tricks techniques rather than coding best practices (again, if you're looking for those, see links at the end).

14 7
10 1,249
Robert Cemper · Jul 4, 2020 4m read
Editor Archaeology

During the development of the Terminal Multi-Line Command Editor I discovered in my IRIS installation
a piece of software that I just can classify as a historic artifact. And it is still fully operational !!!

As it dates back to times before InterSystems was founded in 1978 you may understand my surprise.
I personally stepped into that environment in 1978 and used it then for daily work.

16 5
0 242
Robert Cemper · Jul 4, 2020 2m read
Terminal Multi-Line Command Editor

The Command extension enables the execution of Multi-Line Commands from Terminal prompt.

Terminal Multi-Line Input with Edit, Insert, Delete, Print extension for IRIS and Caché
IRIS and Caché have just single command lines in terminal available
This Multi-Line Commands Editor also will execute the Multi-line Commands.
In addition, it is independent of access to %SYS and can be installed in any namespace

Special thanks to @Jeffrey Drumm who inspired me to this and supported me as beta-tester.

8 1
0 892

Hi Developers!

Suppose you have a persistent class with data and you want to have a simple Angular UI for it to view the data and make CRUD operations.

Recently @Alberto Fuentes described how to build Angular UI for your InterSystems IRIS application using RESTForms2.

In this article, I want to tell you how you can get a simple Angular UI to CRUD and view your InterSystems IRIS class data automatically in less than 5 minutes.

Let's go!

5 2
2 617

Hi Devs!

Last weekend I had been testing the newborn csvgen module and was looking for a CSV file to test - thus I came across an interesting datafile on Data.World with Game of Throne episodes statistics. Death statistics. These folks documented all the murders through all the 8 seasons and noted where, who, from what clan with what weapon had killed another one.

So I imported it and made an IRIS Analytics dashboard.

You Know Nothing, Jon Snow | You Know Nothing, Jon Snow | Know ...

Don't worry, Jon, with this dashboard we can figure out something ). See the details below.

6 0
2 442

Hi Developers!

Sometimes we need to import CSV data programmatically to InterSystems IRIS either from CSV or from URL. And we expect the class with proper datatypes to be created and the data to be imported.

I published a module csvgen on Open Exchange which does exactly that.

If you just need the CSV file be imported into IRIS you can do the following:

USER>do ##class(community.csvgen).Generate("/usr/data/titanic.csv",,"Data.Titanic")

Class name: Data.Titanic
Header: PassengerId INTEGER,Survived INTEGER,Pclass INTEGER,Name VARCHAR(250),Sex VARCHAR(250),Age INTEGER,SibSp INTEGER,Parch INTEGER,Ticket VARCHAR(250),Fare MONEY,Cabin VARCHAR(250),Embarked VARCHAR(250)
Records imported: 891

Or if you have the CSV on the internet, e.g. COVID-19 Data on Github you can get the data in the following way:

USER>d ##class(community.csvgen).GenerateFromURL("",",","Data.Covid19")

Class name: Data.Covid19
Header: FIPS INTEGER,Admin2 VARCHAR(250),Province_State VARCHAR(250),Country_Region VARCHAR(250),Last_Update DATE,Lat MONEY,Long_ DOUBLE,Confirmed INTEGER,Deaths INTEGER,Recovered INTEGER,Active INTEGER,Combined_Key VARCHAR(250),Incidence_Rate DOUBLE,Case-Fatality_Ratio DOUBLE
Records imported: 3522

7 16
1 900

Hi ObjectScript developers!

How to Protect Your Belongings from Pests While Moving - Delicate ...

InterSystems ObjectScript is perhaps the best language on the planet to deal with globals - and it is an interpretable language.

Yes, it has a compiler. But even the compiler can compile some lines in ObjectScript which will then fire as bugs during the runtime.

There are some technics on how to avoid that such as unit testing, coding guidelines and your coding experience, of course ;)

Here I want to present to you the yet another approach to how you can reduce the number of errors in your ObjectScript runtime and enforce coding guidelines - it's an ObjectScript Quality tool developed by Lite Solutions, InterSystems solution partner.

See the details below.

4 0
0 348

Hi folks,
It's time now for a Micro Service Demo with a total fresh IRIS Image and an image that you both PULL with
docker and run with only 4 lines of docker commands.
June 1st, 2020 - rcc

There is now a compact All-in-1 version available that combines all parts in a single container image.
For details see: IRIS-NativeAPI-Nodejs-compact
May 24, 2020 - rcc

I have added a simplified installation using Docker, see context
May 25, 2020 - rcc

There are enhanced scripts suitable & tested for Linux & Windows available here
May 26, 2020 - rcc

This demo is a redesign of the WebSocket Client based on Node.js existing already for Caché. The major changes:

  • use of the new IRIS Native API for Node.js especially Working with Global Arrays
  • change from a directly triggered client to a server design
  • put the result into a separate docker image as an example for a MicroService / MicroServer
  • add a simple interface in IRIS to control the MicroService execution.

12 12
1 948
Evgeny Shvarov · May 7, 2020 4m read
Unit Testing with ZPM

Hi Developers!

I want to share with you the approach you can use working with Unit Testing which I personally find very convenient and robust.

Will not talk much here about Unit Testing, we have documentation, enough good articles on the topic not only on the Internet but here on Developers Community too, e.g. this one.

How can you manage the Unit Testing of your ZPM module?

This is pretty handy with ZPM. It has a special command "test" which runs all the tests you mentioned in the module. You can execute it as shown below:

zpm:USER>module-name test

And this command runs all the tests you mentioned in module.xml.

Let's see how it works.

5 1
3 379

As you know in Caché / IRIS you have the possibility to define a property as Multidimensional as documented here:
and the explanation of how to use it

Though the access is quite comfortable (in traditional COS sense) there are 2 main restrictions that hurt:

#1) It is not saved to disk unless your application includes code to save it specifically.
#2) It cannot be stored in or exposed through SQL tables
there are some more
I'll show how to overcome these limits

14 0
2 365
Robert Cemper · Apr 26, 2020 5m read
Materialized Views

A VIEW in SQL is basically a prepared SQL statement.
It has to be executed and assembled like any other SQL query.
MATERIALIZED VIEW means that the content is collected before hands and can be retrieved rather fast.
I saw the concept first with my favorite competitor named O* and they made a lot of noise about it.

{ favorite: because I could win every benchmark against them devil }

12 3
1 546
Robert Cemper · 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 381