go to post Timothy Leavitt · Nov 22, 2021 @Steve Pisani glad to hear you'll be using it - your feedback (via GitHub issue, email, Teams, or carrier pigeon) is certainly welcome! I know it took a long time to get this out, but better late than never! Shout out to @Sarmishta Velury and Adewale Adewuyi (who I can't tag) for helping to make it happen. :)
go to post Timothy Leavitt · Nov 22, 2021 See also: https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...
go to post Timothy Leavitt · Nov 22, 2021 Another note on this - there are some new behaviors in recent IRIS versions around the SameSite flag on cookies. (see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/Sam... for general background and https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls... for an explanation of the IRIS changes). This can make cookies behave differently in iframes, doing HTTP redirects, even opening via a link; how you get to a page has a bearing on cookie behavior. Not sure if that fed into the issue you saw but it's worth noting.
go to post Timothy Leavitt · Nov 15, 2021 @Chris Marais This means that ^PERFMON or ^%SYS.MONLBL is already running somewhere on the system. If you do ^%SYS.MONLBL it should provide some helpful output/options.
go to post Timothy Leavitt · Nov 12, 2021 Whoa - I had no idea iFind had JSON indexing features. That said, the docs aren't really helpful here. I'll issue another call for @Benjamin De Boe to chime in :)
go to post Timothy Leavitt · Nov 12, 2021 No, the index that uses BuildValueArray is updated automatically after %Save()/insert/update/etc. The Run() method just demonstrates how the index works, it doesn't do anything special or index-specific.
go to post Timothy Leavitt · Nov 10, 2021 We've done something similar to this for indexing with JSON paths (in the style of https://goessner.net/articles/JsonPath/) as the keys and the value at that path as the value.
go to post Timothy Leavitt · Nov 10, 2021 Maybe not simpler, and definitely more complicated if you use a stream rather than a string with MAXLEN="" (which I'll demo below); here's what it ends up looking like: Class DC.Demo.JSON Extends %String [ ClassType = datatype ] { Parameter MAXLEN; /// Builds value array with subscripts set to values of properties in the JSON stream. ClassMethod BuildValueArray(value As DC.Demo.JSON, ByRef valueArray As %String) As %Status [ Private ] { set sc = $$$OK try { set object = {}.%FromJSON(value) do ..AddObjectToValueArray(object,.valueArray) } catch e { set sc = e.AsStatus() } quit sc } ClassMethod AddObjectToValueArray(object As %DynamicAbstractObject, ByRef valueArray, truncateToLength As %String = 255) { set iter = object.%GetIterator() while iter.%GetNext(.key,.value) { if $isobject(value) { do ..AddObjectToValueArray(value,.valueArray) } else { set sub = $extract(value,1,truncateToLength) set valueArray(sub) = "" } } } } Class DC.Demo.IndexJSON Extends %Persistent { Property JSON As JSON(MAXLEN = ""); Index JSONValues On JSON(KEYS); ClassMethod Run() { try { do ..%KillExtent() for json = {"FirstName":"Magnus", "LastName":"Guvenal"}, ["Magnus", "Guvenal"], { "a":{"b":{"c":"Magnus" } }} { set inst = ..%New() set inst.JSON = json.%ToJSON() $$$ThrowOnError(inst.%Save()) } do ..DisplaySQL("select JSON from DC_Demo.IndexJSON where for some %ELEMENT(JSON) (%KEY = 'Magnus')") do ..DisplaySQL("select JSON from DC_Demo.IndexJSON where for some %ELEMENT(JSON) (%KEY = 'Guvenal')") do ..DisplaySQL("select JSON from DC_Demo.IndexJSON where for some %ELEMENT(JSON) (%KEY = 'FirstName')") } catch e { set sc = e.AsStatus() write !,$system.Status.GetErrorText(sc) } } ClassMethod DisplaySQL(query, args...) { write !,query,! for i=1:1:$get(args) { write "argument: ",args(i),! } do ##class(%SQL.Statement).%ExecDirect(,query,args...).%Display() } Storage Default { <Data name="IndexJSONDefaultData"> <Value name="1"> <Value>%%CLASSNAME</Value> </Value> <Value name="2"> <Value>JSON</Value> </Value> </Data> <DataLocation>^DC.Demo.IndexJSOND</DataLocation> <DefaultData>IndexJSONDefaultData</DefaultData> <IdLocation>^DC.Demo.IndexJSOND</IdLocation> <IndexLocation>^DC.Demo.IndexJSONI</IndexLocation> <StreamLocation>^DC.Demo.IndexJSONS</StreamLocation> <Type>%Storage.Persistent</Type> } } In action: USER>d ##class(DC.Demo.IndexJSON).Run() select JSON from DC_Demo.IndexJSON where for some %ELEMENT(JSON) (%KEY = 'Magnus') JSON {"FirstName":"Magnus","LastName":"Guvenal"} ["Magnus","Guvenal"] {"a":{"b":{"c":"Magnus"}}} 3 Rows(s) Affected select JSON from DC_Demo.IndexJSON where for some %ELEMENT(JSON) (%KEY = 'Guvenal') JSON {"FirstName":"Magnus","LastName":"Guvenal"} ["Magnus","Guvenal"] 2 Rows(s) Affected select JSON from DC_Demo.IndexJSON where for some %ELEMENT(JSON) (%KEY = 'FirstName') JSON 0 Rows(s) Affected
go to post Timothy Leavitt · Nov 10, 2021 Another simpler option would just be using BuildValueArray - see e.g. https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls... (code sample coming...)
go to post Timothy Leavitt · Nov 9, 2021 Ended up being a simpler solution than expected... the query had been update table set newfield = 1 where newfield is null and really should have just been update %NOINDEX table set newfield = 1 (because it was null everywhere).
go to post Timothy Leavitt · Nov 9, 2021 There's great IDE integration for VSCode for local git repos; really it's the package manager awareness that's key. Use case: I find a bug in one of my project's dependencies Assuming it's been loaded from my local filesystem rather than by zpm install, I can just fix it directly via an isfs editing mode and it'll be reflected on the filesystem.
go to post Timothy Leavitt · Nov 8, 2021 Thanks @Ben.Spead! And just to be clear, this isn't just for those working in shared, remote development environments - I anticipate this simplifying a lot of my work on Open Exchange projects even with local instances and VSCode.
go to post Timothy Leavitt · Nov 3, 2021 I wonder if the business host is running an old version of the class. (That would explain why the <UNDEFINED> reports a weird line of code, and why the error hasn't gone away after you fixed it.) Maybe try disabling + reenabling the business operation / restarting the production?
go to post Timothy Leavitt · Oct 28, 2021 The internal hackathon is over but I'd love to still hear more thoughts here. :)
go to post Timothy Leavitt · Oct 28, 2021 Agreed - this feels like the biggest gamechanger among Virtual Summit announcements since we've called it Virtual (or Global) Summit.
go to post Timothy Leavitt · Oct 13, 2021 One note here, $$Quote^%qcr will represent control characters with $c(decimalAsciiCode) syntax - like the newlines in this case. I think there's some more official classmethod that's equivalent, but I don't recall where it is off the top of my head.
go to post Timothy Leavitt · Oct 13, 2021 Hi Erica, $$$Text generates content into the message globals at compile time. Here's one way to solve the problem: Class Erica.DemoLocalizedXData { Parameter DOMAIN = "Demo"; XData LocalizedEmail [ MimeType = text/html ] { <body> <p> Text to be translated into another language </p> </body> } ClassMethod GetLocalizedContent(xDataName As %String) As %String [ CodeMode = objectgenerator ] { do %code.WriteLine(" Quit $Case(xDataName,") set key = "" for { set xdata = %class.XDatas.GetNext(.key) quit:key="" set data = xdata.Data.Read() // Assumptions about length here... do %code.WriteLine(" "_$$$QUOTE(xdata.Name)_":$$$Text("_$$Quote^%qcr(data)_"),") } do %code.WriteLine(" :"""")") } } After compilation you'll have: ^IRIS.Msg("Demo")="en" ^IRIS.Msg("Demo","en",3630108798)="<body>"_$c(13,10)_"<p>"_$c(13,10)_"Text to be translated into another language"_$c(13,10)_"</p>"_$c(13,10)_"</body>"_$c(13,10) If you want to localize individual strings in the XData block independent of the HTML markup that gets a little more complicated. I'd think it's simpler/possibly better to localize the entire block at once though.
go to post Timothy Leavitt · Oct 11, 2021 Neat trick for the expression for r! (Which I hope to never see again outside of the context of contests like this. :))