diff options
author | matthewt <matthewt@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7> | 2007-09-12 18:11:34 +0000 |
---|---|---|
committer | matthewt <matthewt@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7> | 2007-09-12 18:11:34 +0000 |
commit | 7adfd53f17f66ffe93763e944ed1d3fc52a369dc (patch) | |
tree | 19e599e74419b41cbbe651fd226b81e8b73551d3 /lib/Reaction/InterfaceModel/Action/DBIC/Role/CheckUniques.pm | |
parent | c728c97cb1061330e63c7cc048e768ef74988fe6 (diff) | |
download | reaction-7adfd53f17f66ffe93763e944ed1d3fc52a369dc.tar.gz reaction-7adfd53f17f66ffe93763e944ed1d3fc52a369dc.zip |
moved shit to trunk
Diffstat (limited to 'lib/Reaction/InterfaceModel/Action/DBIC/Role/CheckUniques.pm')
-rw-r--r-- | lib/Reaction/InterfaceModel/Action/DBIC/Role/CheckUniques.pm | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/lib/Reaction/InterfaceModel/Action/DBIC/Role/CheckUniques.pm b/lib/Reaction/InterfaceModel/Action/DBIC/Role/CheckUniques.pm new file mode 100644 index 0000000..e4756fd --- /dev/null +++ b/lib/Reaction/InterfaceModel/Action/DBIC/Role/CheckUniques.pm @@ -0,0 +1,114 @@ +package Reaction::InterfaceModel::Action::DBIC::Role::CheckUniques; + +use Reaction::Role; + +role CheckUniques which { + + # requires qw(target_model + # parameter_hashref + # parameter_attributes + # ); + + has _unique_constraint_results => + ( + isa => 'HashRef', + is => 'rw', + required => 1, + default => sub { {} }, + metaclass => 'Reaction::Meta::Attribute' + ); + + implements check_all_uniques => as { + my ($self) = @_; + my $source = $self->target_model->result_source; + my %uniques = $source->unique_constraints; + my $proto = ($self->target_model->isa('DBIx::Class::ResultSet') + ? $self->target_model->new_result({}) + : $self->target_model); + my $param_hr = $self->parameter_hashref; + my %proto_hash = ( + map { + my @ret; + my $attr = $proto->meta->get_attribute($_->name); + if ($attr) { + my $reader = $attr->get_read_method; + if ($reader) { + my $value = $proto->$reader; + if (defined($value)) { + @ret = ($_->name => $value); + } + } + } + @ret; + } $self->parameter_attributes + ); + my %merged = ( + %proto_hash, + (map { + (defined $param_hr->{$_} ? ($_ => $param_hr->{$_}) : ()); + } keys %$param_hr), + ); + my %ident = %{$proto->ident_condition}; + my %clashes; + my $rs = $source->resultset; + foreach my $unique (keys %uniques) { + my %pass; + my @attrs = @{$uniques{$unique}}; + next if grep { !exists $merged{$_} } @attrs; + # skip PK before insertion if auto-inc etc. etc. + @pass{@attrs} = @merged{@attrs}; + if (my $obj = $rs->find(\%pass, { key => $unique })) { + my $found_ident = $obj->ident_condition; + #warn join(', ', %$found_ident, %ident); + if (!$proto->in_storage + || (grep { $found_ident->{$_} ne $ident{$_} } keys %ident)) { + # if in storage and no ident conditions are different the found + # obj is *us* :) + $clashes{$_} = 1 for @attrs; + } + } + } + $self->_unique_constraint_results(\%clashes); + }; + + after sync_all => sub { shift->check_all_uniques; }; + + override error_for_attribute => sub { + my ($self, $attr) = @_; + if ($self->_unique_constraint_results->{$attr->name}) { + return "Already taken, please try an alternative"; + } + return super(); + }; + + override can_apply => sub { + my ($self) = @_; + return 0 if keys %{$self->_unique_constraint_results}; + return super(); + }; + +}; + +1; + +=head1 NAME + +Reaction::InterfaceModel::Action::DBIC::Role::CheckUniques + +=head1 DESCRIPTION + +=head2 check_all_uniques + +=head2 error_for_attribute + +=head2 meta + +=head1 AUTHORS + +See L<Reaction::Class> for authors. + +=head1 LICENSE + +See L<Reaction::Class> for the license. + +=cut |