[Bast-commits] r8588 - in DBIx-Class/0.08/branches/storage-interbase: lib/DBIx/Class/SQLAHacks lib/DBIx/Class/Storage/DBI lib/DBIx/Class/Storage/DBI/ODBC t t/inflate

caelum at dev.catalyst.perl.org caelum at dev.catalyst.perl.org
Mon Feb 8 13:26:41 GMT 2010


Author: caelum
Date: 2010-02-08 13:26:41 +0000 (Mon, 08 Feb 2010)
New Revision: 8588

Removed:
   DBIx-Class/0.08/branches/storage-interbase/lib/DBIx/Class/SQLAHacks/ODBC/
Modified:
   DBIx-Class/0.08/branches/storage-interbase/lib/DBIx/Class/Storage/DBI/InterBase.pm
   DBIx-Class/0.08/branches/storage-interbase/lib/DBIx/Class/Storage/DBI/ODBC/Firebird.pm
   DBIx-Class/0.08/branches/storage-interbase/t/750firebird.t
   DBIx-Class/0.08/branches/storage-interbase/t/inflate/datetime_firebird.t
Log:
better DT inflation for Firebird and _ping

Modified: DBIx-Class/0.08/branches/storage-interbase/lib/DBIx/Class/Storage/DBI/InterBase.pm
===================================================================
--- DBIx-Class/0.08/branches/storage-interbase/lib/DBIx/Class/Storage/DBI/InterBase.pm	2010-02-08 11:52:33 UTC (rev 8587)
+++ DBIx-Class/0.08/branches/storage-interbase/lib/DBIx/Class/Storage/DBI/InterBase.pm	2010-02-08 13:26:41 UTC (rev 8588)
@@ -24,6 +24,12 @@
 
 For ODBC support, see L<DBIx::Class::Storage::DBI::ODBC::Firebird>.
 
+To turn on L<DBIx::Class::InflateColumn::DateTime> support, add:
+
+    on_connect_call => 'datetime_setup'
+
+to your L<DBIx::Class::Storage::DBI/connect_info>.
+
 =cut
 
 sub _prep_for_execute {
@@ -102,31 +108,81 @@
   return { limit_dialect => 'FirstSkip', %{$self->{_sql_maker_opts}||{}} };
 }
 
-sub datetime_parser_type { __PACKAGE__ }
+sub _svp_begin {
+    my ($self, $name) = @_;
 
-my ($datetime_parser, $datetime_formatter);
+    $self->_get_dbh->do("SAVEPOINT $name");
+}
 
-sub parse_datetime {
-    shift;
-    require DateTime::Format::Strptime;
-    $datetime_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',
-    );
-    $datetime_parser->parse_datetime(shift);
+sub _svp_release {
+    my ($self, $name) = @_;
+
+    $self->_get_dbh->do("RELEASE SAVEPOINT $name");
 }
 
-sub format_datetime {
-    shift;
-    require DateTime::Format::Strptime;
-    $datetime_formatter ||= DateTime::Format::Strptime->new(
-        pattern => '%F %H:%M:%S.%4N',
-        on_error => 'croak',
-    );
-    $datetime_formatter->format_datetime(shift);
+sub _svp_rollback {
+    my ($self, $name) = @_;
+
+    $self->_get_dbh->do("ROLLBACK TO SAVEPOINT $name")
 }
 
+sub _ping {
+  my $self = shift;
+
+  my $dbh = $self->_dbh or return 0;
+
+  local $dbh->{RaiseError} = 1;
+
+  eval {
+    $dbh->do('select 1 from rdb$database');
+  };
+
+  return $@ ? 0 : 1;
+}
+
+=head2 connect_call_datetime_setup
+
+Used as:
+
+  on_connect_call => 'datetime_setup'
+
+In L<DBIx::Class::Storage::DBI/connect_info> to set the date and timestamp
+formats using:
+
+  $dbh->{ib_time_all} = 'ISO';
+
+See L<DBD::InterBase> for more details.
+
+The C<TIMESTAMP> data type supports up to 4 digits after the decimal point for
+second precision. The full precision is used.
+
+You will need the L<DateTime::Format::Strptime> module for inflation to work.
+
+For L<DBIx::Class::Storage::DBI::ODBC::Firebird>, this is a noop and sub-second
+precision is not currently available.
+
+=cut
+
+sub connect_call_datetime_setup {
+  my $self = shift;
+
+  $self->_get_dbh->{ib_time_all} = 'ISO';
+}
+
+
+# from MSSQL
+
+sub build_datetime_parser {
+  my $self = shift;
+  my $type = "DateTime::Format::Strptime";
+  eval "use ${type}";
+  $self->throw_exception("Couldn't load ${type}: $@") if $@;
+  return $type->new(
+    pattern => '%Y-%m-%d %H:%M:%S.%4N', # %F %T
+    on_error => 'croak',
+  );
+}
+
 1;
 
 =head1 CAVEATS
@@ -139,16 +195,6 @@
 work with earlier versions, we'll need to figure out how to retrieve the bodies
 of C<BEFORE INSERT> triggers and parse them for the C<GENERATOR> name.
 
-=item *
-
-C<TIMESTAMP> values are written with precision of 4 numbers after the decimal
-point for seconds, but read with only second precision.
-
-If you know of a session variable we can set to control how timestamps look as
-strings, please let us know (via RT.)
-
-Otherwise we'll need to rewrite the produced SQL for timestamps, at some point.
-
 =back
 
 =head1 AUTHOR

Modified: DBIx-Class/0.08/branches/storage-interbase/lib/DBIx/Class/Storage/DBI/ODBC/Firebird.pm
===================================================================
--- DBIx-Class/0.08/branches/storage-interbase/lib/DBIx/Class/Storage/DBI/ODBC/Firebird.pm	2010-02-08 11:52:33 UTC (rev 8587)
+++ DBIx-Class/0.08/branches/storage-interbase/lib/DBIx/Class/Storage/DBI/ODBC/Firebird.pm	2010-02-08 13:26:41 UTC (rev 8588)
@@ -12,7 +12,7 @@
 
 =head1 SYNOPSIS
 
-All functionality is provided by L<DBIx::Class::Storage::DBI::Interbase>, see
+Most functionality is provided by L<DBIx::Class::Storage::DBI::Interbase>, see
 that module for details.
 
 To build the ODBC driver for Firebird on Linux for unixODBC, see:
@@ -21,24 +21,29 @@
 
 =cut
 
-__PACKAGE__->sql_maker_class('DBIx::Class::SQLAHacks::ODBC::Firebird');
+# XXX seemingly no equivalent to ib_time_all in DBD::InterBase via ODBC
+sub connect_call_datetime_setup { 1 }
 
-sub datetime_parser_type { __PACKAGE__ }
+# from MSSQL
 
-my $datetime_parser;
-
-sub parse_datetime {
-    shift;
-    require DateTime::Format::Strptime;
-    $datetime_parser ||= DateTime::Format::Strptime->new(
-        pattern => '%F %H:%M:%S',
-        on_error => 'croak',
-    );
-    $datetime_parser->parse_datetime(shift);
+sub build_datetime_parser {
+  my $self = shift;
+  my $type = "DateTime::Format::Strptime";
+  eval "use ${type}";
+  $self->throw_exception("Couldn't load ${type}: $@") if $@;
+  return $type->new(
+    pattern => '%Y-%m-%d %H:%M:%S', # %F %T
+    on_error => 'croak',
+  );
 }
 
 1;
 
+=head1 CAVEATS
+
+This driver (unlike L<DBD::InterBase>) does not currently support reading or
+writing C<TIMESTAMP> values with sub-second precision.
+
 =head1 AUTHOR
 
 See L<DBIx::Class/AUTHOR> and L<DBIx::Class/CONTRIBUTORS>.

Modified: DBIx-Class/0.08/branches/storage-interbase/t/750firebird.t
===================================================================
--- DBIx-Class/0.08/branches/storage-interbase/t/750firebird.t	2010-02-08 11:52:33 UTC (rev 8587)
+++ DBIx-Class/0.08/branches/storage-interbase/t/750firebird.t	2010-02-08 13:26:41 UTC (rev 8588)
@@ -29,7 +29,9 @@
 
   next unless $dsn;
 
-  $schema = DBICTest::Schema->connect($dsn, $user, $pass);
+  $schema = DBICTest::Schema->connect($dsn, $user, $pass, {
+    auto_savepoint => 1
+  });
   my $dbh = $schema->storage->dbh;
 
   my $sg = Scope::Guard->new(\&cleanup);
@@ -63,6 +65,24 @@
   my $new = $ars->create({ name => 'foo' });
   ok($new->artistid, "Auto-PK worked");
 
+# test savepoints
+#  eval {
+#    $schema->txn_do(sub {
+#      eval {
+#        $schema->txn_do(sub {
+#          $ars->create({ name => 'in_savepoint' });
+#          die "rolling back savepoint";
+#        });
+#      };
+#      ok ((not $ars->search({ name => 'in_savepoint' })->first),
+#        'savepoint rolled back');
+#      $ars->create({ name => 'in_outer_txn' });
+#      die "rolling back outer txn";
+#    });
+#  };
+#  ok ((not $ars->search({ name => 'in_outer_txn' })->first),
+#    'outer txn rolled back');
+
 # test explicit key spec
   $new = $ars->create ({ name => 'bar', artistid => 66 });
   is($new->artistid, 66, 'Explicit PK worked');

Modified: DBIx-Class/0.08/branches/storage-interbase/t/inflate/datetime_firebird.t
===================================================================
--- DBIx-Class/0.08/branches/storage-interbase/t/inflate/datetime_firebird.t	2010-02-08 11:52:33 UTC (rev 8587)
+++ DBIx-Class/0.08/branches/storage-interbase/t/inflate/datetime_firebird.t	2010-02-08 13:26:41 UTC (rev 8588)
@@ -32,14 +32,12 @@
 
 my $schema;
 
-foreach my $info (@info) {
-  my ($dsn, $user, $pass) = @$info;
+foreach my $conn_idx (0..$#info) {
+  my ($dsn, $user, $pass) = @{ $info[$conn_idx] };
 
   next unless $dsn;
 
-  $schema = DBICTest::Schema->clone;
-
-  $schema->connection($dsn, $user, $pass, {
+  $schema = DBICTest::Schema->connect($dsn, $user, $pass, {
     on_connect_call => [ 'datetime_setup' ],
   });
 
@@ -53,6 +51,7 @@
   )
 SQL
   my $now = DateTime->now;
+  $now->set_nanosecond(555600000);
   my $row;
   ok( $row = $schema->resultset('Event')->create({
         id => 1,
@@ -62,7 +61,12 @@
     ->search({ id => 1 }, { select => ['created_on'] })
     ->first
   );
-  is( $row->created_on, $now, 'DateTime roundtrip' );
+  is $row->created_on, $now, 'DateTime roundtrip';
+
+  if ($conn_idx == 0) { # skip for ODBC
+    cmp_ok $row->created_on->nanosecond, '==', 555600000,
+      'fractional part of a second survived';
+  }
 }
 
 done_testing;




More information about the Bast-commits mailing list