Fuse-DBI

 view release on metacpan or  search on metacpan

DBI.pm  view on Meta::CPAN


	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 )