rearrange slides so that searching is more obvious
[dbsrgits/dbix-class-introduction-presentation.git] / slideshow.html
CommitLineData
52d980cb 1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
4<html xmlns="http://www.w3.org/1999/xhtml">
5
6<head>
7<title>DBIx::Class (aka DBIC)</title>
8<!-- metadata -->
9<meta name="contributor" content="youcan[64]netzgesta[46]de" />
10<meta name="publisher" content="s5.netzgesta.de" />
11<meta name="description" content="S5 1.3 is a very flexible and lightweight slide show system available for anyone to use (including transitions and scalable fonts and images)" />
12<meta name="keywords" content="S5, version 1.3, slide show, presentation-mode, projection-mode, powerpoint-like, scala-like, keynote-like, incremental display, scalable fonts, scalable images, transitions, notes, osf, xoxo, css, javascript, xhtml, public domain" />
13
14<meta name="generator" content="S5" />
15<meta name="version" content="1" />
16<meta name="subject" content="DBIx::Class" />
17<meta name="author" content="See first slide" />
18<meta name="company" content="N/A" />
19<meta name="robots" content="index, follow" />
20<meta name="revisit-after" content="7 days" />
21<!-- meta additionally -->
22<meta http-equiv="content-type" content="text/html; charset=utf-8" />
23<meta http-equiv="Content-Script-Type" content="text/javascript" />
24<meta http-equiv="Content-Style-Type" content="text/css" /><!-- configuration parameters -->
25<meta name="defaultView" content="slideshow" />
26<meta name="controlVis" content="hidden" />
27<!-- configuration transition extension -->
28<meta name="tranSitions" content="true" />
29<meta name="fadeDuration" content="500" />
30<meta name="incrDuration" content="250" />
31<!-- configuration autoplay extension -->
32<meta name="autoMatic" content="false" />
33<meta name="playLoop" content="true" />
34<meta name="playDelay" content="10" />
35<!-- configuration audio extension -->
36<meta name="audioSupport" content="false" />
37<meta name="audioVolume" content="0" />
38<meta name="audioError" content="false" />
39<!-- configuration audio debug -->
40<meta name="audioDebug" content="false" />
41<!-- style sheet links -->
42<link rel="stylesheet" href="ui/scala_utf/slides.css" type="text/css" media="projection" id="slideProj" />
43<link rel="stylesheet" href="ui/scala_utf/outline.css" type="text/css" media="screen" id="outlineStyle" />
44<link rel="stylesheet" href="ui/scala_utf/print.css" type="text/css" media="print" id="slidePrint" />
45<link rel="stylesheet" href="ui/scala_utf/opera.css" type="text/css" media="projection" id="operaFix" />
46<!-- embedded styles -->
47<style type="text/css" media="all">
48.imgcon {width: 100%; margin: 0 auto; padding: 0; text-align: center;}
49#anim {width: 33%; height: 320px; position: relative;}
50#anim img {position: absolute; top: 0px; left: 0px;}
51.red {color: red;}
52.grey {color: gray;}
53</style>
54<!-- S5 JS -->
55<script src="ui/scala_utf/slides.js" type="text/javascript"></script>
56</head>
57<body>
58
59<div class="layout">
60 <div id="controls"><!-- DO NOT EDIT --></div>
61 <div id="currentSlide"><!-- DO NOT EDIT --></div>
62 <div id="header"></div>
63 <div id="footer">
64 <h1>DBIx::Class Introduction</h1>
65 <h2>YAPC::NA 2010</h2>
66 </div>
67</div>
68
69<div class="presentation">
70
71 <div class="slide">
72 <h1>DBIX::Class (aka DBIC)</h1>
73 <h3>for (advanced) beginners</h3>
0cffcad7 74 </div>
75
76 <div class="slide">
a7b4c670 77 <h1>Contact Info</h1>
78 <ul>
79 <li>IRC: irc.perl.org #dbix-class</li>
80 <li>ML: <a href="http://lists.scsys.co.uk/mailman/listinfo/dbix-class">http://lists.scsys.co.uk/mailman/listinfo/dbix-class</a></li>
81 <li><a href="http://search.cpan.org/perldoc?DBIx::Class">DBIx::Class</a> yo</li>
82 </ul>
83 </div>
84
85 <div class="slide">
0cffcad7 86 <h1>Authors</h1>
87 <h4>Originally Leo Lapworth @ LPW 2009</h4>
da0b46fd 88 <h4>Amiri Barksdale</h4>
0cffcad7 89 <h4>Justin D. Hunter</h4>
5cac74c7 90 <h4>Arthur Axel "fREW" Schmidt</h4>
52d980cb 91 </div>
92
93 <div class="slide">
7365a110 94 <h1>What's up guys?</h1>
63d0b680 95 <ul class="incremental">
96 <li>How many people have used any ORM?</li><ul class="incremental">
97 <li>In Perl?<ul class="incremental">
98 <li>DBIC?</li>
99 <li>Class::DBI?</li>
100 <li>Rose::DB?</li>
a7b4c670 101 <li>Fey::ORM?</li>
63d0b680 102 <li>Others?</li>
0cffcad7 103 </ul></li>
63d0b680 104 <li>AR?</li>
105 <li>(N)Hibernate?</li>
106 </ul></li>
107 </ul>
52d980cb 108 </div>
109
110 <div class="slide">
da0b46fd 111 <h1>Purpose</h1>
112 <p>The purpose of this talk is to show you as many features of
113 DBIx::Class in 40 minutes so that when you need to do something with
114 it later you will know what's possible</p>
78c1762e 115 <ul class="incremental">
116 <li>Note: links in slides are so you can find docs for what I'm talking about later</li>
117 </ul>
da0b46fd 118 </div>
119
120 <div class="slide">
52d980cb 121 <h1>DBIx::Class?</h1>
122 <ul>
123 <li>ORM (object relational mapper)</li>
124 <li>SQL &lt;-&gt; OO (using objects instead of SQL)</li>
52d980cb 125 <li>There are many ORMs, DBIx::Class just happens to be the best in Perl (personal opinion)</li>
126 </ul>
127 </div>
128
129 <div class="slide">
da0b46fd 130 <h1>Meta</h1>
131 <p>These are reasons that are not technical or inherent to
132 the code of DBIC, but are totally awesome things about it.</p>
133 </div>
134
135 <div class="slide">
136 <h1>Large Community</h1>
137 <p>Currently there are 88 people listed as contributors to DBIC. That
138 ranges from documentation help, to test help, to added features,
139 to entire database support.</p>
140 </div>
141
142 <div class="slide">
143 <h1>Active Community</h1>
144 <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>
145 </div>
146
147 <div class="slide">
148 <h1>Responsive Community</h1>
149 <ul class="incremental">
78c1762e 150 <li>needed MSSQL order-by support, they helped me add support</li>
da0b46fd 151 <li>generally very welcoming of people willing to help</li>
152 </ul>
153 </div>
154
155 <div class="slide">
156 <h1>General ORM</h1>
157 <p>These are things that are in most other ORMs, but are still reasons
158 to use DBIC over raw SQL.</p>
159 </div>
160
161 <div class="slide">
162 <h1>Cross DB</h1>
163 <p>The vast majority of code should run on all databases without needing tweaking</p>
52d980cb 164 </div>
165
166 <div class="slide">
7365a110 167 <h1>Basic CRUD</h1>
da0b46fd 168 <ul class="incremental">
52d980cb 169 <li><strong>C</strong> - Create</li>
170 <li><strong>R</strong> - Read</li>
171 <li><strong>U</strong> - Update</li>
172 <li><strong>D</strong> - Delete</li>
173 </ul>
174 </div>
175
176 <div class="slide">
5cac74c7 177 <h1>SQL: Create</h1>
52d980cb 178<pre>my $sth = $dbh-&gt;prepare('
179 INSERT INTO books
01b7b88c 180 (title, author_id)
52d980cb 181 values (?,?)
182');
183
184$sth-&gt;execute(
185 'A book title', $author_id
186);</pre>
187 </div>
188
189 <div class="slide">
5cac74c7 190 <h1>DBIC: Create</h1>
78c1762e 191<pre>my $book = $book_rs-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#create">create</a>({
01b7b88c 192 title =&gt; 'A book title',
193 author_id =&gt; $author_id,
52d980cb 194});</pre>
da0b46fd 195 <ul class="incremental">
196 <li>No need to pair placeholders and values</li>
ec535d03 197 <li>Automatically gets autoincremented id for you</li>
a33b5750 198 <li>Transparently uses INSERT ... RETURNING for databases that support it</li>
da0b46fd 199 </ul>
52d980cb 200 </div>
201
202 <div class="slide">
7365a110 203 <h1>SQL: Read</h1>
204<pre>my $sth = $dbh-&gt;prepare('
205 SELECT title,
206 authors.name as author_name
207 FROM books, authors
208 WHERE books.author = authors.id
63d0b680 209');
7365a110 210
63d0b680 211while( my $book = $sth-&gt;fetchrow_hashref() ) {
7365a110 212 print 'Author of '
213 . $book-&gt;{title}
214 . ' is '
215 . $book-&gt;{author_name}
216 . "\n";
217}</pre>
52d980cb 218 </div>
219
220 <div class="slide">
5cac74c7 221 <h1>DBIC: Read</h1>
78c1762e 222<pre>my $book = $book_rs-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#find">find</a>($book_id);
52d980cb 223
78c1762e 224my $book = $book_rs-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#search">search</a>({
52d980cb 225 title =&gt; 'A book title',
78c1762e 226}, { rows =&gt; 1 })-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#next">next</a>;
52d980cb 227
01b7b88c 228my @books = $book_rs-&gt;search({
52d980cb 229 author =&gt; $author_id,
63d0b680 230})-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#all">all</a>;
52d980cb 231
63d0b680 232while( my $book = $books_rs-&gt;next ) {
52d980cb 233 print 'Author of '
234 . $book-&gt;title
235 . ' is '
236 . $book-&gt;author-&gt;name
237 . "\n";
63d0b680 238}
239</pre>
240 <ul class="incremental">
241 <li>TMTOWTDI</li>
242 </ul>
52d980cb 243 </div>
244
245 <div class="slide">
7365a110 246 <h1>SQL: Update</h1>
247<pre>my $update = $dbh-&gt;prepare('
248 UPDATE books
249 SET title = ?
250 WHERE id = ?
251');
252
253$update-&gt;execute(
254 'New title',<strong>$book_id</strong>
255);</pre>
256 </div>
257
258 <div class="slide">
5cac74c7 259 <h1>DBIC: Update</h1>
78c1762e 260<pre>$book-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::Row#update">update</a>({
52d980cb 261 title =&gt; 'New title',
262});</pre>
513517e4 263 <ul class="incremental">
a33b5750 264 <li>Won't update unless value changes</li>
513517e4 265 </ul>
52d980cb 266 </div>
267
268 <div class="slide">
7365a110 269 <h1>SQL: Delete</h1>
270<pre>my $delete = $dbh-&gt;prepare('
271 DELETE FROM books
272 WHERE id = ?
273');
274
275$delete-&gt;execute(<strong>$book_id</strong>);</pre>
276 </div>
277
278 <div class="slide">
5cac74c7 279 <h1>DBIC: Delete</h1>
78c1762e 280<pre>$book-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::Row#delete">delete</a>;</pre>
52d980cb 281 </div>
282
283 <div class="slide">
e4676fb8 284 <h1>SQL: Search</h1>
285<pre>my $sth = $dbh-&gt;prepare('
286 SELECT title,
287 authors.name as author_name
288 FROM books
289 WHERE books.name LIKE "%monte cristo%" AND
290 books.topic = "jailbreak"
291');
292</pre>
293 </div>
294
295 <div class="slide">
296 <h1>DBIC: Search</h1>
297<pre>
298my $book = $book_rs-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#search">search</a>({
299 'me.name' =&gt; { -like =&gt; '%monte cristo%' },
300 'me.topic' =&gt; 'jailbreak',
301})-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#next">next</a>;
302</pre>
303 <ul class="incremental">
304 <li><a href="http://search.cpan.org/perldoc?SQL::Abstract">SQL::Abstract</a></li>
305 <li>(kinda) introspectible</li>
306 <li>Prettier than SQL</li>
307 </ul>
308 </div>
309
310 <div class="slide">
da0b46fd 311 <h1>OO Overidability</h1>
312 <ul class="incremental">
313 <li>Override new if you want to do validation</li>
314 <li>Override delete if you want to disable deletion</li>
315 <li>and on and on</li>
316 </ul>
317 <div class="notes">
318 <p>I got yelled at about this before by people, so
319 we don't get EVERYTHING from OO, but we do get a lot
320 so :-P</p>
321 </div>
52d980cb 322 </div>
323
324 <div class="slide">
da0b46fd 325 <h1>Convenience Methods</h1>
326 <ul class="incremental">
78c1762e 327 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#find_or_create">find_or_create</a></li>
328 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#update_or_create">update_or_create</a></li>
da0b46fd 329 </ul>
492be2ae 330 </div>
331
332 <div class="slide">
da0b46fd 333 <h1>Non-column methods</h1>
334 <p>Need a method to get a user's gravatar URL? Add a
335 gravatar_url method to their Result class</p>
336 </div>
337
338 <div class="slide">
339 <h1>RELATIONSHIPS</h1>
340 <ul class="incremental">
341 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship#belongs_to">belongs_to</a></li>
342 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship#has_many">has_many</a></li>
343 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship#might_have">might_have</a></li>
344 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship#has_one">has_one</a></li>
345 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship#many_to_many">many_to_many</a> (technically not a relationship)</li>
346 <li>SET AND FORGET</li>
347 </ul>
348 </div>
349
350 <div class="slide">
351 <h1>DBIx::Class Specific Features</h1>
352 <p>These things may be in other ORM's, but they are very specific, so doubtful</p>
52d980cb 353 </div>
354
355 <div class="slide">
9158dee5 356 <h1>-&gt;deploy</h1>
357 <p>Perl -&gt; DB</p>
d1ed303d 358<pre>my $schema = Foo::Schema-&gt;connect(
359 $dsn, $user, $pass
360);
78c1762e 361$schema-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::Schema#deploy">deploy</a>
9158dee5 362</pre>
363<p>See also: <a href="http://search.cpan.org/perldoc?DBIx::Class::DeploymentHandler">DBIx::Class::DeploymentHandler</a></p>
364 </div>
365
366 <div class="slide">
52d980cb 367 <h1>Schema::Loader</h1>
9158dee5 368 <p>DB -&gt; Perl</p>
451b57c2 369<pre>package Foo::Schema;
c7321880 370use strict; use warnings;
78c1762e 371use base '<a href="http://search.cpan.org/perldoc?DBIx::Class::Schema::Loader">DBIx::Class::Schema::Loader</a>';
372__PACKAGE__-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::Schema::Loader::Base#CONSTRUCTOR_OPTIONS">loader_options</a>({
c7321880 373 naming =&gt; 'v7',
374 debug =&gt; $ENV{DBIC_TRACE},
375});
3761;
377
378# elsewhere...
379
d1ed303d 380my $schema = Foo::Schema-&gt;connect(
381 $dsn, $user, $pass
382);
c7321880 383</pre>
52d980cb 384 </div>
385
386 <div class="slide">
da0b46fd 387 <h1>Populate</h1>
388 <p>Made for inserting lots of rows very quicky into database</p>
78c1762e 389<pre>$schema-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::Schema#populate">populate</a>([ Users =&gt;
da0b46fd 390 [qw( username password )],
d1ed303d 391 [qw( frew &gt;=4char$ )],
da0b46fd 392 [qw( ... )],
393 [qw( ... )],
394);
395</pre>
396 <ul class="incremental">
397 <li>I use this to <a href="http://blog.afoolishmanifesto.com/archives/1255">export our whole (200M~) db to SQLite</a></li>
398 </ul>
52d980cb 399 </div>
400
401 <div class="slide">
da0b46fd 402 <h1>Multicreate</h1>
403 <p>Create an object and all of it's related objects all at once</p>
78c1762e 404<pre>$schema-&gt;resultset('Author')-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#create">create</a>({
da0b46fd 405 name =&gt; 'Stephen King',
406 books =&gt; [{ title =&gt; 'The Dark Tower' }],
407 address =&gt; {
408 street =&gt; '123 Turtle Back Lane',
409 state =&gt; { abbreviation =&gt; 'ME' },
d1ed303d 410 city =&gt; { name =&gt; 'Lowell' },
da0b46fd 411 },
7e77ca11 412});
da0b46fd 413</pre>
414 <div class="notes">
415 <ul>
416 <li>books is a has_many</li>
417 <li>address is a belongs_to which in turn belongs to state and city each</li>
418 <li>for this to work right state and city must mark abbreviation and name as unique</li>
419 </ul>
420 </div>
421 </div>
422
423 <div class="slide">
424 <h1>Extensible</h1>
425 <p>DBIx::Class helped pioneer fast MI in Perl 5 with Class::C3, so it is made
426 to allow extensions to nearly every part of it.</p>
427 </div>
428
429 <div class="slide">
430 <h1>Extensible: DBIC::Helpers</h1>
431 <ul class="incremental">
78c1762e 432 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Helper::ResultSet::IgnoreWantarray">DBIC::Helper::ResultSet::IgnoreWantarray</a></li>
433 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Helper::ResultSet::Random">DBIC::Helper::ResultSet::Random</a></li>
434 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Helper::ResultSet::SetOperations">DBIC::Helper::ResultSet::SetOperations</a></li>
435 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Helper::ResultSet::JoinTable">DBIC::Helper::Row::JoinTable</a></li>
436 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Helper::ResultSet::NumifyGet">DBIC::Helper::Row::NumifyGet</a></li>
437 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Helper::ResultSet::SubClass">DBIC::Helper::Row::SubClass</a></li>
438 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Helper::ResultSet::ToJSON">DBIC::Helper::Row::ToJSON</a></li>
da0b46fd 439 </ul>
440 </div>
441
442 <div class="slide">
78c1762e 443 <h1>Extensible: <a href="http://search.cpan.org/perldoc?DBIx::Class::TimeStamp">DBIC::TimeStamp</a></h1>
da0b46fd 444 <ul class="incremental">
445 <li>Cross DB</li>
446 <li>set_on_create</li>
447 <li>set_on_update</li>
448 </ul>
449 </div>
450
451 <div class="slide">
d1ed303d 452 <h1>Extensible: Kioku</h1>
da0b46fd 453 <ul class="incremental">
78c1762e 454 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::Schema::KiokuDB">DBIx::Class::Schema::KiokuDB</a></li>
da0b46fd 455 <li>Kioku is the new hotness</li>
456 <li>Mix RDBMS with Object DB</li>
457 <li>beta ( == sexy )</li>
458 </ul>
459 </div>
460
461 <div class="slide">
da0b46fd 462 <h1>Result vs ResultSet</h1>
463 <ul class="incremental">
464 <li>Result == Row</li>
513517e4 465 <li>ResultSet == Query Plan<ul class="incremental">
466 <li>Internal Join Optimizer for all DB's (!!!)</li>
467 </ul></li>
da0b46fd 468 <li>(less important but...)</li>
469 <li>ResultSource == Table</li>
470 <li>Storage == Database</li>
471 </ul>
472 </div>
473
474 <div class="slide">
78c1762e 475 <h1><a href="http://search.cpan.org/perldoc?DBIx::Class::Manual::Cookbook#Predefined_searches">ResultSet methods</a></h1>
da0b46fd 476<pre>package MyApp::Schema::ResultSet::Book;
477use base 'DBIx::Class::ResultSet';
478sub good {
d1ed303d 479 my $self = shift;
480 $self-&gt;search({
481 $self-&gt;current_source_alias .
482 '.rating' =&gt; { '&gt;=' =&gt; 4 },
da0b46fd 483 })
484};
485sub cheap {
d1ed303d 486 my $self = shift;
487 $self-&gt;search({
488 $self-&gt;current_source_alias .
489 '.price' =&gt; { '&lt;=' =&gt; 5}
da0b46fd 490 })
491};
492# ...
4931;
494 </pre>
d1ed303d 495 </div>
496
497 <div class="slide">
498 <h1>ResultSet method notes</h1>
da0b46fd 499 <ul class="incremental">
500 <li>All searches should be ResultSet methods</li>
501 <li>Name has obvious meaning</li>
78c1762e 502 <li><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#current_source_alias">current_source_alias</a> helps things to work no matter what</li>
da0b46fd 503 </ul>
504 </div>
505
506 <div class="slide">
507 <h1>ResultSet method in Action</h1>
508 <pre>$schema-&gt;resultset('Book')-&gt;good</pre>
509 </div>
510
511 <div class="slide">
512 <h1>ResultSet Chaining</h1>
513<pre>$schema-&gt;resultset('Book')
514 -&gt;good
515 -&gt;cheap
516 -&gt;recent
6e5edefe 517</pre>
52d980cb 518 </div>
519
520 <div class="slide">
7e77ca11 521 <h1>search_related</h1>
d1ed303d 522<pre>my $score = $schema-&gt;resultset('User')
523 -&gt;search({'me.userid' =&gt; 'frew'})
78c1762e 524 -&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#related_resultset">related_resultset</a>('access')
3ab0ef72 525 -&gt;related_resultset('mgmt')
d1ed303d 526 -&gt;related_resultset('orders')
527 -&gt;telephone
78c1762e 528 -&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#search_related">search_related</a>( shops =&gt; {
d1ed303d 529 'shops.datecompleted' =&gt; {
530 -between =&gt; ['2009-10-01','2009-10-08']
531 }
532 })-&gt;completed
533 -&gt;related_resultset('rpt_score')
78c1762e 534 -&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#get_column">get_column</a>('raw_scores')
d1ed303d 535 -&gt;first;
3ab0ef72 536</pre>
537 </div>
538
539 <div class="slide">
7e77ca11 540 <h1>bonus rel methods</h1>
78c1762e 541<pre>my $book = $author-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship::Base#create_related">create_related</a>(
d1ed303d 542 <strong>books</strong> =&gt; {
543 title =&gt; 'Another Discworld book',
544 }
545);
52d980cb 546
78c1762e 547my $book2 = $pratchett-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship::Base#add_to_$rel">add_to_<strong>books</strong></a>({
7e77ca11 548 title =&gt; 'MOAR Discworld book',
549});</pre>
550 <ul class="incremental">
551 <li>Automaticaly fills in foreign key for you</li>
552 </ul>
52d980cb 553 </div>
554
555 <div class="slide">
7e77ca11 556 <h1>Excellent Transaction Support</h1>
78c1762e 557<pre>$schema-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::Schema#txn_do">txn_do</a>(sub {
7e77ca11 558 ...
559});
52d980cb 560
78c1762e 561my $guard = $schema-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::Schema#txn_scope_guard">txn_scope_guard</a>;
7e77ca11 562# ...
563$guard-&gt;commit;
52d980cb 564
78c1762e 565$schema-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::Schema#txn_begin">txn_begin</a>; # &lt;-- low level
7e77ca11 566# ...
78c1762e 567$schema-&gt;<a href="http://search.cpan.org/perldoc?DBIx::Class::Schema#txn_commit">txn_commit</a>;
7e77ca11 568</pre>
52d980cb 569 </div>
570
571 <div class="slide">
7e77ca11 572 <h1>InflateColumn</h1>
2a65778d 573<pre>package Foo::Schema::Result::Book;
574use base 'DBIx::Class::Core';
d1ed303d 575use DateTime::Format::MySQL;
451b57c2 576# Result code here
78c1762e 577__PACKAGE__-&gt;load_components('<a href="http://search.cpan.org/perldoc?DBIx::Class::InflateColumn">InflateColumn</a>');
578__PACKAGE__-&gt;<strong><a href="http://search.cpan.org/perldoc?DBIx::Class::InflateColumn#inflate_column">inflate_column</a></strong>(
52d980cb 579 <strong>date_published</strong> =&gt; {
d1ed303d 580 inflate =&gt; sub {
581 DateTime::Format::MySQL-&gt;parse_date(
582 shift
583 )
584 },
585 deflate =&gt; sub { shift-&gt;ymd },
451b57c2 586 },
52d980cb 587);
d1ed303d 588# Automatic see: DBIC::InflateColumn::DateTime</pre>
52d980cb 589 </div>
590
591 <div class="slide">
7e77ca11 592 <h1>InflateColumn: deflation</h1>
52d980cb 593<pre>$book-&gt;date_published(DateTime-&gt;now);
594$book-&gt;update;</pre>
595 </div>
596
597 <div class="slide">
7e77ca11 598 <h1>InflateColumn: inflation</h1>
d1ed303d 599<pre>say $book-&gt;date_published-&gt;month_abbr;</pre>
52d980cb 600
601<strong><em>Nov</em></strong>
602 </div>
603
604 <div class="slide">
7e77ca11 605 <h1>FilterColumn</h1>
606<pre>package Foo::Schema::Result::Book;
2a65778d 607use base 'DBIx::Class::Core';
7e77ca11 608# Result code here
78c1762e 609__PACKAGE__-&gt;load_components('<a href="http://search.cpan.org/perldoc?DBIx::Class::FilterColumn">FilterColumn</a>');
52d980cb 610
78c1762e 611__PACKAGE__-&gt;<strong><a href="http://search.cpan.org/perldoc?DBIx::Class::FilterColumn#filter_column">filter_column</a></strong>(
7e77ca11 612 <strong>length</strong> =&gt; {
613 to_storage =&gt; 'to_metric',
614 from_storage =&gt; 'to_imperial',
615 },
52d980cb 616);
52d980cb 617
7e77ca11 618sub to_metric { $_[1] * .305 }
619sub to_imperial { $_[1] * 3.28 }
52d980cb 620 </div>
621
622 <div class="slide">
78c1762e 623 <h1><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSetColumn">ResultSetColumn</a></h1>
d1ed303d 624<pre>my $rsc = $schema-&gt;resultset('Book')
625 -&gt;get_column('price');
63d0b680 626$rsc-&gt;first;
627$rsc-&gt;all;
7e77ca11 628$rsc-&gt;min;
629$rsc-&gt;max;
630$rsc-&gt;sum;
6548782a 631</pre>
52d980cb 632 </div>
633
634 <div class="slide">
7e77ca11 635 <h1>Aggregates</h1>
636<pre>my @res = $rs-&gt;search({}, {
78c1762e 637 <a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#select">select</a> =&gt; [
d1ed303d 638 'price',
639 'genre',
640 { max =&gt; price },
641 { avg =&gt; price },
642 ],
78c1762e 643 <a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#as">as</a> =&gt; [
d1ed303d 644 qw(price genre max_price avg_price)
645 ],
78c1762e 646 <a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#group_by">group_by</a> =&gt; [qw(price genre)],
7e77ca11 647});
648for (@res) {
649 say $_-&gt;price . ' ' . $_-&gt;genre;
650 say $_-&gt;get_column('max_price');
651 say $_-&gt;get_column('min_price');
652}</pre>
d1ed303d 653 </div>
654
655 <div class="slide">
656 <h1>Aggregates Notes</h1>
7e77ca11 657 <ul class="incremental">
658 <li>Careful, get_column can basicaly mean THREE things</li>
659 <li>private for get what you should use an accessor for</li>
660 <li>public for what there is no accessor for</li>
661 <li>public for get resultset column (prev slide)</li>
662 </ul>
52d980cb 663 </div>
664
665 <div class="slide">
7e77ca11 666 <h1>HRI</h1>
667<pre>$rs-&gt;search({}, {
78c1762e 668 <a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#result_class">result_class</a> =&gt;
669 '<a href="http://search.cpan.org/perldoc?DBIx::Class::ResultClass::HashRefInflator">DBIx::Class::ResultClass::HashRefInflator</a>',
52d980cb 670});</pre>
7e77ca11 671 <ul class="incremental">
672 <li>Easy on memory</li>
673 <li>Mega fast</li>
674 <li>Great for quick debugging</li>
675 <li>Great for performance tuning (we went from 2m to &lt; 3s)</li>
52d980cb 676 </ul>
677 </div>
678
679 <div class="slide">
78c1762e 680 <h1><a href="http://search.cpan.org/perldoc?DBIx::Class::Manual::Cookbook#Subqueries">Subquery</a> Support</h1>
d1ed303d 681<pre>my $inside_query = $schema-&gt;resultset('Artist')
682 -&gt;search({
7e77ca11 683 name =&gt; [ 'Billy Joel', 'Brittany Spears' ],
d1ed303d 684})-&gt;get_column('id')-&gt;as_query;
9158dee5 685
7e77ca11 686my $rs = $schema-&gt;resultset('CD')-&gt;search({
d1ed303d 687 artist_id =&gt; { -in =&gt; $inside_query },
7e77ca11 688});</pre>
52d980cb 689 </div>
690
691 <div class="slide">
78c1762e 692 <h1><a href="http://search.cpan.org/perldoc?SQL::Abstract#Literal_SQL_with_placeholders_and_bind_values_(subqueries)">Bare SQL w/ Placeholders</a></h1>
7e77ca11 693<pre>$rs-&gt;update({
d1ed303d 694 # !!! SQL INJECTION VECTOR
695 price =&gt; \"price + $inc",
7e77ca11 696});
697
698$rs-&gt;update({
699 price =&gt; \['price + ?', [inc =&gt; $inc]],
700});
701</pre>
52d980cb 702 </div>
703
704 <div class="slide">
7e77ca11 705 <h1>Questions?</h1>
52d980cb 706 </div>
707
708 <div class="slide">
7e77ca11 709 <h1>END</h1>
52d980cb 710 </div>
52d980cb 711</div>
712</body>
713</html>