/[fuse_dbi]/fuse-couchdb/DBI.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /fuse-couchdb/DBI.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 32 by dpavlin, Mon Nov 15 20:45:03 2004 UTC revision 52 by dpavlin, Sat Nov 27 15:08:10 2004 UTC
# Line 12  use DBI; Line 12  use DBI;
12  use Carp;  use Carp;
13  use Data::Dumper;  use Data::Dumper;
14    
15    our $VERSION = '0.07';
16    
17  our $VERSION = '0.04';  # block size for this filesystem
18    use constant BLOCK => 1024;
19    
20  =head1 NAME  =head1 NAME
21    
# Line 29  See C<run> below for examples how to set Line 31  See C<run> below for examples how to set
31  =head1 DESCRIPTION  =head1 DESCRIPTION
32    
33  This module will use C<Fuse> module, part of C<FUSE (Filesystem in USErspace)>  This module will use C<Fuse> module, part of C<FUSE (Filesystem in USErspace)>
34  available at L<http://sourceforge.net/projects/avf> to mount  available at L<http://fuse.sourceforge.net/> to mount
35  your database as file system.  your database as file system.
36    
37  That will give you possibility to use normal file-system tools (cat, grep, vi)  That will give you possibility to use normal file-system tools (cat, grep, vi)
# Line 132  sub mount { Line 134  sub mount {
134    
135          print Dumper($arg);          print Dumper($arg);
136    
137            unless ($self->fuse_module_loaded) {
138                    print STDERR "no fuse module loaded. Trying sudo modprobe fuse!\n";
139                    system "sudo modprobe fuse" || die "can't modprobe fuse using sudo!\n";
140            }
141    
142          carp "mount needs 'dsn' to connect to (e.g. dsn => 'DBI:Pg:dbname=test')" unless ($arg->{'dsn'});          carp "mount needs 'dsn' to connect to (e.g. dsn => 'DBI:Pg:dbname=test')" unless ($arg->{'dsn'});
143          carp "mount needs 'mount' as mountpoint" unless ($arg->{'mount'});          carp "mount needs 'mount' as mountpoint" unless ($arg->{'mount'});
144    
# Line 152  sub mount { Line 159  sub mount {
159                  die "fork() failed: $!" unless defined $pid;                  die "fork() failed: $!" unless defined $pid;
160                  # child will return to caller                  # child will return to caller
161                  if ($pid) {                  if ($pid) {
162                          return $self;                          my $counter = 4;
163                            while ($counter && ! $self->is_mounted) {
164                                    select(undef, undef, undef, 0.5);
165                                    $counter--;
166                            }
167                            if ($self->is_mounted) {
168                                    return $self;
169                            } else {
170                                    return undef;
171                            }
172                  }                  }
173          }          }
174    
# Line 169  sub mount { Line 185  sub mount {
185          $self->{'read_filenames'} = sub { $self->read_filenames };          $self->{'read_filenames'} = sub { $self->read_filenames };
186          $self->read_filenames;          $self->read_filenames;
187    
         $self->{'mounted'} = 1;  
   
188          $fuse_self = \$self;          $fuse_self = \$self;
189    
190          Fuse::main(          Fuse::main(
# Line 188  sub mount { Line 202  sub mount {
202                  debug=>0,                  debug=>0,
203          );          );
204                    
         $self->{'mounted'} = 0;  
   
205          exit(0) if ($arg->{'fork'});          exit(0) if ($arg->{'fork'});
206    
207          return 1;          return 1;
208    
209  };  };
210    
211    =head2 is_mounted
212    
213    Check if fuse filesystem is mounted
214    
215      if ($mnt->is_mounted) { ... }
216    
217    =cut
218    
219    sub is_mounted {
220            my $self = shift;
221    
222            my $mounted = 0;
223            my $mount = $self->{'mount'} || confess "can't find mount point!";
224            if (open(MTAB, "/etc/mtab")) {
225                    while(<MTAB>) {
226                            $mounted = 1 if (/ $mount fuse /i);
227                    }
228                    close(MTAB);
229            } else {
230                    warn "can't open /etc/mtab: $!";
231            }
232    
233            return $mounted;
234    }
235    
236    
237  =head2 umount  =head2 umount
238    
239  Unmount your database as filesystem.  Unmount your database as filesystem.
# Line 210  database to filesystem. Line 248  database to filesystem.
248  sub umount {  sub umount {
249          my $self = shift;          my $self = shift;
250    
251          if ($self->{'mounted'}) {          if ($self->{'mount'} && $self->is_mounted) {
252                  system "fusermount -u ".$self->{'mount'} || croak "umount error: $!";                  system "( fusermount -u ".$self->{'mount'}." 2>&1 ) >/dev/null" ||
253                            system "sudo umount ".$self->{'mount'} ||
254                            return 0;
255                    return 1;
256          }          }
257    
258          return 1;          return 0;
259  }  }
260    
261  $SIG{'INT'} = sub {  $SIG{'INT'} = sub {
262          print STDERR "umount called by SIG INT\n";          if ($fuse_self && $$fuse_self->umount) {
263          umount;                  print STDERR "umount called by SIG INT\n";
264            }
265    };
266    
267    $SIG{'QUIT'} = sub {
268            if ($fuse_self && $$fuse_self->umount) {
269                    print STDERR "umount called by SIG QUIT\n";
270            }
271  };  };
272    
273  sub DESTROY {  sub DESTROY {
274          my $self = shift;          my $self = shift;
275          return if (! $self->{'mounted'});          if ($self->umount) {
276          print STDERR "umount called by DESTROY\n";                  print STDERR "umount called by DESTROY\n";
277          $self->umount;          }
278  }  }
279    
280  =head2 fuse_module_loaded  =head2 fuse_module_loaded
# Line 251  sub fuse_module_loaded { Line 299  sub fuse_module_loaded {
299  }  }
300    
301  my %files;  my %files;
 my %dirs;  
302    
303  sub read_filenames {  sub read_filenames {
304          my $self = shift;          my $self = shift;
# Line 264  sub read_filenames { Line 311  sub read_filenames {
311                          type => 0040,                          type => 0040,
312                          mode => 0755,                          mode => 0755,
313                  },                  },
314                    '..' => {
315                            type => 0040,
316                            mode => 0755,
317                    },
318          #       a => {          #       a => {
319          #               cont => "File 'a'.\n",          #               cont => "File 'a'.\n",
320          #               type => 0100,          #               type => 0100,
# Line 287  sub read_filenames { Line 338  sub read_filenames {
338                          # first, entry is assumed to be file                          # first, entry is assumed to be file
339                          if ($d) {                          if ($d) {
340                                  $files{$d} = {                                  $files{$d} = {
                                                 size => $dirs{$d}++,  
341                                                  mode => 0755,                                                  mode => 0755,
342                                                  type => 0040                                                  type => 0040
343                                  };                                  };
# Line 305  sub read_filenames { Line 355  sub read_filenames {
355                  }                  }
356          }          }
357    
358          print "found ",scalar(keys %files)-scalar(keys %dirs)," files, ",scalar(keys %dirs), " dirs\n";          print "found ",scalar(keys %files)," files\n";
359  }  }
360    
361    
# Line 321  sub e_getattr { Line 371  sub e_getattr {
371          $file =~ s,^/,,;          $file =~ s,^/,,;
372          $file = '.' unless length($file);          $file = '.' unless length($file);
373          return -ENOENT() unless exists($files{$file});          return -ENOENT() unless exists($files{$file});
374          my ($size) = $files{$file}{size} || 1;          my ($size) = $files{$file}{size} || BLOCK;
375          my ($dev, $ino, $rdev, $blocks, $gid, $uid, $nlink, $blksize) = (0,0,0,1,0,0,1,1024);          my ($dev, $ino, $rdev, $blocks, $gid, $uid, $nlink, $blksize) = (0,0,0,int(($size+BLOCK-1)/BLOCK),0,0,1,BLOCK);
376          my ($atime, $ctime, $mtime);          my ($atime, $ctime, $mtime);
377          $atime = $ctime = $mtime = $files{$file}{ctime} || $ctime_start;          $atime = $ctime = $mtime = $files{$file}{ctime} || $ctime_start;
378    
# Line 330  sub e_getattr { Line 380  sub e_getattr {
380    
381          # 2 possible types of return values:          # 2 possible types of return values:
382          #return -ENOENT(); # or any other error you care to          #return -ENOENT(); # or any other error you care to
383          #print(join(",",($dev,$ino,$modes,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks)),"\n");          print "getattr($file) ",join(",",($dev,$ino,$modes,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks)),"\n";
384          return ($dev,$ino,$modes,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks);          return ($dev,$ino,$modes,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks);
385  }  }
386    
# Line 495  sub e_utime { Line 545  sub e_utime {
545          return 0;          return 0;
546  }  }
547    
548  sub e_statfs { return 255, 1, 1, 1, 1, 2 }  sub e_statfs {
549    
550            my $size = 0;
551            my $inodes = 0;
552    
553            foreach my $f (keys %files) {
554                    if ($f !~ /(^|\/)\.\.?$/) {
555                            $size += $files{$f}{size} || 0;
556                            $inodes++;
557                    }
558                    print "$inodes: $f [$size]\n";
559            }
560    
561            $size = int(($size+BLOCK-1)/BLOCK);
562    
563            my @ret = (255, $inodes, 1, $size, $size-1, BLOCK);
564    
565            print "statfs: ",join(",",@ret),"\n";
566    
567            return @ret;
568    }
569    
570  sub e_unlink {  sub e_unlink {
571          my $file = filename_fixup(shift);          my $file = filename_fixup(shift);
572    
573          if (exists( $dirs{$file} )) {  #       if (exists( $dirs{$file} )) {
574                  print "unlink '$file' will re-read template names\n";  #               print "unlink '$file' will re-read template names\n";
575                  print Dumper($fuse_self);  #               print Dumper($fuse_self);
576                  $$fuse_self->{'read_filenames'}->();  #               $$fuse_self->{'read_filenames'}->();
577                  return 0;  #               return 0;
578          } elsif (exists( $files{$file} )) {          if (exists( $files{$file} )) {
579                  print "unlink '$file' will invalidate cache\n";                  print "unlink '$file' will invalidate cache\n";
580                  read_content($file,$files{$file}{id});                  read_content($file,$files{$file}{id});
581                  return 0;                  return 0;
# Line 520  __END__ Line 590  __END__
590    
591  Nothing.  Nothing.
592    
593    =head1 BUGS
594    
595    Size information (C<ls -s>) is wrong. It's a problem in upstream Fuse module
596    (for which I'm to blame lately), so when it gets fixes, C<Fuse::DBI> will
597    automagically pick it up.
598    
599  =head1 SEE ALSO  =head1 SEE ALSO
600    
601  C<FUSE (Filesystem in USErspace)> website  C<FUSE (Filesystem in USErspace)> website
602  L<http://sourceforge.net/projects/avf>  L<http://fuse.sourceforge.net/>
603    
604  Example for WebGUI which comes with this distribution in  Example for WebGUI which comes with this distribution in
605  directory C<examples/webgui.pl>. It also contains a lot of documentation  directory C<examples/webgui.pl>. It also contains a lot of documentation

Legend:
Removed from v.32  
changed lines
  Added in v.52

  ViewVC Help
Powered by ViewVC 1.1.26