You can update your IRISHealth instance from 2019 version to 2021.
- Log in to post comments
You can update your IRISHealth instance from 2019 version to 2021.
8) is fixed in 2022.1 where UTF8 is the default.
Consider updating to InterSystems IRIS and using Native API for Python (2022.1 preview provides db-api connections, previous versions are pyODBC/JayDeBeAPI compatible).
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).
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.
Workaround is still relevant.
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
}Make code db read-only and it won't be moved as a part of Durable %SYS.
Cool.
Do you autogenerate?
Or did you actually wrote 20 000 classes?
Genuinely curious.
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.
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.
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.
Check %Client.HttpResponse.StatusCode
About that...
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.
Yes, I caught the same behavior. Looks like a bug.
Reported. Please file a wrc if you want to be notified about any changes.
Calling @Robert.Kuszewski.
Something like this?
SELECT
ID,
name,
processedDate,
processedTime
FROM MYprocesses m
WHERE NOT EXISTS ( SELECT 1
FROM MYprocesses m1
WHERE 1=1
AND m1.name=m.name
AND TO_POSIXTIME(m1.processedDate||' '||m1.processedTime, 'yyyy/mm/dd hh:mm:ss') > TO_POSIXTIME(m.processedDate||' '||m.processedTime, 'yyyy/mm/dd hh:mm:ss'))Replace TO_POSIXTIME with TO_TIMESTAMP on older versions.
If record ids are aligned with time (meaning higher id has higher processed date/time) you can simplify and speed up the query:
SELECT
ID,
name,
processedDate,
processedTime
FROM MYprocesses m
WHERE NOT EXISTS ( SELECT 1
FROM MYprocesses m1
WHERE 1=1
AND m1.name=m.name
AND m1.id>m.id)Interoperability callbacks can now be written in Python.
Class dc.DFOperation Extends Ens.BusinessOperation
{
Method OnMessage(ByRef request As Ens.StringContainer, Output response As Ens.Response) As %Status [ Language = python ]
{
import pandas
import iris
query = request.value.StringValue
response.value = iris.cls('Ens.Response')._New()
stmt = iris.sql.prepare(query)
rs = stmt.execute()
df = rs.dataframe()
iris.cls('Ens.Util.Log').LogInfo("dc.DFOperation", "OnMessage", "Dataframe load success")
return iris.cls('%SYSTEM.Status').OK()
}
}Do not use %Library.ClassDefinition, use %Dictionary.ClassDefinition instead.
Just checked XML spec and there's nothing about escaping $c(10) or $c(13).
The only symbols which must be escaped are:
You can check $zcvt - it produces the same output:
zw $zcvt("< > &" _$c(10)_$c(13)_ "TEST", "O", "XML")If you need byte for byte compatibility you'll need a custom datatype with a redefined LogicalToXSD method. Something like:
Class test.XMLString Extends %String
{
ClassMethod LogicalToXSD(%val As %String) As %String [ CodeMode = objectgenerator, ServerOnly = 1 ]
{
quit:%mode'="propertymethod" $$$OK
Do %code.WriteLine($c(9) _ "set %val = $zcvt(%val,""O"",""XML"")")
For replace=$lb("$c(10)","""
"""),$lb("$c(13)","""
""") {
Set from = $lg(replace, 1)
Set to = $lg(replace, 2)
Do %code.WriteLine($c(9) _ "set %val = $replace(%val," _ from _ ", " _ to _")")
}
Do %code.WriteLine($c(9) _ "quit %val")
Quit $$$OK
}
}Please consider providing a code sample.
219 characters:
s r=##class(%Net.HttpRequest).%New(),r.Server="pm.community.intersystems.com",r.SSLConfiguration="ISC.FeatureTracker.SSL.Config" d r.Get("/packages/zpm/latest/installer"),$system.OBJ.LoadStream(r.HttpResponse.Data,"c")Is it just a SELECT * FROM table query or is it something else?
Run the query in a Management Portal and compare the timings.
Open https://login.intersystems.com in Web browser, login and you'll get a new login command for docker.
I think this would be enough:
Set P("Globals")="%DEFAULTDB"
Set tSC=##class(Config.Namespaces).Create("%All",.P)No. %Save never throws an exception, just returns a %Status variable. In your scenario it would return an error indicating validation failure on LastName.
Class User.Person Extends %Persistent
{
Property LastName As %String(MAXLEN = 30);
/// do ##class(User.Person).Test()
ClassMethod Test()
{
set obj = ..%New()
set obj.LastName = $j("", 50)
set sc = obj.%Save()
w $System.Status.GetErrorText(sc)
}
}Results in:
ERROR #7201: Datatype value ' ' length longer than MAXLEN allowed of 30
> ERROR #5802: Datatype validation failed on property 'User.Person:LastName', with value equal to " "SELECT Name
FROM %Dictionary.CompiledIndex
WHERE PrimaryKey = 0 AND parent = 'your.class'Fascinating. Maybe we can pack a separate container with a telnet client and a web page connected to it to debug business hosts in a browser.