In Caché, the dev/cpp and dev/python directories contain the C++ and Python bindings, respectively. As far as I know, these are not available for InterSystems IRIS. They were shipped as source, so maybe they would work with IRIS? I doubt that it's been tested.

The dev/iris-callin directory contains the headers for the C callin API. This includes files that are compatible with programs written using headers that are shipped with Caché in the dev/cache/callin directory.

It appears that your link is to a Docker image of the application installed on YottaDB, a fork of GT.M. I followed the link at the bottom of the page to the FOIA release page:

https://code.osehra.org/journal/journal/view/1576

After downloading the latest copy and skimming the documentation, this release includes a CACHE.DAT database and extensive installation and configuration instructions for Caché. If you want to run the application on InterSystems IRIS, you would do better to start there than the YottaDB-based image.

For a container deployment, there are three things you'll want to be aware of: durable %SYS, bind mounts, and ports.

I believe that durable %SYS is covered in the documentation. Basically, it will store all of the database and mapping configuration that you do outside of the container.

You'll need a bind mount for durable %SYS, and for the RPMS database.

You'll want to export the web server port so that you can access the management portal.

One other suggestion: if you're new to InterSystems IRIS and/or containers, you may want to start with Docker locally on your system before tackling a cloud deployment.

Good luck, and have fun.

Whereas the digest methods in the %SYSTEM .Encryption class return binary strings, which are documented in terms of their byte length, it is indeed conventional to display them using hexadecimal. Instead of $select, I more usually see $translate and $justify:

s h0x=h0x_$tr($j(chr,2)," ",0)

If %xsd.hexBinary is covenient, though, I'd say use that.

For a sanity check, you can compare whatever implementation you choose with the zzdump command:

USER>s digest=$system.Encryption.MD5Hash("12345678")

USER>w ##class(%xsd.hexBinary).LogicalToXSD(digest)
25D55AD283AA400AF464C76D713C07AD
USER>zzdump digest

0000: 25 D5 5A D2 83 AA 40 0A F4 64 C7 6D 71 3C 07 AD

It looks like the accented "é" is causing problems with the directory software. The UTF-8 encoding of \u00e9 is \xc3\xa9, which is URL encoded as %c3%a9, which has been URL encoded again as %25c3%25a9. Try this:

https://openexchange.intersystems.com/package/Cach%C3%A9Quality

My browser displays this as:

https://openexchange.intersystems.com/package/CachéQuality

Interesting. I added a loop for if $increment(num) {} (i.e., a new-style if statement that doesn't set $test): no measurable improvement over legacy if.

I also added a loop for do $increment(num) (i.e., a do statement that neither sets $test nor returns a value): ever so slightly slower.

USER>d ^Times(1,8)
   count   num+1   1+num   =$i()    $i()  $i(){}  d $i()
               times in microseconds
--------------------------------------------------------
       1   1.000   0.000   1.000   0.000   0.000   1.000
      10   0.000   0.000   0.100   0.100   0.000   0.000
     100   0.010   0.010   0.490   0.030   0.030   0.040
    1000   0.042   0.011   0.029   0.034   0.029   0.033
   10000   0.011   0.010   0.030   0.032   0.032   0.031
  100000   0.009   0.010   0.030   0.028   0.027   0.031
 1000000   0.009   0.010   0.028   0.028   0.027   0.031
10000000   0.010   0.010   0.028   0.028   0.028   0.031

Incidentally, here are some results with num renamed to ^num:

USER>d ^Times(1,8)
   count   num+1   1+num   =$i()    $i()  $i(){}  d $i()
               times in microseconds
--------------------------------------------------------
       1   2.000   0.000   2.000   1.000   0.000   0.000
      10   0.100   0.200   0.100   0.100   0.100   0.100
     100   1.070   0.280   0.130   0.110   0.100   0.110
    1000   0.142   0.144   0.142   0.102   0.102   0.106
   10000   0.142   0.141   0.110   0.116   0.104   0.108
  100000   0.142   0.141   0.102   0.101   0.100   0.104
 1000000   0.139   0.140   0.100   0.098   0.100   0.102
10000000   0.138   0.138   0.098   0.098   0.099   0.102

For "=$i()", I assigned a local, rather than redundantly assigning the global.

There is a way to do something similar in Caché and IRIS. In a Russian locale, you have access to the "KOI8R" I/O translation table. KOI8-R has the funny property that if you mask out the high-order bit, you get a sort of readable transliteration. Here's an example using a Unicode instance in the "rusw" locale:

    USER>s koi8=$zcvt("Пример для Кода","O","KOI8R")

    USER>s ascii="" f i=1:1:$l(koi8) s ascii=ascii_$c($zb($a(koi8,i),127,1))

    USER>zw ascii
    ascii="pRIMER DLQ kODA"

When you're using subscript indirection with a recursive $order traversal, you may find the $name function useful; e.g.,

    do ..RecursiveGlobalCount($na(@pGlobalName@(tKey)),"",.tCount)

As the other answers suggest, you probably want $query instead of $order, but $order can be useful for summarizing on multiple subscript levels (e.g., count, min, and max per country, state, and city).

It's documented here:

https://cedocs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?K...

"The hashes are calculated using the PBKDF2 algorithm with the HMAC-SHA-1 pseudorandom function, as defined in Public Key Cryptography Standard #5 v2.1: 'Password-Based Cryptography Standard.' The current implementation uses 1024 iterations, 64 bits of salt, and generates 20 byte hash values."

It occurs to me that the Visual Basic solution works with minimal modification as Caché Basic: weaken the DIM statements, change Debug.Print to Print, and replace the call to Format$().

Option Explicit

Const VECSIZE = 3350
Const BUFSIZE = 201
Dim buffer
Dim vect
Dim more, karray, num, k, l, n

  For n = 1 To VECSIZE
    vect(n) = 2
  Next n
  For n = 1 To BUFSIZE
    karray = 0
    For l = VECSIZE To 1 Step -1
      num = 100000 * vect(l) + karray * l
      karray = num \ (2 * l - 1)
      vect(l) = num - karray * (2 * l - 1)
    Next l
    k = karray \ 100000
    buffer(n) = more + k
    more = karray - k * 100000
  Next n
  Print buffer(1)
  Print "."
  l = 0
  For n = 2 To BUFSIZE
    Print Right("00000" & buffer(n), 5)
    l = l + 1
    If l = 10 Then
      l = 0
      Print 'line feed
    End If
  Next n