X-Git-Url: http://www.git.stargrave.org/?p=public-inbox.git;a=blobdiff_plain;f=lib%2FPublicInbox%2FLeiMailSync.pm;h=e70cb5de2b6b5046736ba72feeeb51a05a6bdf7b;hp=f83c7de2c064ab0355f2dda7f07a31255d94d1ed;hb=9f8e28a80374e905c831d2d5f3a45c6a9d708fa3;hpb=387f0e693f9e22a7698927bb40dab0742738e8a6 diff --git a/lib/PublicInbox/LeiMailSync.pm b/lib/PublicInbox/LeiMailSync.pm index f83c7de2..e70cb5de 100644 --- a/lib/PublicInbox/LeiMailSync.pm +++ b/lib/PublicInbox/LeiMailSync.pm @@ -47,7 +47,8 @@ sub lms_write_prepare { ($_[0]->{dbh} //= dbh_new($_[0], 1)); $_[0] } sub lms_pause { my ($self) = @_; $self->{fmap} = {}; - delete $self->{dbh}; + my $dbh = delete $self->{dbh}; + eval { $dbh->do('PRAGMA optimize') } if $dbh; } sub create_tables { @@ -197,9 +198,12 @@ INSERT OR IGNORE INTO blob2name (oidbin, fid, name) VALUES (?, ?, ?) sub each_src { my ($self, $folder, $cb, @args) = @_; my $dbh = $self->{dbh} //= dbh_new($self); - my $fid; + my ($fid, @rng); + my $and_ge_le = ''; if (ref($folder) eq 'HASH') { $fid = $folder->{fid} // die "BUG: no `fid'"; + @rng = grep(defined, @$folder{qw(min max)}); + $and_ge_le = 'AND uid >= ? AND uid <= ?' if @rng; } else { $fid = $self->{fmap}->{$folder} //= fid_for($self, $folder) // return; @@ -208,16 +212,17 @@ sub each_src { # minimize implicit txn time to avoid blocking writers by # batching SELECTs. This looks wonky but is necessary since # $cb-> may access the DB on its own. - my $ary = $dbh->selectall_arrayref(<<'', undef, $fid); -SELECT _rowid_,oidbin,uid FROM blob2num WHERE fid = ? + my $ary = $dbh->selectall_arrayref(<<"", undef, $fid, @rng); +SELECT _rowid_,oidbin,uid FROM blob2num WHERE fid = ? $and_ge_le ORDER BY _rowid_ ASC LIMIT 1000 my $min = @$ary ? $ary->[-1]->[0] : undef; while (defined $min) { for my $row (@$ary) { $cb->($row->[1], $row->[2], @args) } - $ary = $dbh->selectall_arrayref(<<'', undef, $fid, $min); -SELECT _rowid_,oidbin,uid FROM blob2num WHERE fid = ? AND _rowid_ > ? + $ary = $dbh->selectall_arrayref(<<"", undef, $fid, @rng, $min); +SELECT _rowid_,oidbin,uid FROM blob2num +WHERE fid = ? $and_ge_le AND _rowid_ > ? ORDER BY _rowid_ ASC LIMIT 1000 $min = @$ary ? $ary->[-1]->[0] : undef; @@ -295,16 +300,19 @@ sub locations_for { # returns a list of folders used for completion sub folders { - my ($self, $pfx) = @_; - my $dbh = $self->{dbh} //= dbh_new($self); + my ($self, @pfx) = @_; my $sql = 'SELECT loc FROM folders'; - my @pfx; - if (defined $pfx) { + if (defined($pfx[0])) { $sql .= ' WHERE loc LIKE ? ESCAPE ?'; - @pfx = ($pfx, '\\'); + 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 } + my $dbh = $self->{dbh} //= dbh_new($self); map { $_->[0] } @{$dbh->selectall_arrayref($sql, undef, @pfx)}; } @@ -331,9 +339,12 @@ WHERE b.oidbin = ? next unless -s $fh; local $/; my $raw = <$fh>; - if ($vrfy && git_sha(1, \$raw)->hexdigest ne $oidhex) { - warn "$f changed $oidhex\n"; - next; + if ($vrfy) { + my $got = git_sha(1, \$raw)->hexdigest; + if ($got ne $oidhex) { + warn "$f changed $oidhex => $got\n"; + next; + } } return \$raw; } @@ -458,7 +469,7 @@ sub arg2folder { # using `$res' instead of `$orig' EOM } else { - $lei->err($res) if defined $res; + warn($res, "\n") if defined $res; push @no, $orig; } } elsif (m!\A(?:nntps?|s?news)://!i) { @@ -470,7 +481,7 @@ EOM # using `$res' instead of `$orig' EOM } else { - $lei->err($res) if defined $res; + warn($res, "\n") if defined $res; push @no, $orig; } } else {