Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,597
|
Comments: 51,224
Privacy Policy · Terms
filter by tags archive
time to read 7 min | 1241 words

While it is possible, it is a pain in the ass. I'm working on a project now that doesn't use NHibernate (yes, I am surprised too).

There is very simple data acess there, and nearly nothing to do with touching the data, so I thought that I could simply use ADO.Net. It works, sort of, but my code is full of strings, and it is nearly untestable. The main issue is that all the *DataAdapter expect their own *Command, *Connection, etc. Which mean that I can't mock much of it.

Check out this little piece of a test (part of about 50 lines of setup, that leads to two lines of real test.

MockRepository mocks = new MockRepository();

IDbConnectionProvider connectionProvider = mocks.CreateMock<IDbConnectionProvider>();

IDbConnection connection = mocks.CreateMock<IDbConnection>();

IDbCommand getRecordsCommand = mocks.CreateMock<IDbCommand>();

ISender sender = mocks.CreateMock<ISender>();

SetupResult.For(connectionProvider.Connection).Return(connection);

IDbCommand deleteItems = mocks.CreateMock<IDbCommand>();

IDbDataParameter dataParameter = mocks.CreateMock<IDbDataParameter>();

IClock clock = mocks.CreateMock<IClock>();

SetupResult.For(clock.Current).Return(new DateTime(2006, 12, 20, 22, 45, 33));

 

connection.Open();

Expect.Call(connection.CreateCommand()).Return(getRecordsCommand);

 

string spToGetItems = "GetLockedRecords";

string spToDeleteItems = "DeleteItems";

getRecordsCommand.CommandText = spToGetItems;

getRecordsCommand.CommandType = CommandType.StoredProcedure;

getRecordsCommand.Dispose();

I could do the same with NHibernate in about three lines, and that would be easy. I'm considerring ripping what I already have and going that route. It would certainly be easier.

time to read 12 min | 2212 words

I need to be able to ask the database for some rows to work on, and I need to be sure that I am the only one that works on those rows. After thinking about it, I came up with this SQL:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRANSACTION

 

      INSERT INTO Locks(LockedBy, LockedAt, LcokedItemId, LockedItemType)

      OUTPUT inserted.Id

      SELECT TOP 100 @lockedBy, getdate(), item.Id, @itemType

      FROM Items item

      WHERE NOT EXISTS (SELECT 1 FROM Locks lock

            WHERE lock.LcokedItemId = item.id AND lock.LockedItemType = @itemType)

      ORDER BY item.Id

 

COMMIT TRANSACTION

This is the first time I need to implement pessimistic locking, and I am not sure if this is the right way to go. The work I am doing is disconnected, so I can't just lock the rows and continue to work.

Any suggestions?

Update: This is what I have now:

CREATE PROCEDURE lockAndGetItems AS

 

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRANSACTION

 

      DECLARE @lockedBy uniqueIdentifier, @countOfItemsToLock int

      SET @lockedBy  = '68A6D54C-557D-428D-8B82-5D68C9C1B33E'

 

      -- Get number of rows already locked by me

      SELECT @countOfItemsToLock = 100 - COUNT(Id) From Locks where LockedBy = @lockedBy

 

      -- Lock rows to complete to an even 100

      INSERT INTO Locks(LockedBy, LockedAt, LockedItemId)

      SELECT TOP (@countOfItemsToLock)  @lockedBy, getdate(), item.Id

      FROM Items item

      WHERE NOT EXISTS (SELECT 1 FROM Locks lock

            WHERE lock.LockedItemId = item.id and lock.LockedBy = @lockedBy)

      ORDER BY item.Id

 

      -- Return row data

      SELECT Items.* FROM Items JOIN Locks ON Items.Id = Locks.LockedItemId AND LockedBy = @lockedBy

     

COMMIT TRANSACTION

Basically it fetch the first 100 items designated for this SP. Each SP has a single caller, so I don't worry about expiring the lock. I will always get the locked rows. In the case of a crash when the rows are locked, when the client is restarted, it will get the same rows that it already locked, and can start working on them. The reason that I implement is as a SP with hard coded Guid is that each SP locks a different table.

time to read 5 min | 823 words

I just posted about semi statics, and now it is finally the post where I explain how I broke the external dependencies in my tests. That was the reason that pushed me to start talking about static in the first place.

I am using NHibernate to handle the data access (naturally), and when I started the project, there was no seperation in the tests from those that needs to touch the database (test that the mapping are working) and those that shouldn't (testing business logic).

I started to feel the pain recently, the tests took a long time to run, and the initial setup overhead was decidely not trivial, so even running a single test took too long. I decided that I really needed to make this seperation to integration tests and unit tests.

The problem was that I had code in both the tests and the business logic that assume that it can pull stuff from the database. I had the architecture I outlined in my previous post, where everything is accessible via the context, and everything is an interface. I did wrote a mocking library, so from there it was mainly going over each test and finding out if it is an integration test or a unit test.  This effort was not trivial, but it certainly paid off. I got a set of tests that run really fast, and I recently had to add another layer that significantly slows the tests. I was able to mock that in about half an hour (to handle all the premutations) and integrate it successuflly.

The integration tests are now much slower, but I don't care that much about their speed at the moment.

The setup for the unit tests is pretty complex right now, since I basically setup the whole environment via Rhino Mocks. All the tests inherits from a common base class that allows me to setup everything once for all the tests.  You can see what I do in this diagram. Just to note, the maximum cyclometic complexity here is 2.

(Image from clipboard).png

By the way, this is the single feature that I absolutely love in Refactor! and CodeRush (where it show you how long a method is).

The whole thing is simply based on code like this:

private void SetupMockObjectInSession(object obj, object key, Type type)

{

    Validation.NotNull(obj, "obj");

    SetupResult.For(_session.Load(type, key)).Return(obj);

    SetupResult.For(_session.Get(type, key)).Return(obj);

}

It gets a little more complex when I need to support complex queries, but it is still easy to grok.

The nice thing about it is that NHibernate is actually a deep infrastructure component in this application, I got a layer or two on top of it, which does all sort of nice things for me (like allowing me to ignore security, or logging, etc), which I am able to test, because I'm mocking the very bottom of the stack.

time to read 3 min | 448 words

I'm starting a new project now, and I thought it might be worth while to blog how I'm starting out.

I started with the initial requirements, and then just let them sit in my head for a day or two. Just thinking about the abstract concepts and trying things out without actually having to put something on paper or keyboard.

Then I created a new project in VS, and started with the class diagram. I just put down a single class and several interfaces, and a few methods. I am using this to focus my thoughts, and there isn't any code that I have written there. Then I opened a word document and start putting down the assumptions.

Those can be high level stuff like "The service will have its own dedicate database" to low level things like "A task will not hold a thread for an extended periods of time". I don't write why those are important, it is not important now. What is important is to figure out the constraints that I am going to work with, and what I assumptions I decide will drive the architecture.

Then I usualy either walk and mutter to myself, or blog about it ( :-) ) about something, and let things fall into shape. I find that putting things to words, either via texts or speaking them out loud helps me organize my thoughts into coherent structures. This is part of the reason that I blog. It keeps me organize.

I usually consider what tools I need to do the work, and what tools I can bend to make my job easier. Active Record is an awesome rule processor, if you know look at it just right. And Windsor is the ultimate configuration manager that you can want.

The next step is to create a test project, and write the first test. This can take a while. I'm futzing with ideas, and I am never sure what direction I will take the project. This is usually one of the hardest part for the project, because there are too many possiblities. I can spend quite a bit of time trying things out, either in code or in diagrams.

At that point I then start coupling my design, so it would actually be usable. This means that I go from things like ICommand to IFileCommand, because that needs the file it works on, etc. Once I reach this point, I have no more reasons to procrascinate and I need to start writing the actual application :-) 

time to read 1 min | 140 words

I arrived to work one day, and I meet this guy just as I setup my laptop for the morning. He noticed that I have the task bar set to three lines height, and he couldn’t understand why I was doing this. I am also the only developer I know personally who uses dual monitors  regularly.

Both the height of the taskbar and the dual monitors are not indulgences, I need them to actually work effectively. Take a look at my task bar at the moment:

 

 

And that is not uncommon. Add a couple of debug sessions, a few emails that I am in the middle of answering to, a couple more notepad windows, and I would completely lose track of what I am doing.

How does your taskbar looks like at the moment?

On Naming...

time to read 1 min | 164 words

After reading Oren's post about naming interfaces, I started to notice how I name my interfaces.

My own contribution to the "interface names that give me a chuckle" is IHaveNameAndId and IDecideWhenToStartTask, which I just created. I am probably going to rename that one, though.

And, as long as we are dealing with naming. I got an outstanding bug that read like this: "Rename Fetch class to something that actually have a meaning." This class has a single method (well, one mehtod, several overloads) that looks like this:

comboBox.DataBind = Fetch.IdAndDescription( ... ) ;

Together with the method name, it actually makes sense, but I am not sure if this is a good practice. Then again, I can't really think of a good name for that one.

FUTURE POSTS

  1. Replacing developers with GPUs - 3 hours from now
  2. Memory optimizations to reduce CPU costs - 2 days from now
  3. AI's hidden state in the execution stack - 5 days from now

There are posts all the way to Aug 18, 2025

RECENT SERIES

  1. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  2. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
  3. Webinar (7):
    05 Jun 2025 - Think inside the database
  4. Recording (16):
    29 May 2025 - RavenDB's Upcoming Optimizations Deep Dive
  5. RavenDB News (2):
    02 May 2025 - May 2025
View all series

Syndication

Main feed ... ...
Comments feed   ... ...
}