Scorpio in August?

I don’t know if anyone checked out the new Scorpio wallpapers posted by Ben Forta, but in the lower right there is a line “<8 : 2007 >.” (See the blue wallpaper .)

I seem to remember reading this speculation somewhere else, but a quick Googling yielded nothing. I think that’s a pretty decent sign that Adobe is targeting August for ColdFusion 8. Woohoo. Good news to those of us that want to deploy apps for a new school year.

Either that or they’re screwing with us. If that is the case I say: “Shame on you, Tim Buntel. Shame.”

Poor, Slightly Misunderstood, Squidhead

I finally got around to listening to the ColdFusion Weekly Podcast on February 12th. Squidhead was mentioned – WoooHooo! Wait a minute from the description it seems like Squidhead just creates CRUD + list stored procedures. The key to my disappointment is the word “just.” Squidhead doesn’t just generate stored procedures. It also reads in stored procedures that you create. So sure, it scaffolds the basic CRUD and list actions building stored procedures and CFC’s but also builds CFML from user defined stored procedures.

So for example, you have a table, person, with columns personid, username, password, first and last name. You run Squidhead once, you get the 4 CRUD procs, plus a DAO CFC to call them, then you get a list proc, plus a gateway CFC to call them. But then you go back and write a procedure “usp_person_select_by_username” because you would rather do that then select by identity. You run Squidhead again; it adds “select_by_username” function to the person DAO CFC.

But let’s take it one step further, suppose you write a stored procedure named “usp_person_auth” that takes the username and password and checks them as an authentication routine. Run Squidhead again. You’ll now have an “auth” function in your person gateway CFC.

The idea here is to do the database work in the database, and not have to do the manual work of writing the cfml calling code. Sure, it creates stored procedures, and that is a leg up, but it also lets those of us that like starting in the database an even higher leg up… (not sure if that’s the right modification of that metaphor.)

Anyway, don’t take this as a swipe at Matt and Peter. I’m glad to have some exposure in the ColdFusion Weekly Podcast. It’s my bad that I haven’t been publicizing Squidhead better.

CFC’s and Access = Package

I was asked today:

Could someone please explain the differences between cfc package and public access? I thought that package access made the method available to other templates within the same application, but that doesn’t seem to be the case.

Now, I remember being confused by this when I first started doing CFC’s so figured I would share.

A function with an access of “package” will be restricted to calling CFC’s and templates in the same directory as the CFC file of the function.

In my personal experience, I haven’t found access=package to be terribly useful. I tend to organize my files into subfolders like cfc, and then further subdivide by type of CFC. (Gateway, DAO, utility.) So to access them, I tend to put functions as either public or private. All in all, “package” just makes it harder to work with all of this stuff.

However, I have the luxury of working on private server, and not a hosting provider for the majority of my work, so my view maybe atypical. Anybody have a different viewpoint?

A Family that Codes Together

My wife, Janice, and I work for the same company. In fact we work for the same boss. It has its ups and downs. But if we didn’t work together, situations like these would never happen:

Janice was working on a Perl script that handles integrating Active Directory and MajorDomo. It was buggy and confusing and overall not well written. Janice was struggling with the parts that were crappy, basically trying to grok the ungrokable, and she calls me over.

Janice: Can you tell me what this section of code does:

## Im not really sure why I did this. It works so back off! my $max = $mesg->count; for($i = 0 ; $i < $max ; $i++) { my $entry = $mesg->entry($i); foreach my $attr ($entry->attributes) { $dn=$entry->get_value($attr) } }

Me: No.

Janice: Why not?

Me: I didn’t understand it when I wrote it. What makes you think I understand it now?

You see, I’ve worked for our current department on and off for the past 6 years. My first past through the group was doing Exchange and Windows Domain systems administration. I managed the upgrade from NT4 to Windows 2000 and Active Directory. I wrote the first batches of code that we used to integrate Active Directory and our legacy systems. That meant Perl. I learned it sort by accident back in the day, and at my height of ability I was never one of those guys who would write twenty lines of function in one line.

Which brings us back to this section of code; I wrote it in my first Active Directory LDAP Perl to CSO script. It was copy and pasted by another developer, and reused again. Until my wife had to deal with it… six years after I wrote it.

Sorry, hon.

Issues with cfntauthenticate

I’ve been meaning to blog about <cfntauthenticate> for awhile, but I keep forgetting. However, someone had an issue with it today, and it spurred me on.

Disclaimer

I don’t work for Adobe, so I have no idea why they did anything they did. Any supposition posted here is just that my supposition. Additionally, it’s not meant as criticism, as for the most part <cfntauthenticate> does exactly what it is supposed to do.

We’re a Window shop that relies heavily on out Active Directory Domain. We use it for LDAP mail routing, Exchange, and single sign on across our environment. From time to time we’ve had issues with <cfntauthenticate> under certain outlier conditions. Let me take you through some of them.

Too Many Groups

Occasionally, we’ll run in to singular users that cannot log into some applications but can log in to others. We’ll tease out variations in form inputs, and ensure the username and password works, and still can’t figure it out. We’ll look at our logs that track the reason for failure, and we’ll see “UserNotInDirFailure.” Even turning on the throwError option of the tag doesn’t help.

Eventually we trace it back to the listGroups flag. Turn it off, it succeeds, turn it on, it fails. So it’s something with the groups. Try taking some groups away from the user. Voila it stops failing.

Turns out, there is some number, N, of groups over which some sort of uncaught error will start to be thrown. It gets caught by the default error code and gets thrown as “UserNotInDirFailure.” N is a little nebulous, as it is unclear to me what effects domain local groups versus global groups versus distribution groups has on N. But in my last set of tests, N was 23.

To workaround, if you aren’t using groups, don’t use listGroups, as you don’t need it. If you are using groups for let’s say, authorization, revert to using LDAP for retrieving groups information. Also you could just prune your group membership…

Service Account Issues

This is the one that happened today. Every user’s login was returning “UserNotInDirFailure,” but only for a particular server. No changes in underlying networking were made.

My default recommendation: restart the server. When the admin of that server did that the ColdFusion service didn’t start. A quick check of the system logs showed that the login for the account the ColdFusion service was running under was failing. Turns out someone changed the password of it and didn’t change it in the services configuration on the server. It took about 36 hours before the problem was noticed.

According to the documentation, “ColdFusion must run as a user that has the privilege to authenticate other users in the specified domain.” So problems with the service account would cause problems with the tag.

No workaround here, just manage your service accounts properly.

PDC emulator

Active Directory domain controllers are intended to be redundant. Except for something called Flexible Single Master Operations roles, or FSMO roles. Each FSMO role makes the domain controller that hosts it unique in a fashion. I’m not going to go into all of it, but suffice it to say one of those FSMO’s is “PDC Emulator.” PDC stands for Primary Domain Controller, and was a feature of NT 4 and below. Basically the PDC was the domain controller to which domain information was read from and written to. Other domain controllers only allowed read operations. When Microsoft moved to Active Directory and multiple domain controller model, they left the PDC Emulator role in order to provide backward compatibility with tools that used NT 4 API’s for various operations.

What does all this have to do with ColdFusion? It’s my theory that <cfntauthenticate> uses the vestigial NT 4 API’s. I base this theory on the fact that if your PDC emulator is inaccessible, <cfntauthenticate> will fail for all users. However, if you have throwError set to false, you won’t know what is going on you’ll get a “UserNotInDirFailure” error. However, if you set throwError to true, you will see the real message, “Could not find domain controller for this domain XXXX” Where XXXX is the name of your domain.

There’s not much you can do about this. If the PDC emulator is unreachable from your Coldfusion server, <cfntauthenticate> will not work. The only solution I have come up with to replace <cfntauthenticate> with an analogous CFC that uses Secure LDAP queries against the domain controller instead.

Conclusion

I blogged this because when I’ve gone looking for <cfntauthenticate> errors, I’ve only found my own random posts on CF-talk. Hopefully, someone else will be less mystified by errors with this very useful tag.

Thinking About Code Objectly

I’m not talking about being unemotional about code, which would be “objectively”. No, “objectly,” I’m talking about code generation. When I first started writing Squidhead, I was writing procedural code to generate my code. After all, it’s tempting to think of it procedurally, as code tends to read from top to bottom. One of the breakthroughs for me was figuring out that most of the coding structures I was using can be expressed as objects. I mean the actual code text itself can be expressed as objects. In ColdFusion, this means a CFC.

Let me show you an example of what I’m talking about:

<!—************************************************—>

<!—create—>

<!—This function inserts a single comment record into the database.—>

<!—************************************************—>

<cffunction
access=“public”
name=“create”
output=“FALSE”
returntype=“numeric”
hint=“This function inserts a single comment record into the database.”
>

<cfargument
name=“body”
type=“string”
required=“FALSE”
default=“”
/>

<cfargument
name=“authorID”
type=“numeric”
required=“FALSE”
default=“0”
/>

<cfargument
name=“createdBy”
type=“numeric”
required=“FALSE”
default=“0”
/>

<cfargument
name=“updatedBy”
type=“numeric”
required=“FALSE”
default=“0”
/>

<cfset
var commentID = “”
/>

<cfset
var results = “”
/>

<cfstoredproc
procedure=“usp_comment_insert”
datasource=“#application.datasource#”
username=“#application.dbusername#”
password=“#application.dbpassword#”>

<cfprocparam
type=“OUT”
cfsqltype=“CF_SQL_INTEGER”
variable=“commentID”
dbvarname=“@commentID”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_LONGVARCHAR”
variable=“body”
dbvarname=“@body”
value=“#arguments.body#”
maxlength=“16”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“authorID”
dbvarname=“@authorID”
value=“#arguments.authorID#”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“createdBy”
dbvarname=“@createdBy”
value=“#arguments.createdBy#”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“updatedBy”
dbvarname=“@updatedBy”
value=“#arguments.updatedBy#”
maxlength=“4”
null=“NO”
/>

<cfprocresult
name=“results”
/>

</cfstoredproc>

<cfset results = commentID />

<cfreturn results />

</cffunction>

This is a basic insert function. We’ve all written this type of function as part of a CFC.

Let’s break this down into its properties:

Documentation

<!—********************************—>

<!—create—>

<!—This function inserts a single comment record into the database.—>

<!—********************************—>

Header

<cffunction
access=“public”
name=“create”
output=“FALSE”
returntype=“numeric”
hint=“This function inserts a single comment record into the database.”
>

Arguments

<cfargument
name=“body”
type=“string”
required=“FALSE”
default=“”
/>

<cfargument
name=“authorID”
type=“numeric”
required=“FALSE”
default=“0”
/>

<cfargument
name=“createdBy”
type=“numeric”
required=“FALSE”
default=“0”
/>

<cfargument
name=“updatedBy”
type=“numeric”
required=“FALSE”
default=“0”
/>

Local Variables

<cfset
var commentID = “”
/>

<cfset
var results = “”
/>

Content

<cfstoredproc
procedure=“usp_comment_insert”
datasource=“#application.datasource#”
username=“#application.dbusername#”
password=“#application.dbpassword#”>

<cfprocparam
type=“OUT”
cfsqltype=“CF_SQL_INTEGER”
variable=“commentID”
dbvarname=“@commentID”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_LONGVARCHAR”
variable=“body”
dbvarname=“@body”
value=“#arguments.body#”
maxlength=“16”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“authorID”
dbvarname=“@authorID”
value=“#arguments.authorID#”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“createdBy”
dbvarname=“@createdBy”
value=“#arguments.createdBy#”
maxlength=“4”
null=“NO”
/>

<cfprocparam
type=“IN”
cfsqltype=“CF_SQL_INTEGER”
variable=“updatedBy”
dbvarname=“@updatedBy”
value=“#arguments.updatedBy#”
maxlength=“4”
null=“NO”
/>

<cfprocresult
name=“results”
/>

</cfstoredproc>

<cfset results = commentID />

Results

<cfset results = commentID />

Footer

</cffunction>

Once you’ve established the structure of the CFC, you make these properties into variables. Anything that could be a list is actually an array. So arguments and local variables are actually an array of <cfargument> declarations, as is local variables. You write getter and setters. Actually I tend to write adders instead of setters as I’m just adding content to properties that grow. The getter that I write just concatenates all of the code and outputs it.

Here’s the code:

Function.cfc

You can even break it down even further. If you wanted, each <cfargument> could be an object with each attribute being a property. I didn’t go that far in Squidhead, but I did break the <cfstoredproc> declaration into an CFC.

This works very well for highly structured code, like <cfcomponents>’s , <cffunction>’s and <cfstoredproc>’s but it can be extended into less obviously structured code like custom tags. I was able to convert most of my procedural code creators to object oriented code creators.

So for whatever that’s worth, maybe this can help someone else out there.

Yet another Framework Post

I know, I know, we don’t need another framework post. But the latest posts from Sean Corfield, Brian Rinaldi, and Jake Munson make me want to speak up. While I’m naming dropping, I feel the need to cite Joel Spolsky’s In Defense of Not-Invented-Here Syndrome.

I am not against frameworks. I’ve tried coding against a couple. I’ve at least looked at most of them. I don’t currently use one. The one I got the furthest with was Model Glue 2. I like it a lot, but I’m just not productive enough in it yet to rely on it. That means that I can accept that Joe Rinehart came up with a better solution to my problems than I, but I can’t use them as productively, as I can use my own, perhaps flawed solutions.

It’s that bit of logic that I think should be the key to using frameworks. Use them where they will be more productive than your own efforts.

Follow what I mean here.

Let’s say you are a database wiz. You design textbook perfect databases in your sleep. You love seeing execution plans with no table scans. You think it’s cool when your queries have to use parallelism. It would not be in your best interest to use a database framework like Reactor. Why? Because you would be substituting Doug Hughes‘ judgment for your own, where you provide the most value.

Well that’s not quite true, because you don’t exercise the full extent of your knowledge on every single piece of SQL interaction code you write. If Reactor makes 80% of what you do take 20% of the time it used to, then it still might be worth it to use, and then manage the exceptional cases.

Okay, I haven’t convinced you – you still prefer the way you deal with your database to the way Reactor does. Okay, but you’re still probably doing a lot of repetitive, rule based code like writing <cfstoredproc> code blocks with are more characters the actual SQL stored procedures you’ve written. Perhaps you should write your own code generator. That’s essentially what I did with Squidhead, and it was easier than I thought, and a great experience for me.

Okay, database wiz, now it comes to the UI. You need to do an Ajax front end. What do you do? Start writing JavaScript? No! You told us you were a database wiz. If you’re not a JavaScript wiz then stop and download an Ajax framework. Because at some point someone has better judgment than you about some of the technology you use.

Now I started with a database guy, but I could have started with an Ajax wiz, or a designer and the advice would have been analogous.

If your expertise is based on a certain set of skills, you would be nuts to accept someone else’s judgment for yours. But if you’re not an expert in an area, that it is equally nuts to assume your judgment is better than an expert.

Pick frameworks and techniques that strengthen your weak spots.

MyWoes with Squidhead

One of the requests I’ve gotten for Squidhead is a MySQL version. Being the responsible Open Source author (or wanting to suck up to the people that are actually interested in it,) I tried to make it work with MySQL 5.0.

It did not go well. Specifically, I cannot call MySQL stored procedures from ColdFusion using <cfstoredproc>. (I get a null error from indexOfIgnoreCaseRespectQuotes in the MySQL driver.) It isn’t an absolute deal breaker, but makes my job much, much harder. I have to branch off more than just the database interaction. I would also have to branch off the CFC code too. (Which is much more complicated than the database stuff.)

So now I’m stuck at a quandary:

  • Do I do the work to get it to interact with MySQL at Squidhead’s present level of features? OR
  • Do I start adding features to Squidhead, along just the MSSQL path, and go back later and add MySQL support for the whole thing?

Part of my original logic behind doing it in MS SQL only, was that the problem I was trying to solve with Squidhead was DBA mandates of “You must use stored procedures!” My gut feeling was that this type of mandate was more likely to found in a shop with a more established database. I’m not knocking MySQL here, but stored procedures were just introduced in version 5.0, and a lot of shops don’t run it yet. Therefore less shops would mandate stored procedures with MySQL. So it would be smarter to go after an Oracle version than a MySQL version.

Then there are the features that I would like to add.

  • I would like to remove the requirement identities. (I would do CRUD against Primary Keys.)
  • I would like to add support for configuration metadata for things like “ORDER BY.”
  • I would like to decouple the custom tags from the data retrieval cfc methods.

Does anyone out there with either an interest in Squidhead, or experience with an open source product have any advice?

My Slow Switch to CFEclipse

This is the third time I’ve tried to switch to CFEclipse. It looks like this time it might stick.

My big problem with CFEclipse to date is that it has been incompatible with the way I have worked. I tend to work on many small projects, each with its own network share. In Dreamweaver each of my sites point to the UNC address of the project’s share. CFEclipse does not seem to handle files over UNC path’s directly. From the little bit of information I have been able to find, it looks like a problem with Eclipse, not CFEclipse specifically. It works just fine with mapped drives, but I have many projects, each with their own share, and that’s a lot of mapped drives.

Now, one of the guys I work with, newly minted MXNA blogger Dave Konopka, pointed out that I could just map the root of my web server. I have the ability to do so, because I have elevated privileges on my ColdFusion servers, seeing as how I built them. Now I’ve always viewed this as abusing my administrative rights since not all of our developers have these rights. I try to consume the services we provide as the rest of the developers here do, because 1, there’s usually a good reason for doing things the way we do, and 2. It helps me spot . However, come to think of it, the whole reason that I have a whole bunch of smaller projects is because I am an administrator. So maybe it’s not really cheating to do it this way.

Anyway, I’m over that hurtle, I’ve got a whole bunch of projects assigned, I’ve integrated Source Safe, and giving it an honest try.

What I like:

I like Snippets, especially after Mark’s tutorial. I like default code folding. I love Control+Shift+D (<cfdump> for those that haven’t used it). I love how much faster it is than Dreamweaver, especially working remotely. I love that the component explorer allows me to drop a fully written <cfinvoke> set down. (Well technically so does Dreamweaver, but CFEclipse does it much faster.)

What Surprised Me:

I’ve gone ANT crazy. It’s not really within the scope of CFEclipse, but now that I get ANT, I love it. It’s so much easier to run build tasks now.

What I don’t like:

I still wish the aforementioned difficulties with UNC paths weren’t there. Other than a few “I’m used to doing a different way” problems that are just learning curve issue, I only have one other concrete issue. I wish I could color the background of comments to the bright yellow I’ve gotten used to in Dreamweaver. (I know, it’s coming. )

I think between the speed, the integration with ANT, and the general direction of the community, I might stick with CFEclipse this time around.