2.  Write a routine to copy (duplicate) all the data from old classes to new ones. (which is not trivial at some point)

Why is it not trivial? If you're not changing class definition  three merges per class should be enough.

Also check that storage definition in the new class is the same as in old class, only pointing to the new globals.

MANAGEDEXTENT=0 may be easier to do, but it raises the risk of accidentally deleting old globals (what are these globals not corresponding to any class? Let's free some space)

On previous versions you can use ^%GSIZE utility:

do ^%GSIZE
Directory name: c:\intersystems\cache\mgr\mdx2json\ =>
 
All Globals? No => No
Global ^Git("TSH")
Global ^
1 global selected from 54 available globals.
Show details?? No => Yes
Device:
Right margin: 80 =>

directory: c:\intersystems\cache\mgr\mdx2json\
Page: 1                           GLOBAL SIZE                        16 Nov 2017
                                                                        11:49 AM
      Global        Blocks       Bytes Used  Packing   Contig.
      --------    --------  ---------------  -------   -------
      Git("TSH")         1              132      2 %         0
 
 
      TOTAL         Blocks       Bytes Used  Packing   Contig.
      --------    --------  ---------------  -------   -------
                         1              132      2 %         0
                                        <RETURN> to continue or '^' to STOP:

I have a Cache-compatible sql script file and each query is separate by white space.

How do you escape white spaces in a query?

 

Anyway, the general approach is:

set file = ##class(%Stream.FileCharacter).%New()
do file.LinkToFile(filename)
while 'file.AtEnd {
  set query = file.ReadLine() // ???
  set rs = ##class(%SQL.Statement).%ExecDirect(, query)
  set sc = rs.%DisplayFormatted(format, outfile)
}

Where:

  • filename - file with queries
  • format - one of  XML, HTML, PDF, TXT or CSV.
  • outfile - file to write results to

I assumed query separation by newline.

Also outfile needs to change between queries as %DisplayFormatted recreates it.

Do you mean web-app settings like in the following screenshot?

Yes.

But why not using basic authentication? Can I consider using it?

It's way better to use CLP because this way Caché tracks authorization and licenses and you don't need to think about it in your app.

Here's some recommendations on securing REST + CSP web apps:

  1. All brokers effectively have Parameter UseSession = 1;
  2. REST web application and client web application allow only authenticated (i.e. password) access.
  3. REST web application and client web application have reasonable Session timeout (i.e. 900, 3600).
  4. REST web application and client web application have the same GroupById value.
  5. REST web application and client web application have the same cookie path.

Client web application can have a custom Login Page (or just use default login page, that's okay too).

Hello, Amir!

  1. That was just a quick testing in the existing class. For the actual project of course I would write this method in a separate utility class. you are completely right on that. Still, I edited my code to avoid bad examples.
  2. I  need a method to return storage position of property in $lb at runtime, and I also can't modify existing classes to achieve that (for example by generating a method for each class with precomputed property name=storage position values).
  3. Impossible, because 2.

 

That said I do agree that idea with method generators is good, just not applicable in this exact case.