1 package DBIx::Class::Storage::DBI;
2 # -*- mode: cperl; cperl-indent-level: 2 -*-
4 use base 'DBIx::Class::Storage';
8 use Carp::Clan qw/^DBIx::Class/;
10 use SQL::Abstract::Limit;
11 use DBIx::Class::Storage::DBI::Cursor;
12 use DBIx::Class::Storage::Statistics;
13 use Scalar::Util qw/blessed weaken/;
15 __PACKAGE__->mk_group_accessors('simple' =>
16 qw/_connect_info _dbi_connect_info _dbh _sql_maker _sql_maker_opts
17 _conn_pid _conn_tid transaction_depth _dbh_autocommit savepoints/
20 # the values for these accessors are picked out (and deleted) from
21 # the attribute hashref passed to connect_info
22 my @storage_options = qw/
23 on_connect_do on_disconnect_do disable_sth_caching unsafe auto_savepoint
25 __PACKAGE__->mk_group_accessors('simple' => @storage_options);
28 # default cursor class, overridable in connect_info attributes
29 __PACKAGE__->cursor_class('DBIx::Class::Storage::DBI::Cursor');
31 __PACKAGE__->mk_group_accessors('inherited' => qw/sql_maker_class/);
32 __PACKAGE__->sql_maker_class('DBIC::SQL::Abstract');
36 package # Hide from PAUSE
37 DBIC::SQL::Abstract; # Would merge upstream, but nate doesn't reply :(
39 use base qw/SQL::Abstract::Limit/;
41 # This prevents the caching of $dbh in S::A::L, I believe
43 my $self = shift->SUPER::new(@_);
45 # If limit_dialect is a ref (like a $dbh), go ahead and replace
46 # it with what it resolves to:
47 $self->{limit_dialect} = $self->_find_syntax($self->{limit_dialect})
48 if ref $self->{limit_dialect};
53 # DB2 is the only remaining DB using this. Even though we are not sure if
54 # RowNumberOver is still needed here (should be part of SQLA) leave the
57 my ($self, $sql, $order, $rows, $offset ) = @_;
60 my $last = $rows + $offset;
61 my ( $order_by ) = $self->_order_by( $order );
66 SELECT Q1.*, ROW_NUMBER() OVER( ) AS ROW_NUM FROM (
71 WHERE ROW_NUM BETWEEN $offset AND $last
79 # While we're at it, this should make LIMIT queries more efficient,
80 # without digging into things too deeply
81 use Scalar::Util 'blessed';
83 my ($self, $syntax) = @_;
85 # DB2 is the only remaining DB using this. Even though we are not sure if
86 # RowNumberOver is still needed here (should be part of SQLA) leave the
88 my $dbhname = blessed($syntax) ? $syntax->{Driver}{Name} : $syntax;
89 if(ref($self) && $dbhname && $dbhname eq 'DB2') {
90 return 'RowNumberOver';
93 $self->{_cached_syntax} ||= $self->SUPER::_find_syntax($syntax);
97 my ($self, $table, $fields, $where, $order, @rest) = @_;
98 local $self->{having_bind} = [];
99 local $self->{from_bind} = [];
101 if (ref $table eq 'SCALAR') {
104 elsif (not ref $table) {
105 $table = $self->_quote($table);
107 local $self->{rownum_hack_count} = 1
108 if (defined $rest[0] && $self->{limit_dialect} eq 'RowNum');
109 @rest = (-1) unless defined $rest[0];
110 die "LIMIT 0 Does Not Compute" if $rest[0] == 0;
111 # and anyway, SQL::Abstract::Limit will cause a barf if we don't first
112 my ($sql, @where_bind) = $self->SUPER::select(
113 $table, $self->_recurse_fields($fields), $where, $order, @rest
118 $self->{for} eq 'update' ? ' FOR UPDATE' :
119 $self->{for} eq 'shared' ? ' FOR SHARE' :
124 return wantarray ? ($sql, @{$self->{from_bind}}, @where_bind, @{$self->{having_bind}}) : $sql;
130 $table = $self->_quote($table) unless ref($table);
131 $self->SUPER::insert($table, @_);
137 $table = $self->_quote($table) unless ref($table);
138 $self->SUPER::update($table, @_);
144 $table = $self->_quote($table) unless ref($table);
145 $self->SUPER::delete($table, @_);
151 return $_[1].$self->_order_by($_[2]);
153 return $self->SUPER::_emulate_limit(@_);
157 sub _recurse_fields {
158 my ($self, $fields, $params) = @_;
159 my $ref = ref $fields;
160 return $self->_quote($fields) unless $ref;
161 return $$fields if $ref eq 'SCALAR';
163 if ($ref eq 'ARRAY') {
164 return join(', ', map {
165 $self->_recurse_fields($_)
166 .(exists $self->{rownum_hack_count} && !($params && $params->{no_rownum_hack})
167 ? ' AS col'.$self->{rownum_hack_count}++
170 } elsif ($ref eq 'HASH') {
171 foreach my $func (keys %$fields) {
172 return $self->_sqlcase($func)
173 .'( '.$self->_recurse_fields($fields->{$func}).' )';
176 # Is the second check absolutely necessary?
177 elsif ( $ref eq 'REF' and ref($$fields) eq 'ARRAY' ) {
178 return $self->_bind_to_sql( $fields );
181 Carp::croak($ref . qq{ unexpected in _recurse_fields()})
189 if (ref $_[0] eq 'HASH') {
190 if (defined $_[0]->{group_by}) {
191 $ret = $self->_sqlcase(' group by ')
192 .$self->_recurse_fields($_[0]->{group_by}, { no_rownum_hack => 1 });
194 if (defined $_[0]->{having}) {
196 ($frag, @extra) = $self->_recurse_where($_[0]->{having});
197 push(@{$self->{having_bind}}, @extra);
198 $ret .= $self->_sqlcase(' having ').$frag;
200 if (defined $_[0]->{order_by}) {
201 $ret .= $self->_order_by($_[0]->{order_by});
203 if (grep { $_ =~ /^-(desc|asc)/i } keys %{$_[0]}) {
204 return $self->SUPER::_order_by($_[0]);
206 } elsif (ref $_[0] eq 'SCALAR') {
207 $ret = $self->_sqlcase(' order by ').${ $_[0] };
208 } elsif (ref $_[0] eq 'ARRAY' && @{$_[0]}) {
209 my @order = @{+shift};
210 $ret = $self->_sqlcase(' order by ')
212 my $r = $self->_order_by($_, @_);
213 $r =~ s/^ ?ORDER BY //i;
217 $ret = $self->SUPER::_order_by(@_);
222 sub _order_directions {
223 my ($self, $order) = @_;
224 $order = $order->{order_by} if ref $order eq 'HASH';
225 return $self->SUPER::_order_directions($order);
229 my ($self, $from) = @_;
230 if (ref $from eq 'ARRAY') {
231 return $self->_recurse_from(@$from);
232 } elsif (ref $from eq 'HASH') {
233 return $self->_make_as($from);
235 return $from; # would love to quote here but _table ends up getting called
236 # twice during an ->select without a limit clause due to
237 # the way S::A::Limit->select works. should maybe consider
238 # bypassing this and doing S::A::select($self, ...) in
239 # our select method above. meantime, quoting shims have
240 # been added to select/insert/update/delete here
245 my ($self, $from, @join) = @_;
247 push(@sqlf, $self->_make_as($from));
248 foreach my $j (@join) {
251 # check whether a join type exists
252 my $join_clause = '';
253 my $to_jt = ref($to) eq 'ARRAY' ? $to->[0] : $to;
254 if (ref($to_jt) eq 'HASH' and exists($to_jt->{-join_type})) {
255 $join_clause = ' '.uc($to_jt->{-join_type}).' JOIN ';
257 $join_clause = ' JOIN ';
259 push(@sqlf, $join_clause);
261 if (ref $to eq 'ARRAY') {
262 push(@sqlf, '(', $self->_recurse_from(@$to), ')');
264 push(@sqlf, $self->_make_as($to));
266 push(@sqlf, ' ON ', $self->_join_condition($on));
268 return join('', @sqlf);
272 my ($self, $arr) = @_;
273 my ($sql, @bind) = @{${$arr}};
274 push (@{$self->{from_bind}}, @bind);
279 my ($self, $from) = @_;
280 return join(' ', map { (ref $_ eq 'SCALAR' ? $$_
281 : ref $_ eq 'REF' ? $self->_bind_to_sql($_)
283 } reverse each %{$self->_skip_options($from)});
287 my ($self, $hash) = @_;
289 $clean_hash->{$_} = $hash->{$_}
290 for grep {!/^-/} keys %$hash;
294 sub _join_condition {
295 my ($self, $cond) = @_;
296 if (ref $cond eq 'HASH') {
301 # XXX no throw_exception() in this package and croak() fails with strange results
302 Carp::croak(ref($v) . qq{ reference arguments are not supported in JOINS - try using \"..." instead'})
303 if ref($v) ne 'SCALAR';
307 my $x = '= '.$self->_quote($v); $j{$_} = \$x;
310 return scalar($self->_recurse_where(\%j));
311 } elsif (ref $cond eq 'ARRAY') {
312 return join(' OR ', map { $self->_join_condition($_) } @$cond);
314 die "Can't handle this yet!";
319 my ($self, $label) = @_;
320 return '' unless defined $label;
321 return "*" if $label eq '*';
322 return $label unless $self->{quote_char};
323 if(ref $self->{quote_char} eq "ARRAY"){
324 return $self->{quote_char}->[0] . $label . $self->{quote_char}->[1]
325 if !defined $self->{name_sep};
326 my $sep = $self->{name_sep};
327 return join($self->{name_sep},
328 map { $self->{quote_char}->[0] . $_ . $self->{quote_char}->[1] }
329 split(/\Q$sep\E/,$label));
331 return $self->SUPER::_quote($label);
336 $self->{limit_dialect} = shift if @_;
337 return $self->{limit_dialect};
342 $self->{quote_char} = shift if @_;
343 return $self->{quote_char};
348 $self->{name_sep} = shift if @_;
349 return $self->{name_sep};
352 } # End of BEGIN block
356 DBIx::Class::Storage::DBI - DBI storage handler
360 my $schema = MySchema->connect('dbi:SQLite:my.db');
362 $schema->storage->debug(1);
363 $schema->dbh_do("DROP TABLE authors");
365 $schema->resultset('Book')->search({
366 written_on => $schema->storage->datetime_parser(DateTime->now)
371 This class represents the connection to an RDBMS via L<DBI>. See
372 L<DBIx::Class::Storage> for general information. This pod only
373 documents DBI-specific methods and behaviors.
380 my $new = shift->next::method(@_);
382 $new->transaction_depth(0);
383 $new->_sql_maker_opts({});
384 $new->{savepoints} = [];
385 $new->{_in_dbh_do} = 0;
386 $new->{_dbh_gen} = 0;
393 This method is normally called by L<DBIx::Class::Schema/connection>, which
394 encapsulates its argument list in an arrayref before passing them here.
396 The argument list may contain:
402 The same 4-element argument set one would normally pass to
403 L<DBI/connect>, optionally followed by
404 L<extra attributes|/DBIx::Class specific connection attributes>
405 recognized by DBIx::Class:
407 $connect_info_args = [ $dsn, $user, $password, \%dbi_attributes?, \%extra_attributes? ];
411 A single code reference which returns a connected
412 L<DBI database handle|DBI/connect> optionally followed by
413 L<extra attributes|/DBIx::Class specific connection attributes> recognized
416 $connect_info_args = [ sub { DBI->connect (...) }, \%extra_attributes? ];
420 A single hashref with all the attributes and the dsn/user/password
423 $connect_info_args = [{
431 This is particularly useful for L<Catalyst> based applications, allowing the
432 following config (L<Config::General> style):
437 dsn dbi:mysql:database=test
446 Please note that the L<DBI> docs recommend that you always explicitly
447 set C<AutoCommit> to either I<0> or I<1>. L<DBIx::Class> further
448 recommends that it be set to I<1>, and that you perform transactions
449 via our L<DBIx::Class::Schema/txn_do> method. L<DBIx::Class> will set it
450 to I<1> if you do not do explicitly set it to zero. This is the default
451 for most DBDs. See L</DBIx::Class and AutoCommit> for details.
453 =head3 DBIx::Class specific connection attributes
455 In addition to the standard L<DBI|DBI/ATTRIBUTES_COMMON_TO_ALL_HANDLES>
456 L<connection|DBI/Database_Handle_Attributes> attributes, DBIx::Class recognizes
457 the following connection options. These options can be mixed in with your other
458 L<DBI> connection attributes, or placed in a seperate hashref
459 (C<\%extra_attributes>) as shown above.
461 Every time C<connect_info> is invoked, any previous settings for
462 these options will be cleared before setting the new ones, regardless of
463 whether any options are specified in the new C<connect_info>.
470 Specifies things to do immediately after connecting or re-connecting to
471 the database. Its value may contain:
475 =item an array reference
477 This contains SQL statements to execute in order. Each element contains
478 a string or a code reference that returns a string.
480 =item a code reference
482 This contains some code to execute. Unlike code references within an
483 array reference, its return value is ignored.
487 =item on_disconnect_do
489 Takes arguments in the same form as L</on_connect_do> and executes them
490 immediately before disconnecting from the database.
492 Note, this only runs if you explicitly call L</disconnect> on the
495 =item disable_sth_caching
497 If set to a true value, this option will disable the caching of
498 statement handles via L<DBI/prepare_cached>.
502 Sets the limit dialect. This is useful for JDBC-bridge among others
503 where the remote SQL-dialect cannot be determined by the name of the
504 driver alone. See also L<SQL::Abstract::Limit>.
508 Specifies what characters to use to quote table and column names. If
509 you use this you will want to specify L</name_sep> as well.
511 C<quote_char> expects either a single character, in which case is it
512 is placed on either side of the table/column name, or an arrayref of length
513 2 in which case the table/column name is placed between the elements.
515 For example under MySQL you should use C<< quote_char => '`' >>, and for
516 SQL Server you should use C<< quote_char => [qw/[ ]/] >>.
520 This only needs to be used in conjunction with C<quote_char>, and is used to
521 specify the charecter that seperates elements (schemas, tables, columns) from
522 each other. In most cases this is simply a C<.>.
524 The consequences of not supplying this value is that L<SQL::Abstract>
525 will assume DBIx::Class' uses of aliases to be complete column
526 names. The output will look like I<"me.name"> when it should actually
531 This Storage driver normally installs its own C<HandleError>, sets
532 C<RaiseError> and C<ShowErrorStatement> on, and sets C<PrintError> off on
533 all database handles, including those supplied by a coderef. It does this
534 so that it can have consistent and useful error behavior.
536 If you set this option to a true value, Storage will not do its usual
537 modifications to the database handle's attributes, and instead relies on
538 the settings in your connect_info DBI options (or the values you set in
539 your connection coderef, in the case that you are connecting via coderef).
541 Note that your custom settings can cause Storage to malfunction,
542 especially if you set a C<HandleError> handler that suppresses exceptions
543 and/or disable C<RaiseError>.
547 If this option is true, L<DBIx::Class> will use savepoints when nesting
548 transactions, making it possible to recover from failure in the inner
549 transaction without having to abort all outer transactions.
553 Use this argument to supply a cursor class other than the default
554 L<DBIx::Class::Storage::DBI::Cursor>.
558 Some real-life examples of arguments to L</connect_info> and
559 L<DBIx::Class::Schema/connect>
561 # Simple SQLite connection
562 ->connect_info([ 'dbi:SQLite:./foo.db' ]);
565 ->connect_info([ sub { DBI->connect(...) } ]);
567 # A bit more complicated
574 { quote_char => q{"}, name_sep => q{.} },
578 # Equivalent to the previous example
584 { AutoCommit => 1, quote_char => q{"}, name_sep => q{.} },
588 # Same, but with hashref as argument
589 # See parse_connect_info for explanation
592 dsn => 'dbi:Pg:dbname=foo',
594 password => 'my_pg_password',
601 # Subref + DBIx::Class-specific connection options
604 sub { DBI->connect(...) },
608 on_connect_do => ['SET search_path TO myschema,otherschema,public'],
609 disable_sth_caching => 1,
619 my ($self, $info_arg) = @_;
621 return $self->_connect_info if !$info_arg;
623 my @args = @$info_arg; # take a shallow copy for further mutilation
624 $self->_connect_info([@args]); # copy for _connect_info
627 # combine/pre-parse arguments depending on invocation style
630 if (ref $args[0] eq 'CODE') { # coderef with optional \%extra_attributes
631 %attrs = %{ $args[1] || {} };
634 elsif (ref $args[0] eq 'HASH') { # single hashref (i.e. Catalyst config)
635 %attrs = %{$args[0]};
637 for (qw/password user dsn/) {
638 unshift @args, delete $attrs{$_};
641 else { # otherwise assume dsn/user/password + \%attrs + \%extra_attrs
643 % { $args[3] || {} },
644 % { $args[4] || {} },
646 @args = @args[0,1,2];
649 # Kill sql_maker/_sql_maker_opts, so we get a fresh one with only
650 # the new set of options
651 $self->_sql_maker(undef);
652 $self->_sql_maker_opts({});
655 for my $storage_opt (@storage_options, 'cursor_class') { # @storage_options is declared at the top of the module
656 if(my $value = delete $attrs{$storage_opt}) {
657 $self->$storage_opt($value);
660 for my $sql_maker_opt (qw/limit_dialect quote_char name_sep/) {
661 if(my $opt_val = delete $attrs{$sql_maker_opt}) {
662 $self->_sql_maker_opts->{$sql_maker_opt} = $opt_val;
667 %attrs = () if (ref $args[0] eq 'CODE'); # _connect() never looks past $args[0] in this case
669 $self->_dbi_connect_info([@args, keys %attrs ? \%attrs : ()]);
670 $self->_connect_info;
675 This method is deprecated in favour of setting via L</connect_info>.
680 Arguments: ($subref | $method_name), @extra_coderef_args?
682 Execute the given $subref or $method_name using the new exception-based
683 connection management.
685 The first two arguments will be the storage object that C<dbh_do> was called
686 on and a database handle to use. Any additional arguments will be passed
687 verbatim to the called subref as arguments 2 and onwards.
689 Using this (instead of $self->_dbh or $self->dbh) ensures correct
690 exception handling and reconnection (or failover in future subclasses).
692 Your subref should have no side-effects outside of the database, as
693 there is the potential for your subref to be partially double-executed
694 if the database connection was stale/dysfunctional.
698 my @stuff = $schema->storage->dbh_do(
700 my ($storage, $dbh, @cols) = @_;
701 my $cols = join(q{, }, @cols);
702 $dbh->selectrow_array("SELECT $cols FROM foo");
713 my $dbh = $self->_dbh;
715 return $self->$code($dbh, @_) if $self->{_in_dbh_do}
716 || $self->{transaction_depth};
718 local $self->{_in_dbh_do} = 1;
721 my $want_array = wantarray;
724 $self->_verify_pid if $dbh;
726 $self->_populate_dbh;
731 @result = $self->$code($dbh, @_);
733 elsif(defined $want_array) {
734 $result[0] = $self->$code($dbh, @_);
737 $self->$code($dbh, @_);
742 if(!$exception) { return $want_array ? @result : $result[0] }
744 $self->throw_exception($exception) if $self->connected;
746 # We were not connected - reconnect and retry, but let any
747 # exception fall right through this time
748 $self->_populate_dbh;
749 $self->$code($self->_dbh, @_);
752 # This is basically a blend of dbh_do above and DBIx::Class::Storage::txn_do.
753 # It also informs dbh_do to bypass itself while under the direction of txn_do,
754 # via $self->{_in_dbh_do} (this saves some redundant eval and errorcheck, etc)
759 ref $coderef eq 'CODE' or $self->throw_exception
760 ('$coderef must be a CODE reference');
762 return $coderef->(@_) if $self->{transaction_depth} && ! $self->auto_savepoint;
764 local $self->{_in_dbh_do} = 1;
767 my $want_array = wantarray;
772 $self->_verify_pid if $self->_dbh;
773 $self->_populate_dbh if !$self->_dbh;
777 @result = $coderef->(@_);
779 elsif(defined $want_array) {
780 $result[0] = $coderef->(@_);
789 if(!$exception) { return $want_array ? @result : $result[0] }
791 if($tried++ > 0 || $self->connected) {
792 eval { $self->txn_rollback };
793 my $rollback_exception = $@;
794 if($rollback_exception) {
795 my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
796 $self->throw_exception($exception) # propagate nested rollback
797 if $rollback_exception =~ /$exception_class/;
799 $self->throw_exception(
800 "Transaction aborted: ${exception}. "
801 . "Rollback failed: ${rollback_exception}"
804 $self->throw_exception($exception)
807 # We were not connected, and was first try - reconnect and retry
809 $self->_populate_dbh;
815 Our C<disconnect> method also performs a rollback first if the
816 database is not in C<AutoCommit> mode.
823 if( $self->connected ) {
824 my $connection_do = $self->on_disconnect_do;
825 $self->_do_connection_actions($connection_do) if ref($connection_do);
827 $self->_dbh->rollback unless $self->_dbh_autocommit;
828 $self->_dbh->disconnect;
834 =head2 with_deferred_fk_checks
838 =item Arguments: C<$coderef>
840 =item Return Value: The return value of $coderef
844 Storage specific method to run the code ref with FK checks deferred or
845 in MySQL's case disabled entirely.
849 # Storage subclasses should override this
850 sub with_deferred_fk_checks {
851 my ($self, $sub) = @_;
859 if(my $dbh = $self->_dbh) {
860 if(defined $self->_conn_tid && $self->_conn_tid != threads->tid) {
867 return 0 if !$self->_dbh;
869 return ($dbh->FETCH('Active') && $dbh->ping);
875 # handle pid changes correctly
876 # NOTE: assumes $self->_dbh is a valid $dbh
880 return if defined $self->_conn_pid && $self->_conn_pid == $$;
882 $self->_dbh->{InactiveDestroy} = 1;
889 sub ensure_connected {
892 unless ($self->connected) {
893 $self->_populate_dbh;
899 Returns the dbh - a data base handle of class L<DBI>.
906 $self->ensure_connected;
910 sub _sql_maker_args {
913 return ( bindtype=>'columns', array_datatypes => 1, limit_dialect => $self->dbh, %{$self->_sql_maker_opts} );
918 unless ($self->_sql_maker) {
919 my $sql_maker_class = $self->sql_maker_class;
920 $self->_sql_maker($sql_maker_class->new( $self->_sql_maker_args ));
922 return $self->_sql_maker;
929 my @info = @{$self->_dbi_connect_info || []};
930 $self->_dbh($self->_connect(@info));
932 # Always set the transaction depth on connect, since
933 # there is no transaction in progress by definition
934 $self->{transaction_depth} = $self->_dbh_autocommit ? 0 : 1;
936 if(ref $self eq 'DBIx::Class::Storage::DBI') {
937 my $driver = $self->_dbh->{Driver}->{Name};
938 if ($self->load_optional_class("DBIx::Class::Storage::DBI::${driver}")) {
939 bless $self, "DBIx::Class::Storage::DBI::${driver}";
944 $self->_conn_pid($$);
945 $self->_conn_tid(threads->tid) if $INC{'threads.pm'};
947 my $connection_do = $self->on_connect_do;
948 $self->_do_connection_actions($connection_do) if ref($connection_do);
951 sub _do_connection_actions {
953 my $connection_do = shift;
955 if (ref $connection_do eq 'ARRAY') {
956 $self->_do_query($_) foreach @$connection_do;
958 elsif (ref $connection_do eq 'CODE') {
959 $connection_do->($self);
966 my ($self, $action) = @_;
968 if (ref $action eq 'CODE') {
969 $action = $action->($self);
970 $self->_do_query($_) foreach @$action;
973 # Most debuggers expect ($sql, @bind), so we need to exclude
974 # the attribute hash which is the second argument to $dbh->do
975 # furthermore the bind values are usually to be presented
976 # as named arrayref pairs, so wrap those here too
977 my @do_args = (ref $action eq 'ARRAY') ? (@$action) : ($action);
978 my $sql = shift @do_args;
979 my $attrs = shift @do_args;
980 my @bind = map { [ undef, $_ ] } @do_args;
982 $self->_query_start($sql, @bind);
983 $self->_dbh->do($sql, $attrs, @do_args);
984 $self->_query_end($sql, @bind);
991 my ($self, @info) = @_;
993 $self->throw_exception("You failed to provide any connection info")
996 my ($old_connect_via, $dbh);
998 if ($INC{'Apache/DBI.pm'} && $ENV{MOD_PERL}) {
999 $old_connect_via = $DBI::connect_via;
1000 $DBI::connect_via = 'connect';
1004 if(ref $info[0] eq 'CODE') {
1008 $dbh = DBI->connect(@info);
1011 if($dbh && !$self->unsafe) {
1012 my $weak_self = $self;
1014 $dbh->{HandleError} = sub {
1016 $weak_self->throw_exception("DBI Exception: $_[0]");
1019 croak ("DBI Exception: $_[0]");
1022 $dbh->{ShowErrorStatement} = 1;
1023 $dbh->{RaiseError} = 1;
1024 $dbh->{PrintError} = 0;
1028 $DBI::connect_via = $old_connect_via if $old_connect_via;
1030 $self->throw_exception("DBI Connection failed: " . ($@||$DBI::errstr))
1033 $self->_dbh_autocommit($dbh->{AutoCommit});
1039 my ($self, $name) = @_;
1041 $name = $self->_svp_generate_name
1042 unless defined $name;
1044 $self->throw_exception ("You can't use savepoints outside a transaction")
1045 if $self->{transaction_depth} == 0;
1047 $self->throw_exception ("Your Storage implementation doesn't support savepoints")
1048 unless $self->can('_svp_begin');
1050 push @{ $self->{savepoints} }, $name;
1052 $self->debugobj->svp_begin($name) if $self->debug;
1054 return $self->_svp_begin($name);
1058 my ($self, $name) = @_;
1060 $self->throw_exception ("You can't use savepoints outside a transaction")
1061 if $self->{transaction_depth} == 0;
1063 $self->throw_exception ("Your Storage implementation doesn't support savepoints")
1064 unless $self->can('_svp_release');
1066 if (defined $name) {
1067 $self->throw_exception ("Savepoint '$name' does not exist")
1068 unless grep { $_ eq $name } @{ $self->{savepoints} };
1070 # Dig through the stack until we find the one we are releasing. This keeps
1071 # the stack up to date.
1074 do { $svp = pop @{ $self->{savepoints} } } while $svp ne $name;
1076 $name = pop @{ $self->{savepoints} };
1079 $self->debugobj->svp_release($name) if $self->debug;
1081 return $self->_svp_release($name);
1085 my ($self, $name) = @_;
1087 $self->throw_exception ("You can't use savepoints outside a transaction")
1088 if $self->{transaction_depth} == 0;
1090 $self->throw_exception ("Your Storage implementation doesn't support savepoints")
1091 unless $self->can('_svp_rollback');
1093 if (defined $name) {
1094 # If they passed us a name, verify that it exists in the stack
1095 unless(grep({ $_ eq $name } @{ $self->{savepoints} })) {
1096 $self->throw_exception("Savepoint '$name' does not exist!");
1099 # Dig through the stack until we find the one we are releasing. This keeps
1100 # the stack up to date.
1101 while(my $s = pop(@{ $self->{savepoints} })) {
1102 last if($s eq $name);
1104 # Add the savepoint back to the stack, as a rollback doesn't remove the
1105 # named savepoint, only everything after it.
1106 push(@{ $self->{savepoints} }, $name);
1108 # We'll assume they want to rollback to the last savepoint
1109 $name = $self->{savepoints}->[-1];
1112 $self->debugobj->svp_rollback($name) if $self->debug;
1114 return $self->_svp_rollback($name);
1117 sub _svp_generate_name {
1120 return 'savepoint_'.scalar(@{ $self->{'savepoints'} });
1125 $self->ensure_connected();
1126 if($self->{transaction_depth} == 0) {
1127 $self->debugobj->txn_begin()
1129 # this isn't ->_dbh-> because
1130 # we should reconnect on begin_work
1131 # for AutoCommit users
1132 $self->dbh->begin_work;
1133 } elsif ($self->auto_savepoint) {
1136 $self->{transaction_depth}++;
1141 if ($self->{transaction_depth} == 1) {
1142 my $dbh = $self->_dbh;
1143 $self->debugobj->txn_commit()
1146 $self->{transaction_depth} = 0
1147 if $self->_dbh_autocommit;
1149 elsif($self->{transaction_depth} > 1) {
1150 $self->{transaction_depth}--;
1152 if $self->auto_savepoint;
1158 my $dbh = $self->_dbh;
1160 if ($self->{transaction_depth} == 1) {
1161 $self->debugobj->txn_rollback()
1163 $self->{transaction_depth} = 0
1164 if $self->_dbh_autocommit;
1167 elsif($self->{transaction_depth} > 1) {
1168 $self->{transaction_depth}--;
1169 if ($self->auto_savepoint) {
1170 $self->svp_rollback;
1175 die DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION->new;
1180 my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
1181 $error =~ /$exception_class/ and $self->throw_exception($error);
1182 # ensure that a failed rollback resets the transaction depth
1183 $self->{transaction_depth} = $self->_dbh_autocommit ? 0 : 1;
1184 $self->throw_exception($error);
1188 # This used to be the top-half of _execute. It was split out to make it
1189 # easier to override in NoBindVars without duping the rest. It takes up
1190 # all of _execute's args, and emits $sql, @bind.
1191 sub _prep_for_execute {
1192 my ($self, $op, $extra_bind, $ident, $args) = @_;
1194 if( blessed($ident) && $ident->isa("DBIx::Class::ResultSource") ) {
1195 $ident = $ident->from();
1198 my ($sql, @bind) = $self->sql_maker->$op($ident, @$args);
1201 map { ref $_ eq 'ARRAY' ? $_ : [ '!!dummy', $_ ] } @$extra_bind)
1203 return ($sql, \@bind);
1206 sub _fix_bind_params {
1207 my ($self, @bind) = @_;
1209 ### Turn @bind from something like this:
1210 ### ( [ "artist", 1 ], [ "cdid", 1, 3 ] )
1212 ### ( "'1'", "'1'", "'3'" )
1215 if ( defined( $_ && $_->[1] ) ) {
1216 map { qq{'$_'}; } @{$_}[ 1 .. $#$_ ];
1223 my ( $self, $sql, @bind ) = @_;
1225 if ( $self->debug ) {
1226 @bind = $self->_fix_bind_params(@bind);
1228 $self->debugobj->query_start( $sql, @bind );
1233 my ( $self, $sql, @bind ) = @_;
1235 if ( $self->debug ) {
1236 @bind = $self->_fix_bind_params(@bind);
1237 $self->debugobj->query_end( $sql, @bind );
1242 my ($self, $dbh, $op, $extra_bind, $ident, $bind_attributes, @args) = @_;
1244 my ($sql, $bind) = $self->_prep_for_execute($op, $extra_bind, $ident, \@args);
1246 $self->_query_start( $sql, @$bind );
1248 my $sth = $self->sth($sql,$op);
1250 my $placeholder_index = 1;
1252 foreach my $bound (@$bind) {
1253 my $attributes = {};
1254 my($column_name, @data) = @$bound;
1256 if ($bind_attributes) {
1257 $attributes = $bind_attributes->{$column_name}
1258 if defined $bind_attributes->{$column_name};
1261 foreach my $data (@data) {
1262 my $ref = ref $data;
1263 $data = $ref && $ref ne 'ARRAY' ? ''.$data : $data; # stringify args (except arrayrefs)
1265 $sth->bind_param($placeholder_index, $data, $attributes);
1266 $placeholder_index++;
1270 # Can this fail without throwing an exception anyways???
1271 my $rv = $sth->execute();
1272 $self->throw_exception($sth->errstr) if !$rv;
1274 $self->_query_end( $sql, @$bind );
1276 return (wantarray ? ($rv, $sth, @$bind) : $rv);
1281 $self->dbh_do('_dbh_execute', @_)
1285 my ($self, $source, $to_insert) = @_;
1287 my $ident = $source->from;
1288 my $bind_attributes = $self->source_bind_attributes($source);
1290 $self->ensure_connected;
1291 foreach my $col ( $source->columns ) {
1292 if ( !defined $to_insert->{$col} ) {
1293 my $col_info = $source->column_info($col);
1295 if ( $col_info->{auto_nextval} ) {
1296 $to_insert->{$col} = $self->_sequence_fetch( 'nextval', $col_info->{sequence} || $self->_dbh_get_autoinc_seq($self->dbh, $source) );
1301 $self->_execute('insert' => [], $source, $bind_attributes, $to_insert);
1306 ## Still not quite perfect, and EXPERIMENTAL
1307 ## Currently it is assumed that all values passed will be "normal", i.e. not
1308 ## scalar refs, or at least, all the same type as the first set, the statement is
1309 ## only prepped once.
1311 my ($self, $source, $cols, $data) = @_;
1313 my $table = $source->from;
1314 @colvalues{@$cols} = (0..$#$cols);
1315 my ($sql, @bind) = $self->sql_maker->insert($table, \%colvalues);
1317 $self->_query_start( $sql, @bind );
1318 my $sth = $self->sth($sql);
1320 # @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args
1322 ## This must be an arrayref, else nothing works!
1324 my $tuple_status = [];
1327 ##print STDERR Dumper( $data, $sql, [@bind] );
1331 ## Get the bind_attributes, if any exist
1332 my $bind_attributes = $self->source_bind_attributes($source);
1334 ## Bind the values and execute
1335 my $placeholder_index = 1;
1337 foreach my $bound (@bind) {
1339 my $attributes = {};
1340 my ($column_name, $data_index) = @$bound;
1342 if( $bind_attributes ) {
1343 $attributes = $bind_attributes->{$column_name}
1344 if defined $bind_attributes->{$column_name};
1347 my @data = map { $_->[$data_index] } @$data;
1349 $sth->bind_param_array( $placeholder_index, [@data], $attributes );
1350 $placeholder_index++;
1352 my $rv = $sth->execute_array({ArrayTupleStatus => $tuple_status});
1353 $self->throw_exception($sth->errstr) if !$rv;
1355 $self->_query_end( $sql, @bind );
1356 return (wantarray ? ($rv, $sth, @bind) : $rv);
1360 my $self = shift @_;
1361 my $source = shift @_;
1362 my $bind_attributes = $self->source_bind_attributes($source);
1364 return $self->_execute('update' => [], $source, $bind_attributes, @_);
1369 my $self = shift @_;
1370 my $source = shift @_;
1372 my $bind_attrs = {}; ## If ever it's needed...
1374 return $self->_execute('delete' => [], $source, $bind_attrs, @_);
1379 my $sql_maker = $self->sql_maker;
1380 local $sql_maker->{for};
1381 return $self->_execute($self->_select_args(@_));
1385 my ($self, $ident, $select, $condition, $attrs) = @_;
1386 my $order = $attrs->{order_by};
1388 if (ref $condition eq 'SCALAR') {
1389 my $unwrap = ${$condition};
1390 if ($unwrap =~ s/ORDER BY (.*)$//i) {
1392 $condition = \$unwrap;
1396 my $for = delete $attrs->{for};
1397 my $sql_maker = $self->sql_maker;
1398 $sql_maker->{for} = $for;
1400 if (exists $attrs->{group_by} || $attrs->{having}) {
1402 group_by => $attrs->{group_by},
1403 having => $attrs->{having},
1404 ($order ? (order_by => $order) : ())
1407 my $bind_attrs = {}; ## Future support
1408 my @args = ('select', $attrs->{bind}, $ident, $bind_attrs, $select, $condition, $order);
1409 if ($attrs->{software_limit} ||
1410 $self->sql_maker->_default_limit_syntax eq "GenericSubQ") {
1411 $attrs->{software_limit} = 1;
1413 $self->throw_exception("rows attribute must be positive if present")
1414 if (defined($attrs->{rows}) && !($attrs->{rows} > 0));
1416 # MySQL actually recommends this approach. I cringe.
1417 $attrs->{rows} = 2**48 if not defined $attrs->{rows} and defined $attrs->{offset};
1418 push @args, $attrs->{rows}, $attrs->{offset};
1423 sub source_bind_attributes {
1424 my ($self, $source) = @_;
1426 my $bind_attributes;
1427 foreach my $column ($source->columns) {
1429 my $data_type = $source->column_info($column)->{data_type} || '';
1430 $bind_attributes->{$column} = $self->bind_attribute_by_data_type($data_type)
1434 return $bind_attributes;
1441 =item Arguments: $ident, $select, $condition, $attrs
1445 Handle a SQL select statement.
1451 my ($ident, $select, $condition, $attrs) = @_;
1452 return $self->cursor_class->new($self, \@_, $attrs);
1457 my ($rv, $sth, @bind) = $self->_select(@_);
1458 my @row = $sth->fetchrow_array;
1459 my @nextrow = $sth->fetchrow_array if @row;
1460 if(@row && @nextrow) {
1461 carp "Query returned more than one row. SQL that returns multiple rows is DEPRECATED for ->find and ->single";
1463 # Need to call finish() to work round broken DBDs
1472 =item Arguments: $sql
1476 Returns a L<DBI> sth (statement handle) for the supplied SQL.
1481 my ($self, $dbh, $sql) = @_;
1483 # 3 is the if_active parameter which avoids active sth re-use
1484 my $sth = $self->disable_sth_caching
1485 ? $dbh->prepare($sql)
1486 : $dbh->prepare_cached($sql, {}, 3);
1488 # XXX You would think RaiseError would make this impossible,
1489 # but apparently that's not true :(
1490 $self->throw_exception($dbh->errstr) if !$sth;
1496 my ($self, $sql) = @_;
1497 $self->dbh_do('_dbh_sth', $sql);
1500 sub _dbh_columns_info_for {
1501 my ($self, $dbh, $table) = @_;
1503 if ($dbh->can('column_info')) {
1506 my ($schema,$tab) = $table =~ /^(.+?)\.(.+)$/ ? ($1,$2) : (undef,$table);
1507 my $sth = $dbh->column_info( undef,$schema, $tab, '%' );
1509 while ( my $info = $sth->fetchrow_hashref() ){
1511 $column_info{data_type} = $info->{TYPE_NAME};
1512 $column_info{size} = $info->{COLUMN_SIZE};
1513 $column_info{is_nullable} = $info->{NULLABLE} ? 1 : 0;
1514 $column_info{default_value} = $info->{COLUMN_DEF};
1515 my $col_name = $info->{COLUMN_NAME};
1516 $col_name =~ s/^\"(.*)\"$/$1/;
1518 $result{$col_name} = \%column_info;
1521 return \%result if !$@ && scalar keys %result;
1525 my $sth = $dbh->prepare($self->sql_maker->select($table, undef, \'1 = 0'));
1527 my @columns = @{$sth->{NAME_lc}};
1528 for my $i ( 0 .. $#columns ){
1530 $column_info{data_type} = $sth->{TYPE}->[$i];
1531 $column_info{size} = $sth->{PRECISION}->[$i];
1532 $column_info{is_nullable} = $sth->{NULLABLE}->[$i] ? 1 : 0;
1534 if ($column_info{data_type} =~ m/^(.*?)\((.*?)\)$/) {
1535 $column_info{data_type} = $1;
1536 $column_info{size} = $2;
1539 $result{$columns[$i]} = \%column_info;
1543 foreach my $col (keys %result) {
1544 my $colinfo = $result{$col};
1545 my $type_num = $colinfo->{data_type};
1547 if(defined $type_num && $dbh->can('type_info')) {
1548 my $type_info = $dbh->type_info($type_num);
1549 $type_name = $type_info->{TYPE_NAME} if $type_info;
1550 $colinfo->{data_type} = $type_name if $type_name;
1557 sub columns_info_for {
1558 my ($self, $table) = @_;
1559 $self->dbh_do('_dbh_columns_info_for', $table);
1562 =head2 last_insert_id
1564 Return the row id of the last insert.
1568 sub _dbh_last_insert_id {
1569 # All Storage's need to register their own _dbh_last_insert_id
1570 # the old SQLite-based method was highly inappropriate
1573 my $class = ref $self;
1574 $self->throw_exception (<<EOE);
1576 No _dbh_last_insert_id() method found in $class.
1577 Since the method of obtaining the autoincrement id of the last insert
1578 operation varies greatly between different databases, this method must be
1579 individually implemented for every storage class.
1583 sub last_insert_id {
1585 $self->dbh_do('_dbh_last_insert_id', @_);
1590 Returns the database driver name.
1594 sub sqlt_type { shift->dbh->{Driver}->{Name} }
1596 =head2 bind_attribute_by_data_type
1598 Given a datatype from column info, returns a database specific bind
1599 attribute for C<< $dbh->bind_param($val,$attribute) >> or nothing if we will
1600 let the database planner just handle it.
1602 Generally only needed for special case column types, like bytea in postgres.
1606 sub bind_attribute_by_data_type {
1610 =head2 create_ddl_dir
1614 =item Arguments: $schema \@databases, $version, $directory, $preversion, \%sqlt_args
1618 Creates a SQL file based on the Schema, for each of the specified
1619 database types, in the given directory.
1621 By default, C<\%sqlt_args> will have
1623 { add_drop_table => 1, ignore_constraint_names => 1, ignore_index_names => 1 }
1625 merged with the hash passed in. To disable any of those features, pass in a
1626 hashref like the following
1628 { ignore_constraint_names => 0, # ... other options }
1632 sub create_ddl_dir {
1633 my ($self, $schema, $databases, $version, $dir, $preversion, $sqltargs) = @_;
1635 if(!$dir || !-d $dir) {
1636 warn "No directory given, using ./\n";
1639 $databases ||= ['MySQL', 'SQLite', 'PostgreSQL'];
1640 $databases = [ $databases ] if(ref($databases) ne 'ARRAY');
1642 my $schema_version = $schema->schema_version || '1.x';
1643 $version ||= $schema_version;
1646 add_drop_table => 1,
1647 ignore_constraint_names => 1,
1648 ignore_index_names => 1,
1652 $self->throw_exception(q{Can't create a ddl file without SQL::Translator 0.09003: '}
1653 . $self->_check_sqlt_message . q{'})
1654 if !$self->_check_sqlt_version;
1656 my $sqlt = SQL::Translator->new( $sqltargs );
1658 $sqlt->parser('SQL::Translator::Parser::DBIx::Class');
1659 my $sqlt_schema = $sqlt->translate({ data => $schema }) or die $sqlt->error;
1661 foreach my $db (@$databases) {
1663 $sqlt->{schema} = $sqlt_schema;
1664 $sqlt->producer($db);
1667 my $filename = $schema->ddl_filename($db, $version, $dir);
1668 if (-e $filename && ($version eq $schema_version )) {
1669 # if we are dumping the current version, overwrite the DDL
1670 warn "Overwriting existing DDL file - $filename";
1674 my $output = $sqlt->translate;
1676 warn("Failed to translate to $db, skipping. (" . $sqlt->error . ")");
1679 if(!open($file, ">$filename")) {
1680 $self->throw_exception("Can't open $filename for writing ($!)");
1683 print $file $output;
1686 next unless ($preversion);
1688 require SQL::Translator::Diff;
1690 my $prefilename = $schema->ddl_filename($db, $preversion, $dir);
1691 if(!-e $prefilename) {
1692 warn("No previous schema file found ($prefilename)");
1696 my $difffile = $schema->ddl_filename($db, $version, $dir, $preversion);
1698 warn("Overwriting existing diff file - $difffile");
1704 my $t = SQL::Translator->new($sqltargs);
1707 $t->parser( $db ) or die $t->error;
1708 my $out = $t->translate( $prefilename ) or die $t->error;
1709 $source_schema = $t->schema;
1710 unless ( $source_schema->name ) {
1711 $source_schema->name( $prefilename );
1715 # The "new" style of producers have sane normalization and can support
1716 # diffing a SQL file against a DBIC->SQLT schema. Old style ones don't
1717 # And we have to diff parsed SQL against parsed SQL.
1718 my $dest_schema = $sqlt_schema;
1720 unless ( "SQL::Translator::Producer::$db"->can('preprocess_schema') ) {
1721 my $t = SQL::Translator->new($sqltargs);
1724 $t->parser( $db ) or die $t->error;
1725 my $out = $t->translate( $filename ) or die $t->error;
1726 $dest_schema = $t->schema;
1727 $dest_schema->name( $filename )
1728 unless $dest_schema->name;
1731 my $diff = SQL::Translator::Diff::schema_diff($source_schema, $db,
1735 if(!open $file, ">$difffile") {
1736 $self->throw_exception("Can't write to $difffile ($!)");
1744 =head2 deployment_statements
1748 =item Arguments: $schema, $type, $version, $directory, $sqlt_args
1752 Returns the statements used by L</deploy> and L<DBIx::Class::Schema/deploy>.
1753 The database driver name is given by C<$type>, though the value from
1754 L</sqlt_type> is used if it is not specified.
1756 C<$directory> is used to return statements from files in a previously created
1757 L</create_ddl_dir> directory and is optional. The filenames are constructed
1758 from L<DBIx::Class::Schema/ddl_filename>, the schema name and the C<$version>.
1760 If no C<$directory> is specified then the statements are constructed on the
1761 fly using L<SQL::Translator> and C<$version> is ignored.
1763 See L<SQL::Translator/METHODS> for a list of values for C<$sqlt_args>.
1767 sub deployment_statements {
1768 my ($self, $schema, $type, $version, $dir, $sqltargs) = @_;
1769 # Need to be connected to get the correct sqlt_type
1770 $self->ensure_connected() unless $type;
1771 $type ||= $self->sqlt_type;
1772 $version ||= $schema->schema_version || '1.x';
1774 my $filename = $schema->ddl_filename($type, $version, $dir);
1778 open($file, "<$filename")
1779 or $self->throw_exception("Can't open $filename ($!)");
1782 return join('', @rows);
1785 $self->throw_exception(q{Can't deploy without SQL::Translator 0.09003: '}
1786 . $self->_check_sqlt_message . q{'})
1787 if !$self->_check_sqlt_version;
1789 require SQL::Translator::Parser::DBIx::Class;
1790 eval qq{use SQL::Translator::Producer::${type}};
1791 $self->throw_exception($@) if $@;
1793 # sources needs to be a parser arg, but for simplicty allow at top level
1795 $sqltargs->{parser_args}{sources} = delete $sqltargs->{sources}
1796 if exists $sqltargs->{sources};
1798 my $tr = SQL::Translator->new(%$sqltargs);
1799 SQL::Translator::Parser::DBIx::Class::parse( $tr, $schema );
1800 return "SQL::Translator::Producer::${type}"->can('produce')->($tr);
1804 my ($self, $schema, $type, $sqltargs, $dir) = @_;
1807 return if($line =~ /^--/);
1809 # next if($line =~ /^DROP/m);
1810 return if($line =~ /^BEGIN TRANSACTION/m);
1811 return if($line =~ /^COMMIT/m);
1812 return if $line =~ /^\s+$/; # skip whitespace only
1813 $self->_query_start($line);
1815 $self->dbh->do($line); # shouldn't be using ->dbh ?
1818 warn qq{$@ (running "${line}")};
1820 $self->_query_end($line);
1822 my @statements = $self->deployment_statements($schema, $type, undef, $dir, { no_comments => 1, %{ $sqltargs || {} } } );
1823 if (@statements > 1) {
1824 foreach my $statement (@statements) {
1825 $deploy->( $statement );
1828 elsif (@statements == 1) {
1829 foreach my $line ( split(";\n", $statements[0])) {
1835 =head2 datetime_parser
1837 Returns the datetime parser class
1841 sub datetime_parser {
1843 return $self->{datetime_parser} ||= do {
1844 $self->ensure_connected;
1845 $self->build_datetime_parser(@_);
1849 =head2 datetime_parser_type
1851 Defines (returns) the datetime parser class - currently hardwired to
1852 L<DateTime::Format::MySQL>
1856 sub datetime_parser_type { "DateTime::Format::MySQL"; }
1858 =head2 build_datetime_parser
1860 See L</datetime_parser>
1864 sub build_datetime_parser {
1866 my $type = $self->datetime_parser_type(@_);
1868 $self->throw_exception("Couldn't load ${type}: $@") if $@;
1873 my $_check_sqlt_version; # private
1874 my $_check_sqlt_message; # private
1875 sub _check_sqlt_version {
1876 return $_check_sqlt_version if defined $_check_sqlt_version;
1877 eval 'use SQL::Translator "0.09003"';
1878 $_check_sqlt_message = $@ || '';
1879 $_check_sqlt_version = !$@;
1882 sub _check_sqlt_message {
1883 _check_sqlt_version if !defined $_check_sqlt_message;
1884 $_check_sqlt_message;
1888 =head2 is_replicating
1890 A boolean that reports if a particular L<DBIx::Class::Storage::DBI> is set to
1891 replicate from a master database. Default is undef, which is the result
1892 returned by databases that don't support replication.
1896 sub is_replicating {
1901 =head2 lag_behind_master
1903 Returns a number that represents a certain amount of lag behind a master db
1904 when a given storage is replicating. The number is database dependent, but
1905 starts at zero and increases with the amount of lag. Default in undef
1909 sub lag_behind_master {
1915 return if !$self->_dbh;
1924 =head2 DBIx::Class and AutoCommit
1926 DBIx::Class can do some wonderful magic with handling exceptions,
1927 disconnections, and transactions when you use C<< AutoCommit => 1 >>
1928 combined with C<txn_do> for transaction support.
1930 If you set C<< AutoCommit => 0 >> in your connect info, then you are always
1931 in an assumed transaction between commits, and you're telling us you'd
1932 like to manage that manually. A lot of the magic protections offered by
1933 this module will go away. We can't protect you from exceptions due to database
1934 disconnects because we don't know anything about how to restart your
1935 transactions. You're on your own for handling all sorts of exceptional
1936 cases if you choose the C<< AutoCommit => 0 >> path, just as you would
1942 The module defines a set of methods within the DBIC::SQL::Abstract
1943 namespace. These build on L<SQL::Abstract::Limit> to provide the
1944 SQL query functions.
1946 The following methods are extended:-
1960 See L</connect_info> for details.
1964 See L</connect_info> for details.
1968 See L</connect_info> for details.
1974 Matt S. Trout <mst@shadowcatsystems.co.uk>
1976 Andy Grundman <andy@hybridized.org>
1980 You may distribute this code under the same terms as Perl itself.