[Dbix-class] Strange overwriting of values from db query
Byron Young
Byron.Young at riverbed.com
Tue Jun 30 00:28:32 GMT 2009
kakimoto at tpg.com.au wrote on 2009-06-24:
>
> hi guys,
>
> I have a very weird problem here.
> I make 3 db search calls to a method, _get_entries_from_db and
> store each of the results in different hash slices of
> $lists{'active_list'}, $lists{'expired_list'} and
> $lists{'inactive_list'}.
>
> The weirdness occurs when I notice that the values in the hash
> slices
> change after each run of the method , _get_entries_from_db even if
> I did
> not write to them!
>
The problem is that you're re-using the hashref you pass to _get_entries_from_db, which gets stored in the $user_subscriptions resultset that is returned. Remember DBIC resultsets don't actually run the query until you ask for some data, so if you pass a hashref as the where clause and then subsequently modify that hash, your resultset will be modified.
Example:
package Test;
sub new {
my $class = shift;
my $hashref = shift;
my $self = { data => $hashref };
return bless $self, $class;
}
sub test {
my $self = shift;
print $self->{data}->{a} . "\n";
}
my $hashref = { a => 1 };
my $test_obj = Test->new($hashref);
$test_obj->test();
$hashref->{a} = 2;
$test_obj->test();
This will print
1
2
because you changed the data that the test_obj was referencing. Same thing is happening with your resultsets.
Just pass in some anonymous hashref to your _get_entries_from_db() call, like:
$lists{'active_list'} = $self->_get_entries_from_db($c, { 'active_to' => { '>=', \'NOW()' } });
Byron
> Here's the output
> ===============
>
> [debug] _get_entries_from_db - 7 entries pulled
> [debug] _get_entries_from_db - 7 entries pulled
> [debug] _get_entries_from_db - 68 entries pulled
> [debug] _get_entries_from_db - 68 entries pulled
> [debug] _get_entries_from_db - 4 entries pulled
> [debug] _get_entries_from_db - 4 entries pulled
> [debug] R has 4
> f has 4
> j has 4
> [debug] INACTIVE LIST - inactive List has 4 entries
> [debug] INACTIVE LIST - expired List has 4 entries
> [debug] INACTIVE LIST - Active List has 4 entries
> [debug] Outside, active_list has 4
> [debug] Outside, inactive_list has 4
> [debug] Outside, expired_list has 4
> [debug] Retrieved current user's subscriptions.
> [debug] Rendering template "agents/subscriptions/manage.tt2"
> [info] Request took 0.259641s (3.851/s)
>
>
>
> Here are the codes:
> =============
>
>
> sub _get_entries_from_db
> {
> my ($self, $c, $user_subscriptions_filters) = @_;
>
> my $user_subscriptions =
> $c->model('gozilaDB::UserSubscriptions')->search(
> $user_subscriptions_filters,
> {
> # join with the Subscriptions database table( identified via
> # the accessor/relationship name, subscription. q{join}
> => q{subscription}, q{prefetch} => q{subscription},
> },
> );
>
> $c->log->debug(" _get_entries_from_db - " .
> $user_subscriptions->count. " entries pulled" ); return
> $user_subscriptions;
> }
>
>
>
>
> sub get_user_subscriptions
> {
> my ( $self, $c, $args ) = @_;
>
> my %user_subscriptions_filter = (
> q{user_id} =>
> gozila::Controller::Shared->get_current_active_user($c),
> );
>
> my %extra_clause = (
> q{join} => q{subscription},
> # prefetch data from the subscriptions database table too
> );
>
> if (defined($args->{'id'}))
> {
> $user_subscriptions_filter{'me.id'} = $args->{'id'};
> }
>
> $c->log->debug( " _get_user_subscriptions -> Retrieving with
> args of "
> . Data::Dumper->Dump( [\%user_subscriptions_filter] ) );
>
> my %lists = (); # get active entries
> $user_subscriptions_filter{'active_to'} = { '>=', 'NOW()'};
> $lists{'active_list'} = $self->_get_entries_from_db($c,
> \%user_subscriptions_filter); my $r = $self->_get_entries_from_db($c,
> \%user_subscriptions_filter);
>
> # get expired entries $user_subscriptions_filter{'active_to'} = {
> '<', 'NOW()'}; $lists{'expired_list'} =
> $self->_get_entries_from_db($c, \%user_subscriptions_filter); my $f
> =$self->_get_entries_from_db($c,
> \%user_subscriptions_filter);
>
> # get inactive entries - waiting for activation
> $user_subscriptions_filter{'active_to'} = { '=', undef };
> $lists{'inactive_list'} = $self->_get_entries_from_db($c,
> \%user_subscriptions_filter); my $j =$self->_get_entries_from_db($c,
> \%user_subscriptions_filter);
>
> $c->log->debug("R has ". $r->count . "\n f has ". $f->count
> ."\nj
> has ". $j->count );
> $c->log->debug("INACTIVE LIST - inactive List has " .
> $lists{'inactive_list'}->count . " entries ");
> $c->log->debug("INACTIVE LIST - expired List has " .
> $lists{'expired_list'}->count . " entries ");
> $c->log->debug("INACTIVE LIST - Active List has " .
> $lists{'active_list'}->count . " entries ");
>
> return \%lists;
> }
>
>
>
>
> thank you :)
>
> K. akimoto
>
> _______________________________________________
> List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
> IRC: irc.perl.org#dbix-class
> SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
> Searchable Archive: http://www.grokbase.com/group/dbix-
> class at lists.scsys.co.uk
More information about the DBIx-Class
mailing list