Scott Adams sent me on a Wikipedia journey today with his article Monte Hall Problem. I started reading about the double-slit experiment, its extension in the quantum-eraser experiment, and finally quantum entanglement.
I suggest you read them, but only if you are prepared on looking at the world around you a little differently. If you're happy with the things the way they are I suggest you read something else instead.
2008-04-16
The Boggling of the Mind
history meme
history|awk '{a[$2]++ } END{for(i in a){print a[i] " " i}}'|sort -rn|head
Home:
155 cd
97 sudo
79 ls
69 svn
51 heyu
47 mvn
38 grep
37 less
28 vi
23 screen
Work:
252 mvn
119 cd
86 svn
50 ls
40 rm
32 less
22 ssh
22 man
22 cp
21 psql
2008-04-15
Open Source in the Enterprise
I guess many like me working in a large enterprise can relate to a story like this one: Jonathan Schwartz's Blog: Freedom's Choice:
The CIO responded categorically with 'we don't run MySQL, we run [name withheld to protect the proprietary].' The CISO said, 'We can't just let developers download software off the net, you know, we've got regulation and security to worry about.' The CTO smiled. Everyone else appeared to be sitting on their hands. I was going to leave it at that. Thanks for the business.How does your enterprise deal with this? Is freely available software treated as an opportunity, or a threat?
Until a (diplomatically) assertive Sun sales rep piped up, 'Um... no, I connected with a buddy of mine over at MySQL, and had him check - you've downloaded MySQL more than 1,300 times in the last twelve months.'
After a profoundly awkward silence, one of the individuals from their internal development team piped up, 'Actually, everybody uses it. Why bother hassling with license agreements when MySQL's got you covered. We're stoked you bought them.'
2008-04-07
Unit testing the database
A recurring challenge in any application employing a database is how to unit test the database access layer.
Quite often one of two suggestions seems to appear: Either using DbUnit together with an in-memory database, or by setting up separate database instances for unit testing purposes. Jakub Korab suggests that you set up two database schema per developer.
But is this a unit test? Try asking yourself the following question: What am I trying to assert here?
- That the database engine works?
- That the DB driver works?
- That your object mapping library is functioning?
So the thing you should assert is correct usage of the API.
For instance, I use Spring JDBC to talk to a PostgreSQL database, more specifically using Spring's SimpleJdbcTemplate. This class implements a handy interface, SimpleJdbcOperations, making it very easy to set up a mock for the entire database stack.
Your entire testing setup then collapses into adding behavior to this SimpleJdbcOperations mock, verifying that the correct invocations appear, optionally also verifying the ordering of the invocations.
This scheme does however have limitations. One is that you don't get the benefit of actually verifying that the SQL syntax is correct. The other is that any errors due to table column names and types go undetected by this unit test.
Asserting correct SQL syntax
The first problem is quite easy to solve. SQL syntax is not that hard, especially if you are strict on what syntax standards you want to hold for your statements. For example, I have written this EasyMock argument matcher to validate an SQL insert statement:
import java.util.regex.Matcher;This matcher verifies that the SQL syntax, database table name, and number of columns is correct. It also verifies that the number of placeholder arguments match the number of column names.
import java.util.regex.Pattern;
import org.easymock.EasyMock;
import org.easymock.IArgumentMatcher;
public class SqlStatementMatcher {
public static String insertStatement(String tableName, int argumentCount) {
EasyMock.reportMatcher(new SqlStatementMatcher.InsertStatementMatcher(tableName, argumentCount));
return "Insert Statement Matcher";
}
static class InsertStatementMatcher implements IArgumentMatcher {
private final String tableName;
private final int arguments;
private final Pattern pattern;
public InsertStatementMatcher(String tableName, int arguments) {
this.arguments = arguments;
this.tableName = tableName;
this.pattern = Pattern.compile(
"^ *INSERT +INTO +([ a-z_]+) +\\(([ a-z_,]+)\\) +VALUES +\\(([ ?,]+)\\)( +RETURNING [a-z_]+)?$");
}
public void appendTo(StringBuffer buffer) {
buffer.append("a valid SQL INSERT statement into table ").append(tableName)
.append(" with ").append(arguments).append(" arguments");
}
public boolean matches(Object argument) {
if (!(argument instanceof String)) {
return false;
}
String input = (String)argument;
Matcher matcher = pattern.matcher(input);
if (!matcher.matches()) {
return false;
}
if (matcher.groupCount() != 4) {
return false;
}
String actualTable = matcher.group(1);
if (! (tableName.equals(actualTable))) {
return false;
}
String[] argumentNames = matcher.group(2).split(",");
String[] placeholders = matcher.group(3).split(",");
if (argumentNames.length != placeholders.length) {
return false;
}
if (argumentNames.length != arguments) {
return false;
}
return true;
}
}
}
As you probably can imagine this matcher is very easily extended to matching select statements and even stronger syntax checking.
Asserting correct table column names and types
This problem is in part tested by the strong typing, both of the parameters for update calls and return type for query calls. But the aforementioned matcher could also be extended to check column names if so desired.
The final acid test for any database access layer is the integration test
This is where you put your application through a proper testing scenario. It could for instance be run as part of an automatic nightly build and test, or routinely as part of the release process. Don't mistake your unit test for integration tests! Unit testing has its purpose, integration test quite another.



