Question
· Aug 31, 2017

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?

Discussion (6)1
Log in or sign up to continue

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.name

You may do it as well with SQL

select count(*) cnt , ID from (
  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

cntID
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

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.