go to post Jenna Poindexter · Aug 23, 2019 When you installed Cache, what type of security did you specify?MinimalNormalLocked Down
go to post Jenna Poindexter · Aug 23, 2019 The following will count the number of data nodes under a given ^Location(country)USER>S G1=$NA(^Locations("Canada")) USER>S G=$E(G1,1,$L(G1)-1)USER>W G^Locations("Canada"USER>W G1^Locations("Canada")USER>F S G1=$Q(@G1) Q:G1=""!($E(G1,1,$L(G))'=G) S CT=$I(CT)USER>W CT2
go to post Jenna Poindexter · Aug 8, 2019 Hi-Heres something I did on a Windows system at one point to purge files in a directory that were older than a given time frame ClassMethod PurgeFiles(Path As %String, OlderThan As %Integer) { set Date=$zd($h-OlderThan) set cmd="forfiles /P "_Path_" /D -"_Date_" /C ""cmd /c del @path""" set sc=$zf(-1,cmd) } I'm pretty sure there is also ways to do this using something in %File or one of those classes also. I will poke around for an example there as well, but this should get you started. Jen
go to post Jenna Poindexter · Aug 8, 2019 Hi SalmaWhat do you mean by "subfolders" . Is this a CSP project?Jenna
go to post Jenna Poindexter · Aug 8, 2019 is it possible that "par1" and "par2" don't contain the values you think they do. I would start there and confirm that par1 = "2019" and par2 = "0912"Jenna
go to post Jenna Poindexter · Aug 6, 2019 Hi ThomasCan I clarify your question, what you are really looking to do is each day start a process that will delete files in a given directory that are older than some period of time?If so I may be able to help there.Jenna
go to post Jenna Poindexter · Aug 6, 2019 Hi JimmyThe short answer is that the EnsLib.File.PassthroughOperation is a special operation that can take a stream and write it out to a file. The operation expects you to pass in an instance of Ens.StreamContainer and you need to populate the Stream property which is what the PassthroughOperation is looking for.An example might be:set sc=##class(Ens.StreamContainer).%New()set stream = ##class(%Stream.GlobalCharacter).%New()do stream.Write("This is my text to go into the file")set sc.Stream=streamOnce you have done this, you can send sc as the input to your operation using ..SendRequestAsync or ..SendRequestSync, or from a BP if that is where the message is coming fromMy question is given your request message you created, what are you hoping the output in the file will look like?ThanksJenna
go to post Jenna Poindexter · Jul 17, 2019 To answer the original question. InterSystems provides detailed class documentation. For SQL tables, columns in general will map to class properties. See if this link provides what you are looking for.https://docs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cls?APP=1&LIBRARY=ENSLIB&CLASSNAME=EnsLib.HL7.Message
go to post Jenna Poindexter · Apr 25, 2019 Chris, Great tutorial. Was able to get this all working fairly easy against an InterSystems IRIS for Health environment. Looking forward to the next section.Ken
go to post Jenna Poindexter · May 3, 2018 Okay, looked at the docs more and my eyes were playing tricks on me.Looks like you cant call a routine at a tag in another namespace, but can call a routine at the top in another namespace.The syntax is:do ^|"namespace"|routineso:do ^|"SAMPLES"|YJM
go to post Jenna Poindexter · May 3, 2018 Interesting, I dont see anywhere in the docs where it would indicate that D ["SAMPLES"]YJM^YJM will workThe docs would indicate that you can do this:DO ^["SAMPLES"]Y2KHowever, that throws a SYNTX error too
go to post Jenna Poindexter · May 2, 2018 Yes, that is true, however, that doesnt allow you to execute a class method from namespace A in namespace B.When you :do ["b"]tag^routineCache actually executes tag^routine in namespace b vs the namespace you are currently in.Creating a package map for namespace a that maps a particular package from namespace b only makes that class available to namespace a. When I execute methods within the mapped class those methods are executed in namespace a and not b.
go to post Jenna Poindexter · May 2, 2018 Im pretty sure that class methods cant be called in another namespace without wrapping the method call in a call that actually switches namespaces, calls them method and then switches back.do ["namespace"]obj.method isn't supported wheredo ["namespace"]tag+offset^routineis
go to post Jenna Poindexter · Apr 28, 2018 I added an export of the ISC.JSONGlobalProcessor class which contains the Export method to the original post
go to post Jenna Poindexter · Apr 28, 2018 So a customer asked me a question about this and I decided to actually implement a mechanism to encode a global as JSON. I haven't done the opposite which would be to take the encoded json and turn it back into a global, but the reverse is pretty simple Here's the way I encode the Global as json There is a top-level object with two properties, globalName and nodes. globalName is a string and represents the actual global name, nodes is an array and contains an object for each node of the global which contains data. To ensure that non-printable characters are handled properly, I am using HTML Escaping to escape both the data and the subscript values { "globalName":"^ISCSOAP", "nodes":[{ "data":"io", "subscripts":[ ""Log"" ] }, { "data":"c:\\temp\\SOAP.log", "subscripts":[ ""Log"", ""LogFile"" ] }] } Here is an example of the class method that generates this output Class ISC.JSONGlobalProcessor [ Not ProcedureBlock ] { ClassMethod Export(GlobalRoot As %String, Output JSON As %DynamicObject) As %Status [ ProcedureBlock = 0 ] { if '$d(@GlobalRoot) quit $System.Status.Error(5001, "Nothing to export; "_GlobalRoot_" <undefined>") set root=$p(GlobalRoot,")",1,$l(GlobalRoot,")")-1),node=GlobalRoot s:root="" root=GlobalRoot set JSON=##class(%DynamicObject).%New() set JSON.globalName=$p(GlobalRoot,"(",1) set JSON.nodes=##class(%DynamicArray).%New() while $e(node,1,$l(root))=root { if $d(@node)#10 do ..addNode(node,.JSON) set node=$q(@node) } quit 1 } ClassMethod addNode(node As %String, ByRef JSON As %DynamicObject) As %Status { set nodeJSON=##class(%DynamicObject).%New() set data=@node,nodeJSON.data=##class(%CSP.Page).EscapeHTML(data) set subscripts=$p(node,"(",2,999),subscripts=$p(subscripts,")",1,$l(subscripts,")")-1) if ""'=subscripts { set nodeJSON.subscripts=##class(%DynamicArray).%New() set cp=1 for { q:cp>$l(subscripts,",") set subscript=$p(subscripts,",",cp) f { q:$l(subscript,"""")#2 set cp=cp+1,subscript=subscript_","_$p(subscripts,",",cp) } set subArray=$i(subArray),subArray(subArray)=subscript set cp=cp+1 } for i=1:1:subArray do nodeJSON.subscripts.%Push(##class(%CSP.Page).EscapeHTML(subArray(i))) } do JSON.nodes.%Push(nodeJSON) } } To call this code you can do the following set sc=##class(ISC.JSONGlobalProcessor).Export($na(^SAMPLE.PersonD),.json) Once you have the global encoded in a JSON object, you can output that JSON by: do json.%ToJSON()
go to post Jenna Poindexter · Apr 25, 2018 There are extra commands executed in order to call the class method, however the impact is negligible and the ultimate code executed is really identical assuming the method and routine code is the same Yes, Not extending %RegisteredObject will produce less code however the code you are executing will be identical.
go to post Jenna Poindexter · Apr 25, 2018 Another reason to opt for Objects over Routines is that Objects provide an automated documentation mechanism that Routines dont. All elements of a class are documented in the class documentation and the developer can add their own text documentation as well
go to post Jenna Poindexter · Apr 23, 2018 I think it really depends on your coding preferences. There are benefits to writing using Objects (CLS) and benefits to writing in (MAC) and which you use may simply depend on what your coding preferences are. Do you like to code using objects, then CLS is the way to go. Are you a procedural programmer, then (MAC) is the way to go. Using CLS, you program using objects with properties and methods. You gain the benefit of being able to access your object data via three different mechanisms, direct global access, object access, or sql. You implement methods and typically your methods are logically organized into the classes that they pertain to. You gain inheritance, XML support, JSON support, and so much more. All that said, if you come from a background of procedural programming and don't have a need or desire to work in objects, there's nothing wrong with using MAC routines.
go to post Jenna Poindexter · Jan 8, 2018 Hello- First, admittedly I'm not sure the cause to your error as I do not have access to your generated SOAP client classes, your SSL Configuration, etc. That said, I was able to implement the UPS API for the Tracking API and was able to execute without issue. To get it to work you will need to do the following. 1. Create a SSL client configuration (test it against the UPS server) to be used for SSL encryption. it does not appear that UPS provides a non encrypted connection for testing. 2. Obtain all of the wsdl files (including the additional xsd documentts that define the different types that UPS API supports. 3. Use the SOAP wizard to create a client. I used the package UPS. In the wizard, on the Step 3 page, select the option "Use unwrapped message format for document style web methods " This is critical because the SOAP wizard will not create the correct client without it checked. Once created, the following class method can be used to test your service. I just added this to my SOAP client class UPS.TrackPort ClassMethod Test(InquiryNumber As %String) As UPS.common.ResponseType { ; Setup Web Service Client and Security s ws=##class(UPS.TrackPort).%New() s ws.SSLConfiguration="SSLClient" s sechdr=##class(UPS.upss.UPSSecurity).%New() s usertoken=##class(UPS.upss.UsernameToken).%New() s usertoken.Username="myusername" s usertoken.Password="mypassword" s sechdr.UsernameToken=usertoken s acctoken=##class(UPS.upss.ServiceAccessToken).%New() s acctoken.AccessLicenseNumber="myaccessLicenseNumber" s sechdr.ServiceAccessToken=acctoken do ws.HeadersOut.SetAt(sechdr,"UPSSecurity") ; ; Setup Request set trakRequest=##class(UPS.trk.TrackRequest).%New() set trakRequest.Request=##class(UPS.common.RequestType).%New() do trakRequest.Request.RequestOption.Insert(1) set transactionReference=##class(UPS.common.TransactionReferenceType).%New() set transactionReference.CustomerContext="My Ensemble Process "_$j set trakRequest.Request.TransactionReference=transactionReference set trakRequest.InquiryNumber=InquiryNumber ; quit ws.ProcessTrack(trakRequest) } Once this is done, you can test as follows USER>s resp=##class(UPS.TrackPort).Test("1Z12345E0205271688") USER>w resp 20@UPS.trk.TrackResponse USER>zw resp resp=<OBJECT REFERENCE>[20@UPS.trk.TrackResponse] +----------------- general information --------------- | oref value: 20 | class name: UPS.trk.TrackResponse | reference count: 2 +----------------- attribute values ------------------ | (none) +----------------- swizzled references --------------- | i%Disclaimer = "" | i%Disclaimer(1) = "You are using UPS tracking service on customer integration test environment, please switch to UPS production environment once you finish the test. The URL is https://onlinetools.ups.com/webservices/Track" | r%Disclaimer = "49@%Collection.ListOfDT" <Set> | i%Response = "" | r%Response = "21@UPS.common.ResponseType" | i%Shipment = "" | i%Shipment(1) = "" | r%Shipment = "48@%Collection.ListOfObj" | r%Shipment(1) = "24@UPS.trk.ShipmentType" +----------------------------------------------------- Hope this helps