Danny Wijnschenk · Jul 16, 2019 go to post

To start debugging in Studio, you first have to set your method as a debug-target : right-click on the method header and choose 'Set DoMyWork as debug target'.

Then set a breakpoint  anywhere in the method you want to start debugging (click on F9  to toggle breakpoints)

Then start the debugger in the menu  or Ctrl-F5.

If you want to call your method with some predefined arguments, it is better to create another method that will call ..DoMyWork(.arg1, arg2) and use this method as your debug-target, or  better, in the debug menu, click on debug-target and add proper arguments in the classmethod.

If you wish to debug in terminal, you need to use the command Break with some options :

USER> Break "S+" Do ##class(MyPackage.MyClass).DoMyWork(.arg1)
^
<BREAK>zDoMyWork+1^...
USER 2d1> 
 

Option S or L with + or - depending if you want to debug instruction by instruction (S) or Line by line (L), debug into methods (+) or execute them(-).

Use G (or Goto) to go step by step, Use Break "C" to clear debugging.

More info on Break : https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_debug

Danny Wijnschenk · Aug 6, 2019 go to post

Hi Sergio,

I have the following code that will do what you need, but i don't see this as the best approach since it is more complicated than a bunch of If's. 

But it works, and it shows that you do anything in ObjectScript!

Class MyPackage.MyClass
{
ClassMethod MyMethod(p1 = 1, p2 = 2, p3 = 3)
{
Write p1,"-",p2,"-",p3,!
}
ClassMethod Test()
{
Do ..FromJson({})
Do ..FromJson({"P1":"first value""P2":"second value"})
Do ..FromJson({"P1":"first value""P3":"third value"})
Do ..FromJson({"P2":"second value"})
}
ClassMethod FromJson(json)
{
Set call="(json) Do ##class(MyPackage.MyClass).MyMethod("  //we need to pass json as input param to xecute
Set first = 1
For jsonProp = "P1","P2","P3" {
If 'first Set call=call_","
//Set call=call_$Select(json.%IsDefined(jsonProp):"json."_jsonProp,1:"") //same as $Property, but doc mentions to use $Property instead
Set call=call_$Select(json.%IsDefined(jsonProp):"$Property(json,"""_jsonProp_""")",1:"")
Set first = 0
}
Set call=call_")"
Xecute (call,json) //pass json as input parameter
}
}
Danny Wijnschenk · Aug 8, 2019 go to post

Hi Robert,

take a look at the %SYS.Journal.File , %SYS.Journal.Record and %SYS.Journal.SetKillRecord classes.

It contains methods & properties to loop through the journalfiles, and get the information of all changes. You could then write this info in a (summarized) file and email it.

ClassMethod ShowJrn(file = "C:\InterSystems\Cache\mgr\journal\20190804.001")
{
  Set jrnforef = ##class(%SYS.Journal.File).%OpenId(file)
  set record = jrnforef.FirstRecordGet()
  While record'="" {
      If record.%ClassName()="SetKillRecord" {
        Write record.Type,! ;6 = SET, 7 = KILL
        Write record.GlobalReference,!
        Write record.OldValue,!
        Write record.NewValue,!
    }
    Set record = jrnforef.GetRecordAt(record.NextAddress)
  }
}
   
Danny Wijnschenk · Aug 14, 2019 go to post

Are you pointing the filestream to the correct file : is there any data in the filestream (you are using \Temp\GaganTest : it will use the same drive as the one where your database is located, also no extension is mentioned)

You can set a timeout (Set ftp.Timeout = 100) if the ftp server times out when uploading big files.

The file size will not effect your cache.dat size.

Danny Wijnschenk · Sep 24, 2019 go to post

Any special mappings in that namespace? Size ?

Try to export classes and routines from that namespace and import them in a new namespace, is it still slow in the new namespace?

Danny Wijnschenk · Sep 26, 2019 go to post

Hi Everardo,

I have seen the error, but not in testing ensemble messages :

USER>Write _test1
 
<FUNCTION>GetProp+2^%CDCalBk
USER 3e1>

variables preceded by _ (underscore) are only to be used in Caché Direct (VISM) programs.

Are you running any code that uses too much underscores ?

For example :

USER>set var1=1
 
USER>set var2="a"_var1
 
USER>set var2="a"__var1  ;two underscores
 
<FUNCTION>GetProp+2^%CDCalBk
USER 3e1>
Danny Wijnschenk · Nov 14, 2019 go to post

It all depends from which backup and journal files you start the recovery.

You need to start from a backup  & all journal files from before your event that killed the data (and stop the restore just before that event, which i assume is 11/14/2019 15:18:56). What happened on this time : did you kill some data or remove the class ?

It seems that the restore did not fully restored the class definition : can you go into studio and recompile the class ?

In the class definition, you will find the actual global names where the data is stored (by default it will be ^User.MemberD and ^User.MemberI (and possibly ^User.MemberS). Do you have these globals after the restore ?

Danny Wijnschenk · Nov 27, 2019 go to post
set myVar="",$piece(myVar,"=",31)=""  ;repeat = 30 times

works also with multiple characters :

USER>set myVar="",$piece(myVar,"=?",31)=""
 
USER>write myVar
=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?=?
 
Danny Wijnschenk · Jan 6, 2020 go to post

Hi Youness,

how are you exporting the data to excel : as a .csv file ?

I am not sure if this is your problem, but when exporting data (numbers) to excel,  you need to be careful on the decimal character you are using : if i export numbers with a decimal point, and my locale is set on comma as a decimal , the numbers are treated as strings, and no validation works.

Danny Wijnschenk · Feb 7, 2020 go to post

Hi Yone,

what version are you using ? From Caché/Ensemble 2016.2 you could create your json directly like :

Set body = {
     "app_id""e47322de-64c8-43c5-a1b7-42aa6409eb48",
     "headings"{"en":"Cita Atencion Primaria","es":"Cita Atencion Primaria"},
     "subtitle"{"en":"C.P. ISORA","es":"C.P. ISORA"},
     "contents"{"en""Next appointment""es""Siguiente cita"},
     "data":{
                "centro""C.P. ISORA",            
                "fecha""yyyy/mm/dd",       
                "hora""hh:mm",
                "profesional""nombre del profesional",
                "nomUsuario""nombre del usuario",
                "codcita""idCita",
                "sepuedeborrar"1
     },
     "include_player_ids"["2b3a6be7-5475-4871-b3be-a50eb2ec6034"]
}
Do httpRequest.EntityBody.Write(body.%ToJSON())
Danny Wijnschenk · Jul 5, 2020 go to post

Hi Anthony,

Look at the doc for the property EntityBody, you can do something like :

Set body = { "MyKey":"MyValue" }
Do httpRequest.EntityBody.Write(  body.%ToJSON() )

 property EntityBody as %GlobalBinaryStream;

When an Entity-Body is included with a message, the data type of that body is determined via the header fields Content-Type and Content- Encoding. These define a two-layer, ordered encoding model.

This is a stream so to insert into this stream use:

Do oref.EntityBody.Write("Data into stream")
Danny Wijnschenk · Jul 5, 2020 go to post

Hi Robert,

Handy to know i can still use this whenever the internet goes down, and i need to dial into my customers with a 300 BAUD modem !

Danny (fellow dinosaur)

Danny Wijnschenk · Aug 3, 2020 go to post

You should not always rely that all data is in cache and processing of the data can be done before a timeout occurs. (data will grow, more users can use the system, ...)
For REST queries that have the risk of running too long,  you can do as follows :
- the api responds immediately with a queryId (some sequential number),
- the query continues to run in the background, and the response of the query will be stored in some table/global/...  with the queryId as the key
- a separate api call is used by the client (with the queryId) to get the response (or a 'not ready' status when the query is still running).
It is a little more work on the client to call once to launch the query, and a second.. time to get the results, but you are safe when your systems  grows with data or users

Danny Wijnschenk · Aug 21, 2020 go to post

What error are you getting ? Can you call the function in terminal ?

SQL queries via xDBC are cached, you can remove the cached queries in the managment portal, Explorer -> SQL :

Danny Wijnschenk · Sep 3, 2020 go to post

Look at the file CodeSnippets.txt which is located in the Documents\InterSystems directory on your windows pc where Studio is installed

Danny Wijnschenk · Sep 3, 2020 go to post

The maximum length of a column is defined by the MAXLEN parameter in the class definition.
The maximum string length is 32,767 and 3,641,144 if long strings are enabled.
If you use Streams as data type, you don't have a limit and can use Substring(column, from, maxlen) in SQL

Danny Wijnschenk · Sep 3, 2020 go to post

When i use %SQL.Statement, and I pass sql to the %Prepare method as an array, it will start to fail  around 11,400 characters

Danny Wijnschenk · Sep 14, 2020 go to post

I don't see any performance disavantages in using SOAP or REST to call classmethods of other IRIS instances compared to ECP.
And SOAP/REST is available in all IRIS license types, in contrast with ECP.

Danny Wijnschenk · Sep 14, 2020 go to post

Hi Hansel,

Temp should only grow because of use of temporary globals. (^IRIS.temp, ^mtemp, or any other global explicitly mapped to IRISTEMP)
In my experience, sudden growth of temp is mostly due to an SQL query that is doing a join or order of non-indexed columns.
When you restart Iris, you could delete the iristemp (it will recreate it), you can also set a param to truncate it automatically at startup:
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cl…
 

Danny Wijnschenk · Mar 10, 2021 go to post

I am using read queue to be able to monitor the output from Image like this :
 

Parameter INSTALLDIR = "c:\ImageMagick\";

/// Do ##class(Image.Utils).Resize(file, newFile500, "500X500", .msg)ClassMethod Resize(fileOrig As %String, fileNew As %String, newSize As %String, ByRef output as %String) As %Boolean{  Quit ..Convert(fileOrig, "-resize "_newSize_"^> """_fileNew_"""", .output)}

ClassMethod Convert(file, options, ByRef output as %String) As %Boolean{  Do ..Cmd("convert """_file_""" "_options, .output)  Quit 1}

ClassMethod Cmd(command As %String, ByRef outputStr As %String){  Kill outputStr  Try {    Set cmd=..#INSTALLDIR_command    Open cmd:("RQ")    For {      Use cmd Read line If $ZEOF=-1 Quit      Set outputStr($i(outputStr))=line    }catch {  }  Close cmd}
Danny Wijnschenk · Mar 10, 2021 go to post

Hi Daniel, did you do a zwrite output ? It is an array, so if output=2 there should be more data in it.

(usually output is empty when the command was executed successfully)
I like using using OPEN because any shell output message is captured and can be logged.
e.g.

do ##class(Image.Utils).Convert("a.jpg","-resize 10X10", .output)
zwrite output
output=2
output(1)="convert: UnableToOpenBlob 'a.jpg': No such file or directory @ error/blob.c/OpenBlob/3109."
output(2)="convert: MissingAnImageFilename `10X10' @ error/convert.c/ConvertImageCommand/3272."