package DbUtils; # A package containing utility code for interacting with databases. # Right now it only has code to manage connections to databases. # It "caches" the database handles in a hash. # # To use, your calling script looks like this: # # use strict; # use DbUtils; # # my $dbh = DbUtils::connect('mydb'); # # This module reads database user/password/DSN info from a file called # "pw.cgi" (or whatever you set for $pw_file). Create that file, # and put database connection info on lines that start with 3 pound signs # "###". After the 3 pound signs, put a string like this: # # DB:dbname DSN:dsn for this db USER:usename PW:password # # Put as many lines as you have databases to connect to. See below # for an example "pw.cgi" with info for 2 databases: # #STARTFILE # # #!/usr/bin/perl # # use strict; # use CGI; # # my $q = CGI->new; # print $q->redirect('http://faculty.washington.edu/joelg'); # # exit; # # Database information below here: # # ### DB:mydb DSN:dbi:mysql:mydb:mydbhost.com USER:username PW:password # ### DB:work DSN:dbi:mysql:workdb:mydbhost.com USER:workuser PW:password # #EOF # use strict; use DBI; # I have to cloak this password file as a CGI script so that people don't just # pull up the file directly in their browser to view the passwords. # You should/could also change file permissions on it. # You can also put this file in a separate folder from your WEBROOT, # then a web server can't see the file. I can't do that on this machine, # because of how the directories are mounted. my $pw_file = 'pw.cgi'; my %databases = _get_db_info(); my %dbhs = (); # db handle "cache" hash sub connect { my $db = shift; # do we already have a handle for this db? if ($dbhs{$db}) { return $dbhs{$db}; } else { # nope. create a handle, stash it in the cache, and return it. my $rh_db = $databases{$db} || die "Invalid db string '$db'!\n"; my $dbh = DBI->connect($rh_db->{dsn}, $rh_db->{user}, $rh_db->{pw}) or die "Can't connect to ". $rh_db->{dsn} . ": " . DBI::errstr; $dbhs{$db} = $dbh; return $dbh; } } sub _get_db_info { open (IN, $pw_file) or die "Can't open '$pw_file': $!"; my %databases = (); while (my $line = ) { chomp ($line); if ($line =~ /^### DB:(\w+)\s+DSN:([\w:\.]+)\s+USER:(\w+)\s+PW:(\w+)/) { $databases{$1} = { dsn => $2, user => $3, pw => $4 }; } } return %databases; } 1;