]> git.donarmstrong.com Git - infobot.git/blobdiff - src/dbi.pl
* Fix previous patches missing "and" statements
[infobot.git] / src / dbi.pl
index 76954e70366df98f4393f550be4c988f7fa5cd4a..9e1a664eea7fe50b924c30f2bde786bcc4243012 100644 (file)
@@ -14,6 +14,55 @@ use vars qw($dbh $shm $bot_data_dir);
 
 package main;
 
+eval {
+     # This wrapper's sole purpose in life is to keep the dbh connection open.
+     package Bloot::DBI;
+
+     # These are DBI methods which do not require an active DB
+     # connection. [Eg, don't check to see if the database is working
+     # by pinging it for these methods.]
+     my %no_ping;
+     @no_ping{qw(ping err err_str quote disconnect clone)} = (1) x 6;
+     sub new {
+         my $class = shift;
+         my $dbh = shift;
+         return undef unless $dbh;
+         $class = ref($class) if ref($class);
+         my $self = {dbh=>$dbh};
+         bless $self, $class;
+         return $self;
+     }
+
+     our $AUTOLOAD;
+     sub AUTOLOAD {
+         my $method = $AUTOLOAD;
+         my $self = shift;
+         die "Undefined subroutine $method called" unless defined $self;
+         ($method) = $method =~ /([^\:]+)$/;
+         unshift @_, $self->{dbh};
+         return undef if not defined $self->{dbh};
+         goto &{$self->{dbh}->can($method)} if exists $no_ping{$method} and $no_ping{$method};
+         my $ping_count = 0;
+         while (++$ping_count < 10){
+              last if $self->{dbh}->ping;
+              $self->{dbh}->disconnect;
+              $self->{dbh} = $self->{dbh}->clone;
+         }
+         if ($ping_count >=10 and not $self->{dbh}->ping){
+              &ERROR("Tried real hard but was unable to reconnect");
+              return undef;
+         }
+         $_[0] = $self->{dbh};
+         my $coderef = $self->{dbh}->can($method);
+         goto &$coderef if defined $coderef;
+         # Dumb DBI doesn't have a can method for some
+         # functions. Like func.
+         shift;
+         return eval "\$self->{dbh}->$method(\@_)" or die $@;
+     }
+     1;
+};
+
 #####
 # &sqlOpenDB($dbname, $dbtype, $sqluser, $sqlpass, $nofail);
 sub sqlOpenDB {
@@ -23,15 +72,15 @@ sub sqlOpenDB {
        $db = "dbname=$db.sqlite";
     } elsif ($type =~ /^pg/i) {
        $db = "dbname=$db";
-       $type = "Pg";
+       $type = 'Pg';
     }
 
     my $dsn = "DBI:$type:$db";
-    my $hoststr = "";
+    my $hoststr = '';
     # SQLHost should be unset for SQLite
     if (exists $param{'SQLHost'} and $param{'SQLHost'}) {
-       # PostgreSQL requires ";" and keyword "host". See perldoc Pg -- troubled
-       if ($type eq "Pg") {
+       # PostgreSQL requires ";" and keyword 'host'. See perldoc Pg -- troubled
+       if ($type eq 'Pg') {
                $dsn    .= ";host=$param{SQLHost}";
        } else {
                $dsn    .= ":$param{SQLHost}";
@@ -39,7 +88,7 @@ sub sqlOpenDB {
        $hoststr = " to $param{'SQLHost'}";
     }
     # SQLite ignores $user and $pass
-    $dbh    = DBI->connect($dsn, $user, $pass);
+    $dbh    = Bloot::DBI->new(DBI->connect($dsn, $user, $pass));
 
     if ($dbh && !$dbh->err) {
        &status("Opened $type connection$hoststr");
@@ -61,7 +110,7 @@ sub sqlCloseDB {
     return 0 unless ($dbh);
 
     my $x = $param{SQLHost};
-    my $hoststr = ($x) ? " to $x" : "";
+    my $hoststr = ($x) ? " to $x" : '';
 
     &status("Closed DBI connection$hoststr.");
     $dbh->disconnect();
@@ -232,7 +281,7 @@ sub sqlSet {
        return;
     }
 
-    if (!defined $data_href or ref($data_href) ne "HASH") {
+    if (!defined $data_href or ref($data_href) ne 'HASH') {
        &WARN("sqlSet: data_href == NULL.");
        return;
     }
@@ -265,7 +314,7 @@ sub sqlSet {
 sub sqlUpdate {
     my ($table, $data_href, $where_href) = @_;
 
-    if (!defined $data_href or ref($data_href) ne "HASH") {
+    if (!defined $data_href or ref($data_href) ne 'HASH') {
        &WARN("sqlSet: data_href == NULL.");
        return 0;
     }
@@ -273,7 +322,7 @@ sub sqlUpdate {
     my $where  = &hashref2where($where_href) if ($where_href);
     my $update = &hashref2update($data_href) if ($data_href);
 
-    &sqlRaw("Update", "UPDATE $table SET $update WHERE $where");
+    &sqlRaw('Update', "UPDATE $table SET $update WHERE $where");
 
     return 1;
 }
@@ -282,10 +331,10 @@ sub sqlUpdate {
 # Usage: &sqlInsert($table, $data_href, $other);
 sub sqlInsert {
     my ($table, $data_href, $other) = @_;
-    # note: if $other == 1, add "DELAYED" to function instead.
+    # note: if $other == 1, add 'DELAYED' to function instead.
     # note: ^^^ doesnt actually do anything lol. Need code to s/1/DELAYED/ below -- troubled
 
-    if (!defined $data_href or ref($data_href) ne "HASH") {
+    if (!defined $data_href or ref($data_href) ne 'HASH') {
        &WARN("sqlInsert: data_href == NULL.");
        return;
     }
@@ -299,10 +348,12 @@ sub sqlInsert {
        return;
     }
 
-    return &sqlRaw("Insert($table)", sprintf(
+    &sqlRaw("Insert($table)", sprintf(
        "INSERT %s INTO %s (%s) VALUES (%s)",
-       ($other || ""), $table, join(',',@k), join(',',@v)
+       ($other || ''), $table, join(',',@k), join(',',@v)
     ) );
+
+    return 1;
 }
 
 #####
@@ -310,7 +361,7 @@ sub sqlInsert {
 sub sqlReplace {
     my ($table, $data_href, $pkey) = @_;
 
-    if (!defined $data_href or ref($data_href) ne "HASH") {
+    if (!defined $data_href or ref($data_href) ne 'HASH') {
        &WARN("sqlReplace: data_href == NULL.");
        return;
     }
@@ -339,7 +390,7 @@ sub sqlReplace {
        &WARN("DEBUG: ($pkey = ) " . sprintf(
                 "REPLACE INTO %s (%s) VALUES (%s)",
                 $table, join(',',@k), join(',',@v)
-        )); 
+        ));
 
     } else {
        &sqlRaw("Replace($table)", sprintf(
@@ -356,14 +407,14 @@ sub sqlReplace {
 sub sqlDelete {
     my ($table, $where_href) = @_;
 
-    if (!defined $where_href or ref($where_href) ne "HASH") {
+    if (!defined $where_href or ref($where_href) ne 'HASH') {
        &WARN("sqlDelete: where_href == NULL.");
        return;
     }
 
     my $where  = &hashref2where($where_href);
 
-    &sqlRaw("Delete", "DELETE FROM $table WHERE $where");
+    &sqlRaw('Delete', "DELETE FROM $table WHERE $where");
 
     return 1;
 }
@@ -443,7 +494,7 @@ sub hashref2where {
        return;
     }
 
-    if (ref($href) ne "HASH") {
+    if (ref($href) ne 'HASH') {
        &WARN("hashref2where: href is not HASH ref (href => $href)");
        return;
     }
@@ -466,7 +517,7 @@ sub hashref2where {
 sub hashref2update {
     my ($href) = @_;
 
-    if (ref($href) ne "HASH") {
+    if (ref($href) ne 'HASH') {
        &WARN("hashref2update: href is not HASH ref.");
        return;
     }
@@ -492,7 +543,7 @@ sub hashref2update {
 sub hashref2array {
     my ($href) = @_;
 
-    if (ref($href) ne "HASH") {
+    if (ref($href) ne 'HASH') {
        &WARN("hashref2update: href is not HASH ref.");
        return;
     }
@@ -520,7 +571,7 @@ sub hashref2array {
 # Usage: &countKeys($table, [$col]);
 sub countKeys {
     my ($table, $col) = @_;
-    $col ||= "*";
+    $col ||= '*';
 
     return (&sqlRawReturn("SELECT count($col) FROM $table"))[0];
 }
@@ -650,7 +701,7 @@ sub checkTables {
        my @tables = map {s/^\`//; s/\`$//; $_;} $dbh->func('_ListTables');
        if ($#tables == -1){
            @tables = $dbh->tables;
-       }
+        }
        &status("Tables: ".join(',',@tables));
        @db{@tables} = (1) x @tables;
 
@@ -687,8 +738,6 @@ sub checkTables {
         }
         &status("Tables: ".join(',',@tables));
         @db{@tables} = (1) x @tables;
-
     }
 
     foreach ( qw(botmail connections factoids rootwarn seen stats onjoin) ) {
@@ -706,3 +755,5 @@ sub checkTables {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80