<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0">
	<channel>
		<title>Dan's Shorts</title>
		<pubDate>Mon, 21 Jul 2008 00:00:00 PST</pubDate>
		<description>A blog mostly about the life and times of Dan Short, a web developer in Austin, Texas. When he's not rambling about [insert latest obsession] the blog focuses on technical aspects of ColdFusion and current projects he's working on.</description> 
		<link>http://www.dansshorts.com/</link> 
		<language>en-us</language>
		<copyright>Copyright 2002 - 2008 Daniel Short</copyright>
		<image>
			<title>Dan's Shorts</title> 
			<url>http://www.dansshorts.com/dan.gif</url> 
			<link>http://www.dansshorts.com/</link> 
			<height>112</height>
			<width>49</width>
		</image>

		<item>
			<pubDate>Mon, 21 Jul 2008 14:12:16 PST</pubDate>
			<title>Managing the Transfer Cache with Clones</title> 
			<link>http://www.dansshorts.com/?day=7/21/2008#blog368</link> 
			<description>In my recent adventures with Transfer, I ran into a problem where objects that weren't yet saved were showing up in my cached Transfer objects. Since I don't make mistakes (uh huh...) I immediately assumed this was a bug in Transfer, and went about documenting my problem on the Transfer group. Well it turns out (surprise surprise) that this was by design, and so I had to make a few changes to my way of thinking in order to get my app to behave the way I expected it to. So here's a rundown of the &quot;problem&quot; and what was done to fix it (thanks to Matt Quackenbush for the fix). How's the Cache Work? Basically the Transfer cache keeps track of everything you do to an object, whether it's cached or not. This means that when I create a new object, it's immediately stored in the cache for each retrieval, and if I assign that object to a parent, it's stored with that parent in the cache, even before it gets saved. My initial reaction to this was that it was bad behavior, but after ruminating over the possibilities, I changed my mind entirely. Being able to store complete transfer objects in cache by default would make it easy to do things like multi-page forms or shopping cart and order entry systems without needing to deal with the caching mechanism for it myself (such as putting an object in session). The only issue is that if you do this, other parts of the application that can also see that object see non-saved data before you're ready for them to. That's alright if each user has their own unique &quot;thing&quot; that they're dealing with, but it's a big problem if people are sharing objects and data shouldn't be shared until it's validated and saved. So What's my Problem I have a Group object, which contains multiple Items. In my application, as part of the process of adding a new Item to a Group, I'm creating an empty Item object, and then assigning it to the right Group before I do anything else. The View then gets this object and the user can manipulate the empty and unsaved object. When the user clicks the Add button, the Item object is validated and then saved to the database if there are no errors. Here's the relevant bit of code that handles this: &amp;lt;cffunction name=&quot;addItem&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&amp;gt; 	&amp;lt;cfargument name=&quot;Event&quot; type=&quot;coldbox.system.beans.requestContext&quot;&amp;gt; 	&amp;lt;cfset var rc = Event.getCollection() /&amp;gt; 	&amp;lt;cfset var LOCAL = StructNew() /&amp;gt; 	&amp;lt;!--- Pass the group ID in in order to assign the item to the proper group ---&amp;gt; 	&amp;lt;cfset rc.Item = variables.objectFactory.getBean(&quot;ItemService&quot;).getItem( 			rc.GroupID 			, 0) /&amp;gt; 	&amp;lt;!--- Even if a blank object came back, be sure to set the group ID correctly ---&amp;gt; 	&amp;lt;cfset rc.Item.setParentGroup( 			variables.objectFactory.getBean(&quot;GroupService&quot;).getGroup( 				Session.UserID, rc.GroupID)) /&amp;gt; 	&amp;lt;cfset rc.Success = False /&amp;gt; 	&amp;lt;cfif IsDefined(&quot;rc.do&quot;) AND rc.do EQ &quot;additem&quot;&amp;gt; 		&amp;lt;cfset LOCAL.errors = ArrayNew(1) /&amp;gt; 		&amp;lt;!--- Populate User with data ---&amp;gt; 		&amp;lt;cfset getPlugin(&quot;beanFactory&quot;).populateBean(rc.Item) /&amp;gt; 		&amp;lt;cfset LOCAL.result = variables.objectFactory.getBean(&quot;ItemService&quot;).save(rc.Item) /&amp;gt; 		&amp;lt;cfif LOCAL.result.results&amp;gt; 			&amp;lt;cfset getPlugin(&quot;messagebox&quot;).setMessage( 					type=&quot;info&quot; 					, message=&quot;Item Added!&quot;) /&amp;gt; 			&amp;lt;cfset rc.Success = True /&amp;gt; 		&amp;lt;cfelse&amp;gt; 			&amp;lt;cfset getPlugin(&quot;messagebox&quot;).setMessage( 					type=&quot;error&quot; 					, message= ArrayToList(LOCAL.result.errors, &quot;&amp;lt;br /&amp;gt;&quot;)) /&amp;gt; 		&amp;lt;/cfif&amp;gt; 	&amp;lt;/cfif&amp;gt; 	&amp;lt;cfset Event.setView(&quot;ajax/additem&quot;) /&amp;gt; &amp;lt;/cffunction&amp;gt; When I go to my ItemService, grab an Item, and then set it's Parent Group using the setParentGroup method, Transfer updates the Group object in the cache with the new (non-saved) Item. If an error occurs later in the flow during my ItemService.Save method, then the item still stays in the cache, and I end up with an empty Item for every new Item that doesn't pass validation Cloning to the Rescue So to fix this problem we can use a clone of an object to do our manipulations before we save it into the database. According to the Transfer ORM documentation, the Clone() method on an object allows you to &quot;... to make a deep clone of every generated TransferObject ...&quot;. This newly cloned object is &quot;... outside of any caching that is currently in use within Transfer, which means that any changes that are done to this object, and are not saved, are only particular to the request that they are currently in.&quot; In addition to that, the really slick part is &quot;...that Transfer.save() and Transfer.update() on a clone object will update the object currently in cache to the state of the saved object.&quot; Exactly what I need... So with that information in hand, I changed just two lines of code, and the problem was fixed: &amp;lt;!--- Pass the group ID in in order to assign the item to the proper group ---&amp;gt; &amp;lt;cfset rc.Item = variables.objectFactory.getBean(&quot;ItemService&quot;).getItem( 		rc.GroupID 		, 0).Clone() /&amp;gt; &amp;lt;!--- Even if a blank object came back, be sure to set the group ID correctly ---&amp;gt; &amp;lt;cfset rc.Item.setParentGroup( 		variables.objectFactory.getBean(&quot;GroupService&quot;).getGroup( 			Session.UserID, rc.GroupID).Clone()) /&amp;gt; You should notice that I chained a Clone() method onto each of the getXXX methods in my services. This means that I get a deep copy of each to perform my operations. So when an error happens, it's happening to the objects in the current request, and not on the objects in the cache. As soon as I call the Service.Save method, validate the object, and then call he Transfer.Save method, all of the cache'd objects get magically updated for me so that they're available through the entire application. And that's it... So the rule of thumb is, if you don't want your objects updated into the cache until they're saved, always use a Clone'd copy of them. </description>
		</item>

		<item>
			<pubDate>Sun, 20 Jul 2008 09:34:22 PST</pubDate>
			<title>Dealing with Stamp and StampUpdated with Transfer</title> 
			<link>http://www.dansshorts.com/?day=7/20/2008#blog367</link> 
			<description>Continuing work on my top secret app and learning CCT (ColdBox, ColdSpring, and Transfer), I'm going to describe how to handle stamp and stampupdated columns in your tables. In every table that I have in any database I build, I have both a stamp and stampupdated column. The stamp column tells me when the record was originally created, and the stampupdated column tells me the last time that data changed. Both of these columns have a default value of getDate(). Here's the colum definition for an example table: CREATE TABLE [dbo].MyTable( 	[ID] [int] IDENTITY(1,1) NOT NULL, 	[Label] [varchar](50) NOT NULL, 	[stamp] [datetime] NOT NULL CONSTRAINT [DF_Items_stamp]  DEFAULT (getdate()), 	[stampupdated] [datetime] NOT NULL CONSTRAINT [DF_Items_stampupdated]  DEFAULT (getdate()), This works great on initial insert, but doesn't update the stampupdated column on each UPDATE. So to handle making sure the stampupdated gets taken care of properly I create a trigger on each table like so: CREATE TRIGGER [dbo].[MyTable_Update] ON  [dbo].[MyTable] AFTER UPDATE AS BEGIN 	-- SET NOCOUNT ON added to prevent extra result sets from 	-- interfering with SELECT statements. 	SET NOCOUNT ON; -- Insert statements for trigger here 	UPDATE MyTable 	SET stampupdated = getDate() 	FROM Inserted 	WHERE MyTable.ID = Inserted.ID END Now to handle these properly in Transfer, I can't have transfer updating and inserted those values, because the database is responsible for those actions. So let's take a look at what would be the standard property tags for those two columns: &amp;lt;property name=&quot;stamp&quot; type=&quot;date&quot; column=&quot;stamp&quot; /&amp;gt; &amp;lt;property name=&quot;stampupdated&quot; type=&quot;date&quot; column=&quot;stampupdated&quot; /&amp;gt; So with the above property tags, when I save a transfer object it's going to run either an INSERT or an UPDATE statement that will change the stamp and stampupdated columns. But since the database is responsible for this data, that means that 1) Transfer is doing unnecessary and potentially incorrect work and 2) That the values that the database creates won't get back to the Transfer object. To fix that we need to add a few additional attributes to each of these property tags. &amp;lt;property name=&quot;stamp&quot; type=&quot;date&quot; column=&quot;stamp&quot; 	ignore-insert=&quot;true&quot; refresh-insert=&quot;true&quot; 	ignore-update=&quot;true&quot; /&amp;gt; &amp;lt;property name=&quot;stampupdated&quot; type=&quot;date&quot; column=&quot;stampupdated&quot; 	ignore-insert=&quot;true&quot; refresh-insert=&quot;true&quot; 	ignore-update=&quot;true&quot; refresh-update=&quot;true&quot; /&amp;gt; I've now told Transfer to ignore the stamp for the purposes of INSERTs and UPDATEs, and to update the Transfer value when a new record is inserted. I don't need to refresh the value on UPDATE, as the stamp value should never change. On the stampupdated column however, I'm ignoring the value for both INSERTs and UPDATEs, and I'm also refreshing the value on both. This means that on an update the workflow of the UPDATE works something like this: Call Transfer save method Record is UPDATEd in the database On UPDATE trigger fires and updates stampupdated column to the current date Transfer queries the update record, picks up the new stampupdated column, and updates the stampupdated property of the object to the new value Transfer gives me back a fresh object with the new values So that's how I handle all of my stamp and stampupdated columns in my database. You can find out more about the Transfer config options at the Transfer ORM docs site. </description>
		</item>

		<item>
			<pubDate>Sat, 19 Jul 2008 11:15:17 PST</pubDate>
			<title>Creating Snippets in Eclipse</title> 
			<link>http://www.dansshorts.com/?day=7/19/2008#blog366</link> 
			<description>As I'm working with ColdBox, I was reminded just how handy snippets and trigger text can be. ColdBox has a metric ton of snippets available for CFEclipse, most of them with trigger text all ready to go. So I wanted to take a moment to go through how you can create your own snippets and trigger text to speed up common operations When to use snippets Sometimes it's just not worth writing a snippet. I could go nuts and create one for every CF function, but in the end I'd spend more time trying to remember my trigger text than I would coding. So building a snippet for a &amp;lt;cfset&amp;cfgt; probably isn't worth your time, but building a snippet for a multi-line piece of code that you write constantly can save you a ton of time. Take the following code as an example: &amp;lt;tr&amp;gt; 	&amp;lt;th&amp;gt;&amp;lt;label for=&quot;MyID&quot;&amp;gt;Form Label: &amp;lt;/label&amp;gt;&amp;lt;/th&amp;gt; 	&amp;lt;td&amp;gt;&amp;lt;cfinput 		type=&quot;text&quot; 		name=&quot;MyName&quot; 		id=&quot;MyID&quot; 		value=&quot;#MyObject.getMyName()#&quot; /&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; That's a common piece of code to drop into a form for saving an object back to the database, and entering those lines over and over again for each and every property of the object is both time-consuming and error-prone. The perfect job for a snippet. Retooling the Code Before actually opening the Snippets view and starting to add a new snippet, I usually take the code I want to create as a snippet, and rework it directly in CFEclipse before copy/pasting it into the Snippet view. The New Snippet dialog is cramped and hard to work in, so this makes the process a little smoother. Here's what my code looks like after refactoring it for use as a Snippet: &amp;lt;tr&amp;gt; 	&amp;lt;th&amp;gt;&amp;lt;label for=&quot;$${ID}&quot;&amp;gt;$${Label}: &amp;lt;/label&amp;gt;&amp;lt;/th&amp;gt; 	&amp;lt;td&amp;gt;&amp;lt;cfinput 		type=&quot;$${Type:text|hidden|password|radio|checkbox}&quot; 		name=&quot;$${Name}&quot; 		id=&quot;$${ID}&quot; 		value=&quot;$${Value}&quot; /&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; Notice that I've replaced each of the changeable values of my original code to a Snippet variable. Replace name=&quot;MyName&quot; with name=&quot;$${Name}&quot; will cause Eclipse to display a dialog for me to fill in the blanks when I insert the snippet. Also, the type Snippet variable is followed by a pipe separate list of prefilled values that I can choose from when I insert this snippet, making it even less error prone and fast. Creating the Snippet Now that I have my code ready to go, I can create my snippet. The first thing to do is to make sure you have the Snip Tree View panel available to you in Eclipse. You can enable this view by choose Window &amp;gt; Show View &amp;gt; Other, and then choosing Snip Tree View from the CFML category. After that's complete you should see your Snip Tree View and you can drag it wherever you'd like within the interface. To keep things organized you click click the box looking icon (Create a new snip package) in the toolbar for the panel to create new folders. I'm going to create a Layout folder and then a Forms folder to hold my new snippet. After creating the new folders, select the Forms folder and click the Plus icon to create a new Snippet. You can see there's a lot of information here to work with: Snippet Name: this will display in the Snippets panel so you can easily find your newly created workflow enhancer Trigger Text: the Trigger Text value is a short value that you can use in Eclipse to quickly add the snippet using a shortcut key. I'll cover that at the end. Snippet Description: A description of just what this snippet does. Snippet start block: If your snippet is designed to wrap around something, this is what would go before the selection in the Eclipse editor window. If your snippet isn't design to wrap around something, this is where you'll put the full text of your snippet. Snippet closing block: The closing block of your snippet, if it has one. Use this snippet as a file template: You can actually create entire files from a single snippet. I've been using these to create my base Gateways and Service objects so that I don't have to type as much, and I never forget the code that every single one of them needs. Template extension: If you're going to create a file template, this is the file extension it'll get So now that we know all of that information. This is what my newly created snippet is going to look like with the dialog completed: Using the Snippet There are two ways to use snippets. The first is by simply finding it in the Snip Tree view and double clicking the snippet. This is how you'll have to do use if you have a snippet that has a start and closing block and you want it to wrap around your current selection. The second way is to use the trigger text (my preferred method). To use snippet trigger text, simply type the trigger text (in our case inprow) into the Eclipse editor, and with the cursor at the end of the trigger text, press Ctrl/Cmd + J to activate the snippet. Now you should see the snippet dialog with fields for each of the variables you declared: Now just complete the form and click OK and you have all of your code complete and ready to go: Hopefully this little tutorial helps you become more efficient with Eclipse. Happy coding! </description>
		</item>

		<item>
			<pubDate>Sat, 19 Jul 2008 10:29:25 PST</pubDate>
			<title>Getting Moving Again...</title> 
			<link>http://www.dansshorts.com/?day=7/19/2008#blog365</link> 
			<description>Things have been rough on the work front lately, but I'm starting to finally move forward again. It's been about 6 months since I've actually built anything worth mentioning, and I'm finally starting to get back into it :) So today I'm working on a top secret app using ColdBox, ColdSpring, and Transfer, the super trifecta of ColdFusion development (that's my own personal opinion, your mileage may vary) and I'm starting to get the hang of it. I'm doing all of this development locally on my Mac using a VMWare installation of Windows Server 2003 and SQL Server 2005 with Eclipse as my development IDE of choice. As I move forward, I'm hoping to have the time to post some of my thoughts here on how it all fits together. I've done lots of OO programming over the last two years, but nothing quite like the &quot;pure&quot; MVC that ColdBox and the rest of the frameworks work within. I've generally developed with a View and a Model, but never with the controller in the middle. The new app I'm working on will have external non-CF clients that will need access to the model and a completely different set of views, so I think this is really going to take my development skills to the next level. So as I move forward, my sincere thanks (already) to Luis Majano and Mark Mandel for all the work they do in both building and supporting their frameworks. </description>
		</item>

		<item>
			<pubDate>Thu, 01 Nov 2007 17:39:12 PST</pubDate>
			<title>I'm a Godfather</title> 
			<link>http://www.dansshorts.com/?day=11/1/2007#blog362</link> 
			<description>My girlfriend's ex-husband's girlfriend had a brand spankin' new baby today at 6:31. Isabella Johanna Buraglia is 8 pounds, 5 ounces, and 19 1/2 inches long. I'll be booking our trip to The Springer Show soon :). </description>
		</item>

		<item>
			<pubDate>Tue, 09 Jan 2007 06:27:53 PST</pubDate>
			<title>THE BLINK TAG SURVIVES!!!</title> 
			<link>http://www.dansshorts.com/?day=1/9/2007#blog361</link> 
			<description>BOOYAH! </description>
		</item>

		<item>
			<pubDate>Thu, 04 Jan 2007 13:40:15 PST</pubDate>
			<title>&quot;Not of type numeric&quot; when it damn well is....</title> 
			<link>http://www.dansshorts.com/?day=1/4/2007#blog360</link> 
			<description>I have a problem, and it's ColdFusion... We're working on some complex object interaction, and moving data in and out of our objects. Part of the &quot;moving in&quot; part involves building out a structure of arguments based on query columns, and then passing them all in via the ArgumentCollection. Unfortunately, ColdFusion doesn't love us here at lynda.com... It's pitching a fit and saying that our IDs aren't of type numeric, when I know damn well that they are (grumble grumble)... To demonstrate my point I've come up with the following code example. This fails every time for me: &amp;lt;!--- Get a query ---&amp;lt;&amp;gt; &amp;lt;cfset rs = QueryNew(&quot;ID,FirstName&quot;, &quot;integer,varchar&quot;) /&amp;lt;&amp;gt; &amp;lt;cfset QueryAddRow(rs) /&amp;lt;&amp;gt; &amp;lt;cfset QuerySetCell(rs, &quot;ID&quot;, 3) /&amp;lt;&amp;gt; &amp;lt;cfset QuerySetCell(rs, &quot;FirstName&quot;, &quot;Daniel&quot;) /&amp;lt;&amp;gt; &amp;lt;cfset TestStruct = StructNew() /&amp;lt;&amp;gt; &amp;lt;cfloop list=&quot;#rs.ColumnList#&quot; index=&quot;col&quot;&amp;lt;&amp;gt; 	&amp;lt;cfset TestStruct[col] = rs[col] /&amp;lt;&amp;gt; &amp;lt;/cfloop&amp;lt;&amp;gt; &amp;lt;cfdump var=&quot;#TestStruct#&quot; /&amp;lt;&amp;gt; &amp;lt;!--- Pass the newly created struct into the object to run each setter ---&amp;lt;&amp;gt; &amp;lt;cfset MyObject = CreateObject(&quot;component&quot;, &quot;cfcs.test&quot;).init(ArgumentCollection = TestStruct) /&amp;lt;&amp;gt; &amp;lt;cfdump var=&quot;#MyObject.getSnapShot()#&quot; /&amp;lt;&amp;gt; That generates the following error: The argument ID passed to function init() is not of type numeric. Has anyone else come across this same error? Is there some hotfix that fixes this? It's completely stymied our development... The only way around it is to set our arguments to accept type=&quot;any&quot;, which honestly is unacceptable... </description>
		</item>

		<item>
			<pubDate>Sun, 29 Oct 2006 19:26:57 PST</pubDate>
			<title>Ant, Eclipse, and FTP</title> 
			<link>http://www.dansshorts.com/?day=10/29/2006#blog359</link> 
			<description>I'm having an absolute bear of a time getting Eclipse to play nicely with Subversion, Eclipse, and an Ant build file. One of the wonderful things about working with Dreamweaver is the great FTP integration. I can upload, download, all that wonderful stuff, with a single keyboard shortcut directly in the IDE. I'm not having any such luck with Eclipse. I think the problem is that I'm not only needing FTP access, I also need Subversion/Subclipse integration. It's my understanding that I can &quot;import&quot; from an FTP site and I forever have a connection through the Team plugins. Unfortunately, I need to &quot;import&quot; from a Subversion repository in order to keep things up to date that way. This makes it damn impossible to use any sort of built in FTP integration inside Eclipse. To try and get around this I've been playing with Ant (thanks Jared) and build.xml files. The hope is that I can create an Autobuild file that will upload a file any time it's created or changed (I'm not ambitious enough yet to tackle file deletions, bear with me here). Unfortunately, the only thing I've (that means Jared) been able to find is the &quot;depends&quot; attribute of the &amp;lt;target&amp;gt; tag. Unfortunately, this also doesn't seem to work worth a damn... It always uploads the entire project any time a single file changes. The depends attribute isn't checking to see whether anything is newer or not. The most frustrating part of all of this is trying to find good documentation on complex processes. I've spent several hours on google digging through blog posts, forums, Ant documentation and trying to download jar files, write build scripts, and rebuild workspaces, and nothing seems to work as you'd expect. It seems you need to have a greybeard Java developer looking over your shoulder in order to use Ant, or make it do anything you really want it to. Can someone prove me wrong, and help me figure out how I can make Eclipse just upload a file when I save it? Is that so much to ask? Please??? </description>
		</item>
	</channel>
</rss>
