David Hockenbroch · Nov 23, 2021 go to post

When you're projecting a list of a class to XML, you usually have a parent element for each of those objects, then a separate element for each of it's properties. So I think what you'd need to do would be something more like:

<Results>
    <PersonIDs>
        <PersonID>
            <PersonID>1000000</PersonID>
        </PersonID>
        <PersonID>  
            <PersonID>1000001</PersonID>
        </PersonID>  
        <PersonID>  
            <PersonID>1000005</PersonID>
        </PersonID>  
    </PersonIDs> 
</Results>

So that the outer PersonID element indicates your PersonID object, and the PersonID inside of that is the PersonID property of that object.

David Hockenbroch · Nov 23, 2021 go to post

In that case, does it meet your needs to make it a list of %String instead of making a separate class?

David Hockenbroch · Dec 1, 2021 go to post

..Adapter.SSLConfig should get you the name of the SSL Configuration that the adapter is using. The property of the %Net.HttpRequest is called SSLConfiguration. So it should be:

set httpRequest.SSLConfiguration = ..Adapter.SSLConfig
David Hockenbroch · Dec 2, 2021 go to post

If I try to replicate some of these steps in my instance of Cache 2016, I get an error at:

Set httpRequest.Https = $$$YES

Does it make a difference if you try:

Set httpRequest.Https = 1

David Hockenbroch · Dec 3, 2021 go to post

In your class definition, if you wanted a maximum length of 1000 as an example, you would define your string as:

Property mystring As %String (MAXLEN = 1000);

But as Robert has already pointed out, if you're dealing with something very large, it's better to use some sort of %Stream instead.

David Hockenbroch · Dec 13, 2021 go to post

You can also open your log4j.jar as you would a zip file, go to the META-INF folder, open MANIFEST.MF and look for "Implementation-Version" to see which version of log4j it is.

David Hockenbroch · Dec 22, 2021 go to post

The ones in italics are the ones that are a part of your current project. If you click on the Project tab, they'll show up there too.

David Hockenbroch · Dec 22, 2021 go to post

If you're using the IRIS ODBC driver, try switching to the IRIS ODBC35 driver. This kind of error may mean that the application is expecting the driver to do some ODBC 3.x stuff that the older driver might not be capable of.

David Hockenbroch · Jan 7, 2022 go to post

Here is some useful documentation.

You're going to want to make a class that extends %CSP.REST and set up an application that uses that class as its dispatch class. You'll have a URL map in that class to tell IRIS or Cache what to do with the request. Depending on your specific application, you might also want to get familiar with using %request and %response in that process.

David Hockenbroch · Jan 7, 2022 go to post

This is a long shot, but is the ODBC connection defined in User DSN or System DSN? We had an issue after a recent round of Windows updates where Excel suddenly wasn't always correctly seeing the System DSN connection, and setting it up under User DSN instead resolved that issue.

David Hockenbroch · Jan 11, 2022 go to post

Your result.HttpResponse.Data can be either a string or a stream object. If it's a stream object you'll have to handle it a little bit differently using result.HttpResponse.Data.Read():

set response=result.HttpResponse.Data.Read()
while 'result.HttpResponse.Data.AtEnd{
    set response = response_result.HttpResponse.Data.Read()
}
David Hockenbroch · Jan 12, 2022 go to post

Depending on your needs, you might consider creating a class that extends both %Net.HttpRequest and %JSON.Adaptor and using the %JSON.Adaptor methods to create a JSON representation of the instance. That would be easier to analyze.

David Hockenbroch · Jan 17, 2022 go to post

I've never done that, but if you add it as a menu item, can you then go to View -> Toolbars -> Customize and find it in the commands tab? And if so, can you drag it to the toolbar you want it on from there?

David Hockenbroch · Feb 1, 2022 go to post

Are you trying for the Cache driver, or the IRIS driver? I'm pretty sure the 3.0.0 jar you're using is an IRIS driver, and in that case, the driver is com.intersystems.jdbc.IRISDriver, not com.intersys.jdbc.CacheDriver (note that in that transition, the beginning of the package changed from com.intersys to com.intersystems.)

David Hockenbroch · Feb 7, 2022 go to post

Have you checked the security settings for the user you're logging in as? You should have %Developer and %DB_USER, I think. Or if you have %All, that works too.

David Hockenbroch · Feb 8, 2022 go to post

Why not do this?

set rset1 = ##class(%ResultSet).%New() 
set query = "Select statment" 
set sc = rset1.Prepare(query) 
set:+sc sc = rset1.Execute(parm1, parm2) 
set ^sql = query
David Hockenbroch · Feb 11, 2022 go to post

Eduard, can't the MAXSTRING one also mean that you've exceeded a specified MAXLEN parameter on a string? Like if I have a Property LastName As %String (MAXLEN = 30) and you try to save the object with a 50 character last name, doesn't that also give a "MAXSTRING" error?

David Hockenbroch · Feb 18, 2022 go to post

Here's how I've been doing this:

//Read in content from the HttpRequest
set req = %request.Content.Read()

//Convert content from JSON to a dynamic object
set reqObj = {}.%FromJSON(req)

//Access data from within the new dynamic object
set userName = reqObj.%Get("UserName")
David Hockenbroch · Apr 1, 2022 go to post

Once you know the pid, try:

set process = ##class(%SYS.ProcessQuery).%OpenId(pid)

Then check process.Routine, or process.CurrentLineAndRoutine.

David Hockenbroch · Apr 5, 2022 go to post

I'm not sure your question is clear, but creating a new instance of that class in ObjectScript should be as simple as:

set myDTL = ##class(Ens.DataTransformDTL).%New()
David Hockenbroch · Apr 27, 2022 go to post

There isn't a hard limit on the number of tasks, but you may run into licensing issues. As you set them up, you choose the user they run as, so if that user has too many connections going at once, or if they're run as more different users than you have licenses for, there could be an issue.

David Hockenbroch · May 5, 2022 go to post

Methods that return a %Status don't automatically throw an exception. You have to check if the %Status is an error and throw it yourself. After your SendFormDataURL call, you might want to add the following and see if that gives you any more information:

if $$$ISERR(st) {
  throw ##class(%Exception.StatusException).CreateFromStatus(st)
}

However given that the HTTP status of the response is a 500 (an internal server error) there may also be a problem on that end.

David Hockenbroch · May 9, 2022 go to post

Are you just trying to get the json contained in a character stream into a string a vice versa? If so, just read and write to and from the stream:

set json = ""
while 'stream.AtEnd
{
    set json = json_stream.Read()
}

That should get you the contents of the stream into a string.

do stream.Write(json)

That should write the json to a stream.

Or is that not what you're trying to do?

David Hockenbroch · May 12, 2022 go to post

Are you sure you copied in the right SQL queries in your post? The ones you've included both try to update the EmailOptIn column to 0 where it's already set to 1, not where it's null. It seems to be they should be something more like "update Person set EmailOptIn = 0 where EmailOptIn is null".

David Hockenbroch · May 16, 2022 go to post

In addition to the methods already mentioned, a lot of the %Library classes also have a class method called IsValid that you can use. For instance if ##class(%Numeric).IsValid(n) returns a 1, then n is a valid numeric value.

David Hockenbroch · May 17, 2022 go to post

Even in the global masters rewards where they have an RPi available with IRIS preinstalled, it's running on Ubuntu, not Raspbian, so that part didn't surprise me.

As python becomes more widely adopted in IRIS and word gets out about it, I won't be surprised if some of the RPi community shows up with some pretty cool projects using IRIS Community since a lot of them are python developers. InterSystems tends to lean into health care as the main thing, but there you've got a device that you can connect all kinds of sensors and gizmos to that may lend themselves well to other fields. Let's not be hasty dismissing it because it can't run an entire hospital.

David Hockenbroch · May 18, 2022 go to post

It looks like in your curl you have the Accept header as */*, but in your HttpRequest object, you're setting it to "application/json". Does that make a difference?

David Hockenbroch · May 18, 2022 go to post

If the file isn't accessible to link to directly, you may want to look into extending the %CSP.StreamServer class and linking to that. At a bare minimum, you'll want to override the OnPage and OnPreHTTP methods:

ClassMethod OnPage() As %Status
{
set myfile = ##class(%File).%New("/path/to/file")
do myfile.Open("S")
do myfile.OutputToDevice()
quit $$$OK
}

ClassMethod OnPreHTTP() As %Boolean [ Language = cache ]
{
do %response.SetHeader("Content-Disposition","attachment;filename=""filename""")
quit 1
}

Of course using your own file name and the path to the file. That's the local computer file path, not a URL. You also should set the content type appropriately using set %response.ContentType = "text/csv" or whatever the MIME type of the file is so that the browser can identify it correctly.

Unless you want to have to write another %CSP.StreamServer for every file, you'll have to pass the name of the filepath as an argument. So that would look more like:

ClassMethod OnPage() As %Status
{
set myfile = ##class(%File).%New(%request.Get("filepath"))
do myfile.Open("S")
do myfile.OutputToDevice()
quit $$$OK
}

ClassMethod OnPreHTTP() As %Boolean [ Language = cache ]
{
set filepath = %request.Get("filepath")
set %response.ContentType = "text/csv" //or whatever the appropriate MIME type is
do %response.SetHeader("Content-Disposition","attachment;filename="""_$P(filepath,"/",*)_"""")
quit 1
}

Then you could link to it as whatever the path to your stream server is with ?filepath=/path/to/file on the end.

If you take that approach, though, do some validation on the filepath and make sure it can ONLY go to the folder you want! Or, only pass the filename as a parameter to the page, and hard-code the folder in those methods.