go to post David Hockenbroch · Jun 30 As a point of clarification, property names ARE case sensitive in ObjectScript, but in SQL, column names ARE NOT case sensitive. You aren't allowed have a property named "name" and a property named "Name" because they would be ambiguous when doing SQL queries.
go to post David Hockenbroch · Jun 30 Versions that old used to install all the documentation locally. I forget what options had to be selected in the installer because it's been a while, but if you run it, you should have the option somewhere. Then you should be able to click the Cache icon in your system tray and click on "Documentation".
go to post David Hockenbroch · Jun 27 Do you mean the format as in HL7, FHIR, etc.? There are specific ContentType settings for those in the specification, I believe. If the message is a "vertical bar" encoded HL7 v2.x message, the content type SHALL be: x-application/hl7-v2+er7 If the message is an XML encoded HL7 v2.x message, the content type SHALL be: x-application/hl7-v2+xml If the message is an XML encoded HL7 v3 message, the content type SHALL be: x-application/hl7-v3+xml If the message is an XML encoded FHIR message, the content type SHALL be: x-application/fhir+xml If the message is a JSON encoded FHIR message, the content type SHALL be: x-application/fhir+json If the message is a CDA document, the content type SHALL be: x-application/xml+cda
go to post David Hockenbroch · Jun 27 In the %SYS namespace, you can query the table Security.Applications and check the type column. If you do this in the system management portal in display mode, the Type column will start with "System". In logical mode, though, it will be a number. 1 is System, 2 is CSP Application, 4 is a privileged routine application, and 8 is a client application, and if an application is more than one of those things, the Type column is their sum. For example, if it's a System applcation AND a CSP application, the type will be 3. That complicated things, but fortunately since the 1 is the only odd number and it signified system applications, we can use the modulus function to identify system applications as follows. select * from security.applications where {fn MOD(type,2)} = 1 Also, at the risk of self-promotion, I wrote an article detailing more about managing applications programatically a while back. You can find it here.
go to post David Hockenbroch · Jun 27 Here's an example of how we use the relationship between namespaces and databases. My company sells ERP software for the millwork industry. Our customers sell building materials to contractors, distributors, etc. Some of our customers have multiple locations throughout the country. For those customers, we will usually set up a different namespace for each of those locations. Each of those namespaces is set up to have their own database for their data, but the all share the same database for routines because while they all have different data, like customers, orders, invoices, etc., the same set of code is running all of them.
go to post David Hockenbroch · Jun 26 I have done those two, plus in certain cases a "CreatedBy" and "LastUser" that are automatically computed to the $USERNAME in insert and on insert/update.
go to post David Hockenbroch · Jun 26 Whoops, I replied to the wrong comment somehow. Sorry! Edit: for some reason when I clicked on the Reply button on Evgeny's comment above, it was initially showing this reply under Sergei's post below. Then when I left the page and came back, it was in the right place. Firefox being weird on me, I guess.
go to post David Hockenbroch · Jun 11 @Jude Mukkadayil in one of your posts here, you mentioned this error: [SQLCODE: <-415>:<Fatal error occurred within the SQL filer>] [%msg: <Error occurring during UPDATE in table 'SQLUser.PA_Person': $ZE=<LIST>%SQLUpdate+40^User.PAPerson.1>] According to this documentation, that could be a runtime error in some trigger code. In your User.PA_Person class's ObjectScript, you probably have a trigger defined that is causing issues for you. If so, can you post the code for the trigger(s) in that class?
go to post David Hockenbroch · Jun 11 As I'm diving into Angular right now, mine is to add a projection to a TypeScript interface. Is there a specific tag we're supposed to use for the contest this year?
go to post David Hockenbroch · Jun 3 I grew up in Mifflintown, PA, just a couple hours' drive from Lancaster. We used to make weekend trips to Lancaster and see plays at Sight & Sound and some of the other touristy stuff around there.
go to post David Hockenbroch · Jun 3 I'm David Hockenbroch, and I'm based out of Memphis Tennessee. I'm a senior analyst here at WoodWare, so I get into all kinds of things. Lately that includes spending a lot of time considering how to get some really old pieces of software that were written in VB6 or using Zen pages into something that's supported now. I'm a big food person, so Memphis is a good place for me! I also enjoy being outside or taking in a good story, whether that's a movie, book, TV show, or even a well-written videogame. I will not be at READY 2025. I look at the session list every year, and it seems very healthcare-focused. I'm not in health care, so I always question whether it's worth the trip for me. We write business software. I do typically catch up on some of the keynotes online, though.
go to post David Hockenbroch · May 20 %Stream.FileBinary objects are not considered temporary files. You probably want to be using %Stream.TmpBinary objects.
go to post David Hockenbroch · May 15 I'm not sure there's any getting around having to check to the HTTP status entirely, but you could log an exception without throwing it, then throw a more user-friendly exception to your catch block to be returned. It would also get logged, but that's probably okay as long as whoever is looking at the system logs knows that will happen. //Log this one do ##class(%Exception.StatusException).CreateFromStatus($$$ERROR($$$GeneralError,HTTPSRequest.HttpResponse.StatusCode_" "_HTTPSRequest.HttpResponse.Data.Read())).Log() //Throw this one if HTTPSRequest.HttpResponse.StatusCode = 502{ throw ##class(%Exception.StatusException).CreateFromStatus($$$ERROR($$$GeneralError,"The service is currently unavailable. Please call tech support or try again later.")) } Then some elseif blocks for whatever other HTTP statuses you want to handle, then a final "else" at the bottom to throw something generic to catch anything else. That at least gets the custom handling out of the catch block so it isn't processed for every exception.
go to post David Hockenbroch · May 7 Here's where you're hurting yourself: if $$$ISERR(tSC) { set tSC = $$$ERROR($$$GeneralError, "Error in sending request to the server") quit tSC } tSC is already a status. You are changing it to a different status and forcing it to say "Error in sending request to the server." Replace that whole block of code with: quit:$$$ISERR(tSC) tSC That will quit if tSC is an error and give you the actual status that occurred. Once you have that, it'll hopefully be easier to troubleshoot this.
go to post David Hockenbroch · Apr 28 Just out of curiosity, can you include what you're searching for in the where clause of the initial query?
go to post David Hockenbroch · Apr 25 I would use Dynamic Arrays and Dynamic Objects to make this simpler. Those two are your best friends when working with JSON. ClassMethod GetAllPersons() As %Stream.Object { d ..%SetContentType("application/json") Set rset = ##class(dc.Sample.Person).ExtentFunc() set stream=##class(%Stream.TmpCharacter).%New() set dynArray = [].%New() While rset.%Next() { do ##class(dc.Sample.Person).%OpenId(rset.ID).%JSONExportToString(.myPerson) Set dynObj = {}.%FromJSON(myPerson) do dynArray.%Push(dynObj) } d stream.Write(dynArray.%ToJSON()) return stream }
go to post David Hockenbroch · Apr 16 I know this has already been answered several ways, but let's not overlook embedded SQL as an option. &sql(select JSON_OBJECT('Name':Name,'Title':Title,'Company':Company,'Phone':Phone, 'DOB':DOB) INTO :person WHERE ID = 1) set personobj = {}.%FromJSON(person) This can get a little unruly for tables with a lot of columns, but if you're wanting to pick out certain specific columns or customize the JSON field names, this approach gives you that flexibility.
go to post David Hockenbroch · Mar 5 It's useful in terminal, and in my opinion, it lets me write neater code too. I don't have to include lines like if $$$ISERR(sc) { $$$ThrowStatus(sc) } every time.
go to post David Hockenbroch · Mar 5 Yes, that's how it works. If you don't want it to reset the sc, then you can leave out the R flag when you call the New() method. Just be aware that the error handling only triggers when sc goes from OK to an error, so it won't trigger again unless you manually set sc back to $$$OK.