NAME
OpenInteract::DBIConnect - Centralized connection location to DBI databases
SYNOPSIS
# Just get a database handle from the info in your config
# (conf/server.perl)
my $db = OpenInteract::DBI->connect({
$CONFIG->{db_info}
});
DESCRIPTION
No, we do not subclass DBI with this. No, we do not override any of the DBI methods. Instead, we provide the means to connect to the database from one location along with the ability to manipulate the default connection information before we connect.
For instance, you can setup OpenInteract in two separate databases. When users of a certain name login (say, 'devel'), you can change the 'db_name' key of the database connection info hashref from 'webdb' to 'webdb-devel'.
Note that this should work flawlessly with Apache::DBI, and if you are using this on a different persistent Perl platform (say, PerlEx) then this module gives you a single location from which to retrieve database handles -- this makes using the BEGIN/END tricks ActiveState recommends in their FAQ pretty trivial.
METHODS
connect( \%connnect_info, \%params )
Usage:
my $db = eval { OpenInteract::DBI->connect({
$CONFIG->{db_info}
}) };
if ( $@ ) {
die "Cannot connect to database! Error found: $@";
}
my ( $sth );
eval {
$sth = $db->prepare( 'SELECT blah FROM bleh' );
$sth->execute;
};
...
Returns: A DBI database handle with the following parameters set:
RaiseError: 1
PrintError: 0
ChopBlanks: 1
AutoCommit: 1 (for now...)
The first parameter is a hashref of connection information. This should include:
dsn: the last part of a fully-formed DBI data source name used to connect to this database. Examples:
Full DBI DSN: DBI:mysql:webdb OpenInteract DSN: webdb Full DBI DSN: DBI:Sybase:server=SYBASE;database=web OpenInteract DSN: server=SYBASE;database=web
So the OpenInteract DSN string only includes the database-specific items for DBI, the third entry in the colon-separated string.This third item is generally separated by semicolons and usually specifies a database name, hostname, packet size, protocol version, etc. See your DBD driver for what to do.
db_name: the name of your database
username: what username should we use to login to this database?
password: what password should we use in combination with the username to login to this database?
driver_name: what DBD driver is used to connect to your database? (Examples: 'Sybase', 'mysql', 'Oracle')
db_owner: (optional) who owns this database?
The second parameter is also a hashref and can contain the following keys:
pre_connect: the coderef stored here is called before the database handle is requested, allowing you to modify any of the information in the first parameter before it is sent to DBI.
Takes the hashref of database connection info as its first parameter, and it must return a hashref of database connection info with the same conventions as the one passed in. Failure to do so means the changes are discarded.
post_connect: the coderef stored here is called after the database handle is requested and allows you to perform whatever actions on it that you like.
Takes the hashref of database connection info as its first parameter and the newly created database handle as its second parameter.
There currently is no return value for this callback -- primarily because I am not sure what it might be used for :-) Suggestions welcome!
Any errors encountered will result in an exception thrown via die
. Generally, there will be two errors:
Connect error: This means you cannot even connect to the database. This is generally a very serious error.
You can distinguish this by doing a match on the returned error string for
/^Connect failed:/
. Everything after this string is the actual error reported by DBI.Use database error: This means you connected to the database server, but were not able to 'use' your database. (If your database does not support the 'use' command, please contact the author.)
You can find this error by matching the returned error string on
/^Use database failed: /
. Everything after this string is the actual error reported by DBI.
Other errors may occur in your callbacks, but reporting them is entirely up to you. This class does not wrap the call in an eval {}
block so you can capture the error and inspect it yourself. After all, they are your callbacks.
STRATEGIES
Under mod_perl, you can use the simple connection-pooling module Apache::DBI. This module is quite simple -- it overrides the connect
call for DBI. For each connect
call made, it looks at the parameters (dsn, username, password and the DBI parameters) to determine whether it has connected to this database previously. If so, it returns the cached connection. If not, it creates the connection and caches it. This happens on a per-httpd-child basis, so if you have 10 httpd children you will have 10 concurrent connections to the database. Easy, right?
What happens if you are running multiple websites using one httpd child? Say you have five websites running on mod_perl process group which has the aforementioned 10 children. Since each website likely has its own database, you will eventually have 10 x 5 = 50
connections to your database. This can be a bad thing.
To get around this, and assuming that all of these websites connect to the database as the same user (which certainly is not a given), OpenInteract allows you to specify a single database for connection. Once the connection is handed out, OpenInteract will perform the SQL 'use' command to switch to the correct database.
The trigger for this is the 'db_name' key of the first parameter passed into the connect
method of this class. If this field is specified, the method will perform the following statement:
$dbh->do( "use $db_info->{db_name}" );
So that you only have to keep one connection for this database open all the time.
TO DO
Test with PerlEx
Try to use the BEGIN/END tricks ActiveState recommends -- do they work with just scripts, or also with modules?
BUGS
SEE ALSO
DBI - http://www.symbolstone.org/technology/perl/DBI
PerlEx - http://www.activestate.com/Products/PerlEx/index.html
COPYRIGHT
Copyright (c) 2001 intes.net, inc.. All rights reserved.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
AUTHORS
Chris Winters <chris@cwinters.com>
Marcus Baker <mbaker@intes.net>