It's been over six months since my last post here because I've been slack and I've been busy. Also, I've found a little time to spend on PetaPoco.
After a very busy 2011, I took the first couple of months of 2012 off and did pretty much nothing - at least nothing to do with software development - just alot of unwinding and I feel all the better for it.
Since then I've been working on a few different projects, including new version of Cantabile, some contract work doing mobile development for iOS and Android, and more recently I've been playing with OpenGL, Mono, MonoTouch and MonoDroid with thoughts of maybe doing a mobile game (it's been along time since I did any games programming).
The question I keep getting asked however is when will there be a new version of PetaPoco? Well firstly I'm somewhat reluctant to change PetaPoco too much - simply because I want it to stay as simple as possible and well, I like it the way it is. If you were hoping to see PetaPoco grow into something bigger, more feature rich, then I'm sorry to disappoint - but that's simply missing the point of what PetaPoco is. Also since none of the projects I'm currently working on use PetaPoco it's easy to just leave well enough alone.
That said I have found some time to start on a new version - which will be called v5. Even though there's nothing major about it, I have opted for a major version number bump because it won't be drop-in backwardly compatible.
Dropping the Single C# File Approach
The first thing I've done with v5 is to forget about trying to maintain the whole thing in a single C# source file. Similarly I'm dropping the fascination with trying to keep the line count as small as possible. These ideas served well to keep PetaPoco tiny during its inception, but really serve no practical purpose moving forward.
So the project is now a separate assembly and the original PetaPoco.cs source file has been split up into a series of source files (one class/interface/enum per file) and grouped into folders - all of which means the project is much easier to navigate around and therefore easier to maintain.
But I Like a Single C# File
Although for maintenance purposes having the code base in separate source files is a great, from the point of view of using it in a project there's a certain appeal to being able to drop in a single source file and not having to worry about assembly dependencies. So, I've knocked together a tool that munges everything back into a stand-alone PetaPoco.cs file. Best of both worlds!
CSJ (for CSharp Join) is a simple command line tool which you'll find in the PetaPoco solution that can join a bunch of C# files into a single file. It works well enough for what I need for PetaPoco, but might work for other simple projects too.
CSJ is run automatically by the PetaPoco project during it's post-build phase.
Because of my previous line count obsession I had been reluctant to do XML documentation comments for PetaPoco. Now that it's broken up into separate files I now feel like there's "room" for these.
The XML documentation on all the public parts of PetaPoco is now complete, however... my eyes glazed over and my brain shut-down as I did it - there could be some weird comments in there.
New Mapper API
Turning PetaPoco into an assembly has some ramifications - particularly in relation to the static Database.Mapper property. As an assembly, there's the possibility of it being used by two other assemblies at the same time and if both wanted to register type mappers it would be a case of last in best dressed.
So the old Database.Mapper property has been removed and replaced with a new
Mappers class through which IMapper's can be registered - associating a mapper with either a specific POCO type, or for all the types in an assembly.
Aside from how they're registered the IMapper interface has also had a bit of clean up and PetaPoco's automatic built-in mapping is now implemented as a mapper itself. See the IMapper interface for more on this.
This feature was always a bit of hack. Some DB providers return date time values with a DateTimeKind of Unknown. The ForceToUtc option simply changes the returned values from Unkown to DateTimeKind.Utc - without actually changing the date value.
In PetaPoco 4, this was an option on the Database class - now it's an attribute of the POCO property. eg:
Column[ForceToUtc = true]
Another important change... ForceToUtc used to be true by default, now it's false.
As mentioned above, some things have been renamed for consistency:
- Value -> PrimaryKey
- sequenceName -> SequenceName
- autoIncrement -> AutoIncrement
- Value -> TableName
Tuples for Dictionary Keys
In PetaPoco v4 I was lazy with keying the internal dictionaries that PetaPoco uses. Instead of declaring key objects and writing to associated Hash calculations I just dumped all the key values into a string and used that as a key. With later versions of the runtime an easier (and I presume faster) approach is to use Tuples - which is what PetaPoco now does.
The downside to this is that PetaPoco now requires .NET 4.0. To get it running on earlier versions should just require re-implementing some compatible Tuple classes, but I just haven't got around to it yet.
Other Internal Changes
Internally, PetaPoco has also had a bit of rework/refactor/cleanup:
The old DBType property has been replaced with an abstract DatabaseType class that provides database engine specific functionality. Old
if this database do this else do thattype code has been replaced with calls to the DatabaseType class. (See the DatabaseTypes folder in the solution for more on these)
There's a new Cache classe that simplifies the caching of various objects within PetaPoco.
Lots of other minor bits and pieces.
Pull Requests Merged
At this point, the main functional changes are the following pull requests that have now been merged:
- Replace column names that conflict with CSharp keywords automatically
- Add Page
override to support user defined SQL for Count and Paging
- Fix for issue #91 - Template was selecting the clustered index, not the primary key.
- Check connection state prior to Open() to avoid error: System.InvalidOperation
- Change rxOrderBy Regex and logic to be less greedy during Page
query rewrite to support sub-select ordering
- Add IsNew() Support for PK of Type Guid
- Fix: ensure the primary key value is returned from Insert() when the primary key column is not an autoincrement.
- Fix for Issue #81
- Speeded up mapping with types containing enums.
- Added fix for uint columns in SQLite
- Allow Nullable T in ExecuteScalar
- Fix for crash which would occur when trying to save more than 4000 characters into a SQLServerCE NText column
(Tip: if you want to see something fixed in PetaPoco, your best chance is to submit a pull request).
Here's a quick check list of things to consider/remember if upgrading from PetaPoco 4 to 5.
- If you need pre .NET 4 support, abort now. (or write some tuple classes as described above)
- Get the latest version from GitHub on the v5 (not master) branch
Decide on whether you prefer the Assembly or Single Source File version of PetaPoco.
- If you want the assembly version you'll need to build the PetaPoco project in the supplied solution. Remove PetaPoco.cs from your existing project and add the assembly reference.
- If you want to continue using the Single Source File, just copy the new PetaPoco.cs over the old one.
- If you're using custom mappers, you'll need to switch from assiging the Database.Mapper property to calling Mappers.Register().
- You might get build errors on some attribute properties that have been renamed. Typically these are just upper/lower case issues and should be easily fixed.
- If you're using ForceToUtc option, be warned. You'll need to explicitly decorate all DateTime Columns with the appropriate attribute or, write a custom mapper to do it.
- Cross your fingers :)
All of this is available in a new 'v5' branch on GitHub, but shouldn't be considered production quality. Feel free to grab it and give it a go and let me know what you think, but more importantly what's broken. Once I'm confident that it's stable I'll put up a new build to Nuget.
What's this about an iOS Game?
Yes, I've been doing some iOS game development. Nothing too fancy, but certainly fun - I might post some info about this soon.