Documentation has some information, see "Making Your Own Studio Templates".
- Log in to post comments
Documentation has some information, see "Making Your Own Studio Templates".
What's the advantage of using $$$ERRORCODE macro? ^%qCacheObjectErrors global contains the same values.
See %ZEN.proxyObject class, SaveDocument / OpenDocument methods for sample global storage of dynamic objects. You can convert JSON to %ZEN.proxyObject to Global (and back) with it.
There is also MonCache project - implementation of basic MongoDB functions using Caché as a database engine. It implements json-global engine.
What kind of SQL support are talking about here?
Note, that $list and, for example, %ListOfDataTypes are different concepts. The first one is a datatype and a second one is an object.
%XML.Reader and %SQL.Import.Mgr respectively.
One approach would be to use %XML.DataSet to convert SQL results into XML:
Set result=##class(%XML.DataSet).%New()
Do result.Prepare("SELECT TOP 3 ID, Name FROM Sample.Person")
Do result.Execute() 1
Do result.WriteXML("root",,,,,1) Outputs:
<root>
<s:schema id="DefaultDataSet" xmlns="" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<s:element name="DefaultDataSet" msdata:IsDataSet="true">
<s:complexType>
<s:choice maxOccurs="unbounded">
<s:element name="SQL">
<s:complexType>
<s:sequence>
<s:element name="ID" type="s:long" minOccurs="0" />
<s:element name="Name" type="s:string" minOccurs="0" />
</s:sequence>
</s:complexType>
</s:element>
</s:choice>
</s:complexType>
<s:unique name="Constraint1" msdata:PrimaryKey="true">
<s:selector xpath=".//SQL" />
<s:field xpath="ID" />
</s:unique>
</s:element>
</s:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<DefaultDataSet xmlns="">
<SQL diffgr:id="SQL1" msdata:rowOrder="0">
<ID>96</ID>
<Name>Adam,Wolfgang F.</Name>
</SQL>
<SQL diffgr:id="SQL2" msdata:rowOrder="1">
<ID>188</ID>
<Name>Adams,Phil H.</Name>
</SQL>
<SQL diffgr:id="SQL3" msdata:rowOrder="2">
<ID>84</ID>
<Name>Ahmed,Edward V.</Name>
</SQL>
</DefaultDataSet>
</diffgr:diffgram>
</root>There is also %SQL.Export.Mgr class, which does SQL export.
Thanks!
I often need to run queries from a terminal, so I extended Caché ObjectScript with zsql command to run queries and display the results. Here's how it works:
zsql "SELECT TOP 2 Name FROM Sample.Person"Would output:
Name Adams,Chris Z. Adams,Danielle P
To achieve it I created %ZLANGC00 mac routine with the following code:
; %ZLANGC00
; custom commands for ObjectScript
; http://docs.intersystems.com/cache20141/csp/docbook/DocBook.UI.Page.cls?KEY=GSTU_customize
Quit
/// Execute Query and display the results
/// Call like this:
/// zsql "SELECT TOP 10 Name FROM Sample.Person"
ZSQL(Query)
#Dim ResultSet As %SQL.StatementResult
Set ResultSet = ##class(%SQL.Statement).%ExecDirect(, Query)
Do ResultSet.%Display()
QuitSave and compile it and then you can execute sql (class queries too) in a terminal with zsql command:
zsql "SELECT * FROM Sample.SP_Sample_By_Name('Z')"That said I myself prefer executing SQL queries in SMP because you don't need to type them there (drag&drop from the left panel or copy&paste from the code) - it's very convenient.
Since project is a collection of classes (and other items, yes, but we're talking about classes here) the flow would be something like that:
I'm just saying that 3rd step can have more callers (alternative routes to 3rd step if you will), for example:
I usually add my classes and system classes I often reference from my classes into the project, so they can be opened faster (without dialog).
I would recommend you forego projects entirely and iterate over classes directly with %Dictionary package.
It would be great to see this new docs UI in action. Any chance of open beta?
>$SYSTEM.Status.GetErrorText(sc)["Something"
Would not always work correctly in applications with users requesting content in several languages (for example web app). Why not use error codes?
If $SYSTEM.Status.GetErrorCodes(sc)[$$$GeneralError $$$ThrowStatus(sc)> you could not implement singleton which will be working across jobs, only for this same process;
Storing something in %/PPG would not work across jobs too. Singleton is a single-thread anyway.
> to share instance to teh object you could emply %-named variable or process-private global.
Wrote another singleton using % variable. How would I do it with PPG (any global)? When you set global to an OREF it actually sets a string: "int@class". And you could not convert it back to an OREF with $$$objIntToOref at a later date because the object would be already destroyed.
/// Another singleton
Class Utils.Singleton2 Extends %SystemBase
{
Property Content As %String;
/// Set a = ##class(Utils.Singleton2).Get()
ClassMethod Get() As Utils.Singleton2
{
#Define Var %Var
If '$Data($$$Var) || '$IsObject($$$Var) {
Set Obj = ..%New()
Set $$$Var = Obj
} Else {
Set Obj = $$$Var
}
Return Obj
}
/// Do ##class(Utils.Singleton2).Test()
ClassMethod Test()
{
Set a = ##class(Utils.Singleton2).Get()
Set a.Content = $Random(100)
Set b = ##class(Utils.Singleton2).Get()
Write b.Content
}
}How would you have done it? It's 35 lines of code in total, 25 if we remove persistence (because singleton does not actually has persistence, but OP seemed to need it).
A very interesting question. I decided to write a singleton, with the idea that it searches process memory for other instances of this class and returns existing OREF if found. It also stores data in global and retrives it from there on a first load:
/// Singleton pattern implementation
Class Utils.Singleton Extends %Library.SystemBase
{
/// Global to store content
Parameter Global = "^Singleton";
/// Actual object content
/// It can be be anything: string or a dynamic object
Property Content As %String;
/// This method finds OREF for an object of a current class if it exists in a current process
ClassMethod GetOref() As %Integer
{
// Get current classname
Set Cls = $ClassName()
Set OREF = $$$NULLOREF
// This query returns a list of all object instances currently in memory within the current process.
&sql(SELECT Count(OREF),OREF INTO :Count,:OREFTemp FROM %SYSTEM.OBJ_ObjectList() WHERE ClassName=:Cls)
If Count'=0 {
Set OREF = OREFTemp
}
Return OREF
}
/// If no object of this class is found in process memory
/// then a new one would be returned
/// with Content value taken from global
///
/// If there is an object of this class in memory
/// then it would be returned
ClassMethod Get() As Utils.Singleton
{
Set OREF = ..GetOref()
If OREF = $$$NULLOREF {
Set Obj = ..%New()
} Else {
// Convert integer-oref into real OREF
Set Obj = $$$objIntToOref(OREF)
}
Return Obj
}
/// Test singleton object
/// Do ##class(Utils.Singleton).Test()
ClassMethod Test()
{
Set a = ##class(Utils.Singleton).Get()
Set a.Content = $Random(100)
Set b = ##class(Utils.Singleton).Get()
Write "object b: " _ b.Content,!
Do a.Save()
Kill
Set c = ##class(Utils.Singleton).Get()
Write "object c: " _ c.Content
}
/// Constructor, loads data from global
Method %OnNew() As %Status
{
// Return:($Stack($Stack-2,"PLACE")'["Get") $$$ERROR($$$GeneralError, "Сall Get method")
Set ..Content = $Get(@..#Global)
Return $$$OK
}
/// Saves data to global
Method Save()
{
Set @..#Global = ..Content
}
}Run:
Do ##class(Utils.Singleton).Test()I tried to disable direct instantiation with $Stack checking, but it seems to fail from a terminal. I think it would work from non-interactive code, but I had not checked. Another way would be to set some variable in Get method and check it from %OnNew() method.
Download xml from GitHub.
There is rarely a need to modify web application config in production.
I just restart webserver/Cache when I encounter problems after web application configuration changes. It often helps.
Sure. To see deprecated classes for some version execute this query against it:
SELECT ID, Description FROM %Dictionary.ClassDefinition WHERE LOWER(Description) [ 'deprecated'
To see deprecated methods execute this query:
SELECT parent AS "Class", Name AS "Method", Description FROM %Dictionary.MethodDefinition WHERE LOWER(Description) [ 'deprecated'
And to see deprecated properties execute this query:
SELECT parent AS "Class", Name AS "Method", Description FROM %Dictionary.PropertyDefinition WHERE LOWER(Description) [ 'deprecated'
Note, that this queries only return classes/methods/properties which contain "deprecated" in their definition. To catch deprecated inherited classes/methods/properties query %Dictionary.CompiledClass/%Dictionary.CompiledMethod/%Dictionary.CompiledProperty instead.
Hello.
How can I get/set pool size value for a Production item programmatically? I can't find it in a "Settings Defaults" list.
Could you please tell what do you want to achieve with making 'Open as read-only' setting default?
Consider adding links to cache documentation from the page that describes the issue, we now have version agnostic urls even. For example this issue could use a link to documentation.
Another question is: what's wrong with postconditionals? They exist not only in caché objectscript and in fact very useful as they allow elimination of all 3 lines blocks with one if condition and one action to execute if if is true. Can I disable an issue type for a project?
Thank you.
Sure. You could use %CELLZERO instead:
WITH MEMBER [MEASURES].[Revenue as Percent of Total] AS 'Measures.[Amount Sold] / %MDX("select Measures.[Amount sold] on 1
from holefoods","%CONTEXT","filters|columns")',FORMAT_STRING='##.##%;;;;'
MEMBER [MEASURES].[Revenue Percent Cumulative] AS 'Measures.[Revenue as Percent of Total] + %CELLZERO(0,-1)',
FORMAT_STRING='##.##%;;;;' SELECT {[Measures].[Amount Sold],[MEASURES].[REVENUE PERCENT CUMULATIVE]} ON 0,
NON EMPTY ORDER([Product].[P1].[Product Category].Members,Measures.[Amount Sold],BDESC) ON 1 FROM [HoleFoods] Jokes aside, why do you need to remove %CELL usage?
Thanks. Removed that as it's useless without zzzz variables.
I wondered actually, what for do you prefix all variable names with "zzzz".