Eduard Lebedyuk · May 27, 2019 go to post

What's the use case? I think it's better to keep independent tasks separate.

Anyway:

1. Create your own task class by extending %SYS.Task.Definition.

2. Program your task

  • Specify TaskName parameter to provide readable task name
  • Add class properties if needed - they are task arguments
  • Override OnTask method to program your logic

3. Create a new task, choosing your task class (by TaskName).

Eduard Lebedyuk · May 24, 2019 go to post

1. Execute this query:

SELECT ID FROM %SYS.ProcessQuery WHERE LastGlobalReference [ '1119102928'

2. Iterate over result set. ID is process ID.

3. Kill process by id:

do $system.Process.Terminate(processId)
Eduard Lebedyuk · May 21, 2019 go to post

It's better to not create lists, especially lists which you need to filter later.

Write a SQL query, iterate over it results and do stuff you need to do right there.

SQL Query can be a separate class element for readability purposes.

Eduard Lebedyuk · May 21, 2019 go to post

1. I'd like to add to @Nicole Aaron answer, that moving code is done in two separate steps:

  • On developer machine the code is created, written to files and commited into source control system
  • CI/CD server (in your case TFS) is triggered on repository push and executes CI script - which is OS-level commands in our particular case and would be the same between GitLab or TFS.
Eduard Lebedyuk · May 21, 2019 go to post

Interesting questions.

  1. There are several ways to achieve clean and pseudo-clean builds:
    • Containers. Clean builds every time. Next articles in the series explore how containers can be used for CI/CD.
    • Hooks. Curently I implemented one-time and every-time hooks before and after build. They can be used to do deletion, configuration, etc.
    • Recreate. Add action to delete before build:
      • DBs
      • Namespaces
      • Roles
      • WebApps
      • Anything else you created
  2. I agree with @Ben Spead here. System default settings are the way to go. If you're working outside of  Ensemble architecture, you can create a small settings class which gets the data from global/table and use that. Example.
Eduard Lebedyuk · May 21, 2019 go to post

Thank you, ended up extracting this method:

ClassMethod GetPrivateProp(oref, propName) As %String
{
    Set value = ""
    Set cd=$system.CLS.DumpContext(oref,0)
    Set inst=$piece(cd,"^",8)
    For j=1:1:inst {
        Set pd=$system.CLS.Property(j,oref,0)
        Set ivar=$piece(pd,"^")
        CONTINUE:ivar'=propName
        Set slot=$piece(pd,"^",2)
        Set value = $zobjval(oref,slot,0,3,slot)
        Quit
    }
    
    Quit value
}

UPD: Simplified code, thanks to @Dmitry Maslennikov suggestion:

ClassMethod GetPrivateProp(oref, propName) As %String
{
    Set pd=$system.CLS.Property(propName,oref,0)
    Set slot=$piece(pd,"^",2)
    Set value = $zobjval(oref,slot,0,3,slot)
    Quit value
}
Eduard Lebedyuk · May 20, 2019 go to post

1. I definitely recommend using CLS and not XML for general readability and also sane blame/diff output.

2. There should not be any differences to usual Git development (as described in the series of articles you mention). One of our customers is using TFS for Ensemble development. Are you using Studio or Atelier? VSCode? If Studio, you'll need a source control hook, Atelier works as is and you'll need a plugin for VS Code.

3.Check this article for info on CI/CD on TFS.

Eduard Lebedyuk · May 20, 2019 go to post

Exception still can contain some useful info, so:

    #dim tSC As %Status = $$$OK
    ...
    try {
        set tJSON = {}.%FromJSON(pInput)
    } Catch ex {
        do ex.Log()
        set tempSC = $$$ERROR($$$GeneralError,"Badly formed JSON")
        set tSC = $$$ADDSC(tempSC, ex.AsStatus())
    }

    quit tSC
Eduard Lebedyuk · May 19, 2019 go to post

I'd also recommend to remove or change this line:

if ($$$ISERR(tStatus)) quit

because your method signature has a promise to return a %Status:

Method OnProcessInput(pInput As %FileCharacterStream, pOutput As %RegisteredObject) As %Statu

however above mentioned line quits nothing.

You can rewrite it like this (to return status):

if $$$ISERR(tStatus) quit tStatus

or my personal preference like this using postconditionals:

quit:$$$ISERR(tStatus) tStatus

Well in this exact case you need to remove the line altogether because you no longer get status for ReadLine, but it's just some food for thought.

Eduard Lebedyuk · May 16, 2019 go to post

If you use InterSystems IRIS 2019.2 you can extend from %JSON.Adaptor class, which is similar to XML adaptor and allows property parameters to customize serialization behaviour. In your case 

%JSONINCLUDE=NONE

  %ZEN.Auxiliary.jsonProvider skips % and private properties with some flags. You can use that.

Eduard Lebedyuk · May 15, 2019 go to post

No. Each Business Host job is a separate process. They can share data with each other by sending request/response messages to each other.

Eduard Lebedyuk · May 13, 2019 go to post

You need to specify where you want to send your request. Something like this should work.

Method OnD03Alert(req As User.Alert, Output resp As Ens.StreamContainer) As %Status
{
    #Dim sc As %Status = $$$OK      
    #Dim test As %Integer = 0
    
    Set httprequest = ##class(%Net.HttpRequest).%New()   
    Set httprequest.Server =  "www.usamobility.net"
    Set httprequest.Location = "cgi-bin/wwwpage.exe"
    
    Do httprequest.SetParam("PIN", ..PIN)
    Do httprequest.SetParam("MSSG", "motogplay")
    
    Set sc = httprequest.Post(, test, $$$NO)
    
    If $$$ISOK(sc) {
        Set stream = httprequest.HttpResponse.Data
        Set resp = ##class(Ens.StreamContainer).%New(stream)
    }
    Quit sc
}

Also Ensemble operations must return persistent objects so I replaced string with Ens.StreamResponse.

Eduard Lebedyuk · May 9, 2019 go to post

It somewhat defeats the purpose of $zf(-100).

Parametrized commands are generally better.

Eduard Lebedyuk · May 7, 2019 go to post

SQL is rather static and wants to be resolved at compile time.

What do you want to achieve?

You can have a classmethod that returns resultset(s). Check Sample.Person for example.

Eduard Lebedyuk · May 6, 2019 go to post

1) Yes.

2) Use zwrite command for debugging and key access to get individual values:

zwrite tSettings
set value = tSettings("MySettingName")

Note, that if you want production host settings, you'll need to use GetHostSettings method from the same class.