Lorenzo Scalese · Feb 3, 2023 go to post

Hi Pedro,

In addition to the reply of @Cristiano Silva ,  you can use %Dictionary.CompiledClass instead of PropertyDefinition to retrieve also properties in parents classes.

There is a query available : 

select *
from %Dictionary.CompiledClassQuery_MemberSummary('class.name','a')

See class reference

query MemberSummary(classname As %String, kind As %String)
Selects Name As %String(MAXLEN=256)

Return a list of members of this specific kind which is one of the following:

  • a - Property
  • f - Foreign key
  • i - Index
  • j - Projection
  • m - Method
  • n - Constraint
  • o - System method
  • p - Parameter
  • q - Query
  • s - Storage defintion
  • t - Trigger
  • u - Comment text block
  • x - XData
Lorenzo Scalese · Feb 10, 2023 go to post

Thank you for this very interesting post @Stefan Cronje 

You're right, for example, there are packages today useless because IRIS now provides features.

I have a package which I think should be deleted (to discuss with admin).

About OpenAPI-Suite, I use a lot of dependencies with packages owned by myself or not to avoid code duplication (for this development I make a pull request to an existing package)

A first clean, could be not shown in OpenExchange these dependencies: openapi-client-gen, openapi-server-gen, openapi-common-lib, swagger-validator-cli, swagger-converter-cli.  It's useless, peoples need the complete solution, not the dependencies.

If we create a larger community package on the "REST" topic, of course, I will contribute to the integration.

Lorenzo Scalese · Feb 11, 2023 go to post

Thank you @Stefan Cronje !

All contributions are welcome.

I will create as soon as possible a list of issues for improvement.

People who wish to contribute are welcome.

Lorenzo Scalese · Feb 13, 2023 go to post

Congratulations to all!

It was a fantastic contest!
This is the first time I have seen so many applications.

Lorenzo Scalese · Feb 14, 2023 go to post

Indeed !
The copy paste from google drive create links to my google account ...
Thank you for this report I modify that asap.

Lorenzo Scalese · Feb 15, 2023 go to post

Hi,

This would be an elegant solution rather than adding code to the "ValidateObject" method!

Lorenzo Scalese · Feb 21, 2023 go to post

Hi @Scott Roth ,

I have to search the documentation, but I remember we don't use the virtual IP to set up a mirror member.

The DR member knows who is the primary throughout the arbiter\agent.

Lorenzo Scalese · Feb 21, 2023 go to post

For adding a member, this is the IP of the first member (primary).  It's correct.
No matter the virtual IP, it's the role of the arbiter\agent to communicate who is primary in case of a switch.  

However, a virtual IP is convenient for access to your applications.

For example, with web applications: If the system switches from node A to node B, it is more convenient to use a virtual IP address.  You can use this in your web server configuration so that it always points to the primary node.

Lorenzo Scalese · Feb 25, 2023 go to post

Hello @Pietro Montorfano 

You can try to write your own export method.
Using %Library.RoutineIndex looks good.  Example to export all ".MAC" :

set tRes = ##class(%SQL.Statement).%ExecDirect(.tStmt,"select name||'.'||type as itemName  from %Library.RoutineIndex where type = ? and $Extract(name,1) <> '%'","MAC")
While tRes.%Next() {
	Do$SYSTEM.OBJ.ExportUDL(tRes.%Get("itemName"),"<dir>/"_tRes.%Get("itemName"))
}
Lorenzo Scalese · Mar 1, 2023 go to post

Hi @Scott Roth ,

The routine ZMIRROR.MAC must be installed in the namespace "%SYS" on each failover member.  It needs the IRISLIB database mounted in RW for installation.

I use ZMIRROR.MAC to execute code when a node becomes primary, in my example I just implement "NotifyBecomePrimary" label :

ZMIRROR
    Quit
    
NotifyBecomePrimary()
    New; https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GHA_mirror#GHA_mirror_set_tunable_params_zmirror_routineTry {
        
        Set ns = "MYAPPNAMESPACE"If##class(Config.Namespaces).Exists(ns) {
            JOB##class(pkg.Class).ClassMethod():(ns):2
        }
        
    } Catch(ex) { } ; just a securityQuit:$Quit1Quit

There are many events available, we can see the list on this documentation page .
What event mirror are you interested in?
 

Lorenzo Scalese · Mar 6, 2023 go to post

Hello @Kurt Hofman ,

I experienced a similar problem the last week while testing a library.

To solve it, I created the PYTHONPATH system environment variable with C:\InterSystems\IRISHealth\lib\python\Lib\site-packages\win32;C:\InterSystems\IRISHealth\lib\python\Lib\site-packages\win32\lib.
IRIS need to be restarted to consider any change in an environment variable.

Check If pythoncom39.dll and pywintypes39.dll exist in the directory C:\InterSystems\IRISHealth\lib\python\Lib\site-packages\win32. If they don't exist, copy them. I don't remember the initial directory of these dll files (maybe C:\InterSystems\IRISHealth\mgr\python\pywin32_system32).

I'm a beginner in Python, so maybe a more simple and clean solution exists...

Hope this help.

Lorenzo Scalese · Mar 8, 2023 go to post

Hi @Scott Roth ,

Ten years ago, I implement %ZSTOP routine to execute code when a job process exits or when the instance shutdown.  I removed my code, but the routine looks like this: 

%ZSTOP; User shutdown routine. Quit
SYSTEM ; Cache stoppingSet oldNs = $NamespaceTry {
		Set$Namespace = "MYAPPNAMESPACE"; Do something when stopping the instance.
	}Catch(ex) {}
	
	Set$Namespace = oldNS
    Quit
LOGIN ; a user logs out of Cache (user account or telnet)QuitJOB; JOB'd process exits. If$Namespace = "MYAPPNAMESPACE" {
		; do something when job process exits
	}
    Quit
CALLIN ; process exits via CALLIN interface. Quit
Logit(entrypoint, caller) PRIVATE ;Quit
Lorenzo Scalese · Mar 15, 2023 go to post

Hi @Iryna Mykhailova!
Thank you.  This is an interesting example for the community!

I have often used this when I need to expose data in SQL only stored in globals (without related class definition).

I like the possibility of using the stored procedure "as a table": 

ClassMethod ShowData()
{
 	Set rset = ##class(%SQL.Statement).%ExecDirect(,"SELECT * FROM Sample.Human_GetAllOlderThan(?)",65)
 	Do rset.%Display()
}

We can further filter the results with a where clause without changing the code of the custom class query.

Lorenzo Scalese · Mar 16, 2023 go to post

Thanks you for this tips @Bob Kuszewski 

Maybe the following line allows to retrieve, but I don't have Windows Docker environment to test myself:

Set ip = $SYSTEM.INetInfo.HostNameToAddr("host.docker.internal")

@Robert Cemper : If you test this line with Docker for Windows, let me know if It works or not.
Thank you.

Lorenzo Scalese · Mar 16, 2023 go to post

I agree with @Pietro Montorfano , due to the type of failure it's not possible to know the stop reason.  
Also, If it's an abnormal stop the execution of ZSTOP is not guaranteed.  

Depending on your target, maybe you can execute code on start (ZSTART routine) to clean something when the system has been stopped abnormally.  It could be identified by a trace in your application database or a scan of the messages.log

Lorenzo Scalese · Mar 16, 2023 go to post

Hello @Benjamin De Boe ,

It's great news that the performance is improved for the tune table.  Given the volume of data on some installations, a tune table could take more than 15 days.  

I hope to see a significant decrease now that we are migrating our installations to IRIS.

However, I have a few comments on the current workings.

SQL Stats are in the code, which makes it very difficult to manage.
If a table has no statistics, when the first query is run, the table tune is executed.  This is great!

However, since it is automatic and the statistics are stored in the class definition, when a developer creates a record in the table and runs a test, it will generate the stats and it will certainly end up in the repository.  We lose the benefit of the automatic execution of the tuning, but even worse we have unrepresentative statistics. 

Another problem: Even if we import the statistics after the deployment of a new version, if we update a class (bug fix), we have to remember to import the corresponding statistics.

All this requires particular vigilance.  I hope that in a future version, there will be a split between the stats and the code.  We can't really commit stats in our application repository because, from one installation to another, the stats can be different depending on how the application is used.

I am thinking of developing a tool to manage SQL statistics:
 - Comparison of production statistics with recalculated statistics on a test server (with a copy of the data).
 - Manual selectivity management for the rare cases where the tune table would not be efficient (to avoid overwriting manually modified values).
 - Identification of statistics that need to be modified in production (due to ratio change, value distribution).

I am working on an application that contains far too many tables to be able to do this work manually.

It's great to have improved the performance of the tune table as well as the documentation (I read it yesterday and it's much clearer) and I hope you will improve the system with the split stats\code.

Thank you!

Lorenzo Scalese · Jun 18, 2023 go to post

Hello @Nildo Torres ,

If the collation to install is identified, you can use the following classmethod : 

Set$Namespace = "%SYS"; Change fraw by the locale you need.Set sc = ##class(Config.NLS.Locales).Install("fraw")
Lorenzo Scalese · Jun 20, 2023 go to post

Hello, 

following the documentation of the argument yearopt  , you can do : 

Write$ZDATE($ZDATEH("13/Jun/23",8,,6),8)
6 Represent all dates in the current century with two-digit years and all other dates with four-digit years.