###############################################################################
#
# BaseDBDriver.pm -- base class for all the database drivers
# A component of the Greenstone digital library software from the New Zealand
# Digital Library Project at the University of Waikato, New Zealand.
#
# Copyright (C) 1999-2015 New Zealand Digital Library Project
#
# 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 DBDrivers::BaseDBDriver;

# Pragma
use strict;
no strict 'subs';
no strict 'refs'; # allow filehandles to be variables and viceversa

# Libaries
use Time::HiRes qw( gettimeofday );
use gsprintf 'gsprintf';


## @function constructor
#
sub new
{
    my $class = shift(@_);
    my $debug = shift(@_);
    my $self = {};
    # Debug messages for this driver
    $self->{'debug'} = $debug; # 1 to enable
    # Default file extension - in this case it is an error to create a DB from
    # BaseDBDriver
    $self->{'default_file_extension'} = 'err';
    # Support
    $self->{'supports_set'} = 0;
    bless($self, $class);
    return $self;
}
## new(void) => BaseDBDriver ##


###############################################################################
## Protected Functions
###############################################################################


## @function debugPrint(string) => void
#
sub debugPrint
{
    my $self = shift(@_);
    my $message = shift(@_);
    if ($self->{'debug'}) {
	my ($seconds, $microseconds) = gettimeofday();
	print STDERR '[DEBUG:' . $seconds . '.' . $microseconds . '] ' . (caller 1)[3] . $message . "\n";
    }
}
## debugPrint(string) => void ##


## @function debugPrintFunctionHeader(*) => void
#
sub debugPrintFunctionHeader
{
    my $self = shift(@_);
    if ($self->{'debug'}) {
	my @arguments;
	foreach my $argument (@_) {
	    if ($argument !~ /^-?\d+(\.?\d+)?$/) {
		push(@arguments, '"' . $argument . '"');
	    }
	    else {
		push(@arguments, $argument);
	    }
	}
	my $message = '(' . join(', ', @arguments) . ')';
	# Would love to just call debugPrint() here, but then caller would be wrong
	my ($seconds, $microseconds) = gettimeofday();
	print STDERR '[DEBUG:' . $seconds . '.' . $microseconds . '] ' . (caller 1)[3] . $message . "\n";
    }
}
## debugPrintFunctionHeader(*) => void


## @function errorPrint(string, integer) => void
#
sub errorPrint
{
    my $self = shift(@_);
    my $message = shift(@_);
    my $is_fatal = shift(@_);
    print STDERR 'Error in ' . (caller 1)[3] . '! ' . $message . "\n";
    if ($is_fatal) {
	exit();
    }
}
## errorPrint(string, integer) => void ##

###############################################################################
## Public Functions
###############################################################################


## @function get_infodb_file_path(string, string) => string
#
sub get_infodb_file_path
{
    my $self = shift(@_);
    my $collection_name = shift(@_);
    my $infodb_directory_path = shift(@_);
    my $infodb_file_name = &util::get_dirsep_tail($collection_name) . '.' . $self->{'default_file_extension'};
    my $infodb_file_path = &FileUtils::filenameConcatenate($infodb_directory_path, $infodb_file_name);
    return $infodb_file_path;
}
## get_infodb_file_path(string, string) => string ##


## @function supportsDatestamp(void) => boolean
#
sub supportsDatestamp
{
    my $self = shift(@_);
    return 0;
}
## supportsDatestamp(void) => boolean ##


## @function supportsMerge(void) => boolean
#
sub supportsMerge
{
    my $self = shift(@_);
    return 0;
}
## supportsMerge(void) => boolean ##


## @function supportsRSS(void) => boolean
#
sub supportsRSS
{
    my $self = shift(@_);
    return 0;
}
## supportsRSS(void) => boolean ##


## @function supportsSet(void) => integer
#
#  Not all drivers support the notion of set
#
sub supportsSet
{
    my $self = shift(@_);
    return $self->{'supports_set'};
}
## supportsSet(void) => integer ##


###############################################################################
## Virtual Functions
###############################################################################


## @function close_infodb_write_handle(*) => void
#
sub close_infodb_write_handle
{
    my $self = shift(@_);
    gsprintf(STDERR, (caller(0))[3] . " {common.must_be_implemented}\n");
    die("\n");
}
## close_infodb_write_handle(*) => void ##


## @function delete_infodb_entry(*) => void
#
sub delete_infodb_entry
{
    my $self = shift(@_);
    gsprintf(STDERR, (caller(0))[3] . " {common.must_be_implemented}\n");
    die("\n");
}
## delete_infodb_entry(*) => void ##


## @function mergeDatabases(*) => void
#
sub mergeDatabases
{
    my $self = shift(@_);
    gsprintf(STDERR, (caller(0))[3] . " {common.must_be_implemented}\n");
    die("\n");
}
## mergeDatabases(*) => void ##


## @function open_infodb_write_handle(*) => void
#
sub open_infodb_write_handle
{
    my $self = shift(@_);
    gsprintf(STDERR, (caller(0))[3] . " {common.must_be_implemented}\n");
    die("\n");
}
## open_infodb_write_handle(*) => void ##


## @function set_infodb_entry(*) => void
#
sub set_infodb_entry
{
    my $self = shift(@_);
    gsprintf(STDERR, (caller(0))[3] . " {common.must_be_implemented}\n");
    die("\n");
}
## set_infodb_entry(*) => void ##


## @function read_infodb_rawentry(*) => string
#
sub read_infodb_rawentry
{
    my $self = shift(@_);
    gsprintf(STDERR, (caller(0))[3] . " {common.must_be_implemented}\n");
    die("\n");
}
## read_infodb_rawentry(*) => string ##


## @function read_infodb_file(*) => void
#
sub read_infodb_file
{
    my $self = shift(@_);
    gsprintf(STDERR, (caller(0))[3] . " {common.must_be_implemented}\n");
    die("\n");
}
## read_infodb_file(*) => void ##


## @function read_infodb_keys(*) => void
#
sub read_infodb_keys
{
    my $self = shift(@_);
    gsprintf(STDERR, (caller(0))[3] . " {common.must_be_implemented}\n");
    die("\n");
}
## read_infodb_keys(*) => void ##


## @function write_infodb_entry(*) => void
#
sub write_infodb_entry
{
    my $self = shift(@_);
    gsprintf(STDERR, (caller(0))[3] . " {common.must_be_implemented}\n");
    die("\n");
}
## write_infodb_entry(*) => void ##


## @function write_infodb_rawentry(*) => void
#
sub write_infodb_rawentry
{
    my $self = shift(@_);
    gsprintf(STDERR, (caller(0))[3] . " {common.must_be_implemented}\n");
    die("\n");
}
## write_infodb_rawentry(*) => void ##


1;
