Upgrading Subversion Requires a Bindings Update for Trac!

My Subversion/Trac server was at Trac v0.9.6 and Subversion v1.3.x because those were the latest stable releases when I set up the server. I decided it would be relatively quick and painless to at least get the latest version of Subversion (v1.4.5) installed since I didn’t see anything on the web about Trac v0.9.6 being incompatible with newer Subversion builds.

Using the Windows binary installer, I had no problem installing Subversion v1.4.5 on the server. I tested everything and Subversion still worked, it showed the new version when accessing via web access, and Trac still worked fine.

Alas: Don’t forget that an upgraded version of Subversion will not upgrade your repository. It will upgrade a working copy of a checked-out repository, but it will not upgrade the repository itself.

That said, I was unaware of one more step that you must take to upgrade Subversion on a Subversion/Trac setup: You must also upgrade the Python bindings to Subversion.

This became apparent the next time I created a new repository, which was not a v1.4.x repository, and when I tried to build a Trac environment to point to it, Trac got upset because of the classic “Expected version ’3′ of repository; found version ’5′” error. To fix this, you must set up new bindings to the new version of Subversion, as explained in the TracSubversion page.

Now, I obviously love Subversion and I love Trac, but honestly, straight-forward documentation that is easy to understand for someone who doesn’t want to get in the thick of it isn’t really the strong suit for these communities, at least when it comes to installation and deployment on the server. What exactly it means–and how to do it–when they say, “Update the Subversion bindings” is not easy to understand. However, the solution is simple. All that is needed is to download the appropriate “svn-python” Windows installer that matches your version of Subversion and Python (in my case, 1.4.5 and py2.3) and run it on the server.

In my case, I had to stop Apache for the installation to succeed. Upon restarting Apache, everything worked great.

Union in QoQ Made an Enhancement Simpler

I was working with an app that would take an LDAP query from <cfldap> and do a bunch of processing against it. As it turns out, the LDAP query was targeted on an OU that wasn't grabbing all of the accounts it needed to process. There was a sibling OU that also needed to be included in the results.

I already had scope="SUBTREE" in the <cfldap> call, so I could've just set the context of the LDAP query to the parent of both OU's, but then it would grab a whole bunch of accounts that were in OU's that shouldn't be included in the processing. I could have restricted what was being pulled with a filter, but I already had several filters in the LDAP call and I didn't want to complicate that any further.

Well, think simpler then. What about just wrapping the LDAP call and its processing with a <cfloop>, executing against the different OU's each time? If the processing were simpler, that could've worked, but there is report generation and other stuff going on, and really all the accounts needed to be processed in one sweep.

There is still a simple solution: Query of Queries. Perform each LDAP call separately, then join the results together with a simple UNION statement.

CFM:
  1. <cfquery name="AllAccounts" dbtype="query">
  2.    SELECT * FROM MyFirstLdapQuery
  3.    union
  4.    SELECT * FROM MySecondLdapQuery
  5. </cfquery>

Now all the processing that occurs in my <cfoutput> tags that process the LDAP results will all happen in one sweep, with very few lines of code being altered, and none of my processing code had to be altered.

I simplified the code for this post, but in the app, the OU's are defined by a config file. So, the <cfldap> calls are executed in a loop, and then the SQL with the union statement is also generated by a loop based on the setting in the config file. So, at a later time, more OU's could be added with no additional coding required.

Ubuntu v7.10 on Parallels

You'll get display server issues if you try to install Ubuntu v7.10 in Parallels. But the Parallels Tools CD does have drivers to fix those problems. This blog post, Ubuntu 7.10 Install Guide, helps you get past the display server issues long enough to get the OS installed, and then gives instructions on how to get the Parallels Tools installed.

It worked great. Instructions were very clear and the process was mildly simple.

Backward Use of CASE in SQL

I was updating an old app to use SQL on a new SQL Server database rather than an older Access database. As any database programmer is aware, there are irritating inconsistencies between Access SQL and SQL Server's T-SQL, such as absence of the IIF() and Trim() functions in T-SQL.

So I was going through the SQL and making these changes. I came across a very ugly IIF() function similar to this:

SQL:
  1. IIF(phLead=True,'LEAD',
  2. IIF(phFax=True,'FAX',
  3. IIF(phVVM=True,'VVM', 'DEPT')))

Take that statement and add even more boolean fields. Clearly, the intent was to have a calculated field that had a friendly name based on which boolean field was true.

So, how can this be easily converted into a CASE statement? As it stands, CASE statements are actually more verbose than the IIF() function, and the IIF() function above is already hard to read and verbose as it is.

A direct code conversion would be something like this:

SQL:
  1. CASE phLead WHEN 1 THEN 'LEAD'
  2. ELSE CASE phFax WHEN 1 THEN 'FAX'
  3. ELSE CASE phVVM WHEN 1 THEN 'VVM'
  4. ELSE 'DEPT' END END END

Ugly, ugly, ugly. The cool thing about CASE that differs from IIF() is that you can attack it from the other direction. Instead of saying, "Is phLead true? Is phFax true? Is phVVM true?", you can instead say, "Okay, who's true? phLead? phFax? phVVM?" It sounds negligible, but the code is shorter and easier to read:

SQL:
  1. CASE 1 WHEN phLead THEN 'LEAD'
  2. WHEN phFax THEN 'FAX'
  3. WHEN phVVM then 'VVM'
  4. ELSE 'DEPT' END

Ahh, much better.

  Theme Brought to you by Directory Journal and Elegant Directory.