Written by

Senior Cloud Architect at InterSystems
Question Eduard Lebedyuk · 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?

Comments

Oleg Dmitrovich · Aug 31, 2017
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) 
}
0
Eduard Lebedyuk  Aug 31, 2017 to Robert Cemper

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
0
Robert Cemper · Aug 31, 2017

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

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
0
Robert Cemper  Aug 31, 2017 to Eduard Lebedyuk

You are right, the A -B -C case isn't covered by me:
not a goal but an assist (half points laugh)

0
John Murray · Aug 31, 2017

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.

0