diff --git a/lib/Data/Mapper.pm b/lib/Data/Mapper.pm index c0c6744..f9dc27b 100644 --- a/lib/Data/Mapper.pm +++ b/lib/Data/Mapper.pm @@ -45,16 +45,16 @@ sub search { sub update { my ($self, $data) = @_; my $result; + my $has_changes = $data->isa('Data::Mapper::Data'); - if ($data->is_changed) { - my $params = $self->mapped_params($data); + return if $has_changes && not $data->is_changed; - $result = $self->adapter->update( - $params->{table} => $params->{set} => $params->{where} - ); + my $params = $self->mapped_params($data); + $result = $self->adapter->update( + $params->{table} => $params->{set} => $params->{where} + ); - $data->discard_changes; - } + $data->discard_changes if $has_changes; $result; } @@ -136,9 +136,18 @@ sub mapped_params { die "Data::Mapper doesn't support tables have no primary keys" if !scalar @$primary_keys; - my $result = { set => $data->changes, where => {}, table => $table }; - for my $key (@$primary_keys) { - $result->{where}{$key} = $data->param($key); + my $result = { set => {}, where => {}, table => $table }; + + if ($data->isa('Data::Mapper::Data')) { + $result->{set} = $data->changes; + for my $key (@$primary_keys) { + $result->{where}{$key} = $data->param($key); + } + } else { + $result->{set} = $self->as_serializable($data); # everything + for my $key (@$primary_keys) { + $result->{where}{$key} = $data->{$key}; + } } Carp::croak("where clause is empty") diff --git a/t/lib/Data/Mapper/Data/Popo.pm b/t/lib/Data/Mapper/Data/Popo.pm new file mode 100644 index 0000000..5dbf072 --- /dev/null +++ b/t/lib/Data/Mapper/Data/Popo.pm @@ -0,0 +1,10 @@ +package t::lib::Data::Mapper::Data::Popo; +use strict; +use warnings; + +sub new { + my ($class, $data) = @_; + bless $data, $class; +} + +!!1; diff --git a/t/mapper-popo.t b/t/mapper-popo.t new file mode 100644 index 0000000..ccf9d7a --- /dev/null +++ b/t/mapper-popo.t @@ -0,0 +1,93 @@ +use t::lib::Utils; +use Test::Requires qw(DBI DBD::SQLite); + +use Test::More; +use Test::Fatal; + +use t::lib::Data::Mapper; +use Data::Mapper::Adapter::DBI; + +my $dbh = t::lib::Utils::dbh; + $dbh->do('create table popo (id integer primary key, value text)'); + +my $adapter = Data::Mapper::Adapter::DBI->new({ driver => $dbh }); +my $mapper = t::lib::Data::Mapper->new({ adapter => $adapter }); + +subtest 'create' => sub { + my $data = $mapper->create(popo => { value => 'test create' }); + + ok $data; + isa_ok $data, 't::lib::Data::Mapper::Data::Popo'; + is_deeply $data, +{ + id => 1, + value => 'test create', + }; +}; + +subtest 'find' => sub { + my $created = $mapper->create(popo => { value => 'test find' }); + my $found = $mapper->find(popo => { id => $created->{id} }); + + ok $found; + isa_ok $found, 't::lib::Data::Mapper::Data::Popo'; + is_deeply $created, $found; + + note 'when not found'; + my $ret = $mapper->find(popo => { id => 'not found key' }); + ok !$ret; +}; + +subtest 'search' => sub { + my $created1 = $mapper->create(popo => { value => 'test search' }); + my $created2 = $mapper->create(popo => { value => 'test search' }); + my $result = $mapper->search(popo => { + value => 'test search' + }, { + order_by => 'id desc' + }); + + ok $result; + is ref $result, 'ARRAY'; + is scalar @$result, 2; + + for my $record (@$result) { + isa_ok $record, 't::lib::Data::Mapper::Data::Popo'; + } + + is_deeply $result, [$created2, $created1]; +}; + +subtest 'update' => sub { + my $data = $mapper->create(popo => { value => 'test update' }); + + is $data->{value}, 'test update'; + $data->{value} = 'test updated'; + + my $ret = $mapper->update($data); + + ok $ret; + isa_ok $ret, 'DBI::st'; + is $ret->rows, 1; + + my $updated = $mapper->find(popo => { id => $data->{id} }); + + ok $updated; + is $updated->{value}, 'test updated'; +}; + +subtest 'delete' => sub { + my $data = $mapper->create(popo => { value => 'test delete' }); + + ok $data; + + my $ret = $mapper->delete($data); + + ok $ret; + isa_ok $ret, 'DBI::st'; + is $ret->rows, 1; + + my $deleted = $mapper->find(popo => { id => $data->{id} }); + ok !$deleted; +}; + +done_testing;