TABLE OF CONTENTS


SQL/connect [ Functions ]

[ Top ] [ Functions ]

FUNCTION

   Establish a connection to the database.

RESULT

   Handler to database object if a connection was made.

SOURCE

sub SQL::connect {
  my $dbtype = $settings{'dbtype'};
  my $dbname = $settings{'dbname'};
  my $dbhost = $settings{'dbhost'};
  my $dbuser = $settings{'dbuser'};
  my $dbpass = $settings{'dbpass'};

  my $dsn;

  # build DSN
  if ($dbtype eq "mysql") {
    $dsn = "DBI:mysql:database=$dbname;host=$dbhost";
  } elsif ($dbtype eq "postgresql") {
    $dsn = "DBI:Pg:dbname=$dbname;host=$dbhost";
  } elsif ($dbtype eq "sqlite") {
    $dsn = "DBI:SQLite:dbname=$dbname";
  }

  # connect to database
  my $new_dbh = DBI->connect($dsn, $dbuser, $dbpass)
    or die "ERROR: Could not connect to database.\n";

  return $new_dbh;
}

SQL/deinit [ Functions ]

[ Top ] [ Functions ]

FUNCTION

   Disconnect from the database.

RESULT

   True on success, false otherwise.

SOURCE

sub SQL::deinit {
  # disconnect from database
  my $rc = $dbh->disconnect();

  if (!$rc) {
    print "WARNING: Could not disconnect from database\n";
  }

  return $rc;
}

SQL/get_callbacks [ Functions ]

[ Top ] [ Functions ]

FUNCTION

   Return stack of eventhandlers.

SOURCE

sub SQL::get_callbacks {
  my $callbacks = {
    set_settings => \&SQL::set_settings,
    verify_settings => \&SQL::verify_settings,
    print_help => \&SQL::print_help,
    init => \&SQL::init,
    handle_event => \&SQL::handle_event,
    deinit => \&SQL::deinit
  };

  return $callbacks;
}

SQL/handle_event [ Functions ]

[ Top ] [ Functions ]

FUNCTION

   Wrapper function for processing line.

INPUTS

   year -- year in YYYY format, e.g. "2007"
   month -- month in MM format, e.g. "08"
   day -- day in DD format, e.g. "13"
   line_no -- line number in logfile, e.g. "210"
   type -- see constants in Common.pm
   time -- time in HH:MM[:SS] format, e.g. "14:48"
   nick -- nickname, e.g. "rjm"
   content -- in case of a message, the message itself, e.g. "hello world"

SOURCE

sub SQL::handle_event {
  my $year = shift @_;
  my $month = shift @_;
  my $day = shift @_;
  my ($line_no, $type, $time, $nick, $content) = @_;
  my $rows = 0;

  # add event
  if ($settings{'emulate'}) {
    SQL::emulate($year, $month, $day,
                 $line_no, $type,
                 $time, $nick, $content);
  }
  else {
    unless (SQL::record_exists("$year$month$day", $line_no)) {

      Debug::print("Adding new record (type=$type)");

      $rows = SQL::record_event($year, $month, $day,
                                $line_no, $type,
                                $time, $nick, $content);
    }
  }

  # process further if record was added
  if ($rows != 0) {

    # update wordlist
    if ($type eq Common::SAY) {
      WordList::update_wordlist($last_id, $content);
    }

    # check for URL in message
    my $url = URL::extract_url($content);

    # found URL, handle it
    if (defined($url)) {
      # TODO: spawn threads for network related operations
      SQL::post_process($year, $month, $day,
                        $line_no, $time, $nick,
                        $url);
    }

    $last_id++;
  }
}

SQL/init [ Functions ]

[ Top ] [ Functions ]

FUNCTION

   Connects to database, pass handler to others.

RESULT

   ID of record last added to the events table.

SOURCE

sub SQL::init {
  $dbh = SQL::connect();

  # pass the database handler along
  WordList::set_dbh($dbh);

  return SQL::set_lastid();
}

SQL/post_process [ Functions ]

[ Top ] [ Functions ]

FUNCTION

   Offloads work to Image and URL modules.

INPUTS

   year -- year in YYYY format, e.g. "2007"
   month -- month in MM format, e.g. "08"
   day -- day in DD format, e.g. "13"
   line_no -- line number in logfile, e.g. "210"
   time -- time in HH:MM[:SS] format, e.g. "14:48"
   nick -- nickname, e.g. "rjm"
   url -- url to record, e.g. "http://www.irc-collective.org/"

NOTES

   Candidate for rewrite; does it need a new connection?

SOURCE

sub SQL::post_process {
  my ($year, $month, $day, $line_no, $time, $nick, $url) = @_;

  # proceed if we could get a valid content type
  my $ct = URL::check_for_response($url);
  return unless defined($ct);

  my $new_dbh = SQL::connect();

  my $imagedir = $settings{'imagedir'};

  # continue processing url
  URL::process_url(
    $imagedir,
    $new_dbh,
    $year, $month, $day,
    $line_no, $time, $nick,
    $url, $ct
  );

  $new_dbh->disconnect();
}

SQL/print_help [ Functions ]

[ Top ] [ Functions ]

FUNCTION

   Prints help message for the SQL output handler module.

SOURCE

sub SQL::print_help {
  print << "SQL_HELP";
If using --output-handler=SQL also supply the following arguments:
         --dbname=xxx         name of the database to use
         --dbtype=xxx         set to either mysql, postgresql or sqlite
         --dbhost=xxx         hostname or IP address of the database server
         --dbuser=xxx
         --dbpass=xxx

Optional arguments for SQL output handler are:
     -p, --skip-pictures      do not process images
     -u, --skip-urls          do not process any url, also includes pictures
     -r, --no-mirror          do not mirror websites and pictures
     -t, --no-threads         do not use threading

SQL example:
  parselog --channel=glitch --directory=/home/irc/eggdrop/logs/
           --input-format=Eggdrop --output-handler=SQL
           --dbname=glitch_irc --dbtype=mysql --dbhost=localhost
           --dbuser=irc --dbpass=trinity

SQL_HELP
}

SQL/record_event [ Functions ]

[ Top ] [ Functions ]

FUNCTION

   Adds record to the database.

INPUTS

   year -- year in YYYY format, e.g. "2007"
   month -- month in MM format, e.g. "08"
   day -- day in DD format, e.g. "13"
   line_no -- line number in logfile, e.g. "210"
   type -- see constants in Common.pm
   time -- time in HH:MM[:SS] format, e.g. "14:48"
   nick -- nickname, e.g. "rjm"
   content -- in case of a message, the message itself, e.g. "hello world"

RESULT

   True if record was added, false otherwise.

SOURCE

sub SQL::record_event {
  my $year = shift @_;
  my $month = shift @_;
  my $day = shift @_;
  my ($line_no, $type, $time, $nick, $content) = @_;

  my $eventid = $last_id;
  my $date = "$year$month$day";

  my $sth = $dbh->prepare(
    qq[INSERT INTO events
       (eventid, date, line_no, time, nick, type, content)
       VALUES (?, ?, ?, ?, ?, ?, ?)]);

  $sth->execute(
    $eventid, $date, $line_no, $time, $nick, $type, $content
  ) or print "ERROR: Could not add to database: ", $dbh->errstr;

  $sth->finish;

  return $sth->rows;
}

SQL/record_exists [ Functions ]

[ Top ] [ Functions ]

FUNCTION

   Check if record is already present.

INPUTS

   date -- date in YYYYMMDD format, e.g. "20070813"
   line_no -- line number in logfile, e.g. "210"

RESULT

   True if record was found, false otherwise.

SOURCE

sub SQL::record_exists {
  my $date = shift;
  my $line_no = shift;

  my $sth = $dbh->prepare(qq[SELECT eventid
                             FROM events
                             WHERE date = ?
                             AND line_no = ?
                             LIMIT 1])
    or die "ERROR: Could not prepare statement: ", $dbh->errstr, "\n";

  $sth->execute($date, $line_no)
    or die "ERROR: Could not execute statement: ", $dbh->errstr, "\n";

  if ($sth->rows) {
    Debug::print("Event $date:$line_no already exists");
  }

  # returns true if record was found
  return $sth->rows;
}

SQL/set_lastid [ Functions ]

[ Top ] [ Functions ]

FUNCTION

   Retrieve and set last_id.

RESULT

   ID of record last added to the events table.

SOURCE

sub SQL::set_lastid {
  my $sth = $dbh->prepare(qq[SELECT MAX(eventid) AS lastid
                             FROM events])
    or die "ERROR: Could prepare statement: ", $dbh->errstr, "\n";

  $sth->execute
    or die "ERROR: Could not execute statement: ", $dbh->errstr, "\n";

  if ($sth->rows) {
    my $record = $sth->fetchrow_hashref;
    $last_id = $record->{lastid};
    $last_id++;
  } else {
    $last_id = 1;
  }

  $sth->finish;

  return $last_id;
}

SQL/verify_settings [ Functions ]

[ Top ] [ Functions ]

FUNCTION

   Checks if all required settings are supplied. 

SOURCE

sub SQL::verify_settings {

  if (not $settings{'dbtype'}
      or not $settings{'dbname'}
      or not $settings{'dbhost'}
      or not $settings{'dbuser'}
      or not $settings{'dbpass'} ) {
    print "ERROR: SQL output module does not have all the required ",
          "settings.\n Please see --help-modules or consult ",
          "the documentation for more information.\n\n";

    SQL::print_help();

    exit(0);
  }

  if ($settings{'emulate'}) {
    print "INFO: SQL outputhandler module is running in emulationmode.\n";
  }

}