Advent of Code is a series of 25 small programming challenges, it's an ideal way for beginners to start learning a computer language, and for advanced people to sharpen their programming skills.
There are small and bigger puzzles, which you can solve typically in half an hour to a few hours. (Looking at the leaderboard, the top aces can do them in less than 10 minutes.)
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:
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:
Hi everybody, We have written a convert from Punycode. This is reformed from javascript. Perhaps many non-English systems need to use this feature in domain name resolution. Anyone can use and change the code as needed.
Inspired by the article "Declarative development in Caché" that's still trending on the dev com. The OP explored a functional style of iterating over a collection. A comment today suggested "Caché would need syntax support for anonymous functions".
With Macros you can kind of get anonymous like syntax using dot notation.
This is not production code, but it does work. First the macros...
I've created a datatype class whoch extends from %Library.String with a REGEX parameter and the validation of the value against the regular expression. The class does not support Populate using the regular expression as a template for data population.
A feature I recently used in working on ISC internal applications is the ability to send emails on behalf of someone. This is useful when generating system notifications from an application when you want some of them to show up as being from a specific person, perhaps posting comments on a work ticket.
In my case I was updating our facilities work order system for tracking requests. Normally all notification emails are sent from the same noreply email address. I wanted to change that so comments added from the original requester would show up as being from them and stand out.
As more people join Developer Community, and with increasing efforts to promote code sharing, I'd like to draw fresh attention to this post I wrote a year ago. It spotlights a feature within the class compiler which is both useful and dangerous. When importing code (e.g. from an XML export of classes received from someone), it's worth considering the risks.
Even if that post doesn't seem relevant to you at the moment you may wish to note it for the future. A handy way of doing this is to click the star icon at the end of it.
It is not possible in a COS (Caché Object Script) job/process context to have multiple Named Pipes. It is a one Named Pipe per job/process limited line of communication.
Named Pipes, in Caché, like most pipes on most operating systems are Unidirectional. That means you open them for either Read or Write, but not both.
This is the second part of my long post about package managers in operating systems and language distributions. Now, hopefully, we have managed to convince you that convenient package manager and rich 3rd party code repository is one key factor in establishing of a vibrant and fast growing ecosystem. (Another possible reason for ecosystem success is the consistent language design, but it will be topic for another day.)
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.
Here you have an easy way to write and execute COS code from your unix scripts. This way one does not need to write routines or even open Studio or Atelier. It can be an option for simple and small actions for instance things like installation tasks or compiling.
See sample bash script (compile.sh) to compile classes:
With a routine like this one, you can quickly calculate how many lines of code you are working with. And it is not only for routines, it works for classes because remember that classes generate routines !
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:
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)
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:
We're developing Ensemble PoC and one day our frontend developer (who doesn't have Ensemble production running) said that Populate just doesn't cut it and he needs to see the real data. He needed only one object, but the problem was - it's a big object. Still, I checked ids of everything related and wrote this command (parts omitted, but you get the idea):
Process-private Globals can be used as a data global in storage definition. That way, each process can have its own objects for the class with ppg storage. For example lets define a pool, which can:
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):
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, TimeStamp1 < TimeStamp2 if and only if ID1 < ID2 for 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: