App::Stash - persistent application data storage


App-Stash documentation Contained in the App-Stash distribution.

Index


Code Index:

NAME

Top

App::Stash - persistent application data storage

SYNOPSIS

Top

    use App::Stash;
    $stash = App::Stash->new({application => "test"});
    $stash->data->{'test'} = 1;
    $stash->d->{'test'} = 1;

after new run:

    use App::Stash;
    $s=App::Stash->new({application => "test"});
    print $s->data->{'test'}, "\n";
    print $s->dao->test, "\n";

WARNING

Top

experimental, use on your own risk :-)

DESCRIPTION

Top

The purpose of the module is to transparently save stash data (structure) across application (script) execution. The save is done in DESTROY method. This has certain limitations. Basically make sure you never store object in the data as this one may get destroyed before App::Stash object does.

The module+style is inspired by App::Cache. Unlike App::Cache it uses JSON::Util for storage and not Storable. The stash is saved to $HOME/.app-name/stash.json. It is in the "pretty" format so it should be easy to read and edit. I wanted to go with Storable but using it in DESTROY method causes Segmentation fault on my Perl.

Warn: no file locking in place, use Proc::PID::File or similar to have just one instance of program running or send a wish list bug report and wait for implementation of stash file locking. :)

PROPERTIES

Top

    application
    directory
    stash_filename

See new in App::Cache for a description of application and directory. stash_filename is the full path to the file where stash data will be stored. All three are optional.

METHODS

Top

new()

Object constructor.

d

Shortcut for data.

data

Returns reference to the stash data.

dao()

Returns data passed to dao in Data::AsObject. So basically the data structure becomes an object. See Data::AsObject for details.

Note: Data::AsObject is not compile time dependency. It will be used if installed. If not the exception will be thrown only when calling dao. So if you plan to use it, make it a dependency of your module/program.

clear

Will delete stash data and remove the file with the stash data from the disk.

load

Load stash data from disk. Called automatically by first call to data. Can be used to revert current stash data to the state before current execution.

save

Save stash data to disk - $HOME/.app-name/stash.json. Called automatically via DESTROY method when App::Stash object is going to be destroyed.

Will throw an exception if the file save fails.

DESTROY

Calls save and prints warning if it fails.

SEE ALSO

Top

App::Cache

AUTHOR

Top

Jozef Kutej, <jkutej at cpan.org>

BUGS

Top

Please report any bugs or feature requests to bug-app-stash at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=App-Stash. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

Top

You can find documentation for this module with the perldoc command.

    perldoc App::Stash




You can also look for information at:

* RT: CPAN's request tracker

http://rt.cpan.org/NoAuth/Bugs.html?Dist=App-Stash

* AnnoCPAN: Annotated CPAN documentation

http://annocpan.org/dist/App-Stash

* CPAN Ratings

http://cpanratings.perl.org/d/App-Stash

* Search CPAN

http://search.cpan.org/dist/App-Stash/

ACKNOWLEDGEMENTS

Top

COPYRIGHT & LICENSE

Top


App-Stash documentation Contained in the App-Stash distribution.
package App::Stash;

use warnings;
use strict;

our $VERSION = '0.02';

use File::HomeDir;
use File::Path qw( mkpath );
use Path::Class;
use JSON::Util;


use base qw( Class::Accessor::Chained::Fast );
__PACKAGE__->mk_accessors(qw( application directory stash_filename ));

sub new {
    my $class = shift;
    my $self  = $class->SUPER::new(@_);

    unless ( $self->application ) {
        my $caller = (caller)[0];
        $self->application($caller);
    }

    unless ( $self->directory ) {
        my $dir = dir( home(), "." . $self->_clean( $self->application ));
        $self->directory($dir);
    }
    my $dir = $self->directory;
    unless ( -d "$dir" ) {
        mkpath("$dir")
            || die "Error mkdiring " . $self->directory . ": $!";
    }

    unless ( $self->stash_filename ) {
        my $stash_filename = file($self->directory , "stash.json" )->stringify;
        $self->stash_filename($stash_filename);
    }

    return $self;
}

*d = *data;
sub data {
    my $self = shift;

    $self->load
        if (not $self->{'data'});

    return $self->{'data'};
}

sub dao {
    my $self = shift;
    if (not $INC{'Data/AsObject.pm'}) {
        eval 'use Data::AsObject;';
        die $@ if $@;
    }
    if (not $INC{'Storable.pm'}) {
        eval 'use Storable;';
        die $@ if $@;
    }
    return Data::AsObject::dao(Storable::dclone($self->data));
}

sub clear {
    my $self = shift;
    delete $self->{'data'};
    unlink($self->stash_filename) or die 'failed to unlink '.$self->stash_filename.' - '.$!;
    return;
    
}

sub load {
    my $self = shift;
    $self->{'data'} = eval { JSON::Util->decode([ $self->stash_filename ]) } || {};
    return;
}

sub save {
    my $self = shift;

    eval { JSON::Util->new->encode($self->data, [ $self->stash_filename ]); };
    die 'failed to save application stash - '.$@
        if $@;
    
    return;
}

sub DESTROY {
    my $self = shift;

    eval { $self->save(); };
    warn $@ if $@;
}

sub _clean {
    my ( $self, $text ) = @_;
    $text = lc $text;
    $text =~ s/[^a-z0-9]+/_/g;
    return $text;
}

1;


__END__

1; # End of App::Stash