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)
  }
}
   

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
}

}

Hi John,

I tried to create the classes you are describing, and they seem to give the correct results in the two SQL statements.

The two query plans are also giving the same access path.

Can you tell me what the outcome (data/error) of the second SQL statement is giving you ? 

I used following classes :

Class User.immst Extends %Persistent
{
Relationship PhysicalRecord As User.pytrn [ Cardinality = many, Inverse = ItemRecord ];
Property imdesc As %String;
}

Class User.pytrn Extends %Persistent
{
Relationship ReportRecords As User.pyrpt [ Cardinality = many, Inverse = PhysicalRecord ];
Relationship ItemRecord As User.immst [ Cardinality = one, Inverse = PhysicalRecord ];
Property pypqty As %String;
}

Class User.pyrpt Extends %Persistent
{
Relationship PhysicalRecord As User.pytrn [ Cardinality = one, Inverse = ReportRecords ];
Property pypqty As %String;
}

 

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

Hi Jimmy,

I don't use Ensemble , but maybe the 4th parameter is not in the right format : see doc(https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EHTTP_outbound#EHTTP_C7322547) :

The pData argument is an array. The top node of the array is not used. Each subnode is subscripted by the index of the corresponding form variable in the pFormVarNames list. The value at a given subscript should be specified as follows:

  • For a form variable (varname) with a single value, the value at pData(“varname”) should be the form data value to send. There should be no subnodes.

  • For a form variable (varname) with multiple values, the value pData(“varname”) should be the count of the values. Each of the values for this form variable should appear in a subnode, subscripted by its position in the node.

  • To send a request body instead of form variables, leave pFormVarNames empty and pass the body text as the pData argument.

So, can you try to call the PostURL with pRequest.%ToJSON()

In Caché - using %Net.HttpRequest - it works like this :

Set objHttpRequest = ##class(%Net.HttpRequest).%New()
Set objHttpRequest.ContentType = "application/json"
Set objHttpRequest.Server = "dummy.restapiexample.com"
Set pRequest = {"name":"abc1jim23","salary":"123","age":"23"}
Do objHttpRequest.EntityBody.Write(pRequest.%ToJSON())
If objHttpRequest.Send("POST", "/api/v1/create") {
Set objHttpResponse = objHttpRequest.HttpResponse
If $IsObject(objHttpResponse.Data) {
     Set objStream = objHttpResponse.Data
     Set json =""
     While ('objStream.AtEnd) {
          Set json = json _ objStream.ReadLine()
     }
Else {
     Set json = objHttpResponse.Data
}
Set httpStatus = objHttpResponse.StatusCode
Write "Status : ",httpStatus,!
Write "Response : ",json,!
}

Any of the following is possible, but this will only work if you want to keep the data in the two namespaces for that class exactly the same : 

  • Map the globals that are used by the persistent class to the other namespace.

OR

  • Change the global names in the Class Storage definition (DataLocation, IDLocation, IndexLocation, StreamLocation) and add a namespace reference to it, like this :
Storage Default
{
<Data name="customerDefaultData">
...
<DataLocation>^["USER"]test.customerD</DataLocation>
<DefaultData>customerDefaultData</DefaultData>
<IdLocation>^["USER"]test.customerD</IdLocation>
<IndexLocation>^["USER"]test.customerI</IndexLocation>
<StreamLocation>^["USER"]test.customerS</StreamLocation>
<Type>%Library.CacheStorage</Type>

Be careful if properties are pointing to other persistent classes as well !

You can run the Job command with a timeout parameter, and check if the job has really started with the $TEST variable :

USER> JOB ##class(TestFramework.API.E2E.Service).RunCases()::0

USER> Write $TEST

Should be 1 if the classmethod was started, 0 if the job timed out and did not start

In the second case it can be a license problem, check  https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GSA_license#GSA_license_capacity

Hi Kurt,

Some old terminal emulators cannot work with UTF8.

I used AniTa which had the same problem connecting to a Caché Unicode server.

I tried TeraTerm which is free and can at least work with UTF8 and VT320 emulation, but i haven't tried all our terminal tricks yet to see if it can do the job for 100%.

Once you start TeraTerm, don't forget to change in Setup->General the language to UTF-8,.

Setup -> Save Setup will save all your changes to a Teraterm.ini file so they will be in effect the next time.

Are you unable to POST anything, or are you looking for an easy way to construct JSON in 2012.1.4 ?

The class to POST something is %Net.HttpRequest, you need to send the form as a  stream.

In recent (2016.2 upward) versions, you can create a dynamic object and convert it to a JSON string, but 2012.1.4 is lacking this  JSON support,.

But you should still  be able to send a string in the body part formed (manually) as correct JSON :

    Set httprequest=##class(%Net.HttpRequest).%New()
    Set httprequest.Server="apitest.authorize.net"
    Set httprequest.Https=1
    Set httprequest.SSLConfiguration = "TEST"  ;make sure this SSL is created via mgmt security portal
    Do httprequest.EntityBody.Write("{""createTransactionRequest"":{""merchantAuthentication"":{""name"":""gfufet9QVgT5P"",""transactionKey"":""8pg6FJjxuekeY62m""},""refId"":""123456"",""transactionRequest"":{""transactionType"":""authCaptureTransaction"",""amount"":""5"",""payment"":{""creditCard"":{""cardNumber"":""5424000000000015"",""expirationDate"":""2020-12"",""cardCode"":""999""}}}}})")
    Do httprequest.Post("/xml/v1/request.api")
    Do httprequest.HttpResponse.OutputToDevice()

Hi Eduard,

I have found some old code to visualize a WordCloud using iKnow.

This code is showing the concepts of a source, and adds weight according to a simple tf/idf score.

I have put the (old) code on github here

The code is using %iKnow.Queries.EntityAPI.GetBySource, and the CSP page is using the jquery library from AwesomeCloud to render the wordcloud. (Today I would not use CSP pages anymore with Caché script or CSP tags, but like i said, it is old code;)

After importing the xml from github, the url to call looks like this :

http://localhost:57772/csp/user/WordCloud.csp?domain=pubmed&source=240

and the result would be something like :

Caché can call any OS command (if it has enough rights) by using $ZF(-1 (see also article https://community.intersystems.com/post/callexecute-exe-windows-objectsc...)

In the OS command script, you can use ccontrol to the other Caché instance (see article https://community.intersystems.com/post/starting-routine-windows-command... as an example)

But i would prefer using Webservices to call a routine from one Caché instance the other :  then you don't need to put the two Caché instances on the same server : see  webservices doc https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY...

If you substract the current day-of-the month from the current date in $horolog format, you will end up with the first day of the current month in $horolog format :

Write $horolog - $zdate($horolog, 4) + 1

If your date is in another format, convert it using $zdateh/$zdate, see also :

http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...

and

http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...

Turn on Auditing (Portal -> System Admin -> Security -> Auditing -> Enable Auditing, configure system events to audit login failures ).

It can give you a clue on why you are getting Access Denied.

It could be an issue of licensing : check the system dashboard for Licensing use (maybe you have too many connections open).

If all this does not help, you can also turn on ODBC logging in the ODBC DSN.