go to post Eduard Lebedyuk · Mar 7, 2022 Ah, no. Won't work without parenthesis. For example "0Z" would return true instead of false.
go to post Eduard Lebedyuk · Mar 7, 2022 That was about my idea too. Clever trick getting rid of the parenthesis!
go to post Eduard Lebedyuk · Mar 5, 2022 Write a classmethod: ClassMethod GetStatus(dbFolder) As %String { new $namespace set $namespace = "%SYS" set db = ##class(SYS.Database).%OpenId(dbFolder) quit db.GetStatus() } And call it from Python.
go to post Eduard Lebedyuk · Mar 5, 2022 GetStatus is available in 2017.1 but it's an instance method, not a class method, so you can't call it this way. You need to wrap it in a class method.
go to post Eduard Lebedyuk · Mar 3, 2022 You can update your IRISHealth instance from 2019 version to 2021.
go to post Eduard Lebedyuk · Mar 1, 2022 Consider updating to InterSystems IRIS and using Native API for Python (2022.1 preview provides db-api connections, previous versions are pyODBC/JayDeBeAPI compatible).
go to post Eduard Lebedyuk · Mar 1, 2022 Well, sure. When you execute python script at the beginning add this: import sys sys.path.append(r'C:\Temp') Or set PYTHONPATH variable (requires IRIS restart).
go to post Eduard Lebedyuk · Feb 28, 2022 1. Open <IRIS>\CSP\bin\CSP.ini 2. Edit Username/Password in [LOCAL] section. 3. Using Management Portal or ^SECURITY routine set the same user as (2) if they do not match. 4. Restart InterSystems IRIS.
go to post Eduard Lebedyuk · Feb 28, 2022 Can shorten to: /// Change database permissions /// <ul> /// <li><var>dbDir</var> Path to the database.</li> /// <li><var>mode</var> Permission mode. 0 = read/write, 1 = read-only. Optional</li> /// </ul> ClassMethod SetupDBPermissions(dbDir as %String, mode as %Integer = 0) As %Status { New $NAMESPACE Set $NAMESPACE = "%SYS" Set sc = $$$OK Set db = ##class(SYS.Database).%OpenId(dbDir) Write "Setting database permission for " _ db.Directory _ ". Setting ReadOnly from " _ db.ReadOnly _ " to " _ mode, ! Set db.ReadOnly = mode $$$ThrowOnError(db.%Save()) Return sc }
go to post Eduard Lebedyuk · Feb 25, 2022 Make code db read-only and it won't be moved as a part of Durable %SYS.
go to post Eduard Lebedyuk · Feb 23, 2022 Cool. Do you autogenerate? Or did you actually wrote 20 000 classes? Genuinely curious.
go to post Eduard Lebedyuk · Feb 23, 2022 You have a lucky design without indices. That makes life with 2 distinct globals easy. I though you have a common index for current and archive versions. I guess I misunderstood your point. A simple MERGE ^archive(....)=^source(....) just doesn't maintain any index. I think the biggest issue is that it can store only one (previous) version. Or if you merge: merge ^archive(id, ts) = ^source(id) you'll need a custom storage for a composite id key.
go to post Eduard Lebedyuk · Feb 23, 2022 Okay, why would you want to index active versions and old versions together? In my design I explicitly create indices for the active version only. Old versions are only indexed on the parent field.
go to post Eduard Lebedyuk · Feb 21, 2022 I'm using a modified second approach. 1. Create a base abstract class with all properties: Class model.PersonBase Extends (%XML.Adaptor, %JSON.Adaptor) [ Abstract ] { Property Name; } 2. Create persistent class: Class model.Person Extends (%Persistent, model.PersonBase, Utils.Copyable { /// Indices, fkeys and relationships go here } Utils.Copyable allows easy copy/compare. 3. Create snapshot class: Class model.PersonSnapshot Extends (%Persistent, model.PersonBase, Utils.Copyable) { Index parentIndex On parent; /// Creation timestamp (UTC) Property createdOn As %TimeStamp(POPORDER = -1, XMLPROJECTION = "NONE") [ InitialExpression = {$ZDATETIME($ZTIMESTAMP, 3, 1, 3)}, Required ]; Property parent As model.Person(XMLPROJECTION = "NONE"); Method %OnNew(parentId As %Integer) As %Status [ Private, ServerOnly = 1 ] { #dim sc As %Status = $$$OK set ..parent = ##class(model.Person).%OpenId(parentId,, .sc) if $$$ISERR(sc) quit sc quit ..copyFrom(..parent, ##class(model.PersonBase).%ClassName(1)) } } And done. This way you can add a snapshot of object at any point of time and by calling compareTo calculate a diff between any two versions. There's also a hash function you can use to calculate hash from some or all object properties to speed up equivalence checks.
go to post Eduard Lebedyuk · Feb 21, 2022 Use calculated properties for one offs: Property "status_code" As %Status(XMLPROJECTION = "none"); Property "status_code_xml" As %VarString(XMLNAME = "status_code") [ SqlComputeCode = {set {*} = $System.Status.GetErrorText({"status_code"}}, SqlComputed, Transient ]; Custom datatypes if it's a repeatable issue.