[CDBI] accessor return cached value even after _attribute_delete and delete self->changed

Ying-Chi yi at stern.nyu.edu
Wed Jun 20 06:37:22 BST 2007


Hi all,

I apologize if this issue has been asked before. I've searched through 
the mailing lists and rt bug track, and the closest related issue I've 
found was #21199. I've not had another set of eyes on this problem, so 
if I'm false-alarming b/c a bug in my own code, please let me know, thanks!

Basically, I had to perform an update using set_sql. Right after the 
update I needed to get the updated value from the database. So I called 
_attribute_delete on the column, and delete $self->{__Changed} so on the 
next accessor call, the value would be retrieved from the database.

When I called the accessor, I would get the cached value of the updated 
column, and not the value stored in the database after the update. Is 
this suppose to happen? Pouring through the docs I suspect that this 
behavior is not by design.

Here's the test case:
#------start code
mysql> Insert into tblAccountDefaults set DefaultName=uidNumber, 
DefaultValue=500; (i'm using mysql - this is the only row in the table)


package AcctDefaults;
use base 'Class::DBI';
__PACKAGE__->set_db('Main','dbi:mysql:icarus:localhost','', '');
__PACKAGE__->table('tblAccountDefaults');
__PACKAGE__->columns(Primary => 'DefaultId');
__PACKAGE__->columns(Essential => qw/DefaultName DefaultValue/);
__PACKAGE__->set_sql('next_uidNumber' => qq/
    UPDATE __TABLE__
    SET    DefaultValue=DefaultValue+1
    WHERE  __IDENTIFIER__
/);

sub next_uidNumber {
    my $self = shift;

    return unless ref($self);
    my $sth = $self->sql_next_uidNumber;
    $sth->execute($self->id);
    $self->_attribute_delete(qw/DefaultValue/);
    delete $self->{__Changed};
    return $self->DefaultValue;
}

1;

# now my test script
#!/usr/bin/perl

use Test::More qw(no_plan);

my $itr = AcctDefaults->search(
   DefaultName => 'uidNumber',
);

my $defaults_obj = $itr->next;
my $uid_before_update = $defaults_obj->DefaultValue;
my $next_uid = $defaults_obj->next_uidNumber;

is ($next_uid, 501, "returned uid matches the math, 500 + 1"); #<-- not 
ok, got 500, expected 501
is ($next_uid, $uid_before_update, "returned uid matches the uid before 
updating");  #<-- test ok, as returned value was not touched, and 
matches the old one.

# To confirm the value in db is 501 using CDBI, you had to first remove 
it from object_index, then call search again so you get a completely 
unique object.
$defaults_obj->remove_from_object_index();

my $itr2 = AcctDefaults->search(
   DefaultName => 'uidNumber',
);

my $defaults_obj2 = $itr2->next;
is ($defaults_obj2->DefaultValue, 501, "Second search confirms uidNumber 
in db is 501") #<--- test ok

#------end code

I suspect it is due to CDBI's default prepared_cache behavior. The 
object index doesn't help either as all subsequent retrieves or searches 
will lead you back to the same object, unless you call 
remove_from_object_index. Please let me know what is wrong.

Any insight? Is this by design? Or am I just not seeing the faults in my 
logic?
Thanks,

Connie



More information about the ClassDBI mailing list