Windows Azure Tables adapter for DataMapper

The Past

Last Friday, we shipped the first Major version (v1.0.0) of the Windows Azure Storage API gem for ruby, started a few months ago by my friend Johnny Halife. As it is an open-source project, I had the opportunity to contribute with:

  • Support for table service to query, get_one, insert, update, merge and delete entities.
  • Support for running against the Storage Developement Fabriq shipped with Microsoft SDK.
  • Signature support for Tables service according to msdn.microsoft.com/en-us/library/dd179428.aspx
  • Support to enumerate, create, and delete tables on give storage account.
  • Give feedback to Improve the support for stacked connection management.

This release of waz-storage for ruby includes numerous features collected thru 0.5.6 to 1.0.0, for more information you can visit the http://waz-storage.heroku.com/ where you will find all the gem documentation, or if you like to read the source code, contribute or giving us feedback you can get it from on http://github.com/johnnyhalife/waz-storage.

The Present

One of the objectives of having Tables support on the gem was to have an interface to interact with Tables and Entities that we can consume from an adapter as we usually do with our favorite ORM written in ruby which is DataMapper.

This is why this weekend was pretty much to make the dream come true, creating a new project on github called dm-waztables-adapter (http://github.com/jpgarcia/dm-waztables-adapter) and spitting some lines of code.

Writing the adapter

As everything in Ruby wonderful world, it was really easy to have a first version running with the features provided by Datamapper.

It took me a few hours to write down 85 lines of code to cover the whole adapter (Create, Read, Update and Delete methods)

Sorry, I’m forgetting the aditional 30 minutes I spent on writing 32 more lines to cover the Migrations stuff. So you won’t worry about creating the tables when you design your models (As Windows Azure doesn’t have support for schemas inside tables, migrations exists just to make sure that you have the tables. It won’t modify attributes of existing data).

Below you will find some code samples. I hope you like it.

Getting started

sudo gem install dm-waztables-adapter --source http://gemcutter.org

Usage

require 'dm-waztables-adapter'

# set up a DataMapper with your Windwows Azure account
DataMapper.setup(:default, { :adapter => 'WAZTables',
                                         :account_name => 'name',
                                         :access_key => 'your_access_key' })

# define a new model
class Guitarist
    include DataMapper::Resource

    property :id, String, :key => true
    property :name, String
    property :age, Integer
end

# set up database table on Windows Azure for a specific model
Guitarist.auto_migrate! # (destructive)
Guitarist.auto_upgrade! # (safe)

# set up database table on Windows Azure for all defined models
Datamapper.auto_migrate! # (destructive)
Datamapper.auto_upgrade! # (safe)

# play with DataMapper as usual
Guitarist.create(:id => '1', :name => 'Ritchie Blackmore', :age => 65)

yngwie = Guitarist.new(:id => '2', :name => 'Yngwio Malmsteen', :age => 46)
yngwie.name = "Yngwie Malmsteen"
yngwie.save

# retrieving a unique record by its id
ritchie = Guitarist.get('1')
ritchie.age # => 65

# updating records
ritchie.age = 66
ritchie.save

# retrieving all guitarists
    Guitarist.all.length # => 2

# performing queries
    older_guitar_players = Guitarist.all( { :age.gte => 50 } )

# deleting records
older_guitar_players.destroy!

TODO

  • Allow users to define the model partition key by using :partition_key => true option on the property.
  • Allow users to set the partition key as an additional attribute of the model with a lambda as default value.
  • Allow users to set the partition key as a method on the model.
  • Implement “in” operator in queries
  • Implement “order” query option
  • Retrieve more than 1000 fields using Windows Azure :continuation_token

Known Issues

  • Like statements are not working since Microsoft service API is throwing a NotImplemented exception when
    using startswith and endswith filters (more information here)
  • There’s no way to tell thru the entity which is the partition key of our entity, so there’s no out-of-the-box load balancing support (for mor info on the tables model that a look at http://msdn.microsoft.com/en-us/library/dd179338.aspx)



Leave a Reply