Eduard Lebedyuk · Feb 15, 2020 go to post

Great project, @Henrique.GonçalvesDias!

Sent you a small pr.

I have three questions:

  1. Why CSP instead of REST? It doesn't seem too highload of an app, being an admin tool essentially, so I just wonder why you decided to go with CSP.
  2. Let's move filtering to the server. Currently only the last 200 messages can be retrieved.
  3. Are there any plans to add visual trace? Our default visual trace is great, but when a single session exceeds 300-500 thousands of messages it's not as responsive. So I've been searching for a enhanced tool for session viewing.
Eduard Lebedyuk · Feb 14, 2020 go to post

Check xmlStatus, it's an error:

ERROR #6237: Unexpected tag in XML input: RawMaterialThicknessUnit (ending at line 7 character 29).

You need to either specify all properties or define this parameter in both classes:

Parameter XMLIGNOREINVALIDTAG = 1;
Eduard Lebedyuk · Feb 13, 2020 go to post

Ensemble uses $$$GetLocalizedName macro to get localized settings names.

You can add caption directly:

set ^CacheMsg("EnsColumns","en-us","HelloWorld")="Hello World"

Where HelloWorld is a property name, value is a caption and en-us is a session language.

It should work like this:

ClassMethod Add()
{
    quit $$$Text("@HelloWorld@Hello World", "EnsColumns", "en-us")
}

but for me it doesn't set the global. Not sure why.

Eduard Lebedyuk · Feb 9, 2020 go to post

As other commenters have stated you can use Python Gateway to drive Python process, in that case check this article, the Data Transfer section specifically. Also join our MLToolkit@intersystems.comusergroup - it's focused on AI/ML scenarios.

I'm a user of Python Native API so I can give the following advice. There are two cases here:

  • You need to iterate the result set - in that case you may want to call %Next() and retrieve values as you go.
  • You just need a complete dataset for downstream processing (your case). In that case yes, serialization is required.  I see two ways to do that: JSON and CSV. If the size of the dataset is small you can use JSON, no problem, but (I haven't run any tests but fairly sure) CSV serialization can be faster and less CPU/Memory intensive.
Eduard Lebedyuk · Feb 8, 2020 go to post

Looks like this is not possible by default:

You can use this trivial workaround:

set nl = $c(13,10)
set replace = "*"
set search = "MRN"
&sql(DECLARE C1 CURSOR FOR
     SELECT REPLACE(%iFind.Highlight(REPLACE(Text, :nl, :replace),:search), :replace, :nl) ...

And as long as your text does not contain replace sequence it should work.

Eduard Lebedyuk · Feb 6, 2020 go to post

The reason I say this is that the method has extra parameters that don't correspond to the SQL %Fimd.Highlight SQL function.  

What do you mean? Highlight method signature:

ClassMethod Highlight(pText As %String, pSearchString As %String, pSearchOption As %String = {$$$IFSEARCHNORMAL}, pTags As %String = {$$$IFDEFAULTHLTAGS}, pLimit As %Integer = 0, pLanguage As %String = "en", Output pSC As %Status) As %String [ SqlName = Highlight, SqlProc ]

Shows that it is available in SQL context (bolded). All classmethod arguments (except sc) can be passed from SQL.

Eduard Lebedyuk · Feb 6, 2020 go to post

Try double quotes inside:

SELECT %iFind.Highlight(Text , :pSearchString , ,'<span style="background-color:yellow;">') into :results
FROM SSA_OCR.TempSearchable

I checked on my dataset and this query works for me:

SELECT *, %iFind.Highlight(Text,'hello', , '<span style="background-color:yellow;">')
FROM Test.Data
WHERE %ID %FIND search_index(TextIndex,'hello')
Eduard Lebedyuk · Feb 6, 2020 go to post

Read method does read 32000 characters by default, you can specify an amount of characters up to $$$MaxStringLength (3 641 144 characters).

If you want to set property to a stream you can do it like this:

do objInArrMain.%Set("Content", fileStreamBase64, "stream")

I'm not sure when it became available, here's a simple check code:

set stream = ##class(%Stream.TmpCharacter).%New()
do stream.Write(123)
d obj.%Set("prop", stream, "stream")

It should output:  {"prop":"123"}

One other note: you're using file streams for temporary outputs (when building fileStreamBase64), replace file stream with temp stream for better performance.

Eduard Lebedyuk · Feb 6, 2020 go to post

You should initialize the Signature object not with %New method, but with Create or Create509 method.

set sig=##class(%XML.Security.Signature).CreateX509(cert)

do sig.SetSignatureMethod($$$SOAPWSrsasha1)
Eduard Lebedyuk · Feb 6, 2020 go to post

Since ##class(%iFind.Utils).Highlight  and %iFind.Highlight  are the same method, you can pass fourth pTags argument to it:

SELECT %iFind.Highlight(Narrative,'"visibility [1-4] mile*" AND "temp* ? degrees"', , "<span>")
Eduard Lebedyuk · Feb 5, 2020 go to post

You can get columns like this:

 $$$LOGINFO("current result print: " _ result.clave)

Instead of

set printed = result.%CurrentResult.%Print()

$$$LOGINFO("current result print: "_printed)

printed value is 1 because %Print outputs data into the current device and returns %Status.

Eduard Lebedyuk · Feb 5, 2020 go to post

These particular bindings are deprecated.

Replacements are listed in the InterSystems IRIS Adoption Guide which is available in WRC (Downloads - Documents).

Eduard Lebedyuk · Feb 5, 2020 go to post

Another suggestion.

You can define a %ZSTOP routine which would automatically clear ^HITLIST global on job end.

You can also use PPG which would be automatically deleted when job ends.

Eduard Lebedyuk · Feb 4, 2020 go to post

Recommended approach - always use macros for al your GLVN needs (see: DeepSee, %Dictionary). This way reporting is easy - just open inc file and you're done.

%Compiler package contains Traveler/Visitor implementation for ObjectScript but it's not officially supported - use at your own risk.

Although the task is unfortunately unsolvable at compile-time due to the abundant meta programming, such as indirection and xecute.

In your proposed solution you can enable checkbox "Use Wildcards" in Find & Replace and search for * which is essentially everything.

Eduard Lebedyuk · Feb 4, 2020 go to post

<PROTECT> error means you can't access database in the /folder/NSOne_SRC/ directory.

Give the user required rights (at the very least R on that DB) and start a new session.

Eduard Lebedyuk · Jan 30, 2020 go to post

From InterSystems IRIS adoption guide:

Python Binding Applications using the Python Binding should migrate to PyODBC.

2019.1.1 does not have Python Native API - you'll need 2020.1 preview or 2019.2+ container release for that.

Eduard Lebedyuk · Jan 29, 2020 go to post

Have you tried sending the message to several recipients directly? Not CC but TO:

do m.To.Insert("mail1@domain.com")
do m.To.Insert("mail2@domain.com")

Or you can send the same email object to several recipients one by one:

for to = "mail1@domain.com", "mail2@domain.com" {
    do m.To.Clear()
    do m.To.Insert(to)
    set status = ..Adapter.SendMail(m)
    do:$$$ISERR(status) $system.OBJ.DisplayError(status)
}
Eduard Lebedyuk · Jan 29, 2020 go to post

cpp directory was renamed into iris-callin.

python directory should be there in your dev directory.

InterSystems IRIS also offers a brand new Python Native API.

Check out community Python Gateway - a new and easy way to interface with Python from InterSystems IRIS.

Eduard Lebedyuk · Jan 24, 2020 go to post

Here's what I came up with:

Query ClassListAll() As %SQLQuery
{
SELECT Name
FROM %Dictionary.ClassDefinition
}

Query ClassListNS(namespace) As %SQLQuery
{
SELECT Name
FROM %Dictionary.ClassDefinitionQuery_SubclassOf('%XML.Adaptor') c
WHERE 1=1
    AND EXISTS (SELECT 1
                FROM %Dictionary.ParameterDefinition
                WHERE parent = c.Name
                AND Name = 'NAMESPACE'
                AND _Default = :namespace)
}

/// Should be rewritten to return only non-empty namespaces
Query NSList() As %SQLQuery
{
SELECT DISTINCT _Default Name
FROM %Dictionary.ParameterDefinition
WHERE 1=1
    AND Name = 'NAMESPACE'
}

/// do ##class().ExportAllSchemas()
ClassMethod ExportAllSchemas()
{
    set rs = ..NSListFunc()
    while rs.%Next() {
        write "Exporting: ", rs.Name,!
        do ..ExportSchema(rs.Name)
    }
}

/// do ##class().ExportSchema()
ClassMethod ExportSchema(namespace)
{
    kill %objlasterror
    set schema=##class(%XML.Schema).%New()
    set schema.DefaultNamespace=namespace

    
    #dim empty As %Boolean = $$$YES
    #dim rs As %SQL.ISelectResult
    set rs = ..ClassListNSFunc(namespace)
    while rs.%Next() {
        set empty = $$$NO
        set sc = schema.AddSchemaType(rs.Name)
        write:$$$ISERR(sc) $System.Status.GetErrorText(sc)
    }
    if empty {
        write "Empty namespace",!
        quit
    }
    
    do ..AddImports(namespace, schema)
    
    set schema=schema.GetSchema(namespace)

    #dim writer As %XML.Writer = ##class(%XML.Writer).%New()
    set writer.NoXMLDeclaration = $$$YES
    set writer.Indent = $$$YES
    set writer.SuppressXmlns = $$$YES
    do writer.AddSchemaNamespace("s")
    do writer.OutputToFile(..NsToFullFileName(namespace))

    do writer.AddSchemaNamespace()
    do writer.AddNamespace(namespace)

    set sc = writer.DocumentNode(schema)
    write:$$$ISERR(sc) $System.Status.GetErrorText(sc)
}

ClassMethod AddImports(namespace, schema As %XML.Schema)
{
    set rs = ..NSListFunc()
    while rs.%Next() {
        set curNS = rs.Name
        continue:curNS=namespace
        do schema.DefineLocation(curNS, ..NsToLocalFileName(curNS))
    }
}

ClassMethod NsToFullFileName(namespace) As %String [ CodeMode = expression ]
{
##class(%File).SubDirectoryName($system.Util.ManagerDirectory(), "Temp", 1) _ ..NsToLocalFileName(namespace)
}

ClassMethod NsToLocalFileName(namespace) As %String [ CodeMode = expression ]
{
..NsToFileName(namespace) _ ".xsd"
}

ClassMethod NsToFileName(namespace) As %String [ CodeMode = expression ]
{
$p(namespace, "/", *-1)
}
Eduard Lebedyuk · Jan 23, 2020 go to post

Interesting article.

Note that comparison with 1 would always be the fastest regardless of where it is:

Here's your code on my PC:

Time for If: .037652 seconds
Time for ElseIf #1: .045029 seconds
Time for ElseIf #2: .057766 seconds
Time for Else: .053267 seconds

And here's a modified code with comparison to 1 third:

ClassMethod Run3()
{
    For i=1:1:4 {
        Set time(i,"start")=$zh
        For j=1:1:1000000 {
            If i=3 {
                set a=1
            } ElseIf i=2 {
                set a=1
            } ElseIf i=1 {
                set a=1
            } Else {
                set a=1
            }
        }
        Set time(i,"end")=$zh
    }
    
    W "Time for If: ",time(1,"end")-time(1,"start")," seconds",!
    W "Time for ElseIf #1: ",time(2,"end")-time(2,"start")," seconds",!
    W "Time for ElseIf #2: ",time(3,"end")-time(3,"start")," seconds",!
    W "Time for Else: ",time(4,"end")-time(4,"start")," seconds",!
}

Running this code yields these results:

Time for If: .109513 seconds
Time for ElseIf #1: .048419 seconds
Time for ElseIf #2: .029746 seconds
Time for Else: .059306 seconds

Regardless of where comparison to 1 happens it would be the fastest one.

Eduard Lebedyuk · Jan 20, 2020 go to post

Why is

select * from MyTable where MyFieldName like ‘%[^a-zA-Z0-9 !”%#$&”()*+,-./:;<=>?@]%’  

not a solution?

Eduard Lebedyuk · Jan 16, 2020 go to post

Please post query plans.

The most important  question is - are they actually taking different time to run?

Eduard Lebedyuk · Jan 16, 2020 go to post


Ok i will try that, but there's a way to check how many Java Gateways are running?   

There are either production gateways and system gateways, they are listed in SMP - System Administration - Configuration - Connectivity - Object Gateways.

Eduard Lebedyuk · Jan 16, 2020 go to post

a. Check that the JAR you import has the new code. If you build in a separate directory and then copy the JAR into a final directory it can fail as java locks loaded JAR files on OS level.

b. Try stopping all running Java Gateways before copying the JAR and running UploadJar. Do not create new gateway for every import.

c. What does

zw %objlasterror

report after (4)?