Getting the table name right in Reactor custom Gateway methods

Submitted by Falken on

If you are using Reactor, you are probably aware that it's best practice to put all those weird little cfquery's any project has all together in a project-specific Gateway file 'com.falkensweb.project.data.Gateway.barGateway.cfc'.

Obviously, you need to get the table in the FROM clause right, but if you are SELECT'ing the column names to maintain compatibility with the built in Gateway methods (like getByQuery() ) names you need to make sure they are aliased as per your Reactor configuration.
This is very important if you use the fact that column names match transfer object properties to turn queries into arrays of transfer objects.

So, is there some nice way to find out the correct table name and column list strings ? Turns out there are a couple of ways.

After a bit of digging, I discovered you can get at the functions Reactor uses to generate the list of columns and table name:

 <cfset var queryRender = 
createObject('component','reactor.query.render.query').init(_getAlias(),
_getAlias(), _getReactorFactory() ) />

<cfquery name="q" dataSource="#_getConfig().getDsn()#" >
select
#queryRender.getSelectAsString(_getConvention())#
from #queryRender.getFromAsString(_getConvention())#
where
....
</cfquery>

 

Obviously you'll want to cache as many of those calls (like _getConvertion() and createObject() ) as you can to keep the speed up.

Brian Rinadli suggests an alternative approach for the table name based on obtaining the XML from the configuration file and parsing it. It could maybe be extended to parse out column name/alias pairs and format them up, but I think you'll end up rewriting most of the cross-database stuff Reactor already provides.
If you're going to rely on the internal render classes as above for the SELECT clause, you may as well use the same thing for the FROM too.
Here's Brian's code, just in case anyone wants to take a stab at doing it Brian's way:

 <cffunction name="getTableName" access="private" returntype="string"
output="false" hint="I return the table name for the passed table alias.">
<cfargument name="tableAlias" type="string" required="true"
hint="Alias of target table." />
<cfreturn
_getConfig().getObjectConfig(arguments.tableAlias).object.xmlAttributes.name
/>
</cffunction>

 

 

Sections

Submitted by Qasim (not verified) on Fri, 01/18/2008 - 16:48

Permalink

Tom, Thanks for the valuable suggestion. However won't you think this will only work if you are writing query for only one table. What if you were going to join with different tables? Regards

Submitted by Falken on Thu, 03/06/2008 - 14:45

Permalink

If you don't need to select all the columns in your query, you can get the underlying column name for a field by doing something similar to:

md=_getReactorFactory().createMetadata(_getAlias());
colName=md.getField(fieldName).name;

Tom