Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

What’s Data::Mapper?

Slide 6

Slide 6 text

Sort of an ORM Simple & Clean

Slide 7

Slide 7 text

Why Yet Another ORM?

Slide 8

Slide 8 text

Using DBI Directly Full Stack ORM The Middle Way

Slide 9

Slide 9 text

API Design Simple Convention Performance Model for Every Data

Slide 10

Slide 10 text

An implementation of Data Mapper Pattern

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

Characters

Slide 14

Slide 14 text

Adapter Mapper Data

Slide 15

Slide 15 text

Mapper User Blog Entry User Blog Entry Adapter Data

Slide 16

Slide 16 text

Mapper User Blog Entry User Blog Entry Adapter Data

Slide 17

Slide 17 text

Adapter Database External API Memcached etc.

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

Mapper HashRef to HashRef Maps by Schema

Slide 20

Slide 20 text

Data::Mapper Convention

Slide 21

Slide 21 text

Create Find Search Update Delete Basic CRUD

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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()

Slide 24

Slide 24 text

Usage

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

# 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

Slide 33

Slide 33 text

Advanced Usage

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

# 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)

Slide 37

Slide 37 text

# 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)

Slide 38

Slide 38 text

# 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)

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

Any Questions?