go to post Vitaliy Serdtsev · Jan 30, 2020 Are you sure that the "cdate" type is a string ? Maybe %Date or %PosixTime? Even if leave a string, the result is highly dependent on ExtentSize. For example, if ExtentSize=10, the plans match.
go to post Vitaliy Serdtsev · Jan 30, 2020 See Users, Roles, and Privileges. In addition, you can optionally enable auditing.
go to post Vitaliy Serdtsev · Jan 24, 2020 It should be noted that this applies not only to the try/catch block, but also to other blocks, for example: f i=1:1:2 { q 1 ; runtime error, but the line is highlighted } do { q 2 ; compilation error }while(0) while 0 { q 3 ; compilation error }
go to post Vitaliy Serdtsev · Jan 23, 2020 And more food for thought: Class dc.test [ Abstract ] { /// d ##class(dc.test).test() ClassMethod test(N As %Integer = 10) { d ..Run1(N),..Run2(N),..Run3(N),..Run4(N) } ClassMethod Run1(N As %Integer) { f i=1:1:4 { s time(i,"start")=$zh f j=1:1:N { i i=2 { s a=20 } ElseIf i=3 { s a=30 } ElseIf i=1 { s a=10 } Else { s a=-4 } } s time(i,"end")=$zh } w "If i=2: ",?12,time(2,"end")-time(2,"start")," seconds",!, "ElseIf i=3: ",?12,time(3,"end")-time(3,"start")," seconds",!, "ElseIf i=1: ",?12,time(1,"end")-time(1,"start")," seconds",!, "Else: ",?12,time(4,"end")-time(4,"start")," seconds",!! } ClassMethod Run2(N As %Integer) { f i=2,3,1,4 { s time(i,"start")=$zh f j=1:1:N s a=$case(i,1:10,2:20,3:30,:-4) s time(i,"end")=$zh } w "i=1: ",time(1,"end")-time(1,"start")," seconds",!, "i=2: ",time(2,"end")-time(2,"start")," seconds",!, "i=3: ",time(3,"end")-time(3,"start")," seconds",!, "i=4: ",time(4,"end")-time(4,"start")," seconds",!! } ClassMethod Run3(N As %Integer) { f i=1,2,3,4 { s time(i,"start")=$zh f j=1:1:N s a=$case(i,2:20,3:30,1:10,:-4) s time(i,"end")=$zh } w "i=1: ",time(1,"end")-time(1,"start")," seconds",!, "i=2: ",time(2,"end")-time(2,"start")," seconds",!, "i=3: ",time(3,"end")-time(3,"start")," seconds",!, "i=4: ",time(4,"end")-time(4,"start")," seconds",!! } ClassMethod Run4(N As %Integer) [ ProcedureBlock = 0 ] { n i,time,j,a f i=2,3,1,4 { s time(i,"start")=$zh f j=1:1:N d $case(i,1:a1,2:a2,3:a3,:a4) s time(i,"end")=$zh } w "i=1: ",time(1,"end")-time(1,"start")," seconds",!, "i=2: ",time(2,"end")-time(2,"start")," seconds",!, "i=3: ",time(3,"end")-time(3,"start")," seconds",!, "i=4: ",time(4,"end")-time(4,"start")," seconds",!! q a1 s a=10 q a2 s a=20 q a3 s a=30 q a4 s a=-4 q } } USER>d ##class(dc.test).test(1000000) If i=2: .027962 seconds ElseIf i=3: .043612 seconds ElseIf i=1: .073138 seconds Else: .068023 seconds i=1: .035705 seconds i=2: .035941 seconds i=3: .03498 seconds i=4: .033288 seconds i=1: .078231 seconds i=2: .052477 seconds i=3: .066045 seconds i=4: .07372 seconds i=1: .051371 seconds i=2: .052017 seconds i=3: .050972 seconds i=4: .052397 seconds USER>d ##class(dc.test).test(1e6) If i=2: .060933 seconds ElseIf i=3: .071999 seconds ElseIf i=1: .094509 seconds Else: .096684 seconds i=1: .058554 seconds i=2: .058182 seconds i=3: .059299 seconds i=4: .054863 seconds i=1: .09973 seconds i=2: .074734 seconds i=3: .087673 seconds i=4: .097123 seconds i=1: .082372 seconds i=2: .084538 seconds i=3: .081647 seconds i=4: .079353 seconds
go to post Vitaliy Serdtsev · Jan 23, 2020 Hi Peter. Ok. w "Time for If (i=2): ",time(2,"end")-time(2,"start")," seconds",!, "Time for ElseIf #1 (i=3): ",time(3,"end")-time(3,"start")," seconds",!, "Time for ElseIf #2 (i=1): ",time(1,"end")-time(1,"start")," seconds",!, "Time for Else (i=4): ",time(4,"end")-time(4,"start")," seconds",!! 1e6 Time for If (i=2): .030974 seconds Time for ElseIf #1 (i=3): .045126 seconds Time for ElseIf #2 (i=1): .07144 seconds Time for Else (i=4): .087353 seconds 1e9 Time for If (i=2): 28.59286 seconds Time for ElseIf #1 (i=3): 43.044261 seconds Time for ElseIf #2 (i=1): 82.277535 seconds Time for Else (i=4): 69.212718 seconds
go to post Vitaliy Serdtsev · Jan 23, 2020 I have (2019.1.1CE) this is not confirmed: f i=1:1:4 { s time(i,"start")=$zh f j=1:1:1e6 { i i=2 { s a=2 } ElseIf i=3 { s a=3 } ElseIf i=1 { s a=1 } Else { s a=0 } } s time(i,"end")=$zh } w "Time for If (i=2): ",time(1,"end")-time(1,"start")," seconds",!, "Time for ElseIf #1 (i=3): ",time(2,"end")-time(2,"start")," seconds",!, "Time for ElseIf #2 (i=1): ",time(3,"end")-time(3,"start")," seconds",!, "Time for Else (i=4): ",time(4,"end")-time(4,"start")," seconds",! Time for If (i=2): .109283 seconds Time for ElseIf #1 (i=3): .060785 seconds Time for ElseIf #2 (i=1): .08026 seconds Time for Else (i=4): .109974 seconds
go to post Vitaliy Serdtsev · Jan 23, 2020 Hi Nigel. I hasten to inform you that new classes have been added to IRIS for writing/reading streams in JSON format: %Stream.DynamicBinary, %Stream.DynamicCharacter. Here is a sample code: Class dc.test Extends (%RegisteredObject, %JSON.Adaptor) { Property string As %VarString(%JSONFIELDNAME = "longstring"); Property cs As %Stream.TmpCharacter(%JSONFIELDNAME = "cstream"); /// d ##class(dc.test).test() ClassMethod test() { #define fill(%len,%val) $tr($j("",%len)," ",%val) try{ s tmp=..%New() ; the maximum string length when exporting to JSON depends on the length of the property name s tmp.string=$$$fill($$$MaxLocalLength-($l("longstring")+5),$c(351)) $$$ThrowOnError(tmp.cs.Write($$$fill($$$MaxLocalLength,$c(355)))) $$$ThrowOnError(tmp.cs.Write($$$fill($$$MaxLocalLength,$c(354)))) w "[Export] len(string): ",$l(tmp.string),", len(cs): ",tmp.cs.Size,!! s file=##class(%Stream.FileCharacter).%New() s file.Filename="VeryBigObject.json" $$$ThrowOnError(tmp.%JSONExportToStream(file)) $$$ThrowOnError(file.%Save()) ;------------------ s dobj={}.%FromJSON(file) w "1. [Import %DynamicObject] len(longstring): ",$l(dobj.longstring),", len(cstream): ",dobj.%Get("cstream",,"stream").Size,! s obj1=..%JSONNew(dobj) w "2. [Import %RegisteredObject] len(string): ",$l(obj1.string),", len(cs): ",obj1.cs.Size,! /* The following command will generate an error (tested on IRIS 2019.1.1 CE, Unicode): ERROR: <MAXSTRING> zWrite^%Stream.TmpCharacter.1 To avoid errors, you need to fix the code in the GenImportCharacterStream method (see the patch below) */ s obj2=..%New() $$$ThrowOnError(obj2.%JSONImport(file)) w "3. [Import %RegisteredObject] len(string): ",$l(obj2.string),", len(cs): ",obj2.cs.Size,! }catch(ex) { w "ERROR: ",ex.DisplayString(),! } } /// Get an instance of an JSON enabled class.<br><br> /// /// You may override this method to do custom processing (such as initializing /// the object instance) before returning an instance of this class. /// However, this method should not be called directly from user code.<br> /// Arguments:<br> /// dynamicObject is the dynamic object with thee values to be assigned to the new object.<br> /// containerOref is the containing object instance when called from JSONImport. ClassMethod %JSONNew( dynamicObject As %DynamicObject, containerOref As %RegisteredObject = "") As %RegisteredObject [ GenerateAfter = %JSONGenerate, ServerOnly = 1 ] { #dim r As dc.test=$s($IsObject(containerOref):containerOref,1:..%New()) s r.string=dynamicObject.longstring d r.cs.CopyFrom(dynamicObject.%Get("cstream",,"stream")) q r } } Result: USER>d ##class(dc.test).test() [Export] len(string): 3641129, len(cs): 7282288 1. [Import %DynamicObject] len(longstring): 3641129, len(cstream): 7282288 2. [Import %RegisteredObject] len(string): 3641129, len(cs): 7282288 3. [Import %RegisteredObject] len(string): 3641129, len(cs): 7282288 Patch for 2019.1.1CE: Instead of $$$GENERATE(indent_" Set sc=stream.Write(%JSONObject."_$$$QN($$$jsonfieldname(propertyMap))_") If $$$ISERR(sc) Goto %JSONImportExit") need $$$GENERATE(indent_" Set testInvalidField=0, sc=stream.CopyFrom(%JSONObject.%Get(field,,""stream"")) If $$$ISERR(sc) Goto %JSONImportExit")It is possible that in version 2019.4.x has already fixed everything.
go to post Vitaliy Serdtsev · Jan 22, 2020 Can I safely read any size %GlobalBinaryStream into a %Binary? No. Any string (%Binary, %String, %VarString, etc.) has size limit of 3,6MB PS: if it's not a secret, why do you need to read from a stream to a string?
go to post Vitaliy Serdtsev · Jan 22, 2020 The example below works even in Caché: #include %systemInclude n try{ $$$AddAllRoleTemporaryInTry n $namespace s $namespace="SAMPLES" s person=##class(Sample.Person).%OpenId(1) d ##class(%ZEN.Auxiliary.altJSONProvider).%WriteJSONStreamFromObject(.stream,person,,,$$$YES,"aeloq") w "json (string): ",stream.Read($$$MaxLocalLength),!! d ##class(%ZEN.Auxiliary.altJSONProvider).%ConvertJSONToObject(stream,"Sample.Person",.obj) w "obj.Home.Street: ",obj.Home.Street ; or d $system.OBJ.Dump(obj) }catch(ex){ w "Error ", ex.DisplayString(),! }Result: USER>d ^test json (string): {"Name":"Pascal,Martin F.","SSN":"502-68-5767","DOB":43307,"Home":{"Street":"9347 Franklin Drive","City":"Denver","State":"VA","Zip":66346},"Office":{"Street":"4897 Main Blvd","City":"Miami","State":"MO","Zip":60084},"Spouse":"","FavoriteColors":[],"Age":"60"} obj.Home.Street: 9347 Franklin DriveOr use %JSON.Adaptor: Exporting and Importing
go to post Vitaliy Serdtsev · Jan 20, 2020 See also %MATCHES Example: select * from MyTable where MyFieldName %MATCHES '*[~|`]*'
go to post Vitaliy Serdtsev · Jan 17, 2020 See answer by @Brendan Bannon about TuneTable. Documentation: “Relative cost” is an integer value which is computed from many factors as an abstract number for comparing the efficiency of different execution plans for the same query. This calculation takes into account (among other factors) the complexity of the query, the presence of indices, and the size of the table(s). Relative cost is not useful for comparing two different queries. proof
go to post Vitaliy Serdtsev · Jan 17, 2020 Could you cite the test code for $$select^LVBEPVIS and run it from a VBScript program from Windows Explorer. Also give your $zv (interested primarily in 8-bit or Unicode). My test for the Caché Unicode: LVBEPVIS.MAC:select(n) s PLIST=4 s PLIST(1)="018625110" s PLIST(2)="01862511"_$c(9,233,769) s PLIST(3)="F"_$c(1)_"Female"_$c(1)_"Y" s PLIST(4)=35633 q 1test.vbs:Set AxVisM1 = CreateObject("VISM.VisMCtrl.1") AxVisM1.Server="CN_IPTCP:localhost[1972]:_system:@SYS" AxVisM1.NameSpace="USER" AxVisM1.Execute("s err="""",err=$$select^LVBEPVIS(""018625110"")") WScript.Echo AxVisM1.PLISTResult:
go to post Vitaliy Serdtsev · Jan 16, 2020 Example with one file for Windows: Class dc.test [ Abstract ] { /// d ##class(dc.test).test() ClassMethod test() { s ts=##class(%PosixTime).LogicalToUnixTime(##class(%PosixTime).CurrentUTCTimeStamp()), oldName="C:\Tmp\test", newName=oldName_$$$FormatText("a%1.txt",ts) s f=##class(%Stream.FileBinary).%New() d f.LinkToFile(oldName) s gz=##class(%Stream.FileBinaryGzip).%New() s gz.Filename=newName d gz.CopyFromAndSave(f) d ##class(%File).Delete(oldName) } }
go to post Vitaliy Serdtsev · Jan 16, 2020 I would somehow try to use solutions out of the box, for example %Compiler.COS.Refactor:ChangeClName(). In this class are many other useful methods for refactoring.
go to post Vitaliy Serdtsev · Jan 16, 2020 @Julius Kavay got a point. I will offer two more options: Class ABC.Try { /// d ##class(ABC.Try).PackageExists() ClassMethod PackageExists(package = "ABC") { ; option by Julius Kavay s list=##class(%Dictionary.PackageDefinition).GetPackageList() w ''list.Find($zcvt(package,"U")),! ; option 2 w ##class(%Library.RoutineMgr).Exists($zcvt(package,"U")_".PKG"),! ; option 3 k list d $system.OBJ.GetPackageList(.list,package) w ''$d(list),! } } USER>d ##class(ABC.Try).PackageExists("ab") 0 0 0 USER>d ##class(ABC.Try).PackageExists("abc") 1 1 1UPD: Take another look at the %Dictionary.PackageDefinitionQuery:SubPackage/FlatPackage, %ZEN.Utils:EnumeratePackages
go to post Vitaliy Serdtsev · Jan 15, 2020 In IRIS this property is hidden in contrast to Caché: Caché pvaoref IRIS pvaoref By the way this also doesn't work in IRIS anymore: Is there a way to get [ Internal, Private ] property?
go to post Vitaliy Serdtsev · Jan 14, 2020 You can solve the issue "head-on", namely, to re-convert character stream using %IO.StringStream: Class dc.test [ Abstract ] { ClassMethod test() { s char="тест", bin=$zcvt(char,"O","UTF8") w "dump char:" zzdump char w !!,"dump binary:" zzdump bin w !!,"Char:",?21,$system.Encryption.Base64Encode($system.Encryption.SHAHash(256,char)),!, "Binary:",?21,$system.Encryption.Base64Encode($system.Encryption.SHAHash(256,bin)),!! s cs=##class(%Stream.TmpCharacter).%New() d cs.Write(char) s stream=##class(%IO.StringStream).%New() s stream.CharEncoding="UTF8" ; here should be the encoding of your CSV file d stream.CopyFrom(cs) ; or d stream.CopyFrom(source.Stream) s stream.CharEncoding="Binary" /* Attention! The following code is needed to work around an error in method the SHAHashStream, since it expects "Rewind() As %Status", but class the %IO.StringStream uses "Rewind(Output pSC As %Status)" */ s bs=##class(%Stream.TmpBinary).%New() d bs.CopyFrom(stream) w "Char (stream):",?21,$system.Encryption.Base64Encode($system.Encryption.SHAHashStream(256,cs)),!, "Binary (stream):",?21,$system.Encryption.Base64Encode($system.Encryption.SHAHashStream(256,bs)),!! } }Result: dump char: 0000: 0442 0435 0441 0442 тест dump binary: 0000: D1 82 D0 B5 D1 81 D1 82 Ñ.еÑ.Ñ. Char: 2eEII+27ZRfvbZvK4XNsx7WPDb+82DymPPOAdJ0p1SQ= Binary: 409t7BLE9FmeugePMa6BOUINIbG9LXztfSKwnCB0+0g= Char (stream): 2eEII+27ZRfvbZvK4XNsx7WPDb+82DymPPOAdJ0p1SQ= Binary (stream): 409t7BLE9FmeugePMa6BOUINIbG9LXztfSKwnCB0+0g=
go to post Vitaliy Serdtsev · Jan 13, 2020 Also, I advise you to look at CacheActiveX instead of VisM, which has restrictions on the size of the transmitted data. Here is my old article on this subject: link to machine translation
go to post Vitaliy Serdtsev · Jan 13, 2020 Using PLIST PDELIM COS: #include %systemInclude main() s PLIST=2 s PLIST(1)="line 1" s PLIST(2)="multiline 1"_$$$NL_"multiline 2" q 1DELPHI: procedure TForm1.Button1Click(Sender: TObject); begin VisM.Server:='cn_iptcp:127.0.0.1[1972]:_system:@SYS'; VisM.NameSpace:='USER'; VisM.Execute('$$main^dc'); ListBox.Clear; ListBox.Items.Text:=VisM.PLIST; end; Result: line 1 multiline 1 multiline 2