Fuse-DBI
view release on metacpan or search on metacpan
die "read_content needs file and id" unless ($file && $id);
$sth->{'read'}->execute($id) || die $sth->{'read'}->errstr;
$files{$file}{cont} = $sth->{'read'}->fetchrow_array;
# I should modify ctime only if content in database changed
#$files{$file}{ctime} = time() unless ($files{$file}{ctime});
print "file '$file' content [",length($files{$file}{cont})," bytes] read in cache\n";
}
sub e_open {
# VFS sanity check; it keeps all the necessary state, not much to do here.
my $file = filename_fixup(shift);
my $flags = shift;
return -ENOENT() unless exists($files{$file});
return -EISDIR() unless exists($files{$file}{id});
read_content($file,$files{$file}{id}) unless exists($files{$file}{cont});
$files{$file}{cont} ||= '';
print "open '$file' ",length($files{$file}{cont})," bytes\n";
return 0;
}
sub e_read {
# return an error numeric, or binary/text string.
# (note: 0 means EOF, "0" will give a byte (ascii "0")
# to the reading program)
my ($file) = filename_fixup(shift);
my ($buf_len,$off) = @_;
return -ENOENT() unless exists($files{$file});
my $len = length($files{$file}{cont});
print "read '$file' [$len bytes] offset $off length $buf_len\n";
return -EINVAL() if ($off > $len);
return 0 if ($off == $len);
$buf_len = $len-$off if ($len - $off < $buf_len);
return substr($files{$file}{cont},$off,$buf_len);
}
sub clear_cont {
print "transaction rollback\n";
$dbh->rollback || die $dbh->errstr;
print "invalidate all cached content\n";
foreach my $f (keys %files) {
delete $files{$f}{cont};
delete $files{$f}{ctime};
}
print "begin new transaction\n";
#$dbh->begin_work || die $dbh->errstr;
}
sub update_db {
my $file = shift || die;
$files{$file}{ctime} = time();
my ($cont,$id) = (
$files{$file}{cont},
$files{$file}{id}
);
if (!$sth->{'update'}->execute($cont,$id)) {
print "update problem: ",$sth->{'update'}->errstr;
clear_cont;
return 0;
} else {
if (! $dbh->commit) {
print "ERROR: commit problem: ",$sth->{'update'}->errstr;
clear_cont;
return 0;
}
print "updated '$file' [",$files{$file}{id},"]\n";
$$fuse_self->{'invalidate'}->() if (ref $$fuse_self->{'invalidate'});
}
return 1;
}
sub e_write {
my $file = filename_fixup(shift);
my ($buffer,$off) = @_;
return -ENOENT() unless exists($files{$file});
my $cont = $files{$file}{cont};
my $len = length($cont);
print "write '$file' [$len bytes] offset $off length ",length($buffer),"\n";
$files{$file}{cont} = "";
$files{$file}{cont} .= substr($cont,0,$off) if ($off > 0);
$files{$file}{cont} .= $buffer;
$files{$file}{cont} .= substr($cont,$off+length($buffer),$len-$off-length($buffer)) if ($off+length($buffer) < $len);
$files{$file}{size} = length($files{$file}{cont});
if (! update_db($file)) {
return -ENOSYS();
} else {
return length($buffer);
}
}
sub e_truncate {
my $file = filename_fixup(shift);
my $size = shift;
print "truncate to $size\n";
$files{$file}{cont} = substr($files{$file}{cont},0,$size);
$files{$file}{size} = $size;
( run in 2.456 seconds using v1.01-cache-2.11-cpan-98e64b0badf )