Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ColdFusion's Duplicate function won't copy metadata of a query

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" />

A query, its copy and its deep copy


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 and getMetaData(qry) in the APPLICATION scope.
like image 424
Xevi Pujol Avatar asked Jan 09 '14 14:01

Xevi Pujol


1 Answers

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.

like image 50
Mark A Kruger Avatar answered Sep 28 '22 13:09

Mark A Kruger