Find

Please note that this post is obsolete.
Announcement
· Mar 20, 2023

Sneak Peek (at least for this week)

 Hi Community:

As you may know, I am the person who does the program and scheduling for our Global Summit sessions, so I can give you a sneak peek at our agenda before it is published.

I'm happy to report that we will have two special, four-hour workshops on Sunday, June 4, which is the day you arrive to register in Hollywood, Florida.

One is the return of the standing-room only 2022 workshop with our FHIR guru, Russ Leftwich - "Getting to Know FHIR: The Best Explanation of FHIR They've Ever Heard." Needless to say, we've reserved a bigger room.

Plus, we are planning eight related breakout sessions:

  1. "FHIR to IntegratedML: Can You Get There from Here?'
  2. "Building a FHIR Façade" 
  3. "How to Customize Your FHIR Server"
  4. "Clinical Alerts and Notifications on FHIR: Putting the Healthcare Action Engine into the Workflow"
  5. "Performing Advanced FHIR Validation"
  6. "Clinical Research Data Pipeline using FHIR and OMOP"
  7. "FHIR in the Cloud"
  8. "Introducing Bulk FHIR Export"

Our second workshop in an introduction to containers -- "Working with Containers and InterSystems Technology" - led by Derek Robinson from our online learning team. It will prepare you for these two related sessions

  1. "The Container Lifecycle: When is Your App Ready to Accept Work?"
  2. "Can you Autoscale This?  Lessons from the Field on Kubernetes"

Register TODAY for Global Summit 2023 to take advantage of Early Bird Prices. (You will be able to register for sessions, including the workshops, soon.)

Discussion (0)1
Log in or sign up to continue
Article
· Mar 16, 2023 6m read

Kinds of properties in IRIS

InterSystems IRIS has quite a few different kinds properties. Let’s put them in order so that they make better sense.

First of all, I would divide them into categories:

  • Atomic or simple properties (all those %String, %Integer, %Data and other system or user datatypes)
  • References to stored objects
  • Built-in objects
  • Streams (both binary and character)
  • Collections (which are divided into arrays and lists)
  • Relationships (one-many and parent-children)

Some of these kinds of properties are quite straightforward. For example, atomic properties:

Property Name As %Name;
Property DoB As %Date
Property Age As %Integer

They are also easily created using Studio Wizard:

The concepts of references to stored objects and built-in objects are also quite easy to grasp. Basically, if the class of an object you’re trying to use as a property extends %Persistent, then it’s a reference to a stored object. If the related class extends %SerialObject – then it’s a built-in object, because such objects can’t be stored themselves, only inside other objects. And in a class definition they look exactly the same:

Property Human as Sample.Human;

To create this kind of property, on the second step of the Wizard in Studio enter the name of the class:

Streams are also quite easy to explain. You have a big chunk of unstructured data, be it binary or character, and here is your stream. Can be anything – audio, video, document, text etc. Depending on what type of data you want to store, you may choose to use Binary or Character Stream. Another defining characteristic of a stream is the place where you want to store it – on disk (takes less space but accessible from your OS unless you set up access rules for the folder) or in the database (secure, no unauthorized access, takes more space). To work with streams, use classes from package %Stream. For example:

Property Log As %Stream.GlobalCharacter;
Property Instruction As %Stream.FileCharacter(LOCATION = "D:\Temp");
Property Doc As %Stream.FileBinary;
Property Audio As %Stream.GlobalBinary;

In this case input the classname of the stream you wish to use:

Then there are two types of collections:

  • Lists – a collection where each element is defined by its position in the collection
Property FavoriteColors as list of %String;
  • Arrays – key-value pairs, where value is defined by its key that is set by a user
Property Contacts as array of %String;

Both collections can be of simple types or of objects. And when we’re talking about a collection of objects, the objects inside collection aren’t “aware” that they are inside any collection. Meaning that it’s a one-way link.

When working with arrays, it’s necessary to remember that both key and value should be new and useful piece of info. There is no point of making an integer key that will imitate a position in a list. In the example above, key of the Contacts array is a name of the type of the contact, e.g. “Facebook”, “LinkedIn”, “Twitter” etc and the value is a link to a personal page.

Under the hood, when working with a list, you’re working with the class %Collection.ListOfDT for a list of simple types, %Collection.ListOfObj when working with a list of objects and %Collection.ListOfStream when dealing with a list of streams.

The same is true for arrays. %Collection.ArrayOfDT is used when working with an array of simple datatypes, %Collection.ArrayOfObj – when working with an array of objects and %Collection.ArrayOfStream – when working with an array of streams.

For the collection on the second step of the Wizard in Studio choose the second option “The collection of type” 

and then specify the type:

And probably the most challenging kind of the property for people who switch from relational databases – relationship. The relationship is a two-way one-to-many link between two stored objects. In relational DBMS people are taught that they need an additional table to store the foreign keys to two other tables to realize one-to-many link of independent entities. For example:

table Invoice – table Product – table Invoice_Product

There is no need for an additional table/class to do this in IRIS. If there’s no need to often query the information about all the invoices in which the exact Product is listed you can make products as an array or list in an invoice. In this case you will have to manually ascertain logical integrity so that your invoice doesn’t reference products that are no longer in a DB.

To automatically check for the logical integrity of data in this case you can use a relationship between these two classes: Invoice, Product. There are two types of relationships:

  • Parent-children – it’s a dependent link between objects of two different persistent classes. It means that the dependent object can’t exist without the main object. For example, let’s say that a chapter in a book can’t exist without a book. This will be an example of parent-children relationship, where a book is a main object and chapter is a dependent object and if we delete a book all the chapters from this book will be deleted as well.
  • One-many – it’s an independent link between objects of one or two persistent classes. It means that both objects can exist and make sense one without the other and if you try to delete the aggregating object, you’ll get an error saying that you first have to unlink all the linked objects. If you try to delete the linked objects, they will disappear from the aggregating object. Let’s take our invoice and products as an example. We have many products in an invoice. If we try to delete an invoice, we first need to delete all the products from our invoice. If we delete a product, it will disappear from the invoice.

Since it’s a two-way link you need to define the properties in both classes. For example in a class Sample.Invoice you will have the definition:

Relationship Products As Sample.Product [ Cardinality = many, Inverse = Invoice ];


Note that the property is called Relationship and that it has two characteristics:

Cardinality = manymeaning that there are links to many objects inside this property

Inverse = Invoicethis is the name of the property on the other side of the relationship

At the same time in the other class (or it can be in the same class for one-many relationship) there should be the mirror property:

Relationship Invoice As Sample.Invoice [ Cardinality = one, Inverse = Products ];

Here cardinality “one” means that in this property there is a link only to one object.

To create a relationship using Wizard in Studio just choose on the second step Relationship:

Then choose the correct cardinality for the property in the class and fill in the name of the related class and property in it:

For the example with the book with chapters the properties would look as follows.

In a class Sample.Book:

Relationship Chapters As Sample.Chapter [ Cardinality = children, Inverse = Book ];

In a class Sample.Chapter:

Relationship Book As Sample.Book [ Cardinality = parent, Inverse = Chapters ];

This is the end of a brief overview of different kinds of properties present in IRIS. Hope it makes it clearer.

4 Comments
Discussion (4)2
Log in or sign up to continue
Article
· Mar 8, 2023 5m read

Keep your docker iris images in shape ;)

iris-docker-multi-stage-script

A python script to keep your docker iris images in shape ;)

Witout changing your dockerfile or your code you can reduce the size of your image by 50% or more !

TL;DR

Name the builder image builder and the final image final and add this to end of your Dockerfile:

Modify your Dockerfile to use a multi-stage build:

ARG IMAGE=intersystemsdc/irishealth-community:latest
FROM $IMAGE as builder

Add this to end of your Dockerfile:

FROM $IMAGE as final

ADD --chown=${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} https://github.com/grongierisc/iris-docker-multi-stage-script/releases/latest/download/copy-data.py /irisdev/app/copy-data.py

RUN --mount=type=bind,source=/,target=/builder/root,from=builder \
    cp -f /builder/root/usr/irissys/iris.cpf /usr/irissys/iris.cpf && \
    python3 /irisdev/app/copy-data.py -c /usr/irissys/iris.cpf -d /builder/root/ 

Boom! You're done!

11 Comments
Discussion (11)4
Log in or sign up to continue
Announcement
· Mar 8, 2023

Global Masters: get points for your ideas on Ideas Portal

Hi All, 

We are excited to announce that starting from February 22, 2023 you are getting Global Masters points for your product ideas on InterSystems Ideas Portal!

Free Vector | Businessman get an idea

100 points - for submitted ideas. You get points after the idea passed moderation, and has  status.
500 points - when idea is promoted for implementation, has"Planned", "In Progress" or "Community Opportunity" statuses.
3000 points - when idea is implemented and has "Implemented"or "Done by Community" statuses.

Please note: points awarded only for ideas submitted under "InterSystems Products" category.

Publish your awesome ideas and gain points for them!

Not a Global Masters gamification program member yet? Log in using your InterSystems SSO credentials.

5 Comments
Discussion (5)3
Log in or sign up to continue
Article
· Mar 2, 2023 4m read

Tutorial - Streams in Pieces

This tutorial is a follow on to Working with %Query    
It was displaying the content of the input stream chopped in fixed-size chunks.
But often those streams are structured and have well-defined separators (e.g HL7)
So as a side subject of this tutorial, this chapter shows how to break a stream into PIECES.

It is exactly the same idea as the $PIECE() function for strings with some add-ons.


The query takes these input parameters:

  • idfrom = first ID to show
  • idto = last ID to show - missing shos al higher IDs available
  • maxtxt = maximum size of output text from the stream. Default = 25
  • separator = characters as know from $Piece function 
  • startpiece = first piece to display
  • endpiece = last piece to display - if missing only the first is displayed
  • grouped = number of pieces in output text.  limited by maxtxt - default = 1
  • before = number of characters before the limiter from the previous piece

Implementation

The base for the Query was shown in the previous chapters.
Again the Source Object is kept local while processing the related Stream.
And as for the fixed-sized chunks also the Stream Object is kept while
processing the resulting output lines.

To find the pieces and count them method FindAt() scans the whole Stream
as a first action and builds a list of start points. It is used when the pieces
are collected into their groups by line.
The Streàm-Function used is ReadSQL(start, end). It is somewhat sensitive
and honors unprecise values with no result or ERROR. So besides locating all
pieces correctly composing precise and meaningful limits is the major challenge
for this part of the exercise.
It is all packaged in the method Piece() of the example code 

To enable multiple reentrances in the Fetch method all parameters are kept in
the common JSON object of the customized Query.

Here are some examples

  • Record #3 was deleted
  • Record#4 has no stream
  • PieceCnt shows the total pieces in the first row and number of pieces following
  • PieceId shows the number of the first Piece displayed

Some variations to the previous Tutorials:

  • the common variable qHandle that hat holds all requirements changed its name to qj to demonstrate independence from docu and for less typing.
  • the layout of the output in ROWSPEC is changed to also show the number of the starting piece, the total number of pieces in the first row, and the number of pieces in the following rows.

The first example shows objects 1..5 with max 33 chars
separated by || pieces 2..4  grouped by 2  with 3 previous characters

 

[SQL]USER>>call rcc.Q3(1,5,33,'||',2,4,2,3)
7.     call rcc.Q3(1,5,33,'||',2,4,2,3)

Dumping result #1
ID      City    Name    Age     pcCnt   PieceId PieceTxt
1       Bensonh Kovalev 16      52      2       ty.||Scope ||An AmAn LoIcA On
_       _       _       _       2       4        On||Iso
2       Queensb Yeats   15      52      2       00.||LoI||IesMorphSy
_       _       _       _       2       4       hSy||Re Uni
4       Newton  Evans   61      0       2
5       Hialeah Zemaiti 47      52      2       ks.||TwoToLy Wa||LoGraphIc Theti
_       _       _       _       2       4       eti||Ism LoToTri AticViaOpOp
 
7 Rows(s) Affected
statement prepare time(s)/globals/lines/disk: 0.0064s/2159/18029/0ms
          execute time(s)/globals/lines/disk: 0.0060s/186/21480/0ms
                          cached query class: %sqlcq.USER.cls86
---------------------------------------------------------------------------

Next example:
All records from 5 to end, maximum 33 characters, separated with || pieces 50 ..55 and 1 by line

USER>>call rcc.Q3(5,,33,'||',50,55,1)
9.     call rcc.Q3(5,,33,'||',50,55,1)

Dumping result #1
ID      City    Name    Age     pcCnt   PieceId PieceTxt
5       Hialeah Zemaiti 47      52      50      ||LoOp Am TriAmGeo LookMuch ReAble
_       _       _       _       1       51      ||AnIAn I GeoIc Ly Copter A IcA
_       _       _       _       1       52      ||***Done***
6       Elmhurs Jenkins 29      52      50      ||Re PhotoTech Ies
_       _       _       _       1       51      ||A
_       _       _       _       1       52      ||***Done***
7       Islip   Drabek  61      52      50      ||Thetic Status Cycle AmAm To Tech
_       _       _       _       1       51      ||Ly SoundCo CoCo AmCo Am ToRePus
_       _       _       _       1       52      ||***Done***
8       Islip   Kovalev 88      52      50      ||IcGeoType PhysicalLyIsm Ies To T
_       _       _       _       1       51      ||ComI An GeoRange On AnOnTo Two P
_       _       _       _       1       52      ||***Done***
 
12 Rows(s) Affected
statement prepare time(s)/globals/lines/disk: 0.0065s/2158/18091/0ms
          execute time(s)/globals/lines/disk: 0.0082s/245/28753/0ms
                          cached query class: %sqlcq.USER.cls103
---------------------------------------------------------------------------

Just a reminder:
All test data are generated using the System method %Populate
So your output will be different. I suggest you run our tests also with other parameters
than the shown examples to get the full power of this tool.

The full code example is again available on GitHub  

The Video is available now. See section Streams in Pieces 

For immediate access, you can use Demo Server WebTerminal  
and the related system Management Portal on Demo Server SMP

I hope you liked it so far and I can count on your votes.

1 Comment
Discussion (1)1
Log in or sign up to continue