Rubens Silva · Sep 10, 2020 go to post

This means your query is taking a longer time to return the result back to your CSP application than what it expects.

I'd recommend you to verify why it's taking so long and optimize your query, but you can also ask the CSP gateway to wait for a longer period before it times out.

  // On OnPreHTTP callback method.
  set %response.Timeout = 900 // this will make your application wait for the response for 900 seconds.

Note that %response.Timeout will change the timeout for the current request only.

Rubens Silva · Aug 17, 2020 go to post

Currently ObjectScript doesn't support method override. But you might be able to simulate it by using rest parameters and delegating to a second private method that handles it according to what has been provided to the initial method.
EDIT: Whoops! I meant overload.

Rubens Silva · Aug 11, 2020 go to post

Works even on Caché 2018.1.2. I can't think of a reason as to why it wouldn't work for IRIS CE.
EDIT: Just to point out that GetOSErrorText is indeed limited to 2020.1+ releases, including Caché.

Rubens Silva · Jul 8, 2020 go to post

Thanks for everyone's suggestions. But we have opted for using CompilePackage while providing the method the argument dynamically by using envs.

Rubens Silva · Jun 24, 2020 go to post

You mean like this?

ClassMethod CallHook(hook As %String = "", args...) As %Status [ Private ]
{
  if hook = "" return $$$OK

  set classname = $piece(hook, ":", 1)
  set method = $piece(hook, ":", 2)
  try {
    return $classmethod(classname, method, args...)
  } catch ex {
    return ex.AsStatus()
  }
  return $$$OK
}

It certainly does for me.

https://github.com/rfns/frontier/blob/fe0868c8e0821ffdfd15407994288b28327a476f/cls/Frontier/Files/Uploader.cls#L94-L111

Rubens Silva · May 26, 2020 go to post

Yes, we are on the road for making it a SPA (single page application) using React.

In the short term, we probably won't make it a PWA though since we also have developers with enough knowledge to create mobile applications using React-Native (me included).

Since you mentioned libraries and framework, I'll go a bit further and provide you a history background about why we are using React after dropping Angular:

Several years ago we initially used Angular 1.5 to create partial SPA applications embedded to our legacy CSP application, however as the demands increased we noticed that Angular introduced a spike in the learning curve messing up with our development speed as several domain specific languages had to be researched to fill these demands, including knowledge for advanced usage/creation of directives, really deep understanding of scope and its cycles. A complete mess.

We considered using Angular 2 at that time, but we dropped the idea as we noticed Angular 2 getting close to the component-based approach just like React and since our experiences with Angular were not the best along with the effort put from learning the 1.5 version becoming useless, we started to move to React.

Sadly VueJS was a late player at that time although I do recognize its efforts to use the best both from each worlds.

Rubens Silva · May 25, 2020 go to post

%CSP.StreamServer is just a helper to cut short some manual labor.

What you need to do is write the file stream back to the device and change three Content-* headers as follows.

Your CSP page has an OnPreHTTP just like every %CSP.Page extended class. You can use this method to modify the Content-Type, Content-Disposition and Content-Length headers. In your case you'll need to use the <script> tag syntax for creating the method.

The example below assumes you're using a class instead.

NOTE: If you really customize your %CSP.Page or %CSP.REST. You don't even need to use the OnPreHTTP method. But I'll be using it here for educational purposes.

ClassMethod OnPreHTTP() As %Boolean [ ServerOnly = 1 ]
{
   set file = %request.GetMimeData("FileStream")
   if '$isobject(file) return 0
   
   do ##class(%CSP.StreamServer).FileClassify("XLS", .contentType, .isBinary, .charset)
   do %response.SetHeader("Content-Type", contentType)
   do %response.SetHeader("Content-Disposition", "attachment; filename=""_file.FileName_""")

  return 1
}

ClassMethod OnPage() As %Status [ ServerOnly = 1 ]
{
  set iStream = %request.GetMimeData("FileStream")
  $$$QuitOnError(##class(something).method(iStream, .oStream))
  
  do %response.SetHeader("Content-Length", oStream.Size)
  
  do oStream.Rewind()
  do oStream.OutputToDevice()
  
  return $$$OK
}
Rubens Silva · May 23, 2020 go to post

I try to use Studio whenever possible because it feels "faster" for me. This is mostly because it also feels more "native" as well. I usually fallback to VSCode when I can't but I still find the UX lacking (obviously, it's not a dedicated tool after all).

However this is not the only obstacle: the Atelier API as oposed to Studio feels really slow when I use my instance locally. Think about it: I have the files locally, so I still have to execute HTTPs request to my own machine even though I could simply use the file system to import these files, having a network layer in this case only introduces a bottleneck.

Also, the Atelier API doesn't seems to be optimized to handle large projects (more than 5000 items) which in turn reflects to the VSCode extension.

Here's an use case from my company:

  • We use distributed development and versionment.
  • 3 of our users are Mac based due to working with tools like React-Native, so they have to use VSCode.
  • Since we're adapting from a legacy development style, for now our project has about 3200 items.
  • Our project contains lots of static files from CSP to JS even HTML files. And we are moving away from CSP because we plan on making our product a SPA.
  • We do NOT use IRIS for development and CD due to critical compability issues with Caché versions (try importing a XML generated from IRIS into Caché to see what happens).
  • We use VSCode to edit these JS and HTML files.
  • Releases are XML based and generated using a docker version of Caché.

To be honest, the only thing we use from this poll is Studio, otherwise we had to create our own tool to fit our needs.

Rubens Silva · Apr 16, 2020 go to post

Yes, but if you provide a pre-object like let's say: %Stream.FileCharacter, it outputs to it as well.
I also tried setting the TranslateTable to UTF-8 and used the OutputToDevice method to see the result, but that brought me  the same result.

Rubens Silva · Apr 16, 2020 go to post

Yes, what I meant to say is that the original file is correct. It's not us who did the double transcoding. The resulting output that I posted:

"text": "Condição de pagamento sujeito a análise de crédito: "

Is straight from the call from Export and/or ExportToStream. Which is why I said that these methods seems to impose a transcoding step.

This is weird, I shouldn't have to convert a file to RAW in order to export to UTF-8. But instead provide the same charset for both input/output so that the engine actually knows which encoding to use (but not transcode).

Unless there's is a way to effectively disable that hidden transcoding step that these method do, this make these methods really misleading.

Rubens Silva · Apr 16, 2020 go to post

@Robert Cemper

Certainly it's not a hand-made double encoding.

Because we also made sure of that by writing a new file for both charsets to simulate the issue.

Rubens Silva · Apr 16, 2020 go to post

Hello @akoblov.

I also did the test using Export instead of ExportToStream and got the same result.

Now first thing, you must make sure that the file you used is indeed written using UTF-8.

You can check it by using the following command:

file -bi ..\..\csp\user\test.json

It should display:

charset=utf-8

Now regarding more tests I did, it seems like there's an imposed transcoding step when exporting the file. I ran several simulations with many type of combinations:

  • When the original is file written using UTF-8 and I exported using UTF8 it broke the encoding.
  • When the original is file written using UTF-8 and I exported using RAW (which is ISO-8859-1 in my case), it DID NOT broke the encoding.
  • When the original is file written using ISO-8859-1 and I exported using RAW, it DID NOT broke the encoding.
  • When the original is file written using ISO-8859-1 and I exported using UTF8 it DID NOT broke the encoding.

This is very strange.

Rubens Silva · Mar 16, 2020 go to post

I can't believe I forgot about that Data property.
I just won't mark your reply as the answer because I didn't specified that I wanted to know how to do that. My bad... but thanks anyway.

Rubens Silva · Mar 16, 2020 go to post

I cannot see any need to combine both in the same instruction, both return null if the item does not exist.

I wanted to avoid writing more than one line or having to get the value twice, e.g.

set value = array.GetAt("key")
if value = "" set value = "default"

I actually did it that way. But I could do it this way too:

set value = $select(array.GetAt("key") '= "" array.GetAt("key"), 1: "default")

But now I would be calling it twice which seemed like code smell for me.

Rubens Silva · Mar 11, 2020 go to post

Yep, this one works fine as long as you don't embed another error using $$$ADDSC or $$$EMBEDSC.

Rubens Silva · Mar 11, 2020 go to post

Indeed, I got this error too. However if I use a dummy directory it accepts.
I haven't used this feature yet because I must change plenty of things to actually consume that REST application. But the way I'm seeing things so far I guess it would work.
So what if you provide a dummy directory like: "/tmp/dummycsp" as well?

Rubens Silva · Mar 10, 2020 go to post

From your code above I see that you attempted to use both Directory and DispatchClass attributes. Have you tried removing the Directory attribute?

Rubens Silva · Mar 9, 2020 go to post

Looks like the new version of the %Installer for IRIS already supports this setting.
But it might still be helpful to clear that question about the ZPM for other circunstances.

Rubens Silva · Mar 9, 2020 go to post

Can I use the ZPM client like a standalone the same way it works when using the %Installer manifest? Bu that I mean, just calling the ZPM to parse the manifest and install it without relying on the registry and the CLI for now, because all the code I want to import is already local, I just need to create a web application that uses the DispatchClass property.

Rubens Silva · Mar 9, 2020 go to post

I might have to check the IRIS version, because my Caché 2018 doesn't have any traces of the DispatchClass configuration.
Method CSPApplication(
pUrl As %String,
pNamespace As %String,
pDescription As %String,
pDirectory As %String,
pResource As %String,
pRecurse As %String,
pLoginClass As %String,
pGrant As %String,
pCookiePath As %String,
pAuthMethods As %Integer,
pLockCSPName As %Boolean,
pEventClass As %String,
pDefaultTimeout As %Integer,
pDefaultSuperclass As %String,
pUseSessionCookie As %Integer,
pServeFiles As %Boolean,
pServeFilesTimeout As %Integer,
pCustomErrorPage As %String,
pPackageName As %String,
pChangePasswordPage As %String,
pGroupById As %String = "",
pCspZenEnabled As %Boolean = 1,
pInboundWebServicesEnabled As %Boolean = 1,
pTwoFactorEnabled As %Boolean = 0,
pIsNameSpaceDefault As %Boolean = 0,
pPermittedClasses As %String = "",
pAutoCompile As %Boolean = 1) [ Internal ]

Rubens Silva · Mar 6, 2020 go to post

Is your Caché unicode?
Can you try reading the content of headings.en right before you send it?  So that we can see see if that's already corrupted before the HttprRequest takes control or if it's corrupting the input.

Rubens Silva · Mar 5, 2020 go to post

Try defining these settings and see if that solves your issue.

set httpRequest.ContentCharset = "utf-8"
set httpRequest.ContentType = "application/json"
set httpRequest.ContentEncoding = "utf-8"
set httpRequest.NoDefaultContentCharset = 0 // Specifically this one.
Rubens Silva · Feb 10, 2020 go to post

Hello @Ken Earl 
Since you're using a VCS for a personal project. You might want to check Port and see if it fits your needs.
You can also see how it works by reading the tutorial  that I posted sometime ago.