#=================================================================
# imp_servdb.pm
# Mark Pruett - 06/12/2000
#
# These routines handle actual database access. This module can
# be replaced by other modules that access other database
# back-ends. Replacement modules should retain the same functions
# and parameter semantics.
#
# This module supports the RDB database format, which should be
# sufficient for all intranet and most moderate-traffic intranet
# sites.
#=================================================================
use db_RDB;
#-----------------------------------------------------------------
# Initialize some module-global variables based on configuration
# values or hard-coded defaults.
#-----------------------------------------------------------------
sub impdb_init {
my (%DBCONF) = @_;
if (defined ($DBCONF{"DB_DIR"})) {
$db_dir = $DBCONF{"DB_DIR"};
}
else {
$db_dir = "/tmp"; # MLP: probably not a good default...
}
if (defined ($DBCONF{"RDBDIR"})) {
$rdbdir = $DBCONF{"RDBDIR"};
}
}
#-----------------------------------------------------------------
# Given a table "token" return the actual table name.
#-----------------------------------------------------------------
sub impdb_get_table_name {
my ($tbl_token) = @_;
#-----------------------------------------------------------------
# Read the entire aliases table and return in recs array.
#-----------------------------------------------------------------
sub impdb_get_aliases_records {
my @recs;
my $row = 0;
my $filename = "$db_dir/$db_aliases_file";
# Check for table write lock, wait a few seconds if necessary.
if (! db_wait_for_unlock ($filename, 10)) {
return undef;
}
#-----------------------------------------------------------------
# Read the entire geography table and return in recs array.
#-----------------------------------------------------------------
sub impdb_get_geography_records {
my @recs;
my $row = 0;
my $filename = "$db_dir/$db_geography_file";
# Check for table write lock, wait a few seconds if necessary.
if (! db_wait_for_unlock ($filename, 10)) {
return undef;
}
#-----------------------------------------------------------------
# Read the geo_preferences table and return in recs array.
#-----------------------------------------------------------------
sub impdb_get_geopref_records {
my @recs;
my $filename = "$db_dir/$db_geopref_file";
# Check for table write lock, wait a few seconds if necessary.
if (! db_wait_for_unlock ($filename, 10)) {
return undef;
}
#-----------------------------------------------------------------
# Return all records that match canonical name in all geo_preference
# tables. Return in rec array.
#
# Note: this does not return the records in any particular prefer-
# ence order.
#-----------------------------------------------------------------
sub impdb_get_printer_records {
my ($canonical_name, $language) = @_;
my @recs;
my $row = 0;
@geopref = impdb_get_geopref_records ();
if (! db_wait_for_unlock ("$db_dir/$table_name", 10)) {
next;
}
my %locations_tbl = db_get_table ("cat $db_dir/$table_name");
for ($i=0; $i < $locations_tbl{NUM_RECORDS}; $i++) {
$val = db_get_field ("printer_id", $i, %locations_tbl);
if ($val eq $canonical_name) {
# If no language was specified, or the language matches the db.
my $db_language = db_get_field ("language", $i, %locations_tbl);
if ((! defined $language) || ($language eq $db_language)) {
$recs[$row]->{"geo_code"} = $geo_code;
$recs[$row]->{"package_name"} =
db_get_field ("package_name", $i, %locations_tbl);
$recs[$row]->{"location_url"} =
db_get_field ("location_url", $i, %locations_tbl);
$recs[$row]->{"language"} =
db_get_field ("language", $i, %locations_tbl);
$recs[$row]->{"gpg_version"} =
db_get_field ("gpg_version", $i, %locations_tbl);
$recs[$row]->{"gpg_sig"} =
db_get_field ("gpg_sig", $i, %locations_tbl);
$recs[$row]->{"gpg_crc"} =
db_get_field ("gpg_crc", $i, %locations_tbl);
}
$row++;
}
}
}
return @recs;
}
#-----------------------------------------------------------------
# Given a table name, an id (either an exact name or a partial
# name), a boolean indicating theat the match should be partial
# or exact, and the language string (en for english, etc.), return
# an array of records that match the ID.
#-----------------------------------------------------------------
sub impdb_query_printer_records {
my ($table_name, $partial_id, $exact, $language) = @_;
my @recs;
my $row = 0;
my $i;
my $testpartial = $partial_id;
if (! db_wait_for_unlock ("$db_dir/$table_name", 10)) {
return undef;
}
# We need to do some transformations on the partial_id
# if we're doing a partial match. These transforms
# will convert normal file-globbing-style wildcards
# (* and ?) into equivalent perl regexps.
if ($exact != 1) {
# Special case: if $testpartial is blank, then
# convert it to "*" to match everything.
$testpartial = "*" if ($testpartial eq "");
# Convert "*" to ".*"
$testpartial =~ s/\*/\.\*/g;
# convert (for example) "???" to ".{3}"
while ($testpartial =~ /(\?+)/) {
$count = length($1);
$testpartial =~ s/(\?+)/\.{$count}/;
}
}
my %locations_tbl = db_get_table ("cat $db_dir/$table_name | $rdbdir/sorttbl printer_id");
$matched = 0;
if ($exact == 1) {
if ($val eq $partial_id) {
$matched = 1;
}
}
else {
my $testval = $val;
# Squeeze out white space:
$testval =~ s/ //g;
$testpartial =~ s/ //g;
if ($testval =~ /^$testpartial$/i ) {
$matched = 1;
}
}
if ($matched == 1) {
my $db_language = db_get_field ("language", $i, %locations_tbl);
# If no language was specified, or the language matches the db.
if ((! defined $language) || ($language eq $db_language)) {
#-----------------------------------------------------------------
# Given an alias name, find the matching canonical printer name.
# The latter name is the "master key" for subsequent table look-ups.
#-----------------------------------------------------------------
sub impdb_get_alias_record {
my ($alias) = @_;
my $filename = "$db_dir/$db_aliases_file";
# Check for table write lock, wait a few seconds if necessary.
if (! db_wait_for_unlock ($filename, 10)) {
return undef;
}
my $name = "";
my %alias_tbl = db_get_table ("cat $filename");
# search for alias match to $alias
my $row = db_find_record ("alias", $alias, %alias_tbl);
#-----------------------------------------------------------------
# Add a record to the location table.
#-----------------------------------------------------------------
sub impdb_add_location_record {
my ($prn_id, $fldstr, $valstr, $table_name) = @_;
my $rc = 1;
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# If there are no records, then this is a new table, so
# we'll build the necessary data structures.
if ($rdb{"NUM_RECORDS"} == 0) {
%rdb = db_new_table ("# New Location Table",
$fldstr, "20\t25\t100");
}
# Check if record already exists with this printer_id
my $row = db_find_record ("printer_id", $prn_id, %rdb);
# If no existing record, then add.
if ($row == -1) {
%rdb = db_add_record ("", $fldstr, $valstr, %rdb);
# Write table
$rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
}
return $rc;
}
#-----------------------------------------------------------------
# Add a record to the aliases table.
#-----------------------------------------------------------------
sub impdb_add_aliases_record {
my ($alias_fname, $alias_fvalue, $fldstr, $valstr, $table_name) = @_;
my $rc = 1;
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# Check if record already exists with this printer_id
my $row = db_find_record ($alias_fname, $alias_fvalue, %rdb);
# If no existing record, then add.
if ($row == -1) {
%rdb = db_add_record ("", $fldstr, $valstr, %rdb);
# Write table
$rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
}
return $rc;
}
#-----------------------------------------------------------------
# Add a record to the geopref table.
#-----------------------------------------------------------------
sub impdb_add_geopref_record {
my ($geopref_fname, $geopref_fvalue, $fldstr, $valstr, $table_name) = @_;
my $rc = 1;
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# Check if record already exists with this unique id
my $row = db_find_record ($geopref_fname, $geopref_fvalue, %rdb);
# If no existing record, then add.
if ($row == -1) {
%rdb = db_add_record ("$geopref_fname", $fldstr, $valstr, %rdb);
# Write table
$rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
}
return $rc;
}
#-----------------------------------------------------------------
# Add a record to the geography table.
#-----------------------------------------------------------------
sub impdb_add_geography_record {
my ($autoinc_fname, $fldstr, $valstr, $table_name) = @_;
my $rc = 1;
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# Check if record already exists with this geo_description
my $row = db_find_record ("geo_description", $valstr, %rdb);
# If no existing record, then add.
if ($row == -1) {
%rdb = db_add_record ($autoinc_fname, $fldstr, $valstr, %rdb);
# Write table
$rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
}
return $rc;
}
#-----------------------------------------------------------------
# Edit an existing geography record.
#-----------------------------------------------------------------
sub impdb_edit_geography_record {
my ($target_fname, $target_fvalue, $fldstr, $valstr, $table_name) = @_;
my $rc = 1;
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# Find the record that has this geo_code.
my $row = db_find_record ($target_fname, $target_fvalue, %rdb);
# If record exists, edit.
if ($row >= 0) {
%rdb = db_edit_record ($row, $fldstr, $valstr, %rdb);
# Write table
$rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
}
return $rc;
}
#-----------------------------------------------------------------
# Edit an existing geopref record.
#-----------------------------------------------------------------
sub impdb_edit_geopref_record {
my ($target_fname, $target_fvalue, $fldstr, $valstr, $table_name) = @_;
my $rc = 1;
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# Check if record already exists with this printer_id
my $row = db_find_record ($target_fname, $target_fvalue, %rdb);
# If record exists, edit.
if ($row >= 0) {
%rdb = db_edit_record ($row, $fldstr, $valstr, %rdb);
# Write table
$rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
}
return $rc;
}
#-----------------------------------------------------------------
# Edit an existing aliases record.
#-----------------------------------------------------------------
sub impdb_edit_aliases_record {
my ($target_fname, $target_fvalue, $fldstr, $valstr, $table_name) = @_;
my $rc = 1;
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# Check if record already exists with this printer_id
my $row = db_find_record ($target_fname, $target_fvalue, %rdb);
# If record exists, edit.
if ($row >= 0) {
%rdb = db_edit_record ($row, $fldstr, $valstr, %rdb);
# Write table
$rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
}
return $rc;
}
#-----------------------------------------------------------------
# Edit an existing locations record.
#-----------------------------------------------------------------
sub impdb_edit_locations_record {
my ($target_fname, $target_fvalue, $fldstr, $valstr, $table_name) = @_;
my $rc = 1; # 1 = failure, 0 = success
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# Check if record already exists with this printer_id
my $row = db_find_record ($target_fname, $target_fvalue, %rdb);
# If record exists, edit.
if ($row >= 0) {
%rdb = db_edit_record ($row, $fldstr, $valstr, %rdb);
# Write table
$rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
}
return $rc;
}
#-----------------------------------------------------------------
# Delete an existing locations record.
#-----------------------------------------------------------------
sub impdb_delete_locations_record {
my ($fname, $fvalue, $table_name) = @_;
my $rc = 0;
my $write_rc;
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# Check if record already exists with this printer_id
($rc, %rdb) = db_delete_record ($fname, $fvalue, %rdb);
# Write table ($rc contains number of records deleted).
if ($rc > 0) {
$write_rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
if ($write_rc != 0) {
$rc = 0;
}
}
return $rc;
}
#-----------------------------------------------------------------
# Delete an existing geography record.
#-----------------------------------------------------------------
sub impdb_delete_geography_record {
my ($fname, $fvalue, $table_name) = @_;
my $rc = 0;
my $write_rc;
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# Check if record already exists with this printer_id
($rc, %rdb) = db_delete_record ($fname, $fvalue, %rdb);
# Write table ($rc contains number of records deleted).
if ($rc > 0) {
$write_rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
if ($write_rc != 0) {
$rc = 0;
}
}
return $rc;
}
#-----------------------------------------------------------------
# Delete an existing geopref record.
#-----------------------------------------------------------------
sub impdb_delete_geopref_record {
my ($fname, $fvalue, $table_name) = @_;
my $rc = 0;
my $write_rc;
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# If record matches, delete it
($rc, %rdb) = db_delete_record ($fname, $fvalue, %rdb);
# Write table ($rc contains number of records deleted).
if ($rc > 0) {
$write_rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
if ($write_rc != 0) {
$rc = 0;
}
}
return $rc;
}
#-----------------------------------------------------------------
# Delete an existing aliases record.
#-----------------------------------------------------------------
sub impdb_delete_aliases_record {
my ($fname, $fvalue, $table_name) = @_;
my $rc = 0;
my $write_rc;
# Read the table
my %rdb = db_get_table ("cat $db_dir/$table_name");
# If record matches, delete it
($rc, %rdb) = db_delete_record ($fname, $fvalue, %rdb);
# Write table ($rc contains number of records deleted).
if ($rc > 0) {
$write_rc = write_rdb_table ("$db_dir/$table_name", $db_backup_table, %rdb);
if ($write_rc != 0) {
$rc = 0;
}
}
return $rc;
}
#-----------------------------------------------------------------
# Read a table and return it "as-is".
#-----------------------------------------------------------------
sub impdb_get_table {
my ($tabname) = @_;
my $filename = "$db_dir/$tabname";
# Check for table write lock, wait a few seconds if necessary.
if (! db_wait_for_unlock ($filename, 10)) {
return undef;
}
my %tbl = db_get_table ("cat $filename");
return %tbl;
}
#-----------------------------------------------------------------
#-----------------------------------------------------------------
sub impdb_dump_table {
my (%rdb) = @_;
my $order = ($rdb{ORDER});
# COMMENTS
my $comments = $rdb{COMMENTS};
for ($idx=0; $idx <= $#$comments; $idx++) {
print $comments->[$idx]."\n";
}
# FIELD NAMES
$textout = $order->[0];
for ($fld=1; $fld <= $#$order; $fld++) {
$textout .= "\t".$order->[$fld];
}
print $textout."\n";
# FIELD TYPES
$textout = $rdb{FIELDS}->{$order->[0]}->{FTYPE};
for ($fld=1; $fld <= $#$order; $fld++) {
$textout .= "\t".$rdb{FIELDS}->{$order->[$fld]}->{FTYPE};
}
print $textout."\n";