The function Duplicate
of ColdFusion 9 is supposed to return a clone, also known as a deep copy, of a variable, with no reference to the original variable. That's supposed to be true for complex objects, such as structures and queries.
I'm working on a code that uses a query object that is in the APPLICATION scope. This query needs to be modified locally for use in a particular page and I need to know what the original query string was (which is in the query object's metadata). So in this case, creating a deep copy of the original query is the most sensible solution.
But unfortunately, it looks like ColdFusion doesn't clone the whole object, but only its result set, thus losing all the metadata.
That's not the behaviour I expected from Duplicate
, and I don't find it consistent with what happens when duplicating other kinds of complex objects.
One solution to my problem would be passing the result set AND the sql string as separate arguments to the function.
I'd like to know, however, if you have a more elegant solution, and/or throw a bit of light on the query Duplicate issue.
Here's some code that proves the issues for query Duplicate:
<cfquery name="qry" datasource="mydatasource">
SELECT "blue" AS colour, "pear" as fruit
</cfquery>
<cfset qry_copy = qry>
<cfset qry_deepcopy = duplicate(qry)>
<cfdump var="#qry#" label="Original query" />
<cfdump var="#qry_copy#" label="Copy of the query (by reference)" />
<cfdump var="#qry_deepcopy#" label="Deep copy of the query (by value)" />
<cfdump var="#qry.getMetaData().getExtendedMetaData()#" label="Metadata of the original query" />
<cfdump var="#qry_copy.getMetaData().getExtendedMetaData()#" label="Metadata of the copy of the query" />
<cfdump var="#qry_deepcopy.getMetaData().getExtendedMetaData()#" label="Metadata of the deep copy of the query" />
Edit:
In a nutshell, these are my conclusions so far:
qry.getMetaData()
is a JAVA class and, as mentioned in the documentation, If an array element or structure field is a COM, CORBA, or JAVA object, you cannot duplicate the array or structure.getMetaData(qry)
.qry
and getMetaData(qry)
in the APPLICATION scope.Hmmm... that is to my way of thinking a bug. My guess would be that there is a reference to the metadata that is not pulled into the deep copy. If it was something else the "getMetaData()" function called on the deep copy would throw an error.
Have you tried adding the "result" attribute to the query tag? As in:
<cfquery name="qry" datasource="mydatasource" result="myresult">
SELECT "blue" AS colour, "pear" as fruit
</cfquery>
That might create a property or class embedded in the result set - although "result" is actually set in the variables scope I believe. I need to think about this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With