Hello community! I have to work with queries using all kinds of methods like embedded sql and class queries. But my favorite is dynamic sql, simply because of how easy it is to manipulate them at runtime. The downside to writing a lot of these is the maintenance of the code and interacting with the output in a meaningful way.
For each defined property, query or an index, several corresponding methods would be automatically generated on a class compilation. These methods can be very useful. In this article, I would describe some of them.
How can I remove elements from $lb property? Specifically last element? $list does not work with $lb properties. $listupdate can't remove elements The only solution I found is a temp variable and $list, but isn't there something better?
I have a very simple web service that I'd like to secure via SAML Authorization with X.509 Certificates. I am, however struggling with documentation and my lack of cryptographic skills. (I do this just for educational purposes now, but need to use it in the future)
Does anyone have an example that shows how to construct a SOAP Client with adding all necessary security headers manually or point me to a decent learning resource?
One of the features I like in InterSystems ObjectScript is how you can process array transformations in a specific method or a function.
Usually when we say "process an array" we assume a very straightforward algorithm which loops through an array and does something with its entries upon a certain rule.
The trick is how you transfer an array to work with into a function.
One of the nice approaches on how to pass the information about an array is using $Name and Indirection operator.
Below you can find a very simple example which illustrates the thing.
I needed to know programmatically if last ran failed or not.
After some exploring, here's the code:
ClassMethod isLastTestOk() As %Boolean
{
set in = ##class(%UnitTest.Result.TestInstance).%OpenId(^UnitTest.Result)
for i=1:1:in.TestSuites.Count() {
#dim suite As %UnitTest.Result.TestSuite
set suite = in.TestSuites.GetAt(i)
return:suite.Status=0 $$$NO
}
quit $$$YES
}
I've seen a few password change posts, but I wasn't 100% sure it was the same process, so I am asking here. We periodically have to change the passwords for a few Cache user accounts across several servers. Is there a process/script to change these passwords without having to go into the web portal on each server? Thanks so much, and I apologize if this was covered in some of the other articles that I've run across. Just looking for the best method.
(Originally posted by @Sascha Kisser on March 11, 2014)
The following 2 classes are a component for a webcam, and a ZEN page that incorporates it. The webcam can take a snapshot and save it to Caché:
Recently I needed a classmethod that returns annotation value based on a name of a activity.
As doing it at runtime seemed inefficient, I wrote compile-time utility that iterates over all business process activities and generates relevant code.
This code could be used in a variety of situations when you need to iterate over business process activities, just add it as a secondary superclass to your BPL processes.
The class method "test" in the following code snippet sends an HTML email with an embedded image. Edit the literal strings to change the embedded image, to address, from address, subject, and body of the email.
This code snippet sends an XML request to a server and saves the response to a file. The class method "test" runs the code:
Class objectscript.postXML
{
classmethod test() {
Set HTTPRequest = ##class(%Net.HttpRequest).%New()
Set HTTPRequest.ContentType = "text/xml"
Set HTTPRequest.NoDefaultContentCharset = 1
Set HTTPRequest.Location = "ITOMCZ"
Set HTTPRequest.Server = "wph.foactive.com"
Do HTTPRequest.RemoveHeader("User-Agent")
Do HTTPRequest.RemoveHeader("Accept-Encoding")
Do HTTPRequest.RemoveHeader("Connection")
Do HTTPRequest.SetHeader("Expect","100-continue")
Set RequestXML = ##class(%Library.File).%New("c:\test.xml")
Do RequestXML.Open("RS")
Do HTTPRequest.EntityBody.CopyFrom(RequestXML)
Do RequestXML.%Close()
Do HTTPRequest.Post(HTTPRequest.Location)
Do $System.OBJ.Dump(HTTPRequest)
Do $System.OBJ.Dump(HTTPRequest.HttpResponse)
Write HTTPRequest.HttpResponse.Data.Size
Write HTTPRequest.ContentLength
Set ResponseStream = ##class(%Stream.FileBinary).%New()
// Second part is typically the file extension, i.e.: application/pdf -> pdf
Set FileType = $Piece(HTTPRequest.HttpResponse.GetHeader("CONTENT-TYPE"),"/",2)
Set ResponseStream.Filename = "C:\test."_FileType
Write ResponseStream.CopyFrom(HTTPRequest.HttpResponse.Data)
Write ResponseStream.%Save()
Do ResponseStream.%Close()
}
}
The following code walks a DOM using %XML.Node. It also prevents %XML.Writer to change whitespace. Run the code using the class method "test":
Class objectscript.walkDOM Extends %Persistent
{
ClassMethod dfs(node As %XML.Node)
{
s entrynode=node.NodeId
do {
//element nodes with one whitespacetyped child are the ones we want to change
if (node.NodeType=$$$xmlELEMENTNODE){
s snode=node.NodeId
if (node.MoveToFirstChild())
{
i ('node.MoveToNextSibling()){
i (node.NodeType=$$$xmlWHITESPACENODE){
s node.NodeType=$$$xmlTEXTNODE
s node.NodeId=snode
}
}
}
s node.NodeId=snode
}
if (node.HasChildNodes()){
d node.MoveToFirstChild()
d ..dfs(node)
}
} while (node.NodeType'="" && node.MoveToNextSibling())
s node.NodeId=entrynode
}
ClassMethod test()
{
set xml = "abcdefg<![CDATA[ ]]>"
s reader=##class(%XML.Reader).%New()
do reader.OpenString(xml)
set writer = ##class(%XML.Writer).%New()
//do some magic
d ..dfs(reader.Document)
w !,"with indent=1:",!
set writer.Indent = 1
do writer.OutputToString()
do writer.Document(reader.Document)
w writer.GetXMLString()
set writer.Indent = 0
w !,"with indent=0:",!
do writer.OutputToString()
do writer.Document(reader.Document)
w writer.GetXMLString()
}
}
I am trying to use %INLIST in SQL query using a cursor and the query fails to return results. It appears that the variable I use against %INLIST returns an empty string. All the examples I have seen use result sets and build the query as a string. Is it possible to use %INLIST in a cursor-based query? Below is a a snippet of the code I am using:
Property mylist as %String (MAXLEN="") [InitialExpression = "route1, route2, route3"];
(Originally posted to InterSystems CODE by @Dmitry Maslennikov)
The following code snippet outputs message header data in Ensemble. The class method "fetchExecute" runs the process, and the result is stored in the argument "qHandle":
(Originally posted on Intersystems CODE by @Iain Bray) The following code snippet converts all indices in a package to bitmap indices. The subroutine "test" runs the code:
EnsLib.HL7.Message.cls provides many API methods for manipulating an HL7 message. RemoveSegmentAt(), for example, can be used to remove a segment by path or index, but only one segment at a time. There may be times that you'll need to remove all segments within a group or even many groups of segments from the HL7 message. Surely you can iterate through each segment in each group and remove them one by one, but there's a much easier way.
With just one command, like below, you can remove all OBX segments in an ORU_R01 message (msg):
(Originally posted on Intersystems CODE by @Eduard Lebedyuk, 10/12/15) The following code snippet outputs all filenames in the file path "dir" in the Cache/IRIS terminal. The class method "test" runs the code:
Class eduardlebedyuk.filenamesInDir Extends %RegisteredObject
{
classmethod test() {
// replace dir with file path you want
set dir = "D:\directory"
set dir = ##class(%File).NormalizeDirectory(dir)
set file=$ZSEARCH(dir_"*")
while file'="" {
write !,file
set file=$ZSEARCH("")
}
}
}
This code snippet contains the class method "test" which sends an HTML email. Change the literal strings in the method to customize the email's from address, to address, subject, and body:
Class objectscript.sendEmail Extends %RegisteredObject
{
classmethod test() {
set m=##class(%Net.MailMessage).%New()
set m.From="user@company.com"
set m.IsHTML=1
do m.To.Insert("user@company.com")
set m.Subject="Sent by IRIS mail"
set m.Charset="iso-8859-1"
do m.TextData.Write("<HTML><HEAD><TITLE></TITLE>"_$char(13,10))
do m.TextData.Write("<META http-equiv=Content-Type content=""text/html; charset=iso-8859-2""></HEAD>"_$char(13,10))
do m.TextData.Write("<BODY><FONT face=Arial size=2>Test <B>Test</B></FONT></BODY></HTML>")
set s=##class(%Net.SMTP).%New()
set s.smtpserver="mail.company.com"
set status=s.Send(m)
}
}
This code snippet uses %ZEN.Auxiliary.jsonSQLProvider. The namespace and string of SQL can be edited for different situations. The class method "test" runs the code:
Class eduardlebedyuk.passQuestionParams
{
classmethod test(pValue = 50) {
s ns = $Namespace
zn "samples"
s tSQL = "SELECT ID, Name FROM Sample.Person WHERE Id > ?"
s tPR = ##class(%ZEN.Auxiliary.jsonSQLProvider).%New()
s tPR.sql = tSQL
s tPR.%Format = "tw"
s tPR.maxRows = 100
s tParam = ##class(%ZEN.Auxiliary.parameter).%New()
s tParam.value = pValue
d tPR.parameters.SetAt(tParam,1)
d tPR.%DrawJSON()
//d ##class(%ZEN.Auxiliary.jsonSQLProvider).%WriteJSONFromSQL(,,,,,tPR) //same thing
zn ns
}
}
(Originally posted to Intersystems CODE by @Eduard Lebedyuk, 5/13/15)
It's well-known that namespace global mapping helps us to write code independent on database storage details (Caché instance name, directory path). But sometimes we can face problems accessing an unsubscripted global which has subscript level mapping (SLM) defined. Most of such cases are evident and associated with administrative tasks that should be done on database level, but some of them can confuse even an experienced developer. Just to start: