Article Gevorg Arutiunian · Sep 13, 2018 1m read

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

Jolyon Smith · Sep 14, 2018

A couple of small pieces of feedback: 

  1. %Close() doesn't do anything. You can call result.Close(), but if your intention is to destroy the object, you should just kill it.
  2. Using $get(result.Data("Name")) will be quicker than using GetDataByName.
0
Evgeny Shvarov · Sep 14, 2018

I would also change 

For

{ if result.Next()=0 quit 

to

while result.Next() { 
0
Eduard Lebedyuk · Sep 14, 2018

What does it actually do?

I have a table SQLUser.Person for example, it returns nothing.

0
Vitaliy Serdtsev · Sep 14, 2018

I have a few comments.:

  1. 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>##class(objectscript.findTable).test("aaa")
    ?
  2. 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.

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

0
Vitaliy Serdtsev  Sep 17, 2018 to Vitaliy Serdtsev

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>

0
Gevorg Arutiunian · Sep 21, 2018

Thanks for all the suggestions I have amended accordingly!

0