Project Class-Name as SQL-field

66 views
Skip to first unread message

Axel Rohde

unread,
Jun 6, 2003, 9:01:12 AM6/6/03
to x...@info2.kinich.com

Is there any simple way to display a Record's Class-Name in an SQL
Resultset? I don't mean the extent mentioned in the SELECT-statement,
but the real Instance's classname.

Let's suppose I have a (persistent) class called "MotherOfAllClasses"
and I have two more classes which inherit from that: "Son", "Daughter".

If I query the following:
SELECT * FROM MotherOfAllClasses

I would like to know if the row I am looking at is an instance of class
"Son" or of class "Daughter".

I think it would be no problem to define a SqlComputed property in
"MotherOfAllClasses" which would carry the
%Library.RegisteredObject.%ClassName(1) result into the SQL-Projection.
But this would impair the query-performance and I have the feeling of
reinventing the weel, because this seems kind of a basic requirement
that can be solved with a (undocumented hidden-documented ;-) trick.


TIA!

Axel.


Peter Cooper

unread,
Jun 6, 2003, 11:35:54 AM6/6/03
to x...@info2.kinich.com
Axel

Not easy
SQL knows nothing about inhertance - it will treat all rows that it
finds as MotherOfAllClasses

you can work around it
create a property pClassName as %String
with initialexpression={..%ClassName(1)}

this will at least give you the class name to inspect

but
no sub-class properties willl be available
no overriden property get/set methods will be available
any calculated fields will be that of the parent

:{

Again stressing that it's not really down to ISC it's that SQL knows
nothing about super/sub classses


Peter



On Fri, 06 Jun 2003 15:01:12 +0200, Axel Rohde <ro...@direvo.de>
wrote:

Sukesh Hoogan

unread,
Jun 6, 2003, 11:40:22 AM6/6/03
to x...@info2.kinich.com
Axel

Try

SELECT x__classname FROM MotherOfAllClasses

The x__classname field is a hidden field, it gives the name of the child
class from which the instance was created..

--
Regards

Sukesh Hoogan
sukesh...@vsnl.com
http://personal.vsnl.com/sukesh_hoogan


"Axel Rohde" <ro...@direvo.de> wrote in message
news:3ee09...@info2.kinich.com...
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.488 / Virus Database: 287 - Release Date: 05/06/2003



Axel Rohde

unread,
Jun 6, 2003, 12:00:40 PM6/6/03
to x...@info2.kinich.com

Thanks for your suggestion! That was just what I was looking for: Get
the "real" ClassName of a row in SQL resultsets without impairing the
query-performance. Since once an instance of a class is created it will
never change its type (class), I can create my own property pClassName,
use the initialexpression feature and get that info projected into SQL.
One drawback is that I am storing redundant information within my
database. Suppose I have 100000 Instances of Class named
"MyPackage.MySuperDuperClass": thats 27*100000 characters of storage
wasted, because there is no means to project (polymorphically) the
ClassName of a Record in SQL. Hmmmm :-/

Thank you again!

Axel.

Axel Rohde

unread,
Jun 6, 2003, 12:16:35 PM6/6/03
to x...@info2.kinich.com
Wow! That's the kind of trick I was looking for!
I've tried that and I've seen that it not just returns the child-class
name but also the whole inheritance history of that child class.

For instance the following query:

SELECT x__classname FROM MotherOfAllClasses

will return the following strings
~MotherOfAllClasses~Son~
~MotherOfAllClasses~Daughter~
~MotherOfAllClasses~Daughter~Grandchild

In that manner I can do something like %Library.RegisteredObject.%IsA()
on the SQL side. Nice, very nice!

But I still have to think about how to use that as a search-criterion on
the standard CSP Lookup-page. (<CSP:SEARCH...) Maybe a user defined
SQL-function to trim that x__classname... I'll let you know, if I find a
way.

Sukesh, are those hidden fields documented somewhere? Where in the
InterSystems source-code can I find them?

Thank you very much!
Axel.

Sukesh Hoogan

unread,
Jun 6, 2003, 12:41:33 PM6/6/03
to x...@info2.kinich.com
Axel

>Sukesh, are those hidden fields documented somewhere? Where in the
>InterSystems source-code can I find them?

I think you redirect this question to ISC.
or on second thoughts to Ramón Jimenéz. He is supposed to write a book on
undocumented features :-).
Hey, Ramón - What happened to your book ?

By the way this hidden field is 'visible' in the SQL Manager for all the
tables.
--
Regards

Sukesh Hoogan
sukesh...@vsnl.com
http://personal.vsnl.com/sukesh_hoogan


"Axel Rohde" <ro...@direvo.de> wrote in message
news:3ee0b...@info2.kinich.com...

Peter Cooper

unread,
Jun 8, 2003, 7:32:31 AM6/8/03
to x...@info2.kinich.com
Axel

I knew about x__classname but it can be a bit tricky - if this is the
superclass then x__classname=""
you have to do some logic to find out what this class actually is


Also you cannot make indices on x__classname (or %%CLASSNAME}

<snip>

>In that manner I can do something like %Library.RegisteredObject.%IsA()
>on the SQL side. Nice, very nice!

I do not think so %IsA is a method generator - you cannot call it
directy

Peter


Axel Rohde

unread,
Jun 8, 2003, 11:59:01 AM6/8/03
to x...@info2.kinich.com

Peter, I am actually implementing your suggestion (propietary property
with InitialExpression), since I found out that x__classname doesn't
work with the <CSP:SEARCH> tag. Another reason is, as you said, the use
of indices, which is not posible on x_classname.

What I meant by "do something like %IsA()" was that on an ODBC client I
can check for a given substring in order to know if a retreived row
belongs to a certain class. I mean a thick client (like a VBA-powered
Excel template) using ODBC.

Basically it would be just the same what the method generator for %IsA()
does. The generated %IsA() of class "GrandChild" looks (simplified) like
that:

%IsA(isclass) public {
quit "~MotherOfAllClasses~Daughter~Grandchild~" [ isclass
}


For most applications this posibility may not be that important, but my
data-model is vast and deeply hierarchical in the manner of:

MyPersistentClass
^
|
AuditedObject
^
|
Molecule
^ ^
| |
| DNA
|
Protein
^
|
Enzyme


If a ODBC client queries for all molecules in a certain molecular-weight
range, then it's a nice feature if I can find out if it's just a dumb
protein or a cool enzyme. Of course I could have splitted my query into
a query for each and every one of my branches, but my data-model is
expected to change very often and I don't want to modify the application
logic each and every time that happens.
I probably won't have to use that, because the ActiveX binding is much
powerfull. It's just an idea of how to get class-hierarchy info when
retreiving data with ODBC.


Axel.

Sukesh Hoogan

unread,
Jun 8, 2003, 1:27:04 PM6/8/03
to x...@info2.kinich.com
For x__classname to be used as search condition in the WHERE clause

Try

"SELECT whatever, x__classname FROM MyParentClass WHERE
x__classname='~MyChildClass~'"

i.e you have to include x__classname as one the fields to be retrieved.

Axel Rohde

unread,
Jun 8, 2003, 2:28:44 PM6/8/03
to x...@info2.kinich.com


.... and if you have more than one level of inheritance branching below
MyParentClass, then you could either check for a specific "leaf" with:

SELECT whatever, x__classname FROM MyParentClass
WHERE x__classname LIKE '%~MyChildClass~'

.... or for a specific "branch":

SELECT whatever, x__classname FROM MyParentClass
WHERE x__classname LIKE '%~MyChildClass~%'

But for this purpose it would be much easier to do it the usual way:
SELECT whatever FROM MyChildClass
since, IMHO, there is no benefit of querying like you suggest, Sukesh.


But let me give you an example of what could be done in an elegant way
with x_classname:

With just a single query, like :
SELECT whatever, x__classname FROM MyParentClass
WHERE whatevercriteria

.... we could iterate over the resulting record-set in order to display
each row and use the x__classname value in order to decide what kind of
icon to display with each row, so that the user can easily *see* what
kind of query-hit each row is. This may be interesting in situations
where a property defined in a parent-class may be interpreted in a
slightly different way, depending on what kind of child class it is. An
example of such a property could be a human-readable ID-value with
different nomenclature depending on the actual class of the instance.


Again: this is just interesting on clients whose only binding-choice is
ODBC. It would be of course much powerfull to use the ActiveX, C++,
etc... binding in order to access the info in the %Dictionary.


Axel.
Reply all
Reply to author
Forward
0 new messages