$30 off During Our Annual Pro Sale. View Details »

Data::Mapper

 Data::Mapper

My presentation about Data::Mapper at Kyoto.pm #1 on 2012-03-17. Data::Mapper is a simple ORM and a implementation of Data Mapper Pattern described in PofEAA.

Data::Mapper is available at https://github.com/kentaro/data-mapper

Kentaro Kuribayashi

March 17, 2012
Tweet

More Decks by Kentaro Kuribayashi

Other Decks in Technology

Transcript

  1. Data::Mapper
    Kyoto.pm #1
    2012-03-17
    id:antipop / @kentaro

    View Slide

  2. id:antipop
    @kentaro
    Programmer
    Ikemen
    Perler/Emacser/Hatena
    Kentaro Kuribayashi
    One of Representatives in Japanese
    IT industry

    View Slide

  3. View Slide

  4. View Slide

  5. What’s
    Data::Mapper?

    View Slide

  6. Sort of an ORM
    Simple & Clean

    View Slide

  7. Why Yet Another ORM?

    View Slide

  8. Using DBI Directly
    Full Stack ORM
    The Middle Way

    View Slide

  9. API Design
    Simple Convention
    Performance
    Model for Every Data

    View Slide

  10. An implementation of
    Data Mapper Pattern

    View Slide

  11. Maps Data Between
    DB and In-memory
    Data
    Isolating Them from
    Each Other
    http://martinfowler.com/eaaCatalog/dataMapper.html

    View Slide

  12. An object that wraps a row in a
    database table or view,
    encapsulates the database
    access, and adds domain logic
    on that data.
    http://martinfowler.com/eaaCatalog/activeRecord.html

    View Slide

  13. Characters

    View Slide

  14. Adapter
    Mapper
    Data

    View Slide

  15. Mapper
    User
    Blog
    Entry
    User
    Blog
    Entry
    Adapter Data

    View Slide

  16. Mapper
    User
    Blog
    Entry
    User
    Blog
    Entry
    Adapter Data

    View Slide

  17. Adapter
    Database
    External API
    Memcached
    etc.

    View Slide

  18. Data
    Data::Mapper::Data
    POPO
    (Plain Old Perl Object)

    View Slide

  19. Mapper
    HashRef to HashRef
    Maps by Schema

    View Slide

  20. Data::Mapper
    Convention

    View Slide

  21. Create
    Find
    Search
    Update
    Delete
    Basic
    CRUD

    View Slide

  22. Adapter
    Retrieves Data from
    Somewhere and Returns It as
    a HashRef
    Data
    Hash-based Object
    Knows Schema Info

    View Slide

  23. Table <-> Data
    user <-> User
    user_info <-> UserInfo
    Table <-> Data Class
    user <-> D::M::Data::User
    user_info <-> D::M::Data::UserInfo
    (Customizable by D::M#data_class()

    View Slide

  24. Usage

    View Slide

  25. my $handler = DBIx::Handler->new(...);
    my $adapter =
    Data::Mapper::Adapter::DBI->new({
    driver => sub { $handler->dbh }
    });
    my $mapper = My::Mapper->new({
    adapter => $adapter
    });
    Instanciate

    View Slide

  26. Mapper Adapter
    DBI
    API
    etc.
    adapter() driver()

    View Slide

  27. my $data = $mapper->create(user => {
    name => 'kentaro',
    age => 34
    });
    #=> $data is a Data::Mapper::Data-
    based object
    Create

    View Slide

  28. $data = $mapper->find(user => {
    name => 'kentaro'
    });
    #=> $data is a Data::Mapper::Data-
    based object
    Retrieve

    View Slide

  29. $result = $mapper->search(user => {
    age => 34
    }, {
    order_by => 'id DESC'
    });
    #=> $result is an ArrayRef of
    Data::Mapper::Data-based object
    Search

    View Slide

  30. # Updates params like below
    $data->param(age => 35);
    my $sth = $mapper->update($data);
    $sth->rows; #=> 1
    Update

    View Slide

  31. my $sth = $mapper->delete($data);
    $sth->rows; #=> 1
    Delete

    View Slide

  32. # Data to Table
    sub mapped_params {
    my ($self, $data) = @_;
    my $table = $self-
    >to_table_name($data);
    my $schema = $self->adapter->schemata-
    >{$table}
    or Carp::croak("no such table:
    $table");
    # snip
    }
    Schema

    View Slide

  33. Advanced
    Usage

    View Slide

  34. sub create {
    my ($self, $name, $args) = @_;
    my $content_type =
    File::MimeInfo::Magic::mimetype($args->{filename});
    # $self->driver is a Fule::S3 object
    my $res = $self->driver->create_object_from_file(
    $name, $args->{key}, $args->{filename}, {
    content_type => $content_type,
    'x-amz-acl' => $args->{acl},
    }
    );
    +{
    bucket => $name,
    key => $args->{key},
    type => $content_type,
    }
    }
    Adapter for
    External API

    View Slide

  35. # How can we implement below?
    $user->blog;
    $blog->entries;
    Relation
    (Under Considering)

    View Slide

  36. # Mapper
    sub map_data {
    # snip ...
    my $obj = $data_class->new($data);
    $obj->SOMESPECIALMETHOD($self)
    if $obj->isa('Data::Mapper::Data');
    $obj;
    }
    # Data
    sub SOMESPECIALMETHOD {
    my ($self, $mapper) = @_;
    $self->{author} = $mapper->find(author => {
    id => $self->param('author_id')
    });
    }
    Relation
    (Idea 1)

    View Slide

  37. # Data
    sub mapper {
    my ($self, $mapper) = @_;
    $self->{_mapper} = $mapper
    if defined $mapper;
    $self->{_mapper};
    }
    # Mapper
    sub map_data {
    my $self = shift;
    my $data = $self->SUPER::map_data(@_);
    $data->mapper($self);
    $data;
    }
    Relation
    (Idea 2)

    View Slide

  38. # Data
    sub mapper {
    my ($self, $mapper) = @_;
    $self->{_mapper} = $mapper
    if defined $mapper;
    $self->{_mapper};
    }
    # Mapper
    sub map_data {
    my $self = shift;
    my $data = $self->SUPER::map_data(@_);
    $data->mapper($self);
    $data;
    }
    Relation
    (Idea 2)

    View Slide

  39. TODO:
    Relation
    (But Should It Be Supported by Module?)
    Master/Slave
    Unit of Work

    View Slide

  40. Available on GitHub
    https://github.com/kentaro/data-mapper

    View Slide

  41. Data::Mapper:
    Recap
    • Is a Simple ORM
    • Just Defines
    Minimum Conventions
    • Deals with Any Data
    from Anywhere

    View Slide

  42. Any Questions?

    View Slide