[CDBI] Help tracking down a problem w/ has_a and unexpected deflating.

George Hartzell hartzell at kestrel.alerce.com
Mon Aug 29 00:30:23 BST 2005


I'm building a Mason based web app on FreeBSD 6-ish using perl 5.8.6
and a whole passel of cpan-standard stuff (details if they're
interesting).  I'm using SQLite to store my data and Class::DBI to
manipulate it.  I'm using Class::DBI version 0.96 built via FreeBSD's
ports system but see similar results with a copy of 0.999.

I'm using DateTime to play with dates, and as I was getting started I
just stuff them into SQLite STRING columns via DateTime->now().

I've been actually working on the date/time stuff now, and have
switched over to storing seconds since the epoch in the DB tables
(via DateTime->now->epoch()) and have been trying to use Class::DBI's
has_a and inflate to convert the from the epoch's to DateTime's.
Here's my Project.pm class (with a couple of useless functions
elided).

    package DNASeqr::DB::Project;
    use strict;
    use warnings;
    
    use base qw(DNASeqr::DB::DBI);
    our $VERSION = 0.01;
    
    __PACKAGE__->table('project');
    __PACKAGE__->columns(All => qw/project_id/);
    __PACKAGE__->columns(Essential => qw/name
    				     seq_request
    				     started_on
    				     ended_on
    				     comment
    				     /);
    
    __PACKAGE__->has_a(seq_request => 'DNASeqr::DB::SeqRequest');
    __PACKAGE__->has_a(started_on  => 'DateTime',
    		   inflate => sub {DateTime->from_epoch(epoch => shift);});
    __PACKAGE__->has_a(ended_on  => 'DateTime',
    		   inflate => sub {DateTime->from_epoch(epoch => shift);});
    __PACKAGE__->has_many(samples => 'DNASeqr::DB::Sample');
    __PACKAGE__->has_many(primers => 'DNASeqr::DB::Primer');
    __PACKAGE__->has_many(oligo_orders => 'DNASeqr::DB::OligoOrder');
    
    # some unrelated subs were deleted here....
    
    1; #this line is important and will help the module return a true value
    __DATA__
    
    CREATE TABLE project (
    	project_id	INTEGER PRIMARY KEY,
            seq_request     INTEGER REFERENCES seq_request(seq_request_id),
    	name		STRING,
    	started_on	STRING,
    	ended_on	STRING,
    	comment 	STRING
    );	

I think that it works as I'd expect, although I saw one instance of
my particular problem, but I'd been single stepping through the
Class::DBI code and may have fubar'ed something myself.

I cut and pasted the has_a line into my other date using classes, and
it seems to work for everything except one class.  In particular, if I
look at the database via the sqlite command, the date columns have
values that are nice looking integers, and converting from them into
a DateTime and printing them out yields reasonable results.

One class, OligoOrder.pm, included here has a problem.
    
    package DNASeqr::DB::OligoOrder;
    use strict;
    use warnings;
    
    use base qw(DNASeqr::DB::DBI);
    
    use Bio::Seq;
    use Bio::SeqFeature::Generic;
    
    our $VERSION = 0.01;
    
    __PACKAGE__->table('oligo_order');
    __PACKAGE__->columns(All => qw/order_id/);
    # by calling *all* of the columns essential, we avoid the lazy loading stuff.
    __PACKAGE__->columns(Essential => qw/project
    				     name
    				     seq
    				     ordered_on
    				     /);
    __PACKAGE__->has_a(project => 'DNASeqr::DB::Project');
    __PACKAGE__->has_a(ordered_on  => 'DateTime',
     		   inflate => sub {DateTime->from_epoch(epoch => shift);});
    
    
    1; #this line is important and will help the module return a true value
    __DATA__
    CREATE TABLE oligo_order (
          order_id         INTEGER PRIMARY KEY,
          project          INTEGER REFERENCES project(project_id),
          name             STRING,
          seq              STRING,
          ordered_on       STRING
    );
    
Values in the ordered_on column end up looking like
'2005-08-28T23:19:17' (which is DateTime's default stringification).

I've stepped down into the Class::DBI code and it seems that
OligoOrder.pm has a deflator that's being called that does the
conversion, but I can't figure out why it's happening.  The scalar
holding the value is a nice clean integer all of the way down.  More
confusingly, why is it happening here, but not in my other classes
(having cut and paste the same has_a lines and then touched up the
column names?)

Worse yet, it seems to be a heisenbug, for a couple of moments (while
running in the debugger) I've seen reasonable values in the OligoOrder
table and I've seen one bad value in the Project table (also whilst
poking in the debugger.

I've tried changing the column type to INTEGER (which it will
ultimately be), but it doesn't seem to fix anything.  The date columns
are still STRINGs in the other tables, so I'm leaving it that way for
the moment until I figure this out.

If I remove the has_a for the ordered_on column, then the values
stored in the db are appropriately valued integers.

I'm at a loss as to where to look next, I don't understand how to
figure out why I'm getting the deflator....

Any help, suggestions, and/or pointers would be welcome. 

g.




More information about the ClassDBI mailing list