go to post Vitaliy Serdtsev · Jun 28, 2022 Caché 5.0.21: Class DC.DemoPropertyQuery Extends %Persistent [ ClassType = persistent, ProcedureBlock ] { Property Foo As %String; Property Bar As %Boolean; ClassMethod Benchmark() { set Job=##CLASS(%SYSTEM.Process).%OpenId($job) set start = $zhorolog set startGlobalRefs = Job.GlobalReferences set startLines = Job.LinesExecuted for i=1:1:1000 { kill properties do ..GetPropertiesAsQuickly(.properties) } set endLines = Job.LinesExecuted set endGlobalRefs = Job.GlobalReferences write "Elapsed time (1000x): ",($zhorolog-start)," seconds; ",(endGlobalRefs-startGlobalRefs)," global references; ",(endLines-startLines)," routine lines",! do ..Print(.properties) write ! } ClassMethod Print(ByRef properties) { set key = "" for { set key = $order(properties(key),1,data) quit:key="" set $listbuild(type,origin) = data write !,"property: ",key,"; type: ",type,"; origin: ",origin } } ClassMethod GetPropertiesAsQuickly(Output properties) { // Getting properties via macro-wrapped direct global references is harder to read, // but is the fastest way to do it. set key = "" set class = ..%ClassName(1) for { set key = $$$comMemberNext(class,$$$cCLASSproperty,key) quit:key="" set type = $$$comMemberKeyGet(class,$$$cCLASSproperty,key,$$$cPROPtype) set origin = $$$comMemberKeyGet(class,$$$cCLASSproperty,key,$$$cPROPorigin) set properties(key) = $listbuild(type,origin) } } }Result: USER>do ##class(DC.DemoPropertyQuery).Benchmark() Elapsed time (1000x): .018047 seconds; 25003 global references; 40000 routine lines property: %Concurrency; type: %Library.CacheString; origin: %Library.Persistent property: %IsInSave; type: %Library.CacheString; origin: %Library.Persistent property: Bar; type: %Library.Boolean; origin: DC.DemoPropertyQuery property: Foo; type: %Library.String; origin: DC.DemoPropertyQuery
go to post Vitaliy Serdtsev · Jun 23, 2022 See $SYSTEM.SQL.SetServerInitCode() (there are differences for IRIS) Simple example: Class dc.test { ClassMethod Test() { s programname=$zcvt(##class(%SYS.ProcessQuery).%OpenId($j).ClientExecutableName,"L") i programname="blablabla.exe" { ;useful work s $EC="ERROR" ;or s $ROLES="r1" } } } USER>d $SYSTEM.SQL.SetServerInitCode("d ##class(dc.test).Test()")Now, when connecting from a specific program via ODBC/JDBC to namespace "USER", an error will occur. You can configure something another.
go to post Vitaliy Serdtsev · Jun 23, 2022 See Parent-Child Relationships and Storage Demonstration: Class dc.child Extends %Persistent { Property name; Property parent As dc.parent; // Relationship parent As dc.parent [ Cardinality = parent, Inverse = child ]; } Class dc.parent Extends %Persistent { Property name; // Relationship child As dc.child [ Cardinality = children, Inverse = parent ]; ClassMethod Test() { d ..%KillExtent() d ##class(child).%KillExtent() &sql(insert into dc.parent(name) values('parent1')) &sql(insert into dc.parent(name) values('parent2')) &sql(insert into dc.child(name,parent) values('child11',1)) &sql(insert into dc.child(name,parent) values('child12',1)) &sql(insert into dc.child(name,parent) values('child21',2)) &sql(insert into dc.child(name,parent) values('child22',2)) zw ^dc.parentD,^dc.childD } }USER>d ##class(dc.parent).Test() ^dc.parentD=2 ^dc.parentD(1)=$lb("","parent1") ^dc.parentD(2)=$lb("","parent2") ^dc.childD=4 ^dc.childD(1)=$lb("","child11",1) ^dc.childD(2)=$lb("","child12",1) ^dc.childD(3)=$lb("","child21",2) ^dc.childD(4)=$lb("","child22",2) Important: do not touch the existing Storages in both classes!!! Class dc.child Extends %Persistent { Property name; //Property parent As dc.parent; Relationship parent As dc.parent [ Cardinality = parent, Inverse = child ]; Storage Default { ... } } Class dc.parent Extends %Persistent { Property name; Relationship child As dc.child [ Cardinality = children, Inverse = parent ]; ClassMethod Test() { ... } Storage Default { ... } }USER>d ##class(dc.parent).Test() ^dc.parentD=2 ^dc.parentD(1)=$lb("","parent1") ^dc.parentD(2)=$lb("","parent2") ^dc.childD=4 ^dc.childD(1,1)=$lb("","child11",1) ^dc.childD(1,2)=$lb("","child12",1) ^dc.childD(2,3)=$lb("","child21",2) ^dc.childD(2,4)=$lb("","child22",2) Important: now remove Storage from dc.child class and recompile both classes. Note that now the Storage of the dc.child class has changed. USER>d ##class(dc.parent).Test() ^dc.parentD=2 ^dc.parentD(1)=$lb("","parent1") ^dc.parentD(1,"child",1)=$lb("","child11") ^dc.parentD(1,"child",2)=$lb("","child12") ^dc.parentD(2)=$lb("","parent2") ^dc.parentD(2,"child",3)=$lb("","child21") ^dc.parentD(2,"child",4)=$lb("","child22") ^dc.childD=4 ^dc.childD(1,1)=$lb("","child11",1) ^dc.childD(1,2)=$lb("","child12",1) ^dc.childD(2,3)=$lb("","child21",2) ^dc.childD(2,4)=$lb("","child22",2)Now the data in ^dc.childD from the previous test/step is hanging in the air and cannot be accessed via SQL Based on the above, the answer to your question will depend on what and how exactly you changed in your classes. PS: for simplicity, I would advise you to create a clone of your dc.child class (without Relationship) and already take the "disappeared" data from it. After linking the tables (possibly with subsequent copying of data from the old Storage to the new one), the clone with the data can be deleted.
go to post Vitaliy Serdtsev · Jun 23, 2022 See MultiValue Basic | Caché Alternative Exists for SOUNDEX() Workaround: Class dc.test [ Abstract ] { ClassMethod Test() { w ..SOUNDEX("M"),! ;or &sql(select SOUNDEX('McD') into :r) w r,! } ClassMethod SOUNDEX(s) As %String [ Language = mvbasic, SqlName = SOUNDEX, SqlProc ] { RETURN SOUNDEX(s) } } Result: USER>d ##class(dc.test).Test() M000 M230
go to post Vitaliy Serdtsev · May 17, 2022 Now on evaluation.intersystems.com for Windows/MacOSX/Container allows to download the version of IRIS 2020.1CE, and for the rest - IRIS 2021.2CE. What happened and when will the problem with downloading the latest version disappear once and for all?
go to post Vitaliy Serdtsev · May 13, 2022 It gives an incorrect result for some data, for example: Detector("abbz", "abzz") Detector("aaz", "azz") Detector("azz", "aaz")
go to post Vitaliy Serdtsev · May 13, 2022 Without loops: size = 82 (likely the code can be further reduced) ClassMethod Detector( a As %String, b As %String) As %Boolean { s a=$zu(28,a,6),b=$zu(28,b,6) q $l(a)=$l(b)&(a'=$tr(a,b,a_b))&(b'=$tr(b,a,b_a)) ;or s a=$zu(28,a,6),b=$zu(28,b,6) q $l(a)=$l(b)&(a'=$tr(a,b,a_b))&(a'=$tr(a,a_b,b)) }
go to post Vitaliy Serdtsev · May 12, 2022 I follow a simple rule: first I change the data, and only then I put the constraints in the code. Not the other way around.
go to post Vitaliy Serdtsev · May 12, 2022 This is the case when don't know whether to stop or continue.
go to post Vitaliy Serdtsev · May 12, 2022 Excellent work. You have come up with an additional optimization different from mine. Your code can be improved to 66. size = 68 ClassMethod Detector( a As %String, b As %String) As %Boolean { f i=65:1:91{q:$$r(a)'=$$r(b)} q i=91 r(x)q $l($$$UPPER(x),$c(i)) } size = 67 ClassMethod Detector( a As %String, b As %String) As %Boolean { f i=0:1:91{q:$$r(a)'=$$r(b)} q i=91 r(x)q $l($zu(28,x,6),$c(i)) } $$$ALPHAUP(x) == $zu(28,x,6) size = 66 ClassMethod Detector( a As %String, b As %String) As %Boolean { f i=90:-1:0{q:$$r(a)'=$$r(b)} q 'i r(x)q $l($zu(28,x,6),$c(i)) }
go to post Vitaliy Serdtsev · May 11, 2022 Ok. size = 190 ClassMethod Compress(s As %String) As %String { a s a=$p(s,",",$i(i)),d=$p(s,",",i+1)-a f c=1:1{q:d*c+a'=$p(s,",",i+c)} s q=$zabs(d),v=$s(c>2&d:"-"_(c-1*d+a)_$s(q=1:"",1:"/"_q),c>1&'d:"*"_c,1:0) s:v'=0 $p(s,",",i,i+c-1)=a_v q:a="" s g a } size = 189 ClassMethod Compress(s As %String) As %String { f i=1:1:2e6{s a=$p(s,",",i),d=$p(s,",",i+1)-a f c=1:1{q:d*c+a'=$p(s,",",i+c)} s q=$zabs(d),v=$s(c>2&d:"-"_(c-1*d+a)_$s(q=1:"",1:"/"_q),c>1&'d:"*"_c,1:0) s:v'=0 $p(s,",",i,i+c-1)=a_v} q s }
go to post Vitaliy Serdtsev · May 11, 2022 (And I think you may be waiting a long time for the Encoder game to close) The author seems to have forgotten or this no longer relevant. I'm not interested in opening code when there are no alternatives and there is no competitive spirit.
go to post Vitaliy Serdtsev · May 11, 2022 size = 74 ClassMethod Detector( a As %String, b As %String) As %Boolean { q $$r(a)=$$r(b) r(x)f i=65:1:90{s $li(y,i)=$l($zcvt(x,"u"),$c(i))} q y } I'm not publishing the option with size = 73 yet, to wait, maybe someone will guess how to do it or offer an ever shorter option (by analogy with Code Golf - Encoder). UPD: I managed to reduce size to 72.
go to post Vitaliy Serdtsev · May 10, 2022 Example Class dc.golf.Anagram { ClassMethod Detector( a As %String, b As %String) As %Boolean { f c="a","b"{ s @c=$zstrip($zcvt(@c,"U"),"*W") } w $$$quote(a),":",$l(a)," - ",$$$quote(b),":",$l(b),! q $tr(a,b)=$tr(b,a)&($l(a)=$l(b)) } } Output (tested on IRIS 2021.2CE): USER>w ##class(dc.golf.Anagram).Detector("apple", "pale") <UNDEFINED>zDetector+2^dc.golf.Anagram.1 *a If I change Undefined, then there is no error, but the result is incorrect: USER>d $system.Process.Undefined(2) USER>w ##class(dc.golf.Anagram).Detector("apple", "pale") "apple":5 - "pale":4 0 The code works correctly if change the signature of the method (ProcedureBlock/PublicList/new), but this is a violation of the conditions of the task.
go to post Vitaliy Serdtsev · May 4, 2022 See %ZEN.Auxiliary.jsonSQLProvider:%WriteJSONStreamFromSQL() Simple example Class dc.test Extends %Persistent { Property int As %Integer; Property str As %VarString; Property bool As %Boolean; Property Date As %Date; ClassMethod Test() { d ..%KillExtent() &sql(insert into dc.test("int",str,bool,"Date") select 30,'Hello Caché',0,current_date union select 303,'ăîşţâ',1,0 union select null,null,null,null) s stream=##class(%Stream.FileBinary).%New(), stream.Filename="c:\temp\test.json", sql="select * from dc.test", format="twu", maxRows=0 s status=##class(%ZEN.Auxiliary.jsonSQLProvider).%WriteJSONStreamFromSQL(.stream, sql, format, maxRows) d:$$$ISOK(status) stream.%Save() } } The contents of the file test.json (UTF8): { "children":[ {"ID":1,"Date":"04.05.2022","bool":0,"int":30,"str":"Hello Caché"} ,{"ID":2,"Date":"31.12.1840","bool":1,"int":303,"str":"ăîşţâ"} ,{"ID":3,"Date":"","bool":"","int":"","str":""} ] }
go to post Vitaliy Serdtsev · May 3, 2022 In Ensemble 2014, which the author indicated in his question, there are no classes %Library.DynamicObject and %Library.DynamicArray