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:
- The metadata doesn't get duplicated because
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. - The documented ColdFusion function to get the metadata of a query is
getMetaData(qry)
. - I've fixed my problem by storing both
qry
andgetMetaData(qry)
in the APPLICATION scope.
duplicate
java objects that may be relevant. So I do not think it makes any guarantees about copying the entire object, if portions of it consist of java objects. – LeighgetMetadata()
function. Those internal methods are not supposed to be used directly, so all bets are off as far as how inbuilt CFML functions deal with them. – Adam Cameron