InterSystems FAQ rubric
This can be done with TRY-CATCH:
#dimAsIf you use ^%ETN, call it from the BACK entry (BACK^%ETN).
Please also take a look at the related article: How to get application errors (^ERRORS) using a command
Pieces of experience in InterSystems Technology which solve some particular problem in elegant or unusual way.
This can be done with TRY-CATCH:
#dimAsIf you use ^%ETN, call it from the BACK entry (BACK^%ETN).
Please also take a look at the related article: How to get application errors (^ERRORS) using a command
Have you ever been editing files in VS Code, but needed to check a global value or run a few ObjectScript commands? Now you can, with no setup required! If you have vscode-objectscript extension version 2.10.0 or later and are connected to InterSystems IRIS 2023.2 or later, you can now open a terminal connection to your server, regardless of where it's located.
In the process of trying to get more familiar with Objectscript I decided to try to build a general priority queue since I wasn't able to find an implementation anywhere. My though process for implementing this followed this general path.
My first though to try to make this work quickly was to implement a binary heap and my first attempt at this used a multidimensional to build it. This version was relatively efficient, worked for strings/numbers natively, and worked for objects be letting the user override the comparitor.
Class pqueue.Queue Extends %RegisteredObject
{
Property Data As %Any [ MultiDimensional ];
Property Size As %Integer [ InitialExpression = 0 ];
Property Comparitor As %String [ InitialExpression = "(a,b) return a < b" ];
Method Swap(i As %Integer, j As %Integer) As %Status [ Private ]
{
set temp = ..Data(i)
set ..Data(i) = ..Data(j)
set ..Data(j) = temp
}
Method Comp(x As %Any, y As %Any) As %Boolean [ Private ]
{
return $XECUTE(..Comparitor, x, y)
}
Method PercolateUp(idx As %Integer) [ Private ]
{
while idx > 0 {
set newidx = (idx-1)\2
if ..Comp( ..Data(idx), ..Data(newidx) ) do ..Swap( idx, newidx )
else Quit
set idx = newidx
}
}
Method PercolateDown() [ Private ]
{
set idx = 0
while ((idx+1)*2) < ..Size {
if ..Comp( ..Data(idx*2+2), ..Data(idx*2+1) ) set newidx = idx*2+2
else set newidx = idx*2+1
if ..Comp( ..Data(idx), ..Data(newidx) ) Quit
do ..Swap( idx, newidx )
set idx = newidx
}
if ( (idx*2+1 < ..Size) && ..Comp( ..Data(idx*2+1), ..Data(idx) ) ) do ..Swap( idx, idx*2+1 )
}
Method IsEmpty() As %Boolean
{
return ..Size = 0
}
Method Top() As %Any
{
if ..IsEmpty() return ""
return ..Data(0)
}
Method Put(inp As %Any) As %Status
{
set sts = $$$OK
set ..Data( ..Size ) = inp
do ..PercolateUp( ..Size )
set ..Size = ..Size + 1
return sts
}
Method Get(Output obj As %Any) As %Status
{
set sts = $$$OK
if ..IsEmpty() {
set obj = ""
return $$$ERROR( "Cannot Get() from empty Queue" )
}
set obj = ..Data( 0 )
set ..Size = ..Size - 1
set ..Data( 0 ) = ..Data( ..Size )
do ..PercolateDown()
kill ..Data( ..Size )
return sts
}
Method GenerateComparitor(operator As %String = "<", transform As %String = "") As %Status
{
set ..Comparitor = "(a,b) return a" _ transform _ " " _ operator _ " b" _ transform
return $$$OK
}
}
After getting this working I wanted to try out different internal arrays since I assumed multidimensional arrays must be slower than a simple integer indexed array. So I modified the above code to use
* `Property Data As list Of %Any;` : This works OK but it is about 3-4 times slower than using a multidimensional making it pointless.
* `Property Data As %DynamicArray;` : I assumed this would be relatively fast but proved to be slow to the point of absurdity. When the amount of data stored in the queue is small it is around as fast as the `list of %Any`, but as the data grows the time it takes to make inserts and gets grows linearly which makes it pointless to build a heap on top of.
## Using the Multidimensional Array's Self-sorting
On its face this idea seems pretty simple, use the fact that the multidimensional array is always sorted to grab the lowest cost (highest priority) item. A problem with this are that indexing by an object simply uses the string representation of that object which isn't useful. To handle this a customer `evaluator` function is needed to return the integer or string evaluation of an object which is then sorted, it is then stored as `data( evaluation, obj_str_rep ) = object` which ensures that objects are correctly sorted even when two objects evaluate to the same value.
Class pqueue.SparseQueue Extends %RegisteredObject
{
// Parameter Comp(a,b) As $XECUTE(..Comparitor, a, b);
Property Data As %Any [ MultiDimensional ];
Property Size As %Integer [ InitialExpression = 0 ];
Property Evaluator As %String [ InitialExpression = "(a) return a" ];
Method IsEmpty() As %Boolean
{
return ..Size = 0
}
Method Top() As %Any
{
if ..IsEmpty() return ""
return $Order( ..Data("") )
}
Method Put(inp As %Any) As %Status
{
set sts = $$$OK
set ..Data( $XECUTE(..Evaluator, inp), inp ) = inp
set ..Size = ..Size + 1
return sts
}
Method Get(Output obj As %Any) As %Status
{
set sts = $$$OK
if ..IsEmpty() {
set obj = ""
return $$$ERROR( "Cannot Get() from empty Queue" )
}
set loc = $ORDER( ..Data("") )
set obj = ..Data(loc, $ORDER( ..Data(loc, "")))
set ..Size = ..Size - 1
kill ..Data( loc, obj )
return sts
}
Method GenerateEvaluator(transform As %String = "") As %Status
{
set ..Evaluator = "(a) return a" _ transform
return $$$OK
}
}
This method proved to be by far the fastest. It has some slight disadvantages in that it can be harder to write an evaluator than a comparitor and, in the form given above, it cannot hold the same object at the same value twice (this is a rare case but could theoretically be a problem or a benefit).
## Speed Test
To test these out I wrote a simple script that generates a large randomized weighted directed graph and runs [Dijkstra's shortest path algorithm](https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/) using a given queue object. Using a graph with `150000` vertices where each has `10` neighbors, the output is printed below. Here while the algorithm is running an update is printed every `10000` edges checked, where the time since the last 10 thousand and size of the priority queue is printed, with some final stats at the end. The order they are run in is
* Self-sorting Multidimensional
* Heap Multidimensional
* Heap Dynamic Array
* Heap List of Object
> Generated Random Graph
We have some ObjectScript code in a custom business process:.png)
When Log Trace Events is ticked on the business process in the Production view in the management portal, the argument is obviously computed.
Our question is whether the argument is computed when Log Trace Events is not ticked? Don't want to accidentally include something in a $$$TRACE() statement that takes enough computation to make a performance difference when released to production, even though the final output is not written to the event log.
Hello Community:
Let's go with the last article on how to record yourselves for the Article Contest video bonus.
I'm not going to go into how to do very specific things in editing because it varies depending on the program you use. The keyboard shortcuts and menus are different, but the concept is the same. You are going to use a programme to organise the recorded material, remove the excess and give it structure. Many of these softwares are free (Capcut, Canva and if I'm not mistaken DaVinci had a free version). I've been editing with Adobe Premiere for almost ten years now (wow, I'm getting old), so if you have any questions about this software, feel free to write to me.
Here are some concrete tips:
Hello Community:
Do you want to know how to record yourself without looking like you're speaking from a cave? Are you one of those who say you ‘don't come off well on camera’?
Today I'm going to share with you some specific tips that I learned after several years of filming interviews for television and networks. I remind you that these are tips in case you are thinking of taking advantage of the Article Contest video bonus. However, they are tips that I'm sure you can use for presenting webinars, video calls and filming yourself in general.
Hi Community,
As you may know, this year's Spanish Technical Articles contest will be in May. I am going to make a series of articles to support you in the creation of your articles, giving tips and tricks. Perhaps they will be useful for the contest you have active in this community as well.
As you may know, one of the bonuses or extra points you can receive is to add a video tutorial to your article. You may not even know how to approach this issue, no problem! I'm here to give you some tips that you can apply not only to the creation of these videos, but to any other.
Hi, this post was initially written for Caché. In June 2023, I finally updated it for IRIS. If you are revisiting the post since then, the only real change is substituting Caché for IRIS! I also updated the links for IRIS documentation and fixed a few typos and grammatical errors. Enjoy :)
In this post, I show strategies for backing up InterSystems IRIS using External Backup with examples of integrating with snapshot-based solutions. Most solutions I see today are deployed on Linux on VMware, so a lot of the post shows how solutions integrate VMware snapshot technology as examples.
Another VSCode "Tips & Tricks" entry -
.png)
Do you want to see this option in VSCode?
The latest "Bringing Ideas to Reality" InterSystems competition saw me trawling through the ideas portal for UI problems to have a go at.
It can be obtained with a List query of the %SYS.Namespace class.
1. Create a routine like this:
getnsp
set##class2. Run it in your terminal
The method of executing class queries introduced in this article can be applied in a variety of cases.
You can see various class queries in the class reference. For example,
%SYS.DatabaseQuery: GetFreeSpace() Free space in database
%SYS.GlobalQuery: DirectoryList List of global names in database
%SYS.GlobalQuery: Size
The ability to resend messages easily has always been a strong feature of our Interoperability capabilities.
With v2024.3 coming out soon (available already now as Developer Preview) out already we've made this even easier!
As we keep updating our software, we often realize that we require more and more modern solutions. So far, only one major piece of our software relies on reading barcodes in documents and images. Since Cache did not have a means of reading barcodes in the past, we have always achieved our goals by using a Visual Basic 6 application. However, it is no longer an ideal solution because it is currently complicated to maintain it. IRIS also lacks this capability, but it has recently got an option that makes up for it: embedded Python!
By default, the order of columns in a table is determined automatically by the system. To change the order, explicitly set the order for each property using the property keyword SqlColumnNumber when defining the class.
Example:
Property Name As %String [SqlColumnNumber = 2];
Please see the documentation below.
If you want to change the SQL table name, specify SqlTableName. If you want to change the column name (field name), specify SqlFieldName.
Both apply only to persistent classes.
I am just writing something to share what I encountered last night, which is the IRIS 2024.3 does not comes with Python by default any more!!!
Which means that I need to install it by myself!!😅 The pros is, I can select my python version😁🤭💃 The trouble is.... at the first place.... I don't know what I should do😥. By going through the community (I am much more prefer than the official document, sorry InterSystems document team😓 ), I found the following piece
https://docs.intersystems.com/iris20242/csp/docbook/DocBook.UI.
I was working on a DTL but kept getting ERROR #5002... MAXSTRING errors. The problem was that most of the DTL GUI action steps only support the string data type when working with the segments. A %String has a limit of 3,641,144 characters and my OBX5.1 was 5,242,952 characters long as the example provided. Of course PACS admin stated ultra high quality up to and including 4K resolution files were needed, so we could not get the vendor to compress or reformat these files to compressed jpg or something similar.
.png)
Initially this vendor sends a 2.3 ORU^R01
Many programming languages use the try-and-catch construct to handle runtime errors gracefully. If the code within the try block encounters an error, it will throw an exception to the catch block, where the error handling occurs. Today we will dive into the ObjectScript implementation of this construct and discuss some ways to clean things up.
In the business world, every second counts, and having high-performing applications is essential for streamlining our business processes. We understand the significance of crafting efficient algorithms, measurable through the big O notation.
Nevertheless, there are numerous strategies to boost the performance of systems built on the IRIS Data Platform. These strategies are equally crucial for optimizing overall efficiency.
Let's join the journey for a sneak peek into the tips for making IRIS Data Platform work better, where every little trick will help your applications shine.
1.
There are many applications for working with HL7 V2 messages, but the tools for working with XML in IRIS Management Portal and Cache Studio are limited. While plenty of external utilities and IDEs work with XML messages and even C-CDA documents, there is a compelling case for being able to test directly against the IRIS C-CDA framework.
Testing within the IRIS environment provides the necessary context:
We are doing healthcare interface development.
Developers have Ensemble installed locally on their laptops - code will be developed locally then deployed to integration, test/UAT and ultimately production servers in due course.
One of the other applications we are developing around happens to utilise an Iris desktop client to a remote Iris server. We want to have the application available on the developers laptops alongside the local Ensemble instance.
✅ It appears that if we install their desktop client then install our local Ensemble server, things work.
On Windows, this cannot be changed, but on Unix-like platforms, it can be changed using the iris rename command.
iris rename instname(<current instance name>) newname(<new instane name>)
For more information about the iris rename command, please refer to the following document:
There's an easy new way to add certificate authority (CA) certificates to your SSL/TLS configurations on InterSystems IRIS 2019.1 (and 2018.1.2) on Windows and Mac. You can ask IRIS to use the operating system's certificate store by entering:
%OSCertificateStore
in the field for "File containing Trusted Certificate Authority X.509 certificate(s)". Here's an image of how to do this in the portal:

And here's a link to the documentation which describes this. It's in the list of options under "File containing trusted Certificate Authority certificate(s)".
That's all you need to do!
Hi,
Is there a way to set the SettingSchedule on a EnsLib.File.PassthroughService at 9:00 am to 9:30 am but only end of the month?
I can START and STOP a business process via its Schedule setting.
Is it possible to change the value of another Setting in an analogous way?
I can imagine a SettingSchedule that could look like
action:YYYY-MM-DDThh:mm:ss[,action:YYYY-MM-DDThh:mm:ss]
But rather than just START or STOP, action could be "SET Setting = value", overriding whatever the normal value is.
Is there an existing way of achieving this kind of functionality?
I've got a business process that triggers from a scheduled task, and sends documents to a downstream system according to business requirements.
For those of you who still use the Studio IDE for ObjectScript programming and are going through the process of migrating to VS Code, did you know there's a section in the VS Code documentation just for you? Have a look at the Migrating from Studio chapter. It covers:
And now there's a new section, Keyboard Shortcuts, that shows you the VS Code equivalent for shortcuts you may be used to, so your hands never have to leave the keyboard.
The following code downloads https://www.intersystems.com/assets/intersystems-logo.png and saves the file as c:\temp\test.png.
You need to define an SSL configuration called SSLTEST before executing this code
ClassMethodAs%StatusTemporary globals stored in the IRISTEMP/CACHETEMP databases are used when a process does not need to store data indefinitely, but requires the powerful performance of globals. The IRISTEMP/CACHETEMP databases are not journaled, so using temporary globals does not create journal files.
The system uses the IRISTEMP/CACHETEMP databases for temporary storage and are available to users for the same.
For more information about temporary globals and the IRISTEMP database, see the following document:
Temporary Globals and the IRISTEMP Database
If you do not specify the option to remove the mirror attribute of the mirror database when deleting the mirror configuration, the database cannot be restored to a normal state and will be mounted read-only the next time it is mounted. To restore the database to a read-write state, you must remove the mirror attribute using the system routine ^MIRROR.
As a part of the IRIS Python 2024 contest, my colleague Damir and I went with an idea to build a platform called ShelterShare for connecting victims and volunteers for shelter requests . To do so we chose django as a framework and proceeded to build the first version with 3 different docker containers, django, iris and nginx which would then utilize IRIS as a pure Database engine via the beautifly composed django_iris (cudos to Dimitry). As we were progressing fast, we decided to explore the option of running it within the same container as IRIS by utilizing WSGI added in 2024.1.
There are two great WRC best practice articles Ensemble Orphaned Messages | InterSystems Developer Community | Best
and the delete helper post DeleteHelper - A Class to Help with Deleting Referenced Persistent Classes (intersystems.com)
that go into orphaned records and how to deal with orphans.