Eduard Lebedyuk · Jul 10, 2017 go to post

You'll need a Business Service and a Business Operation.

Business service runs every X seconds (or you can configure a more complicated schedule) gets a list of hosts and calls Business Operation. Business Operation performs the request.

Eduard Lebedyuk · Jul 9, 2017 go to post
do ##class(%Compiler.UDL.TextServices).GetTextAsString(namespace, class, .text)
write text
Eduard Lebedyuk · Jun 29, 2017 go to post

Make plaintext property triggered computed on insert/update rather than always computed.

Property  PlainText As %String(MAXLEN="") [ SqlComputeCode = {set {*} = ##class(%iKnow.Source.Converter.Html).StripTags({HtmlText}}, SqlComputed, SqlComputeOnChange = (%%INSERT, %%UPDATE) ];
Eduard Lebedyuk · Jun 27, 2017 go to post

There's no need to search for the /s1/s2/s3 in the second template, as the first template would send every node into the second template. So your XSLT should probably look like this:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
     
    <xsl:template match="//@* | //node()">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="//s3" >
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            Content Replaced
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>
Eduard Lebedyuk · Jun 27, 2017 go to post

As both Angular and Zen manage page state, combining them it does not seem particularly promising.

Eduard Lebedyuk · Jun 26, 2017 go to post

Thank you, Benjamin.

I thought TRANSFORMATIONSPEC parameter could have been used somehow, but I'll try your suggested approach.

Eduard Lebedyuk · Jun 26, 2017 go to post

Are these (Caché and Ensemble) systems in production or development?

Emsemble is Caché + Some classes. So the easiest solution would be to move Caché application into Ensemble instance.

Example of calling Ensemble from Caché is available in Demo.ZenService.Zen.WeatherReportForm class, GetWeatherReport method in ENSDEMO namespace.

Eduard Lebedyuk · Jun 25, 2017 go to post

Install latest version (we're currently on v4) from here. Installation instructions are there too (just download and import, that's all).

Eduard Lebedyuk · Jun 21, 2017 go to post

I think the most important part of source control file structure is mirroring package structure in Studio, since that is the view we spend the most time with. That said it looks something like this:

root/
    Package1/
              Class.cls
              Class2.cls
              Routine.mac
              Include.inc
     Package2/ 
              Class.cls
              Class2.cls
              Routine.mac
              Include.inc

Additionally:

  1. Web app should be stored in a separate repository.
  2. If there's docs/dictionaries/etc, then all sources should be in a /src folder instead of repository root.
  3. All libs/modules/etc should be moved into their separate repositories each and plugged in as a submodules.
  4. Builds, if any should not be stored in a repo but rather meta-managed (releases).
  5. Commit messages and granular commit history is one of the most helpful things when analysing project history, enforce commit message style (title is the most important i.e. PART/SUBPART - thing done in a commit).
Eduard Lebedyuk · Jun 21, 2017 go to post

Can you execute in SMP:

SELECT cast('0x1F' AS varbinary(1549))

Not sure why

0x1F8B08000000...

is unescaped though.

Eduard Lebedyuk · Jun 19, 2017 go to post

I would like to, on every file change export the whole project to XML

What do you want to achieve with that?

Eduard Lebedyuk · Jun 17, 2017 go to post

You can project collection property as a child table.

Property MyList as list of Object(STORAGEDEFAULT="array");

Note that it changes class storage, so existing data should be moved to the correct new place.

Several months ago I wrote a small utility class to accomplish exactly that.

Or if you don't have a lot of different classes and data dependencies, you can just export to XML, add STORAGEDEFAULT and import XML.

Eduard Lebedyuk · Jun 15, 2017 go to post

Is it possible to change underlying data model so that 1 row = 1 main object?

Class UserPrefs {

Property Username;

///  Color/Number are keys, and this can be indexed
Property Preferences As Array Of %String(SQLPROJECTION = "table/column");

Parameter ROWLEVELSECURITY = 1;

///Updated for each row when the property 'Preferences' changes
Property %READERLIST As %String [ SqlComputeCode = {set {*} = ##class(Users).%SecurityPolicy()}, SqlComputed, SqlComputeOnChange = Preferences ];

}

You can use SQL to insert into child table. Not sure if it would actually trigger a %READERLIST recalculation (maybe try %%INSERT) but worth a try.

Eduard Lebedyuk · Jun 15, 2017 go to post

16.2 has %ZEN.Auxiliary.altJSONProvider, which has same method signatures but may be preferable (faster).

Eduard Lebedyuk · Jun 13, 2017 go to post

Traced stuff to %SOAP.WebBase and for example in WriteSOAPHeaders there are these lines:

$$$XMLSetBuffer("  </"_..#SOAPPREFIX_":Header>")
$$$XMLWriteLine

I guess there's really no way to remove new lines without a very heavy customization.

Eduard Lebedyuk · Jun 13, 2017 go to post

Using SQLComputeCode and SQLComputeOnChange %READERLIST property is stored but gets recalculated on every SQL and Object INSERT/UPDATE/%Save:

Class Utils.RLS Extends %Persistent
{

Parameter ROWLEVELSECURITY = 1;

Property %READERLIST As %String [ SqlComputeCode = {set {*} = ##class(Utils.RLS).GetAccess({%%ID})}, SqlComputed, SqlComputeOnChange = (%%INSERT, %%UPDATE) ];

Property data As %String;

ClassMethod GetAccess(Id) As %String
{
    return:Id>3 "_SYSTEM"
    return "%All"
}

/// do ##class(Utils.RLS).Fill()
ClassMethod Fill(N = 5)
{
    do ..%KillExtent()
    for i=1:1:N {
        &sql(insert into Utils.RLS(data) values(:i))
    }

    zw ^demo.testD,^demo.testI

    do ##class(%SQL.Statement).%ExecDirect(,"select * from "_$classname()).%Display()
}
Eduard Lebedyuk · Jun 13, 2017 go to post

Target system is very fastidious about XML. I aim to eliminate all possible variables that may affect XML processing.