How certain are you that the server you're sending the request to accepts a content type of "text/plain"? Having that wrong, or using the wrong encoding are probably the most common causes of a 415 error.
- Log in to post comments
How certain are you that the server you're sending the request to accepts a content type of "text/plain"? Having that wrong, or using the wrong encoding are probably the most common causes of a 415 error.
If you're encoding your data before sending it, you have to specify how it was encoded in a content encoding header so that the server you're sending data to knows how to decode it.
I think it's more likely, though, that it's an issue with your content type. Where you're setting it to "text/plain", if it's supposed to be json, you might try setting it to "application/json" instead.
Your tResult will have a property called %SQLCODE that gets set when the query is run. If %SQLCODE = 100, that means that the query ran successfully but returned no results or that you've reached the end of the result set. If %SQLCODE = 0, you have some results. If %SQLCODE is less than zero, that's an error code.
if tResult.%SQLCODE = 100{
//whatever you want to do for no results here
}
Rochdi, I'd get rid of:
Set Line = File.Read(1000)
While (File.Read(1000)'="") {S mystring=mystring_File.Read(1000)
}
And then after your set Httprequest = ##class(%Net.HttpRequest).%New(), use:
set sc = Httprequest.EntityBody.CopyFromAndSave(File)
Then you can check sc to see if you got any errors doing that.
It sounds to me like there's an issue with the design there. If the field can be duplicated, why is it marked as unique at all?
Double check your IP address and port in the settings on the Preferred Server menu.
Ideally, that would be the case, but some of these aren't apps we've written and are forcing to log in with a safe user account. They're 3rd-party apps that our users are logging into using their usual credentials to create an ODBC connection. Most of them are reporting tools, but a few are also capable of running queries other than selects.
I think what we'd like to be able to do is determine roles similarly to how you can set up application roles so that the user gets those roles when they log in, we set permissions based on the program being used. Can we do that somehow in ZSTART?
Thanks, Vitaliy! This seems to be the approach that gives me what I want.
$EXTRACT(input,$FIND(input,"(")-1,*)
$EXTRACT(string,index1,index2) creates a substring out of the initial string from index1 to index2. $FIND finds the first occurrence of ( in the string, so that -1 includes the ( itself. When you're using extract, * is shorthand of the last character of the string.
If you're on IRIS, it definitely has those functions. Did you put just the $ in front of them?
The error seems to occur when it's trying to access the log file. Under you advanced settings, have you checked where it's trying to find or create your log file and made sure it's valid?
In your post, you say "Result is nothing is returned and %SQLCODE is 0". I just want to make sure this isn't just a misunderstanding. If the SQLCODE is 0, that would mean that there is a result returned. When the query executes successfully and nothing is returned, the SQLCODE is 100.
I think what you're looking for might be setting the isolation level to read committed. This will make the process wait for the in-progress changes have been committed, though you'll still want to make sure you handle SQLCODE -114 somehow, too. That's the code you get back if there's a timeout waiting for the lock. You should be able to set that using:
%SYSTEM.SQL.Util.SetOption("IsolationMode",1,.oldval)
If you do that before your query, the rest of the process will run at that isolation level.
You can use that same method to set the LockTimeout too, by the way. Default is 10 seconds.
Postman is a pretty standard tool for this. Even the free version gives you everything you need to get started, and if you end up collaborating with other groups on your API, or if your end users want to do some testing, it's easy to get them and share a collection of requests.
$SYSTEM.Status.GetErrorText(tSC) will work.
On whichever answers you want to mark as an answer, click the check mark next to the reply button. That should mark that reply as an answer.
You can probably make that work, but why not put the method in a %CSP.REST class to start with and have the CSP page call it? That seems more in line with the way those things are meant to be used.
I decided to try this yesterday, and I got a much bigger boost in performance than expected. The query was very simple, just a select distinct fieldname from table order by fieldname asc. The table contained about half a million records, but there are only about 350 distinct values in this field. Without that order by clause, this query always ran pretty quickly, around .013 seconds, but with the order by on the end, it was taking over 8 seconds to run. I tuned that table, and now even with the order by it's running in about .015 seconds. I was not expecting that drastic of a difference on such a simple query!
Rochdi, where is the variable Id getting its value? You're setting ^badis("datetime",Id) but I don't see anywhere in your loop where Id gets updated, so maybe you're just overwriting the same value, ^badis("datetime",1), over and over.
If you have multiple cursors anywhere in the class with the same name, that will come up. If it says C10, then you must have two different places where you're doing a "DECLARE C10 CURSOR FOR . . ." and you'll have to rename one of those cursors.
Great! Just a reminder, make sure you've made that change in all of your other statements for that cursor (open, fetch, close, etc.)
That shows me what I wanted. Thank you!
My use case has to do with change logs on our development server. Having looked at your and Lorenzo's answers, I've got a class set up with an objectgenerator method. It looks at the flags, and if there's an "a" or "v" it adds an entry to a versioninfo table I've made that contains a major version number, a minor version number, the username who compiled the class, and a field for notes which we can fill in later. If it's the "a", the new entry keeps the most recent major version and increments the minor version. If it's a "v", it increments the major version and sets the minor version to 0.
Now I can go into Studio and Compile with options adding either of those flags to get the desired results.
This is a pretty immature idea so far. I just wanted to see if it was possible before I went too much further in depth on it.
Here's the documentation for that function.
It looks like ##CLASS(Ens.Util.FunctionSet).Lookup("AllowLT", pRequest.GetValueAt("OBR:21"),"0",4) would do what you're asking; if the table or value can't be found, it'll return a 0.
In the management portal, go to System Administration, Security, Applications, Web Applications and find your application. Under security settings, disable Unauthenticated, and enable Password.
Then, when you send your requests, you need to include a base 64 encoded basic authentication header with the username and password, or on the end of the URL include ?CacheUserName=username&CachePassword=password. Keep in mind, though, that if you aren't using HTTPS, you could end up transmitting a username and password in plain text or in a very easily decrypted way.
If you want only specific users to be able to access the API, consider creating a new Resource then setting that resource as the Resource Required in the security settings, then only giving that resource to people who need to access the API.
Set tSC=##class(Hosiptal.SDA3.DataTrans).Transform(pRequest)
Is that a typo? Should maybe be "Hospital", not "Hosiptal".
You could create a new class that extends %ZEN.Component.toolbar, and override the ongetdata property to be a certain method name, then define that method in the class. Then you'd have your own custom tag to use in your zen pages. Here's more information on creating custom Zen components.
Inevitably, though, someone is going to come in here and tell you not to use Zen in any new development because it's deprecated, FYI. Which makes me sad, because I still really like working with it.
Is oneFldLogin.cls the login page for the application? Go to your management portal, System Administration, Security, Applications, Web Applications, and find the web app. At the bottom, under Custom Pages, is that set as the login page? If you open it in Studio or VS Code, does oneFldLogin.cls extend %CSP.Login?
Others have already explained why you can't use those list functions on a list of datatype.
As an alternative approach, though, you could change your persistent class to save the original string that you are using to create the list, then use your $ListFromString etc. on that as you have been.
Normally, one user connecting from one ip address uses one license. However, if you have 25 or more simultaneous connections under one license, it starts considering each connection to be a different license. I believe this is to try to prevent people from cheating the license system.
@Nezla in addition to what Danny mentioned here, if you see a part of a URL that starts with a colon in the url map, that part of the url is going to be passed as an argument to the method listed in Call. For example, I'm working on an API for an ERP system, and I've got an endpoint that can be called to get a customer record. The route in the url map is defined as:
<Route Url="/customer/:cust" Method="GET" Call="RequestCust" />
The RequestCust method is defined as:
ClassMethod RequestCust(cust As %String) As %Status
So if a user sends a request to /customer/123456, that gets passed to the RequestCust method with 123456 as the cust argument, and they get customer record 123456. If they send the request to /customer/999999, they get customer record 999999.