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 Statisticshelps, 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.

Eduard Lebedyuk · Jan 9, 2020 go to post

What do you like or dislike about using Studio or Atelier today?

Like: Studio is fast. My REPL cycle is very short.

Dislike:

  • Studio in synchronous so after every connection issue I need to restart it. REST based IDE don't have this problem and it's great.
  • Version pinning (need 2019.4 Studio to connect to 2019.4 server).

What external tools (source control, testing, etc.) do you wish you could integrate more tightly with InterSystems IRIS?

We should offer APIs, so any tool can be integrated.

Have you tried ObjectScript development with 3rd party VS Code extensions (Serenji or vscode-objectscript)?

I use VSCode extension. With direct server edit it's good. Subjectively slower that Studio but now it's comparable. 

Like: The interface is way more modern. Crossplatform.

Dislike: XDatas are unformatted. Only one server connection. No BPL editor.

Do you expect to be writing code in a web-based editor five years from now?  

Not really. Our IDEs don't take that much space. And REPL timings would go up.

Eduard Lebedyuk · Jan 9, 2020 go to post

The easiest way to do that is to create a separate table which refers to Unit Test as a property and set additional fields there.

Eduard Lebedyuk · Jan 6, 2020 go to post

For dropdowns I think the only option is to use Apache POI to generate XLSX. Here's Apache POI JGW wrapper and ObjectScript API but you'll need to extend it.

@Danny.Wijnschenklinked the post with some discussion on different options, check it out.

Eduard Lebedyuk · Jan 5, 2020 go to post

I don't think there is a way to do that.

If you check generated code for this procedure it  would be something like this:

try {
  new err, result
  set result=##class(Test.Obj).MyProc()
  return result
} catch err {
  set SQLCODE=-149
  set %msg="SQL Function TEST.OBJ_MYPROC failed with error:  SQLCODE="_err.AsSQLCODE()_",%msg="_err.AsSQLMessage()
  ztrap "SQER"
}

Maybe @Dan Pasco knows?

Eduard Lebedyuk · Jan 4, 2020 go to post

You need to throw an exception. Sample proc:

Class Test.Obj
{

/// do ##class(Test.Obj).TestFunc().%Display()
Query Test() As %SQLQuery
{
SELECT Test.Obj_MyProc()
}

ClassMethod MyProc() As %String [ SqlProc ]
{
    Set tSC = $$$ERROR($$$GeneralError, "MyMsg")
    If $$$ISERR(tSC)
    {
        Throw ##class(%Exception.SQL).CreateFromSQLCODE(-400, $System.Status.GetErrorText(tSC))
        Quit ""
    }
    Quit "OK"
}

}

And after I call the procedure, this message is returned:

do ##class(Test.Obj).TestFunc().%Display()
Expression_1
 
 
[SQLCODE: <-149>:<SQL Function encountered an error>]
[%msg: <SQL Function TEST.OBJ_MYPROC failed with error:  SQLCODE=-400,%msg=ERROR #5001: MyMsg>]
0 Rows(s) Affected
Eduard Lebedyuk · Jan 4, 2020 go to post

Either Enter or Ctrl-C would exit from the current loop. In your case Ctrl-C seems to work.