package TTXMySQLSetup; # # This module is a part of Trouble Ticket Express package # http://www.troubleticketexpress.com # # COPYRIGHT: 2002-2006, United Web Coders # http://www.unitedwebcoders.com # # $Revision: 203 $ # $Date: 2006-07-18 00:28:33 -0400 (Tue, 18 Jul 2006) $ # $TTXMySQLSetup::VERSION='2.22'; BEGIN { $TTXMySQLSetup::REVISION = '$Revision: 203 $'; if ($TTXMySQLSetup::REVISION =~ /(\d+)/) { $TTXMySQLSetup::REVISION = $1; } }; use TTXConfig; require TTXUser; require TTXTickets; use strict; my $cfg = {}; my $query = {}; my $newdb; my $doimport; my $pwd; # ======================================================================= setup1 sub setup1 { $cfg = $_[0]; $query = $_[1]; my $error; $pwd = cleanit($query, 'pwd'); my $dbid = cleanit($query, 'dbid') || $cfg->get('dbid'); my $host = cleanit($query, 'host') || $cfg->get('dbhost') || 'localhost'; my $port = cleanit($query, 'port') || $cfg->get('dbport') || 3306; my $user = cleanit($query, 'user') || $cfg->get('dbuser'); my $pass = cleanit($query, 'pass') || $cfg->get('dbpass'); my $prefix = cleanit($query, 'prefix'); $prefix = $cfg->get('dbpref') if !$query->param('do'); my $imgurl = $cfg->get('imgurl'); # # Check if DBI module installed # eval "use DBI"; $error = "The DBI Perl library was not found on this server.
Please install DBI library prior to running this program." if $@; # # Check if MySQL DBD driver installed # if ($error eq undef) { my @drivers = DBI->available_drivers(1); $error = "The MySQL DBD driver was not found on this server.
Please install MySQL DBD driver prior to running this program." if !grep(/mysql/, @drivers); } if ($error eq undef && $query->param('do')) { $cfg->set('dbid', $dbid); $cfg->set('dbhost', $host); $cfg->set('dbport', $port); $cfg->set('dbuser', $user); $cfg->set('dbpass', $pass); $cfg->set('dbpref', $prefix); $doimport = 1 if $cfg->get('dbmode') ne 'mysql'; $error = build($cfg); if ($error eq undef) { eval "use TTXMySQLTickets"; if ($@) { $cfg->set('dbmode', 'plaintext'); } else { $cfg->set('dbmode', 'mysql'); $cfg->set('dbschema', '2.22'); } $cfg->save(); } } if ($query->param('do') && $error eq undef ) { ok(); return; } my $warning; if ($cfg->get('dbmode') eq 'mysql') { $warning = "YOU HAVE ALREADY ENABLED MYSQL MODE
\n". "THIS SCRIPT WILL RESET YOUR TICKETS DATABASE
\n". "ALL TICKETS SUBMITTED USING MYSQL MODE WILL BE LOST!"; } $error = "
Error: $error

" if $error ne undef; $warning = "\n
$warning

" if $warning ne undef; print <MySQL Module Setup
(go to Main Setup Utility form)
$error$warning

MySQL database access info. Please contact your hosting provider or system admin if not sure.

MySQL Host:  
MySQL Port:  
Database ID:  
MySQL User:  
MySQL Password:  
 

If you have access to a single database or would like to use existing database, you may provide a prefix, which will be added to the names of all the Trouble Ticket Express tables.

Table prefix (optional):  



Login to Trouble Ticket Express EOT } # =========================================================================== ok sub ok { print "
Congratulations!


\n"; if ($newdb) { print "You have created Trouble Ticket Express database and imported existing tickets.\n" } elsif ($doimport) { print "You have imported existing tickets into Trouble Ticket Express database.\n" } else { print "You are proud owner of the Trouble Ticket Express MySQL Edition.\n". "Please do not run database setup utility unless you want to make changes to the database settings.\n" } print "

\n"; if ($cfg->get('dbmode') ne 'mysql') { print <IMPORTANT Trouble Ticket Express still uses plain text database. Neither new tickets, nor follow-up messages to existing tickets will be added to the MySQL database. In order to enable MySQL features you must install a MySQL add-on module to your web server. The module may be ordered on-line at our web site. After uploading the MySQL add-on module to your web server, please run this script once more - it will update your MySQL database to ensure it includes recent data from your plain text database and will switch Trouble Ticket Express into MySQL mode.

Order MySQL add-on module


EOT } else { print "Trouble Ticket Express now uses MySQL database.

\n"; } print "
Main Setup Utility
". "Trouble Ticket Express
\n"; print "
\n"; } # ====================================================================== cleanit sub cleanit { my ($query, $input) = @_; my $val = $query->param($input); $val =~ s/^\s+//; $val =~ s/\s+$//; $query->param(-name => $input, -value => $val); return $val; } # ======================================================================== build sub build { my $cfg = $_[0]; $newdb = 0; my @manda = ('dbid', 'dbuser', 'dbpass'); my $id2name = { dbid => 'Database ID', dbuser => 'MySQL User ID', dbpass => 'MySQL User Password' }; my $error; foreach my $fld (@manda) { my $val = $cfg->get($fld); if ($val eq undef) { $error .= "Missing ".$id2name->{$fld}."
\n"; } } # # Step one - connect to mysql database engine # my $dsn = "DBI:mysql:database=".$cfg->get('dbid').";host=".$cfg->get('dbhost').";port=".$cfg->get('dbport'); my $dbh = DBI->connect($dsn, $cfg->get('dbuser'), $cfg->get('dbpass'), {RaiseError => 0, AutoCommit => 1}); if (!$dbh) { # got to check as to why if ($DBI::err !~ /\b1049\b/) { $error = "Error connecting to a database. $DBI::errstr"; return $error; } else { # Well, we are allowed to connect but database does not exist. # Will try to create... my $drh = DBI->install_driver('mysql'); if (!$drh) { $error = "Error loading mysql DBD driver. $DBI::errstr"; return $error; } my $rc = $drh->func('createdb', $cfg->get('dbid'), $cfg->get('dbhost'), $cfg->get('dbuser'), $cfg->get('dbpass'), 'admin'); if (!$rc) { $error = "Failed to create database '".$cfg->get('dbid')."'"; return $error; } $newdb = 1; $dbh = DBI->connect($dsn, $cfg->get('dbuser'), $cfg->get('dbpass'), {RaiseError => 0, AutoCommit => 1}); if (!$dbh) { $error = "Error connecting to a database. $DBI::errstr"; return $error; } } } # # Still alive? Good. Try to create tables now. # my $sth = $dbh->prepare("SHOW TABLES"); $sth->execute(); my %tables; while (my @row = $sth->fetchrow_array()) { $tables{$row[0]} = 1; } if (!$tables{$cfg->get('dbpref')."tickets"} && !$tables{$cfg->get('dbpref')."messages"}) { $doimport = 1; } elsif ($doimport) { $dbh->do("DROP TABLE ".$cfg->get('dbpref')."tickets") if $tables{$cfg->get('dbpref')."tickets"}; $dbh->do("DROP TABLE ".$cfg->get('dbpref')."messages") if $tables{$cfg->get('dbpref')."messages"}; $tables{$cfg->get('dbpref')."tickets"} = 0; $tables{$cfg->get('dbpref')."messages"} = 0; } foreach my $table ('tickets', 'messages') { if (!$tables{$cfg->get('dbpref').$table}) { $error = addtable($dbh, $cfg, $table); return $error if $error ne undef; } } # # Import data if needed # if ($doimport) { my @tickfields = TTXTickets::_fields(); my $boundary = TTXTickets::_boundary(); my $fn = $cfg->get('ticketdb'); return undef if ! -f $fn; return "Database import failed: error reading ticket database" if !open(DB, $fn); my @buff = ; close DB; chomp @buff; $| = 1; $dbh->do("SET AUTOCOMMIT=0;"); my $cmtcnt = 0; foreach my $line (@buff) { print "\n"; ++$cmtcnt; if ($cmtcnt > 99) { $dbh->do("COMMIT;"); $cmtcnt = 0; } my @fields = split(/\|/, $line); my %tik; my $sql = "INSERT IGNORE INTO ".$cfg->get('dbpref')."tickets VALUES("; my $values; foreach my $fld (@tickfields) { $tik{$fld} = shift @fields; $tik{$fld} = '' if $tik{$fld} eq undef; $values .= ',' if $values ne undef; if ($fld =~ /^(open|updated|closed)$/) { $values .= $dbh->quote(gmt($tik{$fld})); } else { $values .= $dbh->quote($tik{$fld}); } } $sql .= "$values)"; if (!$dbh->do($sql)) { $error = "Error importing ticket #"."$tik{id}. ".$dbh->errstr; last; } my $msgfn = $cfg->get('basedir')."/tickets/$tik{id}.cgi"; if (-f $msgfn && open(MSG, $msgfn)) { my $rawmsg; read(MSG, $rawmsg, 64*1024); close MSG; my @messages = split(/\n$boundary\n/, $rawmsg); foreach my $msg (@messages) { my @msgparts = split(/\n\n/, $msg); my $rawheader = shift @msgparts; my $body = join("\n\n", @msgparts); my @headerlines = split(/\n/, $rawheader); chomp @headerlines; my %header; foreach my $line (@headerlines) { if ($line =~ /^([a-zA-Z][a-zA-Z0-9-]*):\s*(.*)$/) { $header{uc $1} = $2; } } my $author = $header{FROM} || '-'; my $date = gmt($header{DATE}); my $internal = $header{INTERNAL} ? '1':'0'; my $isoper = $header{OPERATOR} ? '1':'0'; $rawheader = ''; foreach my $hdrkey (sort keys %header) { next if grep(/^$hdrkey$/, ('FROM', 'DATE', 'INTERNAL', 'BODY', 'OPERATOR')); $rawheader .= "$hdrkey: $header{$hdrkey}\n"; } if (!$dbh->do("INSERT IGNORE INTO ".$cfg->get('dbpref')."messages (TID, AUTHOR, DATE, ISOPER, INTERNAL, HEADERS, MSG) VALUES ". "('$tik{id}',".$dbh->quote($author).",'$date','$isoper','$internal',". $dbh->quote($rawheader).','.$dbh->quote($body).')')) { return "Error importing messages of ticket #"."$tik{id}. ".$dbh->errstr; } } } } $dbh->do("COMMIT"); } return $error; } # ========================================================================== gmt sub gmt { my $tm; if ($_[0] ne undef) { $tm = $_[0]; } else { $tm = time(); } my ($s, $min, $h, $d, $m, $y) = (gmtime($tm)); $y += 1900; ++$m; $m = "0$m" if $m < 10; $d = "0$d" if $d < 10; $h = "0$h" if $h < 10; $min = "0$min" if $min < 10; $s = "0$s" if $s < 10; return "$y-$m-$d $h:$min:$s"; } # ===================================================================== addtable sub addtable { my ($dbh, $cfg, $table) = @_; my $tablename = $cfg->get('dbpref').$table; my $sql; if ($table eq 'tickets') { $sql = <get('cfldcnt')); if (!$cfg->get('itemidx')) { $cfg->set('itemidx', ($cnt > 10) ? $cnt:10); $cfg->save(); } if ($cnt > 10) { my $i; for ($i = 10; $i < $cnt; ++$i) { $sql .= "ITEM varchar(255) DEFAULT '' NOT NULL,\n" if $i == $cfg->get('itemidx'); $sql .= "C$i varchar(255) DEFAULT '' NOT NULL,\n"; } $sql .= "ITEM varchar(255) DEFAULT '' NOT NULL,\n" if $i == $cfg->get('itemidx'); } else { $sql .= "ITEM varchar(255) DEFAULT '' NOT NULL,\n"; } $sql .= <do($sql)) { return "Error creating table $tablename, ".$dbh->errstr; } return undef; } 1; #