});
my $opt = $self->{opt} // {};
$dbh->do('PRAGMA synchronous = OFF') if !$opt->{fsync};
- if (my $s = $opt->{cache_size}) {
- $dbh->do("PRAGMA cache_size = $s");
- }
$dbh->do('PRAGMA journal_mode = '.
($opt->{journal_mode} // 'WAL'));
$dbh->do(<<'');
$base //= '';
my $f = $self->{filename} = "$dir/$base.sqlite3";
$self->{lock_path} = $opt->{lock_path} // "$dir/$base.flock";
- unless (-f $f) {
+ unless (-s $f) {
+ PublicInbox::Spawn::nodatacow_dir($dir); # for journal/shm/wal
open my $fh, '+>>', $f or die "failed to open $f: $!";
PublicInbox::Spawn::nodatacow_fd(fileno($fh));
}
}
sub keys {
- my ($self) = @_;
- my $sth = $self->dbh->prepare_cached(<<'', undef, 1);
-SELECT k FROM kv
-
- $sth->execute;
- map { $_->[0] } @{$sth->fetchall_arrayref};
+ my ($self, @pfx) = @_;
+ my $sql = 'SELECT k FROM kv';
+ if (defined $pfx[0]) {
+ $sql .= ' WHERE k LIKE ? ESCAPE ?';
+ my $anywhere = !!$pfx[1];
+ $pfx[1] = '\\';
+ $pfx[0] =~ s/([%_\\])/\\$1/g; # glob chars
+ $pfx[0] .= '%';
+ substr($pfx[0], 0, 0, '%') if $anywhere;
+ } else {
+ @pfx = (); # [0] may've been undef
+ }
+ map { $_->[0] } @{$self->dbh->selectall_arrayref($sql, undef, @pfx)};
}
sub delete_by_val {