Showing posts with label database. Show all posts
Showing posts with label database. Show all posts

Wednesday, 3 June 2015

A little PeanutButter housekeeping

PeanutButter, that collection of libraries that does a whole bunch of stuff, has always been extended with the philosophy that it would be better to have a bunch of small libraries each with only their own dependencies rather than a monolithic installation of a bunch of crap you'd never want.

Well, with the exception of PeanutButter.TestUtils.Generic, which is where interesting test helper code went to lurk and generally be useful. This was where the first incarnation of TempDb was born. It was either Sqlite or SqlCe, I don't remember, but whichever it was, the other was soon to follow, in the same package. So if you wanted a temporary SqlCe database, you ended up getting all of the Sqlite dependencies smooshed into your project. Boo!

I recognised this as sub-optimal, but left it just so, partly because I'm a lazy bugger and partly because I was afraid of fallout for anyone who might upgrade packages and find stuff to be no longer working as it had been moved out into another package.

Not too long ago, I got the itch to add LocalDb support and, of course, it ended up in the same assembly. I was getting less stoked, but remained at the same level of lazy.

Finally, tonight, I got my ass in gear and split these out. So there are 4 new packages:
  • PeanutButter.TempDb
  • PeanutButter.TempDb.Sqlite
  • PeanutButter.TempDb.SqlCe
  • PeanutButter.TempDb.LocalDb
The first contains the generic TempDb<> logic and the remainder are concrete implementations. PeanutButter.TestUtils.Generic no longer provides these classes (and no longer spams your projects with the unused dependencies). Apologies if this causes some "WAT?!" for anyone, but the split was inevitable. As a bonus side-effect, PeanutButter.TestUtils now depends on NUnit, so installing the former will bring in the latter -- which is actually less WAT because of funky things like PropertyAssert.

Anyway, as always, they're totally free. So if they break, you can keep all the pieces.

Thursday, 7 May 2015

PeanutButter TempDb gets LocalDb support

PeanutButter.TestUtils.Generic contains a lot of stuff, including TempDb<>, a generic abstract class which can be used to create temporary database instances and two derivatives, TempDbSqlite and TempDbSqlCe which, as the names might suggest, provide temporary databases of the Sqlite and SqlCe flavours.

Tonight, I added TempDbLocalDb which uses SQL Server's LocalDB mode (as is the default mechanism for MVC web applications. Whilst this does seem to take a little longer to spin up, it means that your tests can now have full SQLServer support with a temporary database which is automatically cleaned up as your tests end.

TempDb<> implements IDisposable, so the natural flow would be something like:

using (var db = new TempDbLocalDb())
{
    var connection = db.CreateConnection();
    connection.Open(); // if you need it open first
    // do stuff with the connection
    // for example, create an Entity context using the DbConnection
}
 
Thanks to Andrew Russell for the idea and pointing me at some resources (http://blog.developers.ba/localdb-for-database-integration-testing-in-asp-net-5-project-and-xunit-net/) which got me going.

You can install via nuget with:

install-package peanutbutter.testutils.generic

Hope this is of use to someone. Whilst it's true that providing a repository layer, for example, and mocking out data get/set operations is a lot faster (and probably better design), there are times when you just have to test against a database engine (for example, when testing that your database migrations work and that your entity models align with your migrated database structures... you are testing that, aren't you?)

Update (2015/06/03):  the TempDb packages have (finally) been split out and swept up so you don't have to install all of the providers you're not using. Check out the post here: http://davydm.blogspot.com/2015/06/a-little-peanutbutter-housekeeping.html

Wednesday, 21 January 2015

EntityFramework: getting to the bottom of a murky error

In doing some work using EF which talks to existing databases on MSSQL in production and SQLCE for testing (check out https://github.com/fluffynuts/OrmNomNom.git for an example of using SQLCE and a transient database to do Entity testing -- there's also a bit in there about using NHibernate too), I used the Entity POCO generation tools to quickly spew out the classes that should work when talking to the existing database. I also wrote some FluentMigrator migrations so I could get a temporary database up to speed and set off to use that method to test some database interaction, when:
Boom! InvalidOperationException ("Sequence contains no elements").
Now the befuddling aspect of this exception is where it was thrown. I basically have some code like:
using (var ctx = new DragonContext(db.CreateConnection()))
{
    var unit = new SupplierPriceList() 
    { 
        SupplierPriceListID = "test", 
        SupplierID = "foo", 
        MaterialID = "foo", 
        CompanyCode = "foo", 
        Date = DateTime.Now, 
        SupplierPrice = 1.23
    };
    ctx.SupplierPriceLists.Add(unit);
    ctx.SaveChanges();
}
And the exception is thrown at the point of the call to Add(). Which doesn't seem to make a lot of sense as the temp database being used has no rows in any tables, so of course SupplierPriceLists is empty and one might expect that to be the source of the exception, considering the text, but it really shouldn't matter. Tables are empty all the time and we can add rows to them. Still, the error befuddles...
Looking at the stack trace, I see the last two frames are:
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
   at System.Data.Entity.Utilities.DbProviderManifestExtensions.GetStoreTypeFromName(DbProviderManifest providerManifest, String name)
Ok, so the last frame explains the raw reason for the exception: something is doing a Single() call on an empty collection. But what? The call one up looks interesting: GetStoreTypeFromName seems to suggest that Entity is doing a lookup to find out how it should store the data for that property. So, on a hunch, comment out all properties except the implied key field (SupplierPriceListID) and the Add() call works. Hm. Perhaps SQLCE doesn't like the
double?
fields? Nope -- uncomment them and things still work.
Then the culprit leaps out. The generator tool has annotated a DateTime? field with:
[Column(TypeName = "date")]
Removing the annotation causes the error to subside -- and the SaveChanges() call on the context passes, on both MSSQL and SQLCE
I thought I'd just make a record of this here as I found nothing particularly useful through much googling and eventually found and resolved the problem based on a hunch. Perhaps this post can save someone else a little mission. Of course the DateTime? value is truncated for the Date field, but hey, that's what the client originally intended...

Monday, 30 June 2014

PeanutButter.DatabaseHelpers: get your compiler to start error-checking your SQL statements

PeanutButter was born out of a desire to share code between projects, in particular, to take advantage of utility and fixes introduced during the development process on a range of concurrent projects in the realm of code which was specific to none.

Quite basically, I had some code which was already figured out and worked fairly well for what it was intended to do and I was just plain too lazy to maintain multiple versions of that code. I thought it would be great if I could use, say, the Nuget packaging system to spread the most up-to-date versions of code between projects, if only packaging for Nuget wasn't such a pain. The CLI tools work, but aren't easy to use. The official GUI for Nuget packaging looks like a revenge unleashed on the world by an angry development manager trying to prove he can code. No offense.

Ok. Offense. The Nuget GUI tools are horrid and the CLI packaging mechanism is a PITA. Thank goodness for the Nuget Package Template extension for Visual Studio. With a simple post-build event from each relevant package, I can push all 11 (currently) PeanutButter.* Nuget package updates after having run all my tests and switched to Release mode. Win!

But I digress; this article is actually to introduce PeanutButter.DatabaseHelpers and show you how you can effectively get your compiler to error-check your application SQL.

First, taking a step back. If you've been using a decent ORM like Entity, NHibernate, Habanero or even just Linq-to-SQL, you don't have a need for PB's DatabaseHelpers. You can save yourself the effort of reading the rest of this article. One of the primary reasons for using an ORM (imo) is to abstract the SQL away from the application. ORMs which do Linq well are especially good at this -- and that's one reason why I've been a fan of Entity (warts and all) for quite some time. None of them are perfect but they all can take a lot of the pain of dealing with direct database calls away. In particular, an ORM allows you to:
  • Switch database backends (eg MSSQL/Firebird/MySQL/PostgreSQL and others). Of course backend support depends on the ORM, but most give you some kind of choice here.
  • Not have to type out correct SQL statements in your code. You may be wondering why this is a problem, unless, of course, you've had the experience where SQL in your code worked once and stopped mysteriously. After back-tracking VCS commits, you find that someone accidentally changed a string and there was nothing to pick it up. Or perhaps there was a test and the test was just as wrong as the code it was constraining.
  • Get the compiler to check that you've gotten the names of your database entities correct -- if you've misspelled an entity in your code in one place, chances are your code doesn't compile. Which is good -- the earlier up the code/compile/run/debug/package/deploy/test/etc chain you fail, the less it costs everyone.
  • Not have to worry about SQL injection attacks.
If you're using a super-light ORM like Dapper or just simply converting a giant project with heaps of direct ADO access or perhaps providing support for an app using an unsupported backend (like Access), you may have to get down to the bare SQL. But it would be great if you didn't have to actually take the risk of writing some SQL. Better still if the tool producing the SQL to run on your backend can be tweaked to target a different backend as required.

So here's a possible approach:


  1. Ensure that all of your database entities are defined as string constants in one accessible source file so that you aren't constantly fighting with each other on how to spell "color". Or "colour". However you all choose to spell it. And you aren't left to discover that "received" is spelled "recieved" sometimes in your SQL at go-live time. 
  2. Get a tool like PeanutButter to do the boring work for you. Reliably and in a manner you can test, with fluent builder syntax.
Sound like a plan? Great (:

First, I like to stick to using a DataConstants file to hold constants like field names, default values, etc. The other advantage here is that you can reference the same DataConstants in your FluentMigrator migrations (you are using FluentMigrator, aren't you?!). For example:

namespace MyProject.Database 
{ 
    public static class DataConstants 
    { 
        public static class Tables 
        { 
            public static class Employee 
            {  
               // to use where you would reference the name of your table
                public const string NAME = "Employee";
                public static class Columns 
                { 
                  public const string EMPLOYEEID = "EmployeeID";
                  public const string FIRSTNAME = "FirstName";
                  public const string SURNAME = "Surname";
                  public const string DATEOFBIRTH = "DateOfBirth";
                }
            } 
        } 
    } 
}

Next, let's say we wanted to get a list of all Employees whose first names are "Bob". We could do:

var sql = SelectStatementBuilder.Create()
            .WithTable(DataConstants.Tables.Employee.NAME)
            .WithField(DataConstants.Tables.Employee.Columns.EMPLOYEEID)
            .WithField(DataConstants.Tables.Employee.Columns.FIRSTNAME)
            .WithField(DataConstants.Tables.Employee.Columns.SURNAME)
            .WithField(DataConstants.Tables.Employee.Columns.DATEOFBIRTH)
            .WithCondition(DataConstants.Tables.Employee.Columns.FIRSTNAME,
                             Condition.EqualityOperators.Equals,
                             "Bob");

Ok, so this looks a little longwinded, but with a using trick like so:

using _Employee = DataConstants.Tables.Employee;
using _Columns = DataConstants.Tables.Employee.Columns;

// some time later, we can do:
var sql = SelectStatementBuilder.Create()
            .WithTable(_Employee.NAME)
            .WithField(_Columns.EMPLOYEEID)
            .WithField(_Columns.FIRSTNAME)
            .WithField(_Columns.SURNAME)
            .WithField(_Columns.DATEOFBIRTH)
            .WithCondition(_Columns.FIRSTNAME, Condition.EqualityOperators.Equals, "Bob");

Now that's fairly readable and always produces the same, valid SQL. And will break compilation if you misstype something. And you can use Intellisense to help figure out required column names. This is a fairly simple example; just a taste. PeanutButter.DatabaseHelpers includes:
  • Statement builders for:
    • Select
    • Update
    • Insert
    • Delete
    • Data copy (insert into <X> select from <Y>)
  • The ability to do Left and Inner joins
  • Order clauses
  • Where clauses
  • Automatic quoting of strings, datetimes and decimals to values which will play nicely at your database (no more SQL injection issues, no more issues with localised decimals containing commas and breaking your SQL)
  • Interfaces you can use for injection and testing, for example with NSubstitute (ISelectStatementBuilder, IInsertStatementBuilder, IUpdateStatementBuilder, IDataCopyStatementBuilder, IDeleteStatementBuilder)
  • Another helper package PeanutButter.DatabaseHelpers.Testability which sets up NSubstitute mock objects for you so you can easily test without having to stub out all of the myriad builder returns on statement builders
  • Executor builders:
    • ScalarExecutorBuilder for insert/update/delete statements
    • DataReaderBuilder for traditional ADO-style code
      • With interfaces for easy testing
  • Support for some computed fields (Min, Max, Coalesce, Count)
  • Constrained by tests, developed TDD.
  • Syntax support for Access, SQLite, MSSQL and Firebird. Additional syntax support can be added upon request, given enough time (:
All in a convenient Nuget package you can use from your .NET application (install-package peanutbutter.databasehelpers), irrespective of target language. PeanutButter.DatabaseHelpers was developed and is maintained in VB.NET simply because of its origins, but that really doesn't matter to you as the consumer (:

Sure, there are features which are missing. This library has been built very much on the premise of extending on requirement. I hope that it can be helpful for someone else though. It has been used in at least 5 decent-sized projects.

I welcome feedback and will implement reasonable requests as and when I have time. Like the rest of PeanutButter, DatabaseHelpers is licensed BSD and you can get the source from GitHub.

What's new in PeanutButter?

Retrieving the post... Please hold. If the post doesn't load properly, you can check it out here: https://github.com/fluffynuts/blog/...