Data-Centric Development with ColdFusion 9 and Flash Builder 4

The second part of my Data-Centric Development with ColdFusion 9 and Flash Builder 4 tutorial is up on DZone. This tutorial builds on the project introduced in part one of the series and covers the new paging and client-side data management features available in Flash Builder 4.

Data-Centric Development with ColdFusion 9 and Flash Builder 4 - Part 2

If you want to find out even more about these seriously cool features be sure to check out the following links:

JSONUtil 1.1

Last year I put together JSONUtil as a proof of concept solution to the issue of ColdFusion's implicit type conversion during JSON serialization. There were some issues with the 1.0 release, and I've had a few people submit patches, but because I had considered the project an experiment I didn't really take the time to update the official release.

Well, last week I was working on an AJAX project where I was making XHR requests to ColdSpring remote proxies using ColdFusion's built in JSON return format when I began running into issues with implicit type conversion. Specifically I had a method that should have returned a query with string values, however numeric strings were getting converted to decimal numbers. (For example the string "001" was being converted to number 1.0.) Because I was already using ColdSpring to generate the proxies I decided to put together a JSONUtil based ColdSpring advice component to handle the serialization. The advice turned out being so handy I thought I'd package it up and include it in the JSONUtil release.

[More]

Another CFScript Query Gotcha

There have been a few issues reported with using the new Query component from cfscript and today I ran into another. Well actually I had a co-worker ask about it, but it still led me to look into the issue. (Little did I know he was researching his own blog post on this. Sorry for stealing your post Adam.) Anyway, my co-worker was trying to run a Query of Queries in cfscript. Here is an example:

<cfscript>
//create an empty query to work with qryFoo = queryNew("a,b,c","varchar,varchar,varchar");

//add a row and fill it with some data queryAddRow(qryFoo);
querySetCell(qryFoo,"a","aaaaaa");
querySetCell(qryFoo,"b","aaaaaa");
querySetCell(qryFoo,"c","aaaaaa");

writeDump(var=qryFoo, label="qryFoo");

qryFoo2 = new query(dbtype="query", sql="select a, 'bbbbb' as b, 'ccccc' as c from qryFoo");
result = qryFoo2.execute();

writeDump(var=result, label="qryFoo2");
</cfscript>

This code resulted in the following error:

Error Executing Database Query.

Query Of Queries runtime error. Table named qryFoo was not found in memory. The name is misspelled or the table is not defined.

At first I was a bit baffled, but when I thought about it for a minute it actually made perfect sense. The script functions implemented as CFCs are just the plain old CFML tags wrapped in components. That means when the cfquery tag actually executes it does so within the context and scope of the component function, not the calling page. To help illustrate the issue consider the following component:

<!--- sample.cfc --->
<cfcomponent>
<cffunction name="doDump">
<cfdump var="#myVar#" />
</cffunction>
</cfcomponent>

You wouldn't really expect the following code to work and it won't. You will get an error stating that myVar is undefined:

<cfset myVar = "This is a test." />
<cfset CreateObject("component","sample").doDump() />

That is basically what is going on with the query of queries example above. One workaround I thought of would be to put the original query in a scope the CFC can access, say the request scope:

<cfscript>
//create an empty query to work with request.qryFoo = queryNew("a,b,c","varchar,varchar,varchar");

//add a row and fill it with some data queryAddRow(request.qryFoo);
querySetCell(request.qryFoo,"a","aaaaaa");
querySetCell(request.qryFoo,"b","aaaaaa");
querySetCell(request.qryFoo,"c","aaaaaa");

writeDump(var=request.qryFoo, label="qryFoo");

qryFoo2 = new query(dbtype="query", sql="select a, 'bbbbb' as b, 'ccccc' as c from request.qryFoo");
result = qryFoo2.execute();

writeDump(var=result, label="qryFoo2");
</cfscript>

This works, but it is obviously less than ideal. Given all of the issues with the current Query.cfc I'm really hoping Adobe can come up with a better solution for full cfscript support in the next version of CF.

Update

Adam Cameron pointed out another solution in the comments below. Apparently you can use the setAttributes method of the Query object to set arbitrary attributes. I didn't realize this as the documentation states that this method supports "all attributes supported by the cfquery tag." But if you look at the implementation for the method you can see it just adds any attributes to the variables scope of the component:

public void function setAttributes()
      {
         if(!structisempty(arguments))
         {
            structappend(variables,arguments,"yes");
         }
      }

Here is a complete example using setAttributes:

<cfscript>
//create an empty query to work with qryFoo = queryNew("a,b,c","varchar,varchar,varchar");

//add a row and fill it with some data queryAddRow(qryFoo);
querySetCell(qryFoo,"a","aaaaaa");
querySetCell(qryFoo,"b","aaaaaa");
querySetCell(qryFoo,"c","aaaaaa");

writeDump(var=qryFoo, label="qryFoo");

qryFoo2 = new query(dbtype="query", sql="select a, 'bbbbb' as b, 'ccccc' as c from qryFoo");
qryFoo2.setAttributes(qryFoo=qryFoo);
result = qryFoo2.execute();

writeDump(var=result, label="qryFoo2");
</cfscript>

Note that there are thread-safety issues with this approach. If you do use setAttributes make sure you create a new instance of the service component for each service call.

Data-Centric Development with ColdFusion 9 and Flash Builder 4

I just posted the first of a two part tutorial over on DZone which walks through using some of the new data-centric development (DCD) features in Flash Builder 4 with ColdFusion 9.

Data-Centric Development with ColdFusion 9 and Flash Builder 4 - Part I

While Flash Builder is still in beta, the DCD features are very impressive and should simplify many ColdFusion/Flex work flows. Please check out the tutorial and let me know what you think. (And be sure to vote it up if you like it!)

New ColdFusion Builder and Flex Builder Betas

In addition to today's release of ColdFusion 9, ColdFusion Builder Beta 2 and Flex Builder 4 Beta 2 have been released on Adobe Labs.

ColdFusion 9 Released

ColdFusion 9 was released today. Go and get it!

http://www.adobe.com/products/coldfusion/

hf801-71643 Breaks Application Specific Custom Tag Paths

About a month ago Adobe released CHF 3 for ColdFusion 8. I was excited about this release because it fixed a bug that has caused quite a few headaches I'm sure, that being application specific custom tags not working under load. At work we recently deployed the cumulative hot fix to one of our production clusters only to find we were still seeing the "Cannot find CFML template for custom tag" error on a pretty consistent basis. Determined to get the bottom of the issue, today I installed CF 8 locally (another post on this later) and put together a quick test app that I could run JMeter against. Our production servers run a few other hot fixes in addition to the CHF so I had a feeling that one of the other hot fixes may be causing the issue. Sure enough, as I tested each hot fix in combination with CHF 3 I found that application specific custom tag paths started failing under load with hf801-71643 applied. That particular hot fix attempts to address some of the issues with CFC serialization to AMF (Flash Remoting) in CF 8. There are numerous issues with CFC serialization to AMF in ColdFuison 8 and hf801-71643 does not fix all of them, so we opted to remove it in favor of working custom tag paths. Anyway, I just thought I'd share this in case others have installed CHF 3 only to find they are still getting "Cannot find CFML template for custom tag" errors with application specific custom tag paths. If your still seeing this error be sure be sure to check the other hot fixes you have installed as they may be the culprit.

BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.