[Dbix-class] unique constrains are ignored when using find_or_create

Daniel Westermann-Clark daniel at acceleration.net
Wed Apr 5 06:21:54 CEST 2006


On 2006-04-04 22:26:28 +0200, Goetz Bock wrote:
> as discussed on irc, I've some problems with unique_contrains beeing
> "ignored" when using find_or_create.

Yes, my apologies.  I implemented the unique constraints.  When you
mentioned this I was getting another project out the door.  (Anybody
want a Catalyst- and DBIC-based voting system?  I'm trying to get
$work to open source it, but we'll see.)

> This is the test case:
> 
> ------------------------------------------------------------------------
> my $cd = $schema->resultset('CD')->find_or_create( 
>     {
>         'artist' => 1, 
>         'title'  => "Spoonful of bees", 
>         'year'   => 2000,
>     },
>     {
>         'key' => 'artist_title',
>     }
> );
> 
> print "The CD is from " . $cd->year . " should be from 1999.\n";
> ------------------------------------------------------------------------
> 
> IMHO it sould find the existing CD from 1999, like update_or_create
> does.

Thanks for the test case.  This is indeed a bug.  I've worked up an
initial patch (see attached) to fix this, but looking at it again I
wonder if find should simply be reorganized to work more like
update_or_create.

> The problem here is there is no update_or_create_related(), at last
> not in the docs.

No, it does not exist currently.  I think for now you can do something
like:

my $artist = $schema->resultset('Artist')->find(1);
my $cd = $artist->search_related('cds')->update_or_create(...);

but a wrapper should probably be added.  Someone correct me if I'm
wrong, as I'm not terribly familiar with the Relationship convenience
methods.

-- 
Daniel Westermann-Clark
-------------- next part --------------
Patching locally against mirror source http://dev.catalyst.perl.org/repos/bast.
==== Patch <-> level 1
Source: [No source]
Target: bd8105ee-0ff8-0310-8827-fb3f25b6796d:/trunk/DBIx-Class:1414
        (http://dev.catalyst.perl.org/repos/bast)
Log:
Constrain query to columns on unique constraint when a key is specified
=== Changes
==================================================================
--- Changes	(revision 1414)
+++ Changes	(patch - level 1)
@@ -2,15 +2,16 @@
 
 0.06001
         - Added fix for quoting with single table
+        - Fix subtle issue with ResultSet::find() on a specific key
 
-0.06000
+0.06000 2006-03-25 11:35:00
         - Lots of documentation improvements
         - Minor tweak to related_resultset to prevent it storing a searched rs
         - Fixup to columns_info_for when database returns type(size)
         - Made do_txn respect void context (on the off-chance somebody cares)
         - Fix exception text for nonexistent key in ResultSet::find()
 
-0.05999_04
+0.05999_04 2006-03-18 13:35:00
         - Fix for delete on full-table resultsets
         - Removed caching on count() and added _count for pager()
         - ->connection does nothing if ->storage defined and no args
=== lib/DBIx/Class/ResultSet.pm
==================================================================
--- lib/DBIx/Class/ResultSet.pm	(revision 1414)
+++ lib/DBIx/Class/ResultSet.pm	(patch - level 1)
@@ -310,6 +310,9 @@
   my $query;
   if (ref $vals[0] eq 'HASH') {
     $query = { %{$vals[0]} };
+    if (exists $attrs->{key}) {
+      $query = { map { $_ => $vals[0]->{$_} } grep { exists $vals[0]->{$_} } @cols };
+    }
   } elsif (@cols == @vals) {
     $query = {};
     @{$query}{@cols} = @vals;
@@ -320,7 +323,7 @@
     $query->{"$self->{attrs}{alias}.$key"} = delete $query->{$key};
   }
   #warn Dumper($query);
-  
+
   if (keys %$attrs) {
       my $rs = $self->search($query,$attrs);
       return keys %{$rs->{collapse}} ? $rs->next : $rs->single;
=== t/run/20unique.tl
==================================================================
--- t/run/20unique.tl	(revision 1414)
+++ t/run/20unique.tl	(patch - level 1)
@@ -1,7 +1,7 @@
 sub run_tests {
 my $schema = shift;
 
-plan tests => 18;
+plan tests => 26;
 
 my $artistid = 1;
 my $title    = 'UNIQUE Constraint';
@@ -69,6 +69,35 @@
 is($cd5->title, $cd2->title, 'title is correct');
 is($cd5->year, 2005, 'updated year is correct');
 
+my $cd6 = $schema->resultset('CD')->find_or_create(
+  {
+    artist => $artistid,
+    title  => $title,
+    year   => 2010,
+  },
+  { key => 'artist_title' }
+);
+
+is($cd6->cdid, $cd1->cdid, 'find or create by specific key: cdid is correct');
+is($cd6->get_column('artist'), $cd1->get_column('artist'), 'artist is correct');
+is($cd6->title, $cd1->title, 'title is correct');
+is($cd6->year, $cd1->year, 'year is correct');
+
+my $artist = $schema->resultset('Artist')->find($artistid);
+my $cd7 = $artist->find_or_create_related('cds',
+  {
+    artist => $artistid,
+    title  => $title,
+    year   => 2020,
+  },
+  { key => 'artist_title' }
+);
+
+is($cd7->cdid, $cd1->cdid, 'find or create related by specific key: cdid is correct');
+is($cd7->get_column('artist'), $cd1->get_column('artist'), 'artist is correct');
+is($cd7->title, $cd1->title, 'title is correct');
+is($cd7->year, $cd1->year, 'year is correct');
+
 }
 
 1;

==== BEGIN SVK PATCH BLOCK ====
Version: svk 1.07 (linux)

eJytVk9v3EQU31MPy6FCQhwqDnNw2Y1UJzO2xx5v1NVC2koICSGacgCKNR7PZK167a09m2YVrxSC
BLdyQXwQEN+gIMFX4Uswf7yrJGwbIjWHzXjee7958/u9eTOP6sP9CWrHY9g6CLaPv/x0NPqcSja9
q76csOVZLqvawW3Bj3nh+G1RHTlBW9IZV1ZJ6yMux2OkgokNfmgC1iCBxkiprMrGiQ1YImvOHdTG
E7XAxGsnvoptkbJWc14mdVVJhU98FCljonNiRdXwRMdOgnaCtbu3dhd5wZ2oPZjS8og3BqgLNn6+
gwLrmOU1Zyqxpd5Cnv7HM9riiVp50c/X6eAunYteSG8DWyudz4tlIvmJzHghqcnV99osRVmMIPPC
IMMCRzxk0EeIpkEapgGN1eqa/M96vb/u/H3rdt37pnf2be+cpT/3/njy/UPQ/bngUX4CmkUqCw7y
pllw8CKXU/AFbxaFfMzlaCTyMhvugKoEFDRzznKRM/CML/t9uAtDCCHwIAxd6LseBgiNfDzazCAC
kK9nIFRUXyDf0NxthXsCBTEjPA39GPtYIBGKMMYRQYJEKbNkKO9gC6VEk7/34ONPTow61zHrb8Dw
Nn2CDdreQUGbxix6HWawwQwvVZEXXUHb27C6O5+ZFK6Dxm8shFCz50MsWOCFUYwEhzEJoUdTTGAg
0ozEqSpMjGwhnP/6wflv77+77L162jtb9s5vvfqq990/oz9TAHIBhvwkb2QDHCpl3bjjUyXxagec
9m2hOM8XvF6C++AUzOhc/ToJuD8GzjEtmq/hU+XvJCuwAkc119Y12FXzhFVFA1b7BnW1tSbMrpif
+YwERASpIB5HfgBZKAQhEY4FEXBDOdkiI27lXr0ozSG8juFogxRfEg9FFmTPg4syV5vflYVZ7jpA
8kbJYr252OdKJAqJQL7wqR8TH2cxT3mkTkIkVOvCkZXsp9u/vPfOjx/+3nt5iM9+eH7n5UIdVaDS
UqCa39P+bAmchk35jCptmmku5H6/Py9oCayH0sgLtRPLQuXR+brj2pRiw+VwcPBgsOOO9TFPqjph
NaeSD5VAVnpaSyWl0doO8+yeMchc9wxjMEM7u+S0BmbWgwjquZX+OdUdQ88OLEhiQgZg1d9R+ebN
UOfnjlmm0HWuaD0e6LxAVQObF0iXl5rQCGg31bkAq2otwkDhbeDUVZKoglvMymG37mBnDb/d1g1f
B2g32iF0HwNLxGsiNB/rADseGIouuxsZ10xvFemjLkUr1HCjhQq26kY60M5eFTOpeaH+ZcMBy5rB
vbchrXczaaP/I22X5Q0kjt62xNGNJY62Sry1sZmzj8IwYCnFkccQIhiGOEhZBsMIhykjKTbvgwi1
B+qBI2ual8A2XlkBu5VG38S2JamZzkmCF1OuL2gthUqz449nCs4dj73W8Tz7mjo0D6zR6EmZH/O6
ocXdsFU9bU7lVD1kan6sPhaLPNMNcE+qTvPMXGCuvQ6DFgUocHz1BMsIgphzF6qurK56BF1CvMgV
qS88nKrrKMz+Bc40K/g=
==== END SVK PATCH BLOCK ====


More information about the Dbix-class mailing list