Duncan's blog

February 4, 2014

CFStoredproc / Duplicate() bug

Filed under: Coldfusion — duncan @ 1:03 pm
Tags: , , ,

Came across this weird one while doing some unit testing using Testbox.  After much head scratching I realised it was a bug in Adobe ColdFusion rather than our testing framework.

Suppose you have a stored procedure which returns more than one recordset:

        <cfstoredproc procedure="foobar" datasource="DSN">
            <cfprocresult name="rstFoo" resultset="1">
            <cfprocresult name="rstBar" resultset="2">

Then you do something where you need to duplicate the first recordset:

        <cfset foo = duplicate(rstFoo)>

That was throwing an error like:

java.lang.ArrayIndexOutOfBoundsException: 1 at coldfusion.sql.imq.Row.getColumn(Row.java:237) at coldfusion.sql.QueryTable.populate(QueryTable.java:230) at coldfusion.sql.QueryTable.<init>(QueryTable.java:77) at coldfusion.sql.QueryTable.<init>(QueryTable.java:72) at coldfusion.runtime.ObjectDuplicator._duplicate(ObjectDuplicator.java:95) at coldfusion.runtime.ObjectDuplicator.duplicate(ObjectDuplicator.java:63) at coldfusion.runtime.CFPage.Duplicate(CFPage.java:5059)

Strangely, this only happens with the first recordset.  This is fine where I do the same with just the second recordset:

        <cfset foo = duplicate(rstBar)>

And if I just remove the second (and subsequent) cfprocresults (without making any adjustment to the stored procedure itself), this also works:

        <cfstoredproc procedure="foobar" datasource="DSN">
            <cfprocresult name="rstFoo" resultset="1">
        <cfset foo = duplicate(rstFoo)>

I came across a couple of bugs in Adobe’s bugbase that basically have the same problem, although both tickets have been closed:

The second of which included this workaround:

        <cfset foo = duplicate(deserializeJSON(serializeJSON(rstFoo), false))>

Which fixed it for me, but ideally Adobe would reopen this bug.   Update: the first of those bugs has now been reopened.

PS: this was running CF 9.01, version 9,0,1,274733


October 5, 2013

CFMap in Railo

Filed under: Coldfusion — duncan @ 9:45 am
Tags: , , , , ,

Adobe ColdFusion has had a CFMap tag since version 9.  It’s not a particularly useful tag, and I suspect it’s not widely used because it’s not too difficult to write your own javascript to call the Google Maps API yourself.  Alternative ColdFusion server Railo has had the CFMap tag since version

Adobe made a bit of a mess of things when Google Maps deprecated version 2 of the API.  It was deprecated in May 2010 in favour of API v3.  Adobe ColdFusion 10 came out in May 2012, a full two years later, but still only supported v2.  So obviously nobody had bothered keeping up to date with what Google Maps were up to, or felt it necessary to update the tag.  The v2 API was going to become completely unsupported in May 2013; Adobe pushed out a hotfix in the same month to upgrade to using v3, but they could have done that as part of the CF10 release a year previously!

As it was, Google delayed turning off the v2 API until November 19 2013.  Apparently anyone still using it will be pushed a basic version of the v3 map instead, which should work for some basic maps, but probably won’t handle any complicated functionality.

So, assuming Railo to normally be quite up-to-date, with frequent updates and so on, I was surprised to spot this code in /mapping-tag/railo/core/ajax/JSLoader.cfc, which makes the AJAX request to load in the Google Maps API (I’ve prettified it slightly to make it more readable):

            provider: {
                google: ["http://maps.google.com/maps?file=api&v=2&key={_cf_params.GOOGLEMAPKEY}&sensor=false", "google/google-map"]
            js: ["RailoMap"],
            events: []

I found this bug already filed back in February 2013, and added my vote and some comments.  It seemed to be about the API key being invalid, and at a guess the user’s key is for v3 not v2.  However the real issue is its use of the old API. So I’ve raised a new feature request for upgrading this; feel free to vote for it.

So in short, Railo haven’t been any better than Adobe in keeping up with updates to Google Maps from 3 years ago!  Although to be fair, I expect the proportion of people using this tag on Railo CF is even less than on Adobe CF.  Read into that what you want – in short the sort of person using Railo I suspect is less likely to need the sort of client-interfacing handholding that tags like CFMap are meant to provide.

August 21, 2013

Regexes for ColdFusion function output attribute

Filed under: Coldfusion,Regular Expressions — duncan @ 5:37 pm
Tags: , ,

One of the things that I frequently see ColdFusion developers forgetting about or getting wrong is the output attribute on cffunction.

Either it’s completely omitted, in which case it’s the same as adding output=true (and will result in extra whitespace being output).

Or it’s incorrectly set to true.  I think developers sometimes assume that if they’re doing something like looping over a query using <cfoutput query=”…”> then they need to have the output set to true.

Here’s a couple of handy regular expressions I sometimes use to find when this has happened.  This blog article is more for my own future reference than anything else.

First (this is from Brian Ghidinelli), this one finds functions without the output attribute:


Secondly, this finds those where it’s not set as false or no.


The (?! … ) syntax is a negative lookahead.  Basically we’re saying, get me everywhere we have something that looks like cffunction output = (not ‘false’ or ‘no’)

This is assuming your text editor can do negative lookaheads.  Alternatively it’s probably simpler to do that the other way round and get everywhere it is cffunction output = (‘true’ or ‘yes’)


June 10, 2013

Scotch on the Rocks

Filed under: Coldfusion,Javascript,Web — duncan @ 5:49 pm
Tags: , , , , ,

I’m just back from this year’s Scotch On The Rocks in Edinburgh. This used to be a ColdFusion-specific conference but now positions itself more for general web-development (although I’d guess easily 80-90% of attendees were CF-developers).

My colleague and ColdFusion über-blogger Adam Cameron wrote up a much better-written post about the whole event. I simply wanted to jot down a bunch of things I’d taken note of during the talks, probably more for my own benefit for future reference than anything else. These are going to seem really disjointed, apologies for that, but I’ll try and annotate them with lots of useful links. I’m also writing all this up several days after it all wrapped, so I might mis-remember some of the details; let me know anything incorrect.

Day One

1. HTML5 Mobile App Development with PhoneGap

Mark Lassoff from LearnToProgram.tv

A quick example (and fun presentation) using HTML5 and PhoneGap to develop a working app for multiple mobile devices. Useful for me, because at this stage I’m not doing any real mobile development, but I expect that to change.

He was using Sublime for his editor.

The viewport meta tag he used was something like

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

PhoneGap and Cordova are basically the same thing

For doing a device ready check he did this:

window.onload = function() {
  document.addEventListener('deviceready', init, false);

function init () {...}

Mark was using the DDMS view in Eclipse for debugging.


2. Mobile Frameworks Shootout!

This talk was scheduled to be by Steve Drucker of Fig Leaf, but it ended up being delivered by his CEO, Dave Gallerizzo. It was a comparison of three major Mobile frameworks.

jQuery Mobile:

  • works off one file for entire app, but in reality you would split it into separate included file
  • good for automatic filtering of lots of data
  • probably use Backbone.js for getting data
  • editors: Aptana Studio, Codiqa, Theme Roller, Brackets, Dreamweaver
  • no MVC framework
  • need 3rd party plugins – Backbone, Google jquery-ui-map
  • good for small apps

Sencha Touch:

Appcelerator Titanium:

  • Eclipse-style editor
  • MVC/XML based
  • good for native app features. Limited forms functionality
  • good for integration of audio/video/photos for native devices


3. Quit your boring 9-5er

Kay Smoljak mentioned all the following:

I’m not convinced it’s a viable idea for myself, but it was an interesting presentation anyway.


4. The number one ingredient behind (technical) success: Team

John Peebles of peebs.org and getadministrate.com gave an engrossing presentation on team building. Some random links he mentioned:

And my favourite quote of the conference, “The plural of anecdote is not data“. Although apparently the original version of the quote was the inverse of that, “The plural of anecdote is data“, but that version’s much less widely used!


5. Zombie Code

Marco Cedaro of cedmax.com speaking about bad javascript code, and going into specifics of writing better code using the AMD pattern. Although a lot of what he mentioned could also apply to other languages too. Slides available here. Some things he mentioned:

I need more time to read up on some of this stuff before thinking of using it.


6. How To Destroy The Web

Bruce Lawson of Opera delivered the most enjoyable presentation of the conference, an ironic look at how we as developers limit our websites (and much more besides).


Day 2

1. Cultured Localisation, or ‘How not to offend one billion people’

Ryan Stenhouse gave the first talk I saw, which had quite a small crowd… unfortunately this was the least professional presentation I saw. I’m not usually critical, but this didn’t meet the standards set by everyone else. His talk was just over 20 minutes compared to the 50 minute slot everyone else I saw filled. His presentation skills were sorely lacking, and he seemed genuinely embarrassed by the end. I’d been looking forward to this as well. The presentation was very similar in style and content to this one he did last year at a Ruby user group, which should give you an idea of what it was like.


2. Using personas in service design – continuously

Tuuli Aalto-Nyyssönen of Ambienta gave a fun presentation about how to use personas when planning and designing websites and apps. Some random things she mentioned:


3. Don’t become Agile, strive for agility

Chris McDermott talking about Agile and Kanban, quite interesting and introducing some things I wasn’t aware of


4. Frakking effective planning: not just for Cylons

Sally Jenkinson discussing technical planning from her position as a consultant. It wasn’t 100% relevant to me, but a good presentation nonetheless. She had a useful mindmap for common questions she always goes through when taking on new work, and I can see a similar approach (or a checklist) being of use to me.


5. Just Mock It: Discovering Mocks & Stubs!

Luis Majano of ColdBox talking about using MockBox when unit testing. I’ve seen him talk before, always entertaining. Adam wrote up a good description of this already, and we both picked up on some new ideas that we could apply to our unit testing. One thing he talked about – You shouldn’t amend your code to accommodate unit testing – this implies you’re probably making your code too complex, tightly-coupled or just aren’t mocking properly. Some links:

Phew, that’s it – mostly just a collection of links to various things which might be useful to me later. Overally – a good conference in all ways.

March 1, 2013

Adobe ColdFusion Developer Center

Filed under: Coldfusion — duncan @ 10:40 am
Tags: , ,

I’d heard there was a hotfix change to Adobe ColdFusion 9 & 10 for the CFMap tag, to start using Google Maps API v3 instead of the deprecated (and very-soon to be unavailable) Google Maps API v2. So I decided to make an infrequent visit to the Developer Center and see if I could find anything about it. Nothing obvious, but I noticed this:

CFDev Center

Aha, a useful example on ‘working with Google maps’ using cfmap!  Unfortunately that link just displays a map. It doesn’t show any code, so is useless as an example of using CFMap.  Similarly the other link on using cfspreadsheet merely shows me a dumped query and a table… very useful I’m sure.

January 22, 2013

Converting UUID to Base36

Filed under: Coldfusion — duncan @ 10:40 am
Tags: , , , , , ,
Base 36

I needed to generate a random unique string of no more than 30 characters length for integrating with an external API.  Usually for something like this we’d use a UUID/GUID, which are 36 characters long (or 35 in ColdFusion).  A colleague came up with the idea of taking that and converting it to Base 32.  He was using C# and this class, but then this part of the work got transferred to the ColdFusion team, so here’s the approach I took.

Firstly, a UUID is a hexadecimal representation of a 128-bit number.  Being hexadecimal that’s Base 16 obviously; the characters 0-9A-F.

A 128-bit number = 2^128, which is a very big number (340,282,366,920,938,463,463,374,607,431,768,211,456 possible values).  ColdFusion can struggle with integers this size in certain functions, e.g. InputBaseN (and its counterpart FormatBaseN), otherwise that would be ideal for what I’m trying to do here

There’s already a function in CFLib which could do this, but it’s compatible with ColdFusion 5, i.e. it’s not got access to any of the underlying Java classes which CFMX does.  My colleague Adam also wrote a different function which can convert between any two bases, but it’s more fully-featured than I require as well.

UUID’s also contain hyphens.  Typically a UUID format is in a 8-4-4-4-12 pattern, i.e. the string is 36 characters long.  ColdFusion does it differently; 8-4-4-16, only 35 characters long.  Apparently this difference was a mistake, which they didn’t want to amend later due to backwards-compatibility. However for the purposes of this code, I don’t care either way, I just want to get rid of the hyphen separators.

So, step 1 is remove the hyphens from a UUID:

<cfset strUUID = createUUID()>
<cfset strUUID = replace(strUUID, "-", "", "ALL")>

Now I want to turn this hexadecimal string into a BigInteger, which is the Java class which can deal with numbers this size (Integer only goes up to 2^31-1, Long goes up to 2^63-1, so BigInteger it has to be).

<cfset bigInt = createObject("java", "java.math.BigInteger").init(strUUID, 16)>

So we use the BigInteger constructor, specifying our string and the Base 16 radix as the second parameter.

Step 3, we want to then convert that BigInteger to Base 36. This is the characters A-Z0-9, and is ‘the most compact case-insensitive alphanumeric numeral system using ASCII characters’. Which I took to be a good thing; the advantage that Base 32 (that my colleague had chosen) would have given is it eliminates certain characters which might be easily-confused if you were reading the values after encoding in that base. So it’s ideal for generating codes used for humans, but that wasn’t going to be an issue here, so I chose Base 36 instead.

<cfset strBase36 = bigInt.toString(36)>

Putting it all together:

<cfset strUUID = createUUID()>
<cfset strUUID = replace(strUUID, "-", "", "ALL")>
<cfset bigInt = createObject("java", "java.math.BigInteger").init(strUUID, 16)>
<cfset strBase36 = bigInt.toString(36)>

strUUID: #strUUID#, #len(strUUID)#<br>
strBase36: #strBase36#, #len(strBase36)#

Gives me something like:

strUUID: AFA64721B8AC6F8CD055DE2527EB20F9, 32
strBase36: aecxzys9dnwydn6ejgkxwgb95, 25

PS: apologies to Base36 (the company) for borrowing their funky (and let’s be honest, better-executed) Base36 mosaic idea.

October 18, 2012

ColdFusion cfloop versus cfscript for loop performance

Filed under: Coldfusion — duncan @ 7:01 pm
Tags: , ,

I’m sure most web developers are aware that, in Javascript, it’s generally considered best practice to do this:

for (var i = 0, len = array.length; i < len; i++) { }

instead of this:

for (var i = 0; i < array.length; i++) { }

The theory being that you improve performance by caching the array length once, instead of each time you iterate over the loop (although it’s open to debate how important this is; it really only benefits IE).

I decided to see if there was any benefit in doing the same thing with array loops in ColdFusion. Initially just tested with CFML, then again with CFScript, to see if there were any differences.

<!--- start with a blank file each time --->
<cfif fileExists("arraylen.txt")>
	<cffile action="delete" file="arraylen.txt">

<cfloop index="j" from="1" to="1000">
	<!--- create a large array to loop over later --->
	<cfset myArray = []>	
	<cfloop index="i" from="1" to="10000000"><cfset arrayAppend(myArray, "")></cfloop>

		// Method 1
		tick = GetTickCount();

		for (i=1; i <= arrayLen(myArray); i++) {}

			type	= "CFScript (arrayLen)",
			tick	= tick

		// Method 2
		tick = GetTickCount();

		len = arrayLen(myArray);

		for (i=1; i <= len; i++) {}

			type	= "CFScript (var'ed)",
			tick	= tick

	<!--- Method 1 --->
	<cfset tick = GetTickCount()>

	<cfloop index="i" from="1" to="#arrayLen(myArray)#"></cfloop>

	<cfset recordTime(
		type	= "CFML (arrayLen)",
		tick	= tick

	<!--- Method 2 --->
	<cfset tick = GetTickCount()>

	<cfset len = arrayLen(myArray)>

	<cfloop index="i" from="1" to="#len#"></cfloop>

	<cfset recordTime(
		type	= "CFML (var'ed)",
		tick	= tick

<cffunction name="recordTime" output="false" returntype="void">
	<cfargument name="type" type="string" required="true">
	<cfargument name="tick" type="numeric" required="true">

	<cfset var tock = GetTickCount()>
	<cfset var time = tock - arguments.tick>

	<cffile action="append" output="#arguments.type##chr(9)##time#ms" file="arraylen.txt">

What I did find was that the two methods, of either calculating arrayLen() within the FOR loop, or storing it as a variable, hardly differed at all in performance.

However there was a big difference in performance between CFML and CFScript. In this case, the looping was much slower in CFScript. This isn’t something new, I’m sure I’ve heard this before, but it was an interesting reminder for me that sometimes it’s not always best to write everything in CFScript.

So here’s the results showing the average times from running this 1000 times:

CFML (arrayLen) 257.883ms
CFML (var’ed) 258.284ms
CFScript (arrayLen) 1259.294ms
CFScript (var’ed) 1180.07ms

As we can see, the difference between caching the array length in a variable, or using arrayLen() for the loop limit, is negligible in CFML, less than 0.5 of a millisecond after 1000 iterations!

However in CFScript, it seems slightly quicker to use a variable instead of referring to arrayLen() within the iterator. But not so much that I’d say I’d favour one method over the other. Although I’ll certainly think twice before writing array loops in CFScript instead of CFML… although in reality the difference in performance is relatively minor (unless you’re working on massive arrays and/or have a high-traffic application).

PS: I’m running this on Adobe ColdFusion 9,0,1,274733 on Windows 7, YMMV 🙂

March 12, 2012

ColdFusion regular expression backreferences and numeric strings

Supposing you have a string that starts with a number, e.g. “25% discount this weekend”, and you’re using that along with a regular expression.  If you’ve got a backreference immediately prior to that “25%…”, ColdFusion treats it as \125 instead of \1. 

For instance:

<cfset myString = "25% Discount this weekend">

<cfset originalString = "Look out for our special offers, including XXX and much more">

<cfset newString = reReplace(originalString, "(.*)XXX(.*)", "\1#myString#\2")>


This just outputs:
% Discount this weekend and much more
as it thinks that you’re trying to do \125 instead of \1 followed by “25%…”

To get around this, you can use \E to separate the backreference from the rest of the string.
\E is meant to indicate when you’ve reached the end of an uppercase or lowercase block as set by \U or \L. However in this case it simply indicates to the regular expression process where the end of the backreference occurs.

<cfset newString = reReplace(originalString, "(.*)XXX(.*)", "\1\E#myString#\2")>


This time it correctly outputs:
Look out for our special offers, including 25% Discount this weekend and much more

November 10, 2011

ColdFusion query-of-queries, tips for adding dynamic columns

Filed under: Coldfusion — duncan @ 5:35 pm
Tags: , , ,

Supposing you’re doing a query of queries, and you want to add a dynamic column, perhaps based on a mixture of existing CF variables and values from the original query. There are a few gotchas to watch out for.

Firstly, you have to use single quotes ‘ ‘ instead of double quotes ” ” for anything in the string. This is contrary to ColdFusion’s normal allowance for any mixture, e.g. this is usually perfectly fine:

<cfset x = "hi" & 'hi'>

However when trying to use ” ” in the query-of-queries, it throws the error:

Query Of Queries syntax error.
Encountered “. Lexical error at line 3, column 25. Encountered: “\”” (34), after : “”

This query will throw that error:

<cfquery name="rstGetStuff" dbtype="query">
	SELECT 	"Hello World" AS columnName
	FROM rstOriginalQuery

But this is fine:

<cfquery name="rstGetStuff" dbtype="query">
	SELECT 	'Hello World' AS columnName
	FROM rstOriginalQuery

Secondly, if you’re wanting to refer to variables within that string, just add them into the string surrounded by # #. Again, contrary to normal CFML, where these are equivalent:

<cfset x = "hi " & variables.strName>
<cfset x = "hi #variables.strName#">

So this throws the error:

Query Of Queries syntax error.
Encountered “.. Incorrect Select Statement, Expecting a ‘FROM’, but encountered ‘.’ instead, A select statement should have a ‘FROM’ construct.

<cfset strName = "Duncan">

<cfquery name="rstGetStuff" dbtype="query">
	SELECT 	'Hello ' + strName AS columnName
	FROM rstOriginalQuery

Instead you have to do

<cfquery name="rstGetStuff" dbtype="query">
	SELECT 	'Hello #strName#' AS columnName
	FROM rstOriginalQuery

Thirdly, if you’re wanting to add values from the original query into that dynamic column, you might need to CAST it to the correct type. In this case I have a column in the original query, intIDColumn, that is a numeric ID.

This throws the error:

Query Of Queries runtime error.
Cannot mix types INTEGER and VARCHAR in a + binary operation.

<cfquery name="rstGetStuff" dbtype="query">
	SELECT 	'/some/url/path/' + intIDColumn + '/' AS strURL
	FROM rstOriginalQuery

Instead I have to cast it to a VARCHAR when trying to add it into my string.

<cfquery name="rstGetStuff" dbtype="query">
	SELECT 	'/some/url/path/' + CAST(intIDColumn AS VARCHAR) + '/' AS strURL
	FROM rstOriginalQuery

September 21, 2011

ColdFusion LSCurrencyFormat inserts hard spaces?

Filed under: Coldfusion — duncan @ 8:31 pm
Tags: , , , , , ,

Today I was doing some work with the LSCurrencyFormat function for the very first time. Along the way I discovered something slightly unexpected. If the locale you specify uses spaces for a thousands separator (e.g. French), then Adobe ColdFusion (no idea for Railo or BlueDragon), doesn’t just add a normal space, it uses a ‘hard’ space.

I wouldn’t have found this out at all if it wasn’t for the fact I was doing some unit tests with MXUnit at the time. My test case was something like this:

<cfset strPrice = lsCurrencyFormat("12345678.9", "none", "fr_FR")>
<cfset assertEquals("12 345 678,90",  strPrice)>

So initially that failed, giving me the useful message that
Expected ’12 345 678,90′ but received ’12 345 678,90′. These values should be the same.
Puzzling. I was doing this in Firefox; if I selected just the error message and then chose View Selection Source, I could see it actually said
Expected ’12 345 678,90′ but received ’12&nbsp;345&nbsp;678,90′.

Ahah, so I assumed it was inserting the ‘&nbsp;’ non-breaking space HTML entity into the value instead of just a normal single space. So I updated my unit test assertion to be like this:

<cfset assertEquals("12&nbsp;345&nbsp;678,90",  strPrice)>

But that also failed, and this time when checking the source, it said
Expected ’12&nbsp;345&nbsp;678,90′ but received ’12&nbsp;345&nbsp;678,90′.
Curiouser and curiouser!

So at this point, I decided to loop over the actual string returned by lsCurrencyFormat to examine it more closely:

	<cfset french = lsCurrencyFormat("12345678.90", "none", "fr_FR")>
	<cfloop index="i" from="1" to="#Len(french)#">
		<cfset char = mid(french, i, 1)>

Which produced output that looked like:


The normal HTML space is ASCII character 32. But in this case it’s inserting ASCII character 160, which the browser interprets as &nbsp;. So for my unit test to work, I’ll have to do something like:

<cfset assertEquals("12" & Chr(160) & "345" & Chr(160) & "678,90",  strPrice)>

Dunno why Adobe in their infinite wisdom (to be honest this probably dates back to Allaire or Macromedia) would use character 160 instead just a normal single space character 32. And I expect other locale-specific formatting functions must do the same thing.
I’m getting exactly the same results with java.text.DecimalFormatSymbols.getGroupingSeparator(), so I expect ColdFusion is using that functionality in the background.

I suppose it shouldn’t really cause any problems, apart from perhaps when you’re needing to unit test (or perhaps if parsing some HTML you’ve received by CFHTTP). Just, unexpected is all.

Next Page »

Blog at WordPress.com.