Populating test/initial data
How do you populate and update test/initial data for you classes?
CSV tables? Globals export? And how do you update test data?
Here's one way I found useful for small projects.
Class utils.Test Extends (%Persistent, %XML.Adaptor)
{
Parameter XDATA = "Data";
Property PropertyA As %String;
/// set sc = ##class(utils.Test).Export()
ClassMethod Export() As %Status
{
quit:$classmethod($classname(), "%Extends", "%XML.Adaptor")=0 $$$ERROR($$$GeneralError, "Class " _ $classname() _ " should extend %XML.Adaptor")
if ##class(%Dictionary.XDataDefinition).IDKEYExists($classname(), ..#XDATA) {
set xdata = ##class(%Dictionary.XDataDefinition).IDKEYOpen($classname(), ..#XDATA)
} else {
set xdata = ##class(%Dictionary.XDataDefinition).%New($classname() _ ":" _ ..#XDATA)
}
#dim stream As %Stream.TmpCharacter
set stream = xdata.Data
do stream.Clear()
do stream.WriteLine("<xml>")
for i=1:1:$g(@##class(utils.Test).GetIdGlobal(), 0) {
set obj = ..%OpenId(i)
do obj.XMLExportToStream(.stream)
do stream.WriteLine("")
}
do stream.WriteLine("</xml>")
quit xdata.%Save()
}
/// do ##class(utils.Test).Import()
ClassMethod Import(killExtent As %Boolean = {$$$YES}) As %Status
{
#dim sc As %Status = $$$OK
set xdata = ##class(%Dictionary.XDataDefinition).IDKEYOpen($classname(), ..#XDATA,,.sc)
quit:$$$ISERR(sc) sc
#dim stream As %Stream.TmpCharacter
set stream = xdata.Data
set reader = ##class(%XML.Reader).%New()
set sc = reader.OpenStream(stream)
quit:$$$ISERR(sc) sc
do reader.Correlate(..GetXMLName(), $classname())
do:killExtent ..%KillExtent()
while reader.Next(.obj, .sc) {
quit:$$$ISERR(sc)
set sc = obj.%Save()
quit:$$$ISERR(sc)
}
quit sc
}
/// Get class XMLName
/// w ##class(utils.Test).GetXMLName()
ClassMethod GetXMLName(class As %Dictionary.CacheClassname = {$classname()}) As %String
{
set xmlname = ..#XMLNAME
set:xmlname="" xmlname = $$$ClassShortName(class)
quit xmlname
}
/// Get the name of Id global from active storage.
/// w ##class(utils.Test).GetIdGlobal()
ClassMethod GetIdGlobal(class As %Dictionary.CacheClassname = {$classname()}) As %String
{
quit:'$$$comClassDefined(class) ""
set strategy = $$$comClassKeyGet(class, $$$cCLASSstoragestrategy)
quit $$$defMemberKeyGet(class, $$$cCLASSstorage, strategy, $$$cSDEFidlocation)
}
}
When you want to save class data (i.e. for project release) you call Export method and it creates XData definition that holds serialized objects:
XData Data
{
<xml>
<Test><PropertyA>1</PropertyA></Test>
<Test><PropertyA>2</PropertyA></Test>
</xml>
}
And to load data you need to call Import method, which would read XData and save the objects found there.
If you have a lot of classes, you can move all these methods to a separate class, and add it as a superclass to the persistent classes you want to save.
It could also have ExportAll/ImportAll methods iterating over results of %Dictionary.ClassDefinitionQuery:SubclassOf query.
What's your approach?
This approach obviously can't hold a lot of data.