package Catmandu::Store::File::Simple; our $VERSION = '1.16'; use Catmandu::Sane; use Moo; use Carp; use Catmandu; use Catmandu::Util; use Catmandu::Store::File::Simple::Index; use Catmandu::Store::File::Simple::Bag; use Catmandu::DirectoryIndex::UUID; use Catmandu::DirectoryIndex::Number; use namespace::clean; with 'Catmandu::FileStore'; with 'Catmandu::Droppable'; has root => (is => 'ro', required => '1'); #DEPRECATED has uuid => (is => 'ro'); #DEPRECATED has keysize => ( is => 'ro', isa => sub { Catmandu::Util::check_natural($_[0]); croak "keysize needs to be a multiple of 3" unless $_[0] % 3 == 0; }, default => 9 ); has directory_index_package => (is => "ro"); has directory_index_options => (is => "ro", lazy => 1, default => sub {+{};}); has directory_index => (is => "lazy"); sub _build_directory_index { my $self = $_[0]; if ($self->directory_index_package()) { Catmandu::Util::require_package($self->directory_index_package(), "Catmandu::DirectoryIndex") ->new(%{$self->directory_index_options(),}, base_dir => $self->root()); } elsif ($self->uuid()) { Catmandu::DirectoryIndex::UUID->new(base_dir => $self->root()); } else { Catmandu::DirectoryIndex::Number->new( base_dir => $self->root(), keysize => $self->keysize() ); } } sub drop { my ($self) = @_; $self->index->delete_all; } 1; __END__ =pod =head1 NAME Catmandu::Store::File::Simple - A Catmandu::FileStore to store files on disk =head1 SYNOPSIS # From the command line # Export a list of all file containers $ catmandu export File::Simple --root t/data to YAML # Export a list of all files in container '1234' $ catmandu export File::Simple --root t/data --bag 1234 to YAML # Add a file to the container '1234' $ catmandu stream /tmp/myfile.txt to File::Simple --root t/data --bag 1234 --id myfile.txt # Download the file 'myfile.txt' from the container '1234' $ catmandu stream File::Simple --root t/data --bag 1234 --id myfile.txt to /tmp/output.txt # Delete the file 'myfile.txt' from the container '1234' $ catmandu delete File::Simple --root t/data --bag 1234 --id myfile.txt # Define a configuration file $ cat catmandu.yml --- store: mypaths: package: DBI options: data_source: dbi:sqlite:dbname=data/index.db myfiles: package: File::Simple options: root: data/files directory_index_package: Map directory_index_options: store_name: mypaths bag_name: data ... # Use the default 'catmandu.yml' configuraion file to add data to the FileStore $ catmandu stream /tmp/myfile.txt to myfiles --bag 1234 --id myfile.txt $ catmandu stream myfiles --bag 1234 --id myfile.txt to /tmp/myfile.txt # From Perl use Catmandu; my $store = Catmandu->store('File::Simple' , root => 't/data'); my $index = $store->index; # List all folder $index->bag->each(sub { my $container = shift; print "%s\n" , $container->{_id}; }); # Add a new folder $index->add({ _id => '1234' }); # Get the folder my $files = $index->files('1234'); # Add a file to the folder $files->upload(IO::File->new('get('foobar.txt'); # Stream the contents of a file $files->stream(IO::File->new('>foobar.txt'), $file); # Delete a file $files->delete('foobar.txt'); # Delete a folder $index->delete('1234'); =head1 DESCRIPTION L is a L implementation to store files in a directory structure. Each L is a deeply nested directory based on the numeric identifier of the bag. E.g. $store->bag(1234) is stored as ${ROOT}/000/001/234 In this directory all the L items are stored as flat files. =head1 METHODS =head2 new(root => $path , [ keysize => NUM , uuid => 1]) Create a new Catmandu::Store::File::Simple with the following configuration parameters: =over =item root The root directory where to store all the files. Required. =item keysize DEPRECATED: use directory_index_package and directory_index_options By default the directory structure is 3 levels deep. With the keysize option a deeper nesting can be created. The keysize needs to be a multiple of 3. All the container keys of a L must be integers. =item uuid DEPRECATED: use directory_index_package and directory_index_options If the to a true value, then the Simple store will require UUID-s as keys =item directory_index_package package name that translates between id and a directory. prefix "Catmandu::DirectoryIndex::" can be omitted. Default: L =item directory_index_options Constructor arguments for the directory_index_package (see above) =item directory_index instance of L. When supplied, directory_index_package and directory_index_options are ignored. When not, this object is constructed from directory_index_package and directory_index_options. =back =head1 INHERITED METHODS This Catmandu::FileStore implements: =over 3 =item L =item L =back The index Catmandu::Bag in this Catmandu::Store implements: =over 3 =item L =item L =item L =back The file Catmandu::Bag in this Catmandu::Store implements: =over 3 =item L =item L =item L =back =head1 SEE ALSO L, L, L, L =cut