Fixed wrong field names: cd.cdid -> cd.id, artist.artistid ->
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
index e113fdb..50bbc10 100644 (file)
@@ -12,6 +12,7 @@ use Storable;
 use DBIx::Class::ResultSetColumn;
 use DBIx::Class::ResultSourceHandle;
 use List::Util ();
+use Scalar::Util ();
 use base qw/DBIx::Class/;
 
 __PACKAGE__->mk_group_accessors('simple' => qw/result_class _source_handle/);
@@ -22,8 +23,8 @@ DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
 
 =head1 SYNOPSIS
 
-  my $rs   = $schema->resultset('User')->search(registered => 1);
-  my @rows = $schema->resultset('CD')->search(year => 2005);
+  my $rs   = $schema->resultset('User')->search({ registered => 1 });
+  my @rows = $schema->resultset('CD')->search({ year => 2005 })->all();
 
 =head1 DESCRIPTION
 
@@ -53,7 +54,10 @@ In the examples below, the following table classes are used:
 
 =head1 OVERLOADING
 
-If a resultset is used as a number it returns the C<count()>.  However, if it is used as a boolean it is always true.  So if you want to check if a result set has any results use C<if $rs != 0>.  C<if $rs> will always be true.
+If a resultset is used in a numeric context it returns the L</count>.
+However, if it is used in a booleand context it is always true.  So if
+you want to check if a resultset has any results use C<if $rs != 0>.
+C<if $rs> will always be true.
 
 =head1 METHODS
 
@@ -1524,8 +1528,18 @@ sub new_result {
 
   # precendence must be given to passed values over values inherited from the cond, 
   # so the order here is important.
-  my %new = (
-    %{ $self->_remove_alias($collapsed_cond, $alias) },
+  my %new;
+  my %implied =  %{$self->_remove_alias($collapsed_cond, $alias)};
+  while( my($col,$value) = each %implied ){
+    if(ref($value) eq 'HASH' && keys(%$value) && (keys %$value)[0] eq '='){
+      $new{$col} = $value->{'='};
+      next;
+    }
+    $new{$col} = $value if $self->_is_deterministic_value($value);
+  }
+
+  %new = (
+    %new,
     %{ $self->_remove_alias($values, $alias) },
     -source_handle => $self->_source_handle,
     -result_source => $self->result_source, # DO NOT REMOVE THIS, REQUIRED
@@ -1534,6 +1548,20 @@ sub new_result {
   return $self->result_class->new(\%new);
 }
 
+# _is_deterministic_value
+#
+# Make an effor to strip non-deterministic values from the condition, 
+# to make sure new_result chokes less
+
+sub _is_deterministic_value {
+  my $self = shift;
+  my $value = shift;
+  my $ref_type = ref $value;
+  return 1 if $ref_type eq '' || $ref_type eq 'SCALAR';
+  return 1 if Scalar::Util::blessed($value);
+  return 0;
+}
+
 # _collapse_cond
 #
 # Recursively collapse the condition.
@@ -1723,6 +1751,12 @@ constraint. For example:
     { key => 'cd_artist_title' }
   );
 
+Note: Because find_or_create() reads from the database and then
+possibly inserts based on the result, this method is subject to a race
+condition. Another process could create a record in the table after
+the find has completed and before the create has started. To avoid
+this problem, use find_or_create() inside a transaction.
+
 See also L</find> and L</update_or_create>. For information on how to declare
 unique constraints, see L<DBIx::Class::ResultSource/add_unique_constraint>.
 
@@ -1802,6 +1836,9 @@ sub update_or_create {
 
 Gets the contents of the cache for the resultset, if the cache is set.
 
+The cache is populated either by using the L</prefetch> attribute to
+L</search> or by calling L</set_cache>.
+
 =cut
 
 sub get_cache {
@@ -1823,6 +1860,9 @@ of objects of the same class as those produced by the resultset. Note that
 if the cache is set the resultset will return the cached objects rather
 than re-querying the database even if the cache attr is not set.
 
+The contents of the cache can also be populated by using the
+L</prefetch> attribute to L</search>.
+
 =cut
 
 sub set_cache {
@@ -2435,13 +2475,27 @@ C<cd> or C<artist> relationships, which saves us two SQL statements in this
 case.
 
 Simple prefetches will be joined automatically, so there is no need
-for a C<join> attribute in the above search. If you're prefetching to
-depth (e.g. { cd => { artist => 'label' } or similar), you'll need to
-specify the join as well.
+for a C<join> attribute in the above search. 
 
 C<prefetch> can be used with the following relationship types: C<belongs_to>,
 C<has_one> (or if you're using C<add_relationship>, any relationship declared
-with an accessor type of 'single' or 'filter').
+with an accessor type of 'single' or 'filter'). A more complex example that
+prefetches an artists cds, the tracks on those cds, and the tags associted 
+with that artist is given below (assuming many-to-many from artists to tags):
+
+ my $rs = $schema->resultset('Artist')->search(
+   undef,
+   {
+     prefetch => [
+       { cds => 'tracks' },
+       { artist_tags => 'tags' }
+     ]
+   }
+ );
+
+B<NOTE:> If you specify a C<prefetch> attribute, the C<join> and C<select>
+attributes will be ignored.
 
 =head2 page