[CDBI] Trouble deflating a Time::Piece with Class::DBI v3.0.14

Ron Savage ron at savage.net.au
Mon Mar 27 02:02:53 BST 2006

Class::DBI v3.0.14
Database: Oracle

I create the table with:

create table evaluation
id $primary_key, # Syntax dependent on db vendor.
campus_id integer not null references campus (id),
q_type_id integer not null references q_type (id),
unit_id integer not null references unit (id),
batch_number varchar(8) not null,
note varchar(255) not null,
student_count integer not null,
timestamp timestamp not null

My table's class module uses:

__PACKAGE__ -> table('evaluation');
__PACKAGE__ -> columns(All => qw/
__PACKAGE__ -> has_a(campus_id => 'X::Campus');
__PACKAGE__ -> has_a
	timestamp	=> 'Time::Piece',
	inflate		=> sub{Time::Piece -> strptime(shift, '%Y-%m-%d %H:%M:%S')},
__PACKAGE__ -> has_a(campus_id => 'X::Campus');
__PACKAGE__ -> has_a(q_type_id => 'X::QType');
__PACKAGE__ -> has_a(unit_id => 'X::Unit');
__PACKAGE__	-> sequence('evaluation_id_seq') if ($^O eq 'linux');

The problem is when trying to write an object to the database.

If I pass into Class::DBI's insert a hashref where the value for the timestamp
column is a string, eg: 2006-03-28 12:00:00, the value is discarded and the
column is populated with the current date/time, presumably by calling now().
(I'll swear this used to work, before 'upgrading').

So I tried to follow the Class::DBI docs on this, which say:
  Music::CD->has_a(reldate => 'Time::Piece',
    inflate => sub { Time::Piece->strptime(shift, "%Y-%m-%d") },
    deflate => 'ymd',
  print $cd->reldate->strftime("%d %b, %Y");
If the foreign class is another Class::DBI representation retrieve is called on
that class with the column value. Any other object will be instantiated either
by calling new($value) or using the given 'inflate' method. If the inflate
method name is a subref, it will be executed, and will be passed the value and
the Class::DBI object as arguments.

When the object is being written to the database the object will be deflated
either by calling the 'deflate' method (if given), or by attempting to stringify
the object. If the deflate method is a subref, it will be passed the Class::DBI
object as an argument.


The line
deflate => 'ymd',
suggests to me the method ymd() will be called on the Time::Piece object being
stored, so I passed in a Time::Piece, constructed by, say, this conversion
(string to object):
	$evaluation_data{'timestamp'}		= Time::Piece ->
strptime($evaluation_data{'timestamp'}, '%Y-%m-%d %H:%M:%S');
and the Time::Piece docs give these (under Usage):
    $t->strftime(FORMAT)    # same as POSIX::strftime (without the overhead
                            # of the full POSIX extension)
    $t->strftime()          # "Tue, 29 Feb 2000 12:34:56 GMT"
 so I tried a deflate line of:
	deflate		=> "strftime('%Y-%m-%d %H:%M:%S)",
Yes, I know this is all very indirect.
I get this error:
Can't locate object method ")" via package "strftime('%Y-%m-%d %H:%M:%S"
(perhaps you forgot to load "strftime('%Y-%m-%d %H:%M:%S"?)

What to do?


The last part of the Class::DBI docs (i.e. 'When the object is being
written...') I take to mean this:
o 'The object' refers to the object for the 'current' column, of type
Time::Piece, not for the 'current' row, despite the end of final sentence saying
'will be passed the Class::DBI object', right?


The part which says "by calling the 'deflate' method (if given)" refers to the
column object having a deflate method, right?

Ron Savage
ron at savage.net.au

More information about the ClassDBI mailing list