From: Daniel Westermann-Clark Date: Sun, 28 May 2006 01:30:16 +0000 (+0000) Subject: Add automatic naming of unique constraints X-Git-Tag: v0.07002~75^2~158 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=368a5228b107faaef1af5d09b0a25ea8bb603421;hp=176149441955d3c4319cfa2f8e0c2b07551d2761 Add automatic naming of unique constraints --- diff --git a/Changes b/Changes index cd9962b..a5dd688 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,6 @@ Revision history for DBIx::Class + - add automatic naming of unique constraints - marked DB.pm as deprecated and noted it will be removed by 1.0 - add ResultSetColumn - refactor ResultSet code to resolve attrs as late as poss diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index cc0d1ef..1c23b4c 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -262,7 +262,7 @@ a row by its primary key: You can also find a row by a specific unique constraint using the C attribute. For example: - my $cd = $schema->resultset('CD')->find('Massive Attack', 'Mezzanine', { key => 'artist_title' }); + my $cd = $schema->resultset('CD')->find('Massive Attack', 'Mezzanine', { key => 'cd_artist_title' }); Additionally, you can specify the columns explicitly by name: @@ -271,7 +271,7 @@ Additionally, you can specify the columns explicitly by name: artist => 'Massive Attack', title => 'Mezzanine', }, - { key => 'artist_title' } + { key => 'cd_artist_title' } ); If no C is specified and you explicitly name columns, it searches on all @@ -1312,7 +1312,7 @@ constraint. For example: artist => 'Massive Attack', title => 'Mezzanine', }, - { key => 'artist_title' } + { key => 'cd_artist_title' } ); See also L and L. For information on how to declare @@ -1355,7 +1355,7 @@ For example: title => 'Mezzanine', year => 1998, }, - { key => 'artist_title' } + { key => 'cd_artist_title' } ); If no C is specified, it searches on all unique constraints defined on the diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index eb58dd5..a5da754 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -292,13 +292,24 @@ constraint. constraint_name => [ qw/column1 column2/ ], ); +Alternatively, you can specify only the columns: + + __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]); + +This will result in a unique constraint named C, where +C is replaced with the table name. + Unique constraints are used, for example, when you call L. Only columns in the constraint are searched. =cut sub add_unique_constraint { - my ($self, $name, $cols) = @_; + my $self = shift; + my $cols = pop @_; + my $name = shift; + + $name ||= $self->name_unique_constraint($cols); foreach my $col (@$cols) { $self->throw_exception("No such column $col on table " . $self->name) @@ -310,6 +321,22 @@ sub add_unique_constraint { $self->_unique_constraints(\%unique_constraints); } +=head2 + +Return a name for a unique constraint containing the specified columns. These +names consist of the table name and each column name, separated by underscores. + +For example, a constraint on a table named C containing the columns +C and C would result in a constraint name of C<cd_artist_title>. + +=cut + +sub name_unique_constraint { + my ($self, $cols) = @_; + + return join '_', $self->name, @$cols; +} + =head2 unique_constraints Read-only accessor which returns the list of unique constraints on this source. diff --git a/t/80unique.t b/t/80unique.t index 30767d2..6540333 100644 --- a/t/80unique.t +++ b/t/80unique.t @@ -7,7 +7,10 @@ use DBICTest; my $schema = DBICTest->init_schema(); -plan tests => 34; +plan tests => 36; + +is_deeply([ sort $schema->source('CD')->unique_constraint_names ], [ qw/cd_artist_title primary/ ], 'CD source has an automatically named unique constraint'); +is_deeply([ sort $schema->source('Producer')->unique_constraint_names ], [ qw/primary prod_name/ ], 'Producer source has a named unique constraint'); my $artistid = 1; my $title = 'UNIQUE Constraint'; @@ -23,14 +26,14 @@ my $cd2 = $schema->resultset('CD')->find( artist => $artistid, title => $title, }, - { key => 'artist_title' } + { key => 'cd_artist_title' } ); is($cd2->get_column('artist'), $cd1->get_column('artist'), 'find by specific key: artist is correct'); is($cd2->title, $cd1->title, 'title is correct'); is($cd2->year, $cd1->year, 'year is correct'); -my $cd3 = $schema->resultset('CD')->find($artistid, $title, { key => 'artist_title' }); +my $cd3 = $schema->resultset('CD')->find($artistid, $title, { key => 'cd_artist_title' }); is($cd3->get_column('artist'), $cd1->get_column('artist'), 'find by specific key, ordered columns: artist is correct'); is($cd3->title, $cd1->title, 'title is correct'); @@ -56,7 +59,7 @@ my $cd5 = $schema->resultset('CD')->update_or_create( title => $title, year => 2007, }, - { key => 'artist_title' } + { key => 'cd_artist_title' } ); ok(! $cd5->is_changed, 'update_or_create by specific key: row is clean'); @@ -87,7 +90,7 @@ my $cd7 = $schema->resultset('CD')->find_or_create( title => $title, year => 2010, }, - { key => 'artist_title' } + { key => 'cd_artist_title' } ); is($cd7->cdid, $cd1->cdid, 'find_or_create by specific key: cdid is correct'); @@ -102,7 +105,7 @@ my $cd8 = $artist->find_or_create_related('cds', title => $title, year => 2020, }, - { key => 'artist_title' } + { key => 'cd_artist_title' } ); is($cd8->cdid, $cd1->cdid, 'find_or_create related by specific key: cdid is correct'); @@ -116,7 +119,7 @@ my $cd9 = $artist->update_or_create_related('cds', title => $title, year => 2021, }, - { key => 'artist_title' } + { key => 'cd_artist_title' } ); ok(! $cd9->is_changed, 'update_or_create by specific key: row is clean'); diff --git a/t/86sqlt.t b/t/86sqlt.t index d01a630..1b80e21 100644 --- a/t/86sqlt.t +++ b/t/86sqlt.t @@ -12,7 +12,7 @@ plan skip_all => 'SQL::Translator required' if $@; my $schema = 'DBICTest::Schema'; -plan tests => 31; +plan tests => 33; my $translator = SQL::Translator->new( parser_args => { @@ -95,6 +95,9 @@ my @unique_constraints = ( {'display' => 'cd artist and title unique', 'table' => 'cd', 'cols' => ['artist', 'title'], 'needed' => 1}, + {'display' => 'producer name unique', + 'table' => 'producer', 'cols' => ['name'], + 'needed' => 1}, {'display' => 'twokeytreelike name unique', 'table' => 'twokeytreelike', 'cols' => ['name'], 'needed' => 1}, diff --git a/t/lib/DBICTest/Schema/CD.pm b/t/lib/DBICTest/Schema/CD.pm index 262d23f..7ba727c 100644 --- a/t/lib/DBICTest/Schema/CD.pm +++ b/t/lib/DBICTest/Schema/CD.pm @@ -22,7 +22,7 @@ __PACKAGE__->add_columns( }, ); __PACKAGE__->set_primary_key('cdid'); -__PACKAGE__->add_unique_constraint(artist_title => [ qw/artist title/ ]); +__PACKAGE__->add_unique_constraint([ qw/artist title/ ]); __PACKAGE__->belongs_to( artist => 'DBICTest::Schema::Artist' ); diff --git a/t/lib/DBICTest/Schema/Producer.pm b/t/lib/DBICTest/Schema/Producer.pm index 36b63a1..036f9f2 100644 --- a/t/lib/DBICTest/Schema/Producer.pm +++ b/t/lib/DBICTest/Schema/Producer.pm @@ -15,5 +15,6 @@ __PACKAGE__->add_columns( }, ); __PACKAGE__->set_primary_key('producerid'); +__PACKAGE__->add_unique_constraint(prod_name => [ qw/name/ ]); 1; diff --git a/t/lib/sqlite.sql b/t/lib/sqlite.sql index b067ee9..d7fa393 100644 --- a/t/lib/sqlite.sql +++ b/t/lib/sqlite.sql @@ -1,6 +1,6 @@ -- -- Created by SQL::Translator::Producer::SQLite --- Created on Tue May 23 21:10:54 2006 +-- Created on Sat May 27 21:28:05 2006 -- BEGIN TRANSACTION; @@ -186,5 +186,6 @@ CREATE TABLE producer ( ); CREATE UNIQUE INDEX tktlnameunique_twokeytreelike on twokeytreelike (name); -CREATE UNIQUE INDEX artist_title_cd on cd (artist, title); +CREATE UNIQUE INDEX cd_artist_title_cd on cd (artist, title); +CREATE UNIQUE INDEX prod_name_producer on producer (name); COMMIT;