go to post Dmitry Maslennikov · Jun 1, 2017 Just for debugging, you can use this command Do LOG^%ETN("some message") It will collect all variables, on every stack level. And you can find this logs in SMP by System > System Logs > View Application Error Log > Application Error Dates > Application Errors. But be careful, this is only for debugging, because creating a log, may take a long time.
go to post Dmitry Maslennikov · Jun 1, 2017 I would suggest that you working on frontend side in the browser, and call some REST API written in Caché or not, it does not matter. So, your code in JavaScript. var data = getDateFromRest(); // you got some data from server, no so matter how you did it. I suggest that your data is array, so, you could use map function and it contains something like this [{ "title": "car", "currency": "USD", "cost": "10000" }] var newData = data.map(el => { return { name: el.title, value: el.cost + el.currency } }) will give you new array [{ "name": "car", "value": "10000USD" }]
go to post Dmitry Maslennikov · Jun 1, 2017 Next time, when you have a question, please create it from the main page, not as a comment to the post. In this case, you may get the response much quicker.And to you question, on which side you have to do such transformation? Do you call some external REST API from Caché, or do you call some API written in Caché from your WebApplication which worked in Browser, or another way?
go to post Dmitry Maslennikov · May 31, 2017 I have not used UnitTests before but looks like, you can just analyze ^UnitTest.Result global, by latest index. USER>set sc=##class(%UnitTest.Manager).DebugRunTestCase("", "MyPackage.Tests","","TestAdd") =============================================================================== Directory: /opt/cache/dev/tutorials/UnitTestEx/ =============================================================================== (root) begins ... MyPackage.Tests begins ... TestAdd() begins ... AssertEquals:Test Add(2,2)=4 (passed) AssertNotEquals:Test Add(2,2)'=5 (failed) <<==== **FAILED** (root):MyPackage.Tests:TestAdd: LogMessage:Duration of execution: .000045 sec. TestAdd failed MyPackage.Tests failed Skipping deleting classes (root) failed Use the following URL to view the result: http://192.168.56.140:57774/csp/sys/%25UnitTest.Portal.Indices.cls?Index=5&$NAMESPACE=USER Some tests FAILED in suites: USER>zw ^UnitTest.Result(^UnitTest.Result) ^UnitTest.Result(5)=$lb("2017-05-31 12:08:01",.0013,"MacBook-Pro.local","CACHE","Cache for UNIX (Apple Mac OS X for x86-64) 2016.2 (Build 736U) Fri Sep 30 2016 11:56:58 EDT","USER","","") ^UnitTest.Result(5,"(root)")=$lb(0,.001218,"","There are failed TestCases") ^UnitTest.Result(5,"(root)","MyPackage.Tests")=$lb(0,.000554,"","There are failed TestMethods") ^UnitTest.Result(5,"(root)","MyPackage.Tests","TestAdd")=$lb(0,.000045,"","There are failed TestAsserts") ^UnitTest.Result(5,"(root)","MyPackage.Tests","TestAdd",1)=$lb(1,"AssertEquals","Test Add(2,2)=4") ^UnitTest.Result(5,"(root)","MyPackage.Tests","TestAdd",2)=$lb(0,"AssertNotEquals","Test Add(2,2)'=5") ^UnitTest.Result(5,"(root)","MyPackage.Tests","TestAdd",3)=$lb(1,"LogMessage","Duration of execution: .000045 sec.") I think from this global, will be quite easy to extract needed information to any format.
go to post Dmitry Maslennikov · May 31, 2017 I don't know how you call Caché method from Jenkins, but anyway you can use $SYSTEM.Process.Terminate in Caché script to exit with an exit status. Something like this. set tSC=##class(%UnitTest.Manager).DebugRunTestCase(....) if 'tSC do $SYSTEM.Process.Terminate(,1) halt I suggest that you may use csession or cterm to call Caché code, then you should get exit code and send it to Jenkins, which will be recognized by Jenkins as an error and will fail the job.
go to post Dmitry Maslennikov · May 30, 2017 I would give you a list from fastest to slowest.Local variables. Yes, this sort of variables is limited by memory, but currently, memory cost not so much and if you need only 1GB per server, it should be quite easy to get. By default, the process has only 256MB of memory for local variables, but you can extend it on a fly with special variable $zstorage, and maximum level is 2TB.Process private globals (^||Global), it is already globals but works faster than any other types of globals, but slower than local variables. It is not limited by memory per process, but stored in memory, and could be moved to the disk if you exceed global buffer size.Globals mapped to CACHETEMP (e.g. ^CacheTemp*, ^mtmp), such globals faster than usual globals because in this database journaling of any changes is switched off. Every other Globals, but still depends on is this database used journaling changes or if changes were made in a transaction.
go to post Dmitry Maslennikov · May 25, 2017 Error with code 126 it is, usually dependencies error. Looks like you loose some of system libraries which used by zlib1.dll.I would suggest using Dependency Walker, to find what you need.
go to post Dmitry Maslennikov · May 18, 2017 Looks like you've copied some example from the documentation. But removed some by your opinion not needed lines. Original code looked like: //create Ensemble request message with given ID set request=##class(ESOAP.CustomerRequest).%New() set request.CustomerID=ID //send Ensemble request message set sc= ..SendRequestSync("GetCustomerInfoBO",request,.response) if $$$ISERR(sc) do ..ReturnMethodStatusFault(sc) You left only the last line. Where checked result from the previous one, in variable sc, as this variable is not defined in your code you got this error in SOAP <UNDEFINED>zTestOperation+1^Test.WebService.1 *sc
go to post Dmitry Maslennikov · May 4, 2017 When you define UrlMap, you should remember, that Caché uses Regular expressions. So, you can just put (?i) before Url, to make regular expression case insensitive XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ] { <Routes> <Route Url="(?i)/user" Method="POST" Call="User"/> <Route Url="(?i)/emailactivation" Method="POST" Call="EmailActivation" /> <Route Url="(?i)/login" Method="POST" Call="Login"/> </Routes> }
go to post Dmitry Maslennikov · Apr 29, 2017 It is possible to get some errors depends on how long query in your URL. It is not a good idea to have such long values in a query. And such value should be escaped to be valid to place in URL. Instead much better to send data as a form in POST.
go to post Dmitry Maslennikov · Apr 25, 2017 command WRITE, outputs $listbuild in binary format, if you would use ZWRITE, it would show you $lb I've just made variable from your output USER>zzdump val 0000: 02 01 04 01 61 61 04 01 4A 4A ....aa..JJ USER>zwrite val val=$lb("","aa","JJ") Just read the documentation and you will get everything needed to work with $listbuild
go to post Dmitry Maslennikov · Apr 24, 2017 Caché stores data from tables in globals in $listbuild format. So you can use $listget, to get value from the particluar column, but you should know number for your column.
go to post Dmitry Maslennikov · Apr 7, 2017 Look at the documentation Menu, Edit-> Find or Find in files
go to post Dmitry Maslennikov · Mar 26, 2017 you should look at XSLT, it can help transform xml as you need ClassMethod SplitXML() { for item="market","product" { set params("path")="/doc/"_item Set tSource=##class(%Dictionary.CompiledXData).%OpenId(..%ClassName(1)_"||XML").Data Set tXSL=##class(%Dictionary.CompiledXData).%OpenId(..%ClassName(1)_"||XSL").Data // Transform the source according to the XSL Set tSC=##class(%XML.XSLT.Transformer).TransformStream(tSource,tXSL,.tOutput,,.params) If $$$ISERR(tSC) Quit write !! // Output the result to the screen Set tSC=tOutput.OutputToDevice() } } XData XML { <?xml version="1.0"?> <doc> <header></header> <product><test>1</test></product> <market><test2>2</test2></market> </doc> } XData XSL { <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:param name="path"></xsl:param> <xsl:output method="xml" indent="no"/> <xsl:template match="/"> <xsl:copy-of select="$path"/> </xsl:template> </xsl:stylesheet> } will output like below USER>d ##class(Test).SplitXML() <?xml version="1.0" encoding="UTF-8"?><market><test2>2</test2></market> <?xml version="1.0" encoding="UTF-8"?><product><test>1</test></product>
go to post Dmitry Maslennikov · Mar 26, 2017 you can do it with ccontrol tool Syntax: ccontrol create <instance name> <parameters> Description: Create an instance's entry in the Cache registry. Parameters: directory=<installation directory name> versionid=<version identifier> Example: ccontrol create mystuff directory=/usr/cachesys versionid=2008.2.0.357.0
go to post Dmitry Maslennikov · Mar 10, 2017 In Caché there is no any such classification for errors. Developer should decide it depends on his own tasks and needs.
go to post Dmitry Maslennikov · Mar 6, 2017 this port is from internal Apache which was installed by default with Caché. And should be used only in development.For production, or pre-production, you should use some external WebServer, IIS (if you use Windows), Apache or Nginx. You can find more information about configuration all of this webservers, in the documentation.
go to post Dmitry Maslennikov · Feb 28, 2017 If you would look carefully to your code, you would see this placeall HTML should be between &html< and >But in your code, some of HTML outside of this command.
go to post Dmitry Maslennikov · Feb 27, 2017 Looks like you forgot to define web application for your REST Service. Please look at the documentation. And at this part:Each subclass that has its own entry point must have its own CSP web application. You define the CSP web application and specify its security for on the Management Portal’s [Home] > [Security Management] > [Web Application] page, which you can access by clicking System Administration, Security, Applications, and Web Applications. When you define the CSP web application, you set the Dispatch Class to the name of the custom subclass of %CSP.REST and specify the first part of the URL for the REST call as the name of the application.
go to post Dmitry Maslennikov · Feb 24, 2017 Since 2011.1 version was added %vid to achieve some paging functionality. Some more details. SELECT *, %vid FROM (SELECT ....) v WHERE %vid BETWEEN 5 AND 10