Posts in Category "ColdFusion"

Who Would Use a CFCONTINUE Tag?

This isn’t an official survey (or even unofficial one, for that matter), but I’m wondering how many people out there would use a CFCONTINUE tag if there were one available. Personally, I find the ability to continue (to jump to the next item in a loop) very useful, and occasionally my ColdFusion code suffers without it. 90% of the time I easily get by with CFIF tags inside loops, but when there is a great deal of processing going on, and a lot of decisions being made, I’ve found myself having to nest a lot of CFIF tags when a CFCONTINUE tag could have simplified my code. What are your thoughts?

Submitting Flash Forms Without Refreshing

I’ve been working on a way to submit Blackstone Flash forms without refreshing the page, and I have it working quite well. The code lets you either submit data to the server without re-rendering the Flash, or submit the data to a different window (the CFFORM tag supports targets, but the target attribute doesn’t give you a way to submit to a different window).

I’ve only tested it with Firefox, but I’m pretty sure it will work on all modern browsers. It’s a bit too early to release the code just yet, but once Blackstone is live, I’ll release the code along with a tutorial.

What do you guys think of what you’ve seen of Flash forms so far?

Reinitializing an Application Using Blackstone Events

One of the most useful tags I’ve ever written is the init tag. Typically, it goes
in your Application.cfm file, and the body of the tag gets executed only the first
time it’s encountered, which means it’s the perfect place to put initialization
code. You can also force the body to execute again by passing a certain query string
parameter in with any request. This is very useful during development when you need
to flush cached components or other data.

As I started thinking more in Blackstone terms, however, I wondered what the Blackstone
equivalent on the init tag would be. Of course, the init tag still works in Blackstone
as does all the CFMX 6.1 code I’ve run so far, but I wanted to take advantage of
the new event handling
mechanisms available in Blackstone
. So here’s what I’ve come
up with so far.

Now, I handle application initialization using the onApplicationStart event. That
takes care of running the code only once (usually when the application receives
its first request since the server was last started). I then added the following
inside my onRequestStart event handler:

<!--- Re-initialize the application, if necessary --->
<cfif structKeyExists(url, "restart") and url.restart>
<!--- Invoke onApplicationStart event --->
</cfif>

Now, when I want to invoke the onApplicationStart event, I just append a restart=true
parameter to any request, and my application is reinitialized without me having
to restart the server.

Chopping Off the End of a List

I’m sure there are tons of these functions around, but I decided to write my own.
The listChop function chops a list down to the specified size. Use it like this:

<cfset myList = "a,b,c,d,e"/>
<!--- Chop this list down to 3 elements. --->
<cfset myList = listChop(myList, 3[, delimiter])/>

Here’s the function:

<cffunction name="listChop" returnType="string" output="no" >
<cfargument name="targetList" type="string" required="true"/>
<cfargument name="amountToKeep" type="numeric" required="true"/>
<cfargument name="delimiter" type="string" required="false" default=","/>
<cfset var listSize = listLen(arguments.targetList, arguments.delimiter)/>
<cfset var i = 0/>
<cfif arguments.amountToKeep lt 0 or listSize - arguments.amountToKeep le 0>
<cfreturn arguments.targetList/>
</cfif>
<cfloop from="#arguments.amountToKeep+1#" to="#listSize#" index="i">
<cfset arguments.targetList = listDeleteAt(arguments.targetList,
arguments.amountToKeep+1,
arguments.delimiter)/>
</cfloop>
<cfreturn arguments.targetList/>
</cffunction>

I’m using it in a pretty big application I’m writing, so let me know if you see
any bugs.

Safely Selecting the Last Inserted ID, Part II

Well, as it turns out, this isn’t
an issue at all. I ran two tests. The first followed these steps:

  1. Using a CFQUERY tag, I executed an insert statement.
  2. Used Thread.sleep() to make the page hang for 10 seconds.
  3. Inserted ten additional rows from the command line (using the MySQL command
    line tool).
  4. After the Thread.sleep(), used LAST_INSERT_ID() to get the last inserted ID,
    and displaed it.

I expected the result to be 11, but it was actually 1.  The 10 rows I inserted
between the initial insert and when I selected the last inserted ID had no effect.  I
figured this was because ColdFusion was considered one client, and the command
line administrator was considered a different client, and since the scope of
the last inserted ID is the client/connection, I was protected.  So I ran this
test, instead:

  1. Executed an insert statement in ColdFusion.
  2. Slept for 10 seconds.
  3. Ran a second CFM page that inserted 10 rows while the first page was hung.
  4. After the thread in the original page woke up, selected the last inserted id
    and displayed it.

Keep in mind I was using no transactions or locks since I was trying to get a
wrong result before trying to figure out how to get the correct one, however
the result was once again 1.  As it turns out, no transactions or locks are
needed.  Why?  Apparently because each request gets its own database connection,
and that one connection gets reused for the duration for the request, regardless
of how many database operations you perform.  Other
requests can happen simultanously, of course, but they all get their own connections,
and hense do not affect the first connection’s last inserted ID value.  In
other words, it seems to work exactly how you would want it to!  ColdFusion
does it again!

Disclaimer: This test was run using JRun, CFMX 6.1 (with the
latest updater) and MySQL
version 4.0.18.  Before you rely on this data, you might want to run some tests
yourself, though I will try to get confirmation from the ColdFusion team that
this technique should work across all databases and future versions of ColdFusion.

Safely Selecting the Last Inserted ID

I run into this issue occasionally, and always find some kind of work-around,
but I’ve finally decided to address it head-on. The scenario is this:

  1. You insert
    a record into the database.
  2. You need the ID of the row you just inserted so you can insert additional
    rows in other tables referencing the first row you inserted.
  3. You’re worried about your code being thread-safe, so you consider
    using locks, transactions, UUIDs, etc. But what is the best way?

The easiest and most database-independent way of doing this is to generate a UUID
and use it for the primary key for the first insert, and the foreign key for any
subsequent inserts. That’s fine for certain apps, but for the app I’m working on
now, I need to use sequential, auto incremented integers as keys. I’m using the
MySQL function LAST_INSERT_ID() to get the last inserted ID, however the ID’s scope
is the current connection, so if I use two CFQUERY tags (one to insert the row,
and one to get the last inserted ID), I believe it’s possible I could get the wrong
ID if another row is inserted between the time I do my insert and the time I select
the last inserted ID. So I’m going to try:

  1. Sending two queries to MySQL at the same time. One to do the insert, and one
    to do the select. Both statements will use the same connection, and problem
    solved. I haven’t had any luck with this so far, though. I’m not sure MySQL supports
    this as I keep getting SQL syntax errors.
  2. Putting both CFQUERY tags in a transaction (they actually already are in a
    transaction), and using the isolation level of serializable. I’m potentially
    sacrificing some performance, but it should be miniscule. This is a very
    good solution if it works, but I’m not 100% positive that it will work, though
    I am hopeful.
  3. Using an exclusive lock. If all else fails, this will definitely work, although
    the disadvantage is that I will only be taking database operations that
    originate from one CF server into account. In other words, another server that
    is unaffected by the lock can slip a new row into the database at just the right
    moment and trip me up. I would much rather the lock occur at a lower level — actually
    in the database, if possible.

I’ll post my results. In the meantime, anyone have any additional insight?

What If You Want To Round Down?

ColdFusion’s round() function rounds up. What if you want to round down? Use this:

<cffunction name="roundDown" output="no">
<cfargument name="target" type="numeric" required="true"/>
<cfreturn abs(round((arguments.target * -1)))/>
</cffunction>

Example:

round(1.1) = 1
roundDown(1.1) = 1

round(1.5) = 2
roundDown(1.5) = 1

round(1.6) = 2
roundDown(1.6) = 2

Addition:

Bill pointed out that the function above doesn’t work with negative numbers. This one does. Thanks, Bill!

<cffunction name="roundDown" output="no">
<cfargument name="target" type="numeric" required="true"/>
<cfreturn (round((arguments.target * -1))) * -1/>
</cffunction>

Example:

roundDown(-1.5) = -2

How to Log Out of an Application that Uses HTTP Authentication

I’m working on an application right now that uses the simple 401 (unauthorized) response code and “WWW-Authenticate” HTTP header to prompt the user for a username and password. This mostly works as expected, however I want the user to be able to log out of the application, which is not so easily done. The CFLOGOUT tag does not tell the browser to stop sending the Authentication header containing your credentials to protected pages, so the only way to be sure you are logged out is to end your session from the browser’s perspective, which means closing it. I’m experimenting with another technique, though, and I’d like to get some feedback.

The only people who log into this application I’m working on are system administrators, so the solution doesn’t have to look pretty as long as it works. The idea is to make the browser forget the user’s credentials by giving it new, false credentials to send, instead. The “logout” code I came up with looks like this:

<cffunction name="logout" ...>
<cflogout/>
<cfheader statuscode="401"/>
<cfheader name="WWW-Authenticate" value="Basic realm=""admin"""/>
<html>
<script language="javascript">
document.location = '../index.cfm';
</script>
</html>
<cfabort/>
</cffunction>

When the user clicks on the “Log Out” link, the function above is executed, and the user is prompted by the browser to enter a username and a password at which point he clicks on cancel, the browser forgets the previous (presumably correct) authentication information, and the user is redirected to an unprotected, public index page. All subsequent requests to the protected admin section of the application will send the wrong credentials, and cause the browser to prompt for new ones.

This seems to work well in the few browsers I’ve tested with, though, as I said, it’s not that pretty, and wouldn’t be a good solution for end users. For admins, though, it seems reasonable.

Does anyone else have a different way of tackling this problem?

ColdFusion 6.1 Updater Now Available

Well, you finally convinced us that there were too many hot fixes out there for you to keep track of, and we needed to roll them all into a 6.1 updater, so here you go. Now back to Blackstone.

Introduction to Flash (for ColdFusion Developers)

I delivered a presentation today to ColdFusion User Group managers via Breeze. It’s basically an introduction to Flash and RIAs for ColdFusion developers. I go through some slides discussing RIAs in general, then dissect a Flash and ColdFusion application line by line. It’s about an hour long, so if you have some time, and you’re curious about Flash and RIAs, check it out.