How do I get a list of classes that are subclasses of 2 unrelated classes?
I need to get a list of all classes that are subclasses of two unrelated classes.
For example I want to get a list of all classes that are both:
- Persistent (extends %Library.Persistent)
- XML-Enabled (extends %XML.Adaptor)
To get subclasses of one class I can use this query:
set rs = ##class(%Dictionary.ClassDefinitionQuery).SubclassOfFunc("%Library.Persistent")But what about two classes?
I suppose I can run this query twice, build two $lb, then iterate over one of them and build a new $lb with classes that appear in both lists. Are there any better approaches?
Comments
s arr=""
while rs.%Next() {
s:'$d(arr(rs.Name)) arr(rs.Name) = "" ; or ^||arr
}
s (list,chld)="" for { s chld=$o(arr(chld)) Q:chld="" s list = list _$lb(chld)
}
This condition:
Super [ 'Persistent'
Is insufficient. Consider this case:
Class Package.ClassA Extends %Library.Persistent
{
}
Class Package.ClassB Extends %XML.Adaptor
{
}
Class Package.ClassC Extends (ClassA, ClassB)
{
}While Package.ClassC satisfies both conditions (it's a subclass of both %Library.Persistent and %XML.Adaptor), it would not be returned by the SQL query, as Super field does not contain required superclasses directly.
But we can easily join 2 SubclassOf queries via SQL:
SELECT s1.name
FROM %Dictionary.ClassDefinitionQuery_SubclassOf('%Library.Persistent') s1
INNER JOIN %Dictionary.ClassDefinitionQuery_SubclassOf('%XML.Adaptor') s2 ON s2.name = s1.nameHere's an article on useful autogenerated methods for properties, indices, queries, etc.
Here's a write-up on defining your own query types to add more methods than just Func().
You may do it as well with SQL
select 'PERS' Typ, ID from %Dictionary.ClassDefinition
where Super [ 'Persistent'
union all
select 'XML' Typ, ID from %Dictionary.ClassDefinition
where Super [ 'XML.Adaptor'
)
group by ID
order by cnt desc
Result : 2 both classes contained in class
| cnt | ID |
|---|---|
| 2 | %BI.Blog |
| 2 | %BI.BlogPost |
| 2 | %BI.DashBoard |
| 2 | %BI.DetailList |
| 2 | %BI.DocMag |
| 2 | %BI.ImageList |
| 2 | %BI.KPI |
| 2 | %BI.ListField |
| 2 | %BI.Measure |
| 2 | %BI.PerfMet |
| 2 | %BI.PerfMetNode |
| 2 | %BI.PivotData |
| 2 | %BI.PivotTable |
You are right, the A -B -C case isn't covered by me:
not a goal but an assist (half points
)
I must admit I was unfamiliar with the xxxFunc() syntax Eduard's code used. So I decided to track it down in the documentation:
http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY…
That comes from the 2012.2 release notes and reads as follows:
Func() Method Added To Query Classes
A new query member method is available for use, Func. Func() accepts actual values corresponding to the formal parameters defined by the query. It returns an instance of %SQL.StatementResult. When the Func method executes successfully that instance of %SQL.StatementResult is a result set.
If an application has a class with a method whose name is the same as a query name concatenated with "Func", then a member method name collision will be reported at compile-time. Refer to the %Library.Query class for more information.