Find a table given its name
The following code snippet includes a class method "test" that runs code to find a class based on the class's name. "test" takes one argument, which is the name of the table:
Class objectscript.findTable Extends %RegisteredObject
{
classmethod test(name as %String="mytable")
{
#Dim result as %ResultSet
#Dim tName as %String
#Dim contain as %Integer
Set contain=0
Set result = ##class(%ResultSet).%New("%Dictionary.ClassDefinition:Summary")
Do result.Execute()
While(result.Next())
{
Set tName=$get(result.Data("Name"))
&sql(select position (:name in :tName) into :contain)
Write:contain'=0 tName, " ... ", name, " (", contain,")", !
}
Return $$$OK
}
}
Here's a link to the code on GitHub
Comments
A couple of small pieces of feedback:
- %Close() doesn't do anything. You can call result.Close(), but if your intention is to destroy the object, you should just kill it.
- Using $get(result.Data("Name")) will be quicker than using GetDataByName.
I would also change
For
{ if result.Next()=0 quit to
while result.Next() { What does it actually do?
I have a table SQLUser.Person for example, it returns nothing.
I have a few comments.:
- your code finds by the class name, not the table name, which is confusing
For example, for the next class, the method finds nothing:
<FONT COLOR="#000080">Class dc.test Extends %Persistent </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">SqlTableName </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#008000">aaa </FONT><FONT COLOR="#000000">] { ... }</FONT>
USER>d ##class(objectscript.findTable).test("aaa") ? - according to the documentation, your code uses the deprecated API:
proof The Caché Library set of class definitions classes has been superseded by the %Dictionary package. The %Library classes described here are maintained for compatibility with existing applications.
New code should make use of the classes within the %Dictionary package.
- in fact, the search is done elementary:
<FONT COLOR="#0000ff">select </FONT><FONT COLOR="#008000">ClassName </FONT><FONT COLOR="#000080">from </FONT><FONT COLOR="#008000">%Dictionary</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">ClassDefinition_ClassIndex</FONT><FONT COLOR="#000000">() </FONT><FONT COLOR="#000080">where </FONT><FONT COLOR="#008000">ClassName </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#008080">'test'</FONT>
or
<FONT COLOR="#0000ff">select </FONT><FONT COLOR="#008000">ClassName </FONT><FONT COLOR="#000080">from </FONT><FONT COLOR="#008000">%Dictionary</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">ClassDefinition_ClassIndex</FONT><FONT COLOR="#000000">() </FONT><FONT COLOR="#000080">where </FONT><FONT COLOR="#808000">nvl</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">SqlTableName</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">ClassName</FONT><FONT COLOR="#000000">) [ </FONT><FONT COLOR="#008080">'aaa'</FONT>
Still can be so:
<FONT COLOR="#0000ff">select </FONT><FONT COLOR="#008000">relation_name tablename</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#008000">%Library</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">SQLCatalog_SQLClassname</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">relation_name</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#008000">classname</FONT><FONT COLOR="#000080">from </FONT><FONT COLOR="#008000">%Library</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">SQLCatalog_SQLTables</FONT><FONT COLOR="#000000">()
-- where relation_name [ 'aaa'</FONT>
Thanks for all the suggestions I have amended accordingly!