DBI

 view release on metacpan or  search on metacpan

DBI.pm  view on Meta::CPAN


An application can set the C<ReadOnly> attribute of a handle to a true value to
indicate that it will not be attempting to make any changes using that handle
or any children of it.

Note that the exact definition of 'read only' is rather fuzzy.
For more details see the documentation for the driver you're using.

If the driver can make the handle truly read-only then it should
(unless doing so would have unpleasant side effect, like changing the
consistency level from per-statement to per-session).
Otherwise the attribute is simply advisory.

A driver can set the C<ReadOnly> attribute itself to indicate that the data it
is connected to cannot be changed for some reason.

If the driver cannot ensure the C<ReadOnly> attribute is adhered to it
will record a warning.  In this case reading the C<ReadOnly> attribute
back after it is set true will return true even if the underlying
driver cannot ensure this (so any application knows the application
declared itself ReadOnly).

Library modules and proxy drivers can use the attribute to influence
their behavior.  For example, the DBD::Gofer driver considers the
C<ReadOnly> attribute when making a decision about whether to retry an
operation that failed.

The attribute should be set to 1 or 0 (or undef). Other values are reserved.

=head3 C<Callbacks>

Type: hash ref

The DBI callback mechanism lets you intercept, and optionally replace, any
method call on a DBI handle. At the extreme, it lets you become a puppet
master, deceiving the application in any way you want.

The C<Callbacks> attribute is a hash reference where the keys are DBI method
names and the values are code references. For each key naming a method, the
DBI will execute the associated code reference before executing the method.

The arguments to the code reference will be the same as to the method,
including the invocant (a database handle or statement handle). For example,
say that to callback to some code on a call to C<prepare()>:

  $dbh->{Callbacks} = {
      prepare => sub {
          my ($dbh, $query, $attrs) = @_;
          print "Preparing q{$query}\n"
      },
  };

The callback would then be executed when you called the C<prepare()> method:

  $dbh->prepare('SELECT 1');

And the output of course would be:

  Preparing q{SELECT 1}

Because callbacks are executed I<before> the methods
they're associated with, you can modify the arguments before they're passed on
to the method call. For example, to make sure that all calls to C<prepare()>
are immediately prepared by L<DBD::Pg>, add a callback that makes sure that
the C<pg_prepare_now> attribute is always set:

  my $dbh = DBI->connect($dsn, $username, $auth, {
      Callbacks => {
          prepare => sub {
              $_[2] ||= {};
              $_[2]->{pg_prepare_now} = 1;
              return; # must return nothing
          },
      }
  });

Note that we are editing the contents of C<@_> directly. In this case we've
created the attributes hash if it's not passed to the C<prepare> call.

You can also prevent the associated method from ever executing. While a
callback executes, C<$_> holds the method name. (This allows multiple callbacks
to share the same code reference and still know what method was called.)
To prevent the method from
executing, simply C<undef $_>. For example, if you wanted to disable calls to
C<ping()>, you could do this:

  $dbh->{Callbacks} = {
      ping => sub {
          # tell dispatch to not call the method:
          undef $_;
          # return this value instead:
          return "42 bells";
      }
  };

As with other attributes, Callbacks can be specified on a handle or via the
attributes to C<connect()>. Callbacks can also be applied to a statement
methods on a statement handle. For example:

  $sth->{Callbacks} = {
      execute => sub {
          print "Executing ", shift->{Statement}, "\n";
      }
  };

The C<Callbacks> attribute of a database handle isn't copied to any statement
handles it creates. So setting callbacks for a statement handle requires you to
set the C<Callbacks> attribute on the statement handle yourself, as in the
example above, or use the special C<ChildCallbacks> key described below.

B<Special Keys in Callbacks Attribute>

In addition to DBI handle method names, the C<Callbacks> hash reference
supports four additional keys.

The first is the C<ChildCallbacks> key. When a statement handle is created from
a database handle the C<ChildCallbacks> key of the database handle's
C<Callbacks> attribute, if any, becomes the new C<Callbacks> attribute of the
statement handle.
This allows you to define callbacks for all statement handles created from a
database handle. For example, if you wanted to count how many times C<execute>
was called in your application, you could write:

  my $exec_count = 0;
  my $dbh = DBI->connect( $dsn, $username, $auth, {
      Callbacks => {
          ChildCallbacks => {
              execute => sub { $exec_count++; return; }
          }
      }
  });

  END {
      print "The execute method was called $exec_count times\n";
  }

The other three special keys are C<connect_cached.new>,
C<connect_cached.connected>, and C<connect_cached.reused>. These keys define
callbacks that are called when C<connect_cached()> is called, but allow
different behaviors depending on whether a new handle is created or a handle
is returned. The callback is invoked with these arguments:
C<$dbh, $dsn, $user, $auth, $attr>.

For example, some applications uses C<connect_cached()> to connect with
C<AutoCommit> enabled and then disable C<AutoCommit> temporarily for
transactions. If C<connect_cached()> is called during a transaction, perhaps in
a utility method, then it might select the same cached handle and then force
C<AutoCommit> on, forcing a commit of the transaction. See the L</connect_cached>
documentation for one way to deal with that. Here we'll describe an alternative
approach using a callback.

Because the C<connect_cached.new> and C<connect_cached.reused> callbacks are
invoked before C<connect_cached()> has applied the connect attributes, you can
use them to edit the attributes that will be applied. To prevent a cached
handle from having its transactions committed before it's returned, you can
eliminate the C<AutoCommit> attribute in a C<connect_cached.reused> callback,
like so:

  my $cb = {
      'connect_cached.reused' => sub { delete $_[4]->{AutoCommit} },
  };

  sub dbh {
      my $self = shift;
      DBI->connect_cached( $dsn, $username, $auth, {
          PrintError => 0,
          RaiseError => 1,
          AutoCommit => 1,
          Callbacks  => $cb,
      });
  }

The upshot is that new database handles are created with C<AutoCommit>
enabled, while cached database handles are left in whatever transaction state
they happened to be in when retrieved from the cache.

Note that we've also used a lexical for the callbacks hash reference. This is
because C<connect_cached()> returns a new database handle if any of the
attributes passed to is have changed. If we used an inline hash reference,
C<connect_cached()> would return a new database handle every time. Which would
rather defeat the purpose.

A more common application for callbacks is setting connection state only when
a new connection is made (by connect() or connect_cached()). Adding a callback
to the connected method (when using C<connect>) or via
C<connect_cached.connected> (when useing connect_cached()>) makes this easy.
The connected() method is a no-op by default (unless you subclass the DBI and
change it). The DBI calls it to indicate that a new connection has been made
and the connection attributes have all been set. You can give it a bit of
added functionality by applying a callback to it. For example, to make sure
that MySQL understands your application's ANSI-compliant SQL, set it up like
so:

  my $dbh = DBI->connect($dsn, $username, $auth, {
      Callbacks => {
          connected => sub {
              shift->do(q{
                  SET SESSION sql_mode='ansi,strict_trans_tables,no_auto_value_on_zero';
              });
              return;
          },
      }
  });

If you're using C<connect_cached()>, use the C<connect_cached.connected>
callback, instead. This is because C<connected()> is called for both new and
reused database handles, but you want to execute a callback only the when a
new database handle is returned. For example, to set the time zone on
connection to a PostgreSQL database, try this:

  my $cb = {
      'connect_cached.connected' => sub {
          shift->do('SET timezone = UTC');
      }
  };

  sub dbh {
      my $self = shift;
      DBI->connect_cached( $dsn, $username, $auth, { Callbacks => $cb });
  }

One significant limitation with callbacks is that there can only be one per
method per handle. This means it's easy for one use of callbacks to interfere
with, or typically simply overwrite, another use of callbacks. For this reason
modules using callbacks should document the fact clearly so application authors
can tell if use of callbacks by the module will clash with use of callbacks by
the application.

You might be able to work around this issue by taking a copy of the original
callback and calling it within your own. For example:

  my $prev_cb = $h->{Callbacks}{method_name};
  $h->{Callbacks}{method_name} = sub {
    if ($prev_cb) {
        my @result = $prev_cb->(@_);
	return @result if not $_; # $prev_cb vetoed call
    }
    ... your callback logic here ...
  };

=head3 C<private_your_module_name_*>

The DBI provides a way to store extra information in a DBI handle as
"private" attributes. The DBI will allow you to store and retrieve any
attribute which has a name starting with "C<private_>".

It is I<strongly> recommended that you use just I<one> private
attribute (e.g., use a hash ref) I<and> give it a long and unambiguous
name that includes the module or application name that the attribute
relates to (e.g., "C<private_YourFullModuleName_thingy>").

Because of the way the Perl tie mechanism works you cannot reliably
use the C<||=> operator directly to initialise the attribute, like this:

  my $foo = $dbh->{private_yourmodname_foo} ||= { ... }; # WRONG

you should use a two step approach like this:

  my $foo = $dbh->{private_yourmodname_foo};
  $foo ||= $dbh->{private_yourmodname_foo} = { ... };

This attribute is primarily of interest to people sub-classing DBI,
or for applications to piggy-back extra information onto DBI handles.

=head1 DBI DATABASE HANDLE OBJECTS

This section covers the methods and attributes associated with
database handles.

=head2 Database Handle Methods

The following methods are specified for DBI database handles:

=head3 C<clone>

  $new_dbh = $dbh->clone(\%attr);

The C<clone> method duplicates the $dbh connection by connecting
with the same parameters ($dsn, $user, $password) as originally used.

The attributes for the cloned connect are the same as those used
for the I<original> connect, with any other attributes in C<\%attr>
merged over them.  Effectively the same as doing:

  %attributes_used = ( %original_attributes, %attr );



( run in 1.778 second using v1.01-cache-2.11-cpan-5837b0d9d2c )