Slide 1

Slide 1 text

Introduction to DBIx::Lite id:motemen

Slide 2

Slide 2 text

me •id:motemen • motemen ඒإث • Application engineer •DBIx::MoCo maintainer

Slide 3

Slide 3 text

ORM and me •DBIx::MoCo •DBIx::Skinny •Data::Model •Teng

Slide 4

Slide 4 text

DBIx::Lite •AUTHOR cpan:AAR •“Chained and minimal ORM” •cf. DBIx::Class

Slide 5

Slide 5 text

SYNOPSIS

Slide 6

Slide 6 text

Preparation •No classes required to declare •e.g. schemas, row classes •Just use

Slide 7

Slide 7 text

Initialization •Passing $dbh •Using DBIx::Connector my $dbix = DBIx::Lite->new(dbh => $dbh); my $dbix = DBIx::Lite->connect( 'dbi:mysql:dbname=...', $username, $password, { mysql_enable_utf8 => 1, RootClass => 'DBIx::Sunny', }, );

Slide 8

Slide 8 text

CRUD •Call table() to start building query •Returns ResultSet object my $entries = $dbix->table('entries');

Slide 9

Slide 9 text

SELECT •Build ResultSet by method chain •Finally retrieve row objects my $entries_rs = $dbix->table('entries') ->search({ author_id => 1 }) ->order_by('created_at'); my @entries = $entries_rs->all; # SELECT me.* FROM entries AS me WHERE ( author_id = '1' ) ORDER BY created_at my $entry = $entries_rs->limit(1)->single; # SELECT me.* FROM entries AS me WHERE ( author_id = '1' ) ORDER BY created_at LIMIT 1 OFFSET 0

Slide 10

Slide 10 text

INSERT •If the table has an auto- incremented pkey, LAST_INSERT_ID is filled in my $entry = $dbix->table('entries')->insert({ author_id => 47, body => '…', created_at => time(), }); # INSERT INTO entries ( author_id, body, created_at) VALUES ( '47', '…', '1345196410' )

Slide 11

Slide 11 text

UPDATE/DELETE $dbix->table('entries') ->search({ id => [ 2, 3, 5 ] }) ->update({ body => '…' }); # UPDATE entries AS me SET body = '…' WHERE ( ( id = '2' OR id = '3' OR id = '5' ) ) $dbix->schema->table('entries')->pk('id'); $entry->update({ body => '…' }); # UPDATE entries AS me SET body = '…' WHERE ( id = '1' )

Slide 12

Slide 12 text

Components

Slide 13

Slide 13 text

•DBIx::Lite •DBIx::Lite::ResultSet •DBIx::Lite::Row •DBIx::Lite::Schema •DBIx::Lite::Schema::Table

Slide 14

Slide 14 text

DBIx::Lite •Represents a database (connection) •$dbix->{connector} •isa DBIx::Connector •$dbix->{schema} •isa DBIx::Lite::Schema •Generates ResultSet (next)

Slide 15

Slide 15 text

DBIL::ResultSet •Represents a set of database rows •Has most major methods •Does not hold actual data in itself •To retrieve row objects: my @all = $rs->all; my $row = $rs->single;

Slide 16

Slide 16 text

DBIL::ResultSet •Chain methods to build specific result set •search() uses SQL::Abstract •Multiple search()’es joined by “AND” $rs = $dbix->table(…); $rs = $rs->search(\%where); # WHERE $rs = $rs->order_by($col); # ORDER BY $rs = $rs->limit($n); # LIMIT $rs = $rs->select(@cols); # SELECT

Slide 17

Slide 17 text

DBIL::Row •Represents a database row •Simple structure •$row->{data}, $row->{dbix_lite} •$row->hashref •No inflates/deflates •AUTOLOAD method names

Slide 18

Slide 18 text

DBIL::Row •Row operation methods •$row->update(\%cols) •$row->delete •pk needed in schema (next)

Slide 19

Slide 19 text

DBIL::Schema & DBIL::Schema::Table •Represents metadata of tables •(Auto-increment) primary keys •Row classes, ResultSet classes •Has-a, has-many relationships

Slide 20

Slide 20 text

DBIL::Schema & DBIL::Schema::Table •Setting primary key lets row objects’ update methods to work •Use autopk() for auto-inc pk •Give row objects custom methods from the package $dbix->schema->table('entries')->pk('id'); $dbix->schema->table('entries') ->class('My::Row::Entry');

Slide 21

Slide 21 text

DBIL::Schema & DBIL::Schema::Table •Register has-many relations •ResultSet gains relation method $dbix->schema->one_to_many( 'authors.id' => 'entries.author_id' ); my @entries = $dbix->table('authors') ->search({ name => 'motemen' }) ->entries->all; # SELECT entries.* FROM authors AS me INNER JOIN entries ON ( me.id = entries.author_id ) WHERE ( name = 'motemen' )

Slide 22

Slide 22 text

Other features

Slide 23

Slide 23 text

Paging •Paging by offset/limit my $entries_rs = $dbix->table('entries') ->rows_per_page(10)->page(3); $entries_rs->all; # SELECT COUNT(*) FROM entries AS me LIMIT 10 OFFSET 0 # SELECT me.* FROM entries AS me LIMIT 10 OFFSET 20 my $pager = $entries_rs->pager; # => Data::Page

Slide 24

Slide 24 text

JOIN •Use $rs->select_also() to fetch joined tables $dbix->table('entries') ->left_join('authors', { author_id => 'id' }) ->select_also([ 'authors.name' => 'author_name' ]) ->all; # SELECT me.*, authors.name AS `author_name` FROM entries AS me LEFT OUTER JOIN authors ON ( me.author_id = authors.id )

Slide 25

Slide 25 text

Raw DBI access •Internally uses DBIx::Connector#run my $now = $dbix->dbh_do(sub { $_->selectcol_arrayref('SELECT NOW()')->[0] });

Slide 26

Slide 26 text

CAVEATS •“SELECT me.* FROM …” queries •Sometimes need to prefix “me.” to field names •Row classes are not automatically require’d

Slide 27

Slide 27 text

HACKING •Auto-upgrade connection to master •Need to alter DBIx::Lite and produced DBIL::ResultSet •Use Role::Tiny •gist:3378389

Slide 28

Slide 28 text

Sum up •Simple APIs •ResultSet •No need to declare classes, easy to start •Extending may need tricks

Slide 29

Slide 29 text

Questions?