my $class = shift;
my ($args) = @_;
- $args->{storage} = DBM::Deep::File->new( $args )
- unless exists $args->{storage};
-
# locking implicitly enables autoflush
if ($args->{locking}) { $args->{autoflush} = 1; }
type => TYPE_HASH,
base_offset => undef,
staleness => undef,
-
- storage => undef,
engine => undef,
}, $class;
$self->lock_exclusive;
$self->_engine->setup_fh( $self );
- $self->_storage->set_inode;
$self->unlock;
}; if ( $@ ) {
my $e = $@;
sub lock_exclusive {
my $self = shift->_get_self;
- return $self->_storage->lock_exclusive( $self );
+ return $self->_engine->lock_exclusive( $self );
}
*lock = \&lock_exclusive;
sub lock_shared {
my $self = shift->_get_self;
- return $self->_storage->lock_shared( $self );
+ return $self->_engine->lock_shared( $self );
}
sub unlock {
my $self = shift->_get_self;
- return $self->_storage->unlock( $self );
+ return $self->_engine->unlock( $self );
}
sub _copy_value {
my $self = shift->_get_self;
#XXX Need to create a new test for this
-# if ($self->_storage->{links} > 1) {
+# if ($self->_engine->storage->{links} > 1) {
# $self->_throw_error("Cannot optimize: reference count is greater than 1");
# }
#XXX Do we have to lock the tempfile?
#XXX Should we use tempfile() here instead of a hard-coded name?
- my $temp_filename = $self->_storage->{file} . '.tmp';
+ my $temp_filename = $self->_engine->storage->{file} . '.tmp';
my $db_temp = DBM::Deep->new(
file => $temp_filename,
type => $self->_type,
$self->lock_exclusive;
$self->_engine->clear_cache;
$self->_copy_node( $db_temp );
- $db_temp->_storage->close;
+ $db_temp->_engine->storage->close;
undef $db_temp;
##
# Attempt to copy user, group and permissions over to new file
##
- $self->_storage->copy_stats( $temp_filename );
+ $self->_engine->storage->copy_stats( $temp_filename );
# q.v. perlport for more information on this variable
if ( $^O eq 'MSWin32' || $^O eq 'cygwin' ) {
# with a soft copy.
##
$self->unlock;
- $self->_storage->close;
+ $self->_engine->storage->close;
}
- if (!rename $temp_filename, $self->_storage->{file}) {
+ if (!rename $temp_filename, $self->_engine->storage->{file}) {
unlink $temp_filename;
$self->unlock;
$self->_throw_error("Optimize failed: Cannot copy temp file over original: $!");
}
$self->unlock;
- $self->_storage->close;
+ $self->_engine->storage->close;
- $self->_storage->open;
+ $self->_engine->storage->open;
$self->lock_exclusive;
$self->_engine->setup_fh( $self );
$self->unlock;
type => $self->_type,
base_offset => $self->_base_offset,
staleness => $self->_staleness,
- storage => $self->_storage,
engine => $self->_engine,
);
}
my $func = shift;
if ( $is_legal_filter{$type} ) {
- $self->_storage->{"filter_$type"} = $func;
+ $self->_engine->storage->{"filter_$type"} = $func;
return 1;
}
return $self->{engine};
}
-sub _storage {
- my $self = $_[0]->_get_self;
- return $self->{storage};
-}
-
sub _type {
my $self = $_[0]->_get_self;
return $self->{type};
my ($key, $value) = @_;
warn "STORE($self, $key, $value)\n" if DEBUG;
- unless ( $self->_storage->is_writable ) {
+ unless ( $self->_engine->storage->is_writable ) {
$self->_throw_error( 'Cannot write to a readonly filehandle' );
}
# User may be storing a complex value, in which case we do not want it run
# through the filtering system.
- if ( !ref($value) && $self->_storage->{filter_store_value} ) {
- $value = $self->_storage->{filter_store_value}->( $value );
+ if ( !ref($value) && $self->_engine->storage->{filter_store_value} ) {
+ $value = $self->_engine->storage->{filter_store_value}->( $value );
}
$self->_engine->write_value( $self, $key, $value);
# Filters only apply to scalar values, so the ref check is making
# sure the fetched bucket is a scalar, not a child hash or array.
- return ($result && !ref($result) && $self->_storage->{filter_fetch_value})
- ? $self->_storage->{filter_fetch_value}->($result)
+ return ($result && !ref($result) && $self->_engine->storage->{filter_fetch_value})
+ ? $self->_engine->storage->{filter_fetch_value}->($result)
: $result;
}
my ($key) = @_;
warn "DELETE($self,$key)\n" if DEBUG;
- unless ( $self->_storage->is_writable ) {
+ unless ( $self->_engine->storage->is_writable ) {
$self->_throw_error( 'Cannot write to a readonly filehandle' );
}
##
my $value = $self->_engine->delete_key( $self, $key);
- if (defined $value && !ref($value) && $self->_storage->{filter_fetch_value}) {
- $value = $self->_storage->{filter_fetch_value}->($value);
+ if (defined $value && !ref($value) && $self->_engine->storage->{filter_fetch_value}) {
+ $value = $self->_engine->storage->{filter_fetch_value}->($value);
}
$self->unlock;
my $self = shift->_get_self;
warn "CLEAR($self)\n" if DEBUG;
- unless ( $self->_storage->is_writable ) {
+ unless ( $self->_engine->storage->is_writable ) {
$self->_throw_error( 'Cannot write to a readonly filehandle' );
}
$self->lock_shared;
- my $SAVE_FILTER = $self->_storage->{filter_fetch_value};
- $self->_storage->{filter_fetch_value} = undef;
+ my $SAVE_FILTER = $self->_engine->storage->{filter_fetch_value};
+ $self->_engine->storage->{filter_fetch_value} = undef;
my $size = $self->FETCH('length') || 0;
- $self->_storage->{filter_fetch_value} = $SAVE_FILTER;
+ $self->_engine->storage->{filter_fetch_value} = $SAVE_FILTER;
$self->unlock;
$self->lock_exclusive;
- my $SAVE_FILTER = $self->_storage->{filter_store_value};
- $self->_storage->{filter_store_value} = undef;
+ my $SAVE_FILTER = $self->_engine->storage->{filter_store_value};
+ $self->_engine->storage->{filter_store_value} = undef;
my $result = $self->STORE('length', $new_length, 'length');
- $self->_storage->{filter_store_value} = $SAVE_FILTER;
+ $self->_engine->storage->{filter_store_value} = $SAVE_FILTER;
$self->unlock;
my $class = shift;
my ($args) = @_;
+ $args->{storage} = DBM::Deep::File->new( $args )
+ unless exists $args->{storage};
+
my $self = bless {
byte_size => 4,
$obj->{staleness} = $initial_reference->staleness;
}
+
+ $self->storage->set_inode;
}
return 1;
################################################################################
+sub lock_exclusive {
+ my $self = shift;
+ my ($obj) = @_;
+ return $self->storage->lock_exclusive( $obj );
+}
+
+sub lock_shared {
+ my $self = shift;
+ my ($obj) = @_;
+ return $self->storage->lock_shared( $obj );
+}
+
+sub unlock {
+ my $self = shift;
+ my ($obj) = @_;
+ return $self->storage->unlock( $obj );
+}
+
+################################################################################
+
sub storage { $_[0]{storage} }
sub byte_size { $_[0]{byte_size} }
sub hash_size { $_[0]{hash_size} }
sub FETCH {
my $self = shift->_get_self;
DBM::Deep->_throw_error( "Cannot use an undefined hash key." ) unless defined $_[0];
- my $key = ($self->_storage->{filter_store_key})
- ? $self->_storage->{filter_store_key}->($_[0])
+ my $key = ($self->_engine->storage->{filter_store_key})
+ ? $self->_engine->storage->{filter_store_key}->($_[0])
: $_[0];
return $self->SUPER::FETCH( $key, $_[0] );
sub STORE {
my $self = shift->_get_self;
DBM::Deep->_throw_error( "Cannot use an undefined hash key." ) unless defined $_[0];
- my $key = ($self->_storage->{filter_store_key})
- ? $self->_storage->{filter_store_key}->($_[0])
+ my $key = ($self->_engine->storage->{filter_store_key})
+ ? $self->_engine->storage->{filter_store_key}->($_[0])
: $_[0];
my $value = $_[1];
sub EXISTS {
my $self = shift->_get_self;
DBM::Deep->_throw_error( "Cannot use an undefined hash key." ) unless defined $_[0];
- my $key = ($self->_storage->{filter_store_key})
- ? $self->_storage->{filter_store_key}->($_[0])
+ my $key = ($self->_engine->storage->{filter_store_key})
+ ? $self->_engine->storage->{filter_store_key}->($_[0])
: $_[0];
return $self->SUPER::EXISTS( $key );
sub DELETE {
my $self = shift->_get_self;
DBM::Deep->_throw_error( "Cannot use an undefined hash key." ) unless defined $_[0];
- my $key = ($self->_storage->{filter_store_key})
- ? $self->_storage->{filter_store_key}->($_[0])
+ my $key = ($self->_engine->storage->{filter_store_key})
+ ? $self->_engine->storage->{filter_store_key}->($_[0])
: $_[0];
return $self->SUPER::DELETE( $key, $_[0] );
$self->unlock();
- return ($result && $self->_storage->{filter_fetch_key})
- ? $self->_storage->{filter_fetch_key}->($result)
+ return ($result && $self->_engine->storage->{filter_fetch_key})
+ ? $self->_engine->storage->{filter_fetch_key}->($result)
: $result;
}
##
my $self = shift->_get_self;
- my $prev_key = ($self->_storage->{filter_store_key})
- ? $self->_storage->{filter_store_key}->($_[0])
+ my $prev_key = ($self->_engine->storage->{filter_store_key})
+ ? $self->_engine->storage->{filter_store_key}->($_[0])
: $_[0];
$self->lock_shared;
$self->unlock();
- return ($result && $self->_storage->{filter_fetch_key})
- ? $self->_storage->{filter_fetch_key}->($result)
+ return ($result && $self->_engine->storage->{filter_fetch_key})
+ ? $self->_engine->storage->{filter_fetch_key}->($result)
: $result;
}
is( $db->{key1}, 'value1', "key1's value is still there after optimize" );
is( $db->{a}{c}, 'value2', "key2's value is still there after optimize" );
-$db->_get_self->_storage->close( $db->_get_self );
+$db->_get_self->_engine->storage->close( $db->_get_self );
##
# now for the tricky one -- try to store a new key while file is being
$hash{key1} = 'value';
is( $hash{key1}, 'value', 'Set and retrieved key1' );
- tied( %hash )->_get_self->_storage->close( tied( %hash )->_get_self );
+ tied( %hash )->_get_self->_engine->storage->close( tied( %hash )->_get_self );
}
{
is( keys %hash, 1, "There's one key so far" );
ok( exists $hash{key1}, "... and it's key1" );
- tied( %hash )->_get_self->_storage->close( tied( %hash )->_get_self );
+ tied( %hash )->_get_self->_engine->storage->close( tied( %hash )->_get_self );
}
{
file => $filename,
type => DBM::Deep->TYPE_ARRAY,
};
- tied( @array )->_get_self->_storage->close( tied( @array )->_get_self );
+ tied( @array )->_get_self->_engine->storage->close( tied( @array )->_get_self );
} qr/DBM::Deep: File type mismatch/, "\$SIG_TYPE doesn't match file's type";
}
type => DBM::Deep->TYPE_HASH,
};
} qr/DBM::Deep: File type mismatch/, "\$SIG_TYPE doesn't match file's type";
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
}
}
## Rewind handle otherwise the signature is not recognised below.
## The signature check should probably rewind the fh?
- seek $db->_get_self->_storage->{fh}, 0, 0;
+ seek $db->_get_self->_engine->storage->{fh}, 0, 0;
}
{
# Testing to verify that the close() will occur if open is called on an open DB.
#XXX WOW is this hacky ...
-$db->_get_self->_storage->open;
+$db->_get_self->_engine->storage->open;
is( $db->{key1}, "value1", "Value still set after re-open" );
throws_ok {
file => $filename,
locking => 1,
);
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
ok( !$db->lock, "Calling lock() on a closed database returns false" );
}
locking => 1,
);
$db->lock;
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
ok( !$db->unlock, "Calling unlock() on a closed database returns false" );
}
is( $db->{unblessed}{b}[2], 3 );
$db->{blessed_long} = bless {}, 'a' x 1000;
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
}
{
is( $db->{blessed}{c}, 'new' );
isa_ok( $db->{blessed_long}, 'a' x 1000 );
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
}
{
is( $structure->{unblessed}{b}[0], 1 );
is( $structure->{unblessed}{b}[1], 2 );
is( $structure->{unblessed}{b}[2], 3 );
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
}
{
is( $db->{unblessed}{b}[0], 1 );
is( $db->{unblessed}{b}[1], 2 );
is( $db->{unblessed}{b}[2], 3 );
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
}
{
}, 'Foo';
$db->import( { blessed => $obj } );
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
}
{
my $blessed = $db->{blessed};
isa_ok( $blessed, 'Foo' );
is( $blessed->{a}, 1 );
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
}
}
skip( "No inode tests on Win32", 1 )
if ( $^O eq 'MSWin32' || $^O eq 'cygwin' );
my $db_obj = $db->_get_self;
- ok( $db_obj->_storage->{inode}, "The inode has been set" );
+ ok( $db_obj->_engine->storage->{inode}, "The inode has been set" );
}
close($fh);
{
my $db = DBM::Deep->new( file => $filename );
verify( $db );
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
}
}
{
my $db = DBM::Deep->new( $filename );
verify( $db );
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
}
}
{
my $db = DBM::Deep->new( $filename );
verify( $db );
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
}
}
{
my $db = DBM::Deep->new( $filename );
verify( $db );
- $db->_get_self->_storage->close( $db->_get_self );
+ $db->_get_self->_engine->storage->close( $db->_get_self );
}
}
autoflush => 1,
num_txns => 2,
);
-seek $db1->_get_self->_storage->{fh}, 0, 0;
+seek $db1->_get_self->_engine->storage->{fh}, 0, 0;
my $db2 = DBM::Deep->new(
file => $filename,
cmp_bag( [ keys %{$db1->{x}{yz}} ], [qw( bar )], "DB1->X->XY keys correct" );
cmp_bag( [ keys %{$db2->{x}{yz}} ], [qw( bar )], "DB2->X->XY keys correct" );
-$db1->_get_self->_storage->close( $db1->_get_self );
-$db2->_get_self->_storage->close( $db2->_get_self );
+$db1->_get_self->_engine->storage->close( $db1->_get_self );
+$db2->_get_self->_engine->storage->close( $db2->_get_self );
num_txns => 16,
);
-seek $db->_get_self->_storage->{fh}, 0, 0;
+seek $db->_get_self->_engine->storage->{fh}, 0, 0;
my $db2 = DBM::Deep->new(
file => $filename,