Entries Tagged as 'CFML'

Announcing tableSnapshots: A ColdFusion Tool For Preserving and Reverting Database Table Data

CFML , ColdFusion 2 Comments »

Several months ago, I was doing some functional testing on a web application that was taking forever.  Each run of the test resulted in changes to the data in several tables, and in order to reset the test I had to go into the tables and undo the changes.  It occurred to me that it would be nice to have a tool or script that could preserve the current table data and then later write that version of the data back to the tables.

That marked the beginning of the tableSnapshots tool.

Read more...

Quick Tip: Avoid Joining Query of Queries (QofQs) Within Loops

CFML , ColdFusion 3 Comments »

Every ColdFusion developer who spends a lot of time working with queries knows that if you have to run a unique query for every iteration of a loop, you should (whenever possible) use a <cfquery> to acquire the entire set of records prior to the loop and then query against that recordset using a Query of Queries (QofQ):

<cfquery name="qryMain" datasource="myDatabase">
    select a.field1, a.field2, b.field7 ...
    from table1 a, table2 b
    where a.field1= b.field2
</cfquery>

<cfloop index="j" from="1" to="1000">
    ....
    <cfset calculatedVal= thisVal + thatVal />
    
    <cfquery name="qrySub" dbtype="query">
        select field2, field7 ...
        from qryMain
        where field1= <cfqueryparam value="#calculatedVal#" cfsqltype="cf_sql_numeric" />
    </cfquery>
    ...
</cfloop>

...That way, you're querying the recordset in memory 1,000 times instead of making 1,000 calls to the database.

Yesterday I was asked to look at an old report that wasn't performing well anymore now that the database tables being queried had grown much larger. While it was designed to use QofQ data within the loop, the QofQ in the loop was doing a join between two recordsets stored in memory:

<cfquery name="dbQry1" datasource="myDatabase">
    select a.field1, a.field2, a.field3, b.field4, b.field5
    from table1 a, table2 b
    where a.field1= b.field2
    ...
</cfquery>

<cfquery name="dbQry2" datasource="myDatabase">
    select c.field1, c.field6, d.field9
    from table3 c, table4 d
    where c.field1= d.field3
    ...
</cfquery>

<cfloop index="j" from="1" to="1000">
    ....
    <cfset calculatedVal= thisVal + thatVal />
    
    <cfquery name="qrySub" dbtype="query">
        select dbQry1.field2, dbQry1.field3, dbQry2.field6, dbQry2.field9
        from dbQry1, dbQry2
        where dbQry1.field1= dbQry2.field1
        and dbQry.field2 > <cfqueryparam value="#calculatedVal#" cfsqltype="cf_sql_numeric" />
        ...
    </cfquery>
    ...
</cfloop>

I discovered that if I created a third QofQ that took care of the join outside of the loop, and queried that new recordset within the loop, the per-iteration performance improved dramatically:

<cfquery name="dbQry1" datasource="myDatabase">
    select a.field1, a.field2, a.field3, b.field4, b.field5
    from table1 a, table2 b
    where a.field1= b.field2
    ...
</cfquery>

<cfquery name="dbQry2" datasource="myDatabase">
    select c.field1, c.field6, d.field9
    from table3 c, table4 d
    where c.field1= d.field3
    ...
</cfquery>

<cfquery name="qryMasterSub" dbtype="query">
    select dbQry1.field2, dbQry1.field3, dbQry2.field6, dbQry2.field9
    from dbQry1, dbQry2
    where dbQry1.field1= dbQry2.field1
</cfquery>


<cfloop index="j" from="1" to="1000">
    ....
    <cfset calculatedVal= thisVal + thatVal />
    
    <cfquery name="qrySub" dbtype="query">
        select field2, field3, field6, field9
        from qryMasterSub
        where field2 > <cfqueryparam value="#calculatedVal#" cfsqltype="cf_sql_numeric" />
        ...
    </cfquery>
    ...
</cfloop>

It makes sense when you think about it, but I had just never considered that join operations would affect QofQs so drastically.

Zen Coding: A Faster Way to Write HTML And Tag-Based CFML in CFBuilder/CFEclipse

CFML , ColdFusion Builder , Miscellaneous , Web development 3 Comments »

Zen Coding, in a nutshell, is a kind of coding shorthand primarily used to output HTML or XML code.  For example, the following line of Zen Coding:

div#page>ul>li*2>img.itemImg+a

...will produce this:

<div id="page">
<ul>
<li><img src="" alt="" class="itemImg" /><a href=""></a></li>
<li><img src="" alt="" class="itemImg" /><a href=""></a></li>
</ul>
</div>

If you compare the Zen Code to its output, you can see what the different parts of the Zen Code statement do. Assuming you know how you want to structure your HTML code, it's a pretty quick and easy way to generate the code you want with very little typing.

Having been recently reminded about Zen Coding, I decided to try out the latest version of the Zen Coding for Eclipse plugin and see if it would work in ColdFusion Builder 2.

The short answer: it does (and I imagine it works in CFEclipse as well). Once the plugin is installed, you can open your .cfm files in the regular editor window and use Zen Coding statements.

But then I discovered something I didn't expect: the Zen Coding plugin will convert even element names it doesn't recognize into matching start and end tags. In other words, even though it's not designed to be used with CFML tags, it can output them. Combine that fact with Zen Coding's support for adding attributes, and you can enter this line:

ul>cfloop[index=s][from=1][to=#ListLen(stateList)#]>li

...and hit the Tab key to get this:

<ul>
<cfloop index="s" from="1" to="#ListLen(stateList)#">
<li></li>
</cfloop>
</ul>

...Maybe not the best real-world example, but it demonstrates the possibilities.  And the plugin lets you define your own shorthand abbreviations, so instead of typing "cfoutput[query]" to get "<cfoutput query=''>", you could define an abbreviation like "cfoutq" that will generate the same code.

I think this could be a cool way to write display code, and I'm looking forward to trying it out in real coding situations.

Update:  I totally overlooked the link on the Github page to the documentation for the current Zen Coding syntax:  http://code.google.com/p/zen-coding/wiki/ZenHTMLSelectorsEn

CFSelenium Now Compatible With ColdFusion 7 and 8

CFML , ColdFusion , Selenium No Comments »

A few weeks ago, Bob Silverberg released his latest open-source project, CFSelenium.  For those who don't know about the project, a little background:  Selenium is a tool suite for testing web pages.  The most well-known member of the Selenium product family is Selenium IDE, a Firefox plugin that lets you record the actions performed on a web page (or a series of connected web pages) and the results of those actions.  You can then use the recording (stored as a series of commands) to redo those steps whenever you need to test the page or pages after making changes.  Another member of the Selenium product family is Selenium Server (formerly called Selenium-RC), which is a small, Java-based server that can run scripts comprised of Selenium commands in multiple browsers, allowing you to conduct the same kinds of tests recorded by Selenium IDE in browsers other than Firefox:  a great way to test web page functionality across multiple browsers.

In creating CFSelenium, Bob made it possible (easy, in fact) to create and run Selenium Server scripts using ColdFusion 9, and created a plugin for Selenium IDE that would output the recording statements in CFSelenium format within MXUnit test case functions.

Bob wrote CFSelenium in ColdFusion 9-compatible cfscript, and after he announced the project a few folks inquired about the possibility of having a version written in tag-based CFML.  On somewhat of a whim, I decided to take on that task, and ended up with a tag-based version of Bob's original selenium.cfc file that is compatible with both ColdFusion 7 and ColdFusion 8, as well as a few test files that run against the tag-based version.

Bob has now incorporated my tag-based version and my test files into the CFSelenium project, and we've agreed that I will maintain the tag-based version while he maintains the CF9 script verison.  You can download CFSelenium from either RIAForge (http://cfselenium.riaforge.org/) or from GitHub (https://github.com/bobsilverberg/CFSelenium).  For more about Selenium in general, I'd suggest reading Bob's blog post announcing CFSelenium as well as the Selenium website.

So if you're a developer whose responsibilities include cross-browser testing of your web pages, you should really check out CFSelenium.

When TimeFormat() Can't Quite Give You What You Need

CFML , ColdFusion 6 Comments »

So today I got a call from one of my clients.  The app we built for her is an event management app, and one of its functions outputs a list of all the events, including the start and ending times for each event.  Those times are output using ColdFusion's TimeFormat() function like so:

#TimeFormat(event.startTime,"h:mm tt")# - #TImeFormat(event.endTime,"h:mm tt")#

...which (for example) comes out as:

10:00 AM - 1:30 PM

My client was calling because she was told (by the local style enforcer, I guess) that the university's publishing style dictates dropping the ":00" for times that start on the hour and to use "a.m." and "p.m." rather than "AM" or "PM".  She wanted to know if I could adjust the report output to meet the style.

I briefly tried to see if there was a way to change the mask parameters in TimeFormat() to get the desired format, with no luck.  A quick search online for a ready-made solution also didn't yield any results.  So I ended up doing this:

<cfset initialVals= "AM,PM,:00">
<cfset newVals= "a.m.,p.m.,">
...
#ReplaceList(TimeFormat(event.startTime,"h:mm tt"),initialVals,newVals)#
- #ReplaceLIst(TimeFormat(event.endTime,"h:mm tt"),initialVals,newVals)#

That did the trick, but if someone's got another way of handling it, please feel free to share.