Not sure I'm being clear here; there's no query of queries involved. A
query gets passed in and modified, with one or more columns of data
from some other planet having been added to it.

Internally to the decorator method, an array of user names gets built,
corresponding to the IDs in the column of the passed query named by
userIDColName. That array then gets added to the passed query with
QueryAddColumn, using the passed userNameColName as the name for the
new column. Passing in the source ID column and desired userName
column lets you do things like call it twice to populate
CreatedByUserName and ModifiedByUserName columns, based on
CreatedByUserID and ModifiedByUserID.

In use, it'd look semething like this:
--------------------
<cfquery name="qryWidgets" datasource="#application.dsn#">
        SELECT WidgetID, WidgetName, ModifedByUserID
          FROM Widgets
</cfquery>

<cfscript>
        UserDAO.addUserNamesToQuery(query=qryWidgets,
idColumn=''ModifedByUserID', nameColumn='ModifiedByUserName');
</cfscript>
--------------------
That'd have the effect of adding a ModifiedByUserName column to qryWidgets.

The source of the user names in this specific case is an LRU cache,
which goes to the db on a cache miss. We also have some additional
arguments to provide a default for empty/0, and format multiple names
in the case where the ID column contains a list of IDs.

Make sense?

s

On Tue, Jul 15, 2008 at 4:34 AM, Alan Livie
<[EMAIL PROTECTED]> wrote:
>
> Thanks sparkpool / barry
>
> I'm curious too!
>
> Can you elaborate on some of the internals of your query decorator.
>
> It's good to see alternatives.
>
> Alan
>
> ________________________________________
> From: [email protected] [EMAIL PROTECTED] On Behalf Of Barry Beattie 
> [EMAIL PROTECTED]
> Sent: 15 July 2008 03:38
> To: [email protected]
> Subject: [CFCDEV] Re: Iterators / IBO's
>
> just curious, you're adding additional data to that query, using
> userIDColName as a foreign key?
>
> if so, what's happening internally? munging two queries together and
> having the final form of the data stored/ accessible as a
> Query'O'Query?
>
>
>
> On Tue, Jul 15, 2008 at 12:21 PM, sparkpool <[EMAIL PROTECTED]> wrote:
>>
>> I'm not sure how this fits into best practices and all, but another
>> option I've used is "query decorator" methods, which add one or more
>> columns of related or calculated data to a passed query. An example
>> might be addUserNameToQuery(query, userIDColName, userNameColName).
>> Methods like this exist in their own domain's code, a DAO most likely
>> I'd think, allowing it to participate in processes that collect
>> completely "foreign" data, in an encapsulated way, without the
>> performance hit of instantiating a bean per composite row. This
>> strategy is especially helpful for items needed in many different
>> contexts, that are either hard to query for directly, or that you want
>> to LRU cache or otherwise pre-process.
>>
>> Not sure if I'm being clear about this, or if it's considered bad
>> form, but I've definitely found it a useful pattern.
>>
>> s
>>
>> On Tue, Jul 8, 2008 at 5:37 PM, Alan Livie <[EMAIL PROTECTED]> wrote:
>>>
>>> Thanks for this Kevan.
>>>
>>> The quick 'logic in the view' fix went live and I was given a day to do a 
>>> refactoring before moving onto something else.
>>>
>>> I would like a good stab at a) and your ideas are along the lines I want to 
>>> go down. It's still a bit vague thouh the best way to do it. In the end I 
>>> did something like b).
>>>
>>> I have a new 'display' bean that is composed of the main BeanA but has 
>>> additional properties for the other 'odds'n'ends' it needs.
>>>
>>> I don't really have duplication in the getters and setters as 
>>> onMissingMethod() nicely takes care of most of them. I do have delegate 
>>> methods though in the display bean delegating to BeanA making the 
>>> Iterator's loadQuery() work as normal.
>>>
>>> It's not fully OO but it does keep the controllers and views free of 
>>> duplicated business logic and works ok for now. If in a few months time we 
>>> go 'doh' we can dio more refactoring into a more complex a) solution with 
>>> the Iterator populating several beans but possibly with only the data the 
>>> View actually needs (it will keep the dba happy too:-)
>>>
>>> Alan
>>>
>>>
>>> ________________________________________
>>> From: [email protected] [EMAIL PROTECTED] On Behalf Of Kevan Stannard 
>>> [EMAIL PROTECTED]
>>> Sent: 08 July 2008 21:21
>>> To: [email protected]
>>> Subject: [CFCDEV] Re: Iterators / IBO's
>>>
>>> Hi Alan
>>>
>>> This is a great question.
>>>
>>> (a) sounds like a good solution. Just thinking this one through - your BeanA
>>> would have functions like beanA.getBeanB() and beanA.getBeanC(), but then
>>> your BeanA needs to know how to get access to BeanB and BeanC all the time.
>>> You would also have a function like beanA.loadQuery(query,row) which would
>>> populate beanA as well as populate the composed BeanB and BeanC (they would
>>> perhaps also have corresponding loadQuery() functions and would take the
>>> same query as a parameter). Not sure if you should "recreate" or
>>> "repopulate" BeanB and BeanC each time though - probably depends on how
>>> complex your bean initialisation is.
>>>
>>> If your BeanA does not currently know how to get access to BeanB and BeanC
>>> then perhaps you could create some kind of decorator/wrapper around BeanA (a
>>> ComposedBeanA, for example) that has all of the functions of BeanA but adds
>>> the extra getBeanB(), getBeanC() and loadQuery() functions.
>>>
>>> For (b) you would want to avoid any duplicate code in the getters/setters of
>>> this new bean and the original beans. You might end up composing the
>>> original bean objects inside the new one anyway so it would perhaps end up
>>> looking like the ComposedBeanA object.
>>>
>>> Another option would be to just put the new function in its own separate
>>> calculator/helper component and just pass in the parameters it needs, then
>>> continue using the raw query data for the display. Not a very OO solution
>>> but will probably take only 10 mins to implement ...
>>>
>>> Kevan
>>>
>>>
>>> -----Original Message-----
>>> From: [email protected] [mailto:[EMAIL PROTECTED] On Behalf Of
>>> Alan Livie
>>> Sent: Saturday, 5 July 2008 7:46 PM
>>> To: [email protected]
>>> Subject: [CFCDEV] Iterators / IBO's
>>>
>>>
>>> I'm an occasional user of iterators.
>>>
>>> I have a query that involved joins on several tables because data from those
>>> tables is needed inside the <cfoutput query in the View. Logic started
>>> creeping into the View as the query was looped.
>>>
>>> ie
>>>
>>> <cfoutput query="qGetXXX">
>>>    <cfif qGetXXX.thisBoolCol>
>>>       <cfset valueToDisplay = qGetXXX.aNumericCol *
>>> qGetXXX.anotherNumericCol>
>>>    <cfelse>
>>>         <cfset valueToDisplay = qGetXXX.aNumericCol + 1 />
>>>    </cfif>
>>> </cfoutput>
>>>
>>> I want to use the Iterator so the logic is taken out the view but I get the
>>> performance benefit of query instead of bean array.
>>>
>>> My question is about the complexity of the bean and apologies if it isn't
>>> the best explanation I give!
>>>
>>> The data returned in the query is from several tables but only one or two
>>> columns may be used. I have simple beans for most of the tables involved in
>>> the joins.
>>>
>>> Should I
>>>
>>> a) Create a complex bean with associations to the other beans ie beanA has
>>> its own properties but is composed of a BeanB and BeanC even though I only
>>> need one property out of BeanB and 2 from BeanC.
>>> b) create a new bean specific to what the page / query is doing  ie have a
>>> BeanD with properties of all the display data I need where I can still use
>>> getters to provide the encapsulation I need.
>>>
>>> My thinking is a) is a more elegant solution and more reusable but I need to
>>> do more work to build the bean in my bean factory and also bring more data
>>> out of the db and b) is quicker, leaner but I have little chance of reusing
>>> it elsewhere in the app.
>>>
>>> Any thoughts? Especially from users of Iterators / IBO's
>>>
>>> Alan
>>>
>>>
>>>
>>>
>>>
>>>
>>> >
>>>
>>
>> >
>>
>
>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"CFCDev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/cfcdev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to