From: Rafael Kitover Date: Fri, 5 Feb 2010 08:55:43 +0000 (+0000) Subject: fix up my Row code for non-pk autoincs, add pretty crappy DT inflation for Firebird X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9cd0b325352c34448af2630f6cfdf3ada060bfba;p=dbsrgits%2FDBIx-Class-Historic.git fix up my Row code for non-pk autoincs, add pretty crappy DT inflation for Firebird --- diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index d270e7f..d02def9 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -352,19 +352,17 @@ sub insert { # get non-PK auto-incs { + my $rsrc = $self->result_source; my %pk; - @pk{ $self->primary_columns } = (); + @pk{ $rsrc->primary_columns } = (); my @non_pk_autoincs = grep { (not exists $pk{$_}) - && $self->column_info($_)->{is_auto_increment} - } $self->columns; + && $rsrc->column_info($_)->{is_auto_increment} + } $rsrc->columns; if (@non_pk_autoincs) { - my @ids = $self->result_source->storage->last_insert_id( - $self->result_source, - @non_pk_autoincs - ); + my @ids = $rsrc->storage->last_insert_id($rsrc, @non_pk_autoincs); if (@ids == @non_pk_autoincs) { $self->store_column($non_pk_autoincs[$_] => $ids[$_]) for 0 .. $#ids; diff --git a/lib/DBIx/Class/Storage/DBI/InterBase.pm b/lib/DBIx/Class/Storage/DBI/InterBase.pm index 5b9ead7..a5f04e6 100644 --- a/lib/DBIx/Class/Storage/DBI/InterBase.pm +++ b/lib/DBIx/Class/Storage/DBI/InterBase.pm @@ -56,7 +56,7 @@ sub _execute { my ($rv, $sth, @bind) = $self->dbh_do($self->can('_dbh_execute'), @_); - if ($op eq 'insert') { + if ($op eq 'insert' && $self->_fb_auto_incs) { local $@; my (@auto_incs) = eval { local $SIG{__WARN__} = sub {}; @@ -94,4 +94,29 @@ sub _sql_maker_opts { return { limit_dialect => 'FirstSkip', %{$self->{_sql_maker_opts}||{}} }; } +sub datetime_parser_type { __PACKAGE__ } + +my ($parser, $formatter); + +sub parse_datetime { + shift; + require DateTime::Format::Strptime; + $parser ||= DateTime::Format::Strptime->new( + pattern => '%a %d %b %Y %r', +# there should be a %Z (TZ) on the end, but it's ambiguous and not parsed + on_error => 'croak', + ); + $parser->parse_datetime(shift); +} + +sub format_datetime { + shift; + require DateTime::Format::Strptime; + $formatter ||= DateTime::Format::Strptime->new( + pattern => '%F %H:%M:%S.%4N', + on_error => 'croak', + ); + $formatter->format_datetime(shift); +} + 1; diff --git a/lib/DBIx/Class/Storage/DBI/ODBC/Firebird.pm b/lib/DBIx/Class/Storage/DBI/ODBC/Firebird.pm index fd13a3b..de1388c 100644 --- a/lib/DBIx/Class/Storage/DBI/ODBC/Firebird.pm +++ b/lib/DBIx/Class/Storage/DBI/ODBC/Firebird.pm @@ -22,6 +22,20 @@ sub _quote_column_for_returning { return $_[1]; } +sub datetime_parser_type { __PACKAGE__ } + +my $parser; + +sub parse_datetime { + shift; + require DateTime::Format::Strptime; + $parser ||= DateTime::Format::Strptime->new( + pattern => '%F %H:%M:%S', + on_error => 'croak', + ); + $parser->parse_datetime(shift); +} + 1; =head1 AUTHOR diff --git a/t/inflate/datetime_firebird.t b/t/inflate/datetime_firebird.t new file mode 100644 index 0000000..9212f37 --- /dev/null +++ b/t/inflate/datetime_firebird.t @@ -0,0 +1,80 @@ +use strict; +use warnings; + +use Test::More; +use Test::Exception; +use lib qw(t/lib); +use DBICTest; +use Scope::Guard (); + +# XXX we're only testing TIMESTAMP here + +my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_FIREBIRD_${_}" } qw/DSN USER PASS/}; +my ($dsn2, $user2, $pass2) = @ENV{map { "DBICTEST_FIREBIRD_ODBC_${_}" } qw/DSN USER PASS/}; + +if (not ($dsn || $dsn2)) { + plan skip_all => <<'EOF'; +Set $ENV{DBICTEST_FIREBIRD_DSN} and/or $ENV{DBICTEST_FIREBIRD_ODBC_DSN} +_USER and _PASS to run this test'. +Warning: This test drops and creates a table called 'event'"; +EOF +} else { + eval "use DateTime; use DateTime::Format::Strptime;"; + if ($@) { + plan skip_all => 'needs DateTime and DateTime::Format::Strptime for testing'; + } +} + +my @info = ( + [ $dsn, $user, $pass ], + [ $dsn2, $user2, $pass2 ], +); + +my $schema; + +foreach my $info (@info) { + my ($dsn, $user, $pass) = @$info; + + next unless $dsn; + + $schema = DBICTest::Schema->clone; + + $schema->connection($dsn, $user, $pass, { + on_connect_call => [ 'datetime_setup' ], + }); + + my $sg = Scope::Guard->new(\&cleanup); + + eval { $schema->storage->dbh->do("DROP TABLE event") }; + $schema->storage->dbh->do(<<"SQL"); + CREATE TABLE event ( + id INT PRIMARY KEY, + created_on TIMESTAMP + ) +SQL + my $now = DateTime->now; + my $row; + ok( $row = $schema->resultset('Event')->create({ + id => 1, + created_on => $now, + })); + ok( $row = $schema->resultset('Event') + ->search({ id => 1 }, { select => ['created_on'] }) + ->first + ); + is( $row->created_on, $now, 'DateTime roundtrip' ); +} + +done_testing; + +# clean up our mess +sub cleanup { + my $dbh; + eval { + $schema->storage->disconnect; # to avoid object FOO is in use errors + $dbh = $schema->storage->dbh; + }; + return unless $dbh; + + eval { $dbh->do("DROP TABLE $_") } for qw/event/; +}