April 2006 - Posts - Jon Galloway

April 2006 - Posts

Job Application? Name and weblog only, please!

Scott Hanselman wrote about being put off by a resume submission with this sort of e-mail signature: Joe Blow, MCSE, MCSE+I, MCSD, MCT, MCP. He jokingly (?) proposed that we sign our names with something a bit more useful: Scott Hanselman, 11 Successful Large Projects, 3 Open Source Applications, 1 Collossal Failure.

Yep, I'm with you. I've got an MCSD, but you won't find that anywhere online.1

Cert's don't answer most of my questions as a resume reviewer:

  1. Are you a job hopper?
  2. Do you have a record of actually shipping code? Version 1.1? Version 2.0?
  3. Have you maintained production applications?
  4. What's your work ethic?
  5. Are you a self starter? Can you pick up new technologies quickly?
  6. Do you just learn what you have to in order to get by, or are you pushing yourself?

Let's go beyond certifications - resumes fail pretty badly here, too. They take a long time to review, and they haven't really helped me find good candidates in the past. Oddly enough, many of these things ARE answered by including a weblog link after a signature. A technical blog is a much better reference than a list of certs, buzzwords, or even a long job history.

Applying for a job? Skip the cert list, skip the buzzwords, and skip the worthless resume. Name and weblog only, please!

1Oops, except now. Backspace backspace backspace...

Assault on 13th Labour - Cross Platform Distributed Computing in .NET

BoingBoing linked to a distributed program attack on an encryption puzzle on Perspex City called Assault on 13th Labour. What caught my eye was the fact that it's a .NET console application which runs on Mac and Linux under Mono as well as Windows under the Microsoft.NET runtime.

A cross platform distributed computing application that's 60K is just plain cool. There's no "Download Windows version here, Mac version here, Linux version here" deal - this is the same EXE running on all three systems, collaborating with a central work dispatcher via webservices. Unlike some other cross platform apps in the past, this thing was a simple unzip / run install, and it's not bogging down my computer.

Could this write once / run anywhere thing actually work?

The Death Star - The Ultimate Waterfall Project?

James Higgs asks a great question: Was the Death Star built using waterfall?

My favorite part (quoting from the beginning of Star Wars Episode VI):

Darth Vader conducting a status meeting.VADER: The Emperor does not share your optimistic appraisal of the situation.
JERJERROD: But he asks the impossible. I need more men.
VADER: Then perhaps you can tell him when he arrives.
JERJERROD (aghast): The Emperor's coming here?
VADER: That is correct, Commander. And he is most displeased with your apparent lack of progress.
JERJERROD: We shall double our efforts.
VADER: I hope so, Commander, for your sake. The Emperor is not as forgiving as I am.

This all sounds like a few status meetings I've been in. And I'll just remind you that despite this terrifying project management approach, at the end of the film, the Death Star remains unfinished and is blown up with the help of some little furry bears.

Posted by Jon Galloway | with no comments

[SQL] FTP download and restore an MSSQL database backup

I extended my DOS batch script to restore a SQL 2000 database and grant permission to ASPNET account to pull the database backup from an FTP location.

This has been a big timesaver on a recent DotNetNuke based project. The designer and client are working off a staging server, so I regularly need to refresh my development database to keep in sync. We have a scheduled nightly database backup on our stage server that writes to a location that's accessible via FTP, so I can just run this script and I'm caught up to the most recent backup.

The variables are set at the top of the script. The ones you'll definitely need to change are shown in bold red.


ECHO Setting Variables
set DBNAME=mydatabase
set DBDIRECTORY=C:\Program Files\Microsoft SQL Server\MSSQL\Data
set FTPADDRESS=ftp.myserver.com
Restoring %DBNAME% Database from FTP

::Use %COMPUTERNAME%\ASPNET for localhost
::Use DOMAIN\ACCOUNT$ for a domain account

set /p GETLATEST=Download backup from FTP (Y/n)

set /p FTPUSERNAME=Enter FTP User Name
set /p FTPPASSWORD=Enter FTP Password

ECHO Downloading backup via FTP
:: Create the temporary script file
script.ftp USER
>>script.ftp ECHO %FTPUSERNAME%
>>script.ftp ECHO %FTPPASSWORD%
>>script.ftp ECHO binary
>>script.ftp ECHO prompt n
>>script.ftp ECHO get %DBBACKUPFILE%
>>script.ftp ECHO bye

:: Use the temporary script for unattended FTP
FTP --s:script.ftp %FTPADDRESS%
:: Overwrite the temporary file before deleting it
TYPE NUL >script.ftp
DEL script.ftp

ECHO Restoring database
osql --d master -"alter database %DBNAME% set single_user with rollback immediate"

osql --d master -"restore database %DBNAME% from disk='%~dp0\%DBBACKUPFILE%' WITH MOVE '%DBLOGICALNAME%_Data' TO '%DBDIRECTORY%\%DBNAME%_Data.MDF', MOVE '%DBLOGICALNAME%_Log' TO '%DBDIRECTORY%\%DBNAME%_Log.LDF'"

osql --%DBNAME% -"sp_grantdbaccess '%ASPNETACCOUNT%'"
osql --%DBNAME% -"sp_addrolemember 'db_owner', '%ASPNETACCOUNT%'"

osql --d master -"alter database %DBNAME% set multi_user"

ECHO Donepress Enter key to close...


Posted by Jon Galloway | 1 comment(s)
Filed under: ,


Jon Udell recently posted about Sparklines :

Here, for example, is a sparkline showing monthly citations of LibraryLookup in del.icio.us since Jan 03: . I made this using Joe Gregorio's excellent sparkline service, by the way.

Grig has some cool examples as well:

Here is the per capita income in California from 1959 to 2003.
And here is the "real" per capita income (adjusted for inflation) in California, from 1959 to 2003.

Edward Tufte proposed Sparklines: "small, high-resolution graphics embedded in a context of works, numbers, images". The idea is to use small graphs to help us view trends and integrate them into the content. Tufte proposed them a few years ago, and it's neat to see them in the wild and supported on so many development platforms.

Jon Udell made use of a simple service which allows you to specify a sparkline using an image url with querystring parameters like this:


There's plenty of .NET code out there for creating Sparklines:

Posted by Jon Galloway | with no comments

[JS/CSS] event:Selectors - the simplest way to hook Javascript events to a CSS class

event:Selectors is a really nice wrapper for the Prototype.js library. It allows you to hook Javascript events to CSS classes with 2 or 3 lines of Javascript code:

'#icons a:mouseout, #other-item:mouseover': function(element) {
  var app = element.id;
new Effect.BlindUp(app + '-content', {queue: 'end', duration: 0.2});

Prototype recently added Attribute Selectors , which allows this kind of fun:

input[type="submit"] {  color:  #ccc; }
a[href!="#"] { background:  #c00; }
a[class~=external][href="#"] {  font-style: italic; }
Posted by Jon Galloway | with no comments

[AJAX] Let's hear it for the WebBus

Andrew Stopford proposed a WebBus - a common communications system for browser components (AJAX, Javascript, Applets, Flash, etc.). That makes a lot of sense - all these AJAX widgets are kind of neat as little individual pieces of flair, but they could do a lot more if there was a common communications protocol for inter-component communication in the browser.

Posted by Jon Galloway | with no comments

[T-SQL] Call a stored procedure once for each row in a query or table

Although it's not at all good from a database performance perspective, sometimes data import or upgrade scenarios require a script which calls a stored procedure once for each row in a table. In this example, I'm calling usp_InsertUser on every employee in EmployeeImportTable.


declare @Proc nvarchar(50)
declare @RowCnt int
@MaxRows int
@ExecSql nvarchar(255)

select @RowCnt 1
select @Proc 'usp_InsertUser'

-- These next two rows are specific to source table or query
declare @Import table (rownum int IDENTITY (11Primary key NOT NULL , EmployeeID varchar(9))
insert into @Import (EmployeeIDselect EmployeeID from EmployeeImportTable

select @MaxRows=count(*) from @Import

while @RowCnt <= @MaxRows
@ExecSql 'exec ' @Proc ' ''' EmployeeID '''' from @Import where rownum @RowCnt 
--print @ExecSql
execute sp_executesql @ExecSql
Select @RowCnt @RowCnt 1


Posted by Jon Galloway | 42 comment(s)
Filed under:

[T-SQL] Drop all constraints on a table

Here's a simple scriptlet I've included in database upgrade scripts to drop all constraints on a table which will then allow dropping the table. Of course, you'll want to replace the @database and @table parameters.

This doesn't take care of circumstances where another table has a foreign key to the table you want to drop - in that case, you'll want to explicity drop that foreign key first.

-- t-sql scriptlet to drop all constraints on a table
DECLARE @database nvarchar(50)
DECLARE @table nvarchar(50)

set @database = 'dotnetnuke'
set @table = 'tabs'

DECLARE @sql nvarchar(255)
WHILE EXISTS(select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where constraint_catalog = @database and table_name = @table)
    select    @sql = 
    where    constraint_catalog = @database and 
            table_name = @table
    exec    sp_executesql @sql
Posted by Jon Galloway | 5 comment(s)
Filed under:

SQLite - ALMOST a great embedded database solution for .NET applications

A comment on my post about the SQL/e announcement said it sounds a lot like SQLite. The subject warrents a separate post. SQLite is a great embedded database. It's free, open source, small, fast, ACID  compliant, and frequently updated. 

SQLite is an ideal embedded database provided you don't care about concurrency. That's because any write operation locks the entire database . Even Microsoft Access beats that; it's had record level locking for a while.

That's not a complete show stopper, even for multi-threaded applications, if your data provider handles SQLITE_BUSY errors correctly. By "handling the error", I mean repeatedly trying the database operation until it succeeds or the connection or command timeout is reached, which is kind of sad but works. I submitted a bug report for the ADO.NET Data Provider for SQLite project almost a year ago about this exact issue; the fix was made quickly, but the result hasn't helped anyone since this project hasn't produced a new release since August 2005. Unless you want to mess with building from the SourceForge CVS repository, you're out of luck under .NET 1.1.

However, there's a new project for a .NET 2.0 data provider for SQLite which appears to handle database locks correctly. So that's good.

Still, before SQLite can compete with Firebird or SQL/e, it needs to clean up its act when it comes to multi-threading. That means moving beyond just publishing best practices on how to work around the quirks of a database engine which has two lock states (locked / not locked) to table, page, and row level locks. I think Shailesh has a pretty good suggestion for adding a real locking strategy to SQLite. Might be a good idea if they integrate this before Mozilla integrates SQLite as their new Unified Storage system.

And a general recommendation for using any embedded database engine - use an abstration layer. I learned this the hard way; an OR/M like NHibernate would have saved me a lot of time and frustration.

Posted by Jon Galloway | with no comments
More Posts Next page »