go to post Eduard Lebedyuk · Jan 24 %Library.RoutineMgr_StudioOpenDialog is a useful query! Originally I started writing something similar, but went into %Dictionary package instead, which of course created issues for me about System and Mapped classes, so I decided to go a different way (ended with what's presented in this article). With your approach I'll advice first building a list of classes to delete and then passing it to $SYSTEM.OBJ.Delete - it will be faster than deleting classes one by one. That said usually deletions are small in number (or at least in frequency) so speed does not really matter here.
go to post Eduard Lebedyuk · Jan 13 PropertyClass is for registered objects, not datatypes themselves.
go to post Eduard Lebedyuk · Jan 10 Please open a support case with WRC. If you can provide a sample class and query triggering this error it would be very helpful.
go to post Eduard Lebedyuk · Jan 10 Thank you, Ben! LoadDir returns loaded list with extensions (.cls) but Delete accepts only wildcards without extensions. If not for that minor detail, it would be a completely trivial two-liner. But accounting for this requires some interesting $LFS/$LTS wrangling in the middle.
go to post Eduard Lebedyuk · Jan 8 If the class to delete is persistent, include the 'e' flag or '/deleteextent' qualifier to delete the extent data and extent metadata.
go to post Eduard Lebedyuk · Dec 22, 2024 Hello, @Enrico Parisi!CSP On in Virtual Hosts is not supported by Web Gateway means that Web Gateway does no request disambiguation based on a Virtual Host and will process any request passed by Apache. However, Apache does Virtual Hosts request validation and won't pass a request to a Web Gateway if there's no corresponding CSP On directive.
go to post Eduard Lebedyuk · Dec 11, 2024 1 outputs but does not send the request, so just call Send with 1 first, then with 2 to get both request and response.
go to post Eduard Lebedyuk · Nov 13, 2024 I don't think you'll get much from parallelization with * in SELECT. Calling @Benjamin De Boe
go to post Eduard Lebedyuk · Nov 11, 2024 Quick question about the port. Is it the standard port the IRIS instance is running on? Yes, 1972 is a default Super Server port. I do not need an external language server connection on the host? External language servers talk to Super Server, so in a case of IRIS to IRIS we can just talk to Super Server directly.
go to post Eduard Lebedyuk · Nov 8, 2024 Convert xml to FHIR object: Set payload=##class(HS.FHIR.DTL.vR4.Model.Resource.Organization).FromXML(FHIRxmlStream)
go to post Eduard Lebedyuk · Nov 8, 2024 Here's how to do it (sample code to transfer files over iris connection): /// Get IRIS connection object /// set iris = ##class().GetIRIS() ClassMethod GetIRIS() As %Net.DB.Iris { Set host = "host" Set port = 1972 Set ns = "%SYS" Set user = "_SYSTEM" Set pass = "***" Set connection = ##class(%Net.DB.DataSource).CreateConnection(host, port, ns, user, pass) Set iris = connection.CreateIris() Quit iris } /// Transfer one file from sourceFile to targetFile on iris connection. ClassMethod Transfer(iris As %Net.DB.Iris, sourceFile As %String, targetFile As %String) As %Status { Set sc = $$$OK Try { Set stream = ##class(%Stream.FileBinary).%New() Do stream.LinkToFile(sourceFile) Set var = "%stream" Do iris.ClassMethodVoid($classname(), "InitStream", var, targetFile) While 'stream.AtEnd { Set chunk = stream.Read($$$MaxStringLength-1000) Do iris.ClassMethodVoid($classname(), "WriteStream", var, chunk) } Do iris.ClassMethodVoid($classname(), "SaveStream", var, ##class(%File).Attributes(sourceFile)) } Catch ex{ Do ##class(%SYS.System).WriteToConsoleLog("SuperServer Copy failure in Transfer:" _ ex.DisplayString()) Throw ex } Quit sc } /// Initialize stream for subsequent write requests and place it in var. /// var must be a global variable (start form %) /// file is created or truncated if already exists ClassMethod InitStream(var As %String, file As %String) { Try { Do ##class(%File).Truncate(file) Set stream = ##class(%Stream.FileBinary).%New() Do stream.LinkToFile(file) Set @var = stream } Catch ex{ Do ##class(%SYS.System).WriteToConsoleLog("SuperServer Copy failure in InitStream: " _ ex.DisplayString()) Throw ex } } /// Wrile string into a stream initialized by InitStream ClassMethod WriteStream(var As %String, string As %String) { Try { Do $method(@var, "Write", string) } Catch ex{ Do ##class(%SYS.System).WriteToConsoleLog("SuperServer Copy failure in WriteStream: " _ ex.DisplayString()) Throw ex } } /// Save stream initialized by InitStream. /// Optionally sets file attributes. ClassMethod SaveStream(var As %String, attributes As %String = "") { Try { Set sc = $method(@var, "%Save") Set file = $property(@var, "Id") Kill @var Do:attributes'="" ##class(%File).SetAttributes(file, attributes) } catch ex { Do ##class(%SYS.System).WriteToConsoleLog("SuperServer Copy failure in Savetream: " _ ex.DisplayString()) Throw ex } } Use ClassMethodValue to get a scalar value back. Use json for complex type transfer as objects are not supported. There are other methods corresponding to APIs in other languages. Also please note that this class (technically only the callee *Stream methods but save yourself a headache and just copy the entire class) needs to be present on both nodes. Finally, remember that callee methods must produce no stdout/stderr writes, since the io is bound to the iris connection itself and it cannot disambiguate stdout.
go to post Eduard Lebedyuk · Sep 20, 2024 In that case, please consider providing sample code which demonstrates your issue.
go to post Eduard Lebedyuk · Sep 20, 2024 Great article, Ron! ICD, DSM, SNOMED, and other classifiers on Coruscant must be crazy.
go to post Eduard Lebedyuk · Sep 20, 2024 I think projecting as an attribute is enough. Here's an example: Class Utils.Message Extends (%RegisteredObject, %XML.Adaptor) { Parameter XMLNAME = "ID"; Property scope As %String(XMLPROJECTION = "ATTRIBUTE"); } DTL: Class Utils.DTL Extends Ens.DataTransformDTL { XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ] { <transform sourceClass='Ens.Request' targetClass='Utils.Message' create='new' language='objectscript' > <assign value='"Message"' property='target.scope' action='set' /> </transform> } /// do ##class(Utils.DTL).Test() ClassMethod Test() { set source = ##class(Ens.Request).%New() #dim target As Utils.Message set sc = ..Transform(source, .target) do target.XMLExportToString(.xml) w xml, ! } } Results in: >do ##class(Utils.DTL).Test() <ID scope="Message"></ID>
go to post Eduard Lebedyuk · Sep 20, 2024 My recommended approach is to call routines in a silent mode if at all possible, or to do minimal modifications to add silent mode. But here's how you can work with read using input redirection: ClassMethod Test() [ ProcedureBlock = 0 ] { set tOldIORedirected = ##class(%Device).ReDirectIO() set tOldMnemonic = ##class(%Device).GetMnemonicRoutine() set tOldIO = $io try { set str="" //Redirect IO to the current routine - makes use of the labels defined below use $io::("^"_$ZNAME) //Enable redirection do ##class(%Device).ReDirectIO(1) set x = ..MyLegacyRoutine() } catch ex { do ex.Log() } //Return to original redirection/mnemonic routine settings if (tOldMnemonic '= "") { use tOldIO::("^"_tOldMnemonic) } else { use tOldIO } do ##class(%Device).ReDirectIO(tOldIORedirected) w !,"x is: ",x,! w "Routine wrote to device: ", str //Labels that allow for IO redirection //Read Character rchr(time) quit "a" //Read a string rstr(len,time) quit "xyz" //Write a character - call the output label wchr(s) do output($char(s)) quit //Write a form feed - call the output label wff() do output($char(12)) quit //Write a newline - call the output label wnl() do output($char(13,10)) quit //Write a string - call the output label wstr(s) do output(s) quit //Write a tab - call the output label wtab(s) do output($char(9)) quit //Output label - this is where you would handle routine device output. //in our case, we want to write to str output(s) set str=str_s quit } ClassMethod MyLegacyRoutine() { read "Input x: ",x write "Hello!" return x } } It outputs: x is: xyz Routine wrote to device: Input x: Hello!