Catmandu-FileStore

 view release on metacpan or  search on metacpan

lib/Catmandu/Store/File/Simple/Bag.pm  view on Meta::CPAN

use Path::Tiny;
use File::Spec;
use File::Copy;
use Catmandu::Util qw(content_type);
use URI::Escape;
use namespace::clean;

with 'Catmandu::Bag';
with 'Catmandu::FileBag';
with 'Catmandu::Droppable';

has _path => (is => 'lazy');

sub _build__path {
    my $self = shift;
    $self->store->directory_index->add($self->name)->{_path};
}

sub generator {
    my ($self) = @_;
    my $path = $self->_path;

    sub {
        state $children = [path($path)->children];

        my $child = shift @$children;

        return undef unless $child;

        my ($volume, $directories, $file) = File::Spec->splitpath($child);

        next if index($file, ".") == 0;

        my $unpacked_key = $self->unpack_key($file);

        return $self->get($unpacked_key);
    };
}

sub exists {
    my ($self, $id) = @_;
    my $path = $self->_path;

    my $packed_key = $self->pack_key($id);

    my $file = File::Spec->catfile($path, $packed_key);

    -f $file;
}

sub get {
    my ($self, $id) = @_;
    my $path = $self->_path;

    my $packed_key = $self->pack_key($id);

    my $file = File::Spec->catfile($path, $packed_key);

    return undef unless -f $file;

    my $stat = [stat($file)];

    my $size     = $stat->[7];
    my $modified = $stat->[9];
    my $created  = $stat->[10];    # no real creation time exists on Unix

    my $content_type = content_type($id);

    return {
        _id          => $id,
        size         => $size,
        md5          => '',
        content_type => $content_type,
        created      => $created,
        modified     => $modified,
        _stream      => sub {
            my $out   = $_[0];
            my $bytes = 0;
            my $data  = IO::File->new($file, "r")
                || Catmandu::Error->throw("$file not readable");

            Catmandu::Error->throw("no io defined or not writable")
                unless defined($out);

            Catmandu::Error->throw("$out doesn't support syswrite!")
                unless $out->can('syswrite');

            while (!$data->eof) {
                my $buffer;
                $data->read($buffer, 1024);

                my $n = $out->syswrite($buffer);

                if ($!{EAGAIN}) {
                    # no data read, try later
                    next;
                }
                elsif ($!) {
                    $self->log->error("filesystem error for $file : $!");
                    Catmandu::Error->throw("filesystem error for $file : $!");
                }
                elsif (!defined($n)) {
        		    $n = 0;
        		}
        		elsif ($n != length $buffer) {
        		    $self->log->error("incomplete write to $file");
                    Catmandu::Error->throw("incomplete write to $file");
        		}
        		else {
        		    # all is ok
        		}

                $bytes += $n;
            }

            $out->close();
            $data->close();

            $bytes;
        }
    };



( run in 1.151 second using v1.01-cache-2.11-cpan-39bf76dae61 )