go to post Julius Kavay · Jan 11, 2024 In general, $extract() and $zstrip() are your friends.If you want to strip ONLY the LAST character, then use this set data="abc,," set $extract(data,*)="" write data --> abc, If you want to strip ALL (same) trailing characters, use this set remove="," set data1="abc," set data2="abc,,," set data3="abc,,-,," set data1=$zstrip(data1,">",remove) set data2=$zstrip(data2,">",remove) set data3=$zstrip(data3,">",remove) write data1 --> abc write data2 --> abc write data3 --> abc,,-
go to post Julius Kavay · Dec 21, 2023 If you know which record is locked (i.e. ^My.Global(123) ) then you can identify the locking process (and therefore the user) in a simple method Class DC.Lock Extends %RegisteredObject { /// For a given (global) reference /// return the (exclusive) locking processID and username /// /// ref: a global reference, for example: $name(^My.Global(1,2,3)) /// /// For other lock types (shared, remote) /// use the infos obtained by info_types OWNER, MODE, FLAGS and COUNTS, see /// https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_slock /// ClassMethod Who(ref) { if ^$LOCK(ref,"MODE")="X" { set pid=^$LOCK(ref,"OWNER") if pid { set job=##class(%SYS.ProcessQuery).%OpenId(pid) quit {"pid":(pid), "usr":($s(job:job.UserName,1:""))} } } else { quit {} } } } For example: set ref=$name(^My.Global(123)) lock +@ref:1 if '$test { // in case, the node is locked, // check up, by who is the node locked set who=##class(DC.Lock).Who(ref) write who.%ToJSON() --> {"pid":"2396","usr":"kav"} }
go to post Julius Kavay · Nov 29, 2023 Just a short update, the problem is fixed in IRIS 2022.1 and later versions.
go to post Julius Kavay · Nov 21, 2023 Take a look on %SYSTEM.OBJ class do $system.OBJ.Compile("your.classname") // or to compile a whole package do $system.OBJ.CompilePackage("your.package")
go to post Julius Kavay · Nov 13, 2023 /// Use the propertydefinition-class: /// Open your.classname || propertyname /// For example: set def=##class(%Dictionary.PropertyDefinition).%OpenId("Sample.Person||Name") if def write def.Type
go to post Julius Kavay · Nov 1, 2023 the above approach ist the right way. And I do not see any problem there: First, in the very first line (of the question) it's stated: "I need to develop a tool ... what data is being consumed by a certain process, ... to build an automated test scenario.", which means, this will be used during a development and/or test phase to gather informations about the touched globals (for automated tests). So the performance is not an issue. Second, the suggestion of Paul Waterman can always run, assuming the process runs with the required right and flag. One can always provide the required conditions.
go to post Julius Kavay · Oct 17, 2023 Some twenty years ago, SOAP was a hype and catchword like today ML, AI and Python are and everybody (includen me) used SOAP.At those times I used tcpTrace (https://www.pocketsoap.com/tcptrace/) for debugging. I can't you help more than that.
go to post Julius Kavay · Oct 16, 2023 Your example shows https but you try a http connection. Is this a mistake or a typo?
go to post Julius Kavay · Sep 25, 2023 Usually, you get a <COMMAND> error, if you call a (class)method as an expression but the called method does not provide a value Method SomethingErr() { write "Hello" } Method SomethingOk() { quit "Hello" } do ..SomethingErr() // this is OK do ..SomethingOK() // this is OK write ..SomethingErr() // gives a <COMMAND> error write ..SomethingOK() // is OK
go to post Julius Kavay · Sep 25, 2023 As an addition to the above said set mydir="C:\dir1\dir2\newdir" // // creates newdir ONLY if dir1 and dir2 exists write ##class(%File).CreateDirectory(mydir) // creates newdir and, IF NECESSARY, the intermediate directories dir2 and dir1 too write ##class(%File).CreateDirectoryChain(mydir)
go to post Julius Kavay · Aug 17, 2023 Some remarks: // on Linux, it's a good idea to limit the ping count set cmnd="ping -c 3 "_host // if $zeof isn't alway on, as on my systems the case is // we need two more lines set cmd="..." set old=$system.Process.SetZEOF(1) // turn $ZEOF on open cmd... ... close cmd do $system.Process.SetZEOF(old) // reset to old state
go to post Julius Kavay · Aug 17, 2023 Four short lines of Objectscript code ClassMethod Ping(host) { set cmd="ping "_host open cmd:"QR":10 for {use cmd read ans quit:$zeof use 0 write ans,!} close cmd } // some test do ##class(your.class).Ping("google.com") Pinging google.com [142.250.185.110] with 32 bytes of data: Reply from 142.250.185.110: bytes=32 time=25ms TTL=114 Reply from 142.250.185.110: bytes=32 time=26ms TTL=114 Reply from 142.250.185.110: bytes=32 time=19ms TTL=114 Reply from 142.250.185.110: bytes=32 time=19ms TTL=114 Ping statistics for 142.250.185.110: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 19ms, Maximum = 26ms, Average = 22ms
go to post Julius Kavay · Aug 5, 2023 also, you could try the $SCONVERT(s,format,endian,position) function (Format: F4)
go to post Julius Kavay · Aug 4, 2023 set name = $name(^A) for i=1:1:10 { set name = $name(@name@("TEST"_i)) } set @name=""
go to post Julius Kavay · Aug 3, 2023 Two more bytes and the problem is solved: Property refDate As %Date [InitialExpression = {$piece($horolog,",",1)}]; //.............................................^......................^
go to post Julius Kavay · Jul 27, 2023 Caution, backward $order() is always slower than forward $order(). If you need the last (hopefully few) entries, than it's OK to use a backward-$O() but running (counting) from the bottom to the top over several millions of nodes is definitely not an effective run.
go to post Julius Kavay · Jul 26, 2023 As others already wrote, write $order(^$GLOBAL("")) gives you the first global name accessible from a given namespace. Usually, this will be a percent-global (^%...) but if you want to get the first (or all) global, which resides in a given database, the do the same as above but with extended global access set dir = "^^c:\databases\mydb\" // "^^" and "the path to your CACHE/IRIS.dat file" write $order(^$|dir|GLOBAL(""))
go to post Julius Kavay · Jul 24, 2023 There are several possibilities, using WinSCP from Windows, Linux and Samba, etc. But if "using Cache codes" (Objectscript) is a requirement, then the simplest way is: open a TCP-(server)port on the one end and a TCP-(client)port on the other end, write and read the data, close the connections. Voila. The job is done. I do not see any problem there. OK, maybe you need to open those ports. And do not forget, USB-Sticks exists too ;-))
go to post Julius Kavay · Jul 18, 2023 I'm not aware of any $ISJSON() or similar named function but you can easily make your own ClassMethod IsJSON(str) { try { ret:{}.%FromJSON(str) 1 } catch e { ret:e.Code=3 0 throw e } } set a="{name:""John Doe"" " set b="{""name"":""John Doe"" }" write ##class(some.class).IsJSON(a) --> 0 write ##class(some.class).IsJSON(b) --> 1 write ##class(some.class).IsJSON() --> <UNDEFINED>zIsJSON+1^... *str
go to post Julius Kavay · Jul 15, 2023 As an addition to the above possibilities, you can ALWAYS use (assumed, you have the rights to access the database where the global lives - this is true for both of the above too) extended global access. Just one remark, this kind of access is possible but not the recommended way for creating regular classes (databases) rather to occasionally (on demand) access data from other namespace and/or namespaces. set nsp = "USER" set myvar = ^|nsp|MyGlobal(1,2,3) If there is no namespace associated with the database (where the global lives) just use the implicit namespace set dir = "^^C:\mydatabases\myfolder\" // win-world, "^^pathToTheDatabase" set dir = "^^/opt/mydatabases/myfolder/" // unix-world, write ^|dir|myglobal(1,2,3) // and, of course all other commands and functions kill ^|dir|myglobal(1) write $order(^|dir|myglobal(1,2)) set isDef = $data(^|dir|myglobal)