X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FMsgmap.pm;h=8fe17a9505f0db151fe8c7f8f67ff9170b54e0b9;hb=2c69f7bc34a2b12dc7f55e2bb24fa28565f24f03;hp=c0fc636f67be6f69a93d281507139368c3a522e1;hpb=761736a312a103ba522abac52a604564f9e788ce;p=public-inbox.git diff --git a/lib/PublicInbox/Msgmap.pm b/lib/PublicInbox/Msgmap.pm index c0fc636f..8fe17a95 100644 --- a/lib/PublicInbox/Msgmap.pm +++ b/lib/PublicInbox/Msgmap.pm @@ -1,10 +1,15 @@ # Copyright (C) 2015 all contributors # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt) -# bidirectional Message-ID <-> Article Number mapping + +# bidirectional Message-ID <-> Article Number mapping for the NNTP +# and web interfaces. This is required for implementing stable article +# numbers for NNTP and allows prefix lookups for partial Message-IDs +# in case URLs get truncated from copy-n-paste errors by users. +# +# This is maintained by ::SearchIdx package PublicInbox::Msgmap; use strict; use warnings; -use fields qw(dbh mid_insert mid_for num_for num_minmax); use DBI; use DBD::SQLite; @@ -20,11 +25,11 @@ sub new { AutoCommit => 1, RaiseError => 1, PrintError => 0, + ReadOnly => !$writable, sqlite_use_immediate_transaction => 1, }); $dbh->do('PRAGMA case_sensitive_like = ON'); - my $self = fields::new($class); - $self->{dbh} = $dbh; + my $self = bless { dbh => $dbh }, $class; if ($writable) { create_tables($dbh); @@ -84,10 +89,10 @@ sub mid_insert { $dbh->last_insert_id(undef, undef, 'msgmap', 'num'); } -use constant MID_FOR => 'SELECT mid FROM msgmap WHERE num = ? LIMIT 1'; sub mid_for { my ($self, $num) = @_; my $dbh = $self->{dbh}; + use constant MID_FOR => 'SELECT mid FROM msgmap WHERE num = ? LIMIT 1'; my $sth = $self->{mid_for} ||= $dbh->prepare(MID_FOR); $sth->bind_param(1, $num); $sth->execute; @@ -155,25 +160,17 @@ sub create_tables { 'val VARCHAR(255) NOT NULL)'); } -sub each_id_batch { - my ($self, $cb) = @_; +sub id_batch { + my ($self, $num, $cb) = @_; my $dbh = $self->{dbh}; - my $n = 0; - my $total = 0; - my $nr; my $sth = $dbh->prepare('SELECT num FROM msgmap WHERE num > ? '. 'ORDER BY num ASC LIMIT 1000'); - while (1) { - $sth->execute($n); - my $ary = $sth->fetchall_arrayref; - @$ary = map { $_->[0] } @$ary; - $nr = scalar @$ary; - last if $nr == 0; - $total += $nr; - $n = $ary->[-1]; - $cb->($ary); - } - $total; + $sth->execute($num); + my $ary = $sth->fetchall_arrayref; + @$ary = map { $_->[0] } @$ary; + my $nr = scalar @$ary; + $cb->($ary) if $nr; + $nr; } 1;