]> git.donarmstrong.com Git - infobot.git/commitdiff
- unify db_mysql and db_pgsql (thus remove db_pgsql.pl) into dbi.pl
authordms <dms@c11ca15a-4712-0410-83d8-924469b57eb5>
Thu, 21 Nov 2002 13:21:31 +0000 (13:21 +0000)
committerdms <dms@c11ca15a-4712-0410-83d8-924469b57eb5>
Thu, 21 Nov 2002 13:21:31 +0000 (13:21 +0000)
- rename db_dbm.pl to dbm.pl

git-svn-id: https://svn.code.sf.net/p/infobot/code/trunk@652 c11ca15a-4712-0410-83d8-924469b57eb5

blootbot/src/db_dbm.pl [deleted file]
blootbot/src/db_mysql.pl [deleted file]
blootbot/src/db_pgsql.pl [deleted file]
blootbot/src/dbi.pl [new file with mode: 0644]
blootbot/src/dbm.pl [new file with mode: 0644]

diff --git a/blootbot/src/db_dbm.pl b/blootbot/src/db_dbm.pl
deleted file mode 100644 (file)
index d702d9e..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-#
-#   db_dbm.pl: Extension on the factoid database.
-#  OrigAuthor: Kevin Lenzo  (c) 1997
-#  CurrAuthor: dms <dms@users.sourceforge.net>
-#     Version: v0.6 (20000707)
-#   FModified: 19991020
-#
-
-#package main;
-
-if (&::IsParam('useStrict')) { use strict;}
-
-use vars qw(%factoids %freshmeat %seen %rootwarn);     # db hash.
-
-{
-    my %formats = (
-       'factoids', [
-           'factoid_key',
-           'factoid_value',
-           'created_by',
-           'created_time',
-           'modified_by',
-           'modified_time',
-           'requested_by',
-           'requested_time',
-           'requested_count',
-           'locked_by',
-           'locked_time'
-       ],
-       'freshmeat', [
-           'projectname_short',
-           'latest_version',
-           'license',
-           'url_homepage',
-           'desc_short'
-       ],
-       'rootwarn', [
-           'nick',
-           'attempt',
-           'time',
-           'host',
-           'channel'
-       ],
-       'seen', [
-           'nick',
-           'time',
-           'channel',
-           'host',
-           'messagecount',
-           'hehcount',
-           'karma',
-           'message'
-       ],
-       'stats', [
-           'nick',
-           'type',
-           'counter',
-           'time'
-       ]
-    );
-
-    sub openDB {
-       my ($dbname) = @_;
-       use DB_File;
-       foreach $table (keys %formats) {
-           my $file = "$dbname-$table";
-           if (&::IsParam($table)) {
-               if (dbmopen(%{ $table }, $file, 0666)) {
-                   &::status("Opened DBM $table ($file).");
-               } else {
-                   &::ERROR("Failed open to DBM $table ($file).");
-                   &::shutdown();
-                   exit 1;
-               }
-           } else {
-               &::status("DBM $table ($file) disabled.");
-           }
-       }
-    }
-
-    sub closeDB {
-       foreach (keys %formats) {
-           next unless (&::IsParam($_));
-
-           if (dbmclose(%{ $_ })) {
-               &::status("Closed DBM $_ successfully.");
-               next;
-           }
-           &::ERROR("Failed closing DBM $_.");
-       }
-    }
-
-    #####
-    # Usage: &dbGetColInfo($table);
-    sub dbGetColInfo {
-       my ($table) = @_;
-
-       if (scalar @{$formats{$table}}) {
-           return @{$formats{$table}};
-       } else {
-           &::ERROR("dbGCI: no format for table ($table).");
-           return;
-       }
-    }
-}
-
-#####
-# Usage: &dbQuote($str);
-sub dbQuote {
-    return $_[0];
-}
-
-#####
-# Usage: &dbGet($table, $select, $where);
-sub dbGet {
-    my ($table, $select, $where) = @_;
-    my ($key, $val) = split('=',$where) if $where =~ /=/;
-    my $found = 0;
-    my @retval;
-    my $i;
-    &::DEBUG("dbGet($table, $select, $where);");
-    return unless $key;
-
-    my @format = &dbGetColInfo($table);
-    if (!scalar @format) {
-       return;
-    }
-
-    if (!defined ${ "$table" }{lc $val}) {     # dbm hash exception.
-       &::DEBUG("dbGet: '$val' does not exist in $table.");
-       return;
-    }
-
-    # return the whole row.
-    if ($select eq "*") {
-       @retval = split $;, ${"$table"}{lc $val};
-       unshift(@retval,$key);
-       return(@retval);
-    }
-
-    &::DEBUG("dbGet: select=>'$select'.");
-    my @array = split "$;", ${"$table"}{lc $val};
-    unshift(@array,$val);
-    for (0 .. $#format) {
-       my $str = $format[$_];
-       next unless (grep /^$str$/, split(/\,/, $select));
-       $array[$_] ||= '';
-       &::DEBUG("dG: '$format[$_]'=>'$array[$_]'.");
-       push(@retval, $array[$_]);
-    }
-
-    if (scalar @retval > 1) {
-       return @retval;
-    } elsif (scalar @retval == 1) {
-       return $retval[0];
-    } else {
-       return;
-    }
-}
-
-#####
-# Usage: &dbGetCol();
-# Usage: &dbGetCol($table, $select, $where, [$type]);
-sub dbGetCol {
-    my ($table, $select, $where, $type) = @_;
-    &::FIXME("STUB: &dbGetCol($table, $select, $where, $type);");
-}
-
-#####
-# Usage: &dbGetColNiceHash($table, $select, $where);
-sub dbGetColNiceHash {
-    my ($table, $select, $where) = @_;
-    &::DEBUG("dbGetColNiceHash($table, $select, $where);");
-    my ($key, $val) = split('=',$where) if $where =~ /=/;
-    return unless ${$table}{lc $val};
-    my (%hash) = ();
-    $hash{lc $key} = $val;
-    my (@format) = &dbGetColInfo($table);
-    shift @format;
-    @hash{@format} = split $;, ${$table}{lc $val};
-    return %hash;
-}
-
-#####
-# Usage: &dbInsert($table, $primkey, %hash);
-#  Note: dbInsert should do dbQuote.
-sub dbInsert {
-    my ($table, $primkey, %hash) = @_;
-    my $found = 0;
-    &::DEBUG("dbInsert($table, $primkey, ...)");
-
-    my $info = ${$table}{lc $primkey} || '';   # primkey or primval?
-
-    my @format = &dbGetColInfo($table);
-    if (!scalar @format) {
-       return 0;
-    }
-
-    my $i;
-    my @array = split $;, $info;
-    delete $hash{$format[0]};
-    for $i (1 .. $#format) {
-       my $col = $format[$i];
-       $array[$i - 1]=$hash{$col};
-       $array[$i - 1]='' unless $array[$i - 1];
-       delete $hash{$col};
-       &::DEBUG("dbI: '$col'=>'$array[$i - 1]'");
-    }
-
-    if (scalar keys %hash) {
-       &::ERROR("dbI: not added...");
-       foreach (keys %hash) {
-           &::ERROR("dbI: '$_'=>'$hash{$_}'");
-       }
-       return 0;
-    }
-
-    ${$table}{lc $primkey}     = join $;, @array;
-
-    return 1;
-}
-
-sub dbUpdate {
-    &::FIXME("STUB: &dbUpdate(@_);=>somehow use dbInsert!");
-}
-
-#####
-# Usage: &dbSetRow($table, @values);
-sub dbSetRow {
-    my ($table, @values) = @_;
-    &::DEBUG("dbSetRow(@_);");
-    my $key = lc $values[0];
-
-    my @format = &dbGetColInfo($table);
-    if (!scalar @format) {
-       return 0;
-    }
-
-    if (defined ${$table}{$key}) {
-       &::WARN("dbSetRow: $table {$key} already exists?");
-    }
-
-    if (scalar @values != scalar @format) {
-       &::WARN("dbSetRow: scalar values != scalar ${table} format.");
-    }
-
-    for (0 .. $#format) {
-       if (defined $array[$_] and $array[$_] ne "") {
-           &::DEBUG("dbSetRow: array[$_] != NULL($array[$_]).");
-       }
-       $array[$_] = $values[$_];
-    }
-
-    ${$table}{$key}    = join $;, @array;
-}
-
-#####
-# Usage: &dbDel($table, $primkey, $primval, [$key]);
-sub dbDel {
-    my ($table, $primkey, $primval, $key) = @_;
-    &::DEBUG("dbDel($table, $primkey, $primval);");
-
-    if (!defined ${$table}{lc $primval}) {
-       &::DEBUG("dbDel: lc $primval does not exist in $table.");
-    } else {
-       delete ${$table}{lc $primval};
-    }
-
-    return '';
-}
-
-#####
-# Usage: &dbReplace($table, $key, %hash);
-#  Note: dbReplace does optional dbQuote.
-sub dbReplace {
-    my ($table, $key, %hash) = @_;
-    &::DEBUG("dbReplace($table, $key, %hash);");
-
-    &dbDel($table, $key, $hash{$key}, %hash);
-    &dbInsert($table, $hash{$key}, %hash);
-    return 1;
-}
-
-#####
-# Usage: &dbSet($table, $primhash_ref, $hash_ref);
-sub dbSet {
-    my ($table, $phref, $href) = @_;
-    &::DEBUG("dbSet(@_)");
-    my ($key) = keys %{$phref};
-    my $where = $key . "=" . $phref->{$key};
-
-    my %hash = &dbGetColNiceHash($table, "*", $where);
-    $hash{$key}=$phref->{$key};
-    foreach (keys %{$href}) {
-       &::DEBUG("dbSet: setting $_=${$href}{$_}");
-       $hash{$_} = ${$href}{$_};
-    }
-    &dbReplace($table, $key, %hash);
-    return 1;
-}
-
-sub dbRaw {
-    &::FIXME("STUB: &dbRaw(@_);");
-}
-
-sub dbRawReturn {
-    &::FIXME("STUB: &dbRawReturn(@_);");
-}
-
-
-
-####################################################################
-##### Factoid related stuff...
-#####
-
-sub countKeys {
-    return scalar keys %{$_[0]};
-}
-
-sub getKeys {
-    return keys %{$_[0]};
-}
-
-sub randKey {
-    &::DEBUG("STUB: &randKey(@_);");
-    my ($table, $select) = @_;
-    my @format = &dbGetColInfo($table);
-    if (!scalar @format) {
-       return;
-    }
-
-    my $rand = int(rand(&countKeys($table) - 1));
-    my @keys = keys %{$table};
-    &dbGet($table, '$select', "$format[0]=$keys[$rand]");
-}
-
-#####
-# Usage: &deleteTable($table);
-sub deleteTable {
-    my ($table) = @_;
-    &::FIXME("STUB: deleteTable($table)");
-}
-
-##### $select is misleading???
-# Usage: &searchTable($table, $returnkey, $primkey, $str);
-sub searchTable {
-    my ($table, $primkey, $key, $str) = @_;
-    &::FIXME("STUB: searchTable($table, $primkey, $key, $str)");
-    return;
-    &::DEBUG("searchTable($table, $primkey, $key, $str)");
-
-    if (!scalar &dbGetColInfo($table)) {
-       return;
-    }   
-
-    my @results;
-    foreach (keys %{$table}) {
-       my $val = &dbGet($table, "NULL", $_, $key) || '';
-       next unless ($val =~ /\Q$str\E/);
-       push(@results, $_);
-    }
-
-    &::DEBUG("sT: ".scalar(@results) );
-
-    @results;
-}
-
-#####
-# Usage: &getFactInfo($faqtoid, $type);
-sub getFactInfo {
-    my ($faqtoid, $type) = @_;
-
-    my @format = &dbGetColInfo("factoids");
-    if (!scalar @format) {
-       return;
-    }
-
-    if (!defined $factoids{$faqtoid}) {        # dbm hash exception.
-       return;
-    }
-
-    if ($type eq "*") {                # all.
-       return split /$;/, $factoids{$faqtoid};
-    }
-
-    # specific.
-    if (!grep /^$type$/, @format) {
-       &::ERROR("gFI: type '$type' not valid for factoids.");
-       return;
-    }
-
-    my @array  = split /$;/, $factoids{$faqtoid};
-    for (0 .. $#format) {
-       next unless ($type eq $format[$_]);
-       return $array[$_];
-    }
-
-    &::ERROR("gFI: should never happen.");
-}   
-
-#####
-# Usage: &getFactoid($faqtoid);
-sub getFactoid {
-    my ($faqtoid) = @_;
-
-    if (!defined $faqtoid or $faqtoid =~ /^\s*$/) {
-       &::WARN("getF: faqtoid == NULL.");
-       return;
-    }
-
-    if (defined $factoids{$faqtoid}) { # dbm hash exception.
-       # we assume 1 unfortunately.
-       ### TODO: use &getFactInfo() instead?
-       my $retval = (split $;, $factoids{$faqtoid})[1];
-
-       if (defined $retval) {
-           &::DEBUG("getF: returning '$retval' for '$faqtoid'.");
-       } else {
-           &::DEBUG("getF: returning NULL for '$faqtoid'.");
-       }
-       return $retval;
-    } else {
-       return;
-    }
-}
-
-#####
-# Usage: &delFactoid($faqtoid);
-sub delFactoid {
-    my ($faqtoid) = @_;
-
-    if (!defined $faqtoid or $faqtoid =~ /^\s*$/) {
-       &::WARN("delF: faqtoid == NULL.");
-       return;
-    }
-
-    if (defined $factoids{$faqtoid}) { # dbm hash exception.
-       delete $factoids{$faqtoid};
-       &::status("DELETED $faqtoid");
-    } else {
-       &::WARN("delF: nothing to deleted? ($faqtoid)");
-       return;
-    }
-}
-
-sub checkTables {
-# nothing - DB_FIle will create them on openDB()
-}
-
-1;
diff --git a/blootbot/src/db_mysql.pl b/blootbot/src/db_mysql.pl
deleted file mode 100644 (file)
index 3343235..0000000
+++ /dev/null
@@ -1,555 +0,0 @@
-#
-# db_mysql.pl: MySQL database frontend.
-#      Author: dms
-#     Version: v0.2c (19991224)
-#     Created: 19991203
-#
-
-package main;
-
-if (&IsParam("useStrict")) { use strict; }
-
-#####
-# &openDB($dbname, $sqluser, $sqlpass, $nofail);
-sub openDB {
-    my ($db, $user, $pass, $no_fail) = @_;
-    my $dsn = "DBI:mysql:$db";
-    my $hoststr = "";
-    if (exists $param{'SQLHost'} and $param{'SQLHost'}) {
-       $dsn    .= ":$param{SQLHost}";
-       $hoststr = " to $param{'SQLHost'}";
-    }
-    $dbh    = DBI->connect($dsn, $user, $pass);
-
-    if ($dbh) {
-       &status("Opened MySQL connection$hoststr");
-    } else {
-       &ERROR("cannot connect$hoststr.");
-       &ERROR("since mysql is not available, shutting down bot!");
-       &closePID();
-       &closeSHM($shm);
-       &closeLog();
-
-       return if ($no_fail);
-
-       exit 1;
-    }
-}
-
-sub closeDB {
-    return 0 unless ($dbh);
-
-    my $hoststr = "";
-    $hoststr = " to $param{'SQLHost'}" if (exists $param{'SQLHost'});
-
-    &status("Closed MySQL connection$hoststr.");
-    $dbh->disconnect();
-
-    return 1;
-}
-
-#####
-# Usage: &dbQuote($str);
-sub dbQuote {
-    return $dbh->quote($_[0]);
-}
-
-#####
-# Usage: &dbGet($table, $select, $where);
-sub dbGet {
-    my ($table, $select, $where) = @_;
-    my $query  = "SELECT $select FROM $table";
-    $query     .= " WHERE $where" if ($where);
-
-    if (!defined $select or $select =~ /^\s*$/) {
-       &WARN("dbGet: select == NULL.");
-       return;
-    }
-
-    if (!defined $table or $table =~ /^\s*$/) {
-       &WARN("dbGet: table == NULL.");
-       return;
-    }
-
-    my $sth;
-    if (!($sth = $dbh->prepare($query))) {
-       &ERROR("Get: prepare: $DBI::errstr");
-       return;
-    }
-
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &ERROR("Get: execute: '$query'");
-       $sth->finish;
-       return 0;
-    }
-
-    my @retval = $sth->fetchrow_array;
-
-    $sth->finish;
-
-    if (scalar @retval > 1) {
-       return @retval;
-    } elsif (scalar @retval == 1) {
-       return $retval[0];
-    } else {
-       return;
-    }
-}
-
-#####
-# Usage: &dbGetCol($table, $select, $where, [$type]);
-sub dbGetCol {
-    my ($table, $select, $where, $type) = @_;
-    my $query  = "SELECT $select FROM $table";
-    $query     .= " WHERE ".$where if ($where);
-    my %retval;
-
-    my $sth = $dbh->prepare($query);
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &ERROR("GetCol: execute: '$query'");
-       $sth->finish;
-       return;
-    }
-
-    if (defined $type and $type == 2) {
-       &DEBUG("dbgetcol: type 2!");
-       while (my @row = $sth->fetchrow_array) {
-           $retval{$row[0]} = join(':', $row[1..$#row]);
-       }
-       &DEBUG("dbgetcol: count => ".scalar(keys %retval) );
-
-    } elsif (defined $type and $type == 1) {
-       while (my @row = $sth->fetchrow_array) {
-           # reverse it to make it easier to count.
-           if (scalar @row == 2) {
-               $retval{$row[1]}{$row[0]} = 1;
-           } elsif (scalar @row == 3) {
-               $retval{$row[1]}{$row[0]} = 1;
-           }
-           # what to do if there's only one or more than 3?
-       }
-
-    } else {
-       while (my @row = $sth->fetchrow_array) {
-           $retval{$row[0]} = $row[1];
-       }
-    }
-
-    $sth->finish;
-
-    return %retval;
-}
-
-#####
-# Usage: &dbGetColNiceHash($table, $select, $where);
-sub dbGetColNiceHash {
-    my ($table, $select, $where) = @_;
-    $select    ||= "*";
-    my $query  = "SELECT $select FROM $table";
-    $query     .= " WHERE ".$where if ($where);
-    my %retval;
-
-    my $sth = $dbh->prepare($query);
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &ERROR("GetColNiceHash: execute: '$query'");
-#      &ERROR("GetCol => $DBI::errstr");
-       $sth->finish;
-       return;
-    }
-
-    %retval = %{ $sth->fetchrow_hashref() };
-
-    $sth->finish;
-
-    return %retval;
-}
-
-####
-# Usage: &dbGetColInfo($table);
-sub dbGetColInfo {
-    my ($table) = @_;
-
-    my $query = "SHOW COLUMNS from $table";
-    my %retval;
-
-    my $sth = $dbh->prepare($query);
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &ERROR("GRI => '$query'");
-       &ERROR("GRI => $DBI::errstr");
-       $sth->finish;
-       return;
-    }
-
-    my @cols;
-    while (my @row = $sth->fetchrow_array) {
-       push(@cols, $row[0]);
-    }
-    $sth->finish;
-
-    return @cols;
-}
-
-#####
-# Usage: &dbSet($table, $primhash_ref, $hash_ref);
-#  Note: dbSet does dbQuote.
-sub dbSet {
-    my ($table, $phref, $href) = @_;
-    my $where = join(' AND ', map {
-               $_."=".&dbQuote($phref->{$_})
-       } keys %{$phref}
-    );
-
-    if (!defined $phref) {
-       &WARN("dbset: phref == NULL.");
-       return;
-    }
-
-    if (!defined $href) {
-       &WARN("dbset: href == NULL.");
-       return;
-    }
-
-    if (!defined $table) {
-       &WARN("dbset: table == NULL.");
-       return;
-    }
-
-    my $result = &dbGet($table, join(',', keys %{$phref}), $where);
-
-    my(@keys,@vals);
-    foreach (keys %{$href}) {
-       push(@keys, $_);
-       push(@vals, &dbQuote($href->{$_}) );
-    }
-
-    if (!@keys or !@vals) {
-       &WARN("dbset: keys or vals is NULL.");
-       return;
-    }
-
-    my $query;
-    if (defined $result) {
-       my @keyval;
-       for(my$i=0; $i<scalar @keys; $i++) {
-           push(@keyval, $keys[$i]."=".$vals[$i] );
-       }
-
-       $query = "UPDATE $table SET ".
-               join(' AND ', @keyval).
-               " WHERE ".$where;
-    } else {
-       foreach (keys %{$phref}) {
-           push(@keys, $_);
-           push(@vals, &dbQuote($phref->{$_}) );
-       }
-
-       $query = sprintf("INSERT INTO $table (%s) VALUES (%s)",
-               join(',',@keys), join(',',@vals) );
-    }
-
-    &dbRaw("Set", $query);
-
-    return 1;
-}
-
-#####
-# Usage: &dbUpdate($table, $primkey, $primval, %hash);
-#  Note: dbUpdate does dbQuote.
-sub dbUpdate {
-    my ($table, $primkey, $primval, %hash) = @_;
-    my (@array);
-
-    foreach (keys %hash) {
-       push(@array, "$_=".&dbQuote($hash{$_}) );
-    }
-
-    &dbRaw("Update", "UPDATE $table SET ".join(', ', @array).
-               " WHERE $primkey=".&dbQuote($primval)
-    );
-
-    return 1;
-}
-
-#####
-# Usage: &dbInsert($table, $primkey, %hash);
-#  Note: dbInsert does dbQuote.
-sub dbInsert {
-    my ($table, $primkey, %hash, $delay) = @_;
-    my (@keys, @vals);
-    my $p      = "";
-
-    if ($delay) {
-       &DEBUG("dbI: delay => $delay");
-       $p      = " DELAYED";
-    }
-
-    foreach (keys %hash) {
-       push(@keys, $_);
-       push(@vals, &dbQuote($hash{$_}));
-    }
-
-    &dbRaw("Insert($table)", "INSERT $p INTO $table (".join(',',@keys).
-               ") VALUES (".join(',',@vals).")"
-    );
-
-    return 1;
-}
-
-#####
-# Usage: &dbReplace($table, $key, %hash);
-#  Note: dbReplace does optional dbQuote.
-sub dbReplace {
-    my ($table, $key, %hash) = @_;
-    my (@keys, @vals);
-
-    foreach (keys %hash) {
-       if (s/^-//) {   # as is.
-           push(@keys, $_);
-           push(@vals, $hash{'-'.$_});
-       } else {
-           push(@keys, $_);
-           push(@vals, &dbQuote( $hash{$_} ));
-       }
-    }
-
-    if (0) {
-       &DEBUG("REPLACE INTO $table (".join(',',@keys).
-               ") VALUES (". join(',',@vals). ")" );
-    }
-
-    &dbRaw("Replace($table)", "REPLACE INTO $table (".join(',',@keys).
-               ") VALUES (". join(',',@vals). ")"
-    );
-
-    return 1;
-}
-
-#####
-# Usage: &dbSetRow($table, $vref, $delay);
-#  Note: dbSetRow does dbQuote.
-sub dbSetRow ($@$) {
-    my ($table, $vref, $delay) = @_;
-    my $p      = ($delay) ? " DELAYED " : "";
-
-    # see 'perldoc perlreftut'
-    my @values;
-    foreach (@{ $vref }) {
-       push(@values, &dbQuote($_) );
-    }
-
-    if (!scalar @values) {
-       &WARN("dbSetRow: values array == NULL.");
-       return;
-    }
-
-    return &dbRaw("SetRow", "INSERT $p INTO $table VALUES (".
-       join(",", @values) .")" );
-}
-
-#####
-# Usage: &dbDel($table, $primkey, $primval, [$key]);
-#  Note: dbDel does dbQuote
-sub dbDel {
-    my ($table, $primkey, $primval, $key) = @_;
-
-    &dbRaw("Del", "DELETE FROM $table WHERE $primkey=".
-               &dbQuote($primval)
-    );
-
-    return 1;
-}
-
-# Usage: &dbRaw($prefix,$rawquery);
-sub dbRaw {
-    my ($prefix,$query) = @_;
-    my $sth;
-
-    if (!($sth = $dbh->prepare($query))) {
-       &ERROR("Raw($prefix): $DBI::errstr");
-       return 0;
-    }
-
-#    &DEBUG("query => '$query'.");
-
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &ERROR("Raw($prefix): => '$query'");
-       # $DBI::errstr is printed as warning automatically.
-       $sth->finish;
-       return 0;
-    }
-
-    $sth->finish;
-
-    return 1;
-}
-
-# Usage: &dbRawReturn($rawquery);
-sub dbRawReturn {
-    my ($query) = @_;
-    my @retval;
-
-    my $sth = $dbh->prepare($query);
-    &SQLDebug($query);
-    &ERROR("RawReturn => '$query'.") unless $sth->execute;
-    while (my @row = $sth->fetchrow_array) {
-       push(@retval, $row[0]);
-    }
-    $sth->finish;
-
-    return @retval;
-}
-
-####################################################################
-##### Misc DBI stuff...
-#####
-
-#####
-# Usage: &countKeys($table, [$col]);
-sub countKeys {
-    my ($table, $col) = @_;
-    $col ||= "*";
-
-    return (&dbRawReturn("SELECT count($col) FROM $table"))[0];
-}
-
-# Usage: &sumKey($table, $col);
-sub sumKey {
-    my ($table, $col) = @_;
-
-    return (&dbRawReturn("SELECT sum($col) FROM $table"))[0];
-}
-
-#####
-# Usage: &randKey($table, $select);
-sub randKey {
-    my ($table, $select) = @_;
-    my $rand   = int(rand(&countKeys($table) - 1));
-    my $query  = "SELECT $select FROM $table LIMIT $rand,1";
-
-    my $sth    = $dbh->prepare($query);
-    &SQLDebug($query);
-    &WARN("randKey($query)") unless $sth->execute;
-    my @retval = $sth->fetchrow_array;
-    $sth->finish;
-
-    return @retval;
-}
-
-#####
-# Usage: &deleteTable($table);
-sub deleteTable {
-    &dbRaw("deleteTable($_[0])", "DELETE FROM $_[0]");
-}
-
-#####
-# Usage: &searchTable($table, $select, $key, $str);
-#  Note: searchTable does dbQuote.
-sub searchTable {
-    my($table, $select, $key, $str) = @_;
-    my $origStr = $str;
-    my @results;
-
-    # allow two types of wildcards.
-    if ($str =~ /^\^(.*)\$$/) {
-       &DEBUG("searchTable: should use dbGet(), heh.");
-       $str = $1;
-    } else {
-       $str .= "%"     if ($str =~ s/^\^//);
-       $str = "%".$str if ($str =~ s/\$$//);
-       $str = "%".$str."%" if ($str eq $origStr);      # el-cheapo fix.
-    }
-
-    $str =~ s/\_/\\_/g;
-    $str =~ s/\?/_/g;  # '.' should be supported, too.
-    $str =~ s/\*/%/g;  # for mysql.
-    # end of string fix.
-
-    my $query = "SELECT $select FROM $table WHERE $key LIKE ". 
-               &dbQuote($str);
-    my $sth = $dbh->prepare($query);
-
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &WARN("Search($query)");
-       return;
-    }
-
-    while (my @row = $sth->fetchrow_array) {
-       push(@results, $row[0]);
-    }
-    $sth->finish;
-
-    return @results;
-}
-
-sub dbCreateTable {
-    my($table) = @_;
-    my(@path)  = ($bot_data_dir, ".","..","../..");
-    my $found  = 0;
-    my $data;
-
-    foreach (@path) {
-       my $file = "$_/setup/$table.sql";
-       &DEBUG("dbCT: file => $file");
-       next unless ( -f $file );
-
-       &DEBUG("dbCT: found!!!");
-
-       open(IN, $file);
-       while (<IN>) {
-           chop;
-           $data .= $_;
-       }
-
-       $found++;
-       last;
-    }
-
-    if (!$found) {
-       return 0;
-    } else {
-       &dbRaw("createTable($table)", $data);
-       return 1;
-    }
-}
-
-sub checkTables {
-    my $database_exists = 0;
-    foreach ( &dbRawReturn("SHOW DATABASES") ) {
-       $database_exists++ if ($_ eq $param{'DBName'});
-    }
-
-    unless ($database_exists) {
-       &status("Creating database $param{DBName}...");
-       $query = "CREATE DATABASE $param{DBName}";
-       &dbRaw("create(db $param{DBName})", $query);
-    }
-
-    # retrieve a list of db's from the server.
-    my %db;
-    foreach ($dbh->func('_ListTables')) {
-       $db{$_} = 1;
-    }
-
-    # create database.
-    if (!scalar keys %db) {
-#      &status("Creating database $param{'DBName'}...");
-#      $query = "CREATE DATABASE $param{'DBName'}";
-#      &dbRaw("create(db $param{'DBName'})", $query);
-    }
-
-    foreach ("factoids", "freshmeat", "rootwarn", "seen", "stats",
-    ) {
-       next if (exists $db{$_});
-       &status("  creating new table $_...");
-
-       &dbCreateTable($_);
-    }
-}
-
-1;
diff --git a/blootbot/src/db_pgsql.pl b/blootbot/src/db_pgsql.pl
deleted file mode 100644 (file)
index f7d91ae..0000000
+++ /dev/null
@@ -1,469 +0,0 @@
-#
-# db_pgsql.pl: PostgreSQL database frontend.
-#      Author: dms
-#     Version: v0.2 (20010908)
-#     Created: 20000629
-#
-
-if (&IsParam("useStrict")) { use strict; }
-
-#####
-# openDB($dbname, $sqluser, $sqlpass, $nofail);
-sub openDB {
-    my($dbname, $sqluser, $sqlpass, $nofail) = @_;
-    my $connectstr = "dbi:Pg:dbname=$dbname;";
-    my $hoststr           = "";
-    if (exists $param{'SQLHost'} and $param{'SQLHost'}) {
-       $hoststr     = " to $param{'SQLHost'}";
-       $connectstr .= ";host=$param{SQLHost}";
-    }
-    $dbh = DBI->connect($connectstr, $sqluser, $sqlpass);
-
-    if ($dbh and !$dbh->err) {
-       &status("Opened pgSQL connection$hoststr");
-    } else {
-       &ERROR("cannot connect$hoststr.");
-       &ERROR("pgSQL: ".$dbh->errstr) if ($dbh);
-
-       &closePID();
-       &closeSHM($shm);
-       &closeLog();
-
-       return 0 if ($nofail);
-
-       exit 1;
-    }
-}
-
-sub closeDB {
-    return 0 unless ($dbh);
-
-    &status("Closed pgSQL connection.");
-    $dbh->disconnect();
-
-    return 1;
-}
-
-#####
-# Usage: &dbQuote($str);
-sub dbQuote {
-    return $dbh->quote($_[0]);
-
-    $_ = $_[0];
-    s/'/\\'/g;
-    return "'$_'";
-}
-
-#####
-# Usage: &dbGet($table, $select, $where);
-sub dbGet {
-    my ($table, $select, $where) = @_;
-    my $query  = "SELECT $select FROM $table";
-    $query     .= " WHERE $where" if ($where);
-
-    if (!defined $select) {
-       &WARN("dbGet: select == NULL. table => $table");
-       return;
-    }
-
-    my $sth;
-    if (!($sth = $dbh->prepare($query))) {
-       &ERROR("Get: prepare: $DBI::errstr");
-       return;
-    }
-
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &ERROR("Get: execute: '$query'");
-       $sth->finish;
-       return 0;
-    }
-
-    my @retval = $sth->fetchrow_array;
-
-    $sth->finish;
-
-    if (scalar @retval > 1) {
-       return @retval;
-    } elsif (scalar @retval == 1) {
-       return $retval[0];
-    } else {
-       return;
-    }
-}
-
-#####
-# Usage: &dbGetCol($table, $select, $where, [$type]);
-sub dbGetCol {
-    my ($table, $select, $where, $type) = @_;
-    my $query  = "SELECT $select FROM $table";
-    $query     .= " WHERE ".$where if ($where);
-    my %retval;
-
-    my $sth = $dbh->prepare($query);
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &ERROR("GetCol: execute: '$query'");
-       $sth->finish;
-       return;
-    }
-
-    if (defined $type and $type == 2) {
-       &DEBUG("dbgetcol: type 2!");
-       while (my @row = $sth->fetchrow_array) {
-           $retval{$row[0]} = join(':', $row[1..$#row]);
-       }
-       &DEBUG("dbgetcol: count => ".scalar(keys %retval) );
-
-    } elsif (defined $type and $type == 1) {
-       while (my @row = $sth->fetchrow_array) {
-           # reverse it to make it easier to count.
-           if (scalar @row == 2) {
-               $retval{$row[1]}{$row[0]} = 1;
-           } elsif (scalar @row == 3) {
-               $retval{$row[1]}{$row[0]} = 1;
-           }
-           # what to do if there's only one or more than 3?
-       }
-    } else {
-       while (my @row = $sth->fetchrow_array) {
-           $retval{$row[0]} = $row[1];
-       }
-    }
-
-    $sth->finish;
-
-    return %retval;
-}
-
-#####
-# Usage: &dbGetColNiceHash($table, $select, $where);
-sub dbGetColNiceHash {
-    my ($table, $select, $where) = @_;
-    $select    ||= "*";
-    my $query  = "SELECT $select FROM $table";
-    $query     .= " WHERE ".$where if ($where);
-    my %retval;
-
-    &DEBUG("dbGetColNiceHash: query => '$query'.");
-
-    my $sth = $dbh->prepare($query);
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &ERROR("GetColNiceHash: execute: '$query'");
-#      &ERROR("GetCol => $DBI::errstr");
-       $sth->finish;
-       return;
-    }
-
-    %retval = %{ $sth->fetchrow_hashref() };
-    $sth->finish;
-
-    return %retval;
-}
-
-####
-# Usage: &dbGetColInfo($table);
-sub dbGetColInfo {
-    my ($table) = @_;
-
-    my $query = "SELECT * FROM $table LIMIT 1;";
-#    my $query = "SHOW COLUMNS from $table";
-    my %retval;
-
-    my $sth = $dbh->prepare($query);
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &ERROR("GRI => '$query'");
-       &ERROR("GRI => $DBI::errstr");
-       $sth->finish;
-       return;
-    }
-
-    %retval = %{ $sth->fetchrow_hashref() };
-    $sth->finish;
-
-    return keys %retval;
-}
-
-#####
-# Usage: &dbSet($table, $primhash_ref, $hash_ref);
-#  Note: dbSet does dbQuote.
-sub dbSet {
-    my ($table, $phref, $href) = @_;
-    my $where = join(' AND ', map {
-               $_."=".&dbQuote($phref->{$_})
-       } keys %{$phref}
-    );
-
-    my $result = &dbGet($table, join(',', keys %{$phref}), $where);
-
-    my(@keys,@vals);
-    foreach (keys %{$href}) {
-       push(@keys, $_);
-       push(@vals, &dbQuote($href->{$_}) );
-    }
-
-    if (!@keys or !@vals) {
-       &WARN("dbset: keys or vals is NULL.");
-       return;
-    }
-
-    my $query;
-    if (defined $result) {
-       my @keyval;
-       for(my$i=0; $i<scalar @keys; $i++) {
-           push(@keyval, $keys[$i]."=".$vals[$i] );
-       }
-
-       $query = "UPDATE $table SET ".
-               join(' AND ', @keyval).
-               " WHERE $where";
-    } else {
-       foreach (keys %{$phref}) {
-           push(@keys, $_);
-           push(@vals, &dbQuote($phref->{$_}) );
-       }
-
-       $query = sprintf("INSERT INTO $table (%s) VALUES (%s)",
-               join(',',@keys), join(',',@vals) );
-    }
-
-    &dbRaw("Set", $query);
-
-    return 1;
-}
-
-#####
-# Usage: &dbUpdate($table, $primkey, $primval, %hash);
-sub dbUpdate {
-    my ($table, $primkey, $primval, %hash) = @_;
-    my (@array);
-    foreach (keys %hash) {
-       push(@array, "$_=".&dbQuote($hash{$_}) );
-    }
-
-    &dbRaw("Update", "UPDATE $table SET ".join(', ', @array).
-               " WHERE $primkey=".&dbQuote($primval)
-    );
-
-    return 1;
-}
-
-#####
-# Usage: &dbInsert($table, $primkey, $primval, %hash);
-sub dbInsert {
-    my ($table, $primkey, $primval, %hash) = @_;
-    my (@keys, @vals);
-
-    foreach (keys %hash) {
-       push(@keys, $_);
-       push(@vals, &dbQuote($hash{$_}));
-    }
-
-    &dbRaw("Insert($table)", "INSERT INTO $table (".join(',',@keys).
-               ") VALUES (".join(',',@vals).")"
-    );
-
-    return 1;
-}
-
-#####
-# Usage: &dbReplace($table, $key, %hash);
-#  Note: dbReplace does optional dbQuote.
-sub dbReplace {
-    my ($table, $key, %hash) = @_;
-    my (@keys, @vals);
-    my $where  = "WHERE $key=".&dbQuote($hash{$key});
-    my $squery = "SELECT $key FROM $table $where;";
-    my $iquery = "INSERT INTO $table ";
-    my $uquery = "UPDATE $table SET ";
-
-    foreach (keys %hash) {
-       if (s/^-//) {   # as is.
-           push(@keys, $_);
-           push(@vals, $hash{'-'.$_});
-       } else {
-           push(@keys, $_);
-           push(@vals, &dbQuote($hash{$_}));
-       }
-       $uquery .= "$keys[-1] = $vals[-1], ";
-    }
-    $uquery =~ s/, $/ $where;/;
-    $iquery .= "(". join(',',@keys) .") VALUES (". join(',',@vals) .");";
-
-    &DEBUG($squery) if (0);
-
-    if(&dbRawReturn($squery)) {
-       &dbRaw("Replace($table)", $uquery);
-    } else {
-       &dbRaw("Replace($table)", $iquery);
-     }
-
-
-    return 1;
-}
-
-##### MADE REDUNDANT BY LEAR.
-# Usage: &dbSetRow($table, $vref, $delay);
-#  Note: dbSetRow does dbQuote.
-sub dbSetRow ($@$) {
-    my ($table, $vref, $delay) = @_;
-    my $p      = ($delay) ? " DELAYED " : "";
-
-    # see 'perldoc perlreftut'
-    my @values;
-    foreach (@{ $vref }) {
-       push(@values, &dbQuote($_) );
-    }
-
-    if (!scalar @values) {
-       &WARN("dbSetRow: values array == NULL.");
-       return;
-    }
-
-    return &dbRaw("SetRow", "INSERT $p INTO $table VALUES (".
-       join(",", @values) .")" );
-}
-
-#####
-# Usage: &dbDel($table, $primkey, $primval, [$key]);
-#  Note: dbDel does dbQuote
-sub dbDel {
-    my ($table, $primkey, $primval, $key) = @_;
-
-    &dbRaw("Del", "DELETE FROM $table WHERE $primkey=".
-               &dbQuote($primval)
-    );
-
-    return 1;
-}
-
-# Usage: &dbRaw($prefix,$rawquery);
-sub dbRaw {
-    my ($prefix,$query) = @_;
-    my $sth;
-
-    if (!($sth = $dbh->prepare($query))) {
-       &ERROR("Raw($prefix): $DBI::errstr");
-       return 0;
-    }
-
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &ERROR("Raw($prefix): => '$query'");
-       $sth->finish;
-       return 0;
-    }
-
-    $sth->finish;
-
-    return 1;
-}
-
-# Usage: &dbRawReturn($rawquery);
-sub dbRawReturn {
-    my ($query) = @_;
-    my @retval;
-
-    my $sth = $dbh->prepare($query);
-    &SQLDebug($query);
-    &ERROR("RawReturn => '$query'.") unless $sth->execute;
-    while (my @row = $sth->fetchrow_array) {
-       push(@retval, $row[0]);
-    }
-    $sth->finish;
-
-    return @retval;
-}
-
-####################################################################
-##### Misc DBI stuff...
-#####
-
-#####
-# Usage: &countKeys($table, [$col]);
-sub countKeys {
-    my ($table, $col) = @_;
-    $col ||= "*";
-
-    return (&dbRawReturn("SELECT count($col) FROM $table"))[0];
-}
-
-# Usage: &sumKey($table, $col);
-sub sumKey {
-    my ($table, $col) = @_;
-
-    return (&dbRawReturn("SELECT sum($col) FROM $table"))[0];
-}
-
-#####
-# Usage: &randKey($table, $select);
-sub randKey {
-    my ($table, $select) = @_;
-    my $rand   = int(rand(&countKeys($table) - 1));
-    my $query  = "SELECT $select FROM $table LIMIT 1,$rand";
-
-    my $sth    = $dbh->prepare($query);
-    &SQLDebug($query);
-    &WARN("randKey($query)") unless $sth->execute;
-    my @retval = $sth->fetchrow_array;
-    $sth->finish;
-
-    return @retval;
-}
-
-#####
-# Usage: &deleteTable($table);
-sub deleteTable {
-    &dbRaw("deleteTable($_[0])", "DELETE FROM $_[0]");
-}
-
-#####
-# Usage: &searchTable($table, $select, $key, $str);
-#  Note: searchTable does dbQuote.
-sub searchTable {
-    my($table, $select, $key, $str) = @_;
-    my $origStr = $str;
-    my @results;
-
-    # allow two types of wildcards.
-    if ($str =~ /^\^(.*)\$$/) {
-       &DEBUG("searchTable: should use dbGet(), heh.");
-       $str = $1;
-    } else {
-       $str .= "%"     if ($str =~ s/^\^//);
-       $str = "%".$str if ($str =~ s/\$$//);
-       $str = "%".$str."%" if ($str eq $origStr);      # el-cheapo fix.
-    }
-
-    $str =~ s/\_/\\_/g;
-    $str =~ s/\?/\_/g; # '.' should be supported, too.
-    # end of string fix.
-
-    my $query = "SELECT $select FROM $table WHERE $key LIKE ". 
-               &dbQuote($str);
-    my $sth = $dbh->prepare($query);
-    &SQLDebug($query);
-    if (!$sth->execute) {
-       &WARN("Search($query)");
-       return;
-    }
-
-    while (my @row = $sth->fetchrow_array) {
-       push(@results, $row[0]);
-    }
-    $sth->finish;
-
-    return @results;
-}
-
-#####
-#
-sub checkTables {
-    &FIXME("pgsql: checkTables(@_);");
-    return 1;
-}
-
-1;
diff --git a/blootbot/src/dbi.pl b/blootbot/src/dbi.pl
new file mode 100644 (file)
index 0000000..8d38b6a
--- /dev/null
@@ -0,0 +1,585 @@
+#
+#   dbi.pl: DBI (mysql/pgsql/sqlite) database frontend.
+#   Author: dms
+#  Version: v0.2c (19991224)
+#  Created: 19991203
+#    Notes: based on db_mysql.pl
+#
+
+use strict;
+
+use vars qw(%param);
+use vars qw($dbh $shm $bot_data_dir);
+
+package main;
+
+#####
+# &openDB($dbname, $dbtype, $sqluser, $sqlpass, $nofail);
+sub openDB {
+    my ($db, $type, $user, $pass, $no_fail) = @_;
+    # this is a mess. someone fix it, please.
+    if ($type =~ /^SQLite$/i) {
+       $db = "dbname=$db.sqlite";
+    } elsif ($type =~ /^pg/i) {
+       $db = "dbname=$db";
+       $type = "Pg";
+    }
+
+    my $dsn = "DBI:$type:$db";
+    my $hoststr = "";
+    # does sqlite support remote servers?
+    if (exists $param{'SQLHost'} and $param{'SQLHost'}) {
+       $dsn    .= ":$param{SQLHost}";
+       $hoststr = " to $param{'SQLHost'}";
+    }
+    $dbh    = DBI->connect($dsn, $user, $pass);
+
+    if ($dbh && !$dbh->err) {
+       &status("Opened $type connection$hoststr");
+    } else {
+       &ERROR("cannot connect$hoststr.");
+       &ERROR("since $type is not available, shutting down bot!");
+       &ERROR( $dbh->errstr ) if ($dbh);
+       &closePID();
+       &closeSHM($shm);
+       &closeLog();
+
+       return 0 if ($no_fail);
+
+       exit 1;
+    }
+}
+
+sub closeDB {
+    return 0 unless ($dbh);
+
+    my $x = $param{SQLHost};
+    my $hoststr = ($x) ? " to $x" : "";
+
+    &status("Closed DBI connection$hoststr.");
+    $dbh->disconnect();
+
+    return 1;
+}
+
+#####
+# Usage: &dbQuote($str);
+sub dbQuote {
+    return $dbh->quote($_[0]);
+}
+
+#####
+# Usage: &dbGet($table, $select, $where);
+sub dbGet {
+    my ($table, $select, $where) = @_;
+    my $query  = "SELECT $select FROM $table";
+    $query     .= " WHERE $where" if ($where);
+
+    if (!defined $select or $select =~ /^\s*$/) {
+       &WARN("dbGet: select == NULL.");
+       return;
+    }
+
+    if (!defined $table or $table =~ /^\s*$/) {
+       &WARN("dbGet: table == NULL.");
+       return;
+    }
+
+    my $sth;
+    if (!($sth = $dbh->prepare($query))) {
+       &ERROR("Get: prepare: $DBI::errstr");
+       return;
+    }
+
+    &SQLDebug($query);
+    if (!$sth->execute) {
+       &ERROR("Get: execute: '$query'");
+       $sth->finish;
+       return 0;
+    }
+
+    my @retval = $sth->fetchrow_array;
+
+    $sth->finish;
+
+    if (scalar @retval > 1) {
+       return @retval;
+    } elsif (scalar @retval == 1) {
+       return $retval[0];
+    } else {
+       return;
+    }
+}
+
+#####
+# Usage: &dbGetCol($table, $select, $where, [$type]);
+sub dbGetCol {
+    my ($table, $select, $where, $type) = @_;
+    my $query  = "SELECT $select FROM $table";
+    $query     .= " WHERE ".$where if ($where);
+    my %retval;
+
+    my $sth = $dbh->prepare($query);
+    &SQLDebug($query);
+    if (!$sth->execute) {
+       &ERROR("GetCol: execute: '$query'");
+       $sth->finish;
+       return;
+    }
+
+    if (defined $type and $type == 2) {
+       &DEBUG("dbgetcol: type 2!");
+       while (my @row = $sth->fetchrow_array) {
+           $retval{$row[0]} = join(':', $row[1..$#row]);
+       }
+       &DEBUG("dbgetcol: count => ".scalar(keys %retval) );
+
+    } elsif (defined $type and $type == 1) {
+       while (my @row = $sth->fetchrow_array) {
+           # reverse it to make it easier to count.
+           if (scalar @row == 2) {
+               $retval{$row[1]}{$row[0]} = 1;
+           } elsif (scalar @row == 3) {
+               $retval{$row[1]}{$row[0]} = 1;
+           }
+           # what to do if there's only one or more than 3?
+       }
+
+    } else {
+       while (my @row = $sth->fetchrow_array) {
+           $retval{$row[0]} = $row[1];
+       }
+    }
+
+    $sth->finish;
+
+    return %retval;
+}
+
+#####
+# Usage: &dbGetColNiceHash($table, $select, $where);
+sub dbGetColNiceHash {
+    my ($table, $select, $where) = @_;
+    $select    ||= "*";
+    my $query  = "SELECT $select FROM $table";
+    $query     .= " WHERE ".$where if ($where);
+    my %retval;
+
+    my $sth = $dbh->prepare($query);
+    &SQLDebug($query);
+    if (!$sth->execute) {
+       &ERROR("GetColNiceHash: execute: '$query'");
+#      &ERROR("GetCol => $DBI::errstr");
+       $sth->finish;
+       return;
+    }
+
+    %retval = %{ $sth->fetchrow_hashref() };
+
+    $sth->finish;
+
+    return %retval;
+}
+
+####
+# Usage: &dbGetColInfo($table);
+sub dbGetColInfo {
+    my ($table) = @_;
+
+    my $query = "SHOW COLUMNS from $table";
+    if ($param{DBType} =~ /^pg/i) {
+       $query = "SELECT * FROM $table LIMIT 1";
+    }
+
+    my %retval;
+
+    my $sth = $dbh->prepare($query);
+    &SQLDebug($query);
+    if (!$sth->execute) {
+       &ERROR("GRI => '$query'");
+       &ERROR("GRI => $DBI::errstr");
+       $sth->finish;
+       return;
+    }
+
+    my @cols;
+    while (my @row = $sth->fetchrow_array) {
+       push(@cols, $row[0]);
+    }
+    $sth->finish;
+
+    return @cols;
+}
+
+#####
+# Usage: &dbSet($table, $primhash_ref, $hash_ref);
+#  Note: dbSet does dbQuote.
+sub dbSet {
+    my ($table, $phref, $href) = @_;
+    my $where = join(' AND ', map {
+               $_."=".&dbQuote($phref->{$_})
+       } keys %{$phref}
+    );
+
+    if (!defined $phref) {
+       &WARN("dbset: phref == NULL.");
+       return;
+    }
+
+    if (!defined $href) {
+       &WARN("dbset: href == NULL.");
+       return;
+    }
+
+    if (!defined $table) {
+       &WARN("dbset: table == NULL.");
+       return;
+    }
+
+    my $result = &dbGet($table, join(',', keys %{$phref}), $where);
+
+    my(@keys,@vals);
+    foreach (keys %{$href}) {
+       push(@keys, $_);
+       push(@vals, &dbQuote($href->{$_}) );
+    }
+
+    if (!@keys or !@vals) {
+       &WARN("dbset: keys or vals is NULL.");
+       return;
+    }
+
+    my $query;
+    if (defined $result) {
+       my @keyval;
+       for(my$i=0; $i<scalar @keys; $i++) {
+           push(@keyval, $keys[$i]."=".$vals[$i] );
+       }
+
+       $query = "UPDATE $table SET ".
+               join(' AND ', @keyval).
+               " WHERE ".$where;
+    } else {
+       foreach (keys %{$phref}) {
+           push(@keys, $_);
+           push(@vals, &dbQuote($phref->{$_}) );
+       }
+
+       $query = sprintf("INSERT INTO $table (%s) VALUES (%s)",
+               join(',',@keys), join(',',@vals) );
+    }
+
+    &dbRaw("Set", $query);
+
+    return 1;
+}
+
+#####
+# Usage: &dbUpdate($table, $primkey, $primval, %hash);
+#  Note: dbUpdate does dbQuote.
+sub dbUpdate {
+    my ($table, $primkey, $primval, %hash) = @_;
+    my (@array);
+
+    foreach (keys %hash) {
+       push(@array, "$_=".&dbQuote($hash{$_}) );
+    }
+
+    &dbRaw("Update", "UPDATE $table SET ".join(', ', @array).
+               " WHERE $primkey=".&dbQuote($primval)
+    );
+
+    return 1;
+}
+
+#####
+# Usage: &dbInsert($table, $primkey, %hash);
+#  Note: dbInsert does dbQuote.
+sub dbInsert {
+    my ($table, $primkey, %hash, $delay) = @_;
+    my (@keys, @vals);
+    my $p      = "";
+
+    if ($delay) {
+       &DEBUG("dbI: delay => $delay");
+       $p      = " DELAYED";
+    }
+
+    foreach (keys %hash) {
+       push(@keys, $_);
+       push(@vals, &dbQuote( $hash{$_} ));
+    }
+
+    &dbRaw("Insert($table)", "INSERT $p INTO $table (".join(',',@keys).
+               ") VALUES (".join(',',@vals).")"
+    );
+
+    return 1;
+}
+
+#####
+# Usage: &dbReplace($table, $key, %hash);
+#  Note: dbReplace does optional dbQuote.
+sub dbReplace {
+    my ($table, $key, %hash) = @_;
+    my (@keys, @vals);
+
+    foreach (keys %hash) {
+       if (s/^-//) {   # as is.
+           push(@keys, $_);
+           push(@vals, $hash{'-'.$_});
+       } else {
+           push(@keys, $_);
+           push(@vals, &dbQuote( $hash{$_} ));
+       }
+    }
+
+    # hrm... does pgsql support REPLACE?
+    # if not, well... fuck it.
+    &dbRaw("Replace($table)", "REPLACE INTO $table (".join(',',@keys).
+               ") VALUES (". join(',',@vals). ")"
+    );
+
+    return 1;
+}
+
+#####
+# Usage: &dbSetRow($table, $vref, $delay);
+#  Note: dbSetRow does dbQuote.
+sub dbSetRow ($@$) {
+    my ($table, $vref, $delay) = @_;
+    my $p      = ($delay) ? " DELAYED " : "";
+
+    # see 'perldoc perlreftut'
+    my @values;
+    foreach (@{ $vref }) {
+       push(@values, &dbQuote($_) );
+    }
+
+    if (!scalar @values) {
+       &WARN("dbSetRow: values array == NULL.");
+       return;
+    }
+
+    return &dbRaw("SetRow", "INSERT $p INTO $table VALUES (".
+       join(",", @values) .")" );
+}
+
+#####
+# Usage: &dbDel($table, $primkey, $primval, [$key]);
+#  Note: dbDel does dbQuote
+sub dbDel {
+    my ($table, $primkey, $primval, $key) = @_;
+
+    &dbRaw("Del", "DELETE FROM $table WHERE $primkey=".
+               &dbQuote($primval)
+    );
+
+    return 1;
+}
+
+# Usage: &dbRaw($prefix,$rawquery);
+sub dbRaw {
+    my ($prefix,$query) = @_;
+    my $sth;
+
+    if (!($sth = $dbh->prepare($query))) {
+       &ERROR("Raw($prefix): !prepare => '$query'");
+       return 0;
+    }
+
+    &SQLDebug($query);
+    if (!$sth->execute) {
+       &ERROR("Raw($prefix): !execute => '$query'");
+       $sth->finish;
+       return 0;
+    }
+
+    $sth->finish;
+
+    return 1;
+}
+
+# Usage: &dbRawReturn($rawquery);
+sub dbRawReturn {
+    my ($query) = @_;
+    my @retval;
+
+    my $sth = $dbh->prepare($query);
+    &SQLDebug($query);
+    # what happens when it can't execute it? does it throw heaps more
+    # error lines? if so. follow dbRaw()'s style.
+    &ERROR("RawReturn => '$query'.") unless $sth->execute;
+    while (my @row = $sth->fetchrow_array) {
+       push(@retval, $row[0]);
+    }
+    $sth->finish;
+
+    return @retval;
+}
+
+####################################################################
+##### Misc DBI stuff...
+#####
+
+#####
+# Usage: &countKeys($table, [$col]);
+sub countKeys {
+    my ($table, $col) = @_;
+    $col ||= "*";
+    &DEBUG("&countKeys($table, $col);");
+
+    return (&dbRawReturn("SELECT count($col) FROM $table"))[0];
+}
+
+#####
+# Usage: &sumKey($table, $col);
+sub sumKey {
+    my ($table, $col) = @_;
+
+    return (&dbRawReturn("SELECT sum($col) FROM $table"))[0];
+}
+
+#####
+# Usage: &randKey($table, $select);
+sub randKey {
+    my ($table, $select) = @_;
+    my $rand   = int(rand(&countKeys($table) - 1));
+    my $query  = "SELECT $select FROM $table LIMIT $rand,1";
+    if ($param{DBType} =~ /^pg/i) {
+       $query =~ s/$rand,1/1,$rand/;
+    }
+
+    my $sth    = $dbh->prepare($query);
+    &SQLDebug($query);
+    &WARN("randKey($query)") unless $sth->execute;
+    my @retval = $sth->fetchrow_array;
+    $sth->finish;
+
+    return @retval;
+}
+
+#####
+# Usage: &deleteTable($table);
+sub deleteTable {
+    &dbRaw("deleteTable($_[0])", "DELETE FROM $_[0]");
+}
+
+#####
+# Usage: &searchTable($table, $select, $key, $str);
+#  Note: searchTable does dbQuote.
+sub searchTable {
+    my($table, $select, $key, $str) = @_;
+    my $origStr = $str;
+    my @results;
+
+    # allow two types of wildcards.
+    if ($str =~ /^\^(.*)\$$/) {
+       &DEBUG("searchTable: should use dbGet(), heh.");
+       $str = $1;
+    } else {
+       $str .= "%"     if ($str =~ s/^\^//);
+       $str = "%".$str if ($str =~ s/\$$//);
+       $str = "%".$str."%" if ($str eq $origStr);      # el-cheapo fix.
+    }
+
+    $str =~ s/\_/\\_/g;
+    $str =~ s/\?/_/g;  # '.' should be supported, too.
+    $str =~ s/\*/%/g;
+    # end of string fix.
+
+    my $query = "SELECT $select FROM $table WHERE $key LIKE ". 
+               &dbQuote($str);
+    my $sth = $dbh->prepare($query);
+
+    &SQLDebug($query);
+    if (!$sth->execute) {
+       &WARN("Search($query)");
+       $sth->finish;
+       return;
+    }
+
+    while (my @row = $sth->fetchrow_array) {
+       push(@results, $row[0]);
+    }
+    $sth->finish;
+
+    return @results;
+}
+
+sub dbCreateTable {
+    my($table) = @_;
+    my(@path)  = ($bot_data_dir, ".","..","../..");
+    my $found  = 0;
+    my $data;
+
+    foreach (@path) {
+       my $file = "$_/setup/$table.sql";
+       &DEBUG("dbCT: table => '$table', file => '$file'");
+       next unless ( -f $file );
+
+       &DEBUG("dbCT: found!!!");
+
+       open(IN, $file);
+       while (<IN>) {
+           chop;
+           $data .= $_;
+       }
+
+       $found++;
+       last;
+    }
+
+    if (!$found) {
+       return 0;
+    } else {
+       &dbRaw("dbcreateTable($table)", $data);
+       return 1;
+    }
+}
+
+sub checkTables {
+    my $database_exists = 0;
+    my %db;
+
+    if ($param{DBType} =~ /^mysql$/i) {
+       my $sql = "SHOW DATABASES";
+       foreach ( &dbRawReturn($sql) ) {
+           $database_exists++ if ($_ eq $param{'DBName'});
+       }
+
+       unless ($database_exists) {
+           &status("Creating database $param{DBName}...");
+           my $query = "CREATE DATABASE $param{DBName}";
+           &dbRaw("create(db $param{DBName})", $query);
+       }
+
+       # retrieve a list of db's from the server.
+       foreach ($dbh->func('_ListTables')) {
+           $db{$_} = 1;
+       }
+
+    } elsif ($param{DBType} =~ /^SQLite$/i) {
+
+       # retrieve a list of db's from the server.
+       foreach ( &dbRawReturn("SELECT name FROM sqlite_master WHERE type='table'") ) {
+           $db{$_} = 1;
+       }
+
+       # create database.
+       if (!scalar keys %db) {
+           &status("Creating database $param{'DBName'}...");
+           my $query = "CREATE DATABASE $param{'DBName'}";
+           &dbRaw("create(db $param{'DBName'})", $query);
+       }
+    }
+
+    foreach ( qw(factoids freshmeat rootwarn seen stats) ) {
+       next if (exists $db{$_});
+       &status("checkTables: creating new table $_...");
+
+       &dbCreateTable($_);
+    }
+}
+
+1;
diff --git a/blootbot/src/dbm.pl b/blootbot/src/dbm.pl
new file mode 100644 (file)
index 0000000..b5067b6
--- /dev/null
@@ -0,0 +1,449 @@
+#
+#      dbm.pl: Extension on the factoid database.
+#  OrigAuthor: Kevin Lenzo  (c) 1997
+#  CurrAuthor: dms <dms@users.sourceforge.net>
+#     Version: v0.6 (20000707)
+#   FModified: 19991020
+#
+
+use strict;
+
+package main;
+
+use vars qw(%factoids %param);
+
+{
+    my %formats = (
+       'factoids', [
+           'factoid_key',
+           'factoid_value',
+           'created_by',
+           'created_time',
+           'modified_by',
+           'modified_time',
+           'requested_by',
+           'requested_time',
+           'requested_count',
+           'locked_by',
+           'locked_time'
+       ],
+       'freshmeat', [
+           'projectname_short',
+           'latest_version',
+           'license',
+           'url_homepage',
+           'desc_short'
+       ],
+       'rootwarn', [
+           'nick',
+           'attempt',
+           'time',
+           'host',
+           'channel'
+       ],
+       'seen', [
+           'nick',
+           'time',
+           'channel',
+           'host',
+           'messagecount',
+           'hehcount',
+           'karma',
+           'message'
+       ],
+       'stats', [
+           'nick',
+           'type',
+           'counter',
+           'time'
+       ]
+    );
+
+    sub openDB {
+       use DB_File;
+       foreach (keys %formats) {
+           next unless (&IsParam($_));
+
+           my $file = "$param{'DBName'}-$_";
+
+           if (dbmopen(%{ $_ }, $file, 0666)) {
+               &status("Opened DBM $_ ($file).");
+           } else {
+               &ERROR("Failed open to DBM $_ ($file).");
+               &shutdown();
+               exit 1;
+           }
+       }
+    }
+
+    sub closeDB {
+       foreach (keys %formats) {
+           next unless (&IsParam($_));
+
+           if (dbmclose(%{ $_ })) {
+               &status("Closed DBM $_ successfully.");
+               next;
+           }
+           &ERROR("Failed closing DBM $_.");
+       }
+    }
+
+    #####
+    # Usage: &dbGetColInfo($table);
+    sub dbGetColInfo {
+       my ($table) = @_;
+
+       if (scalar @{$formats{$table}}) {
+           return @{$formats{$table}};
+       } else {
+           &ERROR("dbGCI: no format for table ($table).");
+           return;
+       }
+    }
+}
+
+#####
+# Usage: &dbQuote($str);
+sub dbQuote {
+    return $_[0];
+}
+
+#####
+# Usage: &dbGet($table, $select, $where);
+sub dbGet {
+    my ($table, $select, $where) = @_;
+    my ($key, $val) = split('=',$where) if $where =~ /=/;
+    my $found = 0;
+    my @retval;
+    my $i;
+    &DEBUG("dbGet($table, $select, $where);");
+    return unless $key;
+
+    my @format = &dbGetColInfo($table);
+    if (!scalar @format) {
+       return;
+    }
+
+    if (!defined ${ "$table" }{lc $val}) {     # dbm hash exception.
+       &DEBUG("dbGet: '$val' does not exist in $table.");
+       return;
+    }
+
+    # return the whole row.
+    if ($select eq "*") {
+       @retval = split $;, ${"$table"}{lc $val};
+       unshift(@retval,$key);
+       return(@retval);
+    }
+
+    &DEBUG("dbGet: select=>'$select'.");
+    my @array = split "$;", ${"$table"}{lc $val};
+    unshift(@array,$val);
+    for (0 .. $#format) {
+       my $str = $format[$_];
+       next unless (grep /^$str$/, split(/\,/, $select));
+       $array[$_] ||= '';
+       &DEBUG("dG: '$format[$_]'=>'$array[$_]'.");
+       push(@retval, $array[$_]);
+    }
+
+    if (scalar @retval > 1) {
+       return @retval;
+    } elsif (scalar @retval == 1) {
+       return $retval[0];
+    } else {
+       return;
+    }
+}
+
+#####
+# Usage: &dbGetCol();
+# Usage: &dbGetCol($table, $select, $where, [$type]);
+sub dbGetCol {
+    my ($table, $select, $where, $type) = @_;
+    &FIXME("STUB: &dbGetCol($table, $select, $where, $type);");
+}
+
+#####
+# Usage: &dbGetColNiceHash($table, $select, $where);
+sub dbGetColNiceHash {
+    my ($table, $select, $where) = @_;
+    &DEBUG("dbGetColNiceHash($table, $select, $where);");
+    my ($key, $val) = split('=',$where) if $where =~ /=/;
+    return unless ${$table}{lc $val};
+    my (%hash) = ();
+    $hash{lc $key} = $val;
+    my (@format) = &dbGetColInfo($table);
+    shift @format;
+    @hash{@format} = split $;, ${$table}{lc $val};
+    return %hash;
+}
+
+#####
+# Usage: &dbInsert($table, $primkey, %hash);
+#  Note: dbInsert should do dbQuote.
+sub dbInsert {
+    my ($table, $primkey, %hash) = @_;
+    my $found = 0;
+    &DEBUG("dbInsert($table, $primkey, ...)");
+
+    my $info = ${$table}{lc $primkey} || '';   # primkey or primval?
+
+    my @format = &dbGetColInfo($table);
+    if (!scalar @format) {
+       return 0;
+    }
+
+    my $i;
+    my @array = split $;, $info;
+    delete $hash{$format[0]};
+    for $i (1 .. $#format) {
+       my $col = $format[$i];
+       $array[$i - 1]=$hash{$col};
+       $array[$i - 1]='' unless $array[$i - 1];
+       delete $hash{$col};
+       &DEBUG("dbI: '$col'=>'$array[$i - 1]'");
+    }
+
+    if (scalar keys %hash) {
+       &ERROR("dbI: not added...");
+       foreach (keys %hash) {
+           &ERROR("dbI: '$_'=>'$hash{$_}'");
+       }
+       return 0;
+    }
+
+    ${$table}{lc $primkey}     = join $;, @array;
+
+    return 1;
+}
+
+sub dbUpdate {
+    &FIXME("STUB: &dbUpdate(@_);=>somehow use dbInsert!");
+}
+
+#####
+# Usage: &dbSetRow($table, @values);
+sub dbSetRow {
+    my ($table, @values) = @_;
+    &DEBUG("dbSetRow(@_);");
+    my $key = lc $values[0];
+
+    my @format = &dbGetColInfo($table);
+    if (!scalar @format) {
+       return 0;
+    }
+
+    if (defined ${$table}{$key}) {
+       &WARN("dbSetRow: $table {$key} already exists?");
+    }
+
+    if (scalar @values != scalar @format) {
+       &WARN("dbSetRow: scalar values != scalar ${table} format.");
+    }
+
+    for (0 .. $#format) {
+       # @array? this is not defined anywhere. please fix, timriker!!!
+       if (defined $array[$_] and $array[$_] ne "") {
+           &DEBUG("dbSetRow: array[$_] != NULL($array[$_]).");
+       }
+       $array[$_] = $values[$_];
+    }
+
+    ${$table}{$key}    = join $;, @array;
+}
+
+#####
+# Usage: &dbDel($table, $primkey, $primval, [$key]);
+sub dbDel {
+    my ($table, $primkey, $primval, $key) = @_;
+    &DEBUG("dbDel($table, $primkey, $primval);");
+
+    if (!defined ${$table}{lc $primval}) {
+       &DEBUG("dbDel: lc $primval does not exist in $table.");
+    } else {
+       delete ${$table}{lc $primval};
+    }
+
+    return '';
+}
+
+#####
+# Usage: &dbReplace($table, $key, %hash);
+#  Note: dbReplace does optional dbQuote.
+sub dbReplace {
+    my ($table, $key, %hash) = @_;
+    &DEBUG("dbReplace($table, $key, %hash);");
+
+    &dbDel($table, $key, $hash{$key}, %hash);
+    &dbInsert($table, $hash{$key}, %hash);
+    return 1;
+}
+
+#####
+# Usage: &dbSet($table, $primhash_ref, $hash_ref);
+sub dbSet {
+    my ($table, $phref, $href) = @_;
+    &DEBUG("dbSet(@_)");
+    my ($key) = keys %{$phref};
+    my $where = $key . "=" . $phref->{$key};
+
+    my %hash = &dbGetColNiceHash($table, "*", $where);
+    $hash{$key}=$phref->{$key};
+    foreach (keys %{$href}) {
+       &DEBUG("dbSet: setting $_=${$href}{$_}");
+       $hash{$_} = ${$href}{$_};
+    }
+    &dbReplace($table, $key, %hash);
+    return 1;
+}
+
+sub dbRaw {
+    &FIXME("STUB: &dbRaw(@_);");
+}
+
+sub dbRawReturn {
+    &FIXME("STUB: &dbRawReturn(@_);");
+}
+
+
+
+####################################################################
+##### Factoid related stuff...
+#####
+
+sub countKeys {
+    return scalar keys %{$_[0]};
+}
+
+sub getKeys {
+    &FIXME("STUB: &getKeys(@_); -- REDUNDANT");
+}
+
+sub randKey {
+    &DEBUG("STUB: &randKey(@_);");
+    my ($table, $select) = @_;
+    my @format = &dbGetColInfo($table);
+    if (!scalar @format) {
+       return;
+    }
+
+    my $rand = int(rand(&countKeys($table) - 1));
+    my @keys = keys %{$table};
+    &dbGet($table, '$select', "$format[0]=$keys[$rand]");
+}
+
+#####
+# Usage: &deleteTable($table);
+sub deleteTable {
+    my ($table) = @_;
+    &FIXME("STUB: deleteTable($table)");
+}
+
+##### $select is misleading???
+# Usage: &searchTable($table, $returnkey, $primkey, $str);
+sub searchTable {
+    my ($table, $primkey, $key, $str) = @_;
+    &FIXME("STUB: searchTable($table, $primkey, $key, $str)");
+    return;
+    &DEBUG("searchTable($table, $primkey, $key, $str)");
+
+    if (!scalar &dbGetColInfo($table)) {
+       return;
+    }   
+
+    my @results;
+    foreach (keys %{$table}) {
+       my $val = &dbGet($table, "NULL", $_, $key) || '';
+       next unless ($val =~ /\Q$str\E/);
+       push(@results, $_);
+    }
+
+    &DEBUG("sT: ".scalar(@results) );
+
+    @results;
+}
+
+#####
+# Usage: &getFactInfo($faqtoid, $type);
+sub getFactInfo {
+    my ($faqtoid, $type) = @_;
+
+    my @format = &dbGetColInfo("factoids");
+    if (!scalar @format) {
+       return;
+    }
+
+    if (!defined $factoids{$faqtoid}) {        # dbm hash exception.
+       return;
+    }
+
+    if ($type eq "*") {                # all.
+       return split /$;/, $factoids{$faqtoid};
+    }
+
+    # specific.
+    if (!grep /^$type$/, @format) {
+       &ERROR("gFI: type '$type' not valid for factoids.");
+       return;
+    }
+
+    my @array  = split /$;/, $factoids{$faqtoid};
+    for (0 .. $#format) {
+       next unless ($type eq $format[$_]);
+       return $array[$_];
+    }
+
+    &ERROR("gFI: should never happen.");
+}   
+
+#####
+# Usage: &getFactoid($faqtoid);
+sub getFactoid {
+    my ($faqtoid) = @_;
+
+    if (!defined $faqtoid or $faqtoid =~ /^\s*$/) {
+       &WARN("getF: faqtoid == NULL.");
+       return;
+    }
+
+    if (defined $factoids{$faqtoid}) { # dbm hash exception.
+       # we assume 1 unfortunately.
+       ### TODO: use &getFactInfo() instead?
+       my $retval = (split $;, $factoids{$faqtoid})[1];
+
+       if (defined $retval) {
+           &DEBUG("getF: returning '$retval' for '$faqtoid'.");
+       } else {
+           &DEBUG("getF: returning NULL for '$faqtoid'.");
+       }
+       return $retval;
+    } else {
+       return;
+    }
+}
+
+#####
+# Usage: &delFactoid($faqtoid);
+sub delFactoid {
+    my ($faqtoid) = @_;
+
+    if (!defined $faqtoid or $faqtoid =~ /^\s*$/) {
+       &WARN("delF: faqtoid == NULL.");
+       return;
+    }
+
+    if (defined $factoids{$faqtoid}) { # dbm hash exception.
+       delete $factoids{$faqtoid};
+       &status("DELETED $faqtoid");
+    } else {
+       &WARN("delF: nothing to deleted? ($faqtoid)");
+       return;
+    }
+}
+
+sub checkTables {
+# nothing - DB_FIle will create them on openDB()
+}
+
+1;