X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=slideshow.html;h=0456e26a78bef17ff608ac22d7cfd88f040aa098;hb=7e77ca11659bb6642b85a4925e89c9d45fb979c2;hp=76917e978ca649be677acad384552352595a59d9;hpb=da0b46fdf0b90e932d2ca0d7874b9e70091cb323;p=dbsrgits%2Fdbix-class-introduction-presentation.git diff --git a/slideshow.html b/slideshow.html index 76917e9..0456e26 100644 --- a/slideshow.html +++ b/slideshow.html @@ -369,6 +369,7 @@ my $schema = Foo::Schema->connect($dsn, $user, $pass); state => { abbreviation => 'ME' }, city => { name => 'Lowell' }, }, +});
-

Result::

-
package Foo::Schema::Result::Book;
-use base 'DBIx::Class::Core';
-use strict;
-use warnings;
-
-# Result code here
-
-sub isbn {
-   my $self = shift;
-
-   # search amazon or something
-   my $api = Amazon::API->book({
-      title => $self->title
-   });
-
-   return $api->isbn;
-}
+      

Excellent Transaction Support

+
$schema->txn_do(sub {
+   ...
+});
 
-1;
-
+my $guard = $schema->txn_scope_guard; +# ... +$guard->commit; -
-

Result::

-
print $book->isbn;
+$schema->txn_begin; # <-- low level +# ... +$schema->txn_commit; +
-

Result:: (inflating)

+

InflateColumn

package Foo::Schema::Result::Book;
 use base 'DBIx::Class::Core';
-use strict;
-use warnings;
-
 # Result code here
-
 __PACKAGE__->load_components('InflateColumn');
 use DateTime::Format::MySQL;
-
 __PACKAGE__->inflate_column(
    date_published => {
       inflate => sub { DateTime::Format::MySQL->parse_date(shift) },
@@ -549,13 +529,13 @@ __PACKAGE__->inflate_column(
    
-

Result:: (deflating)

+

InflateColumn: deflation

$book->date_published(DateTime->now);
 $book->update;
-

Result:: (inflating)

+

InflateColumn: inflation

my $date_published = $book->date_published;
 print $date_published->month_abbr;
@@ -563,319 +543,96 @@ print $date_published->month_abbr;
-

ResultSets::

-
package Foo::Schema::ResultSet::Books;
-use base 'DBIx::Class::ResultSet';
-sub the_ultimate_books {
-   my $self = shift;
-   return $self->search({ title => { -like => '%42%' } });
-}
-sub by_author {
-   my ( $self, $author ) = @_;
-   return $self->search({ author => $author->id })
-}
-
-1;
-
- -
-

ResultSets::

-
use Foo::Schema;
-my $schema = Foo::Schema->connect(...);
-my $book_rs     = Foo::Schema->resultset('Book');
-my $book_search = $book_rs->the_ultimate_books;
-my @books       = $book_search->all;
-
- -
-

ResultSets: Chaining

-
-my $book_rs   = $schema->resultset('Book');
-my $author_rs = $schema->resultset('Author');
-my $author    = $author_rs->search({ name => 'Douglas Adams' })->single;
-$book_rs      = $book_rs->the_ultimate_books->by_author($author);
-my @books     = $book_rs->all;
-
- -
-

ResultSets: Chaining

-
$book_rs = $schema->resultset('Book')
-  ->the_ultimate_books
-  ->by_author($author);
-or - -
my $book_rs = $schema->resultset('Book')
-  ->the_ultimate_books;
-$book_rs = $book_rs->by_author($author);
-
# 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%'
-
- -
-

ResultSets: Chaining

-
my $rs = $book_rs
-  ->category('childrens')
-  ->by_author($author)
-  ->published_after('1812')
-  ->first_page_contains('once upon')
-  ->rating_greater_than(4);
-
-my @books = $rs->all;
-
- -
-

overloading before new record

-
package Foo::Schema::Result::Author;
+      

FilterColumn

+
package Foo::Schema::Result::Book;
 use base 'DBIx::Class::Core';
+# Result code here
+__PACKAGE__->load_components('FilterColumn');
 
-sub new {
-   my ( $class, $attrs ) = @_;
-   # Mess with $attrs
-   my $new = $class->next::method($attrs);
-   return $new
-}
-
-1;
- -
-

Relationships

-
- -
-

Multiple Authors

-

We want to allow a book to be by more than one author

-
- -
-

a few relationships

- -
- -
-

Join Table

-
CREATE TABLE author_and_books(
-  book_id    int(8),
-  author_id  int(8),
-  foreign key (book_id)     references books(id),
-  foreign key (author_id)   references authors(id)
-) engine = InnoDB DEFAULT CHARSET=utf8;
-
-ALTER TABLE `books` DROP `author_id`;
-
- -
-

has_many

- -
- -
-

has_many

-
package Foo::Schema::Result::Book;
-
-__PACKAGE__->has_many( author_and_books =>
-   'Foo::Schema::Result::Author_Book', 'book_id'
-);
-   
- -
-

belongs_to

- -
- -
-

belongs_to

-
package Foo::Schema::Result::Author_Book;
-
-__PACKAGE__->belongs_to(
-   book =>
-   'Foo::Schema::Result::Book', 'book_id'
+__PACKAGE__->filter_column(
+   length => {
+      to_storage   => 'to_metric',
+      from_storage => 'to_imperial',
+   },
 );
-
-
- -
-

same for Authors

- -
-
-

many_to_many

- +sub to_metric { $_[1] * .305 } +sub to_imperial { $_[1] * 3.28 } +# Automatic see: DBIx::Class::InflateColumn::DateTime
-

many_to_many

-
package Foo::Schema::Result::Book;
-use base 'DBIx::Class::Core';
-
-__PACKAGE__->many_to_many(
-   authors => 'author_and_books', 'author'
-);
-
-1;
+      

ResultSetColumn

+
my $rsc = $schema->resultset('Book')->get_column('price');
+$rsc->min;
+$rsc->max;
+$rsc->sum;
 
-

many_to_many

-
package Foo::Schema::Result::Book;
-use base 'DBIx::Class::Core';
-
-__PACKAGE__->many_to_many(
-   authors # Accessor name
-   => "author_and_books", # has_many
-   'author' # foreign relationship name
-);
-
-1;
-
- -
-

many_to_many

-
package Foo::Schema::Result::Author;
-use base 'DBIx::Class::Core';
-
-__PACKAGE__->many_to_many(
-   "books" # Accessor Name
-   => "author_and_books", # has_many accessor_name
-   'book' # foreign relationship name
-);
-
-1;
-
+

Aggregates

+
my @res = $rs->search({}, {
+   select   => [qw(price genre), { max => price }, { avg => price }],
+   as       => [qw(price genre max_price avg_price)],
+   group_by => [qw(price genre)],
+});
+for (@res) {
+   say $_->price . ' ' . $_->genre;
+   say $_->get_column('max_price');
+   say $_->get_column('min_price');
+}
+
-

Using many_to_many

-
#!perl
-use Foo::Schema;
-my $schema    = Foo::Schema->connect(...);
-my $author_rs = $schema->resultset('Authors');
-my $author    = $author_rs->search({
-   name => 'Douglas Adams',
-})->single;
-$author->add_to_books({
-   title => 'A new book',
+      

HRI

+
$rs->search({}, {
+   result_class => 'DBIx::Class::ResultClass::HashRefInflator',
 });
-
- -
-

using many_to_many

-
my $author = $author_rs->search({
-   name => 'Douglas Adams',
-})->single;
-$author->add_to_books({
-   title => 'A new book',
-});
-
-# 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';
-
- -
-

using many_to_many

-
$author->add_to_books($book);
-
-$book->add_to_authors($author_1);
-$book->add_to_authors($author_2);
-
- -
-

errors

-

Read them closely!

-
- -
-

error messages

-
DBIx::Class::Schema::Loader::connection(): Failed to load external
-class definition for 'Foo::Schema::Result::Authors': Can't locate object
-method "many_to_many" via package "Foo::Schema::Result::Author" at
-lib/Foo/Schema/Result/Authors.pm line 9.Compilation failed in require at
-/Library/Perl/5.8.8/DBIx/Class/Schema/Loader/Base.pm line 292.
-
- -
-

error messages

-
DBIx::Class::Schema::Loader::connection(): Failed to load external
-class definition for 'Foo::Schema::Result::Authors': Can't locate object
-method "many_to_many" via package "Foo::Schema::Result::Author" at
-lib/Foo/Schema/Result/Authors.pm line 9.Compilation failed in require at
-/Library/Perl/5.8.8/DBIx/Class/Schema/Loader/Base.pm line 292.
-
- -
-

errors

-
-

LOTS more Features

- -
+

Subquery Support

+
  my $inside_rs = $schema->resultset('Artist')->search({
+    name => [ 'Billy Joel', 'Brittany Spears' ],
+});
 
-   
-

bonus slides!

+my $rs = $schema->resultset('CD')->search({ + artist_id => { -in => $inside_rs->get_column('id')->as_query }, +});
-

Template Toolkit

- +

Bare SQL w/ Placeholders

+
$rs->update({
+   price => \"price + $inc", # !!! SQL INJECTION VECTOR
+});
+
+$rs->update({
+   price => \['price + ?', [inc => $inc]],
+});
+
-

Catalyst

-
package Your::App::Model::Foo;
-use base qw(Catalyst::Model::Schema::Schema);
-
-use strict;
-use warnings;
-
-__PACKAGE__->config(
-  schema_class => 'Foo::Schema',
-);
-
-1;
-

Keep your Schema in a separate package from your Catalyst application

+

Questions?

-

Catalyst

-
sub action_name : Local {
-  my ($self, $c) = @_;
-
-  my $schema = $c->model('Schema::Foo');
-  my $author_rs = $schema->resultset('Authors');
-
-}
-
-1;
+

END

-