base
This commit is contained in:
@@ -0,0 +1,388 @@
|
||||
package TTXInventory;
|
||||
#
|
||||
# This module is a part of Trouble Ticket Express package
|
||||
# http://www.troubleticketexpress.com
|
||||
#
|
||||
# COPYRIGHT: 2006, United Web Coders
|
||||
# http://www.unitedwebcoders.com
|
||||
#
|
||||
# $Revision: 257 $
|
||||
# $Date: 2006-08-16 05:47:08 -0400 (Wed, 16 Aug 2006) $
|
||||
#
|
||||
|
||||
$TTXInventory::VERSION='2.22';
|
||||
BEGIN {
|
||||
$TTXInventory::REVISION = '$Revision: 257 $';
|
||||
if ($TTXInventory::REVISION =~ /(\d+)/) {
|
||||
$TTXInventory::REVISION = $1;
|
||||
}
|
||||
};
|
||||
|
||||
use strict;
|
||||
use TTXData;
|
||||
|
||||
my $idb = undef;
|
||||
my $states = undef;
|
||||
my $lasterror;
|
||||
my @itemfields = ('id', 'title', 'status', 'img');
|
||||
my @statefields = ('id', 'title', 'img');
|
||||
|
||||
# ====================================================================== notesfn
|
||||
|
||||
sub notesfn {
|
||||
my $cfg = TTXData::get('CONFIG');
|
||||
my $dn = $cfg->get('basedir').'/inventory';
|
||||
return "$dn/$_[0].cgi";
|
||||
}
|
||||
|
||||
# ======================================================================== idbfn
|
||||
|
||||
sub idbfn {
|
||||
my $cfg = TTXData::get('CONFIG');
|
||||
my $dn = $cfg->get('basedir').'/inventory';
|
||||
my $fn = "$dn/index.cgi";
|
||||
if (! -d $dn) {
|
||||
if (!mkdir($dn, 0777)) {
|
||||
$lasterror = "Failed to create inventory database directory";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
if (! -f $fn) {
|
||||
open(IDB, ">$fn");
|
||||
close(IDB);
|
||||
if (! -f $fn) {
|
||||
$lasterror = "Failed to create inventory database";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
return $fn;
|
||||
}
|
||||
# ==================================================================== line2item
|
||||
|
||||
sub line2item {
|
||||
chomp($_[0]);
|
||||
my @fields = split(/\|/, $_[0]);
|
||||
my %item;
|
||||
foreach my $key (@itemfields) {
|
||||
$item{$key} = shift @fields;
|
||||
$item{key} =~ s/^\s+//;
|
||||
$item{key} =~ s/\s+$//;
|
||||
}
|
||||
return %item;
|
||||
}
|
||||
# ==================================================================== item2line
|
||||
|
||||
sub item2line {
|
||||
my $item = $_[0];
|
||||
my @vals;
|
||||
foreach my $key (@itemfields) {
|
||||
my $val = $item->{$key};
|
||||
$val =~ s/\|/!/g;
|
||||
push @vals, $val;
|
||||
}
|
||||
return join('|', @vals);
|
||||
}
|
||||
# ========================================================================= load
|
||||
|
||||
sub load {
|
||||
if ($idb eq undef) {
|
||||
my $fn = idbfn();
|
||||
return 0 if $fn eq undef;
|
||||
lockdb();
|
||||
if (!open(IDB, $fn)) {
|
||||
$lasterror = "Failed to open inventory database file";
|
||||
return 0;
|
||||
}
|
||||
flock(IDB,2);
|
||||
for (my $line = <IDB>; $line ne undef; $line = <IDB>) {
|
||||
my %item = line2item($line);
|
||||
next if $item{id} !~ /^\d+$/;
|
||||
my $nfn = notesfn($item{id});
|
||||
if (-f $nfn) {
|
||||
if (open(NOTES, $nfn)) {
|
||||
$item{notes} = join('', <NOTES>);
|
||||
close(NOTES);
|
||||
}
|
||||
}
|
||||
$idb->{$item{id}} = \%item;
|
||||
}
|
||||
close(IDB);
|
||||
unlockdb();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
# ========================================================================= list
|
||||
|
||||
sub list {
|
||||
return keys %{$idb} if load();
|
||||
my @empty;
|
||||
return @empty;
|
||||
}
|
||||
# ====================================================================== getitem
|
||||
|
||||
sub getitem {
|
||||
return undef if !load();
|
||||
if (! exists $idb->{$_[0]}) {
|
||||
$lasterror = "Item $_[0] does not exist";
|
||||
return undef;
|
||||
}
|
||||
return $idb->{$_[0]};
|
||||
}
|
||||
# ======================================================================= savedb
|
||||
|
||||
sub savedb {
|
||||
return 1 if $idb eq undef;
|
||||
my $fn = idbfn();
|
||||
return 0 if $fn eq undef;
|
||||
return 0 if !lockdb();
|
||||
if (!open(IDB, ">$fn")) {
|
||||
$lasterror = "Failed to open inventory database file";
|
||||
unlockdb();
|
||||
return 0;
|
||||
}
|
||||
flock(IDB,2);
|
||||
foreach my $id (sort {$a <=> $b} keys %{$idb}) {
|
||||
next if $id !~ /^\d+$/;
|
||||
print IDB item2line($idb->{$id})."\n";
|
||||
my $nfn = notesfn($id);
|
||||
if ($idb->{$id}->{notes} ne undef) {
|
||||
if (open(NOTES, ">$nfn")) {
|
||||
print NOTES $idb->{$id}->{notes};
|
||||
close(NOTES);
|
||||
}
|
||||
} elsif (-f $nfn) {
|
||||
unlink $nfn;
|
||||
}
|
||||
}
|
||||
close(IDB);
|
||||
unlockdb();
|
||||
if (TTXData::get('_USECACHE')) {
|
||||
eval "use TTXCache";
|
||||
TTXCache::purge() if $@ eq undef;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
# ========================================================================== add
|
||||
|
||||
sub add {
|
||||
my $item = $_[0];
|
||||
my $fn = idbfn();
|
||||
return undef if $fn eq undef;
|
||||
return undef if !lockdb();
|
||||
if (!load()) {
|
||||
unlockdb();
|
||||
return undef;
|
||||
}
|
||||
my @lst = sort {$a <=> $b } list();
|
||||
my $cnt = int(@lst);
|
||||
if (!$cnt) {
|
||||
$item->{id} = 1;
|
||||
} else {
|
||||
$item->{id} = int($lst[$cnt - 1]) + 1;
|
||||
}
|
||||
if (!open(IDB, ">>$fn")) {
|
||||
$lasterror = "Failed to open inventory database file";
|
||||
unlockdb();
|
||||
return undef;
|
||||
}
|
||||
flock(IDB,2);
|
||||
seek(IDB,0,2);
|
||||
print IDB item2line($item)."\n";
|
||||
close(IDB);
|
||||
if ($item->{notes} ne undef) {
|
||||
my $nfn = notesfn($item->{id});
|
||||
if (open(NOTES, ">$nfn")) {
|
||||
print NOTES $item->{notes};
|
||||
close(NOTES);
|
||||
}
|
||||
}
|
||||
unlockdb();
|
||||
if (TTXData::get('_USECACHE')) {
|
||||
eval "use TTXCache";
|
||||
TTXCache::purge() if $@ eq undef;
|
||||
}
|
||||
$idb->{$item->{id}} = $item;
|
||||
return $item->{id};
|
||||
}
|
||||
# ======================================================================= lockdb
|
||||
my $_lockcnt = 0;
|
||||
|
||||
sub lockdb {
|
||||
if ($_lockcnt) {
|
||||
++$_lockcnt;
|
||||
return 1;
|
||||
}
|
||||
my $lockfile = TTXData::get('CONFIG')->get('basedir')."/lockidb.ttx";
|
||||
if (! -f $lockfile) {
|
||||
if (!open(LOCK, ">$lockfile")) {
|
||||
$lasterror = 'LOCKWRERR';
|
||||
return 0;
|
||||
}
|
||||
} elsif (!open(LOCK,"+<$lockfile")) {
|
||||
$lasterror = 'LOCKOPNERR';
|
||||
return 0;
|
||||
}
|
||||
flock(LOCK, 2);
|
||||
$_lockcnt = 1;
|
||||
return 1;
|
||||
}
|
||||
# ===================================================================== unlockdb
|
||||
|
||||
sub unlockdb {
|
||||
return if !$_lockcnt;
|
||||
--$_lockcnt;
|
||||
if (!$_lockcnt) {
|
||||
flock(LOCK, 8);
|
||||
close LOCK;
|
||||
}
|
||||
}
|
||||
# ========================================================================== del
|
||||
|
||||
sub del {
|
||||
my $id = $_[0];
|
||||
return 0 if !lockdb();
|
||||
if (!load()) {
|
||||
unlockdb();
|
||||
return 0;
|
||||
}
|
||||
if (!exists $idb->{$id}) {
|
||||
unlockdb();
|
||||
return 1;
|
||||
}
|
||||
my $nfn = notesfn($id);
|
||||
unlink $nfn if -f $nfn;
|
||||
delete $idb->{$id};
|
||||
my $ccode = 1;
|
||||
if ($_lockcnt == 1) {
|
||||
$ccode = savedb();
|
||||
}
|
||||
unlockdb();
|
||||
return $ccode;
|
||||
}
|
||||
# ======================================================================== sdbfn
|
||||
|
||||
sub sdbfn {
|
||||
my $cfg = TTXData::get('CONFIG');
|
||||
my $dn = $cfg->get('basedir').'/inventory';
|
||||
my $fn = "$dn/states.cgi";
|
||||
if (! -d $dn) {
|
||||
if (!mkdir($dn, 0777)) {
|
||||
$lasterror = "Failed to create inventory database directory";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
if (! -f $fn) {
|
||||
open(IDB, ">$fn");
|
||||
close(IDB);
|
||||
if (! -f $fn) {
|
||||
$lasterror = "Failed to create status database";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
return $fn;
|
||||
}
|
||||
# =================================================================== line2state
|
||||
|
||||
sub line2state {
|
||||
chomp($_[0]);
|
||||
my @fields = split(/\|/, $_[0]);
|
||||
my %state;
|
||||
foreach my $key (@statefields) {
|
||||
$state{$key} = shift @fields;
|
||||
$state{key} =~ s/^\s+//;
|
||||
$state{key} =~ s/\s+$//;
|
||||
}
|
||||
return %state;
|
||||
}
|
||||
# =================================================================== state2line
|
||||
|
||||
sub state2line {
|
||||
my $state = $_[0];
|
||||
my @vals;
|
||||
foreach my $key (@statefields) {
|
||||
my $val = $state->{$key};
|
||||
$val =~ s/\|/!/g;
|
||||
push @vals, $val;
|
||||
}
|
||||
return join('|', @vals);
|
||||
}
|
||||
# =================================================================== loadstates
|
||||
|
||||
sub loadstates {
|
||||
if ($states eq undef) {
|
||||
$states = {};
|
||||
my $fn = sdbfn();
|
||||
return undef if $fn eq undef;
|
||||
if (!open(SDB, $fn)) {
|
||||
$lasterror = "Failed to open status database file";
|
||||
return undef;
|
||||
}
|
||||
flock(SDB,2);
|
||||
for (my $line = <SDB>; $line ne undef; $line = <SDB>) {
|
||||
my %state = line2state($line);
|
||||
next if $state{id} !~ /^\d+$/;
|
||||
$states->{$state{id}} = \%state;
|
||||
}
|
||||
close(SDB);
|
||||
}
|
||||
return $states;
|
||||
}
|
||||
# ===================================================================== addstate
|
||||
|
||||
sub addstate {
|
||||
my $state = $_[0];
|
||||
my $fn = sdbfn();
|
||||
return undef if $fn eq undef;
|
||||
return undef if !lockdb();
|
||||
if (loadstates() eq undef) {
|
||||
unlockdb();
|
||||
return undef;
|
||||
}
|
||||
my @lst = sort {$a <=> $b } keys %{$states};
|
||||
my $cnt = int(@lst);
|
||||
if (!$cnt) {
|
||||
$state->{id} = 1;
|
||||
} else {
|
||||
$state->{id} = int($lst[$cnt - 1]) + 1;
|
||||
}
|
||||
if (!open(SDB, ">>$fn")) {
|
||||
$lasterror = "Failed to open status database file";
|
||||
unlockdb();
|
||||
return undef;
|
||||
}
|
||||
flock(SDB,2);
|
||||
seek(SDB,0,2);
|
||||
print SDB state2line($state)."\n";
|
||||
close(SDB);
|
||||
unlockdb();
|
||||
$states->{$state->{id}} = $state;
|
||||
return $state->{id};
|
||||
}
|
||||
# =================================================================== savestates
|
||||
|
||||
sub savestates {
|
||||
return 1 if $states eq undef;
|
||||
my $fn = sdbfn();
|
||||
return 0 if $fn eq undef;
|
||||
return 0 if !lockdb();
|
||||
if (!open(SDB, ">$fn")) {
|
||||
$lasterror = "Failed to open status database file";
|
||||
unlockdb();
|
||||
return 0;
|
||||
}
|
||||
flock(SDB,2);
|
||||
foreach my $id (sort {$a <=> $b} keys %{$states}) {
|
||||
next if $id !~ /^\d+$/;
|
||||
print SDB state2line($states->{$id})."\n";
|
||||
}
|
||||
close(SDB);
|
||||
unlockdb();
|
||||
return 1;
|
||||
}
|
||||
# ======================================================================== error
|
||||
|
||||
sub error {
|
||||
return $lasterror;
|
||||
}
|
||||
1;
|
||||
#
|
||||
Reference in New Issue
Block a user