first try at making it writable
authorDobrica Pavlinusic <dpavlin@rot13.org>
Wed, 4 Aug 2004 16:17:09 +0000 (16:17 +0000)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Wed, 4 Aug 2004 16:17:09 +0000 (16:17 +0000)
git-svn-id: svn://svn.rot13.org/fuse_dbi/trunk@6 17f4e80c-d0e0-0310-8903-bfc3ae804c12

Makefile
fuse_dbi.pl

index 7068194..a09d827 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,5 @@
 all:
 all:
+       sudo modprobe fuse
        sudo umount /mnt2 || exit 0
        ./fuse_dbi.pl /mnt2
        sudo umount /mnt2
        sudo umount /mnt2 || exit 0
        ./fuse_dbi.pl /mnt2
        sudo umount /mnt2
index a3cfa00..a19c92c 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 
 #!/usr/bin/perl
 
-use POSIX qw(ENOENT EISDIR EINVAL);
+use POSIX qw(ENOENT EISDIR EINVAL O_RDWR);
 use Fuse;
 
 use DBI;
 use Fuse;
 
 use DBI;
@@ -15,10 +15,16 @@ my $sql_filenames = q{
        from template ;
 };
 
        from template ;
 };
 
-my $sql_content = q{
+my $sql_read = q{
        select template
        select template
-       from template
-       where oid = ?;
+               from template
+               where oid = ?;
+};
+
+my $sql_update = q{
+       update template
+               set template = ?        
+               where oid = ?;
 };
 
 
 };
 
 
@@ -31,7 +37,8 @@ print STDERR "$sql_filenames\n";
 my $sth_filenames = $dbh->prepare($sql_filenames) || die $dbh->errstr();
 $sth_filenames->execute() || die $sth_filenames->errstr();
 
 my $sth_filenames = $dbh->prepare($sql_filenames) || die $dbh->errstr();
 $sth_filenames->execute() || die $sth_filenames->errstr();
 
-my $sth_content = $dbh->prepare($sql_content) || die $dbh->errstr();
+my $sth_read = $dbh->prepare($sql_read) || die $dbh->errstr();
+my $sth_update = $dbh->prepare($sql_update) || die $dbh->errstr();
 
 print "#",join(",",@{ $sth_filenames->{NAME} }),"\n";
 
 
 print "#",join(",",@{ $sth_filenames->{NAME} }),"\n";
 
@@ -132,14 +139,29 @@ sub e_getdir {
        return (keys %out),0;
 }
 
        return (keys %out),0;
 }
 
+my $in_transaction = 0;
+
 sub e_open {
        # VFS sanity check; it keeps all the necessary state, not much to do here.
 sub e_open {
        # VFS sanity check; it keeps all the necessary state, not much to do here.
-       my ($file) = filename_fixup(shift);
+       my $file = filename_fixup(shift);
+       my $flags = shift;
+
        return -ENOENT() unless exists($files{$file});
        return -EISDIR() unless exists($files{$file}{id});
        return -ENOENT() unless exists($files{$file});
        return -EISDIR() unless exists($files{$file}{id});
+
+       if (! $in_transaction) {
+               # begin transaction
+               if (! $dbh->begin_work) {
+                       print "transaction begin: ",$dbh->errstr;
+                       return -ENOENT();
+               }
+       }
+       $in_transaction++;
+       print "files opened: $in_transaction\n";
+
        if (!exists($files{$file}{cont})) {
        if (!exists($files{$file}{cont})) {
-               $sth_content->execute($files{$file}{id});
-               $files{$file}{cont} = $sth_content->fetchrow_array;
+               $sth_read->execute($files{$file}{id}) || die $sth_read->errstr;
+               $files{$file}{cont} = $sth_read->fetchrow_array;
        }
        print "open '$file' ",length($files{$file}{cont})," bytes\n";
        return 0;
        }
        print "open '$file' ",length($files{$file}{cont})," bytes\n";
        return 0;
@@ -166,6 +188,77 @@ sub e_read {
        return substr($files{$file}{cont},$off,$buf);
 }
 
        return substr($files{$file}{cont},$off,$buf);
 }
 
+sub clear_cont {
+       print "invalidate all cached content\n";
+       foreach my $f (keys %files) {
+               delete $files{$f}{cont};
+       }
+}
+
+
+sub update_db {
+       my $file = shift || die;
+
+       if (!$sth_update->execute($files{$file}{cont},$files{$file}{id})) {
+               print "update problem: ",$sth_update->errstr;
+               $dbh->rollback;
+               clear_cont;
+               $dbh->begin_work;
+               return 0;
+       } else {
+               if ($dbh->commit) {
+                       print "commit problem: ",$sth_update->errstr;
+                       $dbh->rollback;
+                       clear_cont;
+                       $dbh->begin_work;
+                       return 0;
+               }
+               print "updated '$file' [",$files{$file}{id},"]\n";
+       }
+       return 1;
+}
+
+sub e_write {
+       my $file = filename_fixup(shift);
+       my ($buf,$off) = @_;
+
+       return -ENOENT() unless exists($files{$file});
+
+       my $len = length($files{$file}{cont});
+
+       print "write '$file' [$len bytes] offset $off length $buf\n";
+
+       $files{$file}{cont} =
+               substr($files{$file}{cont},0,$off) .
+               $buf .
+               substr($files{$file}{cont},$off+length($buf));
+
+       if (! update_db($file)) {
+               return -ENOSYS();
+       } else {
+               return length($buf);
+       }
+}
+
+sub e_truncate {
+       my $file = filename_fixup(shift);
+       my $size = shift;
+
+       $files{$file}{cont} = substr($files{$file}{cont},0,$size);
+       return 0
+};
+
+
+sub e_utime {
+       my ($atime,$mtime,$file) = @_;
+       $file = filename_fixup($file);
+
+       return -ENOENT() unless exists($files{$file});
+
+       $files{$file}{time} = $mtime;
+       return 0;
+}
+
 sub e_statfs { return 255, 1, 1, 1, 1, 2 }
 
 # If you run the script directly, it will run fusermount, which will in turn
 sub e_statfs { return 255, 1, 1, 1, 1, 2 }
 
 # If you run the script directly, it will run fusermount, which will in turn
@@ -179,5 +272,8 @@ Fuse::main(
        open=>\&e_open,
        statfs=>\&e_statfs,
        read=>\&e_read,
        open=>\&e_open,
        statfs=>\&e_statfs,
        read=>\&e_read,
+       write=>\&e_write,
+       utime=>\&e_utime,
+       truncate=>\&e_truncate,
        debug=>1,
 );
        debug=>1,
 );