[Bast-commits] r3890 - in DBIx-Class/0.08/branches/versioned_enhancements: . lib/DBIx lib/DBIx/Class lib/DBIx/Class/Manual lib/DBIx/Class/Relationship lib/DBIx/Class/Storage lib/DBIx/Class/Storage/DBI lib/SQL/Translator/Parser/DBIx t t/lib/DBICTest t/lib/DBICTest/Schema

ash at dev.catalyst.perl.org ash at dev.catalyst.perl.org
Sat Nov 24 21:27:52 GMT 2007


Author: ash
Date: 2007-11-24 21:27:52 +0000 (Sat, 24 Nov 2007)
New Revision: 3890

Added:
   DBIx-Class/0.08/branches/versioned_enhancements/t/lib/DBICTest/Schema/ForceForeign.pm
Modified:
   DBIx-Class/0.08/branches/versioned_enhancements/
   DBIx-Class/0.08/branches/versioned_enhancements/Changes
   DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class.pm
   DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/InflateColumn.pm
   DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Manual/Cookbook.pod
   DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Manual/FAQ.pod
   DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Relationship/BelongsTo.pm
   DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/ResultSet.pm
   DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/ResultSource.pm
   DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Row.pm
   DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Storage/DBI/Replication.pm
   DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Storage/Statistics.pm
   DBIx-Class/0.08/branches/versioned_enhancements/lib/SQL/Translator/Parser/DBIx/Class.pm
   DBIx-Class/0.08/branches/versioned_enhancements/t/73oracle_inflate.t
   DBIx-Class/0.08/branches/versioned_enhancements/t/86sqlt.t
   DBIx-Class/0.08/branches/versioned_enhancements/t/90join_torture.t
   DBIx-Class/0.08/branches/versioned_enhancements/t/91merge_attr.t
   DBIx-Class/0.08/branches/versioned_enhancements/t/lib/DBICTest/Schema.pm
Log:
 r5181 at metis (orig r3840):  bert | 2007-10-25 11:04:42 +0100
  r10510 at beetle:  bert | 2007-10-25 11:22:07 +0200
  Merged with replication branch (fixed wrong object-function calls preventing set_schema to work rev3823). Added myself to contributors.
 
 r5182 at metis (orig r3841):  captainL | 2007-10-26 11:53:26 +0100
 the checks in reverse_relationship_info are less ambiguous
 r5183 at metis (orig r3842):  ash | 2007-10-27 18:53:39 +0100
 Reorder Changes file. (New changes go at bottom of block please!)
 r5185 at metis (orig r3843):  tomboh | 2007-10-29 17:19:01 +0000
 Improve Documentation.
 
 r5186 at metis (orig r3844):  captainL | 2007-10-29 20:26:02 +0000
 fixed _merge_attr bug
 r5187 at metis (orig r3845):  captainL | 2007-10-29 20:28:45 +0000
 spelt Zby's name properly
 r8126 at metis (orig r3852):  castaway | 2007-11-03 02:17:11 +0000
 Improve inflatecolumn docs
 
 r9392 at metis (orig r3853):  matthewt | 2007-11-06 14:53:48 +0000
 make belongs_to accept an [] join cond
 r9632 at metis (orig r3872):  castaway | 2007-11-12 21:13:33 +0000
 Added cookbook recipe for using dual, thanks Richard
 
 r9764 at metis (orig r3879):  ash | 2007-11-15 12:49:53 +0000
 Fix is_foreign_key_constraint - thanks Jon Schutz
 r9766 at metis (orig r3880):  ash | 2007-11-15 13:02:15 +0000
 Adding missing file
 r9767 at metis (orig r3881):  ash | 2007-11-15 13:52:58 +0000
 Fix t/82cascade_copy.t
 r9812 at metis (orig r3883):  tomboh | 2007-11-15 15:05:12 +0000
 Remove an unneeded requirement.
 
 r9814 at metis (orig r3885):  ash | 2007-11-16 14:30:51 +0000
 Version bump
 r9896 at metis (orig r3886):  ash | 2007-11-19 18:11:53 +0000
 Fix END block
 r11311 at metis (orig r3887):  wreis | 2007-11-21 13:57:35 +0000
 minor fixes for ResultSet docs
 r11312 at metis (orig r3888):  ash | 2007-11-22 15:27:23 +0000
 Fix mistakes
 r11454 at metis (orig r3889):  ash | 2007-11-24 21:24:53 +0000
 Sort tables for consistent output



Property changes on: DBIx-Class/0.08/branches/versioned_enhancements
___________________________________________________________________
Name: svk:merge
   - 168d5346-440b-0410-b799-f706be625ff1:/DBIx-Class-current:2207
462d4d0c-b505-0410-bf8e-ce8f877b3390:/local/bast/DBIx-Class:3159
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/on_disconnect_do:3694
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/trunk:3829
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-C3:318
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-current:2222
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-joins:173
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-resultset:570
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/datetime:1716
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/find_compat:1855
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/find_unique_query_fixes:2142
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/inflate:1988
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/many_to_many:2025
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/re_refactor_bugfix:1944
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/reorganize_tests:1827
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset-new-refactor:1766
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset_2_electric_boogaloo:2175
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset_cleanup:2102
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/sqlt_tests_refactor:2043
   + 168d5346-440b-0410-b799-f706be625ff1:/DBIx-Class-current:2207
462d4d0c-b505-0410-bf8e-ce8f877b3390:/local/bast/DBIx-Class:3159
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/branches/on_disconnect_do:3694
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/DBIx-Class/0.08/trunk:3889
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-C3:318
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-current:2222
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-joins:173
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class-resultset:570
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/datetime:1716
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/find_compat:1855
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/find_unique_query_fixes:2142
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/inflate:1988
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/many_to_many:2025
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/re_refactor_bugfix:1944
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/reorganize_tests:1827
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset-new-refactor:1766
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset_2_electric_boogaloo:2175
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/resultset_cleanup:2102
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/branches/DBIx-Class/sqlt_tests_refactor:2043
bd8105ee-0ff8-0310-8827-fb3f25b6796d:/trunk/DBIx-Class:3606
fe160bb6-dc1c-0410-9f2b-d64a711b54a5:/local/DBIC-trunk-0.08:10510

Modified: DBIx-Class/0.08/branches/versioned_enhancements/Changes
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/Changes	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/Changes	2007-11-24 21:27:52 UTC (rev 3890)
@@ -1,6 +1,10 @@
 Revision history for DBIx::Class
+
         - Versioning refactored
         - Row::insert will now not fall over if passed duplicate related objects
+
+0.08008 2007-11-16 14:30:00
+        - Fixed join merging bug (test from Zby)
         - When adding relationships, it will throw an exception if you get the
           foreign and self parts the wrong way round in the condition
         - ResultSetColumn::func() now returns all results if called in list
@@ -15,6 +19,11 @@
           RedHat systems from perl-5.8.8-10 and up that have the bless/overload
           patch applied (badly) which causes 2x -> 100x performance penalty.
           (Jon Schutz)
+        - ResultSource::reverse_relationship_info can distinguish between 
+          sources using the same table
+        - Row::insert will now not fall over if passed duplicate related objects
+        - Row::copy will not fall over if you have two relationships to the 
+          same source with a unique constraint on it
 
 0.08007 2007-09-04 19:36:00
         - patch for Oracle datetime inflation (abram at arin.net)

Modified: DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/InflateColumn.pm
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/InflateColumn.pm	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/InflateColumn.pm	2007-11-24 21:27:52 UTC (rev 3890)
@@ -25,13 +25,20 @@
 for the database.
 
 It can be used, for example, to automatically convert to and from
-L<DateTime> objects for your date and time fields.
+L<DateTime> objects for your date and time fields. There's a
+conveniece component to actually do that though, try
+L<DBIx::Class::InflateColumn::DateTime>.
 
-It will accept arrayrefs, hashrefs and blessed references (objects),
-but not scalarrefs. Scalar references are passed through to the
-database to deal with, to allow such settings as C< \'year + 1'> and
-C< \'DEFAULT' > to work.
+It will handle all types of references except scalar references. It
+will not handle scalar values, these are ignored and thus passed
+through to L<SQL::Abstract>. This is to allow setting raw values to
+"just work". Scalar references are passed through to the database to
+deal with, to allow such settings as C< \'year + 1'> and C< \'DEFAULT' >
+to work.
 
+If you want to filter plain scalar values and replace them with
+something else, contribute a filtering component.
+
 =head1 METHODS
 
 =head2 inflate_column
@@ -57,8 +64,7 @@
 
 The coderefs you set for inflate and deflate are called with two parameters,
 the first is the value of the column to be inflated/deflated, the second is the
-row object itself. Thus you can call C<< ->result_source->schema->storage->dbh >> on
-it, to feed to L<DateTime::Format::DBI>.
+row object itself. Thus you can call C<< ->result_source->schema->storage->dbh >> in your inflate/defalte subs, to feed to L<DateTime::Format::DBI>.
 
 In this example, calls to an event's C<insert_time> accessor return a
 L<DateTime> object. This L<DateTime> object is later "deflated" when

Modified: DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Manual/Cookbook.pod
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Manual/Cookbook.pod	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Manual/Cookbook.pod	2007-11-24 21:27:52 UTC (rev 3890)
@@ -767,38 +767,37 @@
 
 =head2 Create a new row in a related table
 
-  my $book->create_related('author', { name => 'Fred'});
+  my $author = $book->create_related('author', { name => 'Fred'});
 
 =head2 Search in a related table
 
 Only searches for books named 'Titanic' by the author in $author.
 
-  my $author->search_related('books', { name => 'Titanic' });
+  my $books_rs = $author->search_related('books', { name => 'Titanic' });
 
 =head2 Delete data in a related table
 
 Deletes only the book named Titanic by the author in $author.
 
-  my $author->delete_related('books', { name => 'Titanic' });
+  $author->delete_related('books', { name => 'Titanic' });
 
 =head2 Ordering a relationship result set
 
 If you always want a relation to be ordered, you can specify this when you 
 create the relationship.
 
-To order C<< $book->pages >> by descending page_number.
+To order C<< $book->pages >> by descending page_number, create the relation
+as follows:
 
-  Book->has_many('pages' => 'Page', 'book', { order_by => \'page_number DESC'} );
+  __PACKAGE__->has_many('pages' => 'Page', 'book', { order_by => \'page_number DESC'} );
 
 =head2 Many-to-many relationships
 
 This is straightforward using L<ManyToMany|DBIx::Class::Relationship/many_to_many>:
 
-  package My::DB;
-  # ... set up connection ...
-
   package My::User;
-  use base 'My::DB';
+  use base 'DBIx::Class';
+  __PACKAGE__->load_components('Core');
   __PACKAGE__->table('user');
   __PACKAGE__->add_columns(qw/id name/);
   __PACKAGE__->set_primary_key('id');
@@ -806,7 +805,8 @@
   __PACKAGE__->many_to_many('addresses' => 'user_address', 'address');
 
   package My::UserAddress;
-  use base 'My::DB';
+  use base 'DBIx::Class';
+  __PACKAGE__->load_components('Core');
   __PACKAGE__->table('user_address');
   __PACKAGE__->add_columns(qw/user address/);
   __PACKAGE__->set_primary_key(qw/user address/);
@@ -814,7 +814,8 @@
   __PACKAGE__->belongs_to('address' => 'My::Address');
 
   package My::Address;
-  use base 'My::DB';
+  use base 'DBIx::Class';
+  __PACKAGE__->load_components('Core');
   __PACKAGE__->table('address');
   __PACKAGE__->add_columns(qw/id street town area_code country/);
   __PACKAGE__->set_primary_key('id');
@@ -841,7 +842,7 @@
     $genus->add_to_species({ name => 'troglodyte' });
     $genus->wings(2);
     $genus->update;
-    $schema->txn_do($coderef2); # Can have a nested transaction
+    $schema->txn_do($coderef2); # Can have a nested transaction. Only the outer will actualy commit
     return $genus->species;
   };
 
@@ -874,7 +875,8 @@
 The recommend way of achieving this is to use the 
 L<make_schema_at|DBIx::Class::Schema::Loader/make_schema_at> method:
 
-  perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib -e 'make_schema_at("My::Schema", { debug => 1 }, [ "dbi:Pg:dbname=foo","postgres" ])'
+  perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib \
+    -e 'make_schema_at("My::Schema", { debug => 1 }, [ "dbi:Pg:dbname=foo","postgres" ])'
 
 This will create a tree of files rooted at C<./lib/My/Schema/> containing
 source definitions for all the tables found in the C<foo> database.
@@ -920,6 +922,98 @@
 requires that the files for 0.1 as created above are available in the
 given directory to diff against.
 
+=head2 Select from dual
+
+Dummy tables are needed by some databases to allow calling functions
+or expressions that aren't based on table content, for examples of how
+this applies to various database types, see:
+L<http://troels.arvin.dk/db/rdbms/#other-dummy_table>.
+
+Note: If you're using Oracles dual table don't B<ever> do anything
+other than a select, if you CRUD on your dual table you *will* break
+your database.
+
+Make a table class as you would for any other table
+                                                                               
+  package MyAppDB::Dual;
+  use strict;
+  use warnings;
+  use base 'DBIx::Class';
+  __PACKAGE__->load_components("Core");
+  __PACKAGE__->table("Dual");
+  __PACKAGE__->add_columns(
+    "dummy",
+    { data_type => "VARCHAR2", is_nullable => 0, size => 1 },
+  );
+ 
+Once you've loaded your table class select from it using C<select>
+and C<as> instead of C<columns>
+ 
+  my $rs = $schema->resultset('Dual')->search(undef,
+    { select => [ 'sydate' ],
+      as     => [ 'now' ]
+    },
+  );
+ 
+All you have to do now is be careful how you access your resultset, the below
+will not work because there is no column called 'now' in the Dual table class
+ 
+  while (my $dual = $rs->next) {
+    print $dual->now."\n";
+  }
+  # Can't locate object method "now" via package "MyAppDB::Dual" at headshot.pl line 23.
+ 
+You could of course use 'dummy' in C<as> instead of 'now', or C<add_columns> to
+your Dual class for whatever you wanted to select from dual, but that's just
+silly, instead use C<get_column>
+ 
+  while (my $dual = $rs->next) {
+    print $dual->get_column('now')."\n";
+  }
+ 
+Or use C<cursor>
+ 
+  my $cursor = $rs->cursor;
+  while (my @vals = $cursor->next) {
+    print $vals[0]."\n";
+  }
+ 
+Or use L<DBIx::Class::ResultClass::HashRefInflator>
+ 
+  $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
+  while ( my $dual = $rs->next ) {
+    print $dual->{now}."\n";
+  }
+ 
+Here are some example C<select> conditions to illustrate the different syntax
+you could use for doing stuff like 
+C<oracles.heavily(nested(functions_can('take', 'lots'), OF), 'args')>
+ 
+  # get a sequence value
+  select => [ 'A_SEQ.nextval' ],
+ 
+  # get create table sql
+  select => [ { 'dbms_metadata.get_ddl' => [ "'TABLE'", "'ARTIST'" ]} ],
+ 
+  # get a random num between 0 and 100
+  select => [ { "trunc" => [ { "dbms_random.value" => [0,100] } ]} ],
+ 
+  # what year is it?
+  select => [ { 'extract' => [ \'year from sysdate' ] } ],
+ 
+  # do some math
+  select => [ {'round' => [{'cos' => [ \'180 * 3.14159265359/180' ]}]}],
+ 
+  # which day of the week were you born on?
+  select => [{'to_char' => [{'to_date' => [ "'25-DEC-1980'", "'dd-mon-yyyy'" ]}, "'day'"]}],
+ 
+  # select 16 rows from dual
+  select   => [ "'hello'" ],
+  as       => [ 'world' ],
+  group_by => [ 'cube( 1, 2, 3, 4 )' ],
+ 
+ 
+
 =head2 Adding Indexes And Functions To Your SQL
 
 Often you will want indexes on columns on your table to speed up searching. To

Modified: DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Manual/FAQ.pod
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Manual/FAQ.pod	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Manual/FAQ.pod	2007-11-24 21:27:52 UTC (rev 3890)
@@ -419,6 +419,17 @@
 search again or relationship accessors. The SQL query is only run when
 you ask the resultset for an actual row object.
 
+=item How do I deal with tables that lack a primary key?
+
+If your table lacks a primary key, DBIx::Class can't work out which row
+it should operate on, for example to delete or update.  However, a
+UNIQUE constraint on one or more columns allows DBIx::Class to uniquely
+identify the row, so you can tell L<DBIx::Class::ResultSource> these
+columns act as a primary key, even if they don't from the database's
+point of view:
+
+ $resultset->set_primary_key(@column);
+
 =back
 
 =head2 Notes for CDBI users

Modified: DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Relationship/BelongsTo.pm
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Relationship/BelongsTo.pm	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Relationship/BelongsTo.pm	2007-11-24 21:27:52 UTC (rev 3890)
@@ -41,20 +41,25 @@
     );
   }
   # explicit join condition
-  elsif (ref $cond eq 'HASH') {
-    my $cond_rel;
-    for (keys %$cond) {
-      if (m/\./) { # Explicit join condition
-        $cond_rel = $cond;
-        last;
+  elsif (ref $cond) {
+    if (ref $cond eq 'HASH') { # ARRAY is also valid
+      my $cond_rel;
+      for (keys %$cond) {
+        if (m/\./) { # Explicit join condition
+          $cond_rel = $cond;
+          last;
+        }
+        $cond_rel->{"foreign.$_"} = "self.".$cond->{$_};
       }
-      $cond_rel->{"foreign.$_"} = "self.".$cond->{$_};
+      $cond = $cond_rel;
     }
-    my $acc_type = (keys %$cond_rel == 1 and $class->has_column($rel))
-      ? 'filter'
-      : 'single';
+    my $acc_type = ((ref $cond eq 'HASH')
+                       && keys %$cond == 1
+                       && $class->has_column($rel))
+                     ? 'filter'
+                     : 'single';
     $class->add_relationship($rel, $f_class,
-      $cond_rel,
+      $cond,
       { accessor => $acc_type, %{$attrs || {}} }
     );
   }

Modified: DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/ResultSet.pm
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/ResultSet.pm	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/ResultSet.pm	2007-11-24 21:27:52 UTC (rev 3890)
@@ -1563,7 +1563,7 @@
 
 =item Arguments: \%vals
 
-=item Return Value: $object
+=item Return Value: a L<DBIx::Class::Row> $object
 
 =back
 
@@ -2078,10 +2078,10 @@
       $position++;
     }
     my ($b_key) = ( ref $b_element eq 'HASH' ) ? keys %{$b_element} : ($b_element);
+
     if ($best_candidate->{score} == 0 || exists $seen_keys->{$b_key}) {
       push( @{$a}, $b_element );
     } else {
-      $seen_keys->{$b_key} = 1; # don't merge the same key twice
       my $a_best = $a->[$best_candidate->{position}];
       # merge a_best and b_element together and replace original with merged
       if (ref $a_best ne 'HASH') {
@@ -2091,6 +2091,7 @@
         $a->[$best_candidate->{position}] = { $key => $self->_merge_attr($a_best->{$key}, $b_element->{$key}) };
       }
     }
+    $seen_keys->{$b_key} = 1; # don't merge the same key twice
   }
 
   return $a;
@@ -2203,7 +2204,7 @@
 =over 4
 
 Indicates additional columns to be selected from storage.  Works the same as
-L<select> but adds columns to the selection.
+L</select> but adds columns to the selection.
 
 =back
 
@@ -2211,7 +2212,7 @@
 
 =over 4
 
-Indicates additional column names for those added via L<+select>.
+Indicates additional column names for those added via L</+select>.
 
 =back
 
@@ -2333,6 +2334,7 @@
 below.
 
 For more help on using joins with search, see L<DBIx::Class::Manual::Joining>.
+
 =head2 prefetch
 
 =over 4

Modified: DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/ResultSource.pm
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/ResultSource.pm	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/ResultSource.pm	2007-11-24 21:27:52 UTC (rev 3890)
@@ -640,7 +640,7 @@
     my $otherrel_info = $othertable->relationship_info($otherrel);
 
     my $back = $othertable->related_source($otherrel);
-    next unless $back->name eq $self->name;
+    next unless $back->source_name eq $self->source_name;
 
     my @othertestconds;
 
@@ -980,7 +980,9 @@
 
 Set the class of the resultset, this is useful if you want to create your
 own resultset methods. Create your own class derived from
-L<DBIx::Class::ResultSet>, and set it here. 
+L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
+this method returns the name of the existing resultset class, if one
+exists.
 
 =head2 resultset_attributes
 

Modified: DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Row.pm
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Row.pm	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Row.pm	2007-11-24 21:27:52 UTC (rev 3890)
@@ -116,7 +116,6 @@
           next;
         }
       }
-      use Data::Dumper;
       $new->throw_exception("No such column $key on $class")
         unless $class->has_column($key);
       $new->store_column($key => $attrs->{$key});          
@@ -532,15 +531,29 @@
   $new->result_source($self->result_source);
   $new->set_columns($changes);
   $new->insert;
+
+  # Its possible we'll have 2 relations to the same Source. We need to make 
+  # sure we don't try to insert the same row twice esle we'll violate unique
+  # constraints
+  my $rels_copied = {};
+
   foreach my $rel ($self->result_source->relationships) {
     my $rel_info = $self->result_source->relationship_info($rel);
-    if ($rel_info->{attrs}{cascade_copy}) {
-      my $resolved = $self->result_source->resolve_condition(
-       $rel_info->{cond}, $rel, $new);
-      foreach my $related ($self->search_related($rel)) {
-        $related->copy($resolved);
-      }
+
+    next unless $rel_info->{attrs}{cascade_copy};
+  
+    my $resolved = $self->result_source->resolve_condition(
+      $rel_info->{cond}, $rel, $new
+    );
+
+    my $copied = $rels_copied->{ $rel_info->{source} } ||= {};
+    foreach my $related ($self->search_related($rel)) {
+      my $id_str = join("\0", $related->id);
+      next if $copied->{$id_str};
+      $copied->{$id_str} = 1;
+      my $rel_copy = $related->copy($resolved);
     }
+ 
   }
   return $new;
 }

Modified: DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Storage/DBI/Replication.pm
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Storage/DBI/Replication.pm	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Storage/DBI/Replication.pm	2007-11-24 21:27:52 UTC (rev 3890)
@@ -131,22 +131,12 @@
     shift->read_source->build_datetime_parser( @_ );
 }
 
-sub limit_dialect {
-    my $self = shift;
-    $self->$_->limit_dialect( @_ ) for( $self->all_sources );
-}
-sub quote_char {
-    my $self = shift;
-    $self->$_->quote_char( @_ ) for( $self->all_sources );
-}
-sub name_sep {
-    my $self = shift;
-    $self->$_->quote_char( @_ ) for( $self->all_sources );
-}
-sub disconnect {
-    my $self = shift;
-    $self->$_->disconnect( @_ ) for( $self->all_sources );
-}
+sub limit_dialect { $_->limit_dialect( @_ ) for( shift->all_sources ) }
+sub quote_char { $_->quote_char( @_ ) for( shift->all_sources ) }
+sub name_sep { $_->quote_char( @_ ) for( shift->all_sources ) }
+sub disconnect { $_->disconnect( @_ ) for( shift->all_sources ) }
+sub set_schema { $_->set_schema( @_ ) for( shift->all_sources ) }
+
 sub DESTROY {
     my $self = shift;
 

Modified: DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Storage/Statistics.pm
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Storage/Statistics.pm	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class/Storage/Statistics.pm	2007-11-24 21:27:52 UTC (rev 3890)
@@ -3,6 +3,7 @@
 use warnings;
 
 use base qw/Class::Accessor::Grouped/;
+use IO::File;
 
 __PACKAGE__->mk_group_accessors(simple => qw/callback debugfh/);
 

Modified: DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class.pm
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class.pm	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/lib/DBIx/Class.pm	2007-11-24 21:27:52 UTC (rev 3890)
@@ -24,7 +24,7 @@
 # i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
 # brain damage and presumably various other packaging systems too
 
-$VERSION = '0.08007';
+$VERSION = '0.08008';
 
 sub MODIFY_CODE_ATTRIBUTES {
   my ($class,$code, at attrs) = @_;
@@ -202,6 +202,8 @@
 
 ash: Ash Berlin <ash at cpan.org>
 
+bert: Norbert Csongradi <bert at cpan.org>
+
 blblack: Brandon L. Black <blblack at gmail.com>
 
 bluefeet: Aran Deltac <bluefeet at cpan.org>

Modified: DBIx-Class/0.08/branches/versioned_enhancements/lib/SQL/Translator/Parser/DBIx/Class.pm
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/lib/SQL/Translator/Parser/DBIx/Class.pm	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/lib/SQL/Translator/Parser/DBIx/Class.pm	2007-11-24 21:27:52 UTC (rev 3890)
@@ -65,7 +65,7 @@
     }
 
 
-    foreach my $moniker (@monikers)
+    foreach my $moniker (sort @monikers)
     {
         my $source = $dbixschema->source($moniker);
 
@@ -125,7 +125,7 @@
 
         my %created_FK_rels;
 
-        foreach my $rel (@rels)
+        foreach my $rel (sort @rels)
         {
             my $rel_info = $source->relationship_info($rel);
 
@@ -163,10 +163,10 @@
                 # us to another table.
                 # OR: If is_foreign_key_constraint attr is explicity set (or set to false) on the relation
                 if ( ! exists $created_FK_rels{$rel_table}->{$key_test} &&
-                     ( exists $rel_info->{attrs}{is_foreign_key_constraint} && 
-                       $rel_info->{attrs}{is_foreign_key_constraint} ||
+                     ( exists $rel_info->{attrs}{is_foreign_key_constraint} ?
+                       $rel_info->{attrs}{is_foreign_key_constraint} :
                        !$source->compare_relationship_keys(\@keys, \@primary)
-                     )
+		     )
                    )
                 {
                     $created_FK_rels{$rel_table}->{$key_test} = 1;

Modified: DBIx-Class/0.08/branches/versioned_enhancements/t/73oracle_inflate.t
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/t/73oracle_inflate.t	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/t/73oracle_inflate.t	2007-11-24 21:27:52 UTC (rev 3890)
@@ -54,9 +54,6 @@
 
 # clean up our mess
 END {
-    # Set the metadata back for the last_updated_on column
-    $schema->class('Track')->add_column( 'last_updated_on' => $col_metadata );
-
     if($dbh) {
         $dbh->do("DROP TABLE track");
     }

Modified: DBIx-Class/0.08/branches/versioned_enhancements/t/86sqlt.t
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/t/86sqlt.t	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/t/86sqlt.t	2007-11-24 21:27:52 UTC (rev 3890)
@@ -10,7 +10,7 @@
 
 my $schema = DBICTest->init_schema;
 
-plan tests => 56;
+plan tests => 60;
 
 my $translator = SQL::Translator->new( 
   parser_args => {
@@ -176,6 +176,16 @@
       on_delete => '', on_update => '',
     },
   ],
+  # ForceForeign
+  forceforeign => [
+    {
+      'display' => 'forceforeign->artist',
+      'selftable' => 'forceforeign', 'foreigntable' => 'artist', 
+      'selfcols'  => ['artist'], 'foreigncols' => ['artist_id'], 
+      on_delete => '', on_update => '',
+    },
+  ],
+
 );
 
 my %unique_constraints = (
@@ -222,7 +232,6 @@
 );
 
 my $tschema = $translator->schema();
-
 # Test that the $schema->sqlt_deploy_hook was called okay and that it removed
 # the 'link' table
 ok( !defined($tschema->get_table('link')), "Link table was removed by hook");
@@ -232,6 +241,8 @@
 ok( !defined($constraint), 'nonexistent FOREIGN KEY constraint not found' );
 $constraint = get_constraint('UNIQUE', 'cd', ['artist']);
 ok( !defined($constraint), 'nonexistent UNIQUE constraint not found' );
+$constraint = get_constraint('FOREIGN KEY', 'forceforeign', ['cd'], 'cd', ['cdid']);
+ok( !defined($constraint), 'forced nonexistent FOREIGN KEY constraint not found' );
 
 for my $expected_constraints (keys %fk_constraints) {
   for my $expected_constraint (@{ $fk_constraints{$expected_constraints} }) {

Modified: DBIx-Class/0.08/branches/versioned_enhancements/t/90join_torture.t
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/t/90join_torture.t	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/t/90join_torture.t	2007-11-24 21:27:52 UTC (rev 3890)
@@ -6,7 +6,7 @@
 use DBICTest;
 my $schema = DBICTest->init_schema();
 
-plan tests => 20;
+plan tests => 22;
 
  {
    my $rs = $schema->resultset( 'CD' )->search(
@@ -119,4 +119,10 @@
 
 ok(!$@, "pathological prefetch ok");
 
+my $rs = $schema->resultset("Artist")->search({}, { join => 'twokeys' });
+my $second_search_rs = $rs->search({ 'cds_2.cdid' => '2' }, { join =>
+['cds', 'cds'] });
+is(scalar(@{$second_search_rs->{attrs}->{join}}), 3, 'both joins kept');
+ok($second_search_rs->next, 'query on double joined rel runs okay');
+
 1;

Modified: DBIx-Class/0.08/branches/versioned_enhancements/t/91merge_attr.t
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/t/91merge_attr.t	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/t/91merge_attr.t	2007-11-24 21:27:52 UTC (rev 3890)
@@ -6,7 +6,7 @@
 use DBICTest;
 use Test::More;
 
-plan tests => 14;
+plan tests => 15;
 
 my $schema = DBICTest->init_schema();
 my $rs = $schema->resultset( 'CD' );
@@ -52,6 +52,14 @@
 }
 
 {
+  my $a = [ 'twokeys' ];
+  my $b = [ 'cds', 'cds' ];
+  my $expected = [ 'twokeys', 'cds', 'cds' ];
+  my $result = $rs->_merge_attr($a, $b);
+  is_deeply( $result, $expected );
+}
+
+{
   my $a = [ 'artist', 'cd', { 'artist' => 'manager' } ];
   my $b = 'artist';
   my $expected = [ 'artist', 'cd', { 'artist' => 'manager' } ];

Added: DBIx-Class/0.08/branches/versioned_enhancements/t/lib/DBICTest/Schema/ForceForeign.pm
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/t/lib/DBICTest/Schema/ForceForeign.pm	                        (rev 0)
+++ DBIx-Class/0.08/branches/versioned_enhancements/t/lib/DBICTest/Schema/ForceForeign.pm	2007-11-24 21:27:52 UTC (rev 3890)
@@ -0,0 +1,32 @@
+package # hide from PAUSE
+    DBICTest::Schema::ForceForeign;
+
+use base 'DBIx::Class::Core';
+
+__PACKAGE__->table('forceforeign');
+__PACKAGE__->add_columns(
+  'artist' => { data_type => 'integer' },
+  'cd' => { data_type => 'integer' },
+);
+__PACKAGE__->set_primary_key(qw/artist/);
+
+# Normally this would not appear as a FK constraint
+# since it uses the PK
+__PACKAGE__->might_have(
+			'artist_1', 'DBICTest::Schema::Artist', {
+			    'foreign.artist_id' => 'self.artist',
+			}, {
+			    is_foreign_key_constraint => 1,
+			},
+);
+
+# Normally this would appear as a FK constraint
+__PACKAGE__->might_have(
+			'cd_1', 'DBICTest::Schema::CD', {
+			    'foreign.cdid' => 'self.cd',
+			}, {
+			    is_foreign_key_constraint => 0,
+			},
+);
+
+1;

Modified: DBIx-Class/0.08/branches/versioned_enhancements/t/lib/DBICTest/Schema.pm
===================================================================
--- DBIx-Class/0.08/branches/versioned_enhancements/t/lib/DBICTest/Schema.pm	2007-11-24 21:24:53 UTC (rev 3889)
+++ DBIx-Class/0.08/branches/versioned_enhancements/t/lib/DBICTest/Schema.pm	2007-11-24 21:27:52 UTC (rev 3890)
@@ -36,7 +36,8 @@
   ),
   qw/SelfRefAlias TreeLike TwoKeyTreeLike Event EventTZ NoPrimaryKey/,
   qw/Collection CollectionObject TypedObject/,
-  qw/Owners BooksInLibrary/
+  qw/Owners BooksInLibrary/,
+  qw/ForceForeign/  
 );
 
 sub sqlt_deploy_hook {




More information about the Bast-commits mailing list