Eduard Lebedyuk · Aug 2, 2021 go to post

Great article.

Some comments on formatting:

  1. Move large code blocks under spoiler to improve readability using button.
  2. There are a lot of empty lines in code blocks, they can be safely removed.

On the article itself my only issue is you create 5 methods per class:

  • GET /class
  • POST /class
  • GET /class/object
  • PUT /class/object
  • DELETE /class/object

That's a lot of code even for 4 classes, but what about a case where there are 10 classes? 50? 100? Generally I would recommend writing 5 methods which would process objects of any allowed class (see RESTForms2).

Eduard Lebedyuk · Jul 30, 2021 go to post

I think the preferred way is to use $SYSTEM.OBJ.Export (or even better - VCS) instead of direct global manipulation to export code.

Eduard Lebedyuk · Jul 29, 2021 go to post

Set in the BP/BPL classes:

Parameter SKIPMESSAGEHISTORY = 1;

it would improve journaling.

Eduard Lebedyuk · Jul 28, 2021 go to post

The BP (and the entire production) is down for the entire modification/compilation/update.

The issue is that for existing instances ResponseHandlers should be updated after BP compilation to point to the new values.

Eduard Lebedyuk · Jul 28, 2021 go to post

For the case where only a new OnResponse method is added the workaround is executing these update queries:

UPDATE process.Context__ResponseHandlers
SET  "_ResponseHandlers" = 'OnResponseXYZ'
WHERE "_ResponseHandlers" = 'OnResponseABC'

Where ABC is an old method name, XYZ is a new method name.

In a case of several new methods they should be executed from the largest number first.

Eduard Lebedyuk · Jul 27, 2021 go to post

Unable to reproduce. Here's my test routine:

ByRef
    kill a
    set a = 1
    set a(1) = 2
    do Test(.a)
    zw a

Test(a)
    set a(1) = a(1) + 1
    set a(2) = -1

And here's an invocation result:

>d ^ByRef
a=1
a(1)=3
a(2)=-1

as you can see a new subscript has been added successfully.

Eduard Lebedyuk · Jul 23, 2021 go to post

Datatype classes are used to define object properties, they allow to:

  • Validate values both generic (for example any defined %Integer property by default checks that it's value is an integer) and based on datatype parameters (for example you can have an %Integer(MINVAL=0, MAXVAL=9) property which in addition to checking that it's value is an integer would check that integer value is between 0 and 9)
  • Provide different representations based on context, specifically:
    • Logical (what's stored in globals)
    • Display (what's shown in object)
    • XSD (for XML export/import)
    • ODBC (returned in SQL)
  • Provide generators for utility methods. Article on some examples.

Docs.

Eduard Lebedyuk · Jul 22, 2021 go to post

Here's an example:

Class User.Assert Extends Ens.BusinessProcess [ ClassType = persistent, Language = objectscript ]
{

Method OnRequest(pRequest As Ens.Request, Output pResponse As Ens.Response) As %Status
{
    Set pResponse = ##class(Ens.Response).%New()
    
    $$$LOGINFO("$$$ASSERT(1)")
    $$$ASSERT(1) // skipped
    
    $$$LOGINFO("$$$LOGASSERT(1)")
    $$$LOGASSERT(1)
    
    $$$LOGINFO("$$$ASSERT(0)")
    $$$ASSERT(0)
    
    $$$LOGINFO("$$$LOGASSERT(0)")
    $$$LOGASSERT(0)

    Quit $$$OK
}
}
Eduard Lebedyuk · Jul 22, 2021 go to post

This looks more like a WRC issue, but I'd wager a guess that the first and second query use different indices.

To be more specific the second query does not use some index due to the need to traverse all RPE.Veterinario rows due to the vet.numConselho > 0 condition.

To solve this issue try to rebuild all indices for these 3 tables.

Eduard Lebedyuk · Jul 22, 2021 go to post

It's a special type of event which is only written to the database if the assert is false. It accepts one argument which must evaluate into 0 or 1. Check the docs for more info.

Eduard Lebedyuk · Jul 17, 2021 go to post

There are two ways to do that:

1. Mappings. Map classes and globals into the namespace you're querying from. This would work if there's no global/class collisions of course.

2. Custom queries. Here's an article on the topic. And here's an example.

3. Just set $namespace before running your query. Works only if you need to query one other namespace at a time. Example.

Eduard Lebedyuk · Jul 15, 2021 go to post

Sure, just mount C:\InterSystems\IRISHealth\mgr\samples\ folder as a docker volume.

After that add a new Database from inside the container pointing to the mounted folder.

Eduard Lebedyuk · Jul 13, 2021 go to post

Well, in that case:

ClassMethod ToNato(t) [ CodeMode = call ]
{
^S
}

And write everything in the S routine.

Eduard Lebedyuk · Jul 12, 2021 go to post

Article idea: Building IRIS images with Docker Build Mounts

From the docs on Docker Build Mounts:

RUN --mount allows you to create mounts that process running as part of the build can access. This can be used to bind files from other part of the build without copying, accessing build secrets or ssh-agent sockets, or creating cache locations to speed up your build.

This is a recent Docker feature allowing users to build compact images (since we no longer need to COPY everything inside). Try it out and write an article about it?