David Hockenbroch · Nov 8, 2023 go to post

Could you maybe use $LISTTOSTRING using a delimiter that works for you (something unlikely to be in your actual list data), convert that to uppercase, then use $LISTFROMSTRING to get it back into $LIST format with everything capitalized and not breaking the list?

David Hockenbroch · Nov 9, 2023 go to post

The requests using port 52773 aren't even going to get to Apache, so you can't solve this problem by changing your Apache configuration. You would have to make your router forward traffic between your server and your other PCs on port 52773 to port 80 (for HTTP) or port 443 (HTTPS).

David Hockenbroch · Nov 9, 2023 go to post

My mistake, Scott, I thought you just had Apache running on its default ports and were trying to figure out how to make the other requests also go there.

David Hockenbroch · Dec 15, 2023 go to post

In my opinion, if you have a page that doesn't necessarily need to have any user interface elements - %CSP.StreamServer is a good example - that's the primary case for extending %CSP.Page. If you need a UI, then a csp page is easier to deal with.

David Hockenbroch · Dec 19, 2023 go to post

Maybe that's old code that's been carried over through some copying and pasting. I have a Cache 2012 instance and Name is not required in it.

David Hockenbroch · Dec 20, 2023 go to post

If your IDList is a string, you'd have to use WHERE 10 %INLIST $LISTFROMSTRING(IDList,' ') so that the string is converted to an actual list for %INLIST to work.

David Hockenbroch · Dec 29, 2023 go to post

You can also use the $ROLES special variable to do that. It contains both the user's assigned roles and any roles you've added during the process. You can't change the user roles, but if you set it that will add a role. So you could do:

set $ROLES = "%All"

Or whatever role you need to add, then do the stuff that requires that roles, then do:

set $ROLES = ""

That will take away the %All role you added, reverting the process to just the user's normal roles.

David Hockenbroch · Jan 2, 2024 go to post

You say you've been able make the tables read only and not "everything". What are the accessing besides tables?

David Hockenbroch · Jan 11, 2024 go to post

When using $EXTRACT, you use a * to signify an offset from the end of a string. So if you did $EXTRACT(Str,1,*-1) you would have the string with the last character removed.

Also note that the arguments for the $EXTRACT are the string, the starting character, and the ending character, so in the examples you gave, you're actually telling it to extract from Str starting at Length(Str)-1. You need to have a 1 in there as the second argument to go from the beginning to that character.

David Hockenbroch · Jan 11, 2024 go to post

Emil, if the request is not coming from a form with the enctype set to multipart/form-data, can you give us an example of how the request is being created? Maybe the issue is that the request has not been created properly.

David Hockenbroch · Jan 18, 2024 go to post

Yes, you do have to tread lightly and program very carefully if you mess with those. Errors in them could make it impossible to start or log into IRIS. This is straight from the documentation about those routines:

Make sure that the routines are well-behaved under all possible conditions. They should be written defensively. That is, they should check to make sure that all the resources needed to complete their task are at hand and, if possible, reserved to them before computation starts. Errors which occur are reported as failures of that system function so it is important to think about the design from the viewpoint of error containment and handling. Failure to properly account for recovery in the face of missing resources or the presence of errors has varied consequences: InterSystems IRIS may fail to start; major functions such as Studio may act strangely; or more subtle and insidious consequences may occur which are not immediately detected. It is strongly recommended that these routines be carefully written and debugged under simulated conditions, and then tested under simulated environment conditions before being put into production systems.

It doesn't sound like you're trying to do anything too crazy, but do make sure you trap or catch any potential errors anyway.

David Hockenbroch · Jan 25, 2024 go to post

To create a task in the task manager, you have to write a class that extends %SYS.Task.Definition. Within that class, you create an OnTask method, and that the method that will run when your task is triggered. There's a more thorough example of this here.

David Hockenbroch · Feb 7, 2024 go to post

I don't have an answer, but I also hope someone does. // is specifically for a single-line comment, so it's odd to me that it's continued like that.

David Hockenbroch · Feb 13, 2024 go to post

I've never done it this way, just by overriding those methods in the class definition containing the property, but I do know in that case Set has to take a value as an argument. Maybe it's not recognizing your Set method because it doesn't match the signature of the usual Set method. When you override it in a class, it looks like this:

Method NewProperty1Set(Arg As %String) As %Status [ ServerOnly = 1 ]

In that case, Arg is the value that the process is trying to set the value of the property to. So it might have to be something like:

Method Set(Arg as %String){ S %val = "asd" Q 1}

Or if you wanted to some something with the input value, you could use Arg to do that?

David Hockenbroch · Feb 15, 2024 go to post

If you're using a dynamic object to set the value, there is an optional third argument to the %Set method where you can specify the data type. So if you use myobject.%Set("testingID",1234567,"number") it will be added as a number.

David Hockenbroch · Mar 12, 2024 go to post

If it's null, your code might not even be getting to the Post method. Are you running this in the terminal, and are you getting any other errors there? Is your RTLS SSL configuration set up in the management portal?

Also, when the response comes back, it's JSON, so if you want to get just the token, you'd have to:

set tokenObj = ##class(%Library.DynamicObject).%FromJSON(AuthToken.HttpResponse.Data)
set AuthTokenValue = tokenObj.%Get("access_token")

David Hockenbroch · Mar 18, 2024 go to post

By the time I started learning ObjectScript, I had already been exposed to varying degrees to Java, javascript, PHP, C#, C++, Visual Basic, Python, and ActionScript, so to me it was different, but I was kind of used to finding my way around the quirks of a new object-oriented language.

One thing that does make it more difficult with ObjectScript in this community, though, is that so many things can be abbreviated in code, and that makes it harder for beginners to read and follow up on. For example, you might see {}.%New() or {}.%FromJSON(). It might take some time to figure out that if you want to look up further documentation on what that is, you have to look at the %Library.DynamicObject class, and that you could also use ##class(%Library.DynamicObject).%New(). Commands like set, do and for get shortened to s, d, and f. Functions like $ZDATETIME get shortened to $ZDT. We mention things like $$$ThrowStatus assuming you'll know that if you're writing a routine, you have to have #include %occStatus at the top to use that.

It's something that, once you figure it out, it's easy to understand, but those of us writing articles on here could also do a better job of writing our code samples to be readable.

David Hockenbroch · Mar 22, 2024 go to post

If you want to treat them as lists, you probably want to use $LISTFROMSTRING along with $LISTGET, $LISTFIND, and $LISTLENGTH. All of which can be abbreviated to their initials, by the way - $LFS, $LG, $LF, $LL.

set y = $LFS("Red,Green,Orange,Yellow")
set x = $LFS("Purple,Black,Yellow,Pink")
for i=1:1:$LL(x){
    if $LF(y,$LG(x,i)) > 0 { 
        write $LG(x,i)_" found in both lists!",!
        //Or whatever else you want to do when you find a match here . . .
    }
}
David Hockenbroch · Mar 25, 2024 go to post

We haven't tried using it for ObjectScript, but we do have some customers who use Crystal Reports who have tried using it to help set those up, and it has been very questionable for that. It definitely doesn't understand what's where in the database structure, and even basic formula fields seem to be far more complicated than necessary.

David Hockenbroch · Mar 26, 2024 go to post

.gz and .zip files are two very, very different things. You can't just rename a gz to zip and expect it to work.

David Hockenbroch · Mar 26, 2024 go to post

gzip and zip are not the same thing. If you are trying to create a .zip, you need to use zip.

It's probably not finding your test001.zip because it's creating a test001.zip.gz.

David Hockenbroch · Mar 26, 2024 go to post

If you want to do all files in a directory, including recursively going into all subfolders, the command should be something like:

zip -r test001.zip /path/to/folder/

If you're trying to do this from inside ObjectScript, you'd have to use $ZF -100 to do that:

set args(1) = "-r"
set args(2) = "test001.zip"
set args(3) = "/path/to/folder/"
do $ZF(-100,"","zip",.args)
David Hockenbroch · Mar 27, 2024 go to post

When you see something that starts with a ..# that's a parameter that's defined in a class. If you look at the source of the %CSP.REST class, you'll see:

Parameter HTTP401UNAUTHORIZED As %String = "401 Unauthorized";

So you could try either set the %response.Status "401 Unauthorized" or add that parameter to your class and use it as you have before in %CSP.REST classes.

David Hockenbroch · Mar 27, 2024 go to post

I've seen this before when the browser has something cached from the old version. Have you cleared your browser's cached files?

David Hockenbroch · Apr 1, 2024 go to post

Your login request technically is an unauthenticated request, which means it uses the account UnknownUser. Since the web application /api/atelier requires user permission on the %Development resource, the request is failing. You could address this by either removing that restriction from the web app or by assigning the %Developer role to UnknownUser. In my opinion, though, neither of those is really ideal.

David Hockenbroch · Apr 1, 2024 go to post

Queries to linked tables will fail if there is an issue with the connection, but when it's up, you've got the current data. Copying it over would help with potential connection issues, though you would still have a problem if the connection can't be established when you're trying to copy the data over. But if you're doing that once a day, your data is going to be a day old at times. I think the question you need to be asking is, for your specific application, how important is it that the data you're getting from the external database is current?

David Hockenbroch · Apr 2, 2024 go to post

In SQL, you can use the following query:

select * from %dictionary.compiledclass where primarysuper like '%abc.test.cls%'