Showing posts with label mongodb. Show all posts
Showing posts with label mongodb. Show all posts

Tuesday, 21 July 2015

Using the Model-Store pattern in Inversion (part 5)

This post is the fifth in a series about using a Model-Store pattern in the Inversion behavioural micro-framework for .Net (see: https://github.com/guy-murphy/inversion-dev).
The first part can be found here.
The second part can be found here.
The third part can be found here.
The fourth part can be found here.

Aftermath


Looking back, I might as well have titled this essay - "I hate ORMs".

Firstly, because I really, really do - I think they are at the root of many evils in .Net software architecture. That's not to say that its the ORMs fault, because it really isn't. However, time after time we are told to "just use" Entity Framework or N-Hibernate because that's what Microsoft or the big boys have blogged about, and time after time I see people getting into the same mess with a half-cocked Repository pattern, absurdly heavyweight models and bloody DTOs springing up all over the place. What I want is a clean, quick, safe and lightweight pattern of data access, and an ORM has never convinced me that it is any of these things because people tend to abuse the functionality it provides without thinking about the consequences or that there might be other ways to approach data access.

Secondly, I didn't actually need to say that this was using Inversion, because Model-Store can be done in any .Net framework. However, it's been useful to write the foundations of the Inversion.Data namespace by considering the paths that writing this article has led me down.

The views in this set of articles almost feel heretical when looking at the current "best practice" of .Net application development. Having an immutable model POCO and a lightweight store (which eschews ORM-like functionality) shifts complexity away from the data access implementation, forcing any business logic back to the application where (in my opinion) it belongs. Data access should be dumb, MUST be dumb, if the application is to be agnostic about the storage technology to be used. This massively increases the platform and language options available for porting and the development of new features. I would counsel avoiding relying upon the features of a particular storage medium, because you never know when that medium could become suddenly unsuitable or unavailable.

Model objects are best designed very closely to the underlying table or document structures. This is for the simplicity of maintenance and the ease of introduction to new development staff. A Model should remain at a level of abstraction such that the properties would be the same across common types of database representation. Therefore, an application that uses this pattern can achieve granular control over the strategies used for reading, writing and updating individual data classes whilst also remaining agnostic to storage technology choices.

When developing the MyOffers.co.uk data analytics engine, we tended to write Stores for at least two storage mediums, e.g. MS Sql Server and Redis and/or MongoDB. This forced us into keeping data access straightforward while letting us concentrate on what the application actually needed to accomplish. These same patterns helped us again when writing a cloud-based quiz engine that would operate at scale and the new version of the website application. It forms part of a discipline that assists what I believe to be a fast and clean way of considering modern system architecture.

Immutable Models and CQRS/Event-Sourcing


There are other benefits that immutable Models can bring. If you take the basic tenet that a Model is immutable, then it follows that any change that is required to a Model can be represented as a separate thing. This is the basis of an architecture which gives CQRS-like benefits to an application that uses immutable Models in combination with read-only, optimised Model Stores, with changes persisted in the form of Events to write-capable Stores which could have a completely different storage medium that is optimised for write, thus separating the reads (a Query) from the writes (a Command).

This helps support eventual consistency, because any changes must be persisted explicitly and the source that the read-optimised Store fetches from can be lazily updated by a mechanism that is in the background. With this architecture, concurrent threads are guaranteed to read the same value when referencing an object, and modifications can be made without having to worry about locking or making a local copy.

Ending


It is not necessary to use the whole of Model-Store to get these advantages. However, the Store part of the pattern provides an efficient way of packaging data access which can use the immutable Model objects, and shows us that when implementing a DAL in the .Net ecosystem there are other options than Repository patterns and ORMs like Entity Framework or N-Hibernate.

If you haven't agreed with me so far, then perhaps the most compelling thing I can offer is that, most of the time, an application need only read what the values of a Model object are; updates and writes are scarce by comparison. Why weigh your application down with the ability to track changes in an object when you don't use it in most operations?

If you design your application to make changes explicitly then you can take advantage of the benefits of lightweight data access.

I've wanted to document some of my thoughts about this pattern for a while, and I do hope that some of you have stuck through to the end. There are many things that can be pointed to in this set of arguments which other developers may not agree with, and that's fine. As I said, this style of pattern may not be for you. However - I have seen it work in small, medium and production-scale systems, making them fly, whilst also providing a great deal of freedom as a developer.

At the very least - please check out the Inversion framework. Full disclosure being that I'm a major contributor for it and I am using it very happily in the production of a large, automatically scaling cloud-based system for a major institution at the moment, including the bits and pieces you will find in the Inversion.Data namespace.

Dream large.

Sunday, 12 July 2015

Using the Model-Store pattern in Inversion (part 4)

This post is the fourth in a series about using a Model-Store pattern in the Inversion behavioural micro-framework for .Net (see: https://github.com/guy-murphy/inversion-dev).

The code that I have been developing as part of this article series can be found at https://github.com/fractos/inversion-data

The first part can be found here.
The second part can be found here.
The third part can be found here.

Using the Store


In this instalment, I'm going to show you what using the pattern looks like. I'll put together a few example functions that use the IUserStore interface to access and manipulate data stored in an underlying MongoDB instance.


Configuring and Instantiation



We are going to use the MongoDBUserStore class that I showed you in the previous article to perform operations in MongoDB. To instantiate it, we will need a few details that describe the MongoDB connection-string, the database name and the name of the collection used for users.

I am using a local MongoDB server, which has a database called 'test' and I want to access model objects in a collection called 'users':



Those details can then be passed to the MongoDBUserStore constructor:



But since this is an IDisposable and we only actually care about the interface methods, then more correctly we should be calling it like this:



At which point we are off to the races.

However, the Store could be gained by dependency injection behind an interface, or fetched from a service container (such as Inversion.Naiad, which implements Inversion.Process.IServiceContainer). I'll try and cover the use of IServiceContainer in a separate article, but the call might look something like this:



By using interfaces alone, you can keep your code free from references to the assemblies needed for accessing MongoDB, keeping the main application as agnostic as possible. All the code cares about is the IUserStore interface.

Asking a service container for an object of type IUserStore which has the label "store-user" will cause the container to perform any configuration required according to the instructions that are associated with the service label. The application doesn't have to care about the configuration of the Store because it is handled by the container. This is a form of loose coupling by service location.

The more agnostic your code is about its dependencies, the more flexible your application can be.

Creating a collection of Users in MongoDB


This method assumes that you have a list of User models which are ready to be written to the database. I've included the basic version of instantiating the Store just to keep it simple.



After this call, you should find that the User models have been written into MongoDB, complete with Object IDs.

Read a list of Users from MongoDB


This method will return all the users from MongoDB as a list of User models.

Note that the IEnumerable is converted to an IList with ToList() before the using statement has been terminated (and therefore the Store and its resources disposed) in order to avoid the enumeration code reading a closed connection.



Updating a list of Users


This function iterates through a passed list of User models, modifying their Password property and then writing them back into MongoDB. It makes use of the Mutate method on the User object in order to change an immutable object. The ID of the User model will remain unchanged, however, so the act of writing the data into MongoDB will perform an update rather than an insert.




Deleting a list of Users


This function will delete each of a list of User models from MongoDB.



Next time ...


In the next (and final, so far ...) instalment, I'll wrap up with a conclusion and some thoughts about how this process went.

Saturday, 9 May 2015

Using the Model-Store pattern in Inversion (part 3)

This post is the third in a series about using a Model-Store pattern in the Inversion behavioural micro-framework for .Net (see: https://github.com/guy-murphy/inversion-dev).

The first part can be found here.
The second part can be found here.

Introduction


I finished the last post by describing the base Store for dealing with a MongoDB database. Now I will go through the specialised Store that uses it to perform operations with the User class I introduced in part 1.

Reminder - you can find the source code for this article at https://github.com/fractos/inversion-data.

Forced specialisation of Models


The first thing I need to cover is that I had to rewrite a whole bunch of stuff in this article after trying really hard to make the examples work with the original Model. This is because of the annoying behaviour in MongoDB of it requiring a property which it deserialises the database object ID into. It's not the only database that enforces this kind of thing (I'm looking at you, DynamoDB), and it's also an unwelcome reminder that sometimes we really are at the mercy of the storage gods.

I've also tried hard to make the examples work with simple serialisation and deserialisation to and from the Model's Builder object, but it just doesn't work. The automatic deserialisation forces you to change the original Model and none of my attempts at wrapping the Model in a way that serves as an adaptor seem to work. Maybe there is a way to wrap it, but the extra plumbing just doesn't feel worth the hassle.

As it is, the User class needs an ID, as the operations performed by the specialised Store become over-complicated without one. I've listed the new source of User.cs, below. Note that the ID property is set to a unique value in the User.Builder parameterless constructor, which means that any newly created User object will have a unique ID already assigned.

In order for the ID to be used correctly with the automatic deserialisation in MongoDB's driver, the type of the ID would have to be changed (to ObjectId) and the property itself marked with a Bson-specific attribute (BsonId). However, I'm not willing to do that as it invalidates the whole idea of having a Model class that is agnostic to the storage technology being used.

So I'm going to show you another way.



Another way around - BsonDocuments


As I mentioned in part two, BsonDocuments are objects that represent a piece of BSON data, which is a binary-serialised version of a JSON document peculiar to MongoDB. The driver is very happy dealing with these constructs as they provide a basic representation of the document. This representation is used internally in the database for binary serialisation. I use the BsonDocument method in all my projects that back onto MongoDB.

Properties are accessible by their name, and they can be any one of the primitive types that MongoDB supports which includes strings, dates, numbers, objects (i.e. another document) and arrays.

So, a way of getting around the forced specialisation of a Model type is to provide custom serialisation/deserialisation to and from a BsonDocument as presented and consumed by the MongoDB driver.

To do this, I use extension methods as a tidy solution for compartmentalisation of the conversion methods.

Using extensions to group conversion methods - MongoDBUserEx.cs


This is the static class that sits in the same namespace as the specialised store MongoDBUserStore. Inside are two extension methods - ConvertUserToBson and ConvertBsonToUser. They pretty much do what they say on the tin. Here's the code.



The ConvertUserToBson method extends an instance of the User class and returns a prepared BsonDocument containing a document representation of the User object's data. The document properties are accessed by name, hence the string indexer on doc. The reserved property name "_id" is used to set the document ID which is set from the User object's ID property.

The "username" and "password" document properties are simply set with the respective string values from the User object.

The "metadata" property, however, is set with a different BsonDocument which is made from the contents of the User object's Metadata property. The BsonDocument constructor can take a IDictionary of values and is quite happy to accept the raw Metadata dictionary which is exposed as IDictionary.

The ConvertBsonToUser method extends an instance of the BsonDocument class and returns a populated User object. Again, the document properties are accessed by name and are used to set the values of a User.Builder object. For the ID, the string value of the underlying ObjectId type is used.

The "metadata" property is retrieved as a BsonDocument, and then its Names property is used as the basis of a ToDictionary call which creates the keys and values of the Builder's Metadata object.

The act of returning the User.Builder object implicitly converts it into an immutable User object.

Interface for the User Store - IUserStore.cs


Here is the interface that I will be implementing for the specialised User Store.




The interface is defined as implementing the IStore interface, so certain methods will be expected to be implemented. However, these should be satisfied by the ancestor of our specialised Store - StoreBase.cs.

There is a Get method that accepts a username to search by, returning an immutable User object. Then there is a GetAll method that should return all the items in the database as an IEnumerable of User objects. I reckon the interface could probably do with a Get method that takes a user's ID value as a parameter, but feel free to do that yourselves (one of them will have to be renamed as they both accept a lone string parameter).

Then the Put method, taking an individual User object which will be entered into the database. I'm assuming that Put also serves as an Update operation in this implementation.

Finally there is a Delete operation that accepts a User object as its target to remove from the database.

Specialised Store for our User model - MongoDBUserStore.cs


Now we have the interface and those conversion tools available, we can proceed with the specialised Store for the User model.

I should point out that this Store flagrantly subverts the new, asynchronous capabilities of the MongoDB driver. This is because not all storage technologies will support async/await style calls and one of the main goals of this pattern is to allow any storage technology to be used behind the same interface. Having some implementations use async/await while others do not is therefore a really bad idea because it forms a leaky abstraction - you need to know from outside the component whether it can be called asynchronously. Further, if an async/await call to an IDisposable object is incorrectly executed, then resources could end up being disposed before an asynchronous call has completed. So, I believe that if you are dealing with async/await calls then you should define an explicit interface for them to make it clear to the developer calling the interface that they will be dealing with the side-effects themselves.

    public class MongoDBUserStore : MongoDBStore, IUserStore

The class signature shows that we are inheriting from the basic MongoDBStore class, and we will be exhibiting the behaviour specified in the IUserStore interface.

Constructor and properties


        

The constructor takes the information needed by the base Store - connStr and dbName, and passes them into the base class constructor. It also takes a collectionName argument which is stored in a private, read-only property. It is assumed that this specialised Store for the User object will only be dealing with a single MongoDB Collection.

Start


        

Knowing the name of the collection up front allows us to perform this operation during the Start method, after having called the base implementation to change the Store state. This step retrieves an IMongoCollection object with which we can perform queries and commands upon the named collection.

Get


        

Now we are starting to implement the IUserStore interface with the first method - Get. The first thing to do is to assert whether the Store is in the correct state to perform operations, i.e. whether Start has been called. The AssertIsStarted method is called which you may remember is implemented on the grandparent Store class.

The query itself is performed by calling the Find method of the IMongoCollection we initialised in the Start method. It is passed a BsonDocument that contains the information to evaluate appropriate documents in the collection. In this case, we set the "username" property in the document to the value that we are looking for. Only the first result is needed (or expected), and so the FirstAsync method is called on the result of the Find operation. Because we are wrapping asynchronous behaviour in this implementation, we will wait for the result of the FirstAsync method by accessing it's Result property. Finally, the Result property (which will be of type BsonDocument to match the generic type of the IMongoCollection) has the extension method ConvertBsonToUser called upon it, that will instantiate an immutable User object that contains the values from the document.

That's a lot of behaviour wrapped up in one line. Fluent interfaces like this which libraries like System.Linq allow are fantastic to use (when you know what you are doing), but unwinding the meaning of them by way of explanation can be a time-consuming business.

GetAll


        

The next part of the IUserStore interface to be implemented is GetAll. This simply returns the entire contents of the collection. However, to do that we need to make a query that will return all items, then turn that list of results into an IEnumerable of the correct User objects. More fluency in the calling methods for this gives us those results.

Special note should be taken that the query used is represented by an empty BsonDocument passed to the FindAsync method - no matching criteria means that it matches against all the items in the collection. The result of the Find operation must be transformed into a list and that is performed by the ToListAsync method. Again, we must wait for the result and this gives us a List which then gives us access to the Select method that we can use to call the ConvertBsonToUser method upon each item finally resulting in an IEnumerable that is returned back to the caller.

Put (single User object)


        

We use the MongoDB driver's Replace method to effectively perform an Upsert operation on the database, creating or replacing an existing entry which has the same ID.


Delete


        

And finally the Delete method, giving us all the CRUD operations (provided you don't mind if the Create and Update are represented by the Put method). Again, we use the BsonDocument method of passing the matching criteria into the driver.

Next time ...


In the next part of the series, I'll show you how to use the Store in practice.

Thursday, 30 April 2015

Using the Model-Store pattern in Inversion (part 2)

This post is the second in a series about using a Model-Store pattern in the Inversion behavioural micro-framework for .Net (see: https://github.com/guy-murphy/inversion-dev).

The first part can be found here.

Introduction


In the previous post in this series, I talked about the Model part of the Model-Store pattern; basically POCO (plain old C# objects) with a little extra infrastructure added to give them immutability (i.e. if a value changes then they become a different object with a different reference) and also decoration with Inversion's IData interface, which lets the object be more useful within the Inversion ecosystem.

In this post, I'm going to talk about the IStore interface and how it can be implemented to be a lightweight, efficient data store that uses immutable models.

The code for this post is not contained in the standard Inversion framework repository. Instead, I have created a new repository that contains the Inversion.Data namespace here: https://github.com/fractos/inversion-data

Stores


A Store provides data access for a specific type of storage medium. This could be a database, a filesystem, or anything that you can perform basic CRUD operations upon.

It is generally tied to a particular type of Model, or a limited set of Models that could be described as being within a Bounded Context. This is in order to avoid duplication of access to the Model objects in storage. If a set of Models exist within a Bounded Context then they are not accessed by the rest of a system and so therefore access duplication should not occur. In other situations it is probably best to define a Store that handles as few Model types as possible so that the granularity of configuration could be on a per-Model basis.

In the example from part one of this series, a Store that is implemented for User objects would also cover UserMetadata objects since the UserMetadata class could be a private class within the User class's domain.

Tying a Store to a Model type has connotations. It is advised that the most suitable way of modelling with this pattern is to use simple objects that do not maintain a web of active references to other types of object and which do not have the expectation of these references to be kept up to date automatically by the actions of a DAL. This won't suit everyone's architectural styles.

The Model should only represent the data. The Store should only deal with the translation of that data in and out of a storage medium.

Now I think it's worth talking briefly about what a Store is not.

A Store is NOT a Repository


To reiterate, a Store uses immutable model objects. A Repository keeps track of changes, but a Store does not because immutable objects become a different object if their properties are changed. Changes in the underlying storage medium must be made explicitly by putting a data object back into the Store. Model objects do not have to track changes automatically so they can be primitive classes with no dependency upon libraries such as Entity Framework.

The IStore Interface


This is the basic interface that all Store classes must implement. It covers the following two areas of concern, those being that a Store is a resource and that a Store has state.




Stores are a resource


A Store is something that an application should be able to dip into; a lightweight component that is used only for data access. Once the data access is over, you should be able to throw away the store.

For this reason a Store implements the IDisposable interface. A Store may not have anything to dispose at the end of its use, but this enforces that there is the chance to perform actions at that point.

Stores have state


A Store should guard against misuse. Certain operations may only be valid when the Store is in a particular state. A primary use-case for this is being able to adjust the properties of a connection in a database store before the connection has been fully opened. The general solution for this is to implement a state property that defines whether the Store has been started or stopped explicitly.

For this reason, a Store implements methods that adjust its state and any data access methods should check the current state when they are called, raising an exception if the Store is in an unsuitable state.

The Store state is represented by a simple enumeration - StoreState:




A Store which has never been started will have a state equal to StoreState.Unstarted. When started explicitly, a Store will have a state equal to StoreState.Started. When stopped explicitly, a Store will have a state equal to StoreState.Stopped.

The IStore interface defines two methods for explicitly changing the state of the Store - Start and Stop:

    void Start();
    void Stop();

The IStore interface defines a public get property HasStarted, which should report whether the Store has had Start called upon it and has not yet had Stop called upon it:

    bool HasStarted { get; }

The IStore interface also defines another public get property HasStopped, which should report whether the Store has had Stop called upon it:

    bool HasStopped { get; }

The StoreBase abstract base class


This abstract class provides a base upon which to build other implementations of a Store, as we will see below.



The private property _state keeps track of whether the Store has ever been started, or is currently started or stopped. The initial value is StoreState.Unstarted. Only methods in the base class can adjust the _state property since it is private. Overriding methods for Start (and Stop) must call their base implementations as part of their instructions.

The public property HasStarted can report whether the Store is in a state where it can perform operations, i.e. whether the _state property is equal to StoreState.Started.

The public property HasStopped can report whether the Store is in a stopped state, i.e. whether the _state property is equal to StoreState.Stopped.

The public method Start is used to explicitly start any resources that the Store implementation needs. If the Store is already started, then an exception is raised.

The public method Stop is used to explicitly stop any resources that the Store implementation needs. This should be called by a descendant implementation of Dispose, and since both Stop or Dispose could be called explicitly (by a call from user code) or implicitly (when leaving a using statement block), then the Stop method does not try to raise an exception if the Store is in an incompatible state. Instead, it changes the state to Stopped if the Store is currently started. Generally, it is useful to keep a flag that records whether Dispose has been called already, and if the flag is set then no action is taken. This protects against the situation of a call to Stop being followed by an implicit call to Dispose. However, this may not be necessary if a Store has nothing to do during its disposal phase.

It is the descendant implementation's responsibility to have the correct behaviour within its overridden instructions for Stop and Dispose, and this is especially important for database connection types which must have their connection objects disposed (e.g. SqlClient). For this reason, Dispose is marked as abstract so that the descendant is forced to provide some form of implementation.

I have also added a simple method for asserting whether the Store has been started called AssertIsStarted. This will be put to a lot of use in our specialised Store.

StoreStartedException is a simple wrapper for ApplicationException. It is used to emit an exception from the Store when trying to start it if it is already in a started state:



Similarly there is a StoreStoppedException which should be emitted from a data access method when the Store is found to be in a stopped state.

Also, StoreProcessException - an instance or descendant of which should be emitted from a Store method if something goes wrong during processing a call, although that's not a hard and fast rule, just a useful convention.

I've omitted the source code for these as they are exactly the same as StoreStartedException apart from the name, but you can find it in the GitHub repository for Inversion.Data. The differentiation between them is just an exercise in taxonomy.

Now we are ready to see how a Store can be implemented for a particular storage technology, and then show how it can be used.

Implementing a Store for MongoDB


You probably already know this, but MongoDB by 10Gen is a cross-platform, "NoSQL" style document database which is used by many projects and applications across the globe. I use it extensively for most of my side-projects as a primary storage mechanism. My experience with it has led me to appreciate a horses-for-courses approach to databases - MongoDB can be a very quick leg-up to a working system and in production it is very stable and well-behaved, clustering notwithstanding. If you're looking to get into document databases then it's a really good starting place.

It's pretty straightforward to set up on Windows or Linux. Check out its home site https://www.mongodb.org/ and also the very good admin UI Windows application MongoVue at http://www.mongovue.com/

A word about namespaces


The projects and assemblies that I am writing as part of this tutorial are arranged in a particular way. Essentially - Store, IStore, StoreState and the Exception classes are sitting in a core assembly called Inversion.Data. But my specialised classes, i.e. the Store and support classes that I am about to make live in a project called Inversion.Data.MongoDB. This has a default namespace of Inversion.Data and a Store folder within it, which means that by referencing the assembly Inversion.Data.MongoDB the Inversion.Data namespace is augmented with the contents of the root of the project, in this case that means the MongoDBStore class. The Store has the technology name used as a prefix to its class name to differentiate it within the namespace.

This convention is in place because we (Guy Murphy and I) have found that it aids a composition-by-augmentation approach; if you include an assembly with a particular technology stack, then it will appear within a well known namespace. No special knowledge of namespaces that are tied to a technology is required and, frankly, it just feels neater.

The base MongoDB implementation - MongoDBStore.cs


To use MongoDB, I start by adding the NuGet package "MongoDB.Driver". That package loads a couple of dependencies - MongoDB.Bson and MongoDB.Core.

The code for the MongoDBStore class is as follows:



This gives us some very basic functionality that can be used to build our specialised Store for a particular Model type.

The constructor for MongoDBStore requires the passing of both a connection string argument and a database name. I've made the base store centric around the named database in MongoDB because this allows basic functionality with collections that would be common across Stores that might want to access more than one collection within a database. Frankly, it's as good a place as any to put this level of organisation. If you feel that you want to change that around then go for it. The connection string and database name are stored in read-only properties which are private as they are unlikely to be of use to anything outside of the base implementation. Connection strings and database names are things that shouldn't leak outside of the Store's abstraction as they are a configuration concern.

Start has been overridden, taking the opportunity to create a MongoClient instance from the connection string and then use that client to gain an IMongoDatabase reference to the named database. The base Start method is called in order to correctly set the state of the Store. The result is that we now have an active MongoClient instance and a stored reference to the required database that is ready to go.

Stop has not been overridden as there is no action to take when stopping.

Similarly, Dispose has no actual work to do so it simply calls Stop on the base Store.

This basic Store has its index property overridden which allows access by name to a MongoDB collection within a database. The get-accessor performs a quick state check of the Store to determine if it has been started (and thus, whether it is safe to use the Database property), and then returns an IMongoCollection generic of type BsonDocument (objects that represent a piece of BSON data, which is a binary-serialised version of JSON peculiar to MongoDB).

Some OO-purists might want to mark this base Store as abstract, such that it cannot itself be instantiated and must be inherited from before it can perform any work. However, this is a fully working Store providing a basic mechanism for retrieving documents from a named collection, therefore I have not marked it as abstract as it could be put to immediate use as-is.

Next time ...


In the next part of this article, I will go through the specialised Store for our User object - MongoDBUserStore.cs.

Update:
Had to change name of Store to StoreBase to avoid a namespace conflict. Gists updated to reflect this.

Wednesday, 26 February 2014

Bookmarks for 20140226

The careful arrangement of strings, bells, lenses and mirrors I employ to wake me at the appointed time definitely did not work this morning. However, it's a sunny day so here's some bookmarks.

Data modelling with MongoDB (general topic as I've been busy with re-writing bits of Xizi just recently):

http://mongolab.org/topic/?data

Warren Ellis has a new, epic looking graphic novel out (shortly), TREES:

http://www.warrenellis.com/?p=15103

Some Kickstarters of note that I've backed recently:

TimeWatch - Gumshoe and Time Travel RPG thingummy that did ridiculously well:
"You've got a time machine, high-powered weapons and a whole lot of history to save. Welcome to TimeWatch!"
https://www.kickstarter.com/projects/kevinkulp/timewatch-gumshoe-investigative-time-travel-rpg

Project: Dark - A stealth-based tabletop RPG that sounds amazing and that also smashed its funding goal:
"Play fantastic thieves in a fantastical city in this new stealth-adventure tabletop roleplaying game."
https://www.kickstarter.com/projects/wordstudio/project-dark

Hello Ruby - A delightful, almost perfect children's book that teaches kids the basics of programming. I cannot recommend this highly enough.
"Hello Ruby is a children’s book that teaches programming fundamentals through stories and kid-friendly activities."
https://www.kickstarter.com/projects/lindaliukas/hello-ruby

Coffee, Cake and Kisses - Fundraising for the new iteration of the Coffee, Cake and Kink space. Not totally sure about the new name but I understand why they've had to do it; their heart is in the right place and I hope they make it:
"A relationships-focused social design space. Tease your taste buds & stimulate your senses in the place that makes you go mmm."
https://www.kickstarter.com/projects/coffeecakeandkisses/coffee-cake-and-kisses

Also: I've been listening to The Black Keys entire discography for about 5 days now. It helps.

END OF LINE.

Friday, 14 June 2013

Bookmarks for 20130614

"No more miracles, loaves and fishes.
Been so busy with the washing of the dishes."

I'm back. Here's some stuff.

Some useful stuff on the blueimp jQuery.UI FileUpload control:

https://github.com/blueimp/jQuery-File-Upload/wiki/How-to-submit-additional-Form-Data

Twitter Bootstrap is just the best bloody thing ever. It feels like cheating when using it to produce what turn out to be really gorgeous, minimalistic, clean web designs.

https://github.com/twitter/bootstrap

Whole bunch of stuff I should have read BEFORE I started writing Xizi:

http://docs.mongodb.org/manual/core/data-modeling/

IPython Notebook looks like a lot of fun, bit like a live, interactive version of One Note maybe?

http://ipython.org/notebook.html