Enrico Parisi · Jan 8, 2025 go to post

IMO a better option would be to create a subclass of %Net.SMTP and copy and modify the GetResponse() method code uncommenting that line.

Then use this class instead of %Net.SMTP.

This way you don't need "to mess" system classes, change system  database configuration (RW in IRISLIB) and then you have full control of the code.

Something like:

Class My.Net.SMTP Extends%Net.SMTP
{

/// Get response to mail command.  Use timeout as specified by RFC1123. 
Method GetResponse(timeout As%Integer, ByRef responseArray As%String) As%String [ Internal, Private ]
{
#define SMTPTRACE
#ifdef SMTPTRACE
#define TraceInit  try { kill^SmtpTrace } catch { set killsave=$zu(68,28,0) kill^SmtpTracedo$zu(68,28,killsave) }
#define TraceNext(%line) set^SmtpTrace($increment(^SmtpTrace))=%line_"<<"_$zb
#else#define TraceInit
#define TraceNext(%line)
#endif

#define WriteText(%text) $$$TraceNext(">>"_%text) write%text#define WriteLine(%text) $$$WriteText(%text),!
 kill responseArray
 set line=""do {
 	read line:timeout
 	elsedo..SetStatus($$$ERROR($$$SMTPTimeout)) set line=""set responseArray($increment(responseArray))=line
 	$$$TraceNext(line)
 } while$extract(line,4)="-"quit line
}

}
Enrico Parisi · Jan 8, 2025 go to post

As I suspected, in the DownloadFiles method the variable "fileName" is not (yet) defined when you use it.
In addition, in your catch method you have a Write command that "Write" invalid javascript code.

I'd suggest to change the catch code with:

} Catch ex {
    Set sc = ex.AsStatus()
    &js<..QuoteJS("Exception: "_ex.DisplayString());>
}

This way if an objectscript error you get an alert with the error details.

Then, change all reference to the "fileName" variable and use "fileList" instead before the line:

For i=1:1:$LISTLENGTH(fileArray)

This prevents <UNDEFINED> errors when referencing "fileName" variable.

Enrico Parisi · Jan 10, 2025 go to post

To my knowledge there is no Action to log an entry in the Interoperability Event Log, but it can be achieved using a custom function.

What you can do is implementing a function as documented in Defining Custom Utility Functions. 

Something like:

Class MyPackage.CustomFunctions Extends Ens.Rule.FunctionSet
{
/// Log an INFO type message in the Iteroperability Event LogClassMethod LogInfo(Message as%String) As%String
{
    $$$LOGINFO(Message)
    Quit Message
}
}

Then in your Rule add a Debug action that call/use the function:

Then, in the Business Process where the Rule is used, add the "d" flag to the RuleLogging settings:

This
way you will have your message logged in the event log AND in the rule log.

Enrico Parisi · Jan 10, 2025 go to post

Wow @Jeffrey Drumm !

It's amazing to see how we had the same idea/solution! 😂

Probably because it's a good idea/solution! 😊

Regarding the debug vs. assign action, maybe assign is easier and simpler to adopt because does not need to change RuleLogging setting that can "conflict" (mess) if more debug actions are used that are not required in production.
Using debug has the advantage to be able to disable the logging from portal/settings, if/when required.
It depends on the environment and requirements, soooo.....good we have to options! 😉

Having said that, it would be great if IRIS will add specific Action(s) to log info/warning/error in the event log.

Enrico Parisi · Jan 10, 2025 go to post

Can you provide more details on how the target class used in the DTL is defined?

Enrico Parisi · Jan 13, 2025 go to post

does it also work for global (i.e the hierarchical  data model)?

Simple answer: yes, it sure does.

Your code implementation need to use transactions (TSTART, TCOMMIT, TROLLBACK) commands to implement ACID.

Don't forget that, in the end, using Objects and/or SQL, the code executed use globals.

Using Objects and/or SQL the framework implement transaction for you, using globals you need to implement/code it.

Enrico Parisi · Jan 13, 2025 go to post

Sorry, I forgot to mention that to implement properly ACID you need transactions AND locking mechanism using LOCK command.

Enrico Parisi · Jan 13, 2025 go to post

Hi @Ashok Kumar T , you also need to use lock to properly implement ACID, something like:

LEARNING>lock +^myTracker("onSomething")
LEARNING>w^myTracker("onSomething")
1
LEARNING>ts
 
TL1:LEARNING>s^myTracker("onSomething")=12
TL1:LEARNING>w^myTracker("onSomething")
12
TL1:LEARNING>trollback
LEARNING>w^myTracker("onSomething")
1
LEARNING>lock -^myTracker("onSomething")
LEARNING>
Enrico Parisi · Jan 14, 2025 go to post

To exchange (in/out) ObjectScript collections (arrays/lists) and streams to/from Java using the new $system.external interface you use the "magical undocumented" %getall() and %setall() methods.

You can get some sample code of using it in the Open Exchange project samples-dynamicgateway-java.

For example for streams you can try something like:

w !,"TRY #"_$I(TEST)
        #Dim argc As%Stream.GlobalCharacter = ##Class(%Stream.GlobalCharacter).%New()
        do argc.Write($C(40))
        do argc.Write($C(41))
		Set bytesArrayIn=javaGate.new("byte["_argc.Size_"]")
		Do bytesArrayIn.%setall(argc)
        do test.testByteArr(bytesArrayIn)
Enrico Parisi · Jan 14, 2025 go to post

Connecting SQL Server to IRIS using ODBC connection

I think you actually describe: "Connecting IRIS to SQL Server using ODBC connection"

Enrico Parisi · Jan 16, 2025 go to post

To me it looks that the remote system (147.185.133.137) it's connecting and then disconnect before sending any data.
Maybe setting Archive IO can provide some hint, but I'm not sure what happen with Archive IO when no data is received, like seems in this case.

I would try to test/connect using something like Postman and see if it works as expected.

Please note that %GlobalCharacterStream class in deprecated in favor of %Stream.GlobalCharacter class.

I'm puzzled by the line:

That method convert an object to a stream, but in fact you are passing a stream and it seems you expect it returns an object.

Also note that this two lines:

don't do anything, you can safely remove them.

Enrico Parisi · Jan 16, 2025 go to post

You should never concatenate query parameters in the query text, instead use placeholders and parameters.

Like this:

set tQuery="SELECT ProvId, AllwOpenSchYN, IsAllwSchedYN FROM "_context.EpicClaritySerMycTable_" WHERE ProvId=? AND Market=?"set tStatement = ##class(%SQL.Statement).%New()
 set qStatus = tStatement.%Prepare(tQuery)
 set rset = tStatement.%Execute(context.ProvId,context.Market)
 do rset.%Next()
 if rset.%SQLCODE<0 { 
    $$$TRACE("SQL Query ["_tQuery_"] FAILED")
 } else {
    set tAllwOpenSchYN = rset.AllwOpenSchYN
    set tIsAllwSchedYN = rset.IsAllwSchedYN
    set tProvId = rset.ProvId
       
 }
 

Suggested reading: Dynamic SQL Best Practices

Enrico Parisi · Jan 16, 2025 go to post

Can you provide some more details?

What kind of object holds your received "File"?

Enrico Parisi · Jan 17, 2025 go to post

I doubt it's possible to change the prefix in your use case (using virtual XML doc.).

The produced xml is perfectly valid and compliant to the xds, changing the prefix makes no sense.

Enrico Parisi · Jan 17, 2025 go to post

Hi @Stephen Canzano

it's my understanding that none of the counters described in the doc page you linked is incremented using UPDATE, nor can be modified by user code/SQL.

Enrico Parisi · Jan 22, 2025 go to post

There is no such a stream you are looking for.

Data is sent to the browser (via WEB Gateway and WEB Server) as you write it from your CSP page/application, IS NOT held in a stream and sent "at the end" (what's the end BTW?).

Enrico Parisi · Feb 2, 2025 go to post

I think/guess you are using the wrong port number in vs code.

Vs code uses the web server port to connect to IRIS. What port do you use to connect to the IRIS Management Portal? Likely you are using port 80 and/or 443, the same port should be used in vs code.

Enrico Parisi · Feb 3, 2025 go to post

Please follow the documentation starting from Visual Studio Code (VS Code) Introduction

First thing to decide if you want to use client-side editing or server-side editing. server-side editing is more similar to working with InterSystems Studio.

Then, if you encounter problems, please come back and provide details on what you have done, what the problem you encountered, any error you get etc.

Enrico Parisi · Feb 3, 2025 go to post

If you want/need to keep the generated .int, then:

set sts = ##class(%Routine).CompileList("*.int","/keepsource=1")

or

set sts = ##class(%Routine).CompileList("*.int","k")

Enrico Parisi · Feb 7, 2025 go to post

To support longer then 500 lines you may use an hash instead of the actual line.

Enrico Parisi · Feb 10, 2025 go to post

What are you using to read the csv file in IRIS?

Can you provide a small sample code?

Enrico Parisi · Feb 10, 2025 go to post

That property contains the last run status of a specific task, so first you need to know what task you are interested and then open that task and get the last status, like:

Set BckTask=##class(Backup.Task).%OpenId("FullDBList")
Set status=BckTask.LastRunStatus

Enrico Parisi · Feb 10, 2025 go to post

Backup.Task is a system class located in %SYS, I'm not sure if creating a Backup.Task in another namespace (hopefully!!) address his issue.

Enrico Parisi · Feb 11, 2025 go to post

Yes, absolutely true, if you are not using an old version/product like Caché/Ensemble.

Windows VSS support was introduced few years ago, maybe with IRIS?

So, if your backup solution has VSS quiescence enabled, you can simply rely on it and you are good to go without any script/freeze/thaw. It's authomatic.

You can check messages.log file during backup, look for something like:

[Utility.Event] Backup.General.ExternalFreeze: Start a journal restore for this backup with journal file: e:\intersystems\iris\mgr\journal\20250210.004
[Utility.Event] Backup.General.ExternalFreeze: System suspended
[Generic.Event] VSS Writer: OnThaw
[Utility.Event] Backup.General.ExternalThaw: Resuming system
[Utility.Event] Backup.General.ExternalThaw: System resumed