From: Matt S Trout Date: Sun, 10 Jan 2010 06:48:38 +0000 (+0000) Subject: select by id support X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e49bd8614d0ac18dc8bc7cae5c3a687d3d032077;p=dbsrgits%2FDBIx-Data-Store-old.git select by id support --- diff --git a/lib/DBIx/Data/Collection/Set.pm b/lib/DBIx/Data/Collection/Set.pm index 7e71b8e..ceb1e3f 100644 --- a/lib/DBIx/Data/Collection/Set.pm +++ b/lib/DBIx/Data/Collection/Set.pm @@ -68,20 +68,22 @@ method _key_cache_has_object ($obj) { } method _key_cache_get_raw ($raw) { - my $id = $self->_raw_to_id($raw); - exists $self->_key_cache->{$id} - ? ($self->_key_cache->{$id}) - : () + $self->_key_cache_get_id($self->_raw_to_id($raw)) } method _key_cache_get_object ($obj) { - $self->_key_cache_get_raw($self->_deflate($obj)) + $self->_key_cache_get_id($self->_object_to_id($obj)) } -## loading data +method _key_cache_get_object_spec ($spec) { + # see _object_spec_to_id for doc of what the difference is + $self->_key_cache_get_id($self->_object_spec_to_id($spec)) +} -method _new_raw_stream { - $self->_store->new_select_command([])->execute +method _key_cache_get_id ($id) { + exists $self->_key_cache->{$id} + ? ($self->_key_cache->{$id}) + : () } ## thunking between the store representation and the set representation @@ -90,6 +92,8 @@ method _new_raw_stream { # _deflate is final repr -> raw data # _merge takes final repr + raw data and updates the repr # (this is used for pk-generated values and later lazy loading) +# +# _deflate_spec is attributes of final repr -> raw data method _inflate ($raw) { bless($raw, $self->_class) if $self->_has_class; @@ -105,6 +109,10 @@ method _merge ($obj, $raw) { $obj } +method _deflate_spec ($spec) { + $spec +} + ## methods to get ids method _raw_to_id ($raw) { @@ -116,8 +124,19 @@ method _object_to_id ($obj) { $self->_raw_to_id($self->_deflate($obj)) } +method _object_spec_to_id ($spec) { + # intentionally C&P from _raw_to - this is not the same thing. If a column + # were mapped to an attribute of a different name, the raw would have the + # column name as a key but an object spec would have the attribute name + join ';', map $spec->{$_}, @{$self->_set_over} +} + ## array-ish operations - i.e. get all members +method _new_raw_stream { + $self->_store->new_select_command([])->execute +} + method flatten { @{$self->_member_cache}; } @@ -126,6 +145,22 @@ method as_stream { Data::Perl::Stream::Array->new(array => $self->_member_cache); } +## load single row + +method get ($spec) { + if (my ($got) = $self->_key_cache_get_object_spec($spec)) { + return $got + } + if (my ($raw) = $self->_get_from_store($self->_deflate_spec($spec))) { + return $self->_add_to_key_cache($self->_inflate($raw)) + } + return undef # we aren't handling cache misses here yet +} + +method _get_from_store ($raw) { + $self->_store->new_select_single_command($raw)->execute +} + ## add to set method add ($new) { diff --git a/lib/DBIx/Data/Store/CRUD.pm b/lib/DBIx/Data/Store/CRUD.pm index eff5e58..88bd4ff 100644 --- a/lib/DBIx/Data/Store/CRUD.pm +++ b/lib/DBIx/Data/Store/CRUD.pm @@ -5,7 +5,7 @@ use Method::Signatures::Simple; has raw_store => (is => 'ro', required => 1); # DBIx::Data::Store object -foreach my $type (qw(select insert update delete)) { +foreach my $type (qw(select select_single insert update delete)) { has "${type}_sql" => (is => 'ro', predicate => "has_${type}_sql"); has "${type}_argument_order" => (is => 'ro', default => sub { [] }); } @@ -23,6 +23,15 @@ method new_select_command ($args) { ); } +method new_select_single_command ($args) { + die "$self->has_select_single_sql" unless $self->has_select_single_sql; + $self->raw_store->new_row_command( + $self->select_single_sql, + $self->_unwrap_args_for(select_single => $args), + $self->select_column_order + ); +} + method _unwrap_args_for ($type, $args) { [ @{$args}{@{$self->${\"${type}_argument_order"}}} ] } diff --git a/lib/DBIx/Data/Store/Command/Row.pm b/lib/DBIx/Data/Store/Command/Row.pm index 402b616..53cb4b5 100644 --- a/lib/DBIx/Data/Store/Command/Row.pm +++ b/lib/DBIx/Data/Store/Command/Row.pm @@ -7,7 +7,7 @@ use Method::Signatures::Simple; has 'column_order' => (is => 'ro', required => 1); method execute { - my $result = (my $stream = DBIx::Data::Stream::STH->new( + return unless my ($result) = (my $stream = DBIx::Data::Stream::STH->new( sth => $self->_new_active_sth, column_order => $self->column_order, ))->next; if ($stream->next) { diff --git a/t/01basic_collection.t b/t/01basic_collection.t index 94ccb0f..c987036 100644 --- a/t/01basic_collection.t +++ b/t/01basic_collection.t @@ -120,4 +120,17 @@ my ($fresh_pterry) = grep $_->{name} =~ /Pterry/, $set->flatten; is($fresh_pterry->{name}, 'Sir Pterry', 'Update persisted correctly'); +$set = make_set {}, { + select_single_sql => q{SELECT id, name FROM person WHERE id = ?}, + select_single_argument_order => [ qw(id) ], +}; + +my $pterry_id = (grep $_->{name} eq 'Pterry', @expect)[0]->{id}; + +$pterry = $set->get({ id => $pterry_id }); + +is($pterry->{name}, 'Sir Pterry', 'Pterry retrieved by id'); + +ok(!defined($set->get({ id => -1 })), 'undef on missing id'); + done_testing;