--- trunk/DBI.pm 2004/08/07 19:06:03 9 +++ trunk/DBI.pm 2004/08/29 20:12:37 13 @@ -9,6 +9,10 @@ use POSIX qw(ENOENT EISDIR EINVAL ENOSYS O_RDWR); use Fuse; use DBI; +use Carp; +use Proc::Simple; +use Data::Dumper; + our $VERSION = '0.01'; @@ -19,7 +23,7 @@ =head1 SYNOPSIS use Fuse::DBI; - Fuse::DBI->run( ... ); + Fuse::DBI->mount( ... ); See L below for examples how to set parametars. @@ -39,11 +43,11 @@ =cut -=head2 run +=head2 mount Mount your database as filesystem. - Fuse::DBI->run({ + my $mnt = Fuse::DBI->mount({ filenames => 'select name from filenamefilenames, read => 'sql read', update => 'sql update', @@ -58,16 +62,25 @@ my $sth; my $ctime_start; -sub run { - my $self = shift +sub read_filenames; + +sub mount { + my $class = shift; + my $self = {}; + bless($self, $class); + + my $arg = shift; - my $arg = {@_}; + print Dumper($arg); - carp "run needs 'dsn' to connect to (e.g. dsn => 'DBI:Pg:dbname=test')" unless ($arg->{'dsn'}); - carp "run needs 'mount' as mountpoint" unless ($arg->{'mount'}); + carp "mount needs 'dsn' to connect to (e.g. dsn => 'DBI:Pg:dbname=test')" unless ($arg->{'dsn'}); + carp "mount needs 'mount' as mountpoint" unless ($arg->{'mount'}); + + # save (some) arguments in self + $self->{$_} = $arg->{$_} foreach (qw(mount)); foreach (qw(filenames read update)) { - carp "run needs '$_' SQL" unless ($arg->{$_}); + carp "mount needs '$_' SQL" unless ($arg->{$_}); } $dbh = DBI->connect($arg->{'dsn'},$arg->{'user'},$arg->{'password'}, { AutoCommit => 0 }) || die $DBI::errstr; @@ -84,24 +97,62 @@ read_filenames; - Fuse::main( - mountpoint=>$arg->{'mount'}, - getattr=>\&e_getattr, - getdir=>\&e_getdir, - open=>\&e_open, - statfs=>\&e_statfs, - read=>\&e_read, - write=>\&e_write, - utime=>\&e_utime, - truncate=>\&e_truncate, - debug=>0, - ); + $self->{'proc'} = Proc::Simple->new(); + $self->{'proc'}->kill_on_destroy(1); + + $self->{'proc'}->start( sub { + Fuse::main( + mountpoint=>$arg->{'mount'}, + getattr=>\&e_getattr, + getdir=>\&e_getdir, + open=>\&e_open, + statfs=>\&e_statfs, + read=>\&e_read, + write=>\&e_write, + utime=>\&e_utime, + truncate=>\&e_truncate, + debug=>0, + ); + } ); + + confess "Fuse::main failed" if (! $self->{'proc'}->poll); + + $self ? return $self : return undef; }; +=head2 umount + +Unmount your database as filesystem. + + $mnt->umount; + +This will also kill background process which is translating +database to filesystem. + +=cut + +sub umount { + my $self = shift; + + confess "no process running?" unless ($self->{'proc'}); + + system "fusermount -u ".$self->{'mount'} || croak "umount error: $!"; + + if ($self->{'proc'}->poll) { + $self->{'proc'}->kill; + return 1 if (! $self->{'proc'}->poll); + } else { + return 1; + } +} + + my %files; my %dirs; sub read_filenames { + my $self = shift; + # create empty filesystem (%files) = ( '.' => { @@ -184,12 +235,11 @@ # return as many text filenames as you like, followed by the retval. print((scalar keys %files)." files total\n"); my %out; - foreach (keys %files) { - my $f = $_; - $f =~ s/^\E$dirname\Q//; - $f =~ s/^\///; + foreach my $f (sort keys %files) { if ($dirname) { - $out{$f}++ if (/^\E$dirname\Q/ && $f =~ /^[^\/]+$/); + if ($f =~ s/^\E$dirname\Q\///) { + $out{$f}++ if ($f =~ /^[^\/]+$/); + } } else { $out{$f}++ if ($f =~ /^[^\/]+$/); } @@ -198,6 +248,7 @@ $out{'no files? bug?'}++; } print scalar keys %out," files in dir '$dirname'\n"; + print "## ",join(" ",keys %out),"\n"; return (keys %out),0; }