<!-- BEGIN s5 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>dbic_chado</title>
<meta name="generator" content="Spork-S5" />
<meta name="version" content="Spork-S5 0.04" />
<meta name="author" content="Robert Buels" />
<link rel="stylesheet" href="ui/slides.css" type="text/css" media="projection" id="slideProj" />
<link rel="stylesheet" href="ui/opera.css" type="text/css" media="projection" id="operaFix" />
<link rel="stylesheet" href="ui/print.css" type="text/css" media="print" id="slidePrint" />
<link rel="stylesheet" type="text/css" href="" />
<script src="ui/slides.js" type="text/javascript"></script>
</head>
<body>
<div class="layout">
<div id="currentSlide"></div>
<div id="header"></div>
<div id="footer">
<h2>Robert Buels</h2>
<h2>rmb32@cornell.edu</h2>
<div id="controls"></div>
</div>
</div>
<div class="slide">
<h1>Introduction to DBIx::Class</h1>
<h2>Portland, OR</h2>
<h3>April 14, 2010</h3>
</div>
<!-- BEGIN slide -->
<div class="slide">
<h1>What is DBIx::Class?</h1>
<ul>
<li>Object-relational mapping framework for Perl</li>
<li>is now the de-facto standard</li>
<li>nice features</li>
</ul>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>What is DBIx::Class?</h1>
<ul>
<li>query building (the magic of chainable ResultSets)</li>
<li>cross-database deployment (using <tt>SQL::Translator</tt> in the backend)</li>
<li>lots and lots of plugins availabe (dates, testing, ...)</li>
</ul>
<p>
see the manual: <a href="http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/Manual.pod">http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/Manual.pod</a>
</p>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>What it looks like</h1>
<pre class="formatter_pre">package My::Schema;
__PACKAGE__->load_namespaces;
package My::Schema::Result::Foo;
__PACKAGE__->table('foo');
__PACKAGE__->add_columns(qw( foo_id bar baz ));
__PACKAGE__->has_many('bars' => 'My::Schema::Result::Bar');
# also belongs_to many_to_many
package My::Schema::Result::Bar;
__PACKAGE__->table('bar');
# and so on
</pre>
<ul>
<li>use <tt>DBIx::Class::Schema::Loader</tt> to generate this from a DB</li>
<li>use <tt>$schema->deploy</tt> to make a DB from this</li>
</ul>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>open the schema. ( actual DB connection is deferred )</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>open the schema. ( actual DB connection is deferred )</li>
</ul>
<pre class="formatter_pre">my $schema = My::Schema->connect( 'dbi:Pg:...', $user, $pass );
</pre>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>open the schema. ( actual DB connection is deferred )</li>
</ul>
<pre class="formatter_pre">my $schema = My::Schema->connect( 'dbi:Pg:...', $user, $pass );
</pre>
<ul>
<li>get a ResultSet object representing a set of Rows</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>open the schema. ( actual DB connection is deferred )</li>
</ul>
<pre class="formatter_pre">my $schema = My::Schema->connect( 'dbi:Pg:...', $user, $pass );
</pre>
<ul>
<li>get a ResultSet object representing a set of Rows</li>
</ul>
<pre class="formatter_pre">my $orgs_rs = $schema->resultset('Organism');
</pre>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>open the schema. ( actual DB connection is deferred )</li>
</ul>
<pre class="formatter_pre">my $schema = My::Schema->connect( 'dbi:Pg:...', $user, $pass );
</pre>
<ul>
<li>get a ResultSet object representing a set of Rows</li>
</ul>
<pre class="formatter_pre">my $orgs_rs = $schema->resultset('Organism');
</pre>
<ul>
<li>take a subset of those (another ResultSet)</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>open the schema. ( actual DB connection is deferred )</li>
</ul>
<pre class="formatter_pre">my $schema = My::Schema->connect( 'dbi:Pg:...', $user, $pass );
</pre>
<ul>
<li>get a ResultSet object representing a set of Rows</li>
</ul>
<pre class="formatter_pre">my $orgs_rs = $schema->resultset('Organism');
</pre>
<ul>
<li>take a subset of those (another ResultSet)</li>
</ul>
<pre class="formatter_pre">my $chickeny_things = $orgs_rs->search({ genus => 'Gallus' });
</pre>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>open the schema. ( actual DB connection is deferred )</li>
</ul>
<pre class="formatter_pre">my $schema = My::Schema->connect( 'dbi:Pg:...', $user, $pass );
</pre>
<ul>
<li>get a ResultSet object representing a set of Rows</li>
</ul>
<pre class="formatter_pre">my $orgs_rs = $schema->resultset('Organism');
</pre>
<ul>
<li>take a subset of those (another ResultSet)</li>
</ul>
<pre class="formatter_pre">my $chickeny_things = $orgs_rs->search({ genus => 'Gallus' });
</pre>
<ul>
<li>first one in the result set</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>open the schema. ( actual DB connection is deferred )</li>
</ul>
<pre class="formatter_pre">my $schema = My::Schema->connect( 'dbi:Pg:...', $user, $pass );
</pre>
<ul>
<li>get a ResultSet object representing a set of Rows</li>
</ul>
<pre class="formatter_pre">my $orgs_rs = $schema->resultset('Organism');
</pre>
<ul>
<li>take a subset of those (another ResultSet)</li>
</ul>
<pre class="formatter_pre">my $chickeny_things = $orgs_rs->search({ genus => 'Gallus' });
</pre>
<ul>
<li>first one in the result set</li>
</ul>
<pre class="formatter_pre">my $chicken = $chickeny_things->first; #< actual query is run
</pre>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>getting actual data</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>getting actual data</li>
</ul>
<pre class="formatter_pre">my $wombat = $orgs_rs->find( 232432 );
</pre>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>getting actual data</li>
</ul>
<pre class="formatter_pre">my $wombat = $orgs_rs->find( 232432 );
say $wombat->genus.' '.$wombat->species; #< print 'Vombatus ursinus' or something
# or search in list context returns all resulting rows
my @all_nightshades = $orgs_rs->search({ genus => 'Solanum' });
</pre>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>traverse relationships (joined queries)</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>traverse relationships (joined queries)</li>
</ul>
<pre class="formatter_pre">my $chickeny_things = $ck_rs->search({ genus => 'Gallus' });
</pre>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>traverse relationships (joined queries)</li>
</ul>
<pre class="formatter_pre">my $chickeny_things = $ck_rs->search({ genus => 'Gallus' });
my @chr = $chickeny_things->chromosomes; #< query is run here
</pre>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>traverse relationships (joined queries)</li>
</ul>
<pre class="formatter_pre">my $chickeny_things = $ck_rs->search({ genus => 'Gallus' });
my @chr = $chickeny_things->chromosomes; #< query is run here
my @genes = $chicken->chromosomes->features->search({ type => 'gene' });
</pre>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>traverse relationships (joined queries)</li>
</ul>
<pre class="formatter_pre">my $chickeny_things = $ck_rs->search({ genus => 'Gallus' });
my @chr = $chickeny_things->chromosomes; #< query is run here
my @genes = $chicken->chromosomes->features->search({ type => 'gene' });
</pre>
<ul>
<li>loading</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>traverse relationships (joined queries)</li>
</ul>
<pre class="formatter_pre">my $chickeny_things = $ck_rs->search({ genus => 'Gallus' });
my @chr = $chickeny_things->chromosomes; #< query is run here
my @genes = $chicken->chromosomes->features->search({ type => 'gene' });
</pre>
<ul>
<li>loading</li>
</ul>
<pre class="formatter_pre">$orgs_rs>create({ genus => 'Mus', species => 'musculus' })
</pre>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>traverse relationships (joined queries)</li>
</ul>
<pre class="formatter_pre">my $chickeny_things = $ck_rs->search({ genus => 'Gallus' });
my @chr = $chickeny_things->chromosomes; #< query is run here
my @genes = $chicken->chromosomes->features->search({ type => 'gene' });
</pre>
<ul>
<li>loading</li>
</ul>
<pre class="formatter_pre">$orgs_rs>create({ genus => 'Mus', species => 'musculus' })
# or piecewise
</pre>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>traverse relationships (joined queries)</li>
</ul>
<pre class="formatter_pre">my $chickeny_things = $ck_rs->search({ genus => 'Gallus' });
my @chr = $chickeny_things->chromosomes; #< query is run here
my @genes = $chicken->chromosomes->features->search({ type => 'gene' });
</pre>
<ul>
<li>loading</li>
</ul>
<pre class="formatter_pre">$orgs_rs>create({ genus => 'Mus', species => 'musculus' })
# or piecewise
my $new = $orgs_rs->new;
$new->genus('Mus'); $new->species('musculus');
$new->insert;
</pre>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Basic Usage</h1>
<ul>
<li>traverse relationships (joined queries)</li>
</ul>
<pre class="formatter_pre">my $chickeny_things = $ck_rs->search({ genus => 'Gallus' });
my @chr = $chickeny_things->chromosomes; #< query is run here
my @genes = $chicken->chromosomes->features->search({ type => 'gene' });
</pre>
<ul>
<li>loading</li>
</ul>
<pre class="formatter_pre">$orgs_rs>create({ genus => 'Mus', species => 'musculus' })
# or piecewise
my $new = $orgs_rs->new;
$new->genus('Mus'); $new->species('musculus');
$new->insert;
</pre>
<ul>
<li>deleting</li>
</ul>
<pre class="formatter_pre">$chicken->chromosomes->features->search({ type => 'gene' })->delete;
</pre>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>When not to use DBIC</h1>
<ul>
<li>tiny app, tiny schema (setup overhead)</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>When not to use DBIC</h1>
<ul>
<li>tiny app, tiny schema (setup overhead)</li>
<li>or tiny number of different queries</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>When not to use DBIC</h1>
<ul>
<li>tiny app, tiny schema (setup overhead)</li>
<li>or tiny number of different queries</li>
<li>or hate objects</li>
</ul>
<p>
strengths/weaknesses ...
</p>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Strengths and Weaknesses</h1>
<ul>
<li>strengths</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Strengths and Weaknesses</h1>
<ul>
<li>strengths</li>
<ul>
<li>chainable ResultSets</li>
</ul></ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Strengths and Weaknesses</h1>
<ul>
<li>strengths</li>
<ul>
<li>chainable ResultSets</li>
<li>lazy querying</li>
</ul></ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Strengths and Weaknesses</h1>
<ul>
<li>strengths</li>
<ul>
<li>chainable ResultSets</li>
<li>lazy querying</li>
<li>good support for custom SQL</li>
</ul></ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Strengths and Weaknesses</h1>
<ul>
<li>strengths</li>
<ul>
<li>chainable ResultSets</li>
<li>lazy querying</li>
<li>good support for custom SQL</li>
<li>prefetching</li>
</ul></ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Strengths and Weaknesses</h1>
<ul>
<li>strengths</li>
<ul>
<li>chainable ResultSets</li>
<li>lazy querying</li>
<li>good support for custom SQL</li>
<li>prefetching</li>
<li>lots of nice extensions</li>
</ul></ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Strengths and Weaknesses</h1>
<ul>
<li>strengths</li>
<ul>
<li>chainable ResultSets</li>
<li>lazy querying</li>
<li>good support for custom SQL</li>
<li>prefetching</li>
<li>lots of nice extensions</li>
</ul></ul>
<ul>
<li>weaknesses</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Strengths and Weaknesses</h1>
<ul>
<li>strengths</li>
<ul>
<li>chainable ResultSets</li>
<li>lazy querying</li>
<li>good support for custom SQL</li>
<li>prefetching</li>
<li>lots of nice extensions</li>
</ul></ul>
<ul>
<li>weaknesses</li>
<ul>
<li>non-ORM-y things are possible, but can be cumbersome</li>
</ul></ul>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Chainable ResultSets</h1>
<pre class="formatter_pre">my $styx_tracks =
$music_schema->resultset('Artist')
->search({ name => 'Styx' })
->albums
->tracks;
SELECT ...
FROM artist
JOIN albums ON ...
JOIN tracks ON ...
WHERE artist.name = 'Styx'
</pre>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Lazy Querying</h1>
<ul>
<li>does not run the query until data is actually needed</li>
</ul>
<pre class="formatter_pre">
# fetch all
my @tracks = $styx_tracks->all;
# or iterate
while( my $track = $styx_tracks->next ) { ... }
</pre>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Custom SQL</h1>
<ul>
<li>can make a view <tt>ResultSource</tt> for big tuned queries</li>
</ul>
<pre class="formatter_pre">
package My::Schema::SummarizedFrobs;
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
__PACKAGE__->result_source_instance->view_definition(<<'');
SELECT omg_so_much_stuff
UNION
SELECT ( SELECT blah blah blah FROM blah ),
( blah blah blah ),
WHERE blah blah blah
UNION
blah blah blah
__PACKAGE__->add_column( <cols in your view> )
</pre>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Custom SQL</h1>
<ul>
<li>for custom conditions, searches accept <tt>SQL::Abstract</tt> syntax</li>
</ul>
<pre class="formatter_pre">
$schema->resultSet('Sequence::Feature')
->search({
'me.feature_id' =>
\[ "IN( select feature_id from clone_feature where clone_id = ?)",
[ dummy => $self->clone_id ],
],
},
{ rows => 10,
order_by => [qw[ me.name me.type_id ]],
having
});
</pre>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Prefetching</h1>
<pre class="formatter_pre"># query will get the wombat organism, and also prefetch *all its
# chromosomes and features on those chromosomes*
my $rs = $schema->resultset('Organism')->search(
{ genus => 'Vombatus', species => 'ursinus' },
{ prefetch => { chromosomes => features => } },
);
</pre>
<p>
(in a real biological DB this would probably blow your memory)
</p>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Extensions</h1>
<ul>
<li><tt>DBIx::Class::Helpers</tt></li>
<ul>
<li><tt>fREW</tt>'s miscellaneous things</li>
</ul></ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Extensions</h1>
<ul>
<li><tt>DBIx::Class::Helpers</tt></li>
<ul>
<li><tt>fREW</tt>'s miscellaneous things</li>
</ul>
<li><tt>DBIx::Class::Cursor::Cached</tt></li>
<ul>
<li>tunable, flexible resultset caching</li>
</ul></ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Extensions</h1>
<ul>
<li><tt>DBIx::Class::Helpers</tt></li>
<ul>
<li><tt>fREW</tt>'s miscellaneous things</li>
</ul>
<li><tt>DBIx::Class::Cursor::Cached</tt></li>
<ul>
<li>tunable, flexible resultset caching</li>
</ul>
<li><tt>DBIx::Class::Ordered</tt></li>
<ul>
<li>nice for doing ordering or ranking columns in a table</li>
</ul></ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Extensions</h1>
<ul>
<li><tt>DBIx::Class::Helpers</tt></li>
<ul>
<li><tt>fREW</tt>'s miscellaneous things</li>
</ul>
<li><tt>DBIx::Class::Cursor::Cached</tt></li>
<ul>
<li>tunable, flexible resultset caching</li>
</ul>
<li><tt>DBIx::Class::Ordered</tt></li>
<ul>
<li>nice for doing ordering or ranking columns in a table</li>
</ul>
<li><tt>DBIx::Class::InflateColumn::DateTime</tt>, <tt>DBIx::Class::Timestamp</tt></li>
<ul>
<li>work with dates, times, and timestamps as <tt>DateTime</tt> objects</li>
</ul></ul>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Thread-Safe / Fork-Safe</h1>
<ul>
<li><tt>theory</tt>'s <tt>DBix::Connector</tt></li>
</ul>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Non-linear Join</h1>
<pre class="formatter_pre"># get features via the potato organism, also joining in the cvterms table
my $potato_bacs =
$schema->resultset('Organism')
->search({ species => 'Solanum tuberosum' })
->search_related( 'features',
{ 'type.name' => 'BAC_clone'},
{ 'join' => 'type' },
);
</pre>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Non-linear Join</h1>
<pre class="formatter_pre"># the equivalent bare SQL
my $potato_bacs = $dbh->selectall_arrayref( <<EOS, undef, 'Solanum tuberosum', 'BAC_clone');
SELECT features.feature_id
, features.dbxref_id
, features.organism_id
, features.name
, features.uniquename
, features.residues
, features.seqlen
, features.md5checksum
, features.type_id
, features.is_analysis
, features.is_obsolete
, features.timeaccessioned
, features.timelastmodified
FROM organism me
LEFT JOIN feature features
ON features.organism_id = me.organism_id
JOIN cvterm type
ON type.cvterm_id = features.type_id
WHERE species = ? AND type.name = ?
EOS
</pre>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Convenient Loading of Relationships</h1>
<pre class="formatter_pre">$chado->resultset( 'Cv::Cv' )
->find_or_create({ name => 'My Fake Ontology' })
->create_related( 'cvterm',
{ name => 'MyFakeTerm' });
</pre>
<p>
makes the SQL:
</p>
<pre class="formatter_pre">SELECT me.cv_id
, me.name
, me.definition
FROM cv me
WHERE ( me.name = 'my fake ontology' )
INSERT INTO cv ( name )
VALUES ( 'my fake ontology' )
RETURNING cv_id
INSERT INTO cvterm ( cv_id, name )
VALUES ( ?, 'MyFakeTerm' )
</pre>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>Transactions</h1>
<pre class="formatter_pre">$schema->txn_do(sub {
$schema->resultset('Cv::Cv')
->find_or_create({ name => 'My Fake Ontology' })
->create_related( 'cvterm', { name => 'MyFakeTerm' } );
});
</pre>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>The Real Advantages of DBIC</h1>
<ul>
<li>easier to manipulate and assemble queries</li>
</ul>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>The Real Advantages of DBIC</h1>
<ul>
<li>complex joined queries (Chado queries) are very easy and compact</li>
</ul>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>The Real Advantages of DBIC</h1>
<ul>
<li>SQL syntax errors are more difficult to make</li>
</ul>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>The Real Advantages of DBIC</h1>
<ul>
<li>it's all objects. you can delegate to them, pass them around, etc.</li>
<li>HOWEVER:</li>
</ul>
<small>continued...</small>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h1>The Real Advantages of DBIC</h1>
<ul>
<li>it's all objects. you can delegate to them, pass them around, etc.</li>
<li>HOWEVER:</li>
<ul>
<li>usually you don't want to subclass them</li>
<li>but, see <tt>DBIx::Class::Manual::Cookbook</tt></li>
</ul></ul>
</div>
<!-- END slide -->
<!-- BEGIN slide -->
<div class="slide">
<h2>That's All</h2>
<ul>
<li>The END</li>
</ul>
</div>
<!-- END slide -->
</body>
</html>
<!-- END s5 -->