Is there a good existing way to export all derived classes of a given class?
It can sometimes be useful to list or export all of the subclasses that are derived, directly or indirectly, from a given class. In Studio, the Class -> Derived Classes menu option will show such a list, but I'm not aware of a built-in API for programmatically exporting their source code.
Yesterday I wrote some code for exporting derived classes, and I'm thinking about cleaning it up and putting it on Open Exchange. But if there's a simple way to do this that someone has already figured out, I'd be happy to know about that (and help others find that solution) rather than reinventing the wheel. So:
- Have you ever wanted to export all of the subclasses derived from a particular class?
- If so, what solution did you come up with? Were you happy with it?
Comments
I usually export the entire package, but if you want subclasses run this query:
SELECTNameFROM %Dictionary.ClassDefinitionQuery_SubclassOf('%Persistent')And then call $system.OBJ.ExportODL on every result.
@Samuel.DuncanHere's a simple method to export subclasses. It exports all of the classes in a single XML file and prints that to the console. You can easily modify that behavior by changing the $SYSTEM.OBJ.Export() line to whatever export strategy you want.
ClassMethod ExportSubclasses(pSuper As%String) As%Status
{
#Dim tSC As%Status = $$$OK#Dim tEx As%Exception.AbstractException#Dim tPc As%ProcedureContext#Dim tRs As%SQL.ClassQueryResultSetTry {
#; Build a subscripted array of subclassesSet tStmt = ##class(%SQL.Statement).%New()
Set tSC = tStmt.%PrepareClassQuery("%Dictionary.ClassDefinitionQuery","SubclassOf")
If$$$ISERR(tSC) QuitSet tPc = tStmt.%Execute(pSuper)
If tPc.%SQLCODE < 0 {
Throw##class(%Exception.SQL).CreateFromSQLCODE(tPc.%SQLCODE,tPc.%Message)
}
Set tRs = tPc.%NextResult()
While tRs.%Next(.tSC) {
Set tSubclasses(tRs.%GetData(1)_".CLS") = ""
}
If$$$ISOK(tSC), $DATA(tSubclasses) = 10 {
#; Export the subclassesSet tSC = $SYSTEM.OBJ.Export(.tSubclasses,,"/nodisplay")
}
} Catch tEx {
Set tSC = tEx.AsStatus()
}
Quit tSC
}Thanks, Brett! That seems to work, and is much more concise than what I had come up with.
set basename="Test.Sub.Base"
set file="c:\temp\subclasses.xml"
// Get list of compiled sub-classes
do $SYSTEM.OBJ.GetDependencies(basename,.out,"/subclasses=1")
// If you didn't want the base class
kill out(basename)
// Write the classes to terminal
zwrite out
// Suffix for export
set next="" for {set next=$Order(out(next)) quit:next="" set toExport(next_".CLS")=""}
// Fire in the hole !!
do $SYSTEM.OBJ.Export(.toExport,file,"/diffexport")
// to display different qualifier flags and values used by various OBJ methods ( /diffexport ):
do $SYSTEM.OBJ.ShowQualifiers()