lib/PublicInbox/Inbox.pm | 2 +- lib/PublicInbox/Msgmap.pm | 19 +++++++++++++++++++ t/msgmap.t | 4 ++++ diff --git a/lib/PublicInbox/Inbox.pm b/lib/PublicInbox/Inbox.pm index b9cd4c40a6dc7541f799f0da8b520e426af7df4d..f307038399b77437b8e5a94ed163e01559959466 100644 --- a/lib/PublicInbox/Inbox.pm +++ b/lib/PublicInbox/Inbox.pm @@ -75,7 +75,7 @@ _set_limiter($opts, $pi_config, 'httpbackend'); _set_uint($opts, 'feedmax', 25); $opts->{nntpserver} ||= $pi_config->{'publicinbox.nntpserver'}; my $dir = $opts->{mainrepo}; - if (defined $dir && -f "$dir/msgmap.sqlite3") { # XXX DIRTY + if (defined $dir && -f "$dir/inbox.lock") { $opts->{version} = 2; } bless $opts, $class; diff --git a/lib/PublicInbox/Msgmap.pm b/lib/PublicInbox/Msgmap.pm index 8e81fba08d12b81ba6b1ead7709881f137c38ff4..78922d3693c9647e0b11c3dc7fc300ce1a985147 100644 --- a/lib/PublicInbox/Msgmap.pm +++ b/lib/PublicInbox/Msgmap.pm @@ -12,6 +12,7 @@ use strict; use warnings; use DBI; use DBD::SQLite; +use File::Temp qw(tempfile); sub new { my ($class, $git_dir, $writable) = @_; @@ -43,6 +44,18 @@ $self->created_at(time) unless $self->created_at; $dbh->commit; } $self; +} + +# used to keep track of used numeric mappings for v2 reindex +sub tmp_clone { + my ($self) = @_; + my ($fh, $fn) = tempfile(EXLOCK => 0); + $self->{dbh}->sqlite_backup_to_file($fn); + my $tmp = ref($self)->new_file($fn, 1); + $tmp->{dbh}->do('PRAGMA synchronous = OFF'); + $tmp->{tmp_name} = $fn; # SQLite won't work if unlinked, apparently + $fh = undef; + $tmp; } # n.b. invoked directly by scripts/xhdr-num2mid @@ -187,6 +200,12 @@ $self->{dbh}->prepare( 'INSERT OR IGNORE INTO msgmap (num,mid) VALUES (?,?)'); }; $sth->execute($num, $mid); +} + +sub DESTROY { + my ($self) = @_; + delete $self->{dbh}; + unlink $self->{tmp_name} if defined $self->{tmp_name}; } 1; diff --git a/t/msgmap.t b/t/msgmap.t index bc22137dd00ca770b31d84c88e6ad0d6aaff0cc2..dce98f46b6f57e48a90653ceba659a3665db247d 100644 --- a/t/msgmap.t +++ b/t/msgmap.t @@ -65,4 +65,8 @@ my $orig = $d->mid_insert('spam@1'); $d->mid_delete('spam@1'); is($d->mid_insert('spam@2'), 1 + $orig, "last number not recycled"); +my $tmp = $d->tmp_clone; +is_deeply([$d->minmax], [$tmp->minmax], 'Cloned temporary DB matches'); +ok($tmp->mid_delete('spam@2'), 'temporary DB is writable'); + done_testing();