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 die "no dbfile in backend delete" unless $params{dbfile};
18 my $backend_data = $params{dbfile}->backend_data;
19 $backend_data = 0 if $params{last};
20 $backend_data = $params{dbfile}->backend_data-1 if $params{all_but_notlast};
22 if ($backend_data > 0 ) {
23 for my $version ( 1..$backend_data) {
24 my $file_path = $self->_filesystem_path($params{dbfile},$version);
27 if ($params{all_but_notlast}) {
28 my $from = $self->_filesystem_path($params{dbfile},$params{dbfile}->backend_data);
29 my $to = $self->_filesystem_path($params{dbfile},1);
30 die "file not exists in backend delete" unless -f $from;
32 $params{dbfile}->backend_data(1);
34 $params{dbfile}->backend_data(0);
35 my $dir_path = $self->_filesystem_path($params{dbfile});
39 my $file_path = $self->_filesystem_path($params{dbfile},$params{dbfile}->backend_data);
40 die "file not exists in backend delete" unless -f $file_path;
42 $params{dbfile}->backend_data($params{dbfile}->backend_data-1);
51 my ($self, %params) = @_;
52 die 'dbfile not exists' unless $params{dbfile};
53 my $dbfile = $params{dbfile};
54 die 'no file contents' unless $params{file_path} || $params{file_contents};
55 $dbfile->backend_data(0) unless $dbfile->backend_data;
56 $dbfile->backend_data($dbfile->backend_data*1+1);
59 my $tofile = $self->_filesystem_path($dbfile);
60 if ($params{file_path} && -f $params{file_path}) {
61 File::Copy::copy($params{file_path}, $tofile);
63 elsif ($params{file_contents}) {
64 open(OUT, "> " . $tofile);
65 print OUT $params{file_contents};
71 sub get_version_count {
72 my ($self, %params) = @_;
73 die "no dbfile" unless $params{dbfile};
74 return $params{dbfile}->backend_data * 1;
78 my ($self, %params) = @_;
79 die "no dbfile" unless $params{dbfile};
80 die "unknown version" if $params{version} &&
81 ($params{version} < 0 || $params{version} > $params{dbfile}->backend_data);
82 my $path = $self->_filesystem_path($params{dbfile}, $params{version});
84 die "No file found at $path. Expected: $params{dbfile}{file_name}, file.id: $params{dbfile}{id}" if !-f $path;
87 my $dt = DateTime->from_epoch(epoch => $st[9])->clone();
92 my ($self, %params) = @_;
93 die "no dbfile" unless $params{dbfile};
94 my $path = $self->_filesystem_path($params{dbfile},$params{version});
95 die "no file in backend get_filepath" if !-f $path;
100 my ($self, %params) = @_;
101 my $path = $self->get_filepath(%params);
102 return "" unless $path;
103 my $contents = File::Slurp::read_file($path);
108 return 0 unless $::instance_conf->get_doc_files;
109 return 0 unless $::lx_office_conf{paths}->{document_path};
110 return 0 unless -d $::lx_office_conf{paths}->{document_path};
114 sub sync_from_backend {
115 my ($self, %params) = @_;
116 my @query = (file_type => $params{file_type});
117 push @query, (file_name => $params{file_name}) if $params{file_name};
118 push @query, (mime_type => $params{mime_type}) if $params{mime_type};
119 push @query, (source => $params{source}) if $params{source};
121 my $sortby = $params{sort_by} || 'itime DESC,file_name ASC';
123 my @files = @{ SL::DB::Manager::File->get_all(query => [@query], sort_by => $sortby) };
125 $main::lxdebug->message(LXDebug->DEBUG2(), "file id=" . $_->id." version=".$_->backend_data);
126 my $newversion = $_->backend_data;
127 for my $version ( reverse 1 .. $_->backend_data ) {
128 my $path = $self->_filesystem_path($_, $version);
129 $main::lxdebug->message(LXDebug->DEBUG2(), "path=".$path." exists=".( -f $path?1:0));
131 $newversion = $version - 1;
133 $main::lxdebug->message(LXDebug->DEBUG2(), "newversion=".$newversion." version=".$_->backend_data);
134 if ( $newversion < $_->backend_data ) {
135 $_->backend_data($newversion);
136 $_->save if $newversion > 0;
137 $_->delete if $newversion <= 0;
147 sub _filesystem_path {
148 my ($self, $dbfile, $version) = @_;
150 die "No files backend enabled" unless $::instance_conf->get_doc_files || $::lx_office_conf{paths}->{document_path};
152 # use filesystem with depth 3
153 $version = $dbfile->backend_data if !$version || $version < 1 || $version > $dbfile->backend_data;
154 my $iddir = sprintf("%04d", $dbfile->id % 1000);
155 my $path = File::Spec->catdir($::lx_office_conf{paths}->{document_path}, $::auth->client->{id}, $iddir, $dbfile->id);
157 File::Path::make_path($path, { chmod => 0770 });
159 return $path if !$version;
160 return File::Spec->catdir($path, $dbfile->id . '_' . $version);
173 SL::File::Backend::Filesystem - Filesystem class for file storage backend
177 See the synopsis of L<SL::File::Backend>.
181 This specific storage backend use a Filesystem which is only accessed by this interface.
182 This is the big difference to the Webdav backend where the files can be accessed without the control of that backend.
183 This backend use the database id of the SL::DB::File object as filename. The filesystem has up to 1000 subdirectories
184 to store the files not to flat in the filesystem. In this Subdirectories for each file an additional subdirectory exists
185 for the versions of this file.
187 The Versioning is done via a Versionnumber which is incremented by one for each version.
188 So the Version 2 of the file with the database id 4 is stored as path {root}/0004/4/4_2.
193 See methods of L<SL::File::Backend>.
201 Martin Helmling E<lt>martin.helmling@opendynamic.deE<gt>