G'day, trying to use InflateColumn::DateTime::Duration with a Pg
database, using the INTERVAL column type; unfortunately the class only
operates on XSD values.
I've hacked around a bit and added DateTime::Format::DBI support, while
falling back to XSD in the case of any errors; please see the attached
patch file. Hope that helps, as a starting point anyway; I'd love to see
support for DB-native duration columns in this class!
Cheers
Brad
Subject: | DBI.patch |
diff -rwupN DBIx-Class-InflateColumn-DateTime-Duration-0.01002/lib/DBIx/Class/InflateColumn/DateTime/Duration.pm DBIx-Class-InflateColumn-DateTime-Duration-0.01002-patched/lib/DBIx/Class/InflateColumn/DateTime/Duration.pm
--- DBIx-Class-InflateColumn-DateTime-Duration-0.01002/lib/DBIx/Class/InflateColumn/DateTime/Duration.pm 2010-08-20 17:14:45.000000000 +0100
+++ DBIx-Class-InflateColumn-DateTime-Duration-0.01002-patched/lib/DBIx/Class/InflateColumn/DateTime/Duration.pm 2012-07-19 18:49:43.000000000 +0100
@@ -39,6 +39,7 @@ our $VERSION = '0.01002';
use base qw(DBIx::Class);
use Try::Tiny;
+use DateTime::Format::DBI;
use DateTime::Format::Duration::XSD;
=head1 METHODS
@@ -63,16 +64,33 @@ sub register_column {
my $duration;
if ($value) {
+
+ # DBI parser; we can fall back to XSD if there isn't
+ # a native one, or the native one doesn't do durations.
+ my $try_XSD = 0;
+ try {
+ my $dbh = $obj->result_source->schema->storage->dbh;
+ my $parser = DateTime::Format::DBI->new($dbh);
+ $duration = $parser->parse_duration($value);
+ }
+ catch {
+ warn "Error parsing with DBI $_";
+ $try_XSD = 1;
+ };
+ if ($try_XSD) {
my $parser = DateTime::Format::Duration::XSD->new;
try {
$duration = $parser->parse_duration($value);
}
catch {
- $self->throw_exception('Could not parse duration from ' . $value);
+ $self->throw_exception(
+ 'Could not parse duration from ' . $value );
}
}
+ }
+
return $duration;
},
deflate => sub {
@@ -80,9 +98,32 @@ sub register_column {
return unless (ref $value eq 'DateTime::Duration');
+ my $duration;
+
+ # DBI parser; we can fall back to XSD if there isn't
+ # a usable native one.
+ my $try_XSD = 0;
+ try {
+ my $dbh = $obj->result_source->schema->storage->dbh;
+ my $parser = DateTime::Format::DBI->new($dbh);
+ $duration = $parser->format_duration($value);
+ }
+ catch {
+ warn "Error parsing with DBI $_";
+ $try_XSD = 1;
+ };
+ if ($try_XSD) {
my $parser = DateTime::Format::Duration::XSD->new;
- return $parser->format_duration($value);
+ try {
+ $duration = $parser->format_duration($value);
+ }
+ catch {
+ $self->throw_exception(
+ 'Could not format duration for ' . $value );
+ }
+ }
+ return $duration;
},
}
);
@@ -91,6 +132,7 @@ sub register_column {
=head1 SEE ALSO
L<DateTime::Duration>,
+L<DateTime::Format::DBI>,
L<DBIx::Class::InflateColumn>,
L<DBIx::Class>.
diff -rwupN DBIx-Class-InflateColumn-DateTime-Duration-0.01002/Makefile.PL DBIx-Class-InflateColumn-DateTime-Duration-0.01002-patched/Makefile.PL
--- DBIx-Class-InflateColumn-DateTime-Duration-0.01002/Makefile.PL 2010-08-20 17:14:19.000000000 +0100
+++ DBIx-Class-InflateColumn-DateTime-Duration-0.01002-patched/Makefile.PL 2012-07-19 18:13:47.000000000 +0100
@@ -8,6 +8,7 @@ perl_version '5.008001';
all_from 'lib/DBIx/Class/InflateColumn/DateTime/Duration.pm';
requires 'DBIx::Class' => '0.07005';
+requires 'DateTime::Format::DBI';
requires 'DateTime::Format::Duration::XSD' => '0.01';
requires 'Try::Tiny' => '0.04';