111 |
|
|
112 |
=back |
=back |
113 |
|
|
114 |
|
There is also alternative way which can generate C<read> and C<update> |
115 |
|
queries on the fly: |
116 |
|
|
117 |
|
my $mnt = Fuse::DBI->mount({ |
118 |
|
'filenames' => 'select id,filename,size,writable from files', |
119 |
|
'read' => sub { |
120 |
|
my ($path,$file) = @_; |
121 |
|
return( 'select content from files where id = ?', $file->{row}->{id} ); |
122 |
|
}, |
123 |
|
'update' => sub { |
124 |
|
my ($path,$file) = @_; |
125 |
|
return( 'update files set content = ? where id = ?', $file->{row}->{id} ); |
126 |
|
}, |
127 |
|
'dsn' => 'DBI:Pg:dbname=test_db', |
128 |
|
'user' => 'database_user', |
129 |
|
'password' => 'database_password', |
130 |
|
'invalidate' => sub { ... }, |
131 |
|
}); |
132 |
|
|
133 |
=cut |
=cut |
134 |
|
|
135 |
my $dbh; |
my $dbh; |
195 |
|
|
196 |
$sth->{'filenames'} = $dbh->prepare($arg->{'filenames'}) || die $dbh->errstr(); |
$sth->{'filenames'} = $dbh->prepare($arg->{'filenames'}) || die $dbh->errstr(); |
197 |
|
|
|
$sth->{'read'} = $dbh->prepare($arg->{'read'}) || die $dbh->errstr(); |
|
|
$sth->{'update'} = $dbh->prepare($arg->{'update'}) || die $dbh->errstr(); |
|
|
|
|
198 |
|
|
199 |
$self->{'sth'} = $sth; |
$self->{'sth'} = $sth; |
200 |
|
|
201 |
$self->{'read_filenames'} = sub { $self->read_filenames }; |
$self->{'read_filenames'} = sub { $self->read_filenames }; |
202 |
$self->read_filenames; |
$self->read_filenames; |
203 |
|
|
204 |
|
foreach my $op (qw/read update/) { |
205 |
|
if (ref($arg->{ $op }) ne 'CODE') { |
206 |
|
$self->{ $op . '_ref' } = sub { |
207 |
|
my $row = shift; |
208 |
|
return ($arg->{ $op }, $row->{'id'}); |
209 |
|
} |
210 |
|
} else { |
211 |
|
$self->{ $op . '_ref' } = $arg->{ $op }; |
212 |
|
} |
213 |
|
} |
214 |
|
|
215 |
$fuse_self = \$self; |
$fuse_self = \$self; |
216 |
|
|
217 |
Fuse::main( |
Fuse::main( |
226 |
truncate=>\&e_truncate, |
truncate=>\&e_truncate, |
227 |
unlink=>\&e_unlink, |
unlink=>\&e_unlink, |
228 |
rmdir=>\&e_unlink, |
rmdir=>\&e_unlink, |
229 |
debug=>0, |
debug=>1, |
230 |
); |
); |
231 |
|
|
232 |
exit(0) if ($arg->{'fork'}); |
exit(0) if ($arg->{'fork'}); |
360 |
$files->{$row->{'filename'}} = { |
$files->{$row->{'filename'}} = { |
361 |
size => $row->{'size'}, |
size => $row->{'size'}, |
362 |
mode => $row->{'writable'} ? 0644 : 0444, |
mode => $row->{'writable'} ? 0644 : 0444, |
363 |
id => $row->{'id'} || 99, |
id => $row->{'id'} || undef, |
364 |
|
row => $row, |
365 |
}; |
}; |
366 |
|
|
367 |
|
|
440 |
} |
} |
441 |
|
|
442 |
sub read_content { |
sub read_content { |
443 |
my ($file,$id) = @_; |
my $file = shift || die "need file"; |
444 |
|
|
445 |
|
warn "file: $file\n", Dumper($fuse_self); |
446 |
|
|
447 |
die "read_content needs file and id" unless ($file && $id); |
my @args = $$fuse_self->{'read_ref'}->($files->{$file}); |
448 |
|
my $sql = shift @args || die "need SQL for $file"; |
449 |
|
|
450 |
$sth->{'read'}->execute($id) || die $sth->{'read'}->errstr; |
$$fuse_self->{'read_sth'}->{$sql} ||= $$fuse_self->{sth}->prepare($sql) || die $dbh->errstr(); |
451 |
$files->{$file}->{cont} = $sth->{'read'}->fetchrow_array; |
my $sth = $$fuse_self->{'read_sth'}->{$sql} || die; |
452 |
|
|
453 |
|
$sth->execute(@args) || die $sth->errstr; |
454 |
|
$files->{$file}->{cont} = $sth->fetchrow_array; |
455 |
# I should modify ctime only if content in database changed |
# I should modify ctime only if content in database changed |
456 |
#$files->{$file}->{ctime} = time() unless ($files->{$file}->{ctime}); |
#$files->{$file}->{ctime} = time() unless ($files->{$file}->{ctime}); |
457 |
print "file '$file' content [",length($files->{$file}->{cont})," bytes] read in cache\n"; |
print "file '$file' content [",length($files->{$file}->{cont})," bytes] read in cache\n"; |
508 |
|
|
509 |
|
|
510 |
sub update_db { |
sub update_db { |
511 |
my $file = shift || die; |
my $file = shift || die "need file"; |
512 |
|
|
513 |
$files->{$file}->{ctime} = time(); |
$files->{$file}->{ctime} = time(); |
514 |
|
|
517 |
$files->{$file}->{id} |
$files->{$file}->{id} |
518 |
); |
); |
519 |
|
|
520 |
if (!$sth->{'update'}->execute($cont,$id)) { |
my @args = $$fuse_self->{'update_ref'}->($files->{$file}); |
521 |
print "update problem: ",$sth->{'update'}->errstr; |
my $sql = shift @args || die "need SQL for $file"; |
522 |
|
|
523 |
|
my $sth = $$fuse_self->{'update_sth'}->{$sql} |
524 |
|
||= $$fuse_self->{sth}->prepare($sql) |
525 |
|
|| die $dbh->errstr(); |
526 |
|
|
527 |
|
if (!$sth->execute(@args)) { |
528 |
|
print "update problem: ",$sth->errstr; |
529 |
clear_cont; |
clear_cont; |
530 |
return 0; |
return 0; |
531 |
} else { |
} else { |
532 |
if (! $dbh->commit) { |
if (! $dbh->commit) { |
533 |
print "ERROR: commit problem: ",$sth->{'update'}->errstr; |
print "ERROR: commit problem: ",$sth->errstr; |
534 |
clear_cont; |
clear_cont; |
535 |
return 0; |
return 0; |
536 |
} |
} |