Tuesday, November 16, 2010

Mapping Classes to Flexible Schemas

The Problem: Schemas change signature over the lifetime of the schema. So, at a single record level, the schema for the entire dataset can be modified just by adding a property to the single record. Now you have a schema that has some clean rules implicitly with a single record that is an exception to the clean rule. The rules just bent a little bit and if you had a class that mapped getters and setters or a DAO to that schema, it is now broken for the exception record.

The solution: Allow the classes mapped to the schema to mutate according to the mutations in the schema. So, if  you could have a class that when instantiated looked at its model and was able to inspect or discover according to that model what the class' data access signature should be and allow that class to create that signature, then you would have a class that solves the problem of the mutating signature.

Case in point: A form where n custom elements are allowed. So, if I have a form where people are allowed to add favorites and those favorites can be of any user specified type, then I have a model being created according to an unknown or less known context. So, the user says "I have a favorite Movie, and I have a favorite Song, and I have a favorite Californian Bordeaux, then how in the world could we predict that and create a model according to that without a bunch of silly aggregation at the class level? Instead, we let the user modify their User model which at first looked like:
{"FirstName":"bob","LastName":"smith", "favorites":[]}
and now that they modified it, it looks like:
{"FirstName":"bob","LastName":"smith", "favorites":{"Movie":"Troll","Song":"Love Song","Northern California Bordeaux":"Frogs Leap"}}

What we do is we have our class of Person inspect this record and decide what its getters and setters will look like like so:
getFirstName, getLastName, getFavorites, getFavoritesMovie.

I ran into this issue while using Node.js and MongoDB. I was using the Server Side Javascript Library from MooTools. In a subsequent post I will show how I solved this issue within this technical context but I will show how simply it can be simplified using just MooTools and a mock document from MongoDB.