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' }, }, +});
my $resultset = $book_rs->search({ - name => { -like => "%$nick%" }, - });+
my $resultset = $book_rs->search({ + name => { -like => "%$nick%" }, +});
package MyApp::Schema::ResultSet::Book; use base 'DBIx::Class::ResultSet'; sub good { - my $self = shift; - $self->search({ + $_[0]->search({ rating => { '>=' => 4 }, }) }; sub cheap { - my $self = shift; - $self->search({ + $_[0]->search({ price => { '<=' => 5} }) }; @@ -478,67 +477,48 @@ sub cheap {
DBIC_TRACE=1 ./your_script.pl+
*get example from work*
INSERT INTO authors (name) - VALUES (?): 'Douglas Adams' - -INSERT INTO books (author, title) - VALUES (?, ?): '5', '42'-
my $book = $author->create_related( + books => { + title => 'Another Discworld book', +}); --overloading
-Foo::Schema::Result::Book -Foo::Schema::ResultSet::Book -Foo::Schema::Result::Author -Foo::Schema::ResultSet::Book+my $book2 = $pratchett->add_to_books({ + title => 'MOAR Discworld book', +}); ++
- Automaticaly fills in foreign key for you
+-+my $guard = $schema->txn_scope_guard; +# ... +$guard->commit; -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;--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'); +}++
- Careful, get_column can basicaly mean THREE things
+- private for get what you should use an accessor for
+- public for what there is no accessor for
+- public for get resultset column (prev slide)
+-- -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
--
- Turn on debugging
-- Read error messages (sometimes useful!)
-- Check field names
-- Check package names
-- Check which database you are connected to (dev/test/live?) - repeat above
++
- Easy on memory
+- Mega fast
+- Great for quick debugging
+- Great for performance tuning (we went from 2m to < 3s)
-+LOTS more Features
--
-- FilterColumn
-- Transactions
-- HashRefInflator
-- Subqueries
-- ResultSetColumn
-- Aggregate Queries
-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
--
+- -
[% author.books.count %]not working?- TT all methods are called in list context
-- -
[% author.books_rs.count %]scalar context- Available for all relationships
-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