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.

Eduard Lebedyuk · May 5, 2019 go to post

Some thoughts.

1. Do not use Hungarian notation.

2. Do not use ByRef params/dynamic objects/$lists/args... as an arguments. There are two exceptions:  you don't know the number of arguments or there's more than 10 arguments.

3. Method should not parse arguments, only validate arguments. If caller passed invalid input it's caller problem. Fail fast.

4. Mandatory arguments go first.

5. If several methods have similar signatures, the order of arguments should be the same.

6. Same logical arguments in different methods should have the same names.

7. Arguments should be consistent. If you pass primitives, pass primitives everywhere. If you pass dynamic objects, pass them everywhere.

8. Return types should also be consistent.

9. If it's object methods and you pass the same optional arguments in several methods extract these arguments as a property.
 

Eduard Lebedyuk · May 5, 2019 go to post

Open JAR file with any archiver program (7zip, WinRar)and check that demo.cashreg.json.JSONValidator class exists.

I used this functionality with %Library.GlobalBinaryStream/byte[] and it worked for me. Here's a sample.

Eduard Lebedyuk · Apr 30, 2019 go to post

Thank you, @Steven Hobbs! I'll try to fix my code on LE platforms at the very least.

There are some unusual rules that must be followed if you want to get the same results as the $LISTxxx functions get in IRIS/Caché.

Is there any place I can familiarize myself with these rules?

Eduard Lebedyuk · Apr 23, 2019 go to post

You can do it with a special property class. Here's how it works:

Class Testing.PropertyClass
{
Parameter myPropName;
}

Class Testing.MyPersistentClass Extends %RegisteredObject  [ PropertyClass = Testing.PropertyClass]
{
Property p1 As %String(MAXLEN = 5, myPropName = "myPropValue");
}

But I recommend you to check RESTForms project (part1, part2), which sounds like what you're doing -automatic REST interface for persistent  classes.

It also defines property class for similar purposes.

Eduard Lebedyuk · Apr 23, 2019 go to post

Why do you want to achieve that?

You need custom datatype for that, defining your parameters:

Class Testing.String Extends %String
{
Parameter myPropName;
}

And use that as a property type:

Class Testing.PropertyParameters Extends %RegisteredObject
{
Property p1 As Testing.String(MAXLEN = 5, myPropName = "myPropValue");
}

Still, please tell us your use case.

Eduard Lebedyuk · Apr 23, 2019 go to post

You can store/access list properties same as array properties(via third table):

Property MyListProp As list Of Some.Class(SQLPROJECTION = "table/column", STORAGEDEFAULT = "list");

Note that you need first to delete class storage if any exists and either recreate or move the data to comply with the new storage.

Eduard Lebedyuk · Apr 23, 2019 go to post

You can also write a stored procedure which accepts id and returns the field you need.

Here's an example:

ClassMethod ListProp(id, prop, listprop) As %String [ SqlProc ]
{
    set ids = $classmethod(, prop _ "GetStored", id)
    quit:'$lv(ids) ""
    
    set ptr = 0
    set result = ""
    if listprop="id" {
        while $listnext(ids, ptr, value) {
            set result = result _ value
        }    
    } else {
        set propClass = $$$defMemberKeyGet($classname(),$$$cCLASSproperty,prop,$$$cPROPtype)
        while $listnext(ids, ptr, value) {
            set result = result _ $lb($classmethod(propClass, listprop _ "GetStored", $lg(value)))
        }
    }
    
    quit $lts(result)
}

Arguments:

  • id - root object id
  • prop - name of "List Of" property (in your case - Collection)
  • listprop - name of element property (in your case  name of any property from ICT.Experiments.B class)
Eduard Lebedyuk · Apr 23, 2019 go to post

Check out our webinar today! It would be about Python Gateway/ML. Also, there's ML Toolkit user group - a private GitHub repository set up as part of InterSystems corporate GitHub organization. It is addressed to the external users that are installing, learning or are already using ML Toolkit components. To join ML Toolkit user group, please send a short e-mail at the following address: MLToolkit@intersystems.com and indicate in your e-mail the following details (needed for the group members to get to know and identify you during discussions):

  • GitHub username
  • Full Name (your first name followed by your last name in Latin script)
  • Organization (you are working for, or you study at, or your home office)
  • Position (your actual position in your organization, or “Student”, or “Independent”)
  • Country (you are based in)
Eduard Lebedyuk · Apr 22, 2019 go to post

Pease consider using code formatting button to format large (multiline) code listings.

Eduard Lebedyuk · Apr 21, 2019 go to post

You need to download (and build from) release. It looks like you're using repository clone for docker build, which is not recommended.