cab66da990b7dc8d6bba95b810ea944eb27948d2
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Informix.pm
1 package DBIx::Class::Storage::DBI::Informix;
2 use strict;
3 use warnings;
4
5 use base qw/DBIx::Class::Storage::DBI/;
6 use mro 'c3';
7
8 use Scope::Guard ();
9 use Context::Preserve 'preserve_context';
10 use namespace::clean;
11
12 __PACKAGE__->sql_limit_dialect ('SkipFirst');
13 __PACKAGE__->sql_quote_char ('"');
14 __PACKAGE__->datetime_parser_type (
15   'DBIx::Class::Storage::DBI::Informix::DateTime::Format'
16 );
17
18
19 __PACKAGE__->mk_group_accessors('simple' => '__last_insert_id');
20
21 =head1 NAME
22
23 DBIx::Class::Storage::DBI::Informix - Base Storage Class for Informix Support
24
25 =head1 DESCRIPTION
26
27 This class implements storage-specific support for the Informix RDBMS
28
29 =head1 METHODS
30
31 =cut
32
33 sub _execute {
34   my $self = shift;
35   my ($rv, $sth, @rest) = $self->next::method(@_);
36
37   $self->__last_insert_id($sth->{ix_sqlerrd}[1])
38     if $self->_perform_autoinc_retrieval;
39
40   return (wantarray ? ($rv, $sth, @rest) : $rv);
41 }
42
43 sub last_insert_id {
44   shift->__last_insert_id;
45 }
46
47 sub _exec_svp_begin {
48     my ($self, $name) = @_;
49
50     $self->_dbh->do("SAVEPOINT $name");
51 }
52
53 # can't release savepoints
54 sub _exec_svp_release { 1 }
55
56 sub _exec_svp_rollback {
57     my ($self, $name) = @_;
58
59     $self->_dbh->do("ROLLBACK TO SAVEPOINT $name")
60 }
61
62 sub with_deferred_fk_checks {
63   my ($self, $sub) = @_;
64
65   my $txn_scope_guard = $self->txn_scope_guard;
66
67   $self->_do_query('SET CONSTRAINTS ALL DEFERRED');
68
69   return preserve_context {
70     my $inner_self = $self; # avoid nested closure leak on 5.8
71     my $sg = Scope::Guard->new(sub {
72       $inner_self->_do_query('SET CONSTRAINTS ALL IMMEDIATE');
73     });
74     $sub->()
75   } after => sub { $txn_scope_guard->commit };
76 }
77
78 =head2 connect_call_datetime_setup
79
80 Used as:
81
82   on_connect_call => 'datetime_setup'
83
84 In L<connect_info|DBIx::Class::Storage::DBI/connect_info> to set the C<DATE> and
85 C<DATETIME> formats.
86
87 Sets the following environment variables:
88
89     GL_DATE="%m/%d/%Y"
90     GL_DATETIME="%Y-%m-%d %H:%M:%S%F5"
91
92 The C<DBDATE> and C<DBCENTURY> environment variables are cleared.
93
94 B<NOTE:> setting the C<GL_DATE> environment variable seems to have no effect
95 after the process has started, so the default format is used. The C<GL_DATETIME>
96 setting does take effect however.
97
98 The C<DATETIME> data type supports up to 5 digits after the decimal point for
99 second precision, depending on how you have declared your column. The full
100 possible precision is used.
101
102 The column declaration for a C<DATETIME> with maximum precision is:
103
104   column_name DATETIME YEAR TO FRACTION(5)
105
106 The C<DATE> data type stores the date portion only, and it B<MUST> be declared
107 with:
108
109   data_type => 'date'
110
111 in your Result class.
112
113 You will need the L<DateTime::Format::Strptime> module for inflation to work.
114
115 =cut
116
117 sub connect_call_datetime_setup {
118   my $self = shift;
119
120   delete @ENV{qw/DBDATE DBCENTURY/};
121
122   $ENV{GL_DATE}     = "%m/%d/%Y";
123   $ENV{GL_DATETIME} = "%Y-%m-%d %H:%M:%S%F5";
124 }
125
126 package # hide from PAUSE
127   DBIx::Class::Storage::DBI::Informix::DateTime::Format;
128
129 my $timestamp_format = '%Y-%m-%d %H:%M:%S.%5N'; # %F %T
130 my $date_format      = '%m/%d/%Y';
131
132 my ($timestamp_parser, $date_parser);
133
134 sub parse_datetime {
135   shift;
136   require DateTime::Format::Strptime;
137   $timestamp_parser ||= DateTime::Format::Strptime->new(
138     pattern  => $timestamp_format,
139     on_error => 'croak',
140   );
141   return $timestamp_parser->parse_datetime(shift);
142 }
143
144 sub format_datetime {
145   shift;
146   require DateTime::Format::Strptime;
147   $timestamp_parser ||= DateTime::Format::Strptime->new(
148     pattern  => $timestamp_format,
149     on_error => 'croak',
150   );
151   return $timestamp_parser->format_datetime(shift);
152 }
153
154 sub parse_date {
155   shift;
156   require DateTime::Format::Strptime;
157   $date_parser ||= DateTime::Format::Strptime->new(
158     pattern  => $date_format,
159     on_error => 'croak',
160   );
161   return $date_parser->parse_datetime(shift);
162 }
163
164 sub format_date {
165   shift;
166   require DateTime::Format::Strptime;
167   $date_parser ||= DateTime::Format::Strptime->new(
168     pattern  => $date_format,
169     on_error => 'croak',
170   );
171   return $date_parser->format_datetime(shift);
172 }
173
174 =head1 FURTHER QUESTIONS?
175
176 Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
177
178 =head1 COPYRIGHT AND LICENSE
179
180 This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
181 by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
182 redistribute it and/or modify it under the same terms as the
183 L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
184
185 =cut
186
187 1;
188