base
This commit is contained in:
@@ -0,0 +1,472 @@
|
||||
package TTXMSSQLSetup;
|
||||
#
|
||||
# This module is a part of Trouble Ticket Express package
|
||||
# http://www.troubleticketexpress.com
|
||||
#
|
||||
# COPYRIGHT: 2005-2006, United Web Coders
|
||||
# http://www.unitedwebcoders.com
|
||||
#
|
||||
# $Revision: 203 $
|
||||
# $Date: 2006-07-18 00:28:33 -0400 (Tue, 18 Jul 2006) $
|
||||
#
|
||||
|
||||
$TTXMSSQLSetup::VERSION='2.22';
|
||||
BEGIN {
|
||||
$TTXMSSQLSetup::REVISION = '$Revision: 203 $';
|
||||
if ($TTXMSSQLSetup::REVISION =~ /(\d+)/) {
|
||||
$TTXMSSQLSetup::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 $dsn = cleanit($query, 'dbdsn1') || cleanit($query, 'dbdsn') || $cfg->get('dbdsn');
|
||||
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";
|
||||
if ($@ ne undef) {
|
||||
$error = <<EOT;
|
||||
The DBI Perl library was not found on this server.<br>
|
||||
Please install DBI library prior to running this program.<br>
|
||||
<table cellpadding=5><tr><td align=left><font color=black>Try this:<br>
|
||||
EOT
|
||||
if ($^O eq 'MSWin32') {
|
||||
$error .= <<EOT;
|
||||
<b> C:\></b><i>ppm.bat</i><br>
|
||||
<b> ppm></b> <i>install DBI</i><br>
|
||||
EOT
|
||||
} else {
|
||||
$error .= <<EOT;
|
||||
<b>#</b><i>perl -MCPAN -e shell</i><br>
|
||||
<b><u>cpan></u></b> <i>install DBI</i><br>
|
||||
EOT
|
||||
}
|
||||
$error .= <<EOT;
|
||||
</font></td></tr></table>
|
||||
EOT
|
||||
}
|
||||
#
|
||||
# Check if ODBC DBD driver installed
|
||||
#
|
||||
if ($error eq undef) {
|
||||
my @drivers = DBI->available_drivers(1);
|
||||
if (!grep(/ODBC/, @drivers)) {
|
||||
$error = <<EOT;
|
||||
The ODBC DBD driver was not found on this server.<br>
|
||||
Please install ODBC DBD driver prior to running this program.<br>
|
||||
<table cellpadding=5><tr><td align=left><font color=black>Try this:<br>
|
||||
EOT
|
||||
my $drv = 'DBD::ODBC';
|
||||
if ($^O eq 'MSWin32') {
|
||||
$error .= <<EOT;
|
||||
<b> C:\></b><i>ppm.bat</i><br>
|
||||
<b> ppm></b> <i>install $drv</i><br>
|
||||
EOT
|
||||
} else {
|
||||
$error .= <<EOT;
|
||||
<b>#</b><i>perl -MCPAN -e shell</i><br>
|
||||
<b><u>cpan></u></b> <i>install $drv</i><br>
|
||||
EOT
|
||||
}
|
||||
$error .= <<EOT;
|
||||
</font></td></tr></table>
|
||||
EOT
|
||||
}
|
||||
}
|
||||
#
|
||||
# Check if any ODBC DSNs defined
|
||||
#
|
||||
my @dsns;
|
||||
if ($error eq undef) {
|
||||
@dsns = grep {s/^DBI:ODBC://} DBI->data_sources('ODBC');
|
||||
$error = "No ODBC DSN records found on this server.<br>Please configure DSN prior to running this program."
|
||||
if !@dsns;
|
||||
}
|
||||
# foreach my $d (@dsns) {
|
||||
# print "$d<br>\n";
|
||||
# }
|
||||
if ($error eq undef && $query->param('do')) {
|
||||
$cfg->set('dbdsn', $dsn);
|
||||
$cfg->set('dbuser', $user);
|
||||
$cfg->set('dbpass', $pass);
|
||||
$cfg->set('dbpref', $prefix);
|
||||
$doimport = 1 if $cfg->get('dbmode') ne 'mssql';
|
||||
$error = build($cfg);
|
||||
if ($error eq undef) {
|
||||
eval "use TTXMSSQLTickets";
|
||||
if ($@) {
|
||||
$cfg->set('dbmode', 'plaintext');
|
||||
} else {
|
||||
$cfg->set('dbmode', 'mssql');
|
||||
$cfg->set('dbschema', '2.22');
|
||||
}
|
||||
$cfg->save();
|
||||
}
|
||||
}
|
||||
if ($query->param('do') && $error eq undef ) {
|
||||
ok();
|
||||
return;
|
||||
}
|
||||
my $warning;
|
||||
if ($cfg->get('dbmode') eq 'mssql') {
|
||||
$warning = "YOU HAVE ALREADY ENABLED SQL SERVER MODE<br>\n".
|
||||
"THIS SCRIPT WILL RESET YOUR TICKETS DATABASE<br>\n".
|
||||
"ALL TICKETS SUBMITTED USING SQL MODE WILL BE LOST!";
|
||||
}
|
||||
$error = "<br><b><font color=red>Error: $error</font></b><br><br>" if $error ne undef;
|
||||
$warning = "\n<br><b><font color=red>$warning</font></b><br><br>" if $warning ne undef;
|
||||
print <<EOT;
|
||||
<center><b>Microsoft SQL Server Module Setup</b><br>
|
||||
<span class=sm>(go to <a href="setup.cgi?cmd=setup4&pwd=$pwd">Main Setup Utility</a> form)</span>
|
||||
<br>$error$warning
|
||||
<form action=$ENV{SCRIPT_NAME} method=post id=mainform>
|
||||
<input type=hidden name=cmd value=setup1>
|
||||
<input type=hidden name=do value=1>
|
||||
<input type=hidden name=pwd value=$pwd>
|
||||
<table border=0 cellpadding=0 cellspacing=0>
|
||||
<tr height=1><td colspan=2 align=center height=1 bgcolor="#9b9b9b"><img
|
||||
src="$imgurl/dot.gif" height=1></td></tr>
|
||||
<tr><td colspan=2><br>
|
||||
SQL Server database access info. Please contact your hosting provider or system admin if not sure.
|
||||
<br><br>
|
||||
A Data Source Name (DSN) is the logical name that is used by Open Database Connectivity (ODBC)
|
||||
to refer to the drive and other information that is required to access data. The name is used by
|
||||
Trouble Ticket Express for a connection to an ODBC data source, such as a Microsoft
|
||||
SQL Server database. To set this name, use the ODBC tool in Control Panel.<br><br>
|
||||
</td></tr>
|
||||
<tr><td align=right><b>DSN:</b></td>
|
||||
<td> <select name=dbdsn1 onChange="document.forms['mainform'].dbdsn.value='';"><option></option>
|
||||
EOT
|
||||
my $dsnval = $dsn;
|
||||
$dsnval = s/"/"/g;
|
||||
foreach my $d (@dsns) {
|
||||
my $quotedsn = $d; $quotedsn =~ s/"/"/g;
|
||||
my $quotedsn1 = $d; $quotedsn =~ s/</</g;
|
||||
print "<option value=\"$quotedsn\"";
|
||||
if ($d eq $dsn) {
|
||||
print " selected";
|
||||
$dsnval = undef;
|
||||
}
|
||||
print ">$quotedsn1</option>\n";
|
||||
}
|
||||
print <<EOT;
|
||||
</select>
|
||||
other: <input type=text name=dbdsn value="$dsnval" onChange="document.forms['mainform'].dbdsn1.options[0].selected=true;">
|
||||
</td></tr>
|
||||
<tr><td align=right><b>User:</b></td><td> <input type=text name=user value="$user"></td></tr>
|
||||
<tr><td align=right><b>Password:</b></td><td> <input type=password name=pass value="$pass"></td></tr>
|
||||
|
||||
<tr><td colspan=2 align=center> </td></tr>
|
||||
<tr height=1><td colspan=2 align=center height=1 bgcolor="#9b9b9b"><img
|
||||
src="$imgurl/dot.gif" height=1></td></tr>
|
||||
<tr><td colspan=2><br>
|
||||
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.<br><br>
|
||||
</td></tr>
|
||||
<tr><td align=right><b>Table prefix</b> (optional)<b>:</b></td><td> <input type=text name=prefix value="$prefix"></td></tr>
|
||||
<tr><td colspan=2 align=center>
|
||||
<br><input type=submit value="Save Settings">
|
||||
<br><br>
|
||||
The import procedure may take several minutes to complete.<br><b>Do not click twice!</b>
|
||||
</td></tr>
|
||||
</form>
|
||||
</table>
|
||||
<br>
|
||||
<br>Login to <a href="ttx.cgi?cmd=login"><b>Trouble Ticket Express</b></a>
|
||||
</center>
|
||||
EOT
|
||||
}
|
||||
# =========================================================================== ok
|
||||
|
||||
sub ok {
|
||||
print "<center><table width=600><tr><td align=left><center><b>Congratulations!</b></center><br><br>\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 Microsoft SQL Server Edition.\n".
|
||||
"Please <b>do not</b> run database setup utility unless you want to make changes to the database settings.\n"
|
||||
}
|
||||
print "<br><br>\n";
|
||||
if ($cfg->get('dbmode') ne 'mssql') {
|
||||
print <<EOT;
|
||||
<b>IMPORTANT</b>
|
||||
Trouble Ticket Express still uses plain text database.
|
||||
Neither new tickets, nor follow-up messages to existing tickets will be added to the SQL Server database.
|
||||
In order to enable SQL Server features you must install a SQL Server add-on module to your web server.
|
||||
The module may be ordered on-line at our web site. After uploading the SQL Server add-on module to your web server,
|
||||
please run this script once more - it will update your SQL Server database to ensure it includes
|
||||
recent data from your plain text database and will switch Trouble Ticket Express into SQL Server mode.
|
||||
<br><br>
|
||||
<center>
|
||||
<a href="http://www.troubleticketexpress.com/mssql.html"><b>Order MS SQL add-on module</b></a>
|
||||
</center>
|
||||
<br><br>
|
||||
EOT
|
||||
} else {
|
||||
print "Trouble Ticket Express now uses SQL Server database.<br><br>\n";
|
||||
}
|
||||
print "<center><a href=\"setup.cgi?cmd=setup4&pwd=$pwd\"><b>Main Setup Utility</b></a><br>".
|
||||
"<a href=\"ttx.cgi?cmd=login\"><b>Trouble Ticket Express</b></a></center>\n";
|
||||
print "</td></tr></table></center>\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 = ('dbdsn', 'dbuser', 'dbpass');
|
||||
my $id2name = {
|
||||
dbdsn => 'DSN',
|
||||
dbuser => 'User ID',
|
||||
dbpass => 'User Password'
|
||||
};
|
||||
my $error;
|
||||
foreach my $fld (@manda) {
|
||||
my $val = $cfg->get($fld);
|
||||
if ($val eq undef) {
|
||||
$error .= "Missing ".$id2name->{$fld}."<br>\n";
|
||||
}
|
||||
}
|
||||
#
|
||||
# Step one - connect to ms sql database engine
|
||||
#
|
||||
# my $dsn = "DBI:mysql:database=".$cfg->get('dbid').";host=".$cfg->get('dbhost').";port=".$cfg->get('dbport');
|
||||
my $dbh = DBI->connect('DBI:ODBC:'.$cfg->get('dbdsn'), $cfg->get('dbuser'), $cfg->get('dbpass'),
|
||||
{RaiseError => 0, AutoCommit => 1});
|
||||
if (!$dbh) {
|
||||
return "Error connecting to a database. $DBI::errstr";
|
||||
}
|
||||
#
|
||||
# Still alive? Good. Try to create tables now.
|
||||
#
|
||||
my $sth = $dbh->prepare("EXECUTE sp_tables");
|
||||
$sth->execute();
|
||||
my %tables;
|
||||
while (my @row = $sth->fetchrow_array()) {
|
||||
$tables{$row[2]} = 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 %fldlen = (
|
||||
email => 128,
|
||||
name => 128,
|
||||
oper => 32,
|
||||
subject => 255,
|
||||
lname => 50,
|
||||
grp => 10,
|
||||
status => 3,
|
||||
key => 64,
|
||||
item => 255
|
||||
);
|
||||
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 = <DB>;
|
||||
close DB;
|
||||
chomp @buff;
|
||||
$| = 1;
|
||||
foreach my $line (@buff) {
|
||||
print "\n";
|
||||
my @fields = split(/\|/, $line);
|
||||
my %tik;
|
||||
my $sql = "INSERT 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}));
|
||||
} elsif ($fld eq 'id') {
|
||||
$values .= $dbh->quote($tik{$fld});
|
||||
} elsif ($fld =~ /^c\d+$/) {
|
||||
$values .= $dbh->quote(substr($tik{$fld},0,255));
|
||||
} else {
|
||||
$values .= $dbh->quote(substr($tik{$fld},0,$fldlen{$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 = substr($header{FROM},0,32);
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 = <<EOT;
|
||||
CREATE TABLE $tablename (
|
||||
ID bigint UNIQUE DEFAULT '' NOT NULL,
|
||||
ACCESSKEY varchar(64) DEFAULT '' NOT NULL ,
|
||||
OPENED datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
||||
UPDATED datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
||||
CLOSED datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
||||
STATUS char(3) DEFAULT '' NOT NULL,
|
||||
OPER varchar(32) DEFAULT '' NOT NULL,
|
||||
EMAIL varchar(128) DEFAULT '' NOT NULL,
|
||||
NAME varchar(128) DEFAULT '' NOT NULL,
|
||||
SUBJECT varchar(255) DEFAULT '' NOT NULL,
|
||||
LNAME varchar(50) DEFAULT '' NOT NULL,
|
||||
C0 varchar(255) DEFAULT '' NOT NULL,
|
||||
C1 varchar(255) DEFAULT '' NOT NULL,
|
||||
C2 varchar(255) DEFAULT '' NOT NULL,
|
||||
C3 varchar(255) DEFAULT '' NOT NULL,
|
||||
C4 varchar(255) DEFAULT '' NOT NULL,
|
||||
C5 varchar(255) DEFAULT '' NOT NULL,
|
||||
C6 varchar(255) DEFAULT '' NOT NULL,
|
||||
C7 varchar(255) DEFAULT '' NOT NULL,
|
||||
C8 varchar(255) DEFAULT '' NOT NULL,
|
||||
C9 varchar(255) DEFAULT '' NOT NULL,
|
||||
GRP varchar(10) DEFAULT '' NOT NULL,
|
||||
EOT
|
||||
my $cnt = int ($cfg->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 .= "PRIMARY KEY (ID))\n";
|
||||
} elsif ($table eq 'messages') {
|
||||
$sql = <<EOT;
|
||||
CREATE TABLE $tablename (
|
||||
MID BIGINT IDENTITY PRIMARY KEY,
|
||||
TID BIGINT NOT NULL DEFAULT '0',
|
||||
AUTHOR VARCHAR(32) DEFAULT '' NOT NULL ,
|
||||
DATE DATETIME DEFAULT '0000-00-00 00:00:00' NOT NULL ,
|
||||
INTERNAL CHAR(1) DEFAULT '0' NOT NULL ,
|
||||
ISOPER CHAR(1) DEFAULT '0' NOT NULL ,
|
||||
HEADERS TEXT DEFAULT '' NOT NULL,
|
||||
MSG TEXT DEFAULT '' NOT NULL
|
||||
)
|
||||
EOT
|
||||
}
|
||||
$sql =~ s/\n/ /g;
|
||||
if (!$dbh->do($sql)) {
|
||||
return "Error creating table $tablename, ".$dbh->errstr;
|
||||
}
|
||||
if ($table eq 'messages') {
|
||||
$dbh->do("CREATE INDEX TID ON $tablename (TID)");
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
1;
|
||||
#
|
||||
Reference in New Issue
Block a user