Beyond the ORM - RuLu Conf 2012

E864e5088627498df8f9b911a9bc3219?s=47 Piotr Solnica
June 24, 2012
1k

Beyond the ORM - RuLu Conf 2012

E864e5088627498df8f9b911a9bc3219?s=128

Piotr Solnica

June 24, 2012
Tweet

Transcript

  1. Beyond the ORM an introduction to DataMapper 2 RuLu 2012

    Sunday, June 24, 12
  2. Piotr Solnica • codebenders.com • solnic.eu • github.com/solnic • @_solnic_

    Sunday, June 24, 12
  3. 4 Facts about This Talk • It has 2 sections:

    “ActiveRecord Retrospective” and “DataMapper 2” • It has 2 obligatory pictures of a cat • It has only 1 quote from Martin Fowler’s PoEAA book • It has only 16 code examples Sunday, June 24, 12
  4. ActiveRecord Retrospective Sunday, June 24, 12

  5. ActiveRecord Pattern Facts Sunday, June 24, 12

  6. Active Record Pattern Facts • Simple ORM Pattern • Designed

    for simple usecases where the business domain is simple. ie. basic CRUD • Mixes together data & behavior • 1:1 mapping between database schema & objects (means tight coupling with the db) Sunday, June 24, 12
  7. ActiveRecord in Rails Sunday, June 24, 12

  8. class User < ActiveRecord::Base end Active Record in Rails Sunday,

    June 24, 12
  9. Active Record in Rails (User.methods.sort - Object.methods.sort).count # => 391

    391 new public class methods... Sunday, June 24, 12
  10. WHAT??!! I’m perfectly fine!!! Sunday, June 24, 12

  11. • Persistence • Validations • Associations • Life cycle hooks

    • Typecasting • Mass-assignment security • ...and much much more! Active Record retrospective Sunday, June 24, 12
  12. Active Record retrospective • Slow test suites • Lack of

    real unit tests • God objects • Code hard to reuse and extend • Code hard to refactor Sunday, June 24, 12
  13. I don’t think I can take it Anymore! Sunday, June

    24, 12
  14. I don’t care if we can create a blog in

    15 minutes Sunday, June 24, 12
  15. but I do care if we can work on a

    project for 15 months and keep it in a good shape Sunday, June 24, 12
  16. DataMapper 2 Sunday, June 24, 12

  17. DataMapper 2 “A layer of Mappers that moves data between

    objects and a database while keeping them independent of each other and the mapper itself.” Martin Fowler Sunday, June 24, 12
  18. DataMapper 2 Repository Mapper & Session Domain Model Validation Serialization

    Extensions Sunday, June 24, 12
  19. Domain Model Sunday, June 24, 12

  20. Domain Model class City attr_reader :name, :lat, :lng def initialize(attributes)

    @name, @lat, @lng = attributes.values_at( :name, :lat, :lng ) end end Sunday, June 24, 12
  21. Domain Model class CityMapper < DataMapper::Mapper map :name, :lat, :lng

    end Sunday, June 24, 12
  22. Domain Model city = City.new( name: 'Kraków', lat: 123456.789, lng:

    987654.321 ) Sunday, June 24, 12
  23. Domain Model class GeoLocation include Virtus::ValueObject attribute :lat, Float attribute

    :lng, Float end class City include Virtus attribute :name, String attribute :location, GeoLocation end Sunday, June 24, 12
  24. Domain Model class CityMapper < DataMapper::Mapper map :name map :location,

    to: [ :lat, :lng ] end Sunday, June 24, 12
  25. Session Sunday, June 24, 12

  26. Session class Person include Virtus attribute :name, String attribute :city,

    City end Sunday, June 24, 12
  27. Session class PersonMapper < DataMapper::Mapper map :name has 1, :city

    end Sunday, June 24, 12
  28. Session city = City.new( name: 'Kraków', location: { lat: 123456789.123,

    lng: 987654321.987 } ) person = Person.new(name: 'Piotr') Sunday, June 24, 12
  29. Session DataMapper.session do |session| session.track(city) session.track(person) person.city = city session.insert(person)

    session.commit end Sunday, June 24, 12
  30. Repository Sunday, June 24, 12

  31. Repository Repository Relation Optimizer Datastore Adapter Sunday, June 24, 12

  32. Repository • Complete support for all relational algebra operations •

    All operations can be run in-memory • Can be extended to support any kind of a datastore • Can be used with multiple different databases • Designed to support per database optimizations Sunday, June 24, 12
  33. Repository relation = Veritas::Relation.new([ [ :id, Integer ], [ :name,

    String ], [ :color, String ] ], [ [ 1, 'Nut', 'Red' ], [ 2, 'Bolt', 'Green' ], [ 3, 'Screw', 'Blue' ], [ 4, 'Screw', 'Red' ], [ 5, 'Cam', 'Blue' ], [ 6, 'Cog', 'Red' ], ] ) Sunday, June 24, 12
  34. Repository # projection new_relation = relation.project([ :id ]) # removal

    new_relation = relation.remove([ :name ]) # rename new_relation = relation.rename(id: :other_id, name: :other_name) # restriction new_relation = relation.restrict { |r| r.color.eq('Red').or(r.color.eq('Blue')) } # natural join new_relation = relation.join(other) Sunday, June 24, 12
  35. Repository include Veritas adapter = Adapter::DataObjects.new( "postgres://localhost/test") header = [

    [ :id, Integer ], [ :name, String ], [ :color, String ] ] relation = Relation::Base.new( 'items', header) gateway = Relation::Gateway.new( adapter, relation) Sunday, June 24, 12
  36. Repository new_relation = gateway.restrict { |r| r.color.eq('Red').or(r.color.eq('Blue')) } new_relation.to_a #

    SELECT "id", "name", "color" # FROM items # WHERE ( # "color" = 'Red' OR "color" = 'Blue' # ) Sunday, June 24, 12
  37. What’s Done Sunday, June 24, 12

  38. What’s Done • Veritas • Veritas DataObject Adapter for PostgreSQL

    • Veritas Optimizer • Virtus (Domain Model features) Sunday, June 24, 12
  39. Work in Progress Sunday, June 24, 12

  40. Work in Progress • “write” support for Veritas • Mapper

    • Session/Unit of Work Sunday, June 24, 12
  41. Work in Progress • Validations • Migrations • Constraints •

    Extension Interfaces • More Veritas adapters (sqlite, MySQL, MongoDB, Riak etc.) Sunday, June 24, 12
  42. Development Process Sunday, June 24, 12

  43. Development Process • All “levels” of API are treated with

    the same amount of care & love • Using metric tools to verify code quality • Mutation testing with Heckle • 100% YARD documentation coverage Sunday, June 24, 12
  44. Virtus Project on CodeClimate Sunday, June 24, 12

  45. Resources • https://github.com/datamapper/dm- core/wiki/Roadmap • https://github.com/dkubb/veritas • https://github.com/dkubb/veritas-do- adapter •

    https://github.com/solnic/virtus • https://github.com/solnic/dm-mapper Sunday, June 24, 12
  46. THANKS! Sunday, June 24, 12