Factor SQL-standard deferred FK checks into a component
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Informix.pm
index c08cb9a..79996d3 100644 (file)
@@ -2,19 +2,39 @@ package DBIx::Class::Storage::DBI::Informix;
 use strict;
 use warnings;
 
-use base qw/DBIx::Class::Storage::DBI/;
-
+use base qw/DBIx::Class::Storage::DBI::SetConstraintsDeferred/;
 use mro 'c3';
 
+use namespace::clean;
+
+__PACKAGE__->sql_limit_dialect ('SkipFirst');
+__PACKAGE__->sql_quote_char ('"');
+__PACKAGE__->datetime_parser_type (
+  'DBIx::Class::Storage::DBI::Informix::DateTime::Format'
+);
+
+
 __PACKAGE__->mk_group_accessors('simple' => '__last_insert_id');
 
+=head1 NAME
+
+DBIx::Class::Storage::DBI::Informix - Base Storage Class for Informix Support
+
+=head1 DESCRIPTION
+
+This class implements storage-specific support for the Informix RDBMS
+
+=head1 METHODS
+
+=cut
+
 sub _execute {
   my $self = shift;
-  my ($op) = @_;
   my ($rv, $sth, @rest) = $self->next::method(@_);
-  if ($op eq 'insert') {
-    $self->__last_insert_id($sth->{ix_sqlerrd}[1]);
-  }
+
+  $self->__last_insert_id($sth->{ix_sqlerrd}[1])
+    if $self->_perform_autoinc_retrieval;
+
   return (wantarray ? ($rv, $sth, @rest) : $rv);
 }
 
@@ -22,36 +42,129 @@ sub last_insert_id {
   shift->__last_insert_id;
 }
 
-sub _sql_maker_opts {
-  my ( $self, $opts ) = @_;
+sub _exec_svp_begin {
+    my ($self, $name) = @_;
+
+    $self->_dbh->do("SAVEPOINT $name");
+}
+
+# can't release savepoints
+sub _exec_svp_release { 1 }
 
-  if ( $opts ) {
-    $self->{_sql_maker_opts} = { %$opts };
-  }
+sub _exec_svp_rollback {
+    my ($self, $name) = @_;
 
-  return { limit_dialect => 'SkipFirst', %{$self->{_sql_maker_opts}||{}} };
+    $self->_dbh->do("ROLLBACK TO SAVEPOINT $name")
 }
 
-1;
+=head2 connect_call_datetime_setup
 
-__END__
+Used as:
 
-=head1 NAME
+  on_connect_call => 'datetime_setup'
 
-DBIx::Class::Storage::DBI::Informix - Base Storage Class for INFORMIX Support
+In L<connect_info|DBIx::Class::Storage::DBI/connect_info> to set the C<DATE> and
+C<DATETIME> formats.
 
-=head1 SYNOPSIS
+Sets the following environment variables:
 
-=head1 DESCRIPTION
+    GL_DATE="%m/%d/%Y"
+    GL_DATETIME="%Y-%m-%d %H:%M:%S%F5"
+
+The C<DBDATE> and C<DBCENTURY> environment variables are cleared.
+
+B<NOTE:> setting the C<GL_DATE> environment variable seems to have no effect
+after the process has started, so the default format is used. The C<GL_DATETIME>
+setting does take effect however.
+
+The C<DATETIME> data type supports up to 5 digits after the decimal point for
+second precision, depending on how you have declared your column. The full
+possible precision is used.
+
+The column declaration for a C<DATETIME> with maximum precision is:
 
-This class implements storage-specific support for Informix
+  column_name DATETIME YEAR TO FRACTION(5)
 
-=head1 AUTHORS
+The C<DATE> data type stores the date portion only, and it B<MUST> be declared
+with:
 
-See L<DBIx::Class/CONTRIBUTORS>
+  data_type => 'date'
 
-=head1 LICENSE
+in your Result class.
 
-You may distribute this code under the same terms as Perl itself.
+You will need the L<DateTime::Format::Strptime> module for inflation to work.
 
 =cut
+
+sub connect_call_datetime_setup {
+  my $self = shift;
+
+  delete @ENV{qw/DBDATE DBCENTURY/};
+
+  $ENV{GL_DATE}     = "%m/%d/%Y";
+  $ENV{GL_DATETIME} = "%Y-%m-%d %H:%M:%S%F5";
+}
+
+package # hide from PAUSE
+  DBIx::Class::Storage::DBI::Informix::DateTime::Format;
+
+my $timestamp_format = '%Y-%m-%d %H:%M:%S.%5N'; # %F %T
+my $date_format      = '%m/%d/%Y';
+
+my ($timestamp_parser, $date_parser);
+
+sub parse_datetime {
+  shift;
+  require DateTime::Format::Strptime;
+  $timestamp_parser ||= DateTime::Format::Strptime->new(
+    pattern  => $timestamp_format,
+    on_error => 'croak',
+  );
+  return $timestamp_parser->parse_datetime(shift);
+}
+
+sub format_datetime {
+  shift;
+  require DateTime::Format::Strptime;
+  $timestamp_parser ||= DateTime::Format::Strptime->new(
+    pattern  => $timestamp_format,
+    on_error => 'croak',
+  );
+  return $timestamp_parser->format_datetime(shift);
+}
+
+sub parse_date {
+  shift;
+  require DateTime::Format::Strptime;
+  $date_parser ||= DateTime::Format::Strptime->new(
+    pattern  => $date_format,
+    on_error => 'croak',
+  );
+  return $date_parser->parse_datetime(shift);
+}
+
+sub format_date {
+  shift;
+  require DateTime::Format::Strptime;
+  $date_parser ||= DateTime::Format::Strptime->new(
+    pattern  => $date_format,
+    on_error => 'croak',
+  );
+  return $date_parser->format_datetime(shift);
+}
+
+=head1 FURTHER QUESTIONS?
+
+Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
+
+=head1 COPYRIGHT AND LICENSE
+
+This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
+by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
+redistribute it and/or modify it under the same terms as the
+L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
+
+=cut
+
+1;
+