From: Will Hawes <wdhawes@gmail.com> Date: Mon, 23 Jan 2006 17:48:39 +0000 (+0000) Subject: flesh out doc for 'from', 'select', 'as' and 'group_by' X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=4a28c3401397f015e833a802ddab5d341693f7dd;p=dbsrgits%2FDBIx-Class-Historic.git flesh out doc for 'from', 'select', 'as' and 'group_by' --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index ff876b1..4df3d58 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -657,11 +657,57 @@ from that, then auto-populates C<as> from C<select> as normal. =head2 select (arrayref) -Indicates which columns should be selected from the storage. +Indicates which columns should be selected from the storage. You can use +column names, or in the case of RDBMS back ends, function or stored procedure +names: + + $rs = $schema->resultset('Foo')->search( + {}, + { + select => { + 'column_name', + { count => 'column_to_count' }, + { sum => 'column_to_sum' } + } + } + ); + +When you use function/stored procedure names and do not supply an C<as> +attribute, the column names returned are storage-dependent. E.g. MySQL would +return a column named C<count(column_to_count)> in the above example. =head2 as (arrayref) -Indicates column names for object inflation. +Indicates column names for object inflation. This is used in conjunction with +C<select>, usually when C<select> contains one or more function or stored +procedure names: + + $rs = $schema->resultset('Foo')->search( + {}, + { + select => { + 'column1', + { count => 'column2' } + }, + as => [qw/ column1 column2_count /] + } + ); + + my $foo = $rs->first(); # get the first Foo + +If the object against which the search is performed already has an accessor +matching a column name specified in C<as>, the value can be retrieved using +the accessor as normal: + + my $column1 = $foo->column1(); + +If on the other hand an accessor does not exist in the object, you need to +use C<get_column> instead: + + my $column2_count = $foo->get_column('column2_count'); + +You can create your own accessors if required - see +L<DBIx::Class::Manual::Cookbook> for details. =head2 join @@ -705,13 +751,92 @@ query (when they are accessed afterwards they will have already been objects, because it saves a query. Currently limited to prefetching one relationship deep, so unlike C<join>, prefetch must be an arrayref. -=head2 from +=head2 from (arrayref) -This attribute can contain a arrayref of elements. Each element can be another -arrayref, to nest joins, or it can be a hash which represents the two sides -of the join. +The C<from> attribute gives you manual control over the C<FROM> clause of SQL +statements generated by L<DBIx::Class>, allowing you to express custom C<JOIN> +clauses. NOTE: Use this on your own risk. This allows you to shoot off your foot! +C<join> will usually do what you need and it is strongly recommended that you +avoid using C<from> unless you cannot achieve the desired result using C<join>. + +In simple terms, C<from> works as follows: + + [ + { <alias> => <table>, -join-type => 'inner|left|right' } + [] # nested JOIN (optional) + { <table.column> = <foreign_table.foreign_key> } + ] + + JOIN + <alias> <table> + [JOIN ...] + ON <table.column> = <foreign_table.foreign_key> + +An easy way to follow the examples below is to remember the following: + + Anything inside "[]" is a JOIN + Anything inside "{}" is a condition for the enclosing JOIN + +The following examples utilize a "person" table in a family tree application. +In order to express parent->child relationships, this table is self-joined: + + # Person->belongs_to('father' => 'Person'); + # Person->belongs_to('mother' => 'Person'); + +C<from> can be used to nest joins. Here we return all children with a father, +then search against all mothers of those children: + + $rs = $schema->resultset('Person')->search( + {}, + { + alias => 'mother', # alias columns in accordance with "from" + from => [ + { mother => 'person' }, + [ + [ + { child => 'person' }, + [ + { father => 'person' }, + { 'father.person_id' => 'child.father_id' } + ] + ], + { 'mother.person_id' => 'child.mother_id' } + ], + ] + }, + ); + + # Equivalent SQL: + # SELECT mother.* FROM person mother + # JOIN ( + # person child + # JOIN person father + # ON ( father.person_id = child.father_id ) + # ) + # ON ( mother.person_id = child.mother_id ) + +The type of any join can be controlled manually. To search against only people +with a father in the person table, we could explicitly use C<INNER JOIN>: + + $rs = $schema->resultset('Person')->search( + {}, + { + alias => 'child', # alias columns in accordance with "from" + from => [ + { child => 'person' }, + [ + { father => 'person', -join-type => 'inner' }, + { 'father.id' => 'child.father_id' } + ], + ] + }, + ); + + # Equivalent SQL: + # SELECT child.* FROM person child + # INNER JOIN person father ON child.father_id = father.id =head2 page @@ -720,13 +845,16 @@ for an unpaged resultset. =head2 rows -For a paged resultset, how many rows per page. Can also be used to simulate an -SQL C<LIMIT>. +For a paged resultset, how many rows per page: + + rows => 10 + +Can also be used to simulate an SQL C<LIMIT>. =head2 group_by (arrayref) -A arrayref of columns to group by (note that L</count> doesn't work on grouped -resultsets). +A arrayref of columns to group by. Can include columns of joined tables. Note +note that L</count> doesn't work on grouped resultsets. group_by => [qw/ column1 column2 ... /]