The Google-Zearing Connection
Posted by Ryan Heldt in on March 28, 2012
This story was from a while back, but always intended to share it. Although I have a love-hate relationship with Google, in 2010 they struck a 20-year deal to buy a bunch of green power from a wind farm in Iowa.

Google is buying power from the 100-turbine Story II Wind Energy Center, which has been operating in Story and Hardin Counties since December 2009.
Source: brighterenergy.org
The reason I mention this is because the majority of these turbines are located around my hometown of Zearing, Iowa. It's pretty cool, although even after several years it's somewhat paradoxical to see these high-tech windmills rising from the corn and bean fields I grew up around.
Thou hast been banished
Posted by Ryan Heldt in Tools on March 6, 2012
Tired of subversion folders and files showing up in your Eclipse project navigator and/or search results? Me too, luckily I found an easy way to banish them. First, right click on your project from the project navigator and select 'Properties'. Under 'Resource' select 'Resource Filters'. Finally click 'Add...'.

What you want to do is create an exclude all filter type for folders and all children with the name '.svn'. Click OK twice to make them go away. I also found this prevents the files inside the SVN folders from appearing in search results.
Revisiting To catch a shooting entityDelete()
Posted by Ryan Heldt in ColdFusion , SQL on February 2, 2012
About a year or so ago, I blogged about problems I was having with ColdFusion 9 ORM and using its entityDelete() function to delete items that ultimately could not be deleted because of foreign key constraints within the database. The problem I was having, in a nutshell, was I couldn't trap the error. Despite all kinds of error trapping, a nasty Hibernate exception kept bubbling up.
I was stuck. I tried posting the problem to cf-talk, but didn't find much help.
Some time later, I discovered the cf-orm-dev Google Group and again posted my quandary. Thankfully, I got several replies. One of those was from Mark Mandel (of Transfer and ColdSpring fame), someone in the CF community that I respect very much. He essentially said using try/catch in the manner I was attempting was bad coding practice. I had never considered that -- it was one of those things I always did. Another person suggested that I use ORM events, namely preDelete(). ORM events were new to me, so I investigated.
ColdFusion ORM includes a bunch of events which get called at various states of a database request's lifecycle. Think of it like Application.cfc for database calls. Among these include preLoad, postLoad, preInsert, postInsert, preUpdate, postUpdate, preDelete, and postDelete. Dan Vega has a really great breakdown of all these on his website. The thing I discovered early on is these events aren't enabled by default. You have to switch on eventhandling in ormsettings, like so:
this.ormsettings.eventhandling = true;
I decided that the preDelete() event would allow me to check for constrains, and if I found anything, eaisly back out of the delete. So, in order to delete something we have to load up a record, then run it through entityDelete():
objSong = ("Song",rc.songID,true);
entityDelete(local.objSong);
At this point, preDelete() gets called in Song.cfc, where I can check for any constraints:
<cffunction name="preDelete" access="public" output="false" returntype="boolean">
<cfquery name="local.qryChildRecords">
SELECT ServiceItemID AS ID FROM ServiceItems WHERE SongID = <cfqueryparam value="#this.getSongID()#" cfsqltype="cf_sql_integer" />
UNION
SELECT EventItemID AS ID FROM EventItems WHERE SongID = <cfqueryparam value="#this.getSongID()#" cfsqltype="cf_sql_integer" />
UNION
SELECT SongFileID AS ID FROM SongFiles WHERE SongID = <cfqueryparam value="#this.getSongID()#" cfsqltype="cf_sql_integer" />
</cfquery>
<cfif local.qryChildRecords.RecordCount>
<!--- Child records exists, abort the delete --->
<cfset this.setSongID(javaCast("null","")) />
<cfreturn true />
</cfif>
<cfreturn false />
</cffunction>
The way preDelete() works is if it returns a true value, the delete is aborted. While that's all fine and good, it doesn't do anything to inform the user nothing was deleted. So in order to detect that, I set the primary key of the object (in this case SongID) to NULL. Then, after entityDelete() is called I know if the delete happened or not. There may be a better way, but that seems to work for the vast majority of what I've done.
If anyone has any ideas or suggestions on how to improve on this, I'd love to hear them!
Friendly Filesize Formatting
Posted by Ryan Heldt in ColdFusion on February 2, 2012
Most ColdFusion functions, like cfdirectory, return file size information in bytes. While that is probably a more technically accurate number, it usually doesn't mean a whole heck of a lot to end users, who are probably more used to "denominations" such as the kilo or megabyte. I remedy this, I whipped up the following helper function.
<cffunction name="fileSizeFormat" access="public" returntype="string" output="false"> <cfargument name="size" type="numeric" required="true" /> <cfif arguments.size lt 1024> <cfreturn "#arguments.size# bytes" /> <cfelseif arguments.size lt 1024^2> <cfreturn "#round(arguments.size/1024)# KB" /> <cfelseif arguments.size lt 1024^3> <cfreturn "#decimalFormat(arguments.size/1024^2)# MB" /> <cfelse> <cfreturn "#decimalFormat(arguments.size/1024^3)# GB" /> </cfif> </cffunction>
Basic usage: fileSizeFormat(size)
If you need to show file sizes larger that GB, you could easily add 1024^4 and 1024^5 to the above if statement. Either that or seriously start looking into compression.
Working with Fuzzy Dates and Times
Posted by Ryan Heldt in ColdFusion on January 2, 2012
You've probably seen those relative or "fuzzy" date displays on various sites across the internet, especially on sites like Twitter and Facebook where they'll say "Just Now" or "13 minutes ago" rather than a traditional date-formatted string. It makes sense, after all that's how we speak to each other. For example, if you're meeting someone, if you're asked how long you'd been there, you don't say "I got here at 11:05:46 am". Instead, you say "I got here about 5 minutes ago."

Wanting similar functionality in a project I was working on, I looked around the web and sites like CFLib to see if I could find something similar. I couldn't, so I decided to write my own. The code for the function is below. Although it could be a lot smarter and more international-friendly, it gets the basic job done.
<cffunction name="fuzzyDateDiff" access="public" output="false" returntype="string">
<cfargument name="date1" type="date" required="true" />
<cfargument name="date2" type="date" required="true" />
<cfset var intDiffUnits = 0 />
<!--- Seconds --->
<cfif dateDiff("s",arguments.date1,arguments.date2) lt 60>
<cfreturn "Just now" />
</cfif>
<!--- Minutes --->
<cfset intDiffUnits = dateDiff("n",arguments.date1,arguments.date2) />
<cfif intDiffUnits lt 60>
<cfreturn "#intDiffUnits# minute#iif(intDiffUnits gt 1,de("s"),"")# ago" />
</cfif>
<!--- Hours --->
<cfset intDiffUnits = dateDiff("h",arguments.date1,arguments.date2) />
<cfif intDiffUnits lt 24>
<cfreturn "#intDiffUnits# hour#iif(intDiffUnits gt 1,de("s"),"")# ago" />
</cfif>
<!--- Days --->
<cfset intDiffUnits = dateDiff("d",arguments.date1,arguments.date2) />
<cfif intDiffUnits lt 7>
<cfreturn dateFormat(arguments.date1,"dddd") />
</cfif>
<!--- Weeks --->
<cfset intDiffUnits = dateDiff("ww",arguments.date1,arguments.date2) />
<cfif intDiffUnits is 1>
<cfreturn "Last week" />
<cfelseif intDiffUnits lt 4>
<cfreturn "#intDiffUnits# weeks ago" />
</cfif>
<!--- Months/Years --->
<cfset intDiffUnits = dateDiff("yyyy",arguments.date1,arguments.date2) />
<cfif intDiffUnits lt 1>
<cfreturn dateFormat(arguments.date1,"mmmm d") />
<cfelse>
<cfreturn dateFormat(arguments.date1,"mmmm d, yyyy") />
</cfif>
</cffunction>
Basic usage fuzzyDateDiff (date1, date2)
If you want the result to be realitive to the current date and time, simply use now() for date2. Happy coding!