Commit | Line | Data |
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 <-> 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->prepare(' |
179 | INSERT INTO books |
01b7b88c |
180 | (title, author_id) |
52d980cb |
181 | values (?,?) |
182 | '); |
183 | |
184 | $sth->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-><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#create">create</a>({ |
01b7b88c |
192 | title => 'A book title', |
193 | author_id => $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->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 |
211 | while( my $book = $sth->fetchrow_hashref() ) { |
7365a110 |
212 | print 'Author of ' |
213 | . $book->{title} |
214 | . ' is ' |
215 | . $book->{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-><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#find">find</a>($book_id); |
52d980cb |
223 | |
78c1762e |
224 | my $book = $book_rs-><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#search">search</a>({ |
52d980cb |
225 | title => 'A book title', |
78c1762e |
226 | }, { rows => 1 })-><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#next">next</a>; |
52d980cb |
227 | |
01b7b88c |
228 | my @books = $book_rs->search({ |
52d980cb |
229 | author => $author_id, |
63d0b680 |
230 | })-><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#all">all</a>; |
52d980cb |
231 | |
63d0b680 |
232 | while( my $book = $books_rs->next ) { |
52d980cb |
233 | print 'Author of ' |
234 | . $book->title |
235 | . ' is ' |
236 | . $book->author->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->prepare(' |
248 | UPDATE books |
249 | SET title = ? |
250 | WHERE id = ? |
251 | '); |
252 | |
253 | $update->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-><a href="http://search.cpan.org/perldoc?DBIx::Class::Row#update">update</a>({ |
52d980cb |
261 | title => '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->prepare(' |
271 | DELETE FROM books |
272 | WHERE id = ? |
273 | '); |
274 | |
275 | $delete->execute(<strong>$book_id</strong>);</pre> |
276 | </div> |
277 | |
278 | <div class="slide"> |
5cac74c7 |
279 | <h1>DBIC: Delete</h1> |
78c1762e |
280 | <pre>$book-><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->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> |
298 | my $book = $book_rs-><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#search">search</a>({ |
299 | 'me.name' => { -like => '%monte cristo%' }, |
300 | 'me.topic' => 'jailbreak', |
301 | })-><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>->deploy</h1> |
357 | <p>Perl -> DB</p> |
d1ed303d |
358 | <pre>my $schema = Foo::Schema->connect( |
359 | $dsn, $user, $pass |
360 | ); |
78c1762e |
361 | $schema-><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 -> Perl</p> |
451b57c2 |
369 | <pre>package Foo::Schema; |
c7321880 |
370 | use strict; use warnings; |
78c1762e |
371 | use base '<a href="http://search.cpan.org/perldoc?DBIx::Class::Schema::Loader">DBIx::Class::Schema::Loader</a>'; |
372 | __PACKAGE__-><a href="http://search.cpan.org/perldoc?DBIx::Class::Schema::Loader::Base#CONSTRUCTOR_OPTIONS">loader_options</a>({ |
c7321880 |
373 | naming => 'v7', |
374 | debug => $ENV{DBIC_TRACE}, |
375 | }); |
376 | 1; |
377 | |
378 | # elsewhere... |
379 | |
d1ed303d |
380 | my $schema = Foo::Schema->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-><a href="http://search.cpan.org/perldoc?DBIx::Class::Schema#populate">populate</a>([ Users => |
da0b46fd |
390 | [qw( username password )], |
d1ed303d |
391 | [qw( frew >=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->resultset('Author')-><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#create">create</a>({ |
da0b46fd |
405 | name => 'Stephen King', |
406 | books => [{ title => 'The Dark Tower' }], |
407 | address => { |
408 | street => '123 Turtle Back Lane', |
409 | state => { abbreviation => 'ME' }, |
d1ed303d |
410 | city => { name => '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; |
477 | use base 'DBIx::Class::ResultSet'; |
478 | sub good { |
d1ed303d |
479 | my $self = shift; |
480 | $self->search({ |
481 | $self->current_source_alias . |
482 | '.rating' => { '>=' => 4 }, |
da0b46fd |
483 | }) |
484 | }; |
485 | sub cheap { |
d1ed303d |
486 | my $self = shift; |
487 | $self->search({ |
488 | $self->current_source_alias . |
489 | '.price' => { '<=' => 5} |
da0b46fd |
490 | }) |
491 | }; |
492 | # ... |
493 | 1; |
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->resultset('Book')->good</pre> |
509 | </div> |
510 | |
511 | <div class="slide"> |
512 | <h1>ResultSet Chaining</h1> |
513 | <pre>$schema->resultset('Book') |
514 | ->good |
515 | ->cheap |
516 | ->recent |
6e5edefe |
517 | </pre> |
52d980cb |
518 | </div> |
519 | |
520 | <div class="slide"> |
7e77ca11 |
521 | <h1>search_related</h1> |
d1ed303d |
522 | <pre>my $score = $schema->resultset('User') |
523 | ->search({'me.userid' => 'frew'}) |
78c1762e |
524 | -><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#related_resultset">related_resultset</a>('access') |
3ab0ef72 |
525 | ->related_resultset('mgmt') |
d1ed303d |
526 | ->related_resultset('orders') |
527 | ->telephone |
78c1762e |
528 | -><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#search_related">search_related</a>( shops => { |
d1ed303d |
529 | 'shops.datecompleted' => { |
530 | -between => ['2009-10-01','2009-10-08'] |
531 | } |
532 | })->completed |
533 | ->related_resultset('rpt_score') |
78c1762e |
534 | -><a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#get_column">get_column</a>('raw_scores') |
d1ed303d |
535 | ->first; |
3ab0ef72 |
536 | </pre> |
537 | </div> |
538 | |
539 | <div class="slide"> |
7e77ca11 |
540 | <h1>bonus rel methods</h1> |
78c1762e |
541 | <pre>my $book = $author-><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship::Base#create_related">create_related</a>( |
d1ed303d |
542 | <strong>books</strong> => { |
543 | title => 'Another Discworld book', |
544 | } |
545 | ); |
52d980cb |
546 | |
78c1762e |
547 | my $book2 = $pratchett-><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship::Base#add_to_$rel">add_to_<strong>books</strong></a>({ |
7e77ca11 |
548 | title => '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-><a href="http://search.cpan.org/perldoc?DBIx::Class::Schema#txn_do">txn_do</a>(sub { |
7e77ca11 |
558 | ... |
559 | }); |
52d980cb |
560 | |
78c1762e |
561 | my $guard = $schema-><a href="http://search.cpan.org/perldoc?DBIx::Class::Schema#txn_scope_guard">txn_scope_guard</a>; |
7e77ca11 |
562 | # ... |
563 | $guard->commit; |
52d980cb |
564 | |
78c1762e |
565 | $schema-><a href="http://search.cpan.org/perldoc?DBIx::Class::Schema#txn_begin">txn_begin</a>; # <-- low level |
7e77ca11 |
566 | # ... |
78c1762e |
567 | $schema-><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; |
574 | use base 'DBIx::Class::Core'; |
d1ed303d |
575 | use DateTime::Format::MySQL; |
451b57c2 |
576 | # Result code here |
78c1762e |
577 | __PACKAGE__->load_components('<a href="http://search.cpan.org/perldoc?DBIx::Class::InflateColumn">InflateColumn</a>'); |
578 | __PACKAGE__-><strong><a href="http://search.cpan.org/perldoc?DBIx::Class::InflateColumn#inflate_column">inflate_column</a></strong>( |
52d980cb |
579 | <strong>date_published</strong> => { |
d1ed303d |
580 | inflate => sub { |
581 | DateTime::Format::MySQL->parse_date( |
582 | shift |
583 | ) |
584 | }, |
585 | deflate => sub { shift->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->date_published(DateTime->now); |
594 | $book->update;</pre> |
595 | </div> |
596 | |
597 | <div class="slide"> |
7e77ca11 |
598 | <h1>InflateColumn: inflation</h1> |
d1ed303d |
599 | <pre>say $book->date_published->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 |
607 | use base 'DBIx::Class::Core'; |
7e77ca11 |
608 | # Result code here |
78c1762e |
609 | __PACKAGE__->load_components('<a href="http://search.cpan.org/perldoc?DBIx::Class::FilterColumn">FilterColumn</a>'); |
52d980cb |
610 | |
78c1762e |
611 | __PACKAGE__-><strong><a href="http://search.cpan.org/perldoc?DBIx::Class::FilterColumn#filter_column">filter_column</a></strong>( |
7e77ca11 |
612 | <strong>length</strong> => { |
613 | to_storage => 'to_metric', |
614 | from_storage => 'to_imperial', |
615 | }, |
52d980cb |
616 | ); |
52d980cb |
617 | |
7e77ca11 |
618 | sub to_metric { $_[1] * .305 } |
619 | sub 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->resultset('Book') |
625 | ->get_column('price'); |
63d0b680 |
626 | $rsc->first; |
627 | $rsc->all; |
7e77ca11 |
628 | $rsc->min; |
629 | $rsc->max; |
630 | $rsc->sum; |
6548782a |
631 | </pre> |
52d980cb |
632 | </div> |
633 | |
634 | <div class="slide"> |
7e77ca11 |
635 | <h1>Aggregates</h1> |
636 | <pre>my @res = $rs->search({}, { |
78c1762e |
637 | <a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#select">select</a> => [ |
d1ed303d |
638 | 'price', |
639 | 'genre', |
640 | { max => price }, |
641 | { avg => price }, |
642 | ], |
78c1762e |
643 | <a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#as">as</a> => [ |
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> => [qw(price genre)], |
7e77ca11 |
647 | }); |
648 | for (@res) { |
649 | say $_->price . ' ' . $_->genre; |
650 | say $_->get_column('max_price'); |
651 | say $_->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->search({}, { |
78c1762e |
668 | <a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet#result_class">result_class</a> => |
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 < 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->resultset('Artist') |
682 | ->search({ |
7e77ca11 |
683 | name => [ 'Billy Joel', 'Brittany Spears' ], |
d1ed303d |
684 | })->get_column('id')->as_query; |
9158dee5 |
685 | |
7e77ca11 |
686 | my $rs = $schema->resultset('CD')->search({ |
d1ed303d |
687 | artist_id => { -in => $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->update({ |
d1ed303d |
694 | # !!! SQL INJECTION VECTOR |
695 | price => \"price + $inc", |
7e77ca11 |
696 | }); |
697 | |
698 | $rs->update({ |
699 | price => \['price + ?', [inc => $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> |