This blog is now running BlogCFC 5.5. I upgraded for two reasons. First, I'm working on a redesign of this blog so I figured I might as well be working with the latest and greatest. Second, I wanted to set up a another site so that my wife and I can share our experiences with our new baby girl. I was going to build a small site for this, but the new image features in this release of BlogCFC saved me the effort. (Time seems to be at a premium with a new baby in the house:) Thanks to Ray and everyone else who worked on this release!
So maybe it's because I've been doing a lot of UI work lately, or maybe it is because Jeff Peters and Hal Helms have been talking about user interfaces on their podcast, but for whatever reason I've been taking greater notice of interfaces over the past few weeks. It really interesting just how bad some interfaces can be, and how sometimes, just one feature can really make or break a user experience. Case in point my cable box. Here in Philadelphia I have Comcast. When I first moved into my new house a few months ago and called to set up my service I was really surprised that human answered the phone within about 10 seconds of dialing. I'm most familiar with Time Warner Cable in New York where you usually had to try to talk to a machine for 5 minutes before getting fed up and pressing 0 or screaming "Operator!," only to be put on hold for another 30 minutes before you could finally talk to someone. And once you did get a human on the line they usually sounded like they were doing you the biggest favor in the world by talking to you. So anyway, at this point I though Comcast really had it together. However once I finally got my HD/DVR digital cable box (made by Motorola) and started using it, well that is where the love affair ended. I've actually had to call customer service three times in a little less than three months due to the horrible interface this box has.
I just got around to listening to last week's ColdFusion Weekly Podcast, Version 1.25, The Fusebox 5 Edition. (For some reason I got a week behind on listening to the Weekly a few months ago and still haven't managed to catch up.) All in all I think it was one of the better versions I've heard. I think Sean Corfield gave a rather compendious overview of the history of Fusebox as well as a great description of the goals and new features of Fusebox 5. However, as a long time Fusebox user I was a little surprised by one of the questions asked. Toward the end of the interview Matt Woodward asked if Fusebox could be used to build OO CF applications. The answer of course was yes. What surprised me is that Fusebox has never really prevented users from building OO applications using the framework. Most of the major frameworks use .cfm templates for the view layer, and Fusebox is no exception. (The only framework I can think of right now that uses components for display is FarCry.)
Case in point, I'm currently working on an addition to an existing application. This new feature set is based on a fully OO domain model, managed by ColdSpring, and oh yeah, it uses Fusebox 2 as the controller. That's right, Fusebox 2. If anyone remembers how FB2 works, I instantiate my ColdSpring bean factory in the app_locals.cfm file for the new circuit, make calls to my service components (via ColdSpring) from ACT files and render the display via DSP files. Sure if I had my choice I'd be using a more modern framework but in this case I didn't. Modern frameworks have many conveniences that make OO development easier, and if you are building a new application I certainly recommend using one, but you don't have to use a framework to build OO apps in ColdFusion, and you can certainly use Fusebox if you want to. Anyway, I'm not really sure where Fusebox got the bad rap as it relates to CF and OO but I hope some people are taking a second look at Fusebox with this new release and realizing it can be used for both procedural and OO applications.
My former employer, nextjump inc., is looking for developers. If you are a CF developer and looking for a job in the NYC area drop them a line. (And be sure to let them know you found them through my blog!) Nextjump is a great company with tons of energy and some very smart people. In my time there I learned a lot about not only enterprise software development but also the business of technology. Here is a bit more about the position (from their website):
Associate Developers will work closely with Product Managers to prototype new web-based applications for our clients, in a fast-paced rapid development environment.
- BS in Computer Science, Engineering or equivalent
- 1 - 2+ years experience with web development
- Cold fusion and JSP
- Excellent oral and written communication skills
- Extremely detail oriented
Often times there are several different ways to write a SQL query to return a desired result set. Some times the ordering of JOINs and WHERE predicates or the approach taken in the query (nested queries vs. joins for example) can make a big difference on query performance. You won't really notice a difference on smaller databases, but on queries which search thousands or millions of records you may see a big difference in performance simply by changing the order of where predicates. So the question becomes, when given two or more queries which return the same results, how do you determine which one performs best?
Well if you are using MS SQL Server just copy the queries into the same Query Analyzer window, turn on the Show Execution Plan (Ctrl+K), and run the queries (F5). Once the queries execute go to the Execution Plan tab and note their relative costs. For example if you run two queries you may have results which look something like:
Query 2: Query cost (relative to batch): %40.00
In this case you would want to go with Query 2 as it has the lowest cost relative to the batch.
Another thing I should point out here is that some times you will notice that two seemingly "different" queries have the exact same cost relative to the batch. If you look at the execution plan you may notice that the query optimizer generated the exact same execution plan for these queries. In these cases it may not make much of a difference which query you choose. (This happened a me a couple of weeks ago. I had 4 different versions of a query, each of which was optimized to the same execution plan by SQL Server's optimizer.)
Anyway, I'm sharing this little Query Analyzer tip because I discovered that not a lot of CF developers are aware of this feature, or at least not as many as I though would be. Also, I'm relatively new to SQL Server so feel free to chime in with any other Query Analyzer tips you may have.
First and foremost I needed a tree control, which the YUI has. Actually the library contains several components which Yahoo classifies as either utilities or controls. So far I've been working with the DOM Collection (for DOM scripting) and Connection Manager (for AJAX) utilities as well as the Menu and TreeView controls, but these are just a few of the available components.
Second, Yahoo released the YUI library under the BSD license earlier this year. While I'm no open source licensing expert it's my understanding that the BSD license is one of the more permissive free software licenses, which is great because that means I can use it at work.
One of the things I like about working on a larger team is that there is plenty of opportunity to bounce questions off of co-workers and, as anyone who has ever answered a question on a forum or mailing list can tell you, you often learn as much trying to answer a question as you do by asking one.
This happened to me last week when a co-worker came to me with a question about XSLT. He had an XML document that looked something like the following:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="">
<Person personId="12345" xmlns="http://schemas.mischefamily.com">
He wanted to transform it into:
He had the beginnings of an XSL stylesheet which had the SOAP-ENV namespace declared in the xsl:styleheet root element, but his search sting, "//SOAP-ENV:Body/QueryResults/People", wasn't returning any results. Just looking at the original XML document I knew the problem had something to do with namespaces, but I wasn't quite sure how to handle the namespaces defined in the QueryResults, People, and Person nodes. Turns out that the answer was fairly simple; we just needed to declare another prefixed namespace in the stylesheet root element pointing to http://schemas.mischefamily.com.
<xsl:output method="xml" indent="yes"/>
<People xsl:exclude-result-prefixes="SOAP-ENV MISCHE">
<xsl:for-each select="//SOAP-ENV:Body/MISCHE:QueryResults/MISCHE:People"> <Person>
There were a few things, however, that threw me for a loop while coming up with this stylesheet. First, I originally thought that PersonalData and all the nodes below it were in the local namespace because everything above that node (QueryResults, People, Person) had a xmlns attribute defined. Based on this assumption my first xsl:value-of select statement for the transformed FirstName node looked like "./MISCHE:Person/PersonalData/Contact/StructuredName/GivenName". The problem was this statement didn't return anything. After some quick research I realized this was because the namespace declared in the xmlns attribute is inherited. This meant that all of the elements below the Person element in the source XML were also in the http://schemas.mischefamily.com namespace and needed to be prefixed with MISCHE in the select statements of my stylesheet. As a side note, to make my original query work you would need to force child nodes back into the local namespace, which you can do if you can give the xmlns attribute an empty value like so:
<Person personId="12345" xmlns="http://schemas.mischefamily.com">
The second issue I had was that my original stylesheet was returning the SOAP-ENV and MISCHE namespace declarations in the root node of my result. To suppress the namespaces in my results I had to add the exclude-result-prefixes attribute to the Person element in my XSL stylesheet.
Anyway, these were just some things I though I'd share in case you find yourself trying to transform XML with a different namespaces defined.
I've been using cfqueryparam for some time for both its performance and security benefits, but today I ran into something new with this tag. (I should state that this behavior was observed and confirmed using CFMX 7 and SQL Server 2000.) It all started with a question from a friend about some strange behavior he was seeing with a query which used cfqueryparam. He had added columns to a table, but his query against this table was not returning these new columns. The query in question used a wildcard select with cfqueryparam so it looked something like:
WHERE myTableID = <cfqueryparam value="#x#" cfsqltype="cf_sql_numeric" />
I suspected it had something to do with the caching of the execution plan, which most databases will do if you use bound parameters, and it turns out I was correct. To explain the issue lets say we start with a table with two columns. The first time we run this query in a ColdFusion template the database compiles and caches the execution plan for the query. If you add a column and run the template again the query will still only return our first two columns because the database uses its cached execution plan. Because the query uses the star wildcard and the plan was compiled before the third column was added to the table the cached plan only knows about our first two columns and completely ignores our new third column.
Now there are several ways around this issue. First don't use wildcard select statements. I generally list all the columns I want to return in my select statement, which may explain why I haven't run into this issue before, but I'll admit that there may be times when this just isn't practical. In those situations you can either not use cfqueryparam or use SET FORCEPLAN to force SQL Server to recompile the execution plan like so:
SET FORCEPLAN ON;
WHERE myTableID = <cfqueryparam value="#x#" cfsqltype="cf_sql_numeric" />;
SET FORCEPLAN OFF;
One other thing I didn't realize is that execution plan reuse is tied to the database connection, so if you restart ColdFusion after adding your new column you should get the expected results.
Anyway, just something to watch out for, especially since many of the examples I've seen for using queryparam use SELECT * and don't mention this behavior.
Another quick note on installing the FarCry 3.0.2 RC package. Many of the rule component tags in farcry_core\packages\rules have hint attributes which span multiple lines. For example ruleNews.cfc looks like this:
hint="News rule publishes news content items in date order, with
most recently published first. News content is only visible
if it is a) approved content; b) time is past the publish date;
c) time is before the expriy date, and; d) it matches the nominated
oRules['#qRules.rulename#'].hint = '#REReplace(application.rules[qRules.rulename].hint,"\r\n"," ","ALL")#';
Note that I haven't test the above code but I think it should work.
So after I posted this I went over to the FarCry bug database to log this issue. Apparently this is something I should have done first because it has already been reported and fixed:
The fix uses a the JSStringFormat function, a function I really haven't used all that often. (OK, maybe never.) I'll have to look into exactly what this function does as it sounds like it could come in pretty handy, especailly given all the AJAX stuff I've been doing lately.
For the past month or so I've been running a small intranet site on FarCry. I've been using this site for project notes, basically just posting my ideas and discoveries as standard FarCry news items for my co-workers to review. I plan to expand the site to contain documentation and other content related to the project I'm working on, but for now it's fairly basic.
So the news items are working well to add transparency to my development process, but I really want to get some feedback from my co-workers on some of my ideas. To do this I wanted to allow comments to be added to news items. Sound like a blog? Well it did to me, so I decided to create some basic blog content objects for FarCry.
Note that I built these objects using the 3.0.2 RC of FarCry with the mollio skin. I haven't done much testing so use at your own risk! That said, to install the blog:
- Download the farcry_mollio_blog.zip and unzip it to your project directory.
- Reload your FarCry application by browsing to your FarCry site and adding updateapp=1 to the url parameters
- Login to the FarCry administrator and deploy the four new objects: nmBlogEntry, nmBlogComment, ruleBlogEntries, and ruleBlogComments.
- Add a page to your FarCry site for the blog.
- Add your first blog entry under Content -> Blog.
- Add the nmBlogEntries rule to the bottom container on the blog page.
- View the blog entry and add the nmBlogComments rule to the blogBottom container.
There is still a lot of work I want to do with these objects. For example there is no way to manage comments. In fact there is absolutely no way to know comments have been added without looking at the blog entry. I'd also like to add a calendar view and a category listing. It all depends on how much time I have and how much interest people show in these objects.
If you do decide to give these components a try please let me know how it goes.