autoinc is nice
[dbsrgits/dbix-class-introduction-presentation.git] / slideshow.html
index 980fe90..9f136a6 100644 (file)
    <div class="slide">
       <h1>DBIX::Class (aka DBIC)</h1>
       <h3>for (advanced) beginners</h3>
-      <h4>Leo Lapworth @ LPW 2009</h4>
-      <h4><a href="http://leo.cuckoo.org/projects">http://leo.cuckoo.org/projects</a></h4>
-      <div class="handout"></div>
    </div>
 
    <div class="slide">
-      <h1>assumptions</h1>
-      <p>You know a little about Perl and using objects</p>
-      <p>You know a little bit about databases and using foreign keys</p>
+      <h1>Authors</h1>
+      <h4>Originally Leo Lapworth @ LPW 2009</h4>
+      <h4>Amiri Barksdale</h4>
+      <h4>Justin D. Hunter</h4>
+      <h4>Arthur Axel "fREW" Schmidt</h4>
    </div>
 
    <div class="slide">
-      <h1>DBIx::Class?</h1>
-      <ul>
-         <li>ORM (object relational mapper)</li>
-         <li>SQL &lt;-&gt; OO (using objects instead of SQL)</li>
-         <li>Simple, powerful, complex, fab and confusing</li>
-         <li>There are many ORMs, DBIx::Class just happens to be the best in Perl (personal opinion)</li>
-      </ul>
+      <h1>What's up guys?</h1>
+      <div class="notes">
+         <ul>
+            <li>How many people have used any ORM?<ul>
+               <li>In Perl?<ul>
+                  <li>DBIC?</li>
+                  <li>Class::DBI?</li>
+                  <li>Rose::DB?</li>
+                  <li>Fey?</li>
+                  <li>Others?</li>
+               </ul></li>
+               <li>AR?</li>
+               <li>DataMapper?</li>
+               <li>(N)Hibernate?</li>
+            </ul></li>
+         </ul>
+      </div>
    </div>
 
    <div class="slide">
-      <h1>why this talk?</h1>
-      <ul>
-         <li>Help avoid mistakes I made!</li>
-         <li>Help learn DBIx::Class faster</li>
-         <li>Make your coding easier</li>
-      </ul>
+      <h1>Purpose</h1>
+      <p>The purpose of this talk is to show you as many features of
+      DBIx::Class in 40 minutes so that when you need to do something with
+      it later you will know what's possible</p>
    </div>
 
    <div class="slide">
-      <h1>point of note</h1>
-      <p><em>"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." - Brian W. Kernighan</em></p>
-      <p>This talk is about making it easy so we are less likely to get confused</p>
-   </div>
-
-   <div class="slide">
-      <h1>table setup</h1>
-   </div>
-
-   <div class="slide">
-      <h1>example...</h1>
+      <h1>DBIx::Class?</h1>
       <ul>
-         <li>Authors</li>
-         <li>Books</li>
+         <li>ORM (object relational mapper)</li>
+         <li>SQL &lt;-&gt; OO (using objects instead of SQL)</li>
+         <li>There are many ORMs, DBIx::Class just happens to be the best in Perl (personal opinion)</li>
       </ul>
    </div>
 
    <div class="slide">
-      <h1>authors table</h1>
-<pre>CREATE TABLE authors(
-   id   int(8) primary key auto_increment,
-   name varchar(255)
-) engine = InnoDB DEFAULT CHARSET=utf8;</pre>
+      <h1>Meta</h1>
+      <p>These are reasons that are not technical or inherent to
+      the code of DBIC, but are totally awesome things about it.</p>
    </div>
 
    <div class="slide">
-      <h1>tips</h1>
-      <p>Name tables as simple plurals (<strong>add an S</strong>) - makes relationships easier to understand</p>
-      <p>(issue: Matt Trout "Tables should not be plural as gives you plurals for Result:: package names which represent a single row" - talk may be rewritten in future to reflect this as this is better once you understand the relationship setup - either way, consistency is important)</p>
-      <p>Use a character set (<strong>UTF8</strong>) from the start (for international characters)</p>
+      <h1>Large Community</h1>
+      <p>Currently there are 88 people listed as contributors to DBIC.  That
+      ranges from documentation help, to test help, to added features,
+      to entire database support.</p>
    </div>
 
    <div class="slide">
-      <h1>authors table</h1>
-<pre>CREATE TABLE author<strong>s</strong>(
-   id   int(8) primary key auto_increment,
-   name varchar(255)
-) engine = <strong>InnoDB</strong> DEFAULT CHARSET=<strong>utf8</strong>;</pre>
+      <h1>Active Community</h1>
+      <p>Currently (June 9, 2010) 6 active branches (commited to in the last two weeks) in git.  Last release (0.08122) had 14 new features, and 16 bug fixes.  Of course that <a href="http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/DBIx-Class.git;a=blob;f=Changes">ebbs and flows</a>.</p>
    </div>
 
    <div class="slide">
-      <h1>books table</h1>
-<pre>CREATE TABLE books(
-   id     int(8) primary key auto_increment,
-   title  varchar(255),
-   author int(8),foreign key (author)
-      references authors(id)
-) engine = InnoDB DEFAULT CHARSET=utf8;</pre>
+      <h1>Responsive Community</h1>
+      <ul class="incremental">
+         <li>needed MSSQL Order by support, they helped me add support</li>
+         <li>generally very welcoming of people willing to help</li>
+      </ul>
    </div>
 
-
    <div class="slide">
-      <h1>tips</h1>
-      <p>Name link fields as singular</p>
-      <p>Check foreign key is the same field and type and size in both tables</p>
+      <h1>General ORM</h1>
+      <p>These are things that are in most other ORMs, but are still reasons
+      to use DBIC over raw SQL.</p>
    </div>
 
    <div class="slide">
-      <h1>books table</h1>
-<pre>CREATE TABLE books(
-   id     int(8) primary key auto_increment,
-   title  varchar(255),
-   author <strong>int(8)</strong>,<strong>foreign key (<em>author</em>)</strong>
-      <strong>references <em>authors(id)</em></strong>
-) engine = InnoDB DEFAULT CHARSET=utf8;</pre>
+      <h1>Cross DB</h1>
+      <p>The vast majority of code should run on all databases without needing tweaking</p>
    </div>
 
    <div class="slide">
-      <h1>CRUD compared</h1>
-      <ul>
+      <h1>Basic CRUD</h1>
+      <ul class="incremental">
          <li><strong>C</strong> - Create</li>
          <li><strong>R</strong> - Read</li>
          <li><strong>U</strong> - Update</li>
    </div>
 
    <div class="slide">
-      <h1>Manual (SQL)</h1>
-   </div>
-
-   <div class="slide">
-      <h1>manual: create</h1>
+      <h1>SQL: Create</h1>
 <pre>my $sth = $dbh-&gt;prepare('
    INSERT INTO books
-   (title, author)
+   (title, author_id)
    values (?,?)
 ');
 
@@ -197,20 +178,19 @@ $sth-&gt;execute(
    </div>
 
    <div class="slide">
-      <h1>manual: create</h1>
-<pre>my $sth = $dbh-&gt;prepare('
-   <strong>INSERT INTO books
-   (title, author)
-   values (?,?)</strong>
-');
-
-$sth-&gt;execute(
-  'A book title', <strong><em>$author_id</em></strong>
-);</pre>
+      <h1>DBIC: Create</h1>
+<pre>my $book = $book_rs-&gt;create({
+   title     =&gt; 'A book title',
+   author_id =&gt; $author_id,
+});</pre>
+      <ul class="incremental">
+         <li>No need to pair placeholders and values</li>
+         <li>Automatically gets autoincremented id for you</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>manual: retrieve</h1>
+      <h1>SQL: Read</h1>
 <pre>my $sth = $dbh-&gt;prepare('
    SELECT title,
    authors.name as author_name
@@ -220,7 +200,7 @@ $sth-&gt;execute(
    </div>
 
    <div class="slide">
-      <h1>manual: retrieve</h1>
+      <h1>SQL: Read</h1>
 <pre>while( my $book = $sth-&gt;fetchrow_hashref() ) {
   print 'Author of '
      . $book-&gt;{title}
@@ -231,103 +211,24 @@ $sth-&gt;execute(
    </div>
 
    <div class="slide">
-      <h1>manual: update</h1>
-<pre>my $update = $dbh-&gt;prepare('
-   UPDATE books
-   SET title = ?
-   WHERE id = ?
-');
-
-$update-&gt;execute(
-  'New title',<strong>$book_id</strong>
-);</pre>
-   </div>
-
-   <div class="slide">
-      <h1>manual: delete</h1>
-<pre>my $delete = $dbh-&gt;prepare('
-   DELETE FROM books
-   WHERE id = ?
-');
-
-$delete-&gt;execute(<strong>$book_id</strong>);</pre>
-   </div>
-
-   <div class="slide">
-      <h1>DBIx::Class</h1>
-   </div>
-
-   <div class="slide">
-      <h1>DBIC: create</h1>
-<pre>my $book = $book_model-&gt;create({
-   title  =&gt; 'A book title',
-   author =&gt; $author_id,
-});</pre>
-      <p>Look ma, no SQL!</p>
-      <p><strong>Tip:</strong> do not pass in primary_key field, even if it's empty/undef as the object returned will have an empty id, even if your field is auto increment.</p>
-   </div>
-
-   <div class="slide">
-      <h1>DBIC: create</h1>
-<pre>my $book = $book_model-&gt;create({
-   title  =&gt; 'A book title',
-   author =&gt; <strong>$author_id</strong>,
-});</pre>
-   </div>
-
-   <div class="slide">
-      <h1>DBIC: create</h1>
-<pre>my $pratchett = $author_model-&gt;create({
-   name =&gt; 'Terry Pratchett',
-});</pre>
-   </div>
-
-   <div class="slide">
-      <h1>DBIC: create</h1>
-<pre>my $book = $pratchett-&gt;create_related(
-  books =&gt; {
-   title =&gt; 'Another Discworld book',
-});</pre>
-<strong>or</strong>
-<pre>my $book = $pratchett-&gt;add_to_books({
-   title =&gt; 'Another Discworld book',
-});</pre>
-   </div>
+      <h1>DBIC: Read</h1>
+<pre>my $book = $book_rs-&gt;find($book_id);
 
-   <div class="slide">
-      <h1>DBIC: create</h1>
-<pre>my $book = $pratchett-&gt;create_related(
-  <strong>books</strong> =&gt; {
-   title =&gt; 'Another Discworld book',
-});</pre>
-<strong>or</strong>
-<pre>my $book = $pratchett-&gt;add_to_<strong>books</strong>({
-   title =&gt; 'Another Discworld book',
-});</pre>
-   </div>
-
-   <div class="slide">
-      <h1>DBIC: retrieve</h1>
-      <p>DBIx::Class - Lots of ways to do the same thing...</p>
-      <p><em>"There is more than one way to do it (TIMTOWTDI, usually pronounced "Tim Toady") is a Perl motto"</em></p>
-   </div>
-
-   <div class="slide">
-      <h1>DBIC: retrieve</h1>
-<pre>my $book = $book_model-&gt;find($book_id);
-
-my $book = $book_model-&gt;search({
+my $book = $book_rs-&gt;search({
    title =&gt; 'A book title',
-})-&gt;single;
+}, { rows =&gt; 1 })-&gt;single;
 
-my @books = $book_model-&gt;search({
+my @books = $book_rs-&gt;search({
    author =&gt; $author_id,
 })-&gt;all;</pre>
+      <ul class="incremental">
+         <li>TMTOWTDI</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>DBIC: retrieve</h1>
-<pre>while( my $book = $books_rs-&gt;next() ) {
+      <h1>DBIC: Read</h1>
+<pre>while( my $book = $books_rs-&gt;next ) {
  print 'Author of '
     . $book-&gt;title
     . ' is '
@@ -337,584 +238,402 @@ my @books = $book_model-&gt;search({
    </div>
 
    <div class="slide">
-      <h1>DBIC: retrieve</h1>
-<pre>my $books_rs = $book_model-&gt;search({
-   author =&gt; $author_id,
-});</pre>
-      <p>Search takes SQL::Abstract formatted queries</p>
-      <pre>&gt; perldoc SQL::Abstract</p>
+      <h1>SQL: Update</h1>
+<pre>my $update = $dbh-&gt;prepare('
+   UPDATE books
+   SET title = ?
+   WHERE id = ?
+');
+
+$update-&gt;execute(
+  'New title',<strong>$book_id</strong>
+);</pre>
    </div>
 
    <div class="slide">
-      <h1>DBIC: update</h1>
+      <h1>DBIC: Update</h1>
 <pre>$book-&gt;update({
   title =&gt; 'New title',
 });</pre>
    </div>
 
    <div class="slide">
-      <h1>DBIC: delete</h1>
-<pre>$book-&gt;delete;</pre>
-   </div>
-
-   <div class="slide">
-      <h1>Creating models</h1>
-   </div>
-
-   <div class="slide">
-      <pre>Example of a DBIC Result</pre>
-   </div>
+      <h1>SQL: Delete</h1>
+<pre>my $delete = $dbh-&gt;prepare('
+   DELETE FROM books
+   WHERE id = ?
+');
 
-   <div class="slide">
-      <pre>Example of a DBIC Result</pre>
+$delete-&gt;execute(<strong>$book_id</strong>);</pre>
    </div>
 
    <div class="slide">
-      <p>too much typing!  too much maintenance!</p>
-      <p>too much maintenance!</p>
+      <h1>DBIC: Delete</h1>
+<pre>$book-&gt;delete;</pre>
    </div>
 
    <div class="slide">
-      <h1>Schema::Loader</h1>
-      <pre>code for S::L here</pre>
+      <h1>OO Overidability</h1>
+      <ul class="incremental">
+         <li>Override new if you want to do validation</li>
+         <li>Override delete if you want to disable deletion</li>
+         <li>and on and on</li>
+      </ul>
+      <div class="notes">
+         <p>I got yelled at about this before by people, so
+         we don't get EVERYTHING from OO, but we do get a lot
+         so :-P</p>
+      </div>
    </div>
 
    <div class="slide">
-      <h1>splitting logic cleanly</h1>
-      <p>LPW::DBIC::Result::Foo = an individual row</p>
-      <p>LPW::DBIC::ResultSet::Foo = searches / results</p>
+      <h1>Convenience Methods</h1>
+      <ul class="incremental">
+         <li>find_or_create</li>
+         <li>create_or_update</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>using your Schema</h1>
-      <pre>example usage code goes here</pre>
+      <h1>Non-column methods</h1>
+      <p>Need a method to get a user's gravatar URL?  Add a
+      gravatar_url method to their Result class</p>
    </div>
 
    <div class="slide">
-      <h1>DEBUGGING</h1>
-      <pre>DBIC_TRACE=1 ./your_script.pl</pre>
+      <h1>RELATIONSHIPS</h1>
+      <ul class="incremental">
+         <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship#belongs_to">belongs_to</a></li>
+         <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship#has_many">has_many</a></li>
+         <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship#might_have">might_have</a></li>
+         <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship#has_one">has_one</a></li>
+         <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship#many_to_many">many_to_many</a> (technically not a relationship)</li>
+         <li>SET AND FORGET</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>Schema::Loader</h1>
-<pre>LPW::DBIC::Result::Authors-&gt;table("authors");
-LPW::DBIC::Result::Authors-&gt;add_columns(
-   id =&gt; {
-      data_type     =&gt; "INT",
-      default_value =&gt; undef,
-      is_nullable   =&gt; 0,
-      size          =&gt; 8
-   },
-   title =&gt; {
-      data_type     =&gt; "VARCHAR",
-      default_value =&gt; undef,
-      is_nullable   =&gt; 1,
-      size          =&gt; 255,
-   },
-);
-LPW::DBIC::Result::Authors-&gt;set_primary_key("id");</pre>
+      <h1>DBIx::Class Specific Features</h1>
+      <p>These things may be in other ORM's, but they are very specific, so doubtful</p>
    </div>
 
    <div class="slide">
-      <h1>Schema::Loader</h1>
-<pre>LPW::DBIC::Result::Books->table("books");
-LPW::DBIC::Result::Books->add_columns(
-   id =&gt; {
-      data_type     =&gt; "INT",
-      default_value =&gt; undef,
-      is_nullable   =&gt; 0,
-      size          =&gt; 8
-   },
-   name =&gt; {
-      data_type     =&gt; "VARCHAR",
-      default_value =&gt; undef,
-      is_nullable   =&gt; 1,
-      size          =&gt; 255,
-   },
-   author =&gt; {
-      data_type     =&gt; "INT",
-      default_value =&gt; undef,
-      is_nullable   =&gt; 1,
-      size          =&gt; 8
-   },
-);
-LPW::DBIC::Result::Books-&gt;set_primary_key("id");</pre>
+      <h1>-&gt;deploy</h1>
+      <p>Perl -&gt; DB</p>
+<pre>my $schema = Foo::Schema-&gt;connect($dsn, $user, $pass);
+$schema-&gt;deploy
+</pre>
+<p>See also: <a href="http://search.cpan.org/perldoc?DBIx::Class::DeploymentHandler">DBIx::Class::DeploymentHandler</a></p>
    </div>
 
    <div class="slide">
       <h1>Schema::Loader</h1>
-<pre>LPW::DBIC::Result::Authors-&gt;has_many(books =&gt; "LPW::DBIC::Books",
-   { "foreign.author" =&gt; "self.id" });
-
-LPW::DBIC::Result::Books-&gt;belongs_to(author =&gt; "LPW::DBIC::Authors",
-   { id =&gt; "author" });</pre>
-   </div>
-
-   <div class="slide">
-      <h1>SQL - debugging</h1>
-<pre>INSERT INTO authors (name)
-   VALUES (?): 'Douglas Adams'
-
-INSERT INTO books (author, title)
-   VALUES (?, ?): '5', '42'</pre>
-   </div>
-
-   <div class="slide">
-      <h1>overloading</h1>
-<pre>LPW::DBIC::Result::Books
-LPW::DBIC::ResultSet::Books
-LPW::DBIC::Result::Authors
-LPW::DBIC::ResultSet::Books</pre>
-   </div>
-
-   <div class="slide">
-      <h1>Result::</h1>
-<pre>package LPW::DBIC::Result::Books;
-use base 'DBIx::Class';
-use strict;
-use warnings;
-
-sub isbn {
-   my $self = shift;
-
-   # search amazon or something
-   my $api = Amazon::API-&gt;book({
-      title =&gt; $self-&gt;title
-   });
-
-   return $api-&gt;isbn;
-}
-
-1;</pre>
-   </div>
-
-   <div class="slide">
-      <h1>Result::</h1>
-<pre>print $book-&gt;isbn;</pre>
-   </div>
-
-   <div class="slide">
-      <h1>Result:: (inflating)</h1>
-<pre>package LPW::DBIC::Result::Books;
-use base 'DBIx::Class';
-use strict;
-use warnings;
+      <p>DB -&gt; Perl</p>
+<pre>package Foo::Schema;
+use strict; use warnings;
+use base 'DBIx::Class::Schema::Loader';
+__PACKAGE__-&gt;loader_options({
+   naming =&gt; 'v7',
+   debug  =&gt; $ENV{DBIC_TRACE},
+});
+1;
 
-use DateTime::Format::MySQL;
+# elsewhere...
 
-__PACKAGE__-&gt;<strong>inflate_column</strong>(
-   <strong>date_published</strong> =&gt; {
-      inflate =&gt; sub { DateTime::Format::MySQL-&gt;parse_date(shift) },
-      deflate =&gt; sub { shift-&gt;ymd},
-   }
-);
-# Automatic see: DBIx::Class::InflateColumn::DateTime</pre>
+my $schema = Foo::Schema-&gt;connect($dsn, $user, $pass);
+</pre>
    </div>
 
    <div class="slide">
-      <h1>Result:: (inflating)</h1>
-<pre>package LPW::DBIC::Result::Books;
-use base 'DBIx::Class';
-use strict;
-use warnings;
-
-use DateTime::Format::MySQL;
-
-__PACKAGE__-&gt;inflate_column(
-   date_published =&gt; {
-      <strong>inflate =&gt; sub { DateTime::Format::MySQL-&gt;parse_date(shift) },
-      deflate =&gt; sub { shift-&gt;ymd},</strong>
-   }
+      <h1>Populate</h1>
+      <p>Made for inserting lots of rows very quicky into database</p>
+<pre>$schema-&gt;populate([ Users =&gt;
+   [qw( username password )],
+   [qw( frew &gt;=4char$  )],
+   [qw(      ...          )],
+   [qw(      ...          )],
 );
-# Automatic see: DBIx::Class::InflateColumn::DateTime
-# Automatic see: DBIx::Class::InflateColumn::DateTime
-# Automatic see: DBIx::Class::InflateColumn::DateTime</pre>
-   </div>
-
-   <div class="slide">
-      <h1>Result:: (deflating)</h1>
-<pre>$book-&gt;date_published(DateTime-&gt;now);
-$book-&gt;update;</pre>
-   </div>
-
-   <div class="slide">
-      <h1>Result:: (inflating)</h1>
-<pre>my $date_published = $book-&gt;date_published;
-print $date_published-&gt;month_abbr;</pre>
-
-<strong><em>Nov</em></strong>
-   </div>
-
-   <div class="slide">
-      <h1>ResultSets::</h1>
-<pre>package LPW::DBIC::ResultSet::Books;
-use base 'DBIx::Class::ResultSet';
-sub the_ultimate_books {
-   my $self = shift;
-   return $self-&gt;search({ title =&gt; { -like =&gt; '%42%' } });
-}
-sub by_author {
-   my ( $self, $author ) = @_;
-   return $self-&gt;search({ author =&gt; $author-&gt;id })
-}
-
-1;</pre>
-   </div>
-
-   <div class="slide">
-      <h1>ResultSets::</h1>
-<pre>package LPW::DBIC::<strong>ResultSet::Books</strong>;
-use base '<strong>DBIx::Class::ResultSet</strong>';
-sub the_ultimate_books {
-   my $self = shift;
-   <strong>return $self-&gt;search({ title =&gt; { -like =&gt; '%42%' } })</strong>
-}
-sub by_author {
-   my ( $self, $author ) = @_;
-   return $self-&gt;search({ author =&gt; $author-&gt;id })
-}
-
-1;</pre>
+</pre>
+      <ul class="incremental">
+         <li>I use this to <a href="http://blog.afoolishmanifesto.com/archives/1255">export our whole (200M~) db to SQLite</a></li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>ResultSets::</h1>
-<pre>package LPW::DBIC::ResultSet::Books;
-use base 'DBIx::Class::ResultSet';
-sub the_ultimate_books {
-   my $self = shift;
-   return $self-&gt;search({ title =&gt; { -like =&gt; '%42%' } });
-}
-sub by_author {
-   my ( $self, $author ) = @_;
-   <strong>return $self-&gt;search({ author =&gt; $author-&gt;id })</strong>
-}
-
-1;</pre>
+      <h1>Multicreate</h1>
+      <p>Create an object and all of it's related objects all at once</p>
+<pre>$schema-&gt;resultset('Author')-&gt;create({
+   name =&gt; 'Stephen King',
+   books =&gt; [{ title =&gt; 'The Dark Tower' }],
+   address =&gt; {
+      street =&gt; '123 Turtle Back Lane',
+      state  =&gt; { abbreviation =&gt; 'ME' },
+      city   =&gt; { name =&gt; 'Lowell' },
+   },
+});
+</pre>
+      <div class="notes">
+         <ul>
+            <li>books is a has_many</li>
+            <li>address is a belongs_to which in turn belongs to state and city each</li>
+            <li>for this to work right state and city must mark abbreviation and name as unique</li>
+         </ul>
+      </div>
    </div>
 
    <div class="slide">
-      <h1>ResultSets::</h1>
-<pre>use LPW::DBIC;
-my $book_model = LPW::DBIC-&gt;resultset('Books');
-my $book_rs    = $book_model-&gt;the_ultimate_books;
-my @books      = $book_rs-&gt;all;</pre>
+      <h1>Extensible</h1>
+      <p>DBIx::Class helped pioneer fast MI in Perl 5 with Class::C3, so it is made
+      to allow extensions to nearly every part of it.</p>
    </div>
 
    <div class="slide">
-      <h1>ResultSets::chaining</h1>
-<pre>use LPW::DBIC;
-my $book_model   = LPW::DBIC-&gt;resultset('Books');
-my $author_model = LPW::DBIC-&gt;resultset('Authors');
-my $author       = $author_model-&gt;search({ name =&gt; 'Douglas Adams' })-&gt;single;
-my $book_rs      = $book_model-&gt;the_ultimate_books-&gt;by_author($author);
-my @books        = $book_rs-&gt;all;</pre>
+      <h1>Extensible: DBIC::Helpers</h1>
+      <ul class="incremental">
+         <li>DBIx::Class::Helper::ResultSet::IgnoreWantarray</li>
+         <li>DBIx::Class::Helper::ResultSet::Random</li>
+         <li>DBIx::Class::Helper::ResultSet::SetOperations</li>
+         <li>DBIx::Class::Helper::Row::JoinTable</li>
+         <li>DBIx::Class::Helper::Row::NumifyGet</li>
+         <li>DBIx::Class::Helper::Row::SubClass</li>
+         <li>DBIx::Class::Helper::Row::ToJSON</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>ResultSets::chaining</h1>
-<pre>my $book_rs = $book_model
-  -&gt;the_ultimate_books
-  -&gt;by_author($author);</pre>
-or
-
-<pre>my $book_rs = $book_model
-  -&gt;the_ultimate_books();
-$book_rs = $book_rs-&gt;by_author($author);</pre>
-<pre># Debug (SQL):
-
-# SELECT me.id, me.title, me.date_published, me.author
-#   FROM books me
-#   WHERE ( ( ( author = ? ) AND ( title LIKE ? ) ) ): '5', '%42%'
-#   WHERE ( ( ( author = ? ) AND ( title LIKE ? ) ) ): '5', '%42%'</pre>
+      <h1>Extensible: DBIC::TimeStamp</h1>
+      <ul class="incremental">
+         <li>Cross DB</li>
+         <li>set_on_create</li>
+         <li>set_on_update</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>ResultSets::chaining</h1>
-<pre>my $rs = $book_model
-  -&gt;category('childrens')
-  -&gt;by_author($author)
-  -&gt;published_after('1812')
-  -&gt;first_page_contains('once upon')
-  -&gt;rating_greater_than(4);
-
-my @books = $rs-&gt;all;</pre>
+      <h1>Extensible: DBIx::Class::Schema::KiokuDB</h1>
+      <ul class="incremental">
+         <li>Kioku is the new hotness</li>
+         <li>Mix RDBMS with Object DB</li>
+         <li>beta ( == sexy )</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>overloading before new record</h1>
+      <h1>SQL::Abstract</h1>
+<pre>my $resultset = $book_rs-&gt;search({
+   name =&gt; { -like =&gt; "%$nick%" },
+});</pre>
+      <ul class="incremental">
+         <li>(kinda) introspectible</li>
+         <li>Prettier than SQL</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>overloading before new record</h1>
-      <pre>package LPW::DBIC::Result::Authors;
-use base 'DBIx::Class';
-
-sub new {
-   my ( $class, $attrs ) = @_;
-   # Mess with $attrs
-   my $new = $class-&gt;next::method($attrs);
-   return $new
-}
-
-1;</pre>
-
-   <div class="slide">
-      <h1>relationships</h1>
+      <h1>Result vs ResultSet</h1>
+         <ul class="incremental">
+            <li>Result == Row</li>
+            <li>ResultSet == Query</li>
+            <li>(less important but...)</li>
+            <li>ResultSource == Table</li>
+            <li>Storage == Database</li>
+         </ul>
    </div>
 
    <div class="slide">
-      <h1>multiple authors</h1>
+      <h1>ResultSet methods</h1>
+<pre>package MyApp::Schema::ResultSet::Book;
+use base 'DBIx::Class::ResultSet';
+sub good {
+   $_[0]-&gt;search({
+      rating =&gt; { '&gt;=' =&gt; 4 },
+   })
+};
+sub cheap {
+   $_[0]-&gt;search({
+      price =&gt; { '&lt;=' =&gt; 5}
+   })
+};
+# ...
+1;
+      </pre>
+      <ul class="incremental">
+         <li>All searches should be ResultSet methods</li>
+         <li>Name has obvious meaning</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>a few relationships</h1>
-      (authors -- author_link_to_book -- books)
+      <h1>ResultSet method in Action</h1>
+      <pre>$schema-&gt;resultset('Book')-&gt;good</pre>
    </div>
 
    <div class="slide">
-      <h1>a few relationships</h1>
-      !
+      <h1>ResultSet Chaining</h1>
+<pre>$schema-&gt;resultset('Book')
+   -&gt;good
+   -&gt;cheap
+   -&gt;recent
+</pre>
    </div>
 
    <div class="slide">
-      <h1>new join table</h1>
-<pre>CREATE TABLE author_and_books(
-  id      int(8)    primary key auto_increment,
-  book    int(8),
-  author  int(8),
-  foreign key (book)     references books(id),
-  foreign key (author)   references authors(id)
-) engine = InnoDB DEFAULT CHARSET=utf8;
-
-ALTER TABLE `books` DROP `author`</pre>
+      <h1>search_related</h1>
+      <pre>*get example from work*</pre>
    </div>
 
    <div class="slide">
-      <h1>new join table</h1>
-<pre>CREATE TABLE author_and_books(
-  id      int(8)    primary key auto_increment,
-  book    int(8),
-  author  int(8),
-  <strong>foreign key (book)     references books(id),
-  foreign key (author)   references authors(id)</strong>
-) engine = InnoDB DEFAULT CHARSET=utf8;
-
-ALTER TABLE `books` DROP `author`</pre>
-   </div>
+      <h1>bonus rel methods</h1>
+<pre>my $book = $author-&gt;create_related(
+  <strong>books</strong> =&gt; {
+   title =&gt; 'Another Discworld book',
+});
 
-   <div class="slide">
-      <h1>has_many</h1>
+my $book2 = $pratchett-&gt;add_to_<strong>books</strong>({
+   title =&gt; 'MOAR Discworld book',
+});</pre>
+      <ul class="incremental">
+         <li>Automaticaly fills in foreign key for you</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>has_many</h1>
-<pre>package LPW::DBIC::<strong>Result::Books</strong>;
+      <h1>Excellent Transaction Support</h1>
+<pre>$schema-&gt;txn_do(sub {
+   ...
+});
 
-__PACKAGE__-&gt;has_many( author_and_books =&gt; "LPW::DBIC::Result::AuthorAndBooks",
-    { "foreign.book" =&gt; "self.id" },
-);
+my $guard = $schema-&gt;txn_scope_guard;
+# ...
+$guard-&gt;commit;
 
-<strong># This is auto generated by Schema::Loader</strong></pre>
-   </div>
-
-   <div class="slide">
-      <h1>has_many</h1>
-<pre>package LPW::DBIC::<strong>Result::Books</strong>;
-
-__PACKAGE__-&gt;has_many(
-author_and_books =&gt; <strong># name of accessor</strong>
-"LPW::DBIC::Result::AuthorAndBooks", <strong># related class</strong>
-    { "foreign.book" =&gt; "self.id" } <strong># Relationship (magic often works if not
-                                        # specified, but avoid!)</strong>
-);
+$schema-&gt;txn_begin; # &lt;-- low level
+# ...
+$schema-&gt;txn_commit;
 </pre>
    </div>
 
    <div class="slide">
-      <h1>belongs_to</h1>
-   </div>
-
-   <div class="slide">
-      <h1>belongs_to</h1>
-<pre>package LPW::DBIC::<strong>Result::AuthorAndBooks</strong>;
-
-__PACKAGE__-&gt;belongs_to(
-   book =&gt; <strong># Accessor name</strong>
-   "LPW::DBIC::Result::Books", <strong># Related class</strong>
-   { id =&gt; "book" } <strong># relationship</strong>
+      <h1>InflateColumn</h1>
+<pre>package Foo::Schema::Result::Book;
+use base 'DBIx::Class::Core';
+# Result code here
+__PACKAGE__-&gt;load_components('InflateColumn');
+use DateTime::Format::MySQL;
+__PACKAGE__-&gt;<strong>inflate_column</strong>(
+   <strong>date_published</strong> =&gt; {
+      inflate =&gt; sub { DateTime::Format::MySQL-&gt;parse_date(shift) },
+      deflate =&gt; sub { shift-&gt;ymd},
+   },
 );
-</pre>
+# Automatic see: DBIx::Class::InflateColumn::DateTime</pre>
    </div>
 
    <div class="slide">
-      <h1>same for Authors</h1>
+      <h1>InflateColumn: deflation</h1>
+<pre>$book-&gt;date_published(DateTime-&gt;now);
+$book-&gt;update;</pre>
    </div>
 
    <div class="slide">
-      <h1>with no coding...</h1>
-   </div>
+      <h1>InflateColumn: inflation</h1>
+<pre>my $date_published = $book-&gt;date_published;
+print $date_published-&gt;month_abbr;</pre>
 
-   <div class="slide">
-      <h1>many_to_many</h1>
+<strong><em>Nov</em></strong>
    </div>
 
    <div class="slide">
-      <h1>many_to_many</h1>
-      <pre>package LPW::DBIC::<strong>Result::Books</strong>;
-use base 'DBIx::Class';
+      <h1>FilterColumn</h1>
+<pre>package Foo::Schema::Result::Book;
+use base 'DBIx::Class::Core';
+# Result code here
+__PACKAGE__-&gt;load_components('FilterColumn');
 
-__PACKAGE__-&gt;many_to_many(
-   authors =&gt; "author_and_books", 'author'
+__PACKAGE__-&gt;<strong>filter_column</strong>(
+   <strong>length</strong> =&gt; {
+      to_storage   =&gt; 'to_metric',
+      from_storage =&gt; 'to_imperial',
+   },
 );
 
-1;
-
-<strong> # This is <em>NOT</em> auto generated by Schema::Loader </strong></pre>
+sub to_metric   { $_[1] * .305 }
+sub to_imperial { $_[1] * 3.28 }
+# Automatic see: DBIx::Class::InflateColumn::DateTime</pre>
    </div>
 
    <div class="slide">
-      <h1>many_to_many</h1>
-      <pre>package LPW::DBIC::<strong>Result::Books</strong>;
-use base 'DBIx::Class';
-
-__PACKAGE__-&gt;many_to_many(
-   authors <strong># Accessor name</strong>
-   =&gt; "author_and_books", <strong># has_many</strong>
-   'author' <strong># foreign relationship name</strong>
-);
-
-1;</pre>
+      <h1>ResultSetColumn</h1>
+<pre>my $rsc = $schema-&gt;resultset('Book')-&gt;get_column('price');
+$rsc-&gt;min;
+$rsc-&gt;max;
+$rsc-&gt;sum;
+</pre>
    </div>
 
    <div class="slide">
-      <h1>many_to_many</h1>
-      <pre>package LPW::DBIC::Result::Authors;
-use base 'DBIx::Class';
-
-__PACKAGE__-&gt;many_to_many(
-   "books" <strong># Accessor Name</strong>
-   =&gt; "author_and_books", <strong># has_many accessor_name</strong>
-   'book' <strong># foreign relationship name</strong>
-);
-
-1;
-
-<strong># This is <em>NOT</em> auto generated by Schema::Loader</strong></pre>
+      <h1>Aggregates</h1>
+<pre>my @res = $rs-&gt;search({}, {
+   select   =&gt; [qw(price genre), { max =&gt; price }, { avg =&gt; price }],
+   as       =&gt; [qw(price genre max_price avg_price)],
+   group_by =&gt; [qw(price genre)],
+});
+for (@res) {
+   say $_-&gt;price . ' ' . $_-&gt;genre;
+   say $_-&gt;get_column('max_price');
+   say $_-&gt;get_column('min_price');
+}</pre>
+      <ul class="incremental">
+         <li>Careful, get_column can basicaly mean THREE things</li>
+         <li>private for get what you should use an accessor for</li>
+         <li>public for what there is no accessor for</li>
+         <li>public for get resultset column (prev slide)</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>using many_to_many</h1>
-      <pre>#!/usr/bin/perl
-
-use LPW::DBIC;
-
-my $author_model = LPW::DBIC-&gt;resultset('Authors');
-my $author       = $author_model-&gt;search({
-   name =&gt; 'Douglas Adams',
-})-&gt;single;
-$author-&gt;add_to_books({
-   title =&gt; 'A new book',
+      <h1>HRI</h1>
+<pre>$rs-&gt;search({}, {
+   result_class =&gt; 'DBIx::Class::ResultClass::HashRefInflator',
 });</pre>
+      <ul class="incremental">
+         <li>Easy on memory</li>
+         <li>Mega fast</li>
+         <li>Great for quick debugging</li>
+         <li>Great for performance tuning (we went from 2m to &lt; 3s)</li>
+      </ul>
    </div>
 
    <div class="slide">
-      <h1>using many_to_many</h1>
-      <pre>my $author = $author_model-&gt;search({
-   name =&gt; 'Douglas Adams',
-})-&gt;single;
-<strong>$author-&gt;add_to_books({
-   title =&gt; 'A new book',
-});</strong>
-
-# SELECT me.id, me.name FROM authors me
-#     WHERE ( name = ? ): 'Douglas Adams';
-# INSERT INTO books (title) VALUES (?): 'A new book';
-# INSERT INTO author_and_books (author, book)
-#     VALUES (?, ?): '5', '2';</pre>
-   </div>
-
-   <div class="slide">
-      <h1>using many_to_many</h1>
-      <pre>$author-&gt;add_to_books($book);
-
-$book-&gt;add_to_authors($author_1);
-$book-&gt;add_to_authors($author_2);</pre>
-   </div>
-
-   <div class="slide">
-      <h1>in 16 lines of code</h1>
-   </div>
-
-   <div class="slide">
-      <h1>errors</h1>
-      <p>Read them closely!</p>
-   </div>
-
-   <div class="slide">
-      <h1>error messages</h1>
-      <pre>DBIx::Class::Schema::Loader::connection(): Failed to load external class definition for 'LPW::DBIC::Result::Authors': Can't locate object method "many_to_many" via package "LPW::DBIC::Result::Author" at lib/LPW/DBIC/Result/Authors.pm line 9.Compilation failed in require at /Library/Perl/5.8.8/DBIx/Class/Schema/Loader/Base.pm line 292.</pre>
-   </div>
-
-   <div class="slide">
-      <h1>error messages</h1>
-   <pre>DBIx::Class::Schema::Loader::connection(): Failed to load external class definition for 'LPW::DBIC::Result::Authors': Can't locate object method "many_to_many" via package "LPW::DBIC::<strong>Result::Author</strong>" at lib/LPW/DBIC/<strong>Result/Authors.pm</strong> line 9.Compilation failed in require at /Library/Perl/5.8.8/DBIx/Class/Schema/Loader/Base.pm line 292.</pre>
-   </div>
+      <h1>Subquery Support</h1>
+<pre>  my $inside_rs = $schema-&gt;resultset('Artist')-&gt;search({
+    name =&gt; [ 'Billy Joel', 'Brittany Spears' ],
+});
 
-   <div class="slide">
-      <h1>errors</h1>
-      <ul>
-         <li>Turn on debugging</li>
-         <li>Read error messages (sometimes useful!)</li>
-         <li>Check field names</li>
-         <li>Check package names</li>
-         <li>Check which database you are connected to (dev/test/live?) - repeat above</li>
-      </ul>
+my $rs = $schema-&gt;resultset('CD')-&gt;search({
+    artist_id =&gt; { -in =&gt; $inside_rs-&gt;get_column('id')-&gt;as_query },
+});</pre>
    </div>
 
    <div class="slide">
-      <h1>bonus slides!</h1>
-   </div>
+      <h1>Bare SQL w/ Placeholders</h1>
+<pre>$rs-&gt;update({
+   price =&gt; \"price + $inc", # !!! SQL INJECTION VECTOR
+});
 
-   <div class="slide">
-      <h1>Template Toolkit</h1>
-      <ul>
-         <li><pre>[% author.books.count %]</pre> not working?</li>
-         <li>TT all methods are called in list context</li>
-         <li><pre>[% author.books<strong>_rs</strong>.count %]</pre> scalar context</li>
-         <li><em>Available for all relationships</em></li>
-      </ul>
+$rs-&gt;update({
+   price =&gt; \['price + ?', [inc =&gt; $inc]],
+});
+</pre>
    </div>
 
    <div class="slide">
-      <h1>Catalyst</h1>
-      <pre>package Your::App::Model::<strong>LPW</strong>;
-use base qw(<strong>Catalyst::Model::DBIC::Schema</strong>);
-
-use strict;
-use warnings;
-
-__PACKAGE__-&gt;config(
-  schema_class =&gt; '<strong>LPW::DBIC</strong>',
-);
-
-1;</pre>
-   <p>Keep your Schema in a <em>separate</em> package to your Catalyst application</p>
+      <h1>Questions?</h1>
    </div>
 
    <div class="slide">
-      <h1>Catalyst</h1>
-<pre>sub action_name : Local {
-  my ($self, $c) = @_;
-
-  my $model = $c-&gt;model('DBIC::LPW');
-  my $author_model = $model-&gt;resultset('Authors');
-
-}
-
-1;</pre>
+      <h1>END</h1>
    </div>
-
 </div>
 </body>
 </html>