@Robert Cemper - I have verified that the query Detail does exist in 2017.2 (closest I can get) but you are spot on that it needs to be run from the %SYS namespace; I tried two other Ensemble-capable namespaces and it errored out both times.

I'm not sure I understand the class examples you have listed, but there's a possibility that you may not need to do this in a class.

Ensemble / HealthShare has a couple different ways that you can send a process output to multiple operations. The first is if you're not using any form of data translation, you can send the output right from the BP configuration screen:

 

Under the Response Target Config Names, I've selected two different targets here, and you can see that the connectivity verifies this - but I'm sending the output to more than two targets! How can that be? Simple, you can also select different targets in the Ensemble Rule Editor - this can be handy if you wanted to apply two different DTL transformations to two different targets. My example is super-simple (as in I'm not applying different rules or DTLs per target) but with multiple Send directives we can specify multiple targets:

 

You can have different rules with different constraints going to different operations - but I just added a send directive to a sample ruleset to show how to configure multiple targets - and as you can see between the two screenshots how Ensemble is sending the data to 4 different targets in two different ways.

Hope this helps!

upgrading to a version where you can safely compact/truncate

If you're not able to upgrade to a newer version, there's still the option of using the ^GBLOCKCOPY utility in the %SYS namespace. Unfortunately, you'll need downtime to use the utility but if you have databases with a high amount of free space, this will make a new copy of a database using the minimal amount of disk space. Then just replace the new database file with the old**, remount the database and Bob's your uncle!

Here's InterSystem's Documentation page for the utility:

https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GSTU_remote_gblockcopy

Hope this helps!

** P.S. If you did want to save the old database, 7zip is quite good at compressing CACHE.DAT (and IRIS.DAT) database files. Be sure to use the LZMA2 compression method as it works well with multiple threads/cores, and I usually use a 'light' compression level - Fast or Fastest if in windows, -mx=3 if in Linux/Unix.

Token,

If you saved it as generatePass.mac and compiled it, try this to generate a single password:

W $$^generatePass

and if you wanted to generate 20 passwords, you'd call it like this:

D LOTS^generatePass(20)

Hope this helps!

Julian,

I've tested the method above, and depending on a user's needs, it may not be the best fit. I've run it several times, and I've not seen a lower case character and it's really 'heavy' on the punctuation, some of which may not work well with some websites' password requirements. Here's one example:

ZZZ>W ##CLASS(%PopulateUtils).VarString(120)
%%XDY^F;="#GO=A<B89&K\ZE&3192R8J+9QFO#7J>M0+W=JW%^CL%BGO.1.W1EJ@7Z3,HS0F(<E?UIAE*+[3"CLD$"'\U

Token,

Years ago I created a password generator utility - it's by no means perfect and it's kind of 'tailored' to my use - I do prefer passwords that alternate left hand then right hand to attempt a bit easier manual typing, and even then the randomization doesn't always create a good 'mix' of characters, so I usually have the utility print 10 passwords (or more) and then I choose the 'best' for character mix, punctuation, etc. The routine could be modified for longer passwords, more/different punctuation characters, etc. It's not the _most_ secure, but it works well for my purposes. Feel free to use/modify it, but use it at your own risk. :-)

PASSWD() ; 
 LEFT,RIGHT,CENTER,LORR,I,J,PASSWD
 LEFT="QAZWSXEDCRFVTGBqazwsxedcrfvtgb234"
 RIGHT="YHNUJMIK,OL.Pyhnujmikolp789"
 CENTER="123456789*-+"
 LORR=$R(2)
 PASSWD=""
 LORR D
 . I=1:1:4 D
 . . PASSWD=PASSWD_$E(LEFT,($R($L(LEFT))+1))_$E(RIGHT,($R($L(RIGHT))+1))
 E  D
 . I=1:1:4 D
 . . PASSWD=PASSWD_$E(RIGHT,($R($L(RIGHT))+1))_$E(LEFT,($R($L(LEFT))+1))
 I=1:1:4 D
 . PASSWD=PASSWD_$E(CENTER,($R($L(CENTER))+1))
 PASSWD
 ;
LOTS(HOWMANY)
 I,J,PASSWD
 +$G(HOWMANY)=0 HOWMANY=10
 ! I=1:1:HOWMANY $$PASSWD,!
 !
 Q
 ;

To run the utility for one password, just execute this:

W $$^PASSWD

But, I generally just print 10 at a time and choose one. To do that, do the LOTS subroutine (which defaults to 10):

ZZZ>D LOTS^PASSWD
 
J3PwIQnX9*76
nzJWPFyt+31+
[[ snippage for brevity ]]

If you want more than 10, add a parameter for the number of passwords you want:

ZZZ>D LOTS^PASSWD(20)

Hope this helps!

Well, everyone has coding styles and ObjectScript offers several different styles - I could have made this prettier (to me, anyway) as I'm more accustomed to the single-letter-command and dot-loop styles... but I tried to keep this in your coding style.

My code isn't pretty - I focused more on making it (barely) functional and demonstrative of the $DATA command - this command will let you know if there's any further subscripts available in a global - documentation page is here:

https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_FDATA

Anyway, here's my code - I didn't have a chance to create a class method (again, I prefer the older styles) but just copy-paste the code center into your method and it should function. Again, it's not pretty, but it will demonstrate what you need.

If you wanted to make this more efficient, recoding this to handle subscripts recursively would be much shorter and could handle any number of subscripts, not just 3.

ZSUBFINDER ; 
 ;
    set subscript = ""
    for {
      set subscript = $order(^Book(subscript))
      quit:(subscript = "")
      set moresub = $data(^Book(subscript))
      if moresub=10 {
      set sub2=""
      for {
           set sub2 = $order(^Book(subscript,sub2))
           quit:(sub2="")
           set moresub2= $data(^Book(subscript,sub2))
           if moresub2=10 {
          set sub3=""
             for {
                 set sub3 = $order(^Book(subscript,sub2,sub3))
                 quit:(sub3="")
                 set moresub3= $data(^Book(subscript,sub2,sub3))
                 if moresub3 = 1 {
                 write !, "subscript=", subscript, ", sub2=", sub2, ", sub3=", sub3, ", value=", ^Book(subscript,sub2,sub3)
                 }
             }
           else {
             if moresub2=1 {
                     write !, "subscript=", subscript, ", sub2=", sub2, ", value=", ^Book(subscript,sub2)
             }
           }
      }
      else {
      if moresub=1 {
      write !, "subscript=", subscript, ", value=", ^Book(subscript)
      }
      }
    }
 quit

Hope this helps!

I think the function you might be looking for may be:

W $SYSTEM.Mirror.GetMemberType()

The return values are: Indeterminate, Not Member, Failover, Async, Disaster Recovery, Read-Only Reporting or Read-Write Reporting.

You can also get a lot more info than just if it's a primary or not from:

W $SYSTEM.Mirror.GetStatus()

Hope this helps!

Would this section of documentation help with your situation?

https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GJSON_create#GJSON_create_serialize_streams

(I'm aware this is from the latest documentation online, but I did confirm that this section also exists in my HealthShare 2017.2 version as well.)

That section appears to basically describe how to save the JSON to a temporary file on the filesystem, then re-open the file as an Object and access the key successfully without hitting <MAXSTRING>. Yes, I'm aware that does cause extra storage I/O, so for busy servers this could have a negative impact on I/O performance.

It looks like they also offer a possible solution changing the JSON entity to a %Stream.GlobalCharacter which can handle strings much larger than <MAXSTRING> which may help with not adding nearly so much storage I/O as the solution in the previous paragraph.

Hope this helps!

43, if you have to read in the variable. -4 if it's assumed to already be there. +4 if you need to see a carriage return between the input and the output:

R Z F I=1:1:$L(Z) S J=$E(Z,I) F K=1:1:J W J

Here's the '-4' code if you assume the Z variable has the initial integers:

F I=1:1:$L(Z) S J=$E(Z,I) F K=1:1:J W J

And, here's the +4 code to add the carriage return between input & output:

R Z W ! F I=1:1:$L(Z) S J=$E(Z,I) F K=1:1:J W J

Enjoy!

[edited to add other cases.]