}
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
# _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;
$obj
}
+method _deflate_spec ($spec) {
+ $spec
+}
+
## methods to get ids
method _raw_to_id ($raw) {
$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};
}
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) {
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 { [] });
}
);
}
+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"}}} ]
}
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;