1 package SL::File::Backend::Filesystem;
5 use parent qw(SL::File::Backend);
9 use File::Path qw(make_path);
16 my ($self, %params) = @_;
17 $main::lxdebug->message(LXDebug->DEBUG2(), "del in backend " . $self . " file " . $params{dbfile});
18 $main::lxdebug->message(LXDebug->DEBUG2(), "file id=" . ($params{dbfile}->id * 1));
19 die "no dbfile" unless $params{dbfile};
20 my $backend_data = $params{dbfile}->backend_data;
21 $backend_data = 0 if $params{last};
22 $backend_data = $params{dbfile}->backend_data-1 if $params{all_but_notlast};
24 if ($backend_data > 0 ) {
25 $main::lxdebug->message(LXDebug->DEBUG2(), "backend_data=" .$backend_data);
26 for my $version ( 1..$backend_data) {
27 my $file_path = $self->_filesystem_path($params{dbfile},$version);
28 $main::lxdebug->message(LXDebug->DEBUG2(), "unlink " .$file_path);
31 if ($params{all_but_notlast}) {
32 my $from = $self->_filesystem_path($params{dbfile},$params{dbfile}->backend_data);
33 my $to = $self->_filesystem_path($params{dbfile},$params{dbfile}->backend_data);
34 die "file not exists" unless -f $from;
36 $params{dbfile}->backend_data(1);
38 $params{dbfile}->backend_data(0);
39 my $dir_path = $self->_filesystem_path($params{dbfile});
41 $main::lxdebug->message(LXDebug->DEBUG2(), "unlink " .$dir_path);
44 my $file_path = $self->_filesystem_path($params{dbfile},$params{dbfile}->backend_data);
45 die "file not exists" unless -f $file_path;
47 $params{dbfile}->backend_data($params{dbfile}->backend_data-1);
55 my ($self, %params) = @_;
56 die 'dbfile not exists' unless $params{dbfile};
57 $main::lxdebug->message(LXDebug->DEBUG2(), "in backend " . $self . " file " . $params{dbfile});
58 $main::lxdebug->message(LXDebug->DEBUG2(), "file id=" . $params{dbfile}->id . " path=" . $params{file_path});
59 my $dbfile = $params{dbfile};
60 die 'no file contents' unless $params{file_path} || $params{file_contents};
61 $dbfile->backend_data(0) unless $dbfile->backend_data;
62 $dbfile->backend_data($dbfile->backend_data*1+1);
65 my $tofile = $self->_filesystem_path($dbfile);
66 $main::lxdebug->message(LXDebug->DEBUG2(), "topath=" . $tofile . " from=" . $params{file_path});
67 if ($params{file_path} && -f $params{file_path}) {
68 File::Copy::copy($params{file_path}, $tofile);
70 elsif ($params{file_contents}) {
71 open(OUT, "> " . $tofile);
72 print OUT $params{file_contents};
78 sub get_version_count {
79 my ($self, %params) = @_;
80 die "no dbfile" unless $params{dbfile};
81 return $params{dbfile}->backend_data * 1;
85 my ($self, %params) = @_;
86 die "no dbfile" unless $params{dbfile};
87 $main::lxdebug->message(LXDebug->DEBUG2(), "version=" .$params{version});
88 die "unknown version" if $params{version} &&
89 ($params{version} < 0 || $params{version} > $params{dbfile}->backend_data) ;
90 my $path = $self->_filesystem_path($params{dbfile},$params{version});
91 die "no file found in backend" if !-f $path;
93 my $dt = DateTime->from_epoch(epoch => $st[9])->clone();
94 $main::lxdebug->message(LXDebug->DEBUG2(), "dt=" .$dt);
99 my ($self, %params) = @_;
100 die "no dbfile" unless $params{dbfile};
101 my $path = $self->_filesystem_path($params{dbfile},$params{version});
102 die "no file" if !-f $path;
107 my ($self, %params) = @_;
108 my $path = $self->get_filepath(%params);
109 return "" unless $path;
110 my $contents = File::Slurp::read_file($path);
115 return 0 unless $::instance_conf->get_doc_files || $::instance_conf->get_doc_files_rootpath;
116 $main::lxdebug->message(LXDebug->DEBUG2(), "root path=" . $::instance_conf->get_doc_files_rootpath . " isdir=" .( -d $::instance_conf->get_doc_files_rootpath?"YES":"NO"));
117 return 0 unless -d $::instance_conf->get_doc_files_rootpath;
126 sub _filesystem_path {
127 my ($self, $dbfile, $version) = @_;
129 die "No files backend enabled" unless $::instance_conf->get_doc_files || $::instance_conf->get_doc_files_rootpath;
131 # use filesystem with depth 3
132 $version = $dbfile->backend_data if !$version || $version < 1 || $version > $dbfile->backend_data;
133 my $iddir = sprintf("%04d", $dbfile->id % 1000);
134 my $path = File::Spec->catdir($::instance_conf->get_doc_files_rootpath, $iddir, $dbfile->id);
135 $main::lxdebug->message(LXDebug->DEBUG2(), "file path=" .$path." id=" .$dbfile->id." version=".$version." basename=".$dbfile->id . '_' . $version);
137 File::Path::make_path($path, { chmod => 0770 });
139 return $path if !$version;
140 return File::Spec->catdir($path, $dbfile->id . '_' . $version);
153 SL::File::Backend::Filesystem - Filesystem class for file storage backend
157 See the synopsis of L<SL::File::Backend>.
161 This specific storage backend use a Filesystem which is only accessed by this interface.
162 This is the big difference to the Webdav backend where the files can be accessed without the control of that backend.
163 This backend use the database id of the SL::DB::File object as filename. The filesystem has up to 1000 subdirectories
164 to store the files not to flat in the filesystem. In this Subdirectories for each file an additional subdirectory exists
165 for the versions of this file.
167 The Versioning is done via a Versionnumber which is incremented by one for each version.
168 So the Version 2 of the file with the database id 4 is stored as path {root}/0004/4/4_2.
173 See methods of L<SL::File::Backend>.
181 Martin Helmling E<lt>martin.helmling@opendynamic.deE<gt>