########################################################################### # # dbutil.pm -- gateway to utilities for reading/writing to different databases # Copyright (C) 2008 DL Consulting Ltd # # A component of the Greenstone digital library software # from the New Zealand Digital Library Project at the # University of Waikato, New Zealand. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # ########################################################################### package dbutil; use strict; sub open_infodb_write_handle { my $infodb_type = shift(@_); my $infodb_file_path = shift(@_); if ($infodb_type eq "sqlite") { require dbutil::sqlite; return &dbutil::sqlite::open_infodb_write_handle($infodb_file_path, @_); } elsif ($infodb_type eq "gdbm-txtgz") { require dbutil::gdbmtxtgz; return &dbutil::gdbmtxtgz::open_infodb_write_handle($infodb_file_path, @_); } elsif ($infodb_type eq "jdbm") { require dbutil::jdbm; return &dbutil::jdbm::open_infodb_write_handle($infodb_file_path, @_); } elsif ($infodb_type eq "mssql") { require dbutil::mssql; return &dbutil::mssql::open_infodb_write_handle($infodb_file_path, @_); } # Use GDBM if the infodb type is empty or not one of the values above require dbutil::gdbm; return &dbutil::gdbm::open_infodb_write_handle($infodb_file_path, @_); } sub close_infodb_write_handle { my $infodb_type = shift(@_); my $infodb_handle = shift(@_); if ($infodb_type eq "sqlite") { require dbutil::sqlite; return &dbutil::sqlite::close_infodb_write_handle($infodb_handle, @_); } elsif ($infodb_type eq "gdbm-txtgz") { require dbutil::gdbmtxtgz; return &dbutil::gdbmtxtgz::close_infodb_write_handle($infodb_handle, @_); } elsif ($infodb_type eq "jdbm") { require dbutil::jdbm; return &dbutil::jdbm::close_infodb_write_handle($infodb_handle, @_); } elsif ($infodb_type eq "mssql") { require dbutil::mssql; return &dbutil::mssql::close_infodb_write_handle($infodb_handle, @_); } # Use GDBM if the infodb type is empty or not one of the values above require dbutil::gdbm; return &dbutil::gdbm::close_infodb_write_handle($infodb_handle, @_); } sub get_default_infodb_type { # The default is GDBM so everything works the same for existing collections # To use something else, specify the "infodbtype" in the collection's collect.cfg file return "gdbm"; } sub get_infodb_file_path { my $infodb_type = shift(@_); my $collection_name = shift(@_); my $infodb_directory_path = shift(@_); if ($infodb_type eq "sqlite") { require dbutil::sqlite; return &dbutil::sqlite::get_infodb_file_path($collection_name, $infodb_directory_path, @_); } elsif ($infodb_type eq "gdbm-txtgz") { require dbutil::gdbmtxtgz; return &dbutil::gdbmtxtgz::get_infodb_file_path($collection_name, $infodb_directory_path, @_); } elsif ($infodb_type eq "jdbm") { require dbutil::jdbm; return &dbutil::jdbm::get_infodb_file_path($collection_name, $infodb_directory_path, @_); } elsif ($infodb_type eq "mssql") { #==================================================================================================# # Updated by Jeffrey (2008/08/25 Monday) # After look into the run-time code, it seems we should still create a database file. # Since the run-time code is always try to read a database file, the easiest way here is not # to change the whole structure, but to give whatever the system is looking for. #==================================================================================================# # Added by Jeffrey (2008/08/15 Friday) # No file path required for MS SQL, it is a server-client connection. # At the moment the information is hard coded in dbutil::mssql::open_infodb_write_handle # the this might need some tidy up sometime. #==================================================================================================# require dbutil::mssql; return &dbutil::mssql::get_infodb_file_path($collection_name, $infodb_directory_path, @_); } # Use GDBM if the infodb type is empty or not one of the values above require dbutil::gdbm; return &dbutil::gdbm::get_infodb_file_path($collection_name, $infodb_directory_path, @_); } # This function, conceptually, would be better structured if it didn't # use return statements, as the database methods it calls do not # themselves return anything. # Note: if doing this, then the GDBM lines of code should be moved into # an 'else' clause sub read_infodb_file { my $infodb_type = shift(@_); my $infodb_file_path = shift(@_); my $infodb_map = shift(@_); if ($infodb_type eq "sqlite") { require dbutil::sqlite; return &dbutil::sqlite::read_infodb_file($infodb_file_path, $infodb_map, @_); } elsif ($infodb_type eq "gdbm-txtgz") { require dbutil::gdbmtxtgz; return &dbutil::gdbmtxtgz::read_infodb_file($infodb_file_path, $infodb_map, @_); } elsif ($infodb_type eq "jdbm") { require dbutil::jdbm; return &dbutil::jdbm::read_infodb_file($infodb_file_path, $infodb_map, @_); } elsif ($infodb_type eq "mssql") { require dbutil::mssql; return &dbutil::mssql::read_infodb_file($infodb_file_path, $infodb_map, @_); } # Use GDBM if the infodb type is empty or not one of the values above require dbutil::gdbm; return &dbutil::gdbm::read_infodb_file($infodb_file_path, $infodb_map, @_); } sub read_infodb_keys { my $infodb_type = shift(@_); my $infodb_file_path = shift(@_); my $infodb_map = shift(@_); if ($infodb_type eq "sqlite") { require dbutil::sqlite; &dbutil::sqlite::read_infodb_keys($infodb_file_path, $infodb_map, @_); } elsif ($infodb_type eq "gdbm-txtgz") { require dbutil::gdbmtxtgz; &dbutil::gdbmtxtgz::read_infodb_keys($infodb_file_path, $infodb_map, @_); } elsif ($infodb_type eq "jdbm") { require dbutil::jdbm; &dbutil::jdbm::read_infodb_keys($infodb_file_path, $infodb_map, @_); } elsif ($infodb_type eq "mssql") { require dbutil::mssql; &dbutil::mssql::read_infodb_keys($infodb_file_path, $infodb_map, @_); } else { # Use GDBM if the infodb type is empty or not one of the values above require dbutil::gdbm; &dbutil::gdbm::read_infodb_keys($infodb_file_path, $infodb_map, @_); } } sub read_infodb_entry { my $infodb_type = shift(@_); my $infodb_file_path = shift(@_); my $infodb_key = shift(@_); if ($infodb_type eq "sqlite") { require dbutil::sqlite; return &dbutil::sqlite::read_infodb_entry($infodb_file_path, $infodb_key, @_); } # elsif ($infodb_type eq "gdbm-txtgz") # { # require dbutil::gdbmtxtgz; # return &dbutil::gdbmtxtgz::read_infodb_entry($infodb_file_path, $infodb_key, @_); # } # elsif ($infodb_type eq "jdbm") # { # require dbutil::jdbm; # return &dbutil::jdbm::read_infodb_entry($infodb_file_path, $infodb_key, @_); # } # elsif ($infodb_type eq "mssql") # { # require dbutil::mssql; # return &dbutil::mssql::read_infodb_entry($infodb_file_path, $infodb_key, @_); # } # # Use GDBM if the infodb type is empty or not one of the values above # require dbutil::gdbm; # return &dbutil::gdbm::read_infodb_entry($infodb_file_path, $infodb_key, @_); # !! TEMPORARY: Slow and naive implementation that just reads the entire file and picks out the one value # !! This will soon be replaced with database-specific versions that will use dbget etc. my $infodb_map = {}; &read_infodb_file($infodb_type, $infodb_file_path, $infodb_map); return $infodb_map->{$infodb_key}; } sub write_infodb_entry { my $infodb_type = shift(@_); my $infodb_handle = shift(@_); my $infodb_key = shift(@_); my $infodb_map = shift(@_); if ($infodb_type eq "sqlite") { require dbutil::sqlite; return &dbutil::sqlite::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_); } elsif ($infodb_type eq "gdbm-txtgz") { require dbutil::gdbmtxtgz; return &dbutil::gdbmtxtgz::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_); } elsif ($infodb_type eq "jdbm") { require dbutil::jdbm; return &dbutil::jdbm::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_); } elsif ($infodb_type eq "mssql") { require dbutil::mssql; return &dbutil::mssql::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_); } # Use GDBM if the infodb type is empty or not one of the values above require dbutil::gdbm; return &dbutil::gdbm::write_infodb_entry($infodb_handle, $infodb_key, $infodb_map, @_); } sub write_infodb_rawentry { my $infodb_type = shift(@_); my $infodb_handle = shift(@_); my $infodb_key = shift(@_); my $infodb_val = shift(@_); if ($infodb_type eq "sqlite") { require dbutil::sqlite; return &dbutil::sqlite::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_); } elsif ($infodb_type eq "gdbm-txtgz") { require dbutil::gdbmtxtgz; return &dbutil::gdbmtxtgz::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_); } elsif ($infodb_type eq "jdbm") { require dbutil::jdbm; return &dbutil::jdbm::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_); } elsif ($infodb_type eq "mssql") { require dbutil::mssql; return &dbutil::mssql::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_); } # Use GDBM if the infodb type is empty or not one of the values above require dbutil::gdbm; return &dbutil::gdbm::write_infodb_rawentry($infodb_handle, $infodb_key, $infodb_val, @_); } sub set_infodb_entry { my $infodb_type = shift(@_); my $infodb_file_path = shift(@_); my $infodb_key = shift(@_); my $infodb_map = shift(@_); if ($infodb_type eq "sqlite") { require dbutil::sqlite; return &dbutil::sqlite::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_); } elsif ($infodb_type eq "gdbm-txtgz") { require dbutil::gdbmtxtgz; return &dbutil::gdbmtxtgz::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_); } elsif ($infodb_type eq "jdbm") { require dbutil::jdbm; return &dbutil::jdbm::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_); } elsif ($infodb_type eq "mssql") { require dbutil::mssql; return &dbutil::mssql::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_); } # Use GDBM if the infodb type is empty or not one of the values above require dbutil::gdbm; return &dbutil::gdbm::set_infodb_entry($infodb_file_path, $infodb_key, $infodb_map, @_); } sub delete_infodb_entry { my $infodb_type = shift(@_); my $infodb_handle = shift(@_); my $infodb_key = shift(@_); if ($infodb_type eq "sqlite") { require dbutil::sqlite; return &dbutil::sqlite::delete_infodb_entry($infodb_handle, $infodb_key, @_); } elsif ($infodb_type eq "gdbm-txtgz") { require dbutil::gdbmtxtgz; return &dbutil::gdbmtxtgz::delete_infodb_entry($infodb_handle, $infodb_key, @_); } elsif ($infodb_type eq "jdbm") { require dbutil::jdbm; return &dbutil::jdbm::delete_infodb_entry($infodb_handle, $infodb_key, @_); } elsif ($infodb_type eq "mssql") { require dbutil::mssql; return &dbutil::mssql::delete_infodb_entry($infodb_handle, $infodb_key, @_); } # Use GDBM if the infodb type is empty or not one of the values above require dbutil::gdbm; return &dbutil::gdbm::delete_infodb_entry($infodb_handle, $infodb_key, @_); } # ---- GENERAL FUNCTIONS -------- sub convert_infodb_hash_to_string { my $infodb_map = shift(@_); my $infodb_entry_value = ""; foreach my $infodb_value_key (keys(%$infodb_map)) { foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}}) { $infodb_entry_value .= "<$infodb_value_key>" . $infodb_value . "\n"; } } return $infodb_entry_value; } sub convert_infodb_string_to_hash { my $infodb_entry_value = shift(@_); my $infodb_map = (); if (!defined $infodb_entry_value) { print STDERR "Warning: No value to convert into a infodb hashtable\n"; } else { while ($infodb_entry_value =~ /^<(.*?)>(.*)$/mg) { my $infodb_value_key = $1; my $infodb_value = $2; if (!defined($infodb_map->{$infodb_value_key})) { $infodb_map->{$infodb_value_key} = [ $infodb_value ]; } else { push(@{$infodb_map->{$infodb_value_key}}, $infodb_value); } } } return $infodb_map; } 1;