about summary refs log tree commit homepage
path: root/lib/PublicInbox/SharedKV.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/PublicInbox/SharedKV.pm')
-rw-r--r--lib/PublicInbox/SharedKV.pm70
1 files changed, 31 insertions, 39 deletions
diff --git a/lib/PublicInbox/SharedKV.pm b/lib/PublicInbox/SharedKV.pm
index 645bb57c..89ab3f74 100644
--- a/lib/PublicInbox/SharedKV.pm
+++ b/lib/PublicInbox/SharedKV.pm
@@ -1,4 +1,4 @@
-# Copyright (C) 2020-2021 all contributors <meta@public-inbox.org>
+# Copyright (C) all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 
 # fork()-friendly key-value store.  Will be used for making
@@ -9,13 +9,13 @@ use strict;
 use v5.10.1;
 use parent qw(PublicInbox::Lock);
 use File::Temp qw(tempdir);
-use DBI ();
+use DBI qw(:sql_types); # SQL_BLOB
 use PublicInbox::Spawn;
-use File::Path qw(rmtree make_path);
+use File::Path qw(rmtree);
 
 sub dbh {
         my ($self, $lock) = @_;
-        $self->{dbh} //= do {
+        $self->{dbh} // do {
                 my $f = $self->{filename};
                 $lock //= $self->lock_for_scope_fast;
                 my $dbh = DBI->connect("dbi:SQLite:dbname=$f", '', '', {
@@ -27,9 +27,6 @@ sub dbh {
                 });
                 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(<<'');
@@ -39,37 +36,35 @@ CREATE TABLE IF NOT EXISTS kv (
         UNIQUE (k)
 )
 
-                $dbh;
+                $self->{dbh} = $dbh;
         }
 }
 
 sub new {
         my ($cls, $dir, $base, $opt) = @_;
         my $self = bless { opt => $opt }, $cls;
-        make_path($dir) if defined($dir) && !-d $dir;
+        File::Path::mkpath($dir) if defined($dir);
         $dir //= $self->{"tmp$$.$self"} = tempdir("skv.$$-XXXX", TMPDIR => 1);
         $base //= '';
         my $f = $self->{filename} = "$dir/$base.sqlite3";
         $self->{lock_path} = $opt->{lock_path} // "$dir/$base.flock";
-        unless (-f $f) {
+        unless (-s $f) {
+                require PublicInbox::Syscall;
+                PublicInbox::Syscall::nodatacow_dir($dir); # for journal/shm/wal
                 open my $fh, '+>>', $f or die "failed to open $f: $!";
-                PublicInbox::Spawn::nodatacow_fd(fileno($fh));
         }
         $self;
 }
 
-sub index_values {
-        my ($self) = @_;
-        my $lock = $self->lock_for_scope_fast;
-        $self->dbh($lock)->do('CREATE INDEX IF NOT EXISTS idx_v ON kv (v)');
-}
-
 sub set_maybe {
         my ($self, $key, $val, $lock) = @_;
         $lock //= $self->lock_for_scope_fast;
-        my $e = $self->{dbh}->prepare_cached(<<'')->execute($key, $val);
+        my $sth = $self->{dbh}->prepare_cached(<<'');
 INSERT OR IGNORE INTO kv (k,v) VALUES (?, ?)
 
+        $sth->bind_param(1, $key, SQL_BLOB);
+        $sth->bind_param(2, $val, SQL_BLOB);
+        my $e = $sth->execute;
         $e == 0 ? undef : $e;
 }
 
@@ -96,36 +91,30 @@ sub keys {
         } else {
                 @pfx = (); # [0] may've been undef
         }
-        map { $_->[0] } @{$self->dbh->selectall_arrayref($sql, undef, @pfx)};
-}
-
-sub delete_by_val {
-        my ($self, $val, $lock) = @_;
-        $lock //= $self->lock_for_scope_fast;
-        $self->{dbh}->prepare_cached(<<'')->execute($val) + 0;
-DELETE FROM kv WHERE v = ?
-
-}
-
-sub replace_values {
-        my ($self, $oldval, $newval, $lock) = @_;
-        $lock //= $self->lock_for_scope_fast;
-        $self->{dbh}->prepare_cached(<<'')->execute($newval, $oldval) + 0;
-UPDATE kv SET v = ? WHERE v = ?
-
+        my $sth = $self->dbh->prepare($sql);
+        if (@pfx) {
+                $sth->bind_param(1, $pfx[0], SQL_BLOB);
+                $sth->bind_param(2, $pfx[1]);
+        }
+        $sth->execute;
+        map { $_->[0] } @{$sth->fetchall_arrayref};
 }
 
 sub set {
         my ($self, $key, $val) = @_;
         if (defined $val) {
-                my $e = $self->{dbh}->prepare_cached(<<'')->execute($key, $val);
+                my $sth = $self->{dbh}->prepare_cached(<<'');
 INSERT OR REPLACE INTO kv (k,v) VALUES (?,?)
 
+                $sth->bind_param(1, $key, SQL_BLOB);
+                $sth->bind_param(2, $val, SQL_BLOB);
+                my $e = $sth->execute;
                 $e == 0 ? undef : $e;
         } else {
-                $self->{dbh}->prepare_cached(<<'')->execute($key);
+                my $sth = $self->{dbh}->prepare_cached(<<'');
 DELETE FROM kv WHERE k = ?
 
+                $sth->bind_param(1, $key, SQL_BLOB);
         }
 }
 
@@ -134,7 +123,8 @@ sub get {
         my $sth = $self->{dbh}->prepare_cached(<<'', undef, 1);
 SELECT v FROM kv WHERE k = ?
 
-        $sth->execute($key);
+        $sth->bind_param(1, $key, SQL_BLOB);
+        $sth->execute;
         $sth->fetchrow_array;
 }
 
@@ -145,9 +135,11 @@ sub xchg {
         if (defined $newval) {
                 set($self, $key, $newval);
         } else {
-                $self->{dbh}->prepare_cached(<<'')->execute($key);
+                my $sth = $self->{dbh}->prepare_cached(<<'');
 DELETE FROM kv WHERE k = ?
 
+                $sth->bind_param(1, $key, SQL_BLOB);
+                $sth->execute;
         }
         $oldval;
 }