Merge 'trunk' into 'void_populate_resultset_cond'
Peter Rabbitson [Tue, 17 Nov 2009 23:42:13 +0000 (23:42 +0000)]
r7765@Thesaurus (orig r7753):  ribasushi | 2009-10-03 15:49:14 +0200
Test reorg (no changes)
r7766@Thesaurus (orig r7754):  ribasushi | 2009-10-03 15:55:25 +0200
Add failing tests for RT#50003
r7767@Thesaurus (orig r7755):  caelum | 2009-10-03 16:09:45 +0200
fix on_connect_ with coderef connect_info
r7771@Thesaurus (orig r7759):  ribasushi | 2009-10-04 13:17:53 +0200
Fix AutoCast's POD
r7782@Thesaurus (orig r7770):  ribasushi | 2009-10-09 06:57:20 +0200
 r7777@Thesaurus (orig r7765):  frew | 2009-10-07 20:05:05 +0200
 add method to check if an rs is paginated
 r7778@Thesaurus (orig r7766):  frew | 2009-10-07 20:31:02 +0200
 is_paginated method and test
 r7780@Thesaurus (orig r7768):  frew | 2009-10-09 06:45:36 +0200
 change name of method
 r7781@Thesaurus (orig r7769):  frew | 2009-10-09 06:47:31 +0200
 add message to changelog for is_paged

r7785@Thesaurus (orig r7773):  ribasushi | 2009-10-09 11:00:36 +0200
Ugh CRLF
r7786@Thesaurus (orig r7774):  ribasushi | 2009-10-09 11:04:35 +0200
Skip versioning test on really old perls lacking Time::HiRes
r7787@Thesaurus (orig r7775):  ribasushi | 2009-10-09 11:04:50 +0200
Changes
r7788@Thesaurus (orig r7776):  triode | 2009-10-09 22:32:04 +0200
added troubleshooting case of excessive memory allocation involving TEXT/BLOB/etc
columns and large LongReadLen

r7789@Thesaurus (orig r7777):  triode | 2009-10-09 22:44:21 +0200
added my name to contributors list

r7790@Thesaurus (orig r7778):  ribasushi | 2009-10-10 18:49:15 +0200
Whoops, this isn't right
r7791@Thesaurus (orig r7779):  ribasushi | 2009-10-11 15:44:18 +0200
More ordered fixes
r7793@Thesaurus (orig r7781):  norbi | 2009-10-13 11:27:18 +0200
 r7982@vger:  mendel | 2009-10-13 11:26:11 +0200
 Fixed a typo and a POD error.

r7805@Thesaurus (orig r7793):  ribasushi | 2009-10-16 14:28:35 +0200
Fix test to stop failing when DT-support is not present
r7811@Thesaurus (orig r7799):  caelum | 2009-10-18 11:13:29 +0200
 r20728@hlagh (orig r7703):  ribasushi | 2009-09-20 18:51:16 -0400
 Another try at a clean sybase branch
 r20730@hlagh (orig r7705):  ribasushi | 2009-09-20 18:58:09 -0400
 Part one of the sybase work by Caelum (mostly reviewed)
 r20731@hlagh (orig r7706):  ribasushi | 2009-09-20 19:18:40 -0400
 main sybase branch ready
 r21051@hlagh (orig r7797):  caelum | 2009-10-18 04:57:43 -0400
  r20732@hlagh (orig r7707):  ribasushi | 2009-09-20 19:20:00 -0400
  Branch for bulk insert
  r20733@hlagh (orig r7708):  ribasushi | 2009-09-20 20:06:21 -0400
  All sybase bulk-insert code by Caelum
  r20750@hlagh (orig r7725):  caelum | 2009-09-24 02:47:39 -0400
  clean up set_identity stuff
  r20751@hlagh (orig r7726):  caelum | 2009-09-24 05:21:18 -0400
  minor cleanups, test update of blob to NULL
  r20752@hlagh (orig r7727):  caelum | 2009-09-24 08:45:04 -0400
  remove some duplicate code
  r20753@hlagh (orig r7728):  caelum | 2009-09-24 09:57:58 -0400
  fix insert with all defaults
  r20786@hlagh (orig r7732):  caelum | 2009-09-25 21:17:16 -0400
  some cleanups
  r20804@hlagh (orig r7736):  caelum | 2009-09-28 05:31:38 -0400
  minor changes
  r20805@hlagh (orig r7737):  caelum | 2009-09-28 06:25:48 -0400
  fix DT stuff
  r20809@hlagh (orig r7741):  caelum | 2009-09-28 22:25:55 -0400
  removed some dead code, added fix and test for _execute_array_empty
  r20811@hlagh (orig r7743):  caelum | 2009-09-29 13:36:20 -0400
  minor changes after review
  r20812@hlagh (orig r7744):  caelum | 2009-09-29 14:16:03 -0400
  do not clobber $rv from execute_array
  r20813@hlagh (orig r7745):  caelum | 2009-09-29 14:38:14 -0400
  make insert_bulk atomic
  r20815@hlagh (orig r7747):  caelum | 2009-09-29 20:35:26 -0400
  remove _exhaaust_statements
  r20816@hlagh (orig r7748):  caelum | 2009-09-29 21:48:38 -0400
  fix insert_bulk when not using bulk api inside a txn
  r20831@hlagh (orig r7749):  caelum | 2009-09-30 02:53:42 -0400
  added test for populate being atomic
  r20832@hlagh (orig r7750):  caelum | 2009-09-30 03:00:59 -0400
  factor out subclass-specific _execute_array callback
  r20833@hlagh (orig r7751):  caelum | 2009-10-01 11:59:30 -0400
  remove a piece of dead code
  r20840@hlagh (orig r7758):  caelum | 2009-10-03 15:46:56 -0400
  remove _pretty_print
  r20842@hlagh (orig r7760):  caelum | 2009-10-04 16:19:56 -0400
  minor optimization for insert_bulk
  r21050@hlagh (orig r7796):  caelum | 2009-10-18 04:56:54 -0400
  error checking related to literal SQL for insert_bulk

r7820@Thesaurus (orig r7808):  caelum | 2009-10-21 03:10:39 +0200
add test for populate with literal sql mixed with binds, improve error messages
r7823@Thesaurus (orig r7811):  ribasushi | 2009-10-21 16:33:45 +0200
Show what's wrong with the current populate code
r7824@Thesaurus (orig r7812):  caelum | 2009-10-22 11:10:38 +0200
stringify values passed to populate/insert_bulk
r7825@Thesaurus (orig r7813):  ribasushi | 2009-10-22 13:17:41 +0200
Some smoker run the suite for 30 *minutes* - the timeout seems to be too short for them (boggle)
r7826@Thesaurus (orig r7814):  caelum | 2009-10-22 14:41:37 +0200
a few extra tests can never hurt, right? :)
r7827@Thesaurus (orig r7815):  ribasushi | 2009-10-23 10:51:05 +0200
Prevent sqlt from failing silently
r7828@Thesaurus (orig r7816):  ribasushi | 2009-10-23 10:52:49 +0200
{ is_foreign_key_constraint => 0, on_delete => undef } is a valid construct - no need to carp
r7832@Thesaurus (orig r7820):  robkinyon | 2009-10-26 20:11:22 +0100
Fixed bad if-check in columns()
r7840@Thesaurus (orig r7828):  caelum | 2009-10-31 14:01:56 +0100
change repository in meta to point to real svn url rather than svnweb
r7842@Thesaurus (orig r7830):  caelum | 2009-10-31 21:04:39 +0100
pass sqlite_version to SQLT
r7843@Thesaurus (orig r7831):  caelum | 2009-10-31 21:22:37 +0100
fix regex to numify sqlite_version
r7844@Thesaurus (orig r7832):  caelum | 2009-10-31 23:59:19 +0100
work-around disconnect bug with DBD::Pg 2.15.1
r7855@Thesaurus (orig r7843):  ribasushi | 2009-11-04 10:55:51 +0100
 r7817@Thesaurus (orig r7805):  rbuels | 2009-10-21 02:37:28 +0200
 making a branch, here we go again with the pg_unqualified_schema
 r7818@Thesaurus (orig r7806):  rbuels | 2009-10-21 02:38:59 +0200
 more pg unqualified schema tests, which expose a gap in the coverage
 r7819@Thesaurus (orig r7807):  rbuels | 2009-10-21 03:10:38 +0200
 gutted Pg storage driver's sequence discovery to just rely on DBD::Pg's last_insert_id.  this needs testing with older versions of DBD::Pg
 r7821@Thesaurus (orig r7809):  rbuels | 2009-10-21 04:00:39 +0200
 more coverage in Pg sequence-discovery tests.  i think this shows why last_insert_id cannot be used.
 r7822@Thesaurus (orig r7810):  rbuels | 2009-10-21 04:07:05 +0200
 reverted [7807], and just changed code to use the custom pg_catalog query, which is the only thing that works in the pathological case where DBIC is told a different primary key from the primary key that is set on the table in the DB ([7809] added testing for this)
 r7852@Thesaurus (orig r7840):  rbuels | 2009-11-03 18:47:05 +0100
 added Changes line mentioning tweak to Pg auto-inc fix
 r7854@Thesaurus (orig r7842):  ribasushi | 2009-11-04 10:55:35 +0100
 Cleanup exceptions

r7858@Thesaurus (orig r7846):  caelum | 2009-11-06 16:01:30 +0100
transactions for MSSQL over DBD::Sybase
r7861@Thesaurus (orig r7849):  caelum | 2009-11-10 13:16:18 +0100
made commit/rollback when disconnected an exception
r7862@Thesaurus (orig r7850):  robkinyon | 2009-11-10 17:19:57 +0100
Added a note about select
r7863@Thesaurus (orig r7851):  ribasushi | 2009-11-10 18:23:10 +0100
Changes
r7867@Thesaurus (orig r7855):  frew | 2009-11-11 21:56:37 +0100
RT50874
r7868@Thesaurus (orig r7856):  frew | 2009-11-11 23:50:43 +0100
RT50828
r7869@Thesaurus (orig r7857):  frew | 2009-11-11 23:54:15 +0100
clearer test message
r7870@Thesaurus (orig r7858):  frew | 2009-11-12 00:37:27 +0100
some cleanup for $rs->populate
r7872@Thesaurus (orig r7860):  ribasushi | 2009-11-12 01:35:36 +0100
Fix find on resultset with custom result_class
r7873@Thesaurus (orig r7861):  ribasushi | 2009-11-12 01:40:14 +0100
Fix return value of in_storage
r7874@Thesaurus (orig r7862):  ribasushi | 2009-11-12 01:43:48 +0100
Extra FAQ entry
r7875@Thesaurus (orig r7863):  ribasushi | 2009-11-12 02:11:25 +0100
Sanify _determine_driver handling in ::Storage::DBI
r7876@Thesaurus (orig r7864):  ribasushi | 2009-11-12 02:14:37 +0100
Add mysql determine_driver test by Pedro Melo
r7881@Thesaurus (orig r7869):  ribasushi | 2009-11-12 11:10:04 +0100
_cond_for_update_delete is hopelessly broken attempting to introspect SQLA1. Replace with a horrific but effective hack
r7882@Thesaurus (orig r7870):  ribasushi | 2009-11-12 11:15:12 +0100
Clarifying comment
r7884@Thesaurus (orig r7872):  ribasushi | 2009-11-13 00:13:40 +0100
The real fix for the non-introspectable condition bug, mst++
r7885@Thesaurus (orig r7873):  ribasushi | 2009-11-13 00:24:56 +0100
Some cleanup
r7887@Thesaurus (orig r7875):  frew | 2009-11-13 10:01:37 +0100
fix subtle bug with Sybase database type determination
r7892@Thesaurus (orig r7880):  frew | 2009-11-14 00:53:29 +0100
release woo!
r7894@Thesaurus (orig r7882):  caelum | 2009-11-14 03:57:52 +0100
fix oracle dep in Makefile.PL
r7895@Thesaurus (orig r7883):  caelum | 2009-11-14 04:20:53 +0100
skip Oracle BLOB tests on DBD::Oracle == 1.23
r7897@Thesaurus (orig r7885):  caelum | 2009-11-14 09:40:01 +0100
 r7357@pentium (orig r7355):  caelum | 2009-08-20 17:58:23 -0400
 branch to support MSSQL over ADO
 r7358@pentium (orig r7356):  caelum | 2009-08-21 00:32:14 -0400
 something apparently working
 r7359@pentium (orig r7357):  caelum | 2009-08-21 00:53:53 -0400
 slightly better mars test, still passes

r7899@Thesaurus (orig r7887):  caelum | 2009-11-14 09:41:54 +0100
 r7888@pentium (orig r7886):  caelum | 2009-11-14 03:41:25 -0500
 add TODO test for large column list in select

r7901@Thesaurus (orig r7889):  caelum | 2009-11-14 09:47:16 +0100
add ADO/MSSQL to Changes
r7902@Thesaurus (orig r7890):  caelum | 2009-11-14 10:27:29 +0100
fix the large column list test for ADO/MSSQL, now passes
r7904@Thesaurus (orig r7892):  caelum | 2009-11-14 12:20:58 +0100
fix Changes (ADO change in wrong release)
r7905@Thesaurus (orig r7893):  ribasushi | 2009-11-14 19:23:23 +0100
Release 0.08114
r7907@Thesaurus (orig r7895):  ribasushi | 2009-11-15 12:09:17 +0100
Failing test to highlight mssql autoconnect regression
r7908@Thesaurus (orig r7896):  ribasushi | 2009-11-15 12:20:25 +0100
Fix plan
r7913@Thesaurus (orig r7901):  ribasushi | 2009-11-15 13:11:38 +0100
 r7773@Thesaurus (orig r7761):  norbi | 2009-10-05 14:49:06 +0200
 Created branch 'prefetch_bug-unqualified_column_in_search_related_cond': A bug that manifests when a prefetched table's column is referenced without the table name in the condition of a search_related() on an M:N relationship.
 r7878@Thesaurus (orig r7866):  ribasushi | 2009-11-12 02:36:08 +0100
 Factor some code out
 r7879@Thesaurus (orig r7867):  ribasushi | 2009-11-12 09:11:03 +0100
 Factor out more stuff
 r7880@Thesaurus (orig r7868):  ribasushi | 2009-11-12 09:21:04 +0100
 Saner naming/comments
 r7910@Thesaurus (orig r7898):  ribasushi | 2009-11-15 12:39:29 +0100
 Move more code to DBIHacks, put back the update/delete rs check, just in case
 r7911@Thesaurus (orig r7899):  ribasushi | 2009-11-15 13:01:34 +0100
 TODOify test until we get an AST
 r7912@Thesaurus (orig r7900):  ribasushi | 2009-11-15 13:10:15 +0100
 Hide from pause

r7921@Thesaurus (orig r7909):  ribasushi | 2009-11-15 14:17:48 +0100
 r7871@Thesaurus (orig r7859):  ribasushi | 2009-11-12 00:46:07 +0100
 Branches to test some ideas
 r7889@Thesaurus (orig r7877):  abraxxa | 2009-11-13 12:05:50 +0100
 added rels to view result classes in test schema

 r7890@Thesaurus (orig r7878):  abraxxa | 2009-11-13 13:05:45 +0100
 seems I found the bugger

 r7917@Thesaurus (orig r7905):  ribasushi | 2009-11-15 13:29:23 +0100
 FK constraints towards a view don't quite work
 r7918@Thesaurus (orig r7906):  ribasushi | 2009-11-15 14:10:10 +0100
 Turn into a straight-inheritance view class
 r7919@Thesaurus (orig r7907):  ribasushi | 2009-11-15 14:11:03 +0100
 Extensive test of virtual and classic view relationships
 r7920@Thesaurus (orig r7908):  ribasushi | 2009-11-15 14:17:23 +0100
 Fix non-sqlt schema file

r7923@Thesaurus (orig r7911):  caelum | 2009-11-15 18:31:37 +0100
fix MSSQL via DBD::Sybase regression
r7930@Thesaurus (orig r7918):  ribasushi | 2009-11-16 19:15:45 +0100
 r7864@Thesaurus (orig r7852):  edenc | 2009-11-10 20:15:15 +0100
 branching for fixes related to prefetch, distinct and group by
 r7865@Thesaurus (orig r7853):  edenc | 2009-11-10 20:21:38 +0100
 added test case for ensuring a column mentioned in the order by clause is also included in the group by clause
 r7926@Thesaurus (orig r7914):  ribasushi | 2009-11-16 08:09:30 +0100
 Make _resolve_column_info function without supplying column names
 r7927@Thesaurus (orig r7915):  ribasushi | 2009-11-16 08:11:17 +0100
 Fix order_by/distinct bug

lib/DBIx/Class/ResultSet.pm
t/101populate_rs.t

index 54f1cac..ea0f296 100644 (file)
@@ -1715,6 +1715,19 @@ sub populate {
       }
     }
 
+    ## merge with the conditions from $self (inherited conditions)
+    my ($inherited_cond) = $self->_merge_with_cond({});
+    delete @{$inherited_cond}{@names};
+    my @inherited_names = keys %$inherited_cond;
+    my @values;
+    foreach my $row (@$data) {
+      my %row_data;
+      @row_data{@names} = @{$row}{@names};
+      my ($merged_cond) = $self->_merge_with_cond(\%row_data);
+      push @values, [ @{$merged_cond}{@names, @inherited_names} ];
+    }
+    push @names, @inherited_names;
+
     ## do bulk insert on current row
     $self->result_source->storage->insert_bulk(
       $self->result_source,
@@ -1856,15 +1869,39 @@ sub new_result {
   $self->throw_exception( "new_result needs a hash" )
     unless (ref $values eq 'HASH');
 
-  my %new;
+  my ($merged_cond, $from_resultset) = $self->_merge_with_cond($values);
+
+  my %new = (
+    %$merged_cond,
+    @$from_resultset
+      ? (-from_resultset => $from_resultset)
+      : (),
+    -source_handle => $self->_source_handle,
+    -result_source => $self->result_source, # DO NOT REMOVE THIS, REQUIRED
+  );
+
+  return $self->result_class->new(\%new);
+}
+
+# _merge_with_cond
+#
+# Merges $values (a hashref) with the condition in the resultset and returns
+# the resulting hashref and an arrayref that contains the keys that are coming
+# from related resultsets.
+
+sub _merge_with_cond {
+  my ($self, $values) = @_;
+
+  my (%merged_cond, @from_resultset);
+
   my $alias = $self->{attrs}{alias};
 
   if (
     defined $self->{cond}
     && $self->{cond} eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION
   ) {
-    %new = %{ $self->{attrs}{related_objects} || {} };  # nothing might have been inserted yet
-    $new{-from_resultset} = [ keys %new ] if keys %new;
+    %merged_cond = %{ $self->{attrs}{related_objects} || {} };  # nothing might have been inserted yet
+    @from_resultset = keys %merged_cond;
   } else {
     $self->throw_exception(
       "Can't abstract implicit construct, condition not a hash"
@@ -1878,24 +1915,22 @@ sub new_result {
 
     # precendence must be given to passed values over values inherited from
     # the cond, so the order here is important.
-    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->{'='};
+    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 '=') {
+        $merged_cond{$col} = $value->{'='};
         next;
       }
-      $new{$col} = $value if $self->_is_deterministic_value($value);
+      $merged_cond{$col} = $value if $self->_is_deterministic_value($value);
     }
   }
 
-  %new = (
-    %new,
+  %merged_cond = (
+    %merged_cond,
     %{ $self->_remove_alias($values, $alias) },
-    -source_handle => $self->_source_handle,
-    -result_source => $self->result_source, # DO NOT REMOVE THIS, REQUIRED
   );
 
-  return $self->result_class->new(\%new);
+  return (\%merged_cond, \@from_resultset);
 }
 
 # _is_deterministic_value
index 89b9f41..2b42771 100644 (file)
@@ -15,8 +15,6 @@ use Test::More;
 use lib qw(t/lib);
 use DBICTest;
 
-plan tests => 142;
-
 
 ## ----------------------------------------------------------------------------
 ## Get a Schema and some ResultSets we can play with.
@@ -26,6 +24,8 @@ my $schema    = DBICTest->init_schema();
 my $art_rs     = $schema->resultset('Artist');
 my $cd_rs      = $schema->resultset('CD');
 
+my $restricted_art_rs  = $art_rs->search({rank => 42});
+
 ok( $schema, 'Got a Schema object');
 ok( $art_rs, 'Got Good Artist Resultset');
 ok( $cd_rs, 'Got Good CD Resultset');
@@ -333,6 +333,18 @@ ARRAY_CONTEXT: {
                is($cdB->artist->name, 'Fred BloggsD', 'Set Artist to FredD');
                ok($cdB->artist->artistid == $aid, "Got Expected Artist ID");
        }
+
+  WITH_COND_FROM_RS: {
+  
+    my ($more_crap) = $restricted_art_rs->populate([
+      {
+        name => 'More Manufactured Crap',
+      },
+    ]);
+    
+    ## Did it use the condition in the resultset?
+    cmp_ok( $more_crap->rank, '==', 42, "Got Correct rank for result object");
+  } 
 }
 
 
@@ -601,6 +613,21 @@ VOID_CONTEXT: {
                ok( $cd2->title eq "VOID_Yet More Tweeny-Pop crap", "Got Expected CD Title");
        }
 
+  WITH_COND_FROM_RS: {
+  
+    $restricted_art_rs->populate([
+      {
+        name => 'VOID More Manufactured Crap',
+      },
+    ]);
+
+    my $more_crap = $art_rs->search({
+      name => 'VOID More Manufactured Crap'
+    })->first;
+    
+    ## Did it use the condition in the resultset?
+    cmp_ok( $more_crap->rank, '==', 42, "Got Correct rank for result object");
+  } 
 }
 
 ARRAYREF_OF_ARRAYREF_STYLE: {
@@ -619,6 +646,8 @@ ARRAYREF_OF_ARRAYREF_STYLE: {
   is $jumped->name, 'A singer that jumped the shark two albums ago', 'Correct Name';
   is $cool->name, 'An actually cool singer.', 'Correct Name';
   
+  #cmp_ok $cool->rank, '==', 42, 'Correct Rank';
+  
   my ($cooler, $lamer) = $art_rs->populate([
     [qw/artistid name/],
     [1003, 'Cooler'],
@@ -627,4 +656,36 @@ ARRAYREF_OF_ARRAYREF_STYLE: {
   
   is $cooler->name, 'Cooler', 'Correct Name';
   is $lamer->name, 'Lamer', 'Correct Name';  
-}
\ No newline at end of file
+
+  #cmp_ok $cooler->rank, '==', 42, 'Correct Rank';
+
+  ARRAY_CONTEXT_WITH_COND_FROM_RS: {
+  
+    my ($mega_lamer) = $restricted_art_rs->populate([
+      {
+        name => 'Mega Lamer',
+      },
+    ]);
+
+    ## Did it use the condition in the resultset?
+    cmp_ok( $mega_lamer->rank, '==', 42, "Got Correct rank for result object");
+  } 
+
+  VOID_CONTEXT_WITH_COND_FROM_RS: {
+  
+    $restricted_art_rs->populate([
+      {
+        name => 'VOID Mega Lamer',
+      },
+    ]);
+
+    my $mega_lamer = $art_rs->search({
+      name => 'VOID Mega Lamer'
+    })->first;
+    
+    ## Did it use the condition in the resultset?
+    cmp_ok( $mega_lamer->rank, '==', 42, "Got Correct rank for result object");
+  } 
+}
+
+done_testing;