FlatFile-DataStore
view release on metacpan or search on metacpan
lib/FlatFile/DataStore/Tiehash.pm view on Meta::CPAN
use Carp;
#---------------------------------------------------------------------
# NOTE: TIEHASH() is defined in FlatFile/DataStore.pm
#---------------------------------------------------------------------
# FETCH() supports tied hash access
# Returns a record object.
sub FETCH {
my( $self, $key ) = @_;
my $lastkeynum = $self->lastkeynum;
$key = $lastkeynum if $key eq '';
return if $key !~ /^[0-9]+$/;
return if $key > $lastkeynum;
$self->retrieve( $key );
}
#---------------------------------------------------------------------
# STORE() supports tied hash access
# Keys are limited to 0 .. lastkeynum (integers)
# If $key is new, it has to be nextkeynum, i.e., you can't leave
# gaps in the sequence of keys
# e.g., $h{ keys %h } = { data => "New", user => "record" };
# or $h{ tied( %h )->nextkeynum } = { data => "New", user => "record" };
# or $h{ '' } = { data => "New", user => "record" };
# or $h{ undef } = { data => "New", user => "record" };
# ('keys %h' is fairly light-weight, but nextkeynum is more so
# and $h{''} (or $h{undef}) is shorthand for nextkeynum)
sub STORE {
my( $self, $key, $parms ) = @_;
my $nextkeynum = $self->nextkeynum;
$key = $nextkeynum if $key eq '';
croak qq/Unsupported key format: $key/
unless $key =~ /^[0-9]+$/ and $key <= $nextkeynum;
my $reftype = ref $parms; # record, hash, sref, string
# for updates, $parms must be a record object
if( $key < $nextkeynum ) {
croak qq/Not a record object: $parms/
unless $reftype and $reftype =~ /Record/;
my $keynum = $parms->keynum;
croak qq/Record key number, $keynum, doesn't match key: $key/
unless $key == $keynum;
return $self->update( $parms );
}
# for creates, $parms may be record, href, sref, or string
else {
if( !$reftype or $reftype eq "SCALAR" ) { # string
return $self->create({ data => $parms });
}
if( $reftype =~ /Record/ ) {
return $self->create( $parms );
}
if( $reftype eq 'HASH' ) { # e.g., {data=>'recdata',user=>'userdata'}
return $self->create( $parms );
}
else {
croak qq/Unsupported ref type: $reftype/;
}
}
}
#---------------------------------------------------------------------
# DELETE() supports tied hash access
# If you want the "delete record" to contain anything more than
# the record being deleted, you have to call tied( %h )->delete()
# instead.
#
# Otherwise, we have to have a record to delete one, so we fetch
# it first.
sub DELETE {
my( $self, $key ) = @_;
return if $key !~ /^[0-9]+$/;
return if $key > $self->lastkeynum;
my $record = $self->retrieve( $key );
$self->delete( $record );
}
#---------------------------------------------------------------------
# CLEAR() supports tied hash access
# except we don't support CLEAR, because it would be very
# destructive and it would be a pain to recover from an
# accidental %h = ();
sub CLEAR {
my $self = shift;
croak qq/Clearing the entire datastore is not supported/;
}
#---------------------------------------------------------------------
# FIRSTKEY() supports tied hash access
# The keys in a datastore are always 0 .. lastkeynum (integers).
# Before the first record is added, nextkeynum() returns 0.
# In that case, the sub below would return undef.
sub FIRSTKEY {
my $self = shift;
return 0 if $self->nextkeynum > 0;
}
#---------------------------------------------------------------------
# NEXTKEY() supports tied hash access
# Because FIRSTKEY/NEXTKEY are functions of integers and require
# reading only a single line from a file (lastkeynum() reads the
# first line of the first toc file), the 'keys %h' operation is
# comparatively light-weight ('values %h' is a different story.)
sub NEXTKEY {
my( $self, $prevkey ) = @_;
return if $prevkey >= $self->lastkeynum;
$prevkey + 1;
}
( run in 0.949 second using v1.01-cache-2.11-cpan-5511b514fd6 )