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)?

Eduard Lebedyuk · Jan 15, 2020 go to post

Create this class:

Class ABC.Try
{

/// w ##class(ABC.Try).PackageExists()
ClassMethod PackageExists(package = "ABC") As %Boolean [ CodeMode = expression ]
{
##class(%Dictionary.PackageDefinition).%ExistsId(package)
}

}

Test:

>w ##class(ABC.Try).PackageExists()
0

It also won't be available in GetPackageList

ABC.Try can also extend registered or persistent to the same effect.

Eduard Lebedyuk · Jan 15, 2020 go to post

%Dictionary.PackageDefinition does not contain all packages, only ones with immediate tables (see Solution 1).

If it did, calling %ExistsId   would be enough.

Eduard Lebedyuk · Jan 15, 2020 go to post

Adapted from @Krishnamuthu Venkatachalam  answer

ClassMethod Rename(oldClass, newClass) As %Status
{
    #dim sc As %Status = $$$OK
    
    quit:'##class(%Dictionary.ClassDefinition).%ExistsId(oldClass) $$$ERROR($$$GeneralError, "Old class does not exist")
    quit:##class(%Dictionary.ClassDefinition).%ExistsId(newClass) $$$ERROR($$$GeneralError, "New class already exists")
    
    merge ^oddDEF(newClass) = ^oddDEF(oldClass)
    $$$defClassKeySet(newClass, $$$cCLASSname, newClass) // Set class name
    $$$defClassKeyKill(newClass, $$$cCLASSstorage) // Kill old storage
    
    do UpdClsDef^%occLibrary(newClass)
    
    set sc = $system.OBJ.Compile(newClass, "/displaylog=0 /displayerror=0")
    quit:$$$ISERR(sc) sc
    
    set sc = ##class(%Dictionary.ClassDefinition).%DeleteId(oldClass)
    
    quit sc
}
Eduard Lebedyuk · Jan 14, 2020 go to post

I get this error on access:

<PRIVATE PROPERTY>

And the property is indeed marked as private.

Eduard Lebedyuk · Jan 14, 2020 go to post

To determine contents of %request, %response and %session objects you can add this to the beginning of your code

set %response.ContentType = "html"
do ##class(%CSP.Utils).DisplayAllObjects()
quit $$$OK

It would return detailed information about the request as an html page.

Eduard Lebedyuk · Jan 13, 2020 go to post

I'm out of ideas. There should not be any changes between file and character streams besides encoding.

I think you need to share a minimal sample that reproduces this error or contact the WRC.

Eduard Lebedyuk · Jan 13, 2020 go to post

What's your SubdirectoryLevels setting value?

Try to move Archive Path outside of File Path.

Eduard Lebedyuk · Jan 11, 2020 go to post

recreates the file with a randomized OriginalFilename

Recreates in the same folder?

What is the value of FilePath, WorkPath, ArchivePath, DeleteFromServer settings?

You need to solve the problem with file recreation, as specifying "binary" as a Charset setting gives you the correct hash.

Eduard Lebedyuk · Jan 10, 2020 go to post

So workspace per server and multiple namespaces per workspace?

Curiously, what do you expect from XData?

Filed.

Eduard Lebedyuk · Jan 10, 2020 go to post

When do you go look for a query plan?

Usually after monlbl indicating a problem.

How are you currently accessing query plans?  

SMP, 100%.

I think the most interesting thing to know is which query slows down the system. If there are two queries:

  • Takes a minute, runs daily
  • Takes a second, runs thousands of times per hour

I'm more interested in optimizing the second one.  SQL Runtime Statistics helps, but improvements in this area (and more visibility) would be great.

Eduard Lebedyuk · Jan 9, 2020 go to post

Could code within the unit test class set these additional fields in the new mapping table programatically?   

Sure, same as with any other object/table.

To get the Unit Test result ID anywhere in the tests call:

set id = $get(^UnitTest.Result,0)+1

Note, that I assume you're running only one test suite at a time. If that's not the case, you'll need to implement OnAfterSaveResult callback (preferable solution anyway) and ID would be available at that time as LogIndex poroperty.

looking at aggregating/classifying their results

This might be easier solved externally to unit tests themselves - by a separate task for example.

Eduard Lebedyuk · Jan 9, 2020 go to post

While the table name cannot be a query argument, you can sanitize the input using:

Write $SYSTEM.SQL.TableExists("Sample.Person")

And as far as sanitizing the table access itself - SQL access privileges should take care of that.