From 158373dcdbf01cb75c9d57eb66305b55c6e092c4 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Tue, 17 Feb 2015 10:10:28 -0500 Subject: [PATCH] Bug 13719 - Make Koha::Objects store list of resultant objects on an as needed basis We can both simplify and improve the functioning of Koha::Objects by removing out reliance on DBIC for set iteration ( first(), next(), reset(), etc ). The problem is that DBIC destroys and refetches results every time reset() is called. For example, take the following code: my $borrowers = Koha::Borrowers->search({ firstname => 'Kyle' }). my $kyle1 = $borrowers->next(); $borrowers->reset(); my $kyle2 = $borrowers->next(); In this case, we would expect $kyle1 and $kyle2 to refer to the exact same object in memory, but they do *not*. This is simply a limitation of DBIx::Class. However, by handling this issue ourselves, we not only solve the problem, but I believe we also reduce the complexity of our code. This is all accomplished without changing the external behavior of the Koha::Objects module. Test Plan: 1) Apply this patch 2) prove t/db_dependent/Borrowers.t --- Koha/Objects.pm | 45 +++++++++++++++++++++++++++++++++++++-------- 1 files changed, 37 insertions(+), 8 deletions(-) diff --git a/Koha/Objects.pm b/Koha/Objects.pm index 6b3100a..701e535 100644 --- a/Koha/Objects.pm +++ b/Koha/Objects.pm @@ -54,6 +54,8 @@ sub new { my ($class) = @_; my $self = {}; + $self->{_iterator} = 0; + bless( $self, $class ); } @@ -67,6 +69,8 @@ sub _new_from_dbic { my ( $class, $resultset ) = @_; my $self = { _resultset => $resultset }; + $self->{_iterator} = 0; + bless( $self, $class ); } @@ -136,14 +140,27 @@ Returns undef if there are no more objects to return. sub next { my ( $self ) = @_; - my $result = $self->_resultset()->next(); - return unless $result; + my $object = $self->_objects()->[ $self->{_iterator}++ ]; - my $object = $self->object_class()->_new_from_dbic( $result ); + $self->reset() unless $object; return $object; } +=head3 Koha::Objects->first(); + +my $object = Koha::Objects->first(); + +Returns the first object that is part of this set. + +=cut + +sub first { + my ( $self ) = @_; + + return $self->_objects()->[0]; +} + =head3 Koha::Objects->reset(); Koha::Objects->reset(); @@ -156,7 +173,7 @@ with the first object in a set. sub reset { my ( $self ) = @_; - $self->_resultset()->reset(); + $self->{_iterator} = 0; return $self; } @@ -172,11 +189,23 @@ Returns an arrayref of the objects in this set. sub as_list { my ( $self ) = @_; - my @dbic_rows = $self->_resultset()->all(); + my $objects = $self->_objects(); + + return wantarray ? @$objects : $objects; +} + +=head3 Koha::Objects->_objects + +Returns an arrayref of all the objects that are part of this Objects set + +=cut + +sub _objects { + my ( $self ) = @_; - my @objects = $self->_wrap(@dbic_rows); + $self->{_objects} ||= $self->_wrap( $self->_resultset()->all() ); - return wantarray ? @objects : \@objects; + return $self->{_objects}; } =head3 Koha::Objects->_wrap @@ -190,7 +219,7 @@ sub _wrap { my @objects = map { $self->object_class()->_new_from_dbic( $_ ) } @dbic_rows; - return @objects; + return wantarray ? @objects : \@objects;; } =head3 Koha::Objects->_resultset -- 1.7.2.5