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=1610eb11823ce43274bfa90a580b68964bce0119;hpb=0a0585ddc73e571741e98d51446d83083ed1e4f1;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 1610eb1..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. @@ -1269,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( @@ -1717,6 +1802,24 @@ sub _remove_alias { return \%unaliased; } +=head2 as_query + +=over 4 + +=item Arguments: none + +=item Return Value: \[ $sql, @bind ] + +=back + +Returns the SQL query and bind vars associated with the invocant. + +This is generally used as the RHS for a subquery. + +=cut + +sub as_query { return shift->cursor->as_query(@_) } + =head2 find_or_new =over 4