Quick-and-dirty unique constraints in Raven DB

Quick-and-dirty unique constraints in Raven DB

Raven DB, like most NoSQL databases designed to be fast and scale out, does not readily support enforcing uniqueness of fields between documents. If two users must not share the same email address or Facebook ID, you cannot simply add a unique constraint for it.

However, Raven DB does guarantee uniqueness in one place: each document must have a unique ID, or a ConcurrencyException will be thrown. By creating dummy documents with say, an email address for an ID, this feature can be effectively exploited to achieve unique constraints in Raven DB.

You can easily add this behaviour to your database if you install the Raven DB UniqueConstraints Bundle, which will enforce uniqueness on updates as well as inserts. However… if the field is immutable and you just want something quick and dirty you can use this: RavenUniqueInserter.cs 🙂

using (var session = documentStore.OpenSession()){    var user = new User                   {                       EmailAddress = "[email protected]",                       Name = "Richard Dingwall"                   };    try    {        new RavenUniqueInserter()            .StoreUnique(session, user, p => p.EmailAddress);    }    catch (ConcurrencyException)    {        // email address already in use    }}

It works by simply wrapping the call to DocumentSession.Store() with another document – in this case, it would also create a document with ID UniqueConstraints/MyApp.User/[email protected], guaranteed to be unique.

You can grab it here: https://gist.github.com/1950991

Fragmented integration tests – aka the questionable value zone

Fragmented integration tests – aka the questionable value zone

In TDD, different styles of tests can be applied to cover different levels in your code base. Two or three years ago, if you asked me what they were, I would probably have listed them as:

  • Highest granularity – unit tests, quick to run, drive low-level class design
  • Fragmented – integration tests, testing higher-level components and external dependencies (e.g. real SQL database, fake message bus)
  • Whole system at once – slow end-to-end tests, testing for story/feature acceptance at the UI or client API level

However, it has become increasingly clear that fragmented integration tests (somewhere in the middle between unit and full-blown end-to-end integration tests) don’t really provide the same value as their brothers.

They suffer all the disadvantages of both unit and end-to-end tests:

  • Like unit tests, they require setting up mocks/test doubles for collaborating modules
  • Like end-to-end tests, they have a high cost of maintaining external components like databases and integrated third party systems (setting them up, populating them with the right test data, reverting changes for next time etc)
  • Like unit tests, they are brittle and not friendly to refactoring
  • Like end-to-end tests, they are slow to run

… and, over the lifetime of the code base, the only real benefit they provide is slightly faster feedback of problems than end-to-end tests. Is it really worth keeping them?

T-SQL equality operator ignores trailing spaces

T-SQL equality operator ignores trailing spaces

Today I discovered something new about SQL Server while debugging an application. T-SQL’s equality operator ignores any trailing spaces when comparing strings. Thus, these two statements are functionally equivalent:

SELECT * FROM Territories WHERE TerritoryDescription = 'Savannah'SELECT * FROM Territories WHERE TerritoryDescription = 'Savannah         '

When executed against the Northwind database included with SQL Server they both return the same row, which has no trailing spaces after its TerritoryDescription.

TerritoryID          TerritoryDescription                               RegionID    -------------------- -------------------------------------------------- ----------- 31406                Savannah                                           4(1 row(s) affected)

This behaviour isn’t immediately obvious from the offset, and isn’t mentioned on the MSDN entry.

To avoid this problem, you should use LIKE instead:

SELECT * FROM Territories WHERE TerritoryDescription LIKE 'Savannah         '

When comparing strings with LIKE all characters are significant, including trailing spaces.

Update: a co-worker discovered yesterday that using LIKE in T-SQL JOINs doesn’t use indices in the same way that the equals operator does. This can have a significant impact on performance. Be warned!

Troubleshooting Windows module dependencies

Troubleshooting Windows module dependencies

I have just got a new computer at work, and over the past week I have been installing all the software that I like to use. One tool I rely on is IISAdmin, a program that sits in the system tray and allows you to run multiple IIS websites under non-server editions of Windows. Unfortunately, when I tried to install it under Window Vista, it failed with the message “Error 1904. Module C:Program Filesiisadminztray.ocx failed to register. HRESULT -2147024770. Contact your support personnel.”

IISAdmin setup error 1904

Attempting to manually register the module with RegSvr32 didn’t work either:

The module "ztray.ocx" failed to load.

I couldn’t find anything searching for either of the error messages, so I did some digging on the module itself. It turns out that ztray.ocx is an old (1997) ActiveX control that allows programs to add an icon to the system tray.

I eventually found Dependency Walker, a tool that scans Windows modules for dependencies. I opened up ztray.ocx to see if it was missing anything.

Viewing ztray.ocx with Dependency Walker

As you can see, ztray.ocx makes calls to a module called msvbvm50.dll, part of the Visual Basic 5.0 run-time. This package is present in Windows XP, but appears to have been dropped from Vista. Luckily it is still available as a free download from Microsoft. Installing it solved the dependency problem, and I was able to install IISAdmin successfully.