X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FManual%2FCookbook.pod;h=677347966193b3cba7bf4256949e1857c8496b84;hb=3d5658966d987a203d6cb80804ad8d337f57e4b5;hp=0552a037b9a8136424a635907f354d6721ada428;hpb=d2f3e87bbb670790a5572e1f7b92f33cc57585ab;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index 0552a03..6773479 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -194,8 +194,6 @@ any of your aliases using either of these: } ); - my $count = $rs->next->get_column('count'); - =head2 SELECT COUNT(DISTINCT colname) my $rs = $schema->resultset('Foo')->search( @@ -208,6 +206,8 @@ any of your aliases using either of these: } ); + my $count = $rs->next->get_column('count'); + =head2 Grouping results L supports C as follows: @@ -255,8 +255,15 @@ and define often used searches as methods: To use your resultset, first tell DBIx::Class to create an instance of it for you, in your My::DBIC::Schema::CD class: + # class definition as normal + __PACKAGE__->load_components(qw/ Core /); + __PACKAGE__->table('cd'); + + # tell DBIC to use the custom ResultSet class __PACKAGE__->resultset_class('My::DBIC::ResultSet::CD'); +Note that C must be called after C and C, or you will get errors about missing methods. + Then call your new method in your code: my $ordered_cds = $schema->resultset('CD')->search_cds_ordered(); @@ -763,42 +770,58 @@ This will cause the following SQL statement to be run: Which will of course only work if your database supports this function. See L for more documentation. +=head2 Creating a result set from a set of rows + +Sometimes you have a (set of) row objects that you want to put into a +resultset without the need to hit the DB again. You can do that by using the +L method: + + my @uploadable_groups; + while (my $group = $groups->next) { + if ($group->can_upload($self)) { + push @uploadable_groups, $group; + } + } + my $new_rs = $self->result_source->resultset; + $new_rs->set_cache(\@uploadable_groups); + return $new_rs; + + =head1 USING RELATIONSHIPS =head2 Create a new row in a related table - my $book->create_related('author', { name => 'Fred'}); + my $author = $book->create_related('author', { name => 'Fred'}); =head2 Search in a related table Only searches for books named 'Titanic' by the author in $author. - my $author->search_related('books', { name => 'Titanic' }); + my $books_rs = $author->search_related('books', { name => 'Titanic' }); =head2 Delete data in a related table Deletes only the book named Titanic by the author in $author. - my $author->delete_related('books', { name => 'Titanic' }); + $author->delete_related('books', { name => 'Titanic' }); =head2 Ordering a relationship result set If you always want a relation to be ordered, you can specify this when you create the relationship. -To order C<< $book->pages >> by descending page_number. +To order C<< $book->pages >> by descending page_number, create the relation +as follows: - Book->has_many('pages' => 'Page', 'book', { order_by => \'page_number DESC'} ); + __PACKAGE__->has_many('pages' => 'Page', 'book', { order_by => \'page_number DESC'} ); =head2 Many-to-many relationships This is straightforward using L: - package My::DB; - # ... set up connection ... - package My::User; - use base 'My::DB'; + use base 'DBIx::Class'; + __PACKAGE__->load_components('Core'); __PACKAGE__->table('user'); __PACKAGE__->add_columns(qw/id name/); __PACKAGE__->set_primary_key('id'); @@ -806,7 +829,8 @@ This is straightforward using Lmany_to_many('addresses' => 'user_address', 'address'); package My::UserAddress; - use base 'My::DB'; + use base 'DBIx::Class'; + __PACKAGE__->load_components('Core'); __PACKAGE__->table('user_address'); __PACKAGE__->add_columns(qw/user address/); __PACKAGE__->set_primary_key(qw/user address/); @@ -814,7 +838,8 @@ This is straightforward using Lbelongs_to('address' => 'My::Address'); package My::Address; - use base 'My::DB'; + use base 'DBIx::Class'; + __PACKAGE__->load_components('Core'); __PACKAGE__->table('address'); __PACKAGE__->add_columns(qw/id street town area_code country/); __PACKAGE__->set_primary_key('id'); @@ -841,7 +866,7 @@ example of the recommended way to use it: $genus->add_to_species({ name => 'troglodyte' }); $genus->wings(2); $genus->update; - $schema->txn_do($coderef2); # Can have a nested transaction + $schema->txn_do($coderef2); # Can have a nested transaction. Only the outer will actualy commit return $genus->species; }; @@ -874,7 +899,8 @@ L and associated sources by examining the database. The recommend way of achieving this is to use the L method: - perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib -e 'make_schema_at("My::Schema", { debug => 1 }, [ "dbi:Pg:dbname=foo","postgres" ])' + perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib \ + -e 'make_schema_at("My::Schema", { debug => 1 }, [ "dbi:Pg:dbname=foo","postgres" ])' This will create a tree of files rooted at C<./lib/My/Schema/> containing source definitions for all the tables found in the C database. @@ -920,6 +946,98 @@ of the schema, plus scripts to convert from version 0.1 to 0.2. This requires that the files for 0.1 as created above are available in the given directory to diff against. +=head2 Select from dual + +Dummy tables are needed by some databases to allow calling functions +or expressions that aren't based on table content, for examples of how +this applies to various database types, see: +L. + +Note: If you're using Oracles dual table don't B do anything +other than a select, if you CRUD on your dual table you *will* break +your database. + +Make a table class as you would for any other table + + package MyAppDB::Dual; + use strict; + use warnings; + use base 'DBIx::Class'; + __PACKAGE__->load_components("Core"); + __PACKAGE__->table("Dual"); + __PACKAGE__->add_columns( + "dummy", + { data_type => "VARCHAR2", is_nullable => 0, size => 1 }, + ); + +Once you've loaded your table class select from it using C conditions to illustrate the different syntax +you could use for doing stuff like +C + + # get a sequence value + select => [ 'A_SEQ.nextval' ], + + # get create table sql + select => [ { 'dbms_metadata.get_ddl' => [ "'TABLE'", "'ARTIST'" ]} ], + + # get a random num between 0 and 100 + select => [ { "trunc" => [ { "dbms_random.value" => [0,100] } ]} ], + + # what year is it? + select => [ { 'extract' => [ \'year from sysdate' ] } ], + + # do some math + select => [ {'round' => [{'cos' => [ \'180 * 3.14159265359/180' ]}]}], + + # which day of the week were you born on? + select => [{'to_char' => [{'to_date' => [ "'25-DEC-1980'", "'dd-mon-yyyy'" ]}, "'day'"]}], + + # select 16 rows from dual + select => [ "'hello'" ], + as => [ 'world' ], + group_by => [ 'cube( 1, 2, 3, 4 )' ], + + + =head2 Adding Indexes And Functions To Your SQL Often you will want indexes on columns on your table to speed up searching. To @@ -1029,7 +1147,7 @@ B Add the L schema component to your Schema class. This will add a new table to your database called -C which will keep track of which version is installed +C which will keep track of which version is installed and warn if the user trys to run a newer schema version than the database thinks it has.