package Yaa::LookupMap::Driver::DB_File;

# inherit everything from Yaa::LookupMap
@ISA = qw(Yaa::LookupMap);

# set debugging constant if YAA_DEBUG environment variable is set
BEGIN {
	use constant DEBUG => ((defined $ENV{YAA_DEBUG}) ? 1 : 0);
	require File::Basename if (DEBUG);
}

use strict;
use DB_File;
use vars qw ($VERSION);

=head1 NAME

Yaa::LookupMap::Driver::BerkeleyDB - DB_File lookup map driver


This driver supports queries to BerkeleyDB 1.x database files supported by DB_File perl module.

WARNING: Do not use this class standalone!

=cut

=head1 SYNOPSIS

my $db_map = Yaa::LookupMap->factory(

	'driver' => 'DB_File',
	'type' => 'hash',
	'mode' => 0400,
	'flags' => O_RDONLY,
	'file' => "/tmp/database";
	'cachesize' => 10000;
);

my $result = $db_map->lookup($key);

# prints out query result

print $result->getMatchValueByKey('result') if (defined $result);

B<Result keys>: This driver returns result object with only one key named B<result>

=cut

######################################################
#                GLOBAL VARIABLES                    #
######################################################
my $VERSION = "0.1";

######################################################
#               OBJECT CONSTRUCTOR                   #
######################################################

=head1 OBJECT CONSTRUCTOR

Object constructor options:

B<'file'> - path to the database file (database must exist)

B<'type'> - database file type { hash | btree | recno } (default: hash)

B<'cachesize'> - database cache size in bytes (default: 1024 * 1024)

B<'flags'> - database open flags (default: O_RDONLY)

B<'mode'> - database open mode (default: undef)


For detailed option documentation see perldoc DB_File.

=cut
sub new {
	my $proto = shift;
	my $class = ref($proto) || $proto;
	
	# call parent constructor
	my $self = Yaa::LookupMap->new();

	##################################################
	#               PUBLIC VARS                      #
	##################################################
	
	##################################################
	#              PRIVATE VARS                      #
	##################################################
	
	# database handle
	$self->{_db} = undef;
	
	bless($self, $class);
	
	# clear parameters
	$self->clearParams();

	# set object properties	
	$self->setParams(@_);
	
	# parse file
	$self->_dbInit() if (defined $self->{file});

	return $self;
}

####################################################
#               PUBLIC  METHODS                    #
####################################################

sub clearParams {
	my ($self) = @_;
	$self->{_db} = undef;

	$self->{'type'} = 'hash';
	$self->{'file'} = undef;
	$self->{mode} = 0400;
	$self->{flags} = O_RDONLY;
	$self->{'cachesize'} = 1024 * 1024;
	return 1;
}

####################################################
#               PRIVATE METHODS                    #
####################################################
sub _lookup {
	my ($self, $key) = @_;
	return undef unless ($self->_dbInit());
	
	my $value = undef;
	if ($self->{_db}->get($key, $value) != 0) {
		$self->{error} = "Error querying database: " . $!;
		return undef;
	}
	
	my $result = Yaa::LookupMap::Result->new;
	$result->addMatch({ result => $value });
	return $result;
}

sub _dbInit {
	my ($self) = @_;
	return 1 if (defined $self->{_db});
	my $db_type = undef;

	if ($self->{type} eq 'hash') {
		$db_type = DB_File::HASHINFO->new;
	}
	elsif ($self->{type} eq 'btree') {
		$db_type = DB_File::BTREEINFO->new;
	}
	elsif ($self->{type} eq 'recno') {
		$db_type =  DB_File::RECNOINFO->new;
	}
	else {
		$self->{error} = "Unknown database type: " . $self->{type};
		return 0;
	}
	
	# set cache
	$db_type->{cachesize} = $self->{cachesize} if (defined $self->{cachesize});

	# try to open database
	$self->{_db} = DB_File->TIEHASH(
		$self->{file},
		$self->{flags},
		$self->{mode},
		$db_type
	);

	unless (defined $self->{_db}) {
		unless (defined $!) {
			$self->{error} = "Unable to open database " . $self->{file} . ": Wrong database type?";
		} else {
			$self->{error} = "Unable to open database " . $self->{file} . ": " . $!;
		}
		return 0;
	}

	return 1;
}

1;
=head1 SEE ALSO

For general class usage, please see perldoc Yaa::LookupMap.

=cut

=head1 AUTHOR

Branko F. Gracnar <bfg@frost.ath.cx>
http://frost.ath.cx/~bfg

=cut

=head1 LICENSE

This software is released under BSD-style license. If you like this software, send me a nice postcard from somewhere to the snail mail address published on my website.

=cut

