X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSet.pm;h=29810f56966086c3c12340929dfb5e672d5496f1;hb=cc3b77095de9f0e574b0ed32403f4299e6588f45;hp=f71743573d39fd109343b0ddace5c796c2ff9c9d;hpb=c7a9d1027d40e6b3275cb26db68141b152f3bd13;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index f717435..29810f5 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -52,6 +52,86 @@ In the examples below, the following table classes are used: __PACKAGE__->belongs_to(artist => 'MyApp::Schema::Artist'); 1; +=head1 DISCUSSION + +When you create a resultset (usually as a result of calling search()), DBIx::Class +B make a DB call. Not yet. A resultset is (in simplistic terms) a set of +where conditions, join conditions, and other metadata that would be needed to execute +a SELECT statement. This has several big implications: + +=over 4 + +=item * You can chain resultsets + +=item * You can run multiple queries using the same resultset + +=back + +=head2 Chaining resultsets + +Let's say you've got a query that needs to be run to return some data to the user. But, +you have an authorization system in place that prevents certain users from seeing certain +information. So, you want to construct the query in one method, but add constraints to it +in another. + + sub get_data { + my $self = shift; + my $request = $self->get_request; # Get a request object somehow. + my $schema = $self->get_schema; # Get the DBIC schema object somehow. + + my $rs = $schema->resultset('some_data')->search({ + foo => $request->param('foo'), + bar => $request->param('bar'), + }); + + $self->apply_security_policy( $rs ); + + return $rs->all; + } + + sub apply_security_policy { + my $self = shift; + my ($rs) = @_; + + return $rs->search({ + hidden_data => 0, + }); + } + +=head2 Multiple queries + +Since a resultset hasn't hit the database yet, you can do all sorts of things with it. + + # Don't hit the DB yet. + my $rs = $schema->resultset('some_table')->search({ + foo => 1, + bar => 2, + }); + + # Each of these hits the DB individually. + my $count = $rs->count; + my $max_baz = $rs->get_column('baz')->max; + my @records = $rs->all; + +And it's not just limited to SELECT statements. + + $rs->delete; + +This is even cooler + + $rs->create({ baz => 20 }); + +That is equivalent to + + $schema->resultset('some_table')->create({ + foo => 1, + bar => 2, + baz => 20, + }); + +Note that C returns a ResultSetColumn object. This will behave almost +exactly like a resultset, except it has methods tuned for working with columns. + =head1 OVERLOADING If a resultset is used in a numeric context it returns the L. @@ -607,6 +687,10 @@ of the resultset. sub single { my ($self, $where) = @_; + if(@_ > 2) { + $self->throw_exception('single() only takes search conditions, no attributes. You want ->search( $cond, $attrs )->single()'); + } + my $attrs = { %{$self->_resolved_attrs} }; if ($where) { if (defined $attrs->{where}) { @@ -1109,7 +1193,11 @@ is returned in list context. =cut sub all { - my ($self) = @_; + my $self = shift; + if(@_) { + $self->throw_exception("all() doesn't take any arguments, you probably wanted ->search(...)->all()"); + } + return @{ $self->get_cache } if $self->get_cache; my @obj; @@ -1261,6 +1349,11 @@ sub update { $self->throw_exception("Values for update must be a hash") unless ref $values eq 'HASH'; + carp( 'WARNING! Currently $rs->update() does not generate proper SQL' + . ' on joined resultsets, and may affect rows well outside of the' + . ' contents of $rs. Use at your own risk' ) + if ( $self->{attrs}{seen_join} ); + my $cond = $self->_cond_for_update_delete; return $self->result_source->storage->update( @@ -1721,56 +1814,11 @@ sub _remove_alias { Returns the SQL query and bind vars associated with the invocant. -=cut - -sub as_query { return shift->cursor->as_query(@_) } - -=head2 as_subselect - -=over 4 - -=item Arguments: none - -=item Return Value: \[ $sql, @bind ] - -=back - -Returns the SQL query and bind vars associated with the invocant. - -The SQL will be wrapped in parentheses, ready for use as a subselect. - -=cut - -sub as_subselect { - my $self = shift; - my $arr = ${$self->as_query(@_)}; - $arr->[0] = '( ' . $arr->[0] . ' )'; - return \$arr; -} - -=head2 as_query - -=over 4 - -=item Arguments: none - -=item Return Value: $sql - -=back - -Returns the SQL query associated with the invocant. All bind vars -will have been bound using C<< DBI->quote() >>. +This is generally used as the RHS for a subquery. =cut -sub as_sql { - my $self = shift; - my $arr = ${$self->as_query(@_)}; - my $sql = shift @$arr; - my $dbh = $self->result_source->schema->storage->dbh; - $sql =~ s/\?/$dbh->quote((shift @$arr)->[1])/eg; - return $sql -} +sub as_query { return shift->cursor->as_query(@_) } =head2 find_or_new @@ -1853,7 +1901,7 @@ Example of creating a new row. $person_rs->create({ name=>"Some Person", - email=>"somebody@someplace.com" + email=>"somebody@someplace.com" }); Example of creating a new row and also creating rows in a related C @@ -1872,10 +1920,10 @@ Cresultset. Note Hashref. $cd_rs->create({ title=>"Music for Silly Walks", - year=>2000, - artist => { - name=>"Silly Musician", - } + year=>2000, + artist => { + name=>"Silly Musician", + } }); =cut @@ -2305,7 +2353,7 @@ sub _resolved_attrs { if (my $prefetch = delete $attrs->{prefetch}) { $prefetch = $self->_merge_attr({}, $prefetch); my @pre_order; - my $seen = $attrs->{seen_join} || {}; + my $seen = { %{ $attrs->{seen_join} || {} } }; foreach my $p (ref $prefetch eq 'ARRAY' ? @$prefetch : ($prefetch)) { # bring joins back to level of current class my @prefetch = $source->resolve_prefetch( @@ -2461,8 +2509,12 @@ sub throw_exception { =head1 ATTRIBUTES -The resultset takes various attributes that modify its behavior. Here's an -overview of them: +Attributes are used to refine a ResultSet in various ways when +searching for data. They can be passed to any method which takes an +C<\%attrs> argument. See L, L, L, +L. + +These are in no particular order: =head2 order_by @@ -2555,7 +2607,7 @@ L but adds columns to the selection. =over 4 -Indicates additional column names for those added via L. +Indicates additional column names for those added via L. See L. =back