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?
I usually export the entire package, but if you want subclasses run this query:
SELECT Name FROM %Dictionary.ClassDefinitionQuery_SubclassOf('%Persistent')
And then call $system.OBJ.ExportODL on every result.
@Sam Duncan Here'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.ClassQueryResultSet Try { #; Build a subscripted array of subclasses Set tStmt = ##class(%SQL.Statement).%New() Set tSC = tStmt.%PrepareClassQuery("%Dictionary.ClassDefinitionQuery","SubclassOf") If $$$ISERR(tSC) Quit Set 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 subclasses Set 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.