Localization in Caché DBMS

Simple example:

  1. Class dc.test Extends %ZEN.Component.page
    {
    
    Parameter DOMAIN = "DCTEST";
    
    XData Contents [ XMLNamespace "http://www.intersystems.com/zen" ]
    {
    <page xmlns="http://www.intersystems.com/zen">
      <radioSet id="lng"
        label="Текущий язык"
        layout="vertical"
        displayList="Португальский,Русский"
        valueList="pt-br,ru"
        value="ru"
        onchange="zenPage.changeLang(zenThis.value);"
      />
      <form>
        <text label="Описание" required="true" requiredMessage="обязательно." />
        <submit caption="Сохранить"/>
      </form>
    </page>
    }
    
    /// User clicked to change preferred language.
    ClientMethod changeLang(lng) [ Language = javascript ]
    {
      var ok this.SrvChangeLang(lng);
      self.document.location.reload();
    }
    
    /// Change preferred language for this session and page
    ClassMethod SrvChangeLang(lngAs %Boolean ZenMethod ]
    {
      %session.Language=lng
      %response.Language=lng
      q $$$YES
    }
    
    Method %OnAfterCreatePage() As %Status
    {
      ..%SetValueById("lng",%session.Language)
      Quit $$$OK
    }
    
    }
  2. USER>##class(%MessageDictionary).ExportDomainList("messages_ru.xml","DCTEST","ru")
    
    Result (messages_ru.xml):
    
    <?xml version="1.0" encoding="UTF-8"?>
    <MsgFile Language="ru">
       <MsgDomain Domain="DCTEST">
          <Message Id="358179803">Текущий язык</Message>
          <Message Id="1805419696">Португальский,Русский</Message>
          <Message Id="2153752096">Описание</Message>
          <Message Id="2835101332">обязательно.</Message>
          <Message Id="3683485237">Сохранить</Message>
       </MsgDomain>
    </MsgFile>
    
  3. messages_pt-br.xml:
    
    <?xml version="1.0" encoding="UTF-8"?>
    <MsgFile Language="pt-br">
       <MsgDomain Domain="DCTEST">
          <Message Id="358179803">Idioma atual</Message>
          <Message Id="1805419696">Português,Russo</Message>
          <Message Id="2153752096">Descrição</Message>
          <Message Id="2835101332">é obrigatório.</Message>
          <Message Id="3683485237">Salvar</Message>
       </MsgDomain>
    </MsgFile>
    
    USER>##class(%MessageDictionary).Import("messages_pt-br.xml")
  4. Profit!
USER>w $zv
Cache for Windows (x86-32) 2015.2 (Build 664_3U) Wed Aug 12 2015 12:29:34 EDT

The date is saved to the database correctly.

Class dc.A Extends %Persistent
{
Property DOB As %Date;
}

Class dc.MVC.A Extends %ZEN.DataModel.ObjectDataModel
{

Property DOB As %Date(ZENATTRS "id:DOB|format:DMY|separator:/"ZENCONTROL "dateText");

Method %OnNewSource(Output pSC As %Status = {$$$OK}) As %RegisteredObject
{
  ##class(dc.A).%New()
}

Method %OnOpenSource(
  pID As %String,
  pConcurrency As %Integer -1,
  Output pSC As %Status = {$$$OK}) As %RegisteredObject
{
  ##class(dc.A).%OpenId(pID,pConcurrency,.pSC)
}

Method %OnSaveSource(pSource As dc.AAs %Status
{
  pSource.%Save()
}

ClassMethod %OnDeleteSource(pID As %StringAs %Status
{
  ##class(dc.A).%DeleteId(pID)
}

Method %OnLoadModel(pSource As dc.AAs %Status
{
  ..DOB pSource.DOB
  q $$$OK
}

Method %OnStoreModel(pSource As dc.AAs %Status
{
  pSource.DOB = ..DOB
  q $$$OK
}

}

Class dc.test Extends %ZEN.Component.page
{

XData Contents [ XMLNamespace "http://www.intersystems.com/zen" ]
{
  <page xmlns="http://www.intersystems.com/zen">
    <dataController id="a-controller" modelClass="dc.MVC.A" modelId=""/>
    <dynaForm id="a-form"  controllerId="a-controller"/>
    <button caption="Save" onclick="zen('a-form').save();" />
  </page>
}

}

Still can be so:

Class dc.test Abstract ]
{

ClassMethod Test("#")
{
  "Test_",s
}

ClassMethod mac() [ ProcedureBlock = 0 ]
{
sub1(s=1)
  "sub1_",s
  q
sub2(s=2)
  "sub2_",s
  q
procPrivate(s=3) {
  "procPrivate_",s
}
procPublic(s=3) public {
  "procPublic_",s
}
}

}

Result:

USER>zTest^dc.test.1(1)
Test_1
USER>sub1^dc.test.1
sub1_1
USER>sub2^dc.test.1
sub2_2
USER>sub1^dc.test.1(10)
sub1_10
USER>sub2^dc.test.1(10)
sub2_10
USER>procPrivate^dc.test.1(10)
 
D procPrivate^dc.test.1(10)
^

USER>procPublic^dc.test.1(10)
procPublic_10
USER>

My best result is 77 72 69 67 so far.

Class ITPlanet.Task4 Abstract ]
{

ClassMethod main(As %Integer 10)
{
 x=1:1:y=1:1:w $c(y#s<2!$lf($lb(1,s,y,s-y+1),x)*3+32)
}

ClassMethod length(
  class = {$classname()},
  method "main"As %Integer CodeMode = expression ]
{
##class(%Dictionary.MethodDefinition).IDKEYOpen(classmethod).Implementation.Size
}

}

USER>##class(ITPlanet.Task4).length()
67
USER>##class(ITPlanet.Task4).main(11)

###########
##       ##
# #     # #
#  #   #  #
#   # #   #
#    #    #
#   # #   #
#  #   #  #
# #     # #
##       ##
###########

Make two changes to your code:

  1. /// return json
    Method infoJson() As %String WebMethod ]
    {
        set soapresponse=##class(webservice.SOAPResponse).%New()
        set soapresponse.CustomerID="1"
        set soapresponse.Name="2"
        set soapresponse.Street="3"
        set soapresponse.City="4"
        set soapresponse.State="5"
        set soapresponse.Zip="6"
    
        set stream=##class(%Stream.TmpBinary).%New()
        do ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(stream,soapresponse,,,$$$YES,"s")
        quit stream.Read($$$MaxStringLength)
    }
  2. /// write ##class(PRD.Test).test1()
    ClassMethod test1() As %String
    {
        set soapresponse=##class(webservice.SOAPResponse).%New()
        set soapresponse.CustomerID="1"
        set soapresponse.Name="2"
        set soapresponse.Street="3"
        set soapresponse.City="4"
        set soapresponse.State="5"
        set soapresponse.Zip="6"
        
        set stream=##class(%Stream.TmpBinary).%New()
        do ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(stream,soapresponse,,,$$$YES,"s")
        quit stream.Read($$$MaxStringLength)
    }

Fixed bugs/typos and added new types.

#include %PVA
types ; Show COS-Datatypes ; kav ; 2018-03-04
 array,i,bitstring
 
 s $bit(bitstring,1) = 1

 "№",?4,"VALUE",?30,"JSON",?45,"$LISTBUILD",!,$TR($J("",55)," ","-"),!
 
 array=[
          (bitstring),
          ($ZBITSET($ZBITSTR(4,1),2,0)),
          ($lb("")),
          null,
          true,
          false,
          (##class(%ZEN.proxyObject).%New()),
          [],
          {},
          "abcd",
          ($wc(35222)),
          "2",
          2,
          -2,
          2.1,
          -2.1,
          ($double(2.1))
          ]
 array."18"=2
 array."19"=-2
          
 i=0:1:array.%Size() {
   i,")",?4,array.%Get(i),?30,$$TypeOf1(.array,i),?45,$$TypeOf2(array.%Get(i)),!
 }
 
 // Return JSON datatype by the documented way
 //
TypeOf1(&array,key)
{
  typ=array.%GetTypeCodeOf(key)
  typ_" "_$case(typ,
    $$$PVVALUENULL:"null",
    $$$PVVALUETRUE:"boolTrue",
    $$$PVVALUEFALSE:"boolFalse",
    $$$PVVALUEINTEGERPOS:"+int",
    $$$PVVALUEINTEGERNEG:"-int",
    $$$PVVALUEUNUSED1:"unused",
    $$$PVVALUEARRAY:"array",
    $$$PVVALUEOBJECT:"object",
    $$$PVVALUETEXT:"text",
    $$$PVVALUENUMBER:"number",
    $$$PVVALUEOVERFLOW:"overflow",
    $$$PVVALUECACHENUMERIC:"cacheNumeric",
    $$$PVVALUEOREF:"oref",
    $$$PVVALUEUNASSIGNED:"unassigned",
    $$$PVVALUELONGPOS:"+long",
    $$$PVVALUELONGNEG:"-long",
    $$$PVVALUEBYTE:"byte[]",
    $$$PVVALUEDATETIME:"dateTime",
    $$$PVVALUEDOUBLE:"double",
    $$$PVVALUESINGLE:"single",
    $$$PVVALUEUTF8:"utf8",
    $$$PVVALUENESTED:"nested",
    $$$PVVALUEEOF:"eof",
    :"unknown")
}
   
 // Return datatype by the undocumented $LB() way
 //
TypeOf2(val)
 {
  i $l(val)>253 {
    typ=$ziswide(val)+1
  else {
    typ=$a($lb(val),2)
  }
  typ_" "_$case(typ
    ,1:"8bitString"
    ,2:"16bitString"
    ,4:"nonNegativeInteger"
    ,5:"negativeInteger"
    ,6:"nonNegativeFloat"
    ,7:"negativeFloat"
    ,8:"double"
    , :"??? never seen before")
}

Result:

USER>^types
№   VALUE                     JSON           $LISTBUILD
-------------------------------------------------------
0)  Ÿ                          8 text         1 8bitString
                              8 text         1 8bitString
2)                            8 text         1 8bitString
3)                            0 null         1 8bitString
4)  1                         1 boolTrue     1 8bitString
5)  0                         2 boolFalse    1 8bitString
6)  4@%ZEN.proxyObject        12 oref        1 8bitString
7)  2@%Library.DynamicArray   6 array        1 8bitString
8)  1@%Library.DynamicObject  7 object       1 8bitString
9)  abcd                      8 text         1 8bitString
10) 視                         8 text         2 16bitString
11) 2                         8 text         1 8bitString
12) 2                         9 number       4 nonNegativeInteger
13) -2                        9 number       5 negativeInteger
14) 2.1                       9 number       6 nonNegativeFloat
15) -2.1                      9 number       7 negativeFloat
16) 2.1000000000000000888     18 double      8 double
17)                           13 unassigned  1 8bitString
18) 2                         3 +int         4 nonNegativeInteger
19) -2                        4 -int         5 negativeInteger
20)                           31 eof         1 8bitString

On my desktop quite other results.

  N,j,time

  N=1e8

  j=1,2/*,3,4,5*/ {
    j,") "

    time=$zh
    d @("j"_j)(N)
    w $zh-time," s.",!
  }
  q
j1(N) public {
  i=1:1:{(a,b,c,d,e,f)=0}
}
j2(N) public {
  i=1:1:{a=0,b=0,c=0,d=0,e=0,f=0}
}
j3(N) public {
  i=1:1:{a=0,b=1,c=2,d=3,e=4,f=5}
}
j4(N) public {
  i=1:1:{a=0 b=1 c=2 d=3 e=4 f=5}
}
j5(N) public {
  i=1:1:{s $lb(a,b,c,d,e,f)=$lb(0,1,2,3,4,5)}
}

Results:

USER>^perf
1) 11.814189 s.
2) 4.683832 s.

As you can see the difference is almost 2.5 times.