use strict;
-use FileHandle;
+#use FileHandle;
use Fcntl qw/:flock/;
use Digest::MD5 ();
use Scalar::Util ();
my $args;
if (scalar(@_) > 1) { $args = {@_}; }
else { $args = { file => shift }; }
+ print "Calling new()\n";
##
# Check if we want a tied hash or array.
##
my $self;
if (defined($args->{type}) && $args->{type} eq TYPE_ARRAY) {
- tie @$self, $class, %$args;
+ my $foo = tie @$self, $class, %$args;
+ print "Tied '$foo' to array\n";
+# return $foo;
}
else {
- tie %$self, $class, %$args;
+ my $foo = tie %$self, $class, %$args;
+ print "Tied '$foo' to hash\n";
+# return $foo;
}
- return bless $self, $class;
+ bless $self, $class;
+ print "Created '$self'\n";
+ return $self;
}
{
}
}
-sub _get_self { tied( %{$_[0]} ) || $_[0] }
+sub _get_self {
+ tied( %{$_[0]} ) || $_[0]
+}
sub TIEHASH {
##
return unless $self;
$self->root->{links}--;
+ print "DESTROY( $self ): ", $self->root, ':', $self->root->{links}, "\n";
if (!$self->root->{links}) {
$self->_close();
}
}
+my %translate_mode = (
+ 'r' => '<',
+ 'r+' => '+<',
+ 'w' => '>',
+ 'w+' => '+>',
+ 'a' => '>>',
+ 'a+' => '+>>',
+);
sub _open {
##
# Open a FileHandle to the database, create if nonexistent.
if (defined($self->fh)) { $self->_close(); }
-# eval {
- if (!(-e $self->root->{file}) && $self->root->{mode} eq 'r+') {
- my $temp = FileHandle->new( $self->root->{file}, 'w' );
+ eval {
+ my $filename = $self->root->{file};
+ my $mode = $translate_mode{ $self->root->{mode} };
+ print "Opening '$filename' as '$mode'\n";
+
+ #if (!(-e $filename) && $self->root->{mode} eq 'r+') {
+ if (!(-e $filename) && $mode eq '+<') {
+ #FileHandle->new( $filename, 'w' );
+ open( FH, '>', $filename );
+ close FH;
}
#XXX Convert to set_fh()
- $self->root->{fh} = FileHandle->new( $self->root->{file}, $self->root->{mode} );
-# }; if ($@ ) { $self->_throw_error( "Received error: $@\n" ); }
+# $self->root->{fh} = FileHandle->new( $self->root->{file}, $self->root->{mode} );
+ my $fh;
+ open( $fh, $mode, $filename )
+ or $fh = undef;
+ $self->root->{fh} = $fh;
+ }; if ($@ ) { $self->_throw_error( "Received error: $@\n" ); }
if (! defined($self->fh)) {
return $self->_throw_error("Cannot open file: " . $self->root->{file} . ": $!");
}
##
# Close database FileHandle
##
+ print "_close()\n";
my $self = _get_self($_[0]);
undef $self->root->{fh};
}
my $is_dbm_deep = eval { $value->isa( 'DBM::Deep' ) };
my $internal_ref = $is_dbm_deep && ($value->root eq $self->root);
+ print "_add: 1\n";
my $fh = $self->fh;
##
# If content is a hash or array, create new child DeepDB object and
# pass each key or element to it.
##
+ print "_add: 2\n";
if ($r eq 'HASH') {
my $branch = DBM::Deep->new(
type => TYPE_HASH,
root => $self->root,
);
foreach my $key (keys %{$value}) {
- $branch->{$key} = $value->{$key};
+ #$branch->{$key} = $value->{$key};
+ $branch->STORE( $key, $value->{$key} );
}
}
elsif ($r eq 'ARRAY') {
+ print "$self -> ", $self->root, $/;
my $branch = DBM::Deep->new(
type => TYPE_ARRAY,
base_offset => $location,
root => $self->root,
);
+ print "After new - $branch -> ", $branch->root, "\n";
my $index = 0;
foreach my $element (@{$value}) {
- $branch->[$index] = $element;
+ #$branch->[$index] = $element;
+ $branch->STORE( $index, $element );
$index++;
}
+ print "After elements\n";
}
+ print "_add: 3\n";
return $result;
}
# Store single hash key/value or array element in database.
##
my $self = _get_self($_[0]);
+ print "STORE: $self ... $_[0]\n";
my $key = ($self->root->{filter_store_key} && $self->type eq TYPE_HASH) ? $self->root->{filter_store_key}->($_[1]) : $_[1];
#XXX What is ref() checking here?
#YYY User may be storing a hash, in which case we do not want it run
if (($self->type eq TYPE_ARRAY) && ($key =~ /^\d+$/)) { $key = pack($LONG_PACK, $key); }
my $md5 = $DIGEST_FUNC->($key);
+ print "1\n";
##
# Make sure file is open
##
if (!defined($self->fh) && !$self->_open()) {
return;
}
+ ##
my $fh = $self->fh;
# Add key/value to bucket list
##
my $result = $self->_add_bucket( $tag, $md5, $key, $value );
+ print "2\n";
##
# If this object is an array, and bucket was not a replace, and key is numerical,
# Fetch single value or element given plain key or array index
##
my $self = _get_self($_[0]);
+ print "FETCH: $self ... $_[0]\n";
my $key = $_[1];
if ( $self->type eq TYPE_HASH ) {
##
# Make sure file is open
##
- if (!defined($self->fh)) { $self->_open(); }
+ if (!defined($self->fh)) { print "Calling _open from FETCH for '$key'\n";$self->_open(); }
##
# Request shared lock for reading
my $SAVE_FILTER = $self->root->{filter_fetch_value};
$self->root->{filter_fetch_value} = undef;
+ print "Fetching size ...\n";
my $packed_size = $self->FETCH('length');
+ print "size is '$packed_size'\n";
$self->root->{filter_fetch_value} = $SAVE_FILTER;
##
# DBM::Deep Test
##
+$|++;
use strict;
use Test::More;
my $max_levels = 1000;
-plan tests => $max_levels + 3;
+plan tests => 3;
use_ok( 'DBM::Deep' );
+can_ok( 'DBM::Deep', 'new' );
unlink "t/test.db";
my $db = DBM::Deep->new(
file => "t/test.db",
type => DBM::Deep->TYPE_ARRAY,
);
+print "Check error( $db )\n";
if ($db->error()) {
die "ERROR: " . $db->error();
}
+print "First assignment\n";
$db->[0] = [];
+print "second assignment\n";
+__END__
my $temp_db = $db->[0];
+print "loop\n";
for my $k ( 0 .. $max_levels ) {
$temp_db->[$k] = [];
$temp_db = $temp_db->[$k];
}
+print "done\n";
$temp_db->[0] = "deepvalue";
+print "undef\n";
undef $temp_db;
undef $db;
type => DBM::Deep->TYPE_ARRAY,
);
+my $cur_level = -1;
$temp_db = $db->[0];
for my $k ( 0 .. $max_levels ) {
+ $cur_level = $k;
$temp_db = $temp_db->[$k];
- isa_ok( $temp_db, 'DBM::Deep' ) || die "Whoops!";
+ eval { $temp_db->isa( 'DBM::Deep' ) } or last;
}
+is( $cur_level, $max_levels, "We read all the way down to level $cur_level" );
is( $temp_db->[0], "deepvalue", "And we retrieved the value at the bottom of the ocean" );