go to post Roger Merchberger · Mar 25, 2022 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!
go to post Roger Merchberger · Mar 24, 2022 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() ; N LEFT,RIGHT,CENTER,LORR,I,J,PASSWD S LEFT="QAZWSXEDCRFVTGBqazwsxedcrfvtgb234" S RIGHT="YHNUJMIK,OL.Pyhnujmikolp789" S CENTER="123456789*-+" S LORR=$R(2) S PASSWD="" I LORR D . F I=1:1:4 D . . S PASSWD=PASSWD_$E(LEFT,($R($L(LEFT))+1))_$E(RIGHT,($R($L(RIGHT))+1)) E D . F I=1:1:4 D . . S PASSWD=PASSWD_$E(RIGHT,($R($L(RIGHT))+1))_$E(LEFT,($R($L(LEFT))+1)) F I=1:1:4 D . S PASSWD=PASSWD_$E(CENTER,($R($L(CENTER))+1)) Q PASSWD ; LOTS(HOWMANY) N I,J,PASSWD I +$G(HOWMANY)=0 S HOWMANY=10 W ! F I=1:1:HOWMANY W $$PASSWD,! W ! 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!
go to post Roger Merchberger · Feb 24, 2022 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!
go to post Roger Merchberger · Nov 5, 2021 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!
go to post Roger Merchberger · Oct 18, 2021 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!
go to post Roger Merchberger · Oct 8, 2021 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.]
go to post Roger Merchberger · Sep 20, 2021 Brandon, All may not be lost; you may just need a different (smaller) FOIA database. Indian Health Service uses an offshoot of the VA's VistA Database which IHS calls RPMS (Resource and Patient Management System). As IHS is a government entity, they also have to release a FOIA version of their database, and last I checked it's around 4G, which should allow you to run it under the free release of IRIS. I will warn you - a lot of the menus will look different and there's a lot of added / modified functionality due to the database customization to bring it inline for the needs of the Native American population, but the core is still VistA and can still be used free as a learning tool. To download it, go here: https://www.ihs.gov/rpms/applications/ftp/ and click on the FOIA link to see the .zip downloads. The most recent version was released on 03 March 2021. Oh, and for some reason, Firefox on Linux tries to download the .zip as a .pdf, so either use Chrome or download it and manually change the extension back to .zip to extract the database. Hope this helps!
go to post Roger Merchberger · Aug 9, 2021 The 31-character limitation is there in 2018 (I'm using 2017 for this demonstration) - although anything longer doesn't technically error out, only the first 31 characters are recognized. A quick demo I pulled from a test server: NAME>s ^HH.LookupLabResultsToPhysiciansD(0)="fluffy" NAME>zw ^HH.LookupLabResultsToPhysiciansD ^HH.LookupLabResultsToPhysicians(0)="fluffy" NAME>s ^HH.LookupLabResultsToPhysiciansDoTryToDemonstrateLongGlobalNames(0)="More Fluffy" NAME>zw ^HH.LookupLabResultsToPhysiciansDoNoFluffy ^HH.LookupLabResultsToPhysicians(0)="More Fluffy" I underlined the characters that are 'ignored' - you can see on the ZWRITE command that the last 'D' (or anything after it) isn't displayed, and you can type all sorts of characters after that final 'D' and it still changes the 'base' 31-character global. InterSystems probably put that check in because folks were using longer global names thinking all of the characters were significant, but some data was getting changed inadvertently. Does that help?
go to post Roger Merchberger · Aug 6, 2021 Give the ^rINDEX global a look. I made a QTEST routine in Studio, and saved it but did not compile it. QTEST ; JUST A TEST. Q EN ; JUST A TEST. Q ; and then I executed this at the programmer prompt: ZW ^rINDEX("QTEST")^rINDEX("QTEST","INT")=$lb("2021-08-06 13:21:58.061867",49) I changed the routine a bit: QTEST ; JUST A BIGGER TEST. Q EN ; JUST A BIGGER TEST. Q ; and I ZW'd the global again: ZW ^rINDEX("QTEST")^rINDEX("QTEST","INT")=$lb("2021-08-06 13:24:50.38743",63) It may be safe to assume that the underlined parameter is the length or number of bytes of storage required. Now once I compile the routine in Studio, and ZW the global again, this is the output: ZW ^rINDEX("QTEST")^rINDEX("QTEST","INT")=$lb("2021-08-06 13:24:50.38743",63)^rINDEX("QTEST","OBJ")=$lb("2021-08-06 13:26:30",152) Hope this helps!
go to post Roger Merchberger · Jul 28, 2021 Yes, you can! Access your XML file as a binary stream, then you can use the LoadStream command to load & compile the stream. S STREAM=##class(%Stream.FileBinary).%New() S STFILE=STREAM.LinkToFile("c:\where\is\your\file.xml") D STREAM.Rewind() ; test loading the stream, doesn't actually create it yet. The last '1' parameter means test & report. D $System.OBJ.LoadStream(STREAM,"ckfsbry/lock=0",.ERR,.LOADED,1) ; You can check the ERR variable to see if it errors out with no changes to the system. Assuming none, rewind & load it "for real" D STREAM.Rewind() D $System.OBJ.LoadStream(STREAM,"ckfsbry/lock=0",.ERR,.LOADED) I haven't tested this in this manner, as I actually have the XML Base-64 encoded in a global... but hopefully this should get you started. PM me if you'd like to see my full code; it's too long to add here. I'll leave the scheduling part as an exercise to the reader. :-) Hope this helps!