Subject: | Tangram/Lazy/BackRef patch |
Date: | Fri, 09 Feb 2007 03:18:08 +0200 |
To: | via RT <bug-Tangram [...] rt.cpan.org> |
From: | Assen Tchorbadjiev <pt [...] tchorbadjiev.com> |
Hello,
attached is a patch against the current head sources.
The current implementation inside Lazy/BackRef does always a select on
the referenced object, w/o considering whether it has been already loaded.
There was a commented line in the code (direct storage->load), that
didn't worked because the oid was not fully constructed. What I did is
to re-use the storage->class_id && storage->combine_ids calls and then
attempt to load the object. If not loaded, it will fallback to the
regular select call.
I've extended the t/musicstore/01-simple.t a bit, and added a test on
the CD -> Artist backref connection, and it seems to behave well.
(also inside the 01-simple.t.patch is a minor duplicate 'my' declaration
fix).
Regards,
Assen
diff --git a/t/musicstore/01-simple.t b/t/musicstore/01-simple.t
index d38085d..ca00ecf 100644
--- a/t/musicstore/01-simple.t
+++ b/t/musicstore/01-simple.t
@@ -7,7 +7,7 @@ use lib "t/musicstore";
use Prerequisites;
use strict;
-use Test::More tests => 25;
+use Test::More tests => 26;
use Tangram::Storage;
# various items that will "persist" between test blocks
@@ -137,7 +137,7 @@ is($CD::c, 0, "no objects leaked");
my ($count) = $storage->count($filter);
is($count, 3, "Can do simple COUNT() queries - compat");
- my ($count) = $storage->count($r_cd, $filter);
+ ($count) = $storage->count($r_cd, $filter);
is($count, 3, "Can do simple COUNT() queries - proper");
# maybe some other aggregation type queries:
@@ -222,10 +222,21 @@ is($CD::c, 0, "no objects leaked");
is($CD::c, 0, "no objects leaked");
{
- # 9. delete some records
+ # 9. try to load CDs via backrefs
+ my (@cds) = $storage->select
+ ($r_cd,
+ $r_cd->{title} eq "The Dark Side of The Moon");
+ my $artist = (shift @cds)->artist;
+ is($artist->name, "Pink Floyd", "retrieved artist via backref");
+}
+
+is($CD::c, 0, "no objects leaked");
+
+{
+ # 10. delete some records
my (@gonners) = $storage->select
- ($r_artist,
- $r_artist->{popularity} eq "one hit wonder");
+ ( $r_artist,
+ $r_artist->{name} eq "Pink Floyd" );
$storage->erase(@gonners);
diff --git a/lib/Tangram/Lazy/BackRef.pm b/lib/Tangram/Lazy/BackRef.pm
index 2075708..287252d 100644
--- a/lib/Tangram/Lazy/BackRef.pm
+++ b/lib/Tangram/Lazy/BackRef.pm
@@ -11,8 +11,18 @@ sub FETCH
my $obj = $storage->{objects}{$id};
my $owner = $storage->remote($class);
- my ($refobj) = $storage->select($owner, $owner->{$field}->includes($obj));
-# my $refobj = $storage->load($refid);
+
+ # try #1 - if already loaded, use it
+ my $cid = $storage->class_id( $class );
+ my $oid = $storage->combine_ids( $refid, $cid );
+
+ my $refobj;
+ $refobj = $storage->load($oid);
+
+ unless ( $refobj ) {
+ # try #2 - fallback to regular select
+ ($refobj) = $storage->select($owner, $owner->{$field}->includes($obj));
+ }
untie $obj->{$member};
$obj->{$member} = $refobj; # weak