Danny Wijnschenk · Mar 4, 2022 go to post

You can create a unix script like this :

NAMESPACE='DEMO'
irissession SERVER <<EOM
znspace "${NAMESPACE}"
Do ^RoutineWithSQL
Halt
EOM

Where ^RoutineWithSQL will do all the stuff to produce the SQL results (using %ResultSet, or %SQL.Statement, ...).
You can choose to capture the output in unix, or better, let the routine create a file and output the results to the file.

Danny Wijnschenk · Mar 4, 2022 go to post

Hi Jonathan : old-school script is easiest :

Set file = "/usr/tmp/somefilename"
Open file:"WNS":1 Else  Write "Could not open file",! Quit
Use file
;;do your normal output statements
Close file

Nowadays, you can also use %File :
 

Set file=##class(%File).%New("file.txt")
	Write file.Size
	Do file.Open("WSN")
	Do file.WriteLine("This is a line of text")
Danny Wijnschenk · Mar 4, 2022 go to post

If you are using %SQL.Statement, there are other methods that directly output to files :
(https://docs.intersystems.com/iris20212/csp/documatic/%25CSP.Documatic…)


method %Display(pDelimiter As %String = $Char(9))

Display the contents of this object on the current device

• method %DisplayFormatted(pFormat As %String = -1, pFileName As %String(MAXLEN="")="", ByRef pMessages As %SQL.Manager.Messages = "", ByRef pFilesUsed As %String(MAXLEN="")=0, pTranslateTable As %String(MAXLEN="")="")

Display the contents of the result object. If formatted display is available then format the results using the requested format and, if appropriate, open the formatted results using the host OS. The output is directed to one or more files and messages are placed in a result set object. All file names used are returned in an array.

Parameters

Name Description
pFormat

The format applied to the result content. This parameter is also used to determine the file name extension.

Supported formats are:

-1 %Display() format
0 XML
1 HTML
2 PDF (requires a renderer such as FOP)
99 TXT
100 CSV

If pFormat is specified as any number not listed above then it will default to TXT.

pFormat can also be specified as XML, HTML, PDF, TXT or CSV.

pFileName

The base file name to be used to generate actual file names used for output. If no value is specified then a file name will be generated, using the TEMP folder defined for the Cache instance. This value is not expected to include an extension. An extension is added to this value to form the actual file used. Also, if nested results exist then a number is appended to the file name specified to produce a unique name for each result.

pMessages

Instance of a system result set class. If no value is passed then the system message result class is instantiated. This parameter is passed by reference. It is up to the caller to process the result set oref that is returned. pMessages.Count() returns the number of messages contained in the result set. pMessages.%Display() will display the messages on the current device. pMessages.%DisplayFormatted() is also implemented and can be used to display the messages using the selected format.

pFilesUsed

This pass-by-reference parameter will contain the number of files used to display the result content and the name of each file. pFilesUsed is the number of files and pFilesUsed(file_number) is the name of the file. The sequence of the files is the same sequence as the results are processed. For simple result objects, there is a single file. For context objects that can contain result set sequences, the results are output in the order they are returned and the files used are present in pFilesUsed in that same order.

pTranslateTable

This is the translate table used for the output files when the format is CSV or TXT. This parameter is optional.

Danny Wijnschenk · Mar 4, 2022 go to post

Can you try this :

...
set mysqlstat="select * from file.Log where ConfigName='hhhhhhhhhhh"
set sr=##class(%SQL.Statement).%ExecDirect(,mysqlstat)
if sr.%SQLCODE=0 {
  set file="/tmp/temp.txt"  ;or any existing directory path + file name
  open file:"wns":1 Else  Write "could not open file",!
  If $Test {
    use file
    do sr.%Display()
    close file
  }
}
halt
EOM

You should preferably put all the code between znspace... and halt in a routine or class method, and just call it from the script.

Danny Wijnschenk · May 26, 2022 go to post

Hi Eduard,

This works in Caché, i guess it should also work on Iris (vt100 escape codes) :

Danny Wijnschenk · May 26, 2022 go to post
Set Attribute Mode	<ESC>[{attr1};...;{attrn}m
  • Sets multiple display attribute settings. The following lists standard attributes:
    0	Reset all attributes
    1	Bright
    2	Dim
    4	Underscore	
    5	Blink
    7	Reverse
    8	Hidden
    
    	Foreground Colours
    30	Black
    31	Red
    32	Green
    33	Yellow
    34	Blue
    35	Magenta
    36	Cyan
    37	White
    
    	Background Colours
    40	Black
    41	Red
    42	Green
    43	Yellow
    44	Blue
    45	Magenta
    46	Cyan
    47	White
Danny Wijnschenk · Jun 13, 2022 go to post

Be carefull : the second parameter of $zdateh is =1 for US format (mm/dd/yyyy), =4 for European format (dd/mm/yyyy) and =8 for yyyymmdd format.
Luckily, $zdateh is smart enough to know your date is really US and not yyymmdd, but the correct answer is to use $zdateh(x,1) > $zdateh(y,1), and not 8 as second parameter :

write $zdateh("05/01/2022",1)
66230  -> the internal date for may 1st 2022
write $zdateh("05/01/2022",4)
66114  -> the internal date for 5 january 2022
write $zdateh("05/01/2022",8)
66230  -> $zdateh expects yyyymmdd, assumes this is US format (but this is wrong if European format was intended)
Danny Wijnschenk · Jul 19, 2022 go to post

Since you don't always know what a classmethod is doing, the option of setting the Active again is not valid, and the %Reload is the only way to correct.
But my point is : be carefull when you have open instances (that could have changed properties that are not saved yet), and using calls that do SQL operations, you can end up with unforseen results.

Danny Wijnschenk · Jul 22, 2022 go to post

The iristray (or any other IRIS utilities like CStudio, ConnectionGUI, util) should get the captions from the c:\InterSystems\IRIS\bin\<utility><language>.DLL. Where <language> should be UKR in your case (according to windows local settings). Is iristrayUKR.DLL missing in your installation ?
(Close and re-start the systray after you changed/renamed the language dll to see the new language)
 

Danny Wijnschenk · Oct 13, 2022 go to post

There should be a web application defined in your Caché/Iris server that calls the class MSDS.BluMicello.InterfaceServices (in the field REST Dispatch class).
The web application is probably called /Csp/Upload and will define the first part of the url after the domain (/Csp/Upload).

(In theory you could have more that one web application that handle each part of the url part).

Your customer should use the complete url :

e.g. POST http://52.24.106.151:80/Csp/Upload/CreateRoute/BmcDev

This url will call your classmethod cmCreateRouteBmcDev

The :80 in your url implies you are using a separate webserver that internally will connect to your Caché/Iris server.

Danny Wijnschenk · Oct 14, 2022 go to post

Caché/Iris normally use a port like 57772 which goes to the Apache web server that was installed together with Caché/Iris. This web server is best used only for internal usage. In your example the localhost url uses this to acess the service locally when you try that on the server itself.
Because you cannot configure that Apache server for security, you have to use an external webserver where you can completely configure the access (together with the firewall).
An external webserver like IIS or the full blown Apache usually uses 80 as the default public port. In your example you mention the port 80 in with http://52.24.106.151:80/Csp/Upload/CreateRoute/Bmc.
So that's why i think there was an external webserver installed, and you will have to start there if you want to set access rights. (You can also use the firewall to limit any unwanted ip addresses)
Another thing : this class is for receiving REST calls, if you want to send a POST from Cache/Iris, you would have to use the %HtppRequest class.

Danny Wijnschenk · Oct 15, 2022 go to post

You can use indirection :

USER>set field="name"
 
USER>set @field="Henry"
 
USER>write @field
Henry
USER>write name
Henry
Danny Wijnschenk · Oct 15, 2022 go to post

The section you refer too describes the behaviour if a client connects more than 25 times (= 'the maximum' in your text) :
When a client starts with e.g. 3 connections, it counts for 1 license.
When the client keeps adding more connection from the same ip, it will remain taking only 1 license, until it reaches 25 connections, at that time, it will count for 25 licences.
When the client keeps adding connections (e.g. 30 in total), the licence count add also up to 30 for this client.
When the client count drops below 25 again (e.g. 10), the licence count keeps counting all these connections as a separate license (so the client will still occupy 10 licences)
Even if the license count drops to 1, and goes up again to e.g. 5, the client will take 5 licenses.
Only when the client logs out completely, the counting of licenses will revert back to the inital behaviour where all connections below 25 only count for 1 license.
So you do not have to purge licenses : they will go away automatically when the client disconnects (except for csp pages where there is a 'grace' period which still holds the license for a number of minutes)
You just have to make sure your client count does not reach 25, or the client should disconnect when this happens to prevent a high license count.

Danny Wijnschenk · Oct 15, 2022 go to post

Hi Robert,
yes, i never use indirection unless it cannot be done in another way,

(or to show-off what cache object script can do)

Danny Wijnschenk · Oct 21, 2022 go to post

When doing a create table, it is indeed a hashed global name, but when defining a new class in Studio, it is still clasname_"D" (unless the global name becomes too long).

The parameter USEEXTENTSET=1 will alter this behaviour (in class definition or CREATE table statement) :
Global Naming Strategy: you can use the USEEXTENTSET parameter to specify shorter and more efficient hashed global names for data and index lookup operations.

You can use %Library.CompiledStorage to find out what the global name is for a class : https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic…

Danny Wijnschenk · Oct 21, 2022 go to post

I added the way to find out which global name is used in my first reply  : try
 

write ##class(%Dictionary.CompiledStorage).%OpenId("MyPackage.MyClass||Default").DataLocation
Danny Wijnschenk · Nov 18, 2022 go to post

Hi Tiago,

There is always a risk of getting errors after an upgrade, depending how your application uses Caché.
For example : your application could use custom data/code that is stored in the manager's database, and that database will be overwritten in the upgrade, so you will risk loosing data/code. (It is bad practice to store info there, but it is possible) 

Best is to contact the vendor/developers, and test the upgrade by copying the server to a test server and do the upgrade there.
 

Danny Wijnschenk · Nov 28, 2022 go to post

Hi Michel,
Good subject, i like to question the things we are used to, but look strange to the outside world.
I would welcome the possibility to change the precedence to something more 'standard'. When i taught Object Script courses, the left-to-right precedence was always the first thing i mentioned, and it always blew the heads of my students.
Unfortunately, the option is not present, and even if there could be ways to implement such an option by InterSystems (e.g. as a method keyword to alter the precedence), the general behaviour will have to default to the current precedence to not break existing code.
Maybe editors like vs-code can issue warnings when operators are used without brackets in Object Script.

Danny Wijnschenk · Dec 24, 2022 go to post

To check if a database is corrupt : Do ^INTEGRIT

To repair a database : Do ^REPAIR (But if you don't know this utility or the internals of database blocks and pointers : don't use it !!!)

Danny Wijnschenk · Jan 2, 2023 go to post

If on Windows :
 

Start Windows Powershell (Admin)

C:\ cd /intersystems\cache\bin (the directory where you installed caché)
C:\Intersystems\cache\bin> ./ccontrol all  (this should open a text file with the instances you have, note the name of your instance, it is 'cache' in my example)

    Instance          Version ID        Port   Directory
    -------------     ----------        ----   ---------                   
up  cache             2018.1.2.309.0    1972   c:\intersystems\cache

If Caché is not down :
C:\Intersystems\cache\bin> ./ccontrol stop cache

To start Caché in emergency mode :
C:\Intersystems\cache\bin> ./ccontrol start cache /EmergencyId=tempuser,temppw (in my case, i got Win Defender warnings, accepted access)

Verify Caché is running :
C:\Intersystems\cache\bin> ./ccontrol all

Launch Caché management portal, login with tempuser and temppw, go to System Admin -> Users (might have to login again with temp credentials)
Change pw for your user(s).

Restart Caché

Danny Wijnschenk · Jan 5, 2023 go to post

Hi Larry,
Can yo start from the command prompt without emergency mode (ccontrol start trycache) ?
If yes, the help mentions that emergency mode is not using the control service, did your control service have specific rights ?

Btw, did you try the default password for SuperUser or Admin. (https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KE…)

ccontrol start <instance name> [<full path and file name of .cpf file>]

                        Starts Caché instance <instance name>, optionally using the specified .cpf file.

                        If a new .cpf file is specified, it becomes the default startup .cpf file.     

            Note:   An optional /EmergencyId=Username,Password can be used

                        to start Caché in emergency mode.  When the EmergencyUserId

argument is supplied, the system starts up in emergency mode in which

only the baseline databases are mounted and access to Caché is governed

by Caché login using that username and password.  Emergency mode is supplied

to give access in the event that privileged users are not available or their password

is forgotten.  Emergency startup is only available from an administrator account.


When Caché is started in emergency mode, the Caché control service is not used.  

This means that if you log out of Windows, all the Caché processes will immediately exit.

Danny Wijnschenk · Jan 11, 2023 go to post

You can use 'client->name as clientname' and .%Get("clientname") or use .%GetData(columnnumber)

Danny Wijnschenk · Jun 13, 2023 go to post

Hi Dinesh,
I am working on a tool that is doing the following :
- create Swagger input file to enable manuel testing of api's (by adding enough comments in the resthandler/methods to generate this automatically)
- create UI to enter scenarios to automate unit/integration tests on api's:
-- call api's with parameters and compare response with expected status/response
-- use response of previous api's in a scenario to populate parameters for next api in scenario (e.g. post returns an id, next put will use the id to change, next delete will delete the id)
-- ability to run a scenario (set of api's) in a transaction, and to rollback in the end (by replacing actual REST call by in-process call)

Danny Wijnschenk · Jun 25, 2023 go to post

Can you show us what you have coded in the catch block ? There should be no problem in handling your own error.