I'm not seeing an example of your desired result(s) ... can you share that as well?
- Log in to post comments
I'm not seeing an example of your desired result(s) ... can you share that as well?
Likely significantly faster:
SELECTCOUNT(DISTINCT SessionId)
FROM Ens.MessageHeader
WHEREID >= (SELECT TOP 1IDFROM Ens.MessageHeader WHERE TimeCreated >='2025-02-01 00:00:00.000'ORDERBY TimeCreated ASC)
ANDID <= (SELECT TOP 1IDFROM Ens.MessageHeader WHERE TimeCreated <='2025-02-28 23:59:59.999'ORDERBY TimeCreated DESC)In my crude and hasty benchmarking, twice as fast on a sampling of 2.7M message headers.
Inserting characters that are defined as HL7 delimiters to fields is likely to be problematic. It would be very helpful if you would provide an example of the source message and the desired result.
You can suspend the task via either ObjectScript or SQL.
Assuming you know the Task ID, and using 1001 as an example:
Set tsk = ##class(%SYS.Task).%OpenId(1001)
Set tsk.Suspended = 1Do tsk.%Save()or
Do##class(%SYS.Task).Suspend(1001,1)Resume the task with
Do##class(%SYS.Task).Resume(1001)Via SQL:
UPDATE %SYS.Task SET Suspended = 1WHEREID = 1001or
UPDATE %SYS.Task SET Suspended = 1WHERE TaskClass = 'Sample.Util.CreateTask'Set Suspended to 0 to re-enable the task.
Something like this should do the trick:
ClassMethod GetConnectionStatus(pItemName As%String, ByRef pStatus As%String, ByRef pState As%String) As%Status [ Language = objectscript ]
{
Set tStatement = ##class(%SQL.Statement).%New()
Set tSC = tStatement.%PrepareClassQuery("Ens.Util.Statistics","EnumerateJobStatus")
Return:$$$ISERR(tSC) tSC
Set tRS = tStatement.%Execute(pItemName)
If tRS.%SQLCODE = 0
{
Do tRS.%Next()
Set pStatus = tRS.%Get("Status")
Set pState = tRS.%Get("AdapterState")
Return$$$OK
}
Return$$$ERROR(5001,"Status not Found")
}
Call it with the status and state variables passed by reference:
Set sc=##class(My.Class).GetConnectionStatus("T_SPM_SIU",.status,.state)I assumed that she wanted to purge the messages returned by this query:
select * from Ens.MessageHeader nolock
where timecreated < '2025-02-11 00:00:00.000'
order by timecreated
If they'd already been purged, there would be no headers returned.
If you're certain that you want to have those messages purged, you can run an UPDATE query against Ens.MessageHeader using the same criteria, but setting the Status field to 4 (Discarded).
|
Status |
ID |
|
Created |
1 |
|
Queued |
2 |
|
Delivered |
3 |
|
Discarded |
4 |
|
Suspended |
5 |
|
Deferred |
6 |
|
Aborted |
7 |
|
Error |
8 |
|
Completed |
9 |
The class Ens.MessageHeader has a classmethod Purge() that deletes message headers and bodies based on the number of days to keep along with a few other criteria; those are used in an SQL query to select the set of messages to purge. That query along with the associated purge code should work as an example to see what's involved in carefully removing messages without collateral damage ... search table indices need to be maintained, for example.
There's also the Ens.Util.MessagePurge task definition that is used for scheduled purges, it has much of the same code but offers a multi-threaded purge feature that leverages the work queue.
@Enrico Parisi's solution moves the actual purge of the messages off to the scheduled Ens.Util.MessagePurge task for messages that exceed the DaysToKeep limit, as long as that is configured to delete bodies too. This is likely the safer solution and requires significantly less effort 😉
It's not recommended to do this with the included Apache web server, since it is now deprecated and will no longer be supplied with IRIS. However, you can install the Web Gateway component and configure it to use a standalone web server and enable SSL/TLS (https) on that. The documentation can be found through this link.
Does the operation have a job number in the Jobs tab on the right side of the Production page?
.png)
That should correspond to the task's process ID in Windows. You should be able to terminate it with Task Manager or the taskkill command.
Another way is to clear the target field, then copy over only the repeating values you want to keep:
.png)
The desired result:.png)
Note that the trailing parentheses were removed from the field name in the clear rule. If you don't do that, it clears the individual repetitions but leaves the delimiters in place.
That only works for Segments, Don. The request was for a method to iterate over a repeating field within a segment.
There's no GUI-based way to iterate over a repeating field in a routing rule, but you can create a custom function that will be available from the drop-down Function list in the expression editor. That can iterate over the repeating field and return whatever value you're looking to test against.
I'm pretty sure the SegType property (deprecated, should be using DocType) should be set to just "2.7:OBX".
This is hilarious! I started to add that exact feature last night but got interrupted by the dog's apparently dire need to go outside ... and that need cannot go unaddressed without unfortunate consequences.
I saw the notification of your update this morning, before I got back to work.
Again, thank you!
Thank you again, @Robert.Cemper1003. I think this thread may be a contender for the "most correct answers" award 😁
Much more readable, too. Thanks!
Hi @Robert Cemper, I had already tried subclassing %Library.String, but used the [ PropertyClass = rcc.FixStr.Props ] syntax rather than Extends.
The class compiles with your suggested change ... now to verify that it works 😉
EDIT: It does! Any idea why the PropertyClass option fails?
Looping back to this.
I thought it might be more user-friendly to define custom property parameters for this solution to specify both length (LENGTH) and alignment (ALIGN), rather than just relying on MAXLEN. I'd also of course modify the code to be generated to handle the desired formatting.
I've defined a a property parameter class with those parameters and added it as a PropertyClass to the class containing the property definition, but on compilation I get:
ERROR #5002: ObjectScript error: <UNDEFINED>Get+1^rcc.FixStr.G1 *%parameter("LENGTH")
> ERROR #5490: Error running generator for method 'Get:rcc.FixStr' What am I missing? Here's the property class:
Class rcc.FixStr.Props
{
Parameter LENGTH As%String = "10";Parameter ALIGN As%String = "LEFT";
}
And the class containing the Get() method for the property definition:
Class rcc.FixStr Extends%RegisteredObject [ PropertyClass = rcc.FixStr.Props ]
{
/// Fill value <var>%val</var> to <a href="#MAXLEN">MAXLEN</a> characters.
Method Get() As%String [ CodeMode = generator, ServerOnly = 1 ]
{
set tCode="$e(%val_"""_$j("",+%parameter("LENGTH"))
set tCode=tCode_""",1,"_+%parameter("LENGTH")_")"$$$GENERATE( " Quit "_tCode)
QUIT$$$OK
}
}
A bit late to the party, I was ...
You could write a custom method that subclasses Ens.Rule.FunctionSet and includes Ensemble.inc (may already be included by default, haven't checked). There's a $$$LOGINFO() macro available that can be invoked from a method; that method would be called in an argument to an assign rule.
Here's an example:
Include Ensemble
Class IDC.Util.FunctionSet Extends Ens.Rule.FunctionSet
{
ClassMethod LogInfo(pText As%String) As%Status
{
$$$LOGINFO(pText)
Return$$$OK
}
}
Invoke it like this (or within another expression):
.png)
And debug is definitely a more sensible option than assign. Thanks, @Enrico Parisi 😁
To add to @Enrico Parisi's point ... your next upgrade will likely undo your modifications to the %Net.SMTP class.
Since there are no ROL segments in the source message, your foreach never executes.
Just check for the existence of the ROL segment in the source, and if it doesn't exist, populate any field in a ROL segment in the target:
.png)
Are both instances on the same host, and if yes, have you set them up with instance prefixes (it looks like you have based on the screenshot). You may want to check all of your service entries in the registry and verify that they're pointing at the right instance.
And I know some of the OAuth2 artifacts are created on production start ... is at least the registry/hub running?
I ran into the same issue. I think it's related to the order in which the access gateway for the CV is activated; if you do it before setting up security (SSL/TLS) it won't register properly with the hub. I deactivated and reactivated the access gateway and that resolved the problem.
Are you looking to view the expected request and/or response? The %Net.HttpRequest Send() method has a test argument as its 3rd option; setting it to 1 outputs the request, 2 the response, and 3 the response headers.
It's unfortunate that this isn't described in the class documentation; you have to look at the source to figure out what the test argument does.
The IRIS regex functionality is built on the ICU engine, which was based on (but does not rigorously adhere to) PCRE. This includes the ObjectScript $MATCH() and $LOCATE() functions as well as the %Regex.Matcher class. A web search turns up a handful of articles and posts discussing the differences between the two.
Python has a PCRE library (python-pcre) that may help if your development effort can be transitioned in whole or part to Python.
Found the SequenceNumber Property property. Just what I needed needed!
for i = 1:1:count {w cdef.Properties.GetAt(i).Name_"|"_cdef.Properties.GetAt(i).Parameters.GetAt("MAXLEN")_"|"_cdef.Properties.GetAt(i).SequenceNumber,!}Thanks, this is useful @Nick Petrocelli! It appears that the order in which the properties are returned by iterating with Count() is sorted alphabetically. Is there any way to fetch them in the order in which they were defined in the class? I have SqlColumnNumber assigned for each of the properties, so if there's a way to fetch that keyword's value I can order them according to that. I'd prefer not to hard-code them in if possible, as the spec may change ...
Thanks!
Ooh, I like this! Thanks @Robert Cemper!