#Code Snippet

6 Followers · 302 Posts

Code snippet is a programming term for a small region of re-usable source code, machine code, or text.

Article Jose Ruperez · Oct 11, 2016 4m read

Now, let’s say you can’t access the terminal or simply you just rather execute it from a web interface. In this article, I will show you how to execute terminal commands from a simple web page.

For example, in the image below you see how we execute $zv on a webpage:

This is mostly possible due to the XECUTE command in Caché ObjectSCript. This command takes a string as a parameter and tries to execute it. This is the command used from the webpage, to execute what is being passed from the left navigation menu.

This article contains three snippets of code.

7
0 32731
Article Kyle Baxter · Jul 19, 2016 2m read

Date range queries going too slow for you?  SQL Performance got you down?  I have one weird trick that might just help you out! (SQL Developers hate this!)*

If you have a class that records timestamps when the data is added, then that data will be in sequence with your IDKEY values - that is, TimeStamp< TimeStampif and only if ID1 < IDfor all IDs and TimeStamp values in table - then you can use this knowledge to increase performance for queries against TimeStamp ranges.  Consider the following table:

Class User.
9
1 30740
Article Jeff Morgan · Oct 21, 2016 3m read

This article will describe and include an example of how to embed an external PDF file into an HL7 segment, specifically ADT_A01:2.3.1 OBX().  This can be useful when attempting to insert pictures or other external data into an HL7 message.  In this example, the name of the PDF file to be embedded is provided in the incoming HL7 message in OBX(1):ObservationValue field.


The basic stipulations for this example are as follows:

  1. Accept a PDF file
  2. Accept an HL7 message
  3. Using the name of the PDF file, embed the PDF data into the HL7 message
  4. Output the message to file

  

Using EnsLib.

4
6 15882
Article Timothy Leavitt · May 12, 2016 6m read

The topic of for/while loop performance in Caché ObjectScript came up in discussion recently, and I'd like to share some thoughts/best practices with the rest of the community. While this is a basic topic in itself, it's easy to overlook the performance implications of otherwise-reasonable approaches. In short, loops iterating over $ListBuild lists with $ListNext or over a local array with $Order are the fastest options.

As a motivating example, we will consider looping over the pieces of a comma-delimited string.

21
5 10131
Article Evgeny Shvarov · May 11, 2016 1m read

Hi!

I believe the simplest is (to work with csv delimited by ";"):


set file = ##class(%File).%New( "data.csv" )
    set sc = file.Open( "R" ) 
    if $$$ISERR(sc) quit    ; or do smth

    while 'file.AtEnd {
        set str=file.ReadLine() 
        for i=1:1:$length( str, ";" ) {
            set id=$piece( str, ";" ,i ) 
            write !, id  // or do smth
        }
    }
    do file.Close()

Possible options:

different variants of error handling with sc code.

Embrace while loop into try/catch block.

And what's yours?

16
0 7281
Question Scott Beeson · Feb 16, 2016

Here is my original query:

SELECT EventType, InitiatedAt, COUNT(*) as cnt
FROM HS_IHE_ATNA_Repository.Aggregation
WHERE EventType = 'LOGIN'
AND LocalDateTime > '2016-02-16 11:00:00'
GROUP BY EventType, InitiatedAt

This gives me data like this:

LOGIN %SYSTEM 69918
LOGIN OTHER 39


However, I need to get the data back as two columns with all but the last concatenated and delimited, more like this:

LOGIN;%SYSTEM 69918
LOGIN;OTHER 39

I tried this:

SELECT EventType + ';' + InitiatedAt as k, COUNT(*) as cnt
FROM HS_IHE_ATNA_Repository.
3
0 7182
Question Eduard Lebedyuk · May 24, 2017

I'm aware of two ways to get list of files in a dir:

set dir = "C:\temp\"
set rs = ##class(%File).FileSetFunc(dir, , , 1)
do rs.%Display()

and:

set dir = "C:\temp\"
set file=$ZSEARCH(dir_"*")
while file'="" {
   write !,file
   set file=$ZSEARCH("")
}

Yet they bot return only files and directories in a current directory, but not files in subdirectories.

I suppose I call one of these recursively, but maybe there's a better solution?

25
1 4282
Article Tani Frankel · Feb 17, 2016 3m read

Question:

How do I get a list of files residing in a certain folder/directory, according to some wildcard/filter.

For example all '*.txt' files in 'C:\Temp'.

Answer:

In CACHE –

You can use the %Library.File's FileSet class query.

Here's some sample code using it (also attached):

run(pDir,pFileSpec)

      Set tRS=##class(%ResultSet).%New("%Library.File:FileSet")

      Set tSC=tRS.Execute(pDir,pFileSpec)

      Write "Name",?30,"Date Modified",?53,"Type",!
      Write "--------------------------------------------------------------------------",!

      While tRS.
2
0 4176
Article Pravin Barton · Mar 28, 2019 2m read

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.

///Status from SQLCODE:set st = $$$ERROR($$$SQLError, SQLCODE, $g(%msg))  //embedded SQLset st = $$$ERROR($$$SQLError, rs.%SQLCODE, $g(rs.%Message)) //dynamic SQL///Exception from SQLCODE:throw ##class(%Exception.
5
23 3960
Article Randy Pallotta · May 27, 2016 3m read

Two fairly common requests we receive from HL7 customers are (1) how to remove all trailing delimiters for fields and segments in HL7 messages and (2) how to "find and replace" for an entire HL7 message (as opposed to one segment/field at a time).  The code sample below shows a custom function that solves for item 1 and by extension item 2 above.  In other words the same approach can be used for finding/replacing any sequence of chars in an entire HL7 message, with some tweaks to the custom function.

Here’s an example of how to actually call the function from DTL.

6
0 3778
Article Evgeny Shvarov · Apr 16, 2016 1m read

Hi!

Want to share with you code snippet of try catch block I usually use in methods which should return %Status. 


{ 
 try {
  	$$$TOE(sc,StatusMethod())
 }
 catch e {
 	set sc=e.AsStatus()
 	do e.Log()
 }

Quit sc 
}

Here $$$TOE is a short form of $$$TROWONERROR macro.

Inside macro StatusMethod is any method you call which will return %Status value. This value will be placed into sc variable.

In case of sc contains error execution will be routed to try catch block. You can wrap any Status methods calls in your code if you need to catch the errors coming from them.

21
2 3582
Question Peter Steiwer · Dec 12, 2016

Is there a better way to iterate through all properties of an object than the following? Perhaps without needing to open a definition of the class but directly against the object?


SAMPLES>set t=##class(HoleFoods.Transaction).%OpenId(1)                          
SAMPLES>set def=##class(%Dictionary.ClassDefinition).%OpenId("HoleFoods.Transaction")
SAMPLES>for i=1:1:def.Properties.Count() {  w def.Properties.GetAt(i).Name_":"_$property(t,def.Properties.GetAt(i).Name),!  }
Actual:0
AmountOfSale:4.
6
1 3551
Article John Hotalen · Sep 29, 2016 1m read

Checking if Directory or File Exists:

Outlined below is an example of how to check if a directory exists:

Set directoryName="c:\temp\nosuchdir"

/* Check for existence of a directory - Return Value:  0 - directory does not exist;  1 - directory does exist  */

Set directoryExists=##class(%File).DirectoryExists(directoryName)

If ('directoryExists)  // do the processing for when a directory does not exist


Outlined below is an example of how to check if a file exists:

Set fileName="a_test_filename.
1
0 3366
Discussion Evgeny Shvarov · Apr 22, 2018

Hi, Community!

Have a question for general discussion. 

In ObjectScript we have cls for classes and mac code, which both compile into int code. 

Is there any reason when you use mac instead of cls  for non-persistent classes?

For me the benefits for cls are:

1. Inheritance and other OOP features

2. Auto-documented code 

For mac one visible benefit is easier call in terminal:

do method^Utils(p1,p2)

vs

do ##class(Package.Utils).method(p1,p2)

What is your choice and why?

43
1 3069
Article Jenna Makin · May 26, 2016 2m read

With the release of Cache 2016.1, JSON support was re-architected and made part of the core object model with the creation of %Object and %Array classes, which allow you to create dynamic JSON enabled objects and arrays.

On a recent demonstration I was working on, I had the need to create a REST web service that returned a JSON representation of a persistent object.  After searching for methods that would allow me to accomplish this, ultimately I found none, until now.

With the release of 2016.

20
0 3045
Article Brendan Batchelder · Jun 8, 2016 2m read

DTL Transformations and GetValueAt/SetValueAt calls on HL7 messages will truncate any fields longer than 32K.  To avoid this, the methods GetFieldStreamRaw and StoreFieldStreamRaw must be used when dealing with fields that might be larger than 32K.  OBX:5 is a frequent example.  These methods have some subtleties and must be used carefully.

This can't be done by simply dragging from left to right in a DTL.  It must be done with a code action.  Also, the StoreFieldStreamRaw call must be the last edit made to the segment because the segment becomes immutable after that.

6
6 2948
Article Daniel Kutac · Jul 18, 2016 3m read

Cache tricks

Several years ago, long before Developer Community Portal was launched, I published a series of Caché tricks at one of Czech web sites. In this article, I’m posting translated version of one of them.

Capturing output of someone else’s methods or routines

Suppose you, or someone else created a useful method or routine, that was producing some computation that you’d like to benefit from, but the routine was writing output to process principal device.

You would like to use the data, but you need it not written to a device, but assigned to a variable. And, for any reason, you can’t modify the code. What can you do?

4
0 2928
Article Sylvain Guilbaud · Oct 6, 2016 3m read

to dismount/mount a database, use Dismount() and Mount() methods in SYS.Database class available in %SYS namespace.
NB: the database ID is its Directory

You'll find  some examples of how to dismount/mount and check if a database is mounted (Mounted=1) or not (Mounted=0), and quickly see all the attributes of a database (via zwrite)


%SYS>set db="/opt/irisapp/data" 

%SYS>w ##class(SYS.Database).%OpenId(db).Mounted                     
1
%SYS>w ##class(SYS.Database).%OpenId(db).Dismount()
1
%SYS>w ##class(SYS.Database).%OpenId(db).Mounted   
0
%SYS>w ##class(SYS.Database).%OpenId(db).
2
1 2910
Article Timothy Leavitt · Mar 9, 2016 3m read

There have been a few use cases recently within InterSystems where we've needed to connect to Caché-based web services from PHP. The first of these was actually the Developer Community itself, which uses web services as part of Single Sign-On with other InterSystems sites/applications. The following example demonstrates how to connect to a Caché-based web service (particularly, the web service in the SAMPLES namespace) from PHP, using password authentication.

0
0 2812
Article Jose-Tomas Salvador · Apr 25, 2018 2m read

What if you could serialize/deserialize objects in whatever format: JSON, XML, CSV,...; attending different criteria: export/import some properties and not others, transform values in this or that way before exporting/importing,...; and all of this without having to change the class definition? Wouldn't that be great??

Well, perhaps it's a goal too ambitious to reach 100% but, exploring this idea, I've developed a bunch of classes that I thought it was good to share. If you want to test, change, modify or improve the code, or just take a look at it, you can do it here. There you'll find a more detailed explanation (see Readme.md)

Be aware, this is a proof of concept for myself done in spare times, sure it's not robust enough or it can be done much better... but, I was just playing...ok, I could just wait to the new JSON Adaptor (coming soon!) that sure is going to resolve much more scenarios in a cleaner way, but... meanwhile... :-) ...
4
4 2809
Article Amir Samary · Oct 12, 2017 4m read

Hi!

It is often necessary to run some external command such as a python program or a shell script from inside Caché/Ensemble. There are three ways of doing this:

  • $ZF(-1) - Runs the command and waits for it to finish.  
  • $ZF(-2) - Runs the command and don't wait for it to finish.
  • Using CPIPE device - Runs the command and opens a device for you to read its output or (exclusive or here!) write to its input.

$ZF(-1) is normally more interesting because it allows you to recover the return code of the program you are calling. If that is important to you, that is the way to go.

8
1 2761
Article Wilber Tang · Jul 25, 2016 1m read

EnsLib.HL7.Message.cls provides many API methods for manipulating an HL7 message.  RemoveSegmentAt(), for example, can be used to remove a segment by path or index, but only one segment at a time.   There may be times that you'll need to remove all segments within a group or even many groups of segments from the HL7 message.  Surely you can iterate through each segment in each group and remove them one by one, but there's a much easier way. 

With just one command, like below, you can remove all OBX segments in an ORU_R01 message (msg):

Set tSC = msg.SetValueAt(,"PIDgrpgrp(1).ORCgrp(1).

1
0 2630
Question Josh Barney · Mar 24, 2016

I believe the I have followed the instructions to attach a document to the body of a post request but nothing is being sent out in the files{} port of the request.  I can either get the stream in "data", not visible at all, or visible but no form data. Any help would be appreciated, below is what I have:

ClassMethod SendFax(phone As %Stringcoverpath As %Stringdocpath As %StringAs %String
{
     Set req ##class(%Net.HttpRequest).%New()
    //test server
    Set req.Server "httpbin.org"
    Set req.SSLConfiguration "CardChoice"
    
    Do req.InsertFormData("Username",##class(HData.

3
0 2546
Article Lexi Hayden · Jul 18, 2017 2m read

The newer dynamic SQL classes (%SQL.Statement and %StatementResult) perform better than %ResultSet, but I did not adopt them for some time because I had learned how to use %ResultSet. Finally, I made a cheat sheet, which I find useful when writing new code or rewriting old code. I thought other people might find it useful.

First, here is a somewhat more verbose adaptation of my cheat sheet:

1
%ResultSet::%New()
%SQL.
35
4 2537
Article Brendan Batchelder · Jun 20, 2016 1m read

The message viewer can resend messages but it is not suitable for resending a large number of messages (>100).  For that, you should use Cache Object Script code such as the following:

Class Sample.Resender Extends %RegisteredObject
{
ClassMethod Resend()
{
//Resend all messages sent from 'FromComponent' to 'ToComponent' between 2016-06-15 and 2016-06-20
&sql(DECLARE C1 CURSOR FOR
 SELECT ID INTO :id FROM Ens.
7
3 2451
Article Benjamin Thorne · Jul 17, 2018 1m read

The following code snippet uses GZIP to compress/decompress a file. Choose a file by specifying a file path in the "filename" variable.


Class objectscript.GZIP Extends %RegisteredObject
{
	classmethod test() {
		//Export Global(s) uncompressed
		set filename="C:\Temp\myglobal.xml"
		do $System.OBJ.Export("^oddEXTR.gbl",filename)
		//Open exported Globals
		set uncompressed = ##class(%FileBinaryStream).%New()
		set uncompressed.Filename=filename
		Set compressed = "C:\temp\mycomglobal.
6
1 2395