Pass attrs to find from update_or_create (reported by Nathan Kurz)
Daniel Westermann-Clark [Fri, 28 Jul 2006 04:14:05 +0000 (04:14 +0000)]
Changes
lib/DBIx/Class/ResultSet.pm
t/80unique.t
t/lib/DBICTest/Schema.pm
t/lib/DBICTest/Schema/NoPrimaryKey.pm [new file with mode: 0644]
t/lib/sqlite.sql

diff --git a/Changes b/Changes
index ae5087f..33e2775 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,6 +1,8 @@
 Revision history for DBIx::Class
 
 0.07001
+        - pass $attrs to find from update_or_create so a specific key can be
+          provided
         - remove anonymous blesses to avoid major speed hit on Fedora Core 5's
           Perl and possibly others; for more information see:
           https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=196836
index daf7e03..b9c2948 100644 (file)
@@ -285,6 +285,9 @@ If the C<key> is specified as C<primary>, it searches only on the primary key.
 If no C<key> is specified, it searches on all unique constraints defined on the
 source, including the primary key.
 
+If your table does not have a primary key, you B<must> provide a value for the
+C<key> attribute matching one of the unique constraints on the source.
+
 See also L</find_or_create> and L</update_or_create>. For information on how to
 declare unique constraints, see
 L<DBIx::Class::ResultSource/add_unique_constraint>.
@@ -300,7 +303,7 @@ sub find {
     ? $self->result_source->unique_constraint_columns($attrs->{key})
     : $self->result_source->primary_columns;
   $self->throw_exception(
-    "Can't find unless a primary key or unique constraint is defined"
+    "Can't find unless a primary key is defined or unique constraint is specified"
   ) unless @cols;
 
   # Parse out a hashref from input
@@ -1341,7 +1344,7 @@ sub update_or_create {
   my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
   my $cond = ref $_[0] eq 'HASH' ? shift : {@_};
 
-  my $row = $self->find($cond);
+  my $row = $self->find($cond, $attrs);
   if (defined $row) {
     $row->update($cond);
     return $row;
index 9c03fc4..7d4dd08 100644 (file)
@@ -7,7 +7,7 @@ use DBICTest;
 
 my $schema = DBICTest->init_schema();
 
-plan tests => 39;
+plan tests => 43;
 
 # Check the defined unique constraints
 is_deeply(
@@ -151,3 +151,17 @@ my $track = $schema->resultset('Track')->find(
 
 is($track->get_column('cd'), 1, 'track cd is correct');
 is($track->get_column('position'), 3, 'track position is correct');
+
+# Test a table with a unique constraint but no primary key
+my $row = $schema->resultset('NoPrimaryKey')->update_or_create(
+  {
+    foo => 1,
+    bar => 2,
+    baz => 3,
+  },
+  { key => 'foo_bar' }
+);
+is(! $row->is_changed, 1, 'update_or_create on table without primary key: row is clean');
+is($row->foo, 1, 'foo is correct');
+is($row->bar, 2, 'bar is correct');
+is($row->baz, 3, 'baz is correct');
index 7c265dc..8e7597d 100644 (file)
@@ -33,7 +33,7 @@ __PACKAGE__->load_classes(qw/
     'Producer',
     'CD_to_Producer',
   ),
-  qw/SelfRefAlias TreeLike TwoKeyTreeLike Event/
+  qw/SelfRefAlias TreeLike TwoKeyTreeLike Event NoPrimaryKey/
 );
 
 1;
diff --git a/t/lib/DBICTest/Schema/NoPrimaryKey.pm b/t/lib/DBICTest/Schema/NoPrimaryKey.pm
new file mode 100644 (file)
index 0000000..1723390
--- /dev/null
@@ -0,0 +1,15 @@
+package # hide from PAUSE 
+    DBICTest::Schema::NoPrimaryKey;
+
+use base 'DBIx::Class::Core';
+
+DBICTest::Schema::NoPrimaryKey->table('noprimarykey');
+DBICTest::Schema::NoPrimaryKey->add_columns(
+  'foo' => { data_type => 'integer' },
+  'bar' => { data_type => 'integer' },
+  'baz' => { data_type => 'integer' },
+);
+
+DBICTest::Schema::NoPrimaryKey->add_unique_constraint(foo_bar => [ qw/foo bar/ ]);
+
+1;
index db76e3b..fd50c36 100644 (file)
@@ -164,6 +164,15 @@ CREATE TABLE twokeys (
 );
 
 --
+-- Table: noprimarykey
+--
+CREATE TABLE noprimarykey (
+  foo integer NOT NULL,
+  bar integer NOT NULL,
+  baz integer NOT NULL
+);
+
+--
 -- Table: fourkeys
 --
 CREATE TABLE fourkeys (
@@ -205,5 +214,6 @@ CREATE UNIQUE INDEX tktlnameunique_twokeytreelike on twokeytreelike (name);
 CREATE UNIQUE INDEX cd_artist_title_cd on cd (artist, title);
 CREATE UNIQUE INDEX track_cd_position_track on track (cd, position);
 CREATE UNIQUE INDEX track_cd_title_track on track (cd, title);
+CREATE UNIQUE INDEX foo_bar_noprimarykey on noprimarykey (foo, bar);
 CREATE UNIQUE INDEX prod_name_producer on producer (name);
 COMMIT;