Article Robert Cemper · Apr 16, 2021 1m read

Some changes in IRIS configuration require a restart of IRIS.
This is no big issue as long as I have access to the server command line with sufficient privileges.
In a container, this is not always given.
Stopping IRIS from the terminal/session prompt is no problem.
But the restart after is.  

Note1: container start-stop is no option as it might be removed by option --rm in docker run
Note2: the target is linux (manly in docker).  Windows is excluded

GitHub

4
0 1220
Article Robert Cemper · Apr 9, 2021 1m read

I'm looking for a way to have an IRIS db distributed over several (hw) drives.  
Without touching the internal data structures (e.g. mapping) !  
Are there any options in file systems to achieve this "splitting" or "appending" ? 

Historic background:

  • Once upon a time CPUs worked on 32 bit
  • Files could mostly not be larger than 2 GB
  • And Caché had a (forgotten) option to EXTEND a db to a next file of another 2 GB max. and a next ...

This EXTENT was excellently suited to move fresh and active data
to a faster spindle for more performance.

 

[ oh dear!

1
0 265
Article Robert Cemper · Apr 3, 2021 2m read

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

0
0 528
Article Robert Cemper · Mar 27, 2021 3m read

Testing ECP-based applications often take quite some effort for setup and preparation.
I have created a Docker-based workbench that allows you to have it quick at hands.
And if you crash it? You just give your containers a fresh start.
The whole setup runs code-based during the start-up of your instance.
In that sense, it is also a portable coding example using ZPM and the objectscript-docker-template

 see Video

3
0 762
Article Robert Cemper · Mar 5, 2021 3m read

Migration from Caché to IRIS can be quite a challenge if your code is grown over many years
and probably not so clean structured as you may like it. So you face the need to check your
migrated code against some reference data. A few samples might not be a problem,
but some hundred GB of data for testing might be.  

A possible step could be to have your fresh code in IRIS but leave your huge datastore on Caché and connect both environments over ECP.  I have created a demo project that gives you the opportunity to try this based on 2 Docker images with IRIS and with Caché connected over ECP.

1
0 976
Article Robert Cemper · Feb 16, 2021 2m read

As you know ObjectScript has neither FOREACH system command nor system function.
But it has a wide room for creativity.

The task is to loop over a global or local array and do something FOR EACH element.

There are 2 possible solutions:

  • creating a macro that generates the required code sequences
  • creating an Extended Command to perform the action. Both ways are presented here. The macro is a generic and quite flexible solution and easy to adapt if required.
1
2 1285
Article Robert Cemper · Feb 8, 2021 2m read

This is a demo to make use of a simple WebSocket Client with Embedded Python in IRIS.

How to Test it

  • Run an Iris Session in Docker
  • Select your WebSocket Echo Server
  • Enter the text you want to send or generate it
  • Send it and see the result
$ docker-compose exec iris iris session iris "##class(rccpy.WSockPy).Run()"

*** Welcome to WebSocket Embedded Python Demo ***

Collecting websocket-client

Hints

%SYS.Python.html is a preliminary class docu to see available functions

run time

0
0 977
Article Robert Cemper · Jan 19, 2021 2m read

This is a first attempt to use Embedded Python in IRIS
The Python code is adapted from solutions for Advent of Code 2020 contest.
Test data are all input to my personal challenge.

Prerequisites

Make sure you have git and Docker desktop installed.

Installation

Clone/git pull this repo into any local directory

$ git clone https://github.com/rcemper/try_embedded_python  
0
1 1259
Article Robert Cemper · Nov 21, 2020 3m read

Every now and then you may encounter a situation where for various reasons
ODBC is the only option to access a remote system. Which is sufficient as long as you need to examine or change tables.
But you can't directly execute some commands or change some Global.

Special thanks @Anna Golitsyna for inspiring me to publish this.
0
0 738
Article Robert Cemper · Sep 14, 2020 3m read

It seems to me that for some reason this didn't make its way to the official documentation
and seems to be rather unknown though implemented already in IRIS 2020.1

Thanks to @Dan Pasco I got a hint on the classes involved.
I used the recommended sequence of how to use it. 
it is all directly taken from Class Reference and I just collected it to create a first overview.

4
2 968
Article Robert Cemper · Aug 30, 2020 1m read

Caused by a conflict in the port assignment I get this  entry in mesages.log and SMP doesn't respond:

08/30/20-12:56:40:714 (15232) 1 [Utility.Event] Private webserver may not start on port 52773, may be in use by another instance
08/30/20-12:56:40:737 (15232) 0 [Utility.Event] Private webserver started on 52773

The first line is true, the second is just wishful thinking sad

demo code on GitHub

6
0 1100
Article Robert Cemper · Aug 3, 2020 3m read

In most cases, a global used by default storage has just 1 subscript level that represents the IDKEY.
For an index-globals we may see 2 or more subscript levels.
Arrays, or parent-child relationships or persistent classes extending a base data class
are examples where we see more levels. Though all these globals are quite uniform.

0
2 546
Article Robert Cemper · Jul 29, 2020 5m read

Standard error logs in IRIS / Caché / Ensemble are written global ^ERRORS.
As this piece dates back some decades back to previous millennium, its structure
is far from the typical SQL storage structures.

16
3 1254
Article Robert Cemper · Jul 27, 2020 2m read

The offer of ZPM is growing daily and the short names and
acronyms of the offer are sometimes hard to understand and
also hard to type with my lazy fingers.

So I decided to have

  • a listing with the descriptions from the repository,
  • split in short junks to avoid backscroll,
  • controlled forward / backward scrolling,
  • the option to select my packages by number,
  • to install or uninstall with limited typing.

It runs with do ^zpmshow

A snapshot from the screen:

USER>d ^zpmshow

1 analyzethis 1.1.4 -- not github --

action (i[nstall),u[ninstall],n[ext],b[back],q[quit]):i package number: 6

0
0 480
Article Robert Cemper · Jul 21, 2020 1m read

This is a sample to use %JSON.Adaptor class available in IRIS to produce a snapshot of your object.

The sample consists of 2 classes that are variations of what was known in Caché/SAMPLES as Sample.Person.
Be aware that the possibilities are limited by %JSON.Adapter and how you make use of it.

Once in place, you create some test data by Populate().
You select an object and take a snapshot.
You apply changes to your object and take another snapshot.
And see the difference.

BINGO!

GitHub

0
0 801
Article Robert Cemper · Jul 21, 2020 1m read

It's also an example of a customized SystemFunction extension (ZZISJSON) in Caché & IRIS
This time it is to be included in %ZLANGF00.mac

A JSON string is mostly imported from a file or over REST
You rely on a clean and compatible structure. This is the check.

required: ZPretty.mac

demo

USER>ZWRITE jsn  
jsn="{"Name":"Li,Robert K.","SSN":"672-92-9664","DOB":"1975-01-12","Home":{"Street":"986 Washington Blvd","City":"Boston","State":"PA","Zip":"95802"},"Office":{"Street":"6012 First Place","City":"Reston","State":"MT","Zip":"77739"},"Spouse":{"Name":"Avery,Zelda H.","SSN":"323-13-7437","DOB":"1943-03-27","Home":{"Street":"196 Main Drive","City":"Youngstown","State":"WY","Zip":"53229"},"Office":{"Street":"4056 Franklin Court","City":"Bensonhurst","State":"IA","Zip":"27688"},"FavoriteColors":["Black"],"Age":77},"Age":45,"Title":"Associate Marketing Manager","Salary":10421}" 
0
0 908
Article Robert Cemper · Jul 21, 2020 2m read

t's also an example for a customized command extension (ZZJSN) in Caché & IRIS

This is the Caché version for fast JSON formatting but it also works in IRIS.
Requires package ZPretty
To allow parallel existence in IRIS this is named ZZJSN

see:

USER>ZWRITE jsn  
jsn="{"Name":"Li,Robert K.","SSN":"672-92-9664","DOB":"1975-01-12","Home":{"Street":"986 Washington Blvd","City":"Boston","State":"PA","Zip":"95802"},"Office":{"Street":"6012 First Place","City":"Reston","State":"MT","Zip":"77739"},"Spouse":{"Name":"Avery,Zelda H.","SSN":"323-13-7437","DOB":"1943-03-27","Home":{"Street":"196 Main Drive","City":"Youngstown","State":"WY","Zip":"53229"},"Office":{"Street":"4056 Franklin Court","City":"Bensonhurst","State":"IA","Zip":"27688"},"FavoriteColors":["Black"],"Age":77},"Age":45,"Title":"Associate Marketing Manager","Salary":10421}" 
0
0 574
Article Robert Cemper · Jul 20, 2020 1m read

t's also an example for a customized command extension (ZZJSON) in IRIS

IRIS has a nice %JSON.Formatter class.
But for debugging it is not really handy.
see:

ZWRITE js1  
js1="{""Name"":""Cunningham,John C."",""SSN"":""294-11-9150"",""DOB"":""1933-01-08"",""Home"":{""Street"":""4249 Ash Street"",""City"":""Tampa"",""State"":""MD"",""Zip"":""30176""},""FavoriteColors"":\[""White"",""Red"",""Green""]}"   

so you proceed for the most simple case

set formatter=##class(%JSON.Formatter).%New()   
do formatter.Format(js1)  
{   
  "Name":"Cunningham,John C.",  
  "SSN":"294-11-9150",  
  "DOB":"1933-01-08",  
  "Home":{  
     "Street":"4249 Ash Street",  
     "City":"Tampa",  
     "State":"MD",  
     "Zip":"30176"  
  },  
  "FavoriteColors":\[  
    "White",  
    "Red",  
    "Green"  
  ]  
}  
0
0 676
Article Robert Cemper · Jul 20, 2020 2m read

It is a classic Global Mapping exercise presenting ^SPOOL as Class / Table

Background

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 till today the most simple way of output redirection.

Solution

This is also an example of a mapped Global.
USE 2 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 SQL table.

0
0 526
Article Robert Cemper · Jul 19, 2020 1m read

The guide “Extending Languages with %ZLANG Routines”
Tells you all details you need to know to extend your programming language.
EXCEPT: How to do it in a clean way.

This example of a %ZLANGC00.mac may show a possible approach
to get an easy to overview and to manage setup.
With less than 50 lines of code you might not be affected.
But if your Studio shows close to 1000 rows or more you may get in troubles.

My recommendation is simple.
Instead of adding line-by-line commands and it's code
you isolate each command and its code into a separate Include file.

0
0 362
Article Robert Cemper · Jul 4, 2020 4m read

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.

5
0 461
Article Robert Cemper · Jul 4, 2020 2m read

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.

1
1 1640