go to post Eduard Lebedyuk · May 5 Use io operations like write, zwrite, zzdump - they would be written to an output file automatically, if set.
go to post Eduard Lebedyuk · May 2 Would canonicalization work for you? Also consider storing your xmls as gzipped streams (%Stream.GblChrCompress) or compressed strings ($system.Util.Compress). I think it will be more effective as a storage space saving strategy.
go to post Eduard Lebedyuk · May 1 Looks like a bug. Please check with WRC. Simplified your example a bit: Class DC.ValueOfThis Extends %RegisteredObject { /// do ##class(DC.ValueOfThis).Test() ClassMethod Test() { write $zv,!! set obj=..%New() do obj.Work() write $$$FormatText("classmethod: $this %1, ..Value() %2", $this, ..Value()),! do obj.Work() } Method Work() { write $$$FormatText("method: $this %1, ..Value() %2", $this, ..Value()),! } ClassMethod Value() { quit $this } }
go to post Eduard Lebedyuk · Apr 25 Here's a sample zzdump custom function for DTL: Class Utils.Functions Extends Ens.Util.FunctionSet { /// w ##class(Utils.Functions).ZZDUMP("abc") ClassMethod ZZDUMP(var) As %String { set id = $random(100000000000000000) while $d(^ISC.AsyncQueue(id)) { set id = $random(100000000000000000) } set str = "" try { $$$TOE(sc, ##class(%Api.Atelier.v1).MonitorBeginCapture(id)) if '$data(var) { write "<UNDEFINED>" } else { if '$isobject(var) { zzdump var } else { if var.%IsA(##class(%DynamicAbstractObject).%ClassName(1)) { zzdump var.%ToJSON() } elseif var.%IsA(##class(%Stream.Object).%ClassName(1)) { do var.Rewind() zzdump var.Read() } elseif var.%IsA(##class(EnsLib.HL7.Message).%ClassName(1)) { zzdump var.OutputToString() } else { // zzdump will output OREF string. zw var } } } $$$TOE(sc, ##class(%Api.Atelier.v1).MonitorEndCapture(id)) for i=1:1:^ISC.AsyncQueue(id,"cout","i") { set str = str _ ^ISC.AsyncQueue(id,"cout",i) _ $$$NL } } catch ex { do ##class(%Api.Atelier.v1).MonitorEndCapture(id) } kill ^ISC.AsyncQueue(id) quit str } }
go to post Eduard Lebedyuk · Apr 24 It's probably not a whitespace, but some other character, use zzdump to check out which character you're getting, after that you can use $translate or $zstrip to remove/replace this character.
go to post Eduard Lebedyuk · Apr 23 Direct set still works (must be executed in %SYS): set ^SYS("Portal","UsersD",$username,"Community")=$lb("","https://community.intersystems.com")
go to post Eduard Lebedyuk · Apr 23 Awesome! You might also need %JSONFIELDNAME with an original property name for json parsing/emitting.
go to post Eduard Lebedyuk · Apr 22 set myjson = myobj.%Get("myjson",,"json") That's convenient! Thank you for sharing it.
go to post Eduard Lebedyuk · Apr 22 If that is okay, please give me the wrc#, I'm interested too. Looked through the sources, but still no idea what's going on here.
go to post Eduard Lebedyuk · Apr 22 Try: set result = $SYSTEM.SQL.Execute("CALL osuwmc_Utils_EnterpriseDirDb.InterfaceCheckConnectMedCtrID('$Get(MedCtrID)')") set rs = result.%NextResult() while rs.%Next(){ set Loc = rs.Get("OSUguestRoleDTL") } Maybe you'll need to call %NextResult() twice.
go to post Eduard Lebedyuk · Apr 17 Any valid alphanumeric section name will work. For example: Class Utils.BO Extends Ens.BusinessOperation { Property MySetting; Parameter SETTINGS = "MySetting:My Custom Category"; } Will create a new My Custom Category for this business host: Settings names can be localized by following this guide (categories too probably, but I haven't tried). Domain would be Ensemble.
go to post Eduard Lebedyuk · Apr 14 I think you can guarantee that the picked list would: Provide the fullest possible coverage of numbers Skip at least fully superfluous lists And do it in O(2n) where n is list count (assuming lists are of similar length). Before anything, zero-init a list for each number (called a number list). You'll need to do two passes over your lists. On a first pass, check each list value against your number list. If at least one corresponding value in a number list is a zero (meaning our current list has a number we did not encounter before), add the list to the result and increment each position in a number list that is present in a current list by 1. In our case: Numbers: 0, 0, 0, 0, 0, 0, 0, 0, 0 List(1)="3,5,6,7,9" As Numbers(3)==0, we add List(1) to the output and modify Numbers: Numbers: 0, 0, 1, 0, 1, 1, 1, 0, 1 In a similar vein, we iterate all our lists (and add all of them, actually); our Numbers after the first pass should look like this: Numbers: 1, 2, 1, 2, 2, 3, 2, 2, 4 Lists: 1, 2, 3, 4, 5 Now do a second pass, only over lists added on a first pass. If every element in a list has a value >1 in a number list, remove the list and decrease the corresponding number list by 1. List(1)="3,5,6,7,9" Numbers: 1, 2, 1, 2, 2, 3, 2, 2, 4 Numbers(3)==1, so this list remains. List(2)="1,2,6,9" Numbers(1)==1, so this list remains. List(3)="5,8,9" Numbers(5)==2>1, Numbers(8)==2>1, Numbers(5)==4>1, so we are removing this list, new numbers: Numbers: 1, 2, 1, 2, 1, 3, 2, 1, 3 List(4)="2,4,6,8" Numbers(8)==1, so this list remains. List(5)="4,7,9" Numbers(4)==2>1, Numbers(7)==2>1, Numbers(9)==3>1, so we are removing this list, new numbers: Numbers: 1, 2, 1, 1, 1, 3, 1, 1, 2 Lists: 1, 2, 4 This, however, does not guarantee that it's a minimum amount of lists, but entirely superfluous lists would be removed, and all possible numbers would be present (have at least one reference in a number list). Another way I thought it could be resolved is by transposing the lists into numbers like this: Number(1)=$lb(2)Number(2)=$lb(2, 4)Number(3)=$lb(1)Number(4)=$lb(4, 5)Number(5)=$lb(1, 3)Number(6)=$lb(1, 2, 4)Number(7)=$lb(1, 5)Number(8)=$lb(3, 4)Number(9)=$lb(1, 2, 3, 5) After that is done, any number with just one reference must be picked (meaning it's present in only one list). In our case, numbers 1 and 3, resulting in picking lists 2 and 1. All numbers in lists 1 and 2 must also be picked: 1, 2, 3, 5, 6, 7, 9 Next, we delete Numbers that we already picked, leaving us with: Number(4)=$lb(4, 5)Number(8)=$lb(3, 4) From the remaining Numbers, we need to remove lists that we already picked (so 1 and 2), but in your example, they are not present anyway. However, after this cleanup, we might encounter a situation where a number is present in only one list. In that case, the first step needs to be redone again until we arrive at a situation where no number is present only in one list, so in our case: Number(4)=$lb(4, 5)Number(8)=$lb(3, 4) After that, pick a list with the largest amount of different numbers - 4 in our case and repeat from the beginning. Eventually, you'll arrive at empty Numbers local, meaning the task is complete.
go to post Eduard Lebedyuk · Apr 14 Starting from 2024.1 IRIS Native disallows routine invocations. Please use class methods instead. For reference, these changes can be identified as DP-422635 and DP-424156.
go to post Eduard Lebedyuk · Mar 10 In the main method of EnsLib.HTTP.OutboundAdapter - SendFormDataArray line 5 you can see the following code: #; Create an Http Request Object Set tHttpRequest=$S($$$IsdefObject(pHttpRequestIn):pHttpRequestIn,1:##class(%Net.HttpRequest).%New()) $$$ASSERT($IsObject(tHttpRequest)&&tHttpRequest.%IsA("%Net.HttpRequest")) Which creates a new empty %Net.HttpRequest object, unless pHttpRequestIn (3rd arg) has been passed with a custom request object. Most wrapper methods (VERB, VERBURL and VERBFormDataArray) do not pass pHttpRequestIn so you should get a fresh request object every time, but SendFormData and SendFormDataURL would pass pHttpRequestIn from caller, if given. Another place to look into is a Send call: Set tSC=tHttpRequest.Send($ZCVT(pOp,"U"),$G(pURL,..URL),..#DEBUG) It has the following signature: Method Send(type As %String, location As %String, test As %Integer = 0, reset As %Boolean = 1) As %Status reset arg defaults to 1, and when it's true the Reset method of %Net.HttpRequest is called after every request. Reset method removes headers (among other things). As you can see in the implementation: Kill i%Headers,i%FormData,i%Params EnsLib.HTTP.OutboundAdapter never calls Send with reset=0, so the request should be reset every time. That said, how do you call SendFormDataArray? I took a look at the article you linked to. Can you add logging to GetRequest method? It should be called on every business operation message.
go to post Eduard Lebedyuk · Mar 6 Hello. I agree it works great for ObjectScript code, but it sits at an empy method invocation unfortunately. And I need not even my method, but library calls.