Vitaliy Serdtsev · Feb 10, 2016 go to post

In my opinion better will be so:

Property SystemTime As %TimeStamp [ InitialExpression = {$ZDATETIME($NOW(),3,1,0)}, ReadOnly ];

 

This variant will work and for SQL and for Objects.

In addition the developer will not be able to explicitly set a different value.

 

Vitaliy Serdtsev · Jan 10, 2017 go to post

You could do the same thing by creating a View with a function in the WHERE clause that called the method to figure out if you should see the row or not.

  1. responsibility lies on developer don't to forget add additional conditions: WHERE, %IGNOREINDEX, etc.
  2. the query becomes more complicated

I think this is a cleaner solution as you do not need to worry about the %RLI becoming available again. 

What prevents force disable %RLI in ^%ZSTART or $SYSTEM.SQL.SetServerInitCode() ?

Vitaliy Serdtsev · Feb 2, 2017 go to post

> Can I make a serial class always computed?
Yes, of course.
Class CS.Serial Extends %SerialObject [ NoExtent ]
{
Property Year As %Integer;
Property Month As %Integer;
}
Class CS.Persistent Extends %Persistent
{
Property data As CS.Serial [ SqlComputeCode = {set {*} = ##class(CS.Persistent).dataGetStatic()}, SqlComputed, Transient ];
ClassMethod dataGetStatic() As %List
{
  quit $lb(2017,1)
}
}
Output:
^CS.PersistentD=1
^CS.PersistentD(1)=$lb("")
ID      data
1       $lb(2017,1)
 
1 Rows(s) Affected

Vitaliy Serdtsev · Feb 2, 2017 go to post

It seems to me that in this case is not well suited %SerialObject.
Will be easier to use %List.

Vitaliy Serdtsev · Feb 3, 2017 go to post

The only single problem here – there is no direct support for importing from .JSON files even for recent versions of Caché/Ensemble with builtin JSON support in the kernel.

See %Library.DynamicAbstractObject:%FromJSON(), %ZEN.Auxiliary.jsonProvider:%ConvertJSONToObject(), %ZEN.Auxiliary.jsonProvider:%ParseFile(), %ZEN.Auxiliary.jsonProvider:%ParseJSON()

Given:
test.json: {"a":"test","b":[1,2,3,4]}
    file=##class(%Stream.FileCharacter).%New()
    file.Filename="C:\test.json"
    file.TranslateTable="UTF8"
    ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(file,,.obj)
    obj.%Print()
 

Output:

-----------------
a: "test"
b:
  [1] 1
  [2] 2
  [3] 3
  [4] 4

Vitaliy Serdtsev · May 25, 2017 go to post
Does this example need to handle this?
Correct, of course, to close the device:
#include %systemInclude

</FONT><FONT COLOR="#0000ff">#dim </FONT><FONT COLOR="#800000">cDev </FONT><FONT COLOR="#0000ff">As </FONT><FONT COLOR="#008080">%String </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$IO

</FONT><FONT COLOR="#008000">; see "dir /?" and RunCommandViaZF() </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%Net.Remote.Utility</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">RunCommandViaCPIPE</FONT><FONT COLOR="#000000">(...,.</FONT><FONT COLOR="#800000">dev</FONT><FONT COLOR="#000000">,.</FONT><FONT COLOR="#800000">con</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#008000">/* ... */ </FONT><FONT COLOR="#0000ff">c</FONT><FONT COLOR="#000000">:(</FONT><FONT COLOR="#0000ff">$get</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">dev</FONT><FONT COLOR="#000000">)'=</FONT><FONT COLOR="#008000">""</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#800000">dev</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#008000">"I" </FONT><FONT COLOR="#0000ff">u </FONT><FONT COLOR="#800000">cDev</FONT>

Also, do you not worry that its an internal class?
No, since for me internal ≠ deprecated.

However, given the openness of the source code, you can make own similar method, thereby to protect yourself from possible issues in the future.

Vitaliy Serdtsev · May 26, 2017 go to post
Anything with this flag can change or be removed with no warning.
There are a few comments:
  • Let's say that the developers changed something in new versions of the DBMS. Is this a problem?

    It is enough to check Caché Recent Upgrade Checklists, where usually there is a ready list of changes that may affect existing user code, for example.

    Note that this can apply to absolutely any member of a class, and not even marked as [Internal]. Suffice it to recall the recent story with JSON support.

  • For a class does not exist flag [Internal], the warning is only on the level of comments.

    As for the other members of the class, according to the documentation this flag is for other purposes, namely:
    Internal class members are not displayed in the class documentation. This keyword is useful if you want users to see a class but not see all its members. proof
  • In any case, the final choice for developer.
Vitaliy Serdtsev · May 26, 2017 go to post

And if so?

##class(%Net.Remote.Utility).RunCommandViaZF($$$FormatText("dir /A-D /B /S %1",$$$quote("C:\InterSystems\Atelier")),.tFileName,,,$$$NO)
f=##class(%Stream.FileCharacter).%New()
f.Filename=tFileName
while('f.AtEnd{f.ReadLine(),!}
f=""
##class(%File).Delete(tFileName)
Vitaliy Serdtsev · May 26, 2017 go to post

Initially the question was about alternative ways of solving the issue (in addition to recursive FileSet and $ZSEARCH).

I just proposed a third method, namely using the capabilities of the OS itself. Maybe someone here didn't know about it.

Which option at end to choose - to solve the developer.


We here vote for the best solution or in general for offered solutions?

If the first, then I'll pass.

Vitaliy Serdtsev · May 29, 2017 go to post

I want to say that this question was already asked and there it was given some answer. No more than.
I personally use Studio and will continue to use.

Vitaliy Serdtsev · Jun 6, 2017 go to post

Rhetorical question - for what?
If for fun, then this is possible.
But I will tell the solution here later.

Vitaliy Serdtsev · Jun 7, 2017 go to post

Ok, exclusively for fun.

I made some improvements and now my score is 9, but if you try very hard, even - 0!
Who less ? ;)

Here is the code:

Class ITPlanet.Task2 Abstract ]
{

Parameter p = {$zwbunpack("㤸㜶㔴㌲㄰")};

ClassMethod main() As %String
{
 ..#p
}

}Class ITPlanet.Test Abstract ]
{

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

ClassMethod test(makeDeploy = {$$$NO})
{
  ;do ##class(ITPlanet.Test).test()

  set classname="ITPlanet.Task2"
  set check=9876543210
  do:makeDeploy $system.OBJ.MakeClassDeployed(classname)
  set result=$classmethod(classname,"main")
  write !,result,!,check,
        !,"correct: ",$select(result=check:"yes",1:"no"),
        !,"length: ",..length(classname)
}

}
USER>do ##class(ITPlanet.Test).test()
 
9876543210
9876543210
correct: yes
length: 9
USER>do ##class(ITPlanet.Test).test(1)
 
9876543210
9876543210
correct: yes
length: 0
Vitaliy Serdtsev · Jun 8, 2017 go to post

Do not forget about the method signature:

<FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">main() </FONT><FONT COLOR="#000080">As %String</FONT>
Need not print the number, but return it.
Vitaliy Serdtsev · Jun 9, 2017 go to post
Is there any way to "generate" compatible storage? And why SQLStorage? Why not default CachéStorage, but copy-pasted from Class A?
Unfortunately, to use %CacheStorage will not work, since at compile occurs the error:
ERROR #5564: Storage reference: '^demo.AD' used in 'demo.B.cls' is already registered for use by 'demo.A.cls'
  > ERROR #5030: An error occurred while compiling class 'demo.B'
Vitaliy Serdtsev · Jun 9, 2017 go to post

Indeed, thank you:

<FONT COLOR="#000080">Class demo.B Extends %Persistent </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">Final </FONT><FONT COLOR="#000000">]
{

</FONT><FONT COLOR="#000080">Parameter </FONT><FONT COLOR="#000000">MANAGEDEXTENT </FONT><FONT COLOR="#000080">As </FONT><FONT COLOR="#000000">INTEGER [ </FONT><FONT COLOR="#000080">Constraint </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800080">"0,1"</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#000080">Flags </FONT><FONT COLOR="#000000">= ENUM ] = </FONT><FONT COLOR="#000080">0</FONT><FONT COLOR="#000000">;

</FONT><FONT COLOR="#000080">Parameter </FONT><FONT COLOR="#000000">READONLY = </FONT><FONT COLOR="#000080">1</FONT><FONT COLOR="#000000">;

</FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">P2;

</FONT><FONT COLOR="#000080">Storage </FONT><FONT COLOR="#000000">Default { <<FONT COLOR="#000080">Data </FONT><FONT COLOR="#800000">name</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"BDefaultData"</FONT><FONT COLOR="#000000">>   <</FONT><FONT COLOR="#000080">Value </FONT><FONT COLOR="#800000">name</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"3"</FONT><FONT COLOR="#000000">>     <</FONT><FONT COLOR="#000080">Value</FONT><FONT COLOR="#000000">>P2</</FONT><FONT COLOR="#000080">Value</FONT><FONT COLOR="#000000">>   </</FONT><FONT COLOR="#000080">Value</FONT><FONT COLOR="#000000">> </</FONT><FONT COLOR="#000080">Data</FONT><FONT COLOR="#000000">> <</FONT><FONT COLOR="#000080">DataLocation</FONT><FONT COLOR="#000000">>^demo.AD</</FONT><FONT COLOR="#000080">DataLocation</FONT><FONT COLOR="#000000">> <</FONT><FONT COLOR="#000080">DefaultData</FONT><FONT COLOR="#000000">>BDefaultData</</FONT><FONT COLOR="#000080">DefaultData</FONT><FONT COLOR="#000000">> <</FONT><FONT COLOR="#000080">IdLocation</FONT><FONT COLOR="#000000">>^demo.AD</</FONT><FONT COLOR="#000080">IdLocation</FONT><FONT COLOR="#000000">> <</FONT><FONT COLOR="#000080">IndexLocation</FONT><FONT COLOR="#000000">>^demo.AI</</FONT><FONT COLOR="#000080">IndexLocation</FONT><FONT COLOR="#000000">> <</FONT><FONT COLOR="#000080">StreamLocation</FONT><FONT COLOR="#000000">>^demo.AS</</FONT><FONT COLOR="#000080">StreamLocation</FONT><FONT COLOR="#000000">> <</FONT><FONT COLOR="#000080">Type</FONT><FONT COLOR="#000000">>%Library.CacheStorage</</FONT><FONT COLOR="#000080">Type</FONT><FONT COLOR="#000000">></FONT> }

}</FONT>

Vitaliy Serdtsev · Jun 15, 2017 go to post

Congratulations, John.

To be a moderator is a big responsibility, so I wish you a lot of patience.

Vitaliy Serdtsev · Jun 16, 2017 go to post

URL and URI Conversions

Try: <FONT COLOR="#0000ff">Set </FONT><FONT COLOR="#800000">tURL</FONT><FONT COLOR="#000000">=..</FONT><FONT COLOR="#0000ff">Adapter</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">URL</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#008000">"/claims/"</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%CSP.Page</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">EscapeURL</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">pRequest</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">claimBlob</FONT><FONT COLOR="#000000">)</FONT> or <FONT COLOR="#0000ff">Set </FONT><FONT COLOR="#800000">tURL</FONT><FONT COLOR="#000000">=..</FONT><FONT COLOR="#0000ff">Adapter</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">URL</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#008000">"/claims/"</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#0000ff">$zcvt</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$zcvt</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">pRequest</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">claimBlob</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"O"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"UTF8"</FONT><FONT COLOR="#000000">),</FONT><FONT COLOR="#008000">"O"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"URL"</FONT><FONT COLOR="#000000">)</FONT>

USER>w $zcvt($zcvt($c(0,1,2,1025),"O","UTF8"),"O","URL")
%00%01%02%D0%81
USER>##class(%CSP.Page).EscapeURL($c(0,1,2,1025))
%00%01%02%D0%81
Vitaliy Serdtsev · Jun 21, 2017 go to post

It is not clear what it will give. To Richard need to save the binary data encoded in hex.

For example, instead of '0x2122232425262728292A2F' to the database should persist the value !"#$%&'()*/

USER>w $c(33,34,35,36,37,38,39,40,41,42,47)
!"#$%&'()*/

USER>##class(%xsd.hexBinary).LogicalToXSD($c(33,34,35,36,37,38,39,40,41,42,47))
2122232425262728292A2F

USER>zzdump ##class(%xsd.hexBinary).XSDToLogical("2122232425262728292A2F"; 0x omitted
 
0000: 21 22 23 24 25 26 27 28 29 2A 2F                        !"#$%&'()*/
Vitaliy Serdtsev · Jul 3, 2017 go to post

Yes, see part "Creation of a custom error message dictionary"

PS: you can even use the letters, for example:

<?xml <FONT COLOR="#008000">version</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"1.0" encoding</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"UTF-8"</FONT><FONT COLOR="#000000">?>
<</FONT><FONT COLOR="#000080">MsgFile </FONT><FONT COLOR="#800000">Language</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"en"</FONT><FONT COLOR="#000000">>
  <</FONT><FONT COLOR="#000080">MsgDomain </FONT><FONT COLOR="#800000">Domain</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"asd"</FONT><FONT COLOR="#000000">>
    <</FONT><FONT COLOR="#000080">Message </FONT><FONT COLOR="#800000">Id</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"a" </FONT><FONT COLOR="#800000">Name</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"ErrorName1"</FONT><FONT COLOR="#000000">>Message about some error 1</</FONT><FONT COLOR="#000080">Message</FONT><FONT COLOR="#000000">>
    <</FONT><FONT COLOR="#000080">Message </FONT><FONT COLOR="#800000">Id</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"b" </FONT><FONT COLOR="#800000">Name</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"ErrorName2"</FONT><FONT COLOR="#000000">>Message about some error 2 %1 %2</</FONT><FONT COLOR="#000080">Message</FONT><FONT COLOR="#000000">>
  </</FONT><FONT COLOR="#000080">MsgDomain</FONT><FONT COLOR="#000000">>
</</FONT><FONT COLOR="#000080">MsgFile</FONT><FONT COLOR="#000000">></FONT>
Vitaliy Serdtsev · Jul 3, 2017 go to post
  • error code 100 do not exist, but there is a code 101. See documentation: General Error Messages
    USER>s $mvv(58)="es"

    USER><FONT COLOR="#0000ff">d $SYSTEM</FONT><FONT COLOR="#008080">.OBJ</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">DisplayError</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$System</FONT><FONT COLOR="#008080">.Status</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Error</FONT><FONT COLOR="#000000">(101))</FONT>

    ERROR #101: Nivel puntero superior: nº bloques=%1 %2kb (%3% total)

  • error with some positive codes are reserved by the system, so you can't use them.
    Two error codes, 83 and 5001, are provided to enable you to generate your own custom error messages.
Vitaliy Serdtsev · Jul 5, 2017 go to post
SAMPLES>d $system.SQL.Shell()
SQL Command Line Shell
----------------------------------------------------
 
The command prefix is currently set to: <>.
Enter q to quit, ? for help.
SAMPLES>>?=CALL %SYSTEM.SQL_TableExists('Sample.Person')
1.      ?=CALL %SYSTEM.SQL_TableExists('Sample.Person')
 
 
executing statement with parameter values: set %tResult=%tStatement.%Execute()
 
 
Output Values:
 
 0. 1
statement prepare time(s)/globals/lines/disk: 0.0025s/14/862/0ms
          execute time(s)/globals/lines/disk: 0.0003s/7/179/0ms
                          cached query class: %sqlcq.SAMPLES.cls2
---------------------------------------------------------------------------
SAMPLES>>