Files
zotero_dataserver-docker/zss/ZSS/Store.pm
Gabriele Facciolo 9f2d51be33 initial commit
2016-08-24 01:34:02 +02:00

165 lines
2.9 KiB
Perl

package ZSS::Store;
use strict;
use warnings;
use Digest::MD5 qw (md5_hex);
use File::Util qw(escape_filename);
use File::Path qw(make_path);
sub new {
my $class = shift;
# TODO: read from config
my $self = {storagepath => shift};
bless $self, $class;
}
sub get_path {
my $self = shift;
my $key = shift;
my $dirname = md5_hex($key);
my $dir = $self->{storagepath} . substr($dirname, 0, 1) . "/" . $dirname ."/";
return $dir;
}
sub get_filename {
my $self = shift;
my $key = shift;
return escape_filename($key, '_');
}
sub get_filepath {
my $self = shift;
my $key = shift;
return $self->get_path($key) . $self->get_filename($key);
}
sub store_file {
my $self = shift;
my $key = shift;
my $data = shift;
my $meta = shift;
my $dir = $self->get_path($key);
my $file = $self->get_filename($key);
make_path($dir);
# Write data to temp file and rename to the desired name
# This only changes this file and not other hardlinks
open(my $fh, '>:raw', $dir.$file.".temp");
print $fh ($data);
close($fh);
rename($dir.$file.".temp", $dir.$file);
if ($meta) {
open($fh, '>:raw', $dir.$file.".meta.temp");
print $fh ($meta);
close($fh);
rename($dir.$file.".meta.temp", $dir.$file.".meta");
}
}
sub check_exists{
my $self = shift;
my $key = shift;
my $path = $self->get_filepath($key);
unless (-e $path){
return 0;
}
return 1;
}
sub retrieve_file {
my $self = shift;
my $key = shift;
unless($self->check_exists($key)){
return undef;
}
my $path = $self->get_filepath($key);
open(my $fh, '<:raw', $path);
return $fh;
}
sub retrieve_filemeta {
my $self = shift;
my $key = shift;
unless($self->check_exists($key)){
return undef;
}
my $metafile = $self->get_filepath($key) . ".meta";
# check if metadata is present
unless (-e $metafile) {
return undef;
}
# limt size of metadata to 8kB
my $size = -s $metafile;
unless ($size <= 8192) {
return undef;
}
my $meta;
open(my $fh, '<:raw', $metafile);
read ($fh, $meta, $size);
return $meta;
}
sub get_size{
my $self = shift;
my $key = shift;
my $path = $self->get_filepath($key);
unless (-e $path) {
return 0;
}
my $size = -s $path;
return $size;
}
sub link_files{
my $self = shift;
my $source_key = shift;
my $destination_key = shift;
my $source_path = $self->get_filepath($source_key);
my $destination_dir = $self->get_path($destination_key);
my $destination_path = $self->get_filepath($destination_key);
make_path($destination_dir);
link($source_path.".meta", $destination_path.".meta");
return link($source_path, $destination_path);
}
sub delete_file{
my $self = shift;
my $key = shift;
my $dir = $self->get_path($key);
my $file = $self->get_filename($key);
# Remove metadata
unlink($dir.$file.".meta");
unless (unlink($dir.$file)) {
return 1;
}
return rmdir($dir);
}
1;