James Wood

About James Wood

James is a programmer here at Matrix Group. He is affectionately known around the office as S.P.A.R.T.A.C.U.S. because he is an avid marathon runner. He is also a beer connoisseur. A little known fact about James is that he was a toxicologist before switching professions for a change of pace. His flexibility will prove to be a valuable quality, because he has a beautiful daughter who’s just headed into her tween years.

Random result from query

Recently, I was upgrading some code and we needed to pull a random result from a table. Not thinking about the SQL server version I went ahead and created a query using common table expression (CTE).

It looked like this (the real query has proper column and table names!)

WITH cte AS
(
    SELECT TOP 1 id FROM table ORDER BY NEWID()
)
SELECT
	table.id,
	table.id2,
	table.column1,
	table.column2,
	table.column3,
	table.column4,
	table2.column1
FROM
	cte
INNER JOIN
	table
ON
	table.id = cte.id
INNER JOIN
	table2
ON
	table2.id = table.id2

Super, I thought. It works great on our development server and boy is the code a lot simpler than before.

I moved it live and it didn’t work. We had SQL 2000 on live and CTE wasn’t introduced until 2005…

…So back to the old code. But surely I could improve on the old code and looping through result. Yes, I could :)


<cfquery datasource="datasource" name="qryRange">
	SELECT
		id
	FROM
		table
</cfquery>

<cfset listIds = valueList(qryRange.id) />
<cfset randNum = RandRange(1, listLen(listIds)) />
<cfset selectID = listGetAt(listIds,randNum) />

<cfquery datasource="datasource" name="returnQuery">
	SELECT
		table.id,
		table.id2,
		table.column1,
		table.column2,
		table.column3,
		table.column4,
		table2.column1
	FROM
		table
	INNER JOIN
		table2
	ON
		table2.id = table.id2
	WHERE
		table.id = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#selectID#" />
</cfquery>

The main areas that I improved was that before, it was just using the record count of the number of records returned from the query and getting a random number from 1 to the record count and looping until it go to that ID.

Problems happen if something has been deleted from the table and there isn’t an ID for the random number. Also, it wouldn’t ever select a result if the ID was a number larger than the number of records in the table.

Once we upgrade to a newer SQL I’ll use the better code, but for now this is a vast improvement.

Hope this helps someone.

Responsive page development

Here at Matrix Group, most of the design work we’ve been doing is responsive. Being a developer and not a Front End Developer (FED) or designer, I didn’t really have as much exposure to it.

Recently, I had the opportunity to redo a page where I wanted 3 columns on my wide screen monitor, but knowing that other people have smaller laptop monitors, that would mean some very squished data.

So along came responsive to my rescue.

Because I wanted to learn how this worked, I did some research which helped me out. Here’s how to solve this issue:

Add this line in to the head of the page

&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;

Then in your CSS, assign styles to the appropriate page widths using @media, which acts like an if/else statement.

So for example if your screen size is greater than 768px but less than 1120px you would have the following line
@media only screen and (min-width: 768px) and (max-width: 1120px) {
/*You would put in your styles here*/
}

You can put any style in including only showing certain things like a “close” link so that you can collapse a div.

For a super simple example take the following code and play around with it. I put inline styles so that you can just see the outline of the divs.

Have fun :)

Responsive.htm

&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;

&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Responsive Page&lt;/title&gt;
	&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
	&lt;link href=&quot;responsiveStyles.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
&lt;/head&gt;

&lt;body&gt;

&lt;div id=&quot;container&quot;&gt;
	&lt;div id=&quot;leftContent&quot; style=&quot;border: solid 1px #000; height:300px; margin-right:5px;&quot;&gt;
		&lt;div id=&quot;closeLeftDivLink&quot; style=&quot;float:right;&quot;&gt;Close&lt;/div&gt;
		This is the left content
	&lt;/div&gt;

	&lt;div id=&quot;middleContent&quot; style=&quot;border: solid 1px #c0c0c0; height:200px; margin-right:5px;&quot;&gt;
		&lt;div id=&quot;closeMiddleDivLink&quot; style=&quot;float:right;&quot;&gt;Close&lt;/div&gt;
		This is the middle content
	&lt;/div&gt;

	&lt;div id=&quot;rightContent&quot; style=&quot;border: solid 1px #cc0000; height:200px; margin-right:5px;&quot;&gt;
		This is the right content
	&lt;/div&gt;
&lt;/div&gt;

&lt;div style=&quot;clear:both;&quot;&gt;

&lt;/body&gt;
&lt;/html&gt;

responsiveStyles.css


/* anything larger than 1120 */
#leftContent {
float:left;
width:30%;
}

#middleContent {
width:40%;
float:left;
}

#rightContent {
width:28%;
float:left;
}
#closeLeftDivLink {display:none;}
#closeMiddleDivLink {display:none;}

/* if your widow display width is between 768px and 1120px */
@media only screen and (min-width: 768px) and (max-width: 1120px) {
#leftContent {
float:left;
width:35%;
}

#middleContent {
float:right;
width:62%;
margin-bottom:20px;
}

#rightContent {
float:right;
width:62%;
}
#closeLeftDivLink {display:none;}
#closeMiddleDivLink {display:block;}
}

/* if your widow display width is between 480px and 767px */
@media only screen and (min-width: 480px) and (max-width: 767px) {
#leftContent {
float:none;
width:auto;
margin-bottom:20px;
}

#middleContent {
float:none;
width:auto;
margin-bottom:20px;
}

#rightContent {
float:none;
width:auto;
}
#closeLeftDivLink {display:block;}
#closeMiddleDivLink {display:block;}
}

/* if your widow display width is less than 479px */
@media only screen and (max-width: 479px) {
#leftContent {
float:none;
width:auto;
}

#middleContent {
float:none;
width:auto;
}

#rightContent {
float:none;
width:auto;
}
#closeLeftDivLink {display:block;}
#closeMiddleDivLink {display:block;}
}

ColdFusion 9 and ajax calls

I’ve been using ajax and ColdFusion for a long time with great success. Just
recently, I have been working on a new site that is on CF9; I know I’m behind
the times!

For years now (at least it seems that long) I’ve simply been passing my
variables from JavaScript to my cfc’s without any alterations.

I set my cfajaxproxy, define the cfc and give it a jsclassname, e.g.

    <cfajaxproxy cfc="ajax.ajaxFile" jsclassname="ajaxJSClassName">

On my js page I instantiate the class:

    var myAjaxJSClassName = new ajaxJSClassName();

And call the function in the cfc something like this:

$(document).ready(function(){
    $(".className").click(function(){
        curElem = $(this);
        curID = $(curElem).attr('id');
        results = myAjaxJSClassName.cfcFunctionName(curID);
    });
});

Fine. Not a problem. All works wonderfully.

If you opened firebug you can see the params of the ajax call and there
would be something like: argumentCollection{“variable1″:”12345″,”variable2″:”67890”}

I moved the exact code over to a CF9 site and I kept getting “WDDX packet
parse error at line 1, column 1. Content is not allowed in prolog..”

I tried so many things it was unreal. Stripped things down to the bare
bones. Updated JQuery. Took it out of JQuery. You name it, I probably tried
it.

So, back to the trusty firebug and I see that in the params the
argumentCollection was “51838EEB9C” no matter what I passed. I searched and
searched and couldn’t find anything related to this.

So, I’m now on the verge of removing the ajax functionality when I happen
across Raymond Camden’s site. It’s not exactly what I’m experiencing, but
it’s close enough!

So I change up my JavaScript to be:

$(document).ready(function(){
    $(".className").click(function(){
        curElem = $(this);
        curID = $(curElem).attr('id');
        var mydata = {data:[curID ]};
        $.post("/ajax/ajaxFile.cfc",
        {method:"cfcFunctionName",argumentCollection:$.toJSON(mydata),
        returnFormat:"plain"}, function(res) {
        })
    });
});

And wouldn’t you know – everything works fine now.

I’d like to know exactly why it wasn’t working in CF9. I presume that it has
something to do with converting the data to JSON, but try as I might to
convert it and put it back into my old code, I just can’t get it to work.

I’m sure that there are some smarter people out there than I that may well
be able to help me out. In the mean time any one else having such issues,
try not to bang your head against the wall for too long and embrace JQuery
even more. :)

UPDATE – 4/12/2013
So after another bout of hair pulling I came across some other articles.
Another Raymond Camden and also something from Andy Scott. The most helpful was the comments from the Raymond Camden article about caching of the scripts folder in the CFIDE folder.

I did a lot of things so I’m afraid I’m not completely sure which fixed it. But in the end I had a different copy of the cfide/scripts/ folder called scripts_901, and I changed Default ScriptSrc Directory in CF admin under settings. This seemed to resolve the issue. I then subsequently changed the name of the old scripts folder, and renamed the script_901 to be scripts, updated CF admin again so that everything looks like it was originally.

I hope this helps.

Sandbox Security in ColdFusion 8

There are certain tags that by default are enabled in ColdFusion that I am never going to use and are a security risk. With this in mind I wanted to disable these CF Tags in a ColdFusion enterprise environment.

We have done this before in the ColdFusion standard edition and it is quite straight black keysforward. So I went ahead and enabled Sandbox Security in a specific CF instance. One of the differences in the Enterprise edition is that you can specify specific directories to define specific permissions. So you can have different permissions on different instances.

I added the directory of the site that I wanted to disable cfexecute and then disabled the cfexecute tag. I was prompted to restart the CF instance and then went to my site. I got an error. I went to CF administrator to change the settings back and it wouldn’t respond! What the…?

Having played around with the guts of ColdFusion and its settings, I knew that I could revert the Sandbox Security by changing the xml file. That file is called neo-security.xml in the \WEB-INF\cfusion\lib folder of the instance that I was updating.

So, what next?

Continue reading

ColdFusion Lists

Lists. We all use them. We make lists before we go to the grocery store, we plan out our days or lay out our favorite movies.

In programming, I use lists a lot for many reasons. Sometimes I have multiple lists and want to compare them and see what’s in between:

  • Does one list contains all the items in another list?
  • Are the lists the same?
  • Show me any elements from one list that exist in another list.
  • Show me any elements from the first list that do not exist in the second.
  • De-duplicating a list.

As we all know ColdFusion is built on top of Java. And because of that we can use the underlying Java methods. Ben Forta wrote a great article on using the underlying Java methods, so I’m not going to go into details here.

I just want to concentrate on lists and how we, as programmers, can use some methods that are not readily documented:

Lets take 2 simple lists.
<cfscript>
	list1 = "1,2,3,4,5,6,7,8,9";
	list2 = "2,4,6,8";
</cfscript>

We shall run these lists through a series of actions that one may find useful
For the Java methods that I shall be using here, we need to out the lists into an array. So lets just do that first and use the same array throughout

<cfscript>
	arraylist1 = ListToArray(list1);
	arraylist2 = ListToArray(list2);
</cfscript>

1. Does 1 list contains all the items in another list?
Using the Java method of containsAll this question is very easy.


<cfoutput>
	Does list1 contain all in list2: #arraylist1.containsAll(arraylist2)#
</cfoutput>

2. Are the lists the same?
This time we shall use the Java method of equals.

<cfoutput>
	Does list1 equal list2: #arraylist1.containsAll(arraylist2)#
</cfoutput>

3. Show me any elements from 1 list that exist in another list.
For me this is where things get a lot more useful. We shall use the Java method of retainAll.

<!--- Create a deep copy of the first list to keep it intact. --->
<cfset variables.finalList = duplicate(arraylist1)>
<!--- Retain any elements from the first list that do exist in the second. --->
<cfset variables.finalList.retainAll(arraylist2)>
<cfset variables.finalList = arrayToList(variables.finalList)>

<cfoutput>
	Final List: #variables.finalList#<br>
	Number of IDs the same: #listLen(variables.finalList)#
</cfoutput>

4. Show me any elements from the first list that do not exist in the second.
Again, this is something that I use a lot in my programming. I’ve set this up as a function that I simply pass in the 2 lists.

<!--- Create a deep copy of the first list to keep it intact. --->
<cfset variables.finalList = duplicate(variables.arraylist1)>
<!--- Remove any elements from the first list that exist in the second. --->
<cfset variables.finalList.removeAll(variables.arraylist2)>
<cfset variables.finalList = arrayToList(variables.finalList)>

<cfoutput>
	Final List: #variables.finalList#<br>
	Number of IDs not in second list: #listLen(variables.finalList)#
</cfoutput>

So very simple, yes?

But one could do that with cfloop no problems and with such small numbers of items in the lists, the overhead is negligible. But, what when we have a lot more items in the lists.

Here are some interesting numbers
Using the following lists

  • List 1 contains 35417 numbers
  • List 2 contains 728 numbers

I ran these 5 times using cftimer and the average times are below.

1. Does 1 list contains all the items in another list?
Takes 134ms

2. Are the lists the same?
Takes 18ms

3. Show me any elements from 1 list that exist in another list.
Takes 3692ms

4. Show me any elements from the first list that do not exist in the second.
Takes 1172ms

Now those numbers on their own don’t mean much, but lets compare them to cfloop numbers:

3. Takes 8115.2ms over twice as long.

4. Takes 37681.2ms. That’s a staggering over 32 times longer!

I think that you can see going the Java method route is well worth it.

Raw data
1.
117
100
217
119
117

2.
17
17
21
17
18

3.
3398
2869
3778
3787
4628

4.
883
999
1450
1175
1353

cfloop 3
7918
8122
7354
9318
7864

cfloop 4
38957
33179
37573
39038
39659

What are your thoughts?