summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changes2
-rw-r--r--lib/App/BorgRestore/DB.pm20
-rw-r--r--t/handle_added_archives_with_db.t49
3 files changed, 64 insertions, 7 deletions
diff --git a/Changes b/Changes
index dae2435..c90d245 100644
--- a/Changes
+++ b/Changes
@@ -1,6 +1,8 @@
Revision history for Perl extension App-BorgRestore
{{$NEXT}}
+ - Properly handle cases where the DB is empty after removal of archive
+ information
3.2.1 2018-11-01T12:54:26Z
- Add missing version requirement to List::Util dependency
diff --git a/lib/App/BorgRestore/DB.pm b/lib/App/BorgRestore/DB.pm
index 3c9e0fb..fd8506f 100644
--- a/lib/App/BorgRestore/DB.pm
+++ b/lib/App/BorgRestore/DB.pm
@@ -105,21 +105,27 @@ method remove_archive($archive) {
}
my @columns_to_copy = map {'`'._prefix_archive_id($_).'`'} @keep_archives;
+ my @timestamp_columns_to_copy = @columns_to_copy;
@columns_to_copy = ('`path`', @columns_to_copy);
- $self->{dbh}->do('insert into `files_new` select '.join(',', @columns_to_copy).' from files');
+
+ if (@timestamp_columns_to_copy > 0) {
+ $self->{dbh}->do('insert into `files_new` select '.join(',', @columns_to_copy).' from files');
+ }
$self->{dbh}->do('drop table `files`');
$self->{dbh}->do('alter table `files_new` rename to `files`');
- my $sql = 'delete from `files` where ';
- $sql .= join(' is null and ', grep {$_ ne '`path`' } @columns_to_copy);
- $sql .= " is null";
+ if (@timestamp_columns_to_copy > 0) {
+ my $sql = 'delete from `files` where ';
+ $sql .= join(' is null and ', @timestamp_columns_to_copy);
+ $sql .= " is null";
- my $st = $self->{dbh}->prepare($sql);
- my $rows = $st->execute();
+ my $st = $self->{dbh}->prepare($sql);
+ $st->execute();
+ }
- $st = $self->{dbh}->prepare('delete from `archives` where `archive_name` = ?;');
+ my $st = $self->{dbh}->prepare('delete from `archives` where `archive_name` = ?;');
$st->execute($archive);
}
diff --git a/t/handle_added_archives_with_db.t b/t/handle_added_archives_with_db.t
index 2e222b3..6fd94ea 100644
--- a/t/handle_added_archives_with_db.t
+++ b/t/handle_added_archives_with_db.t
@@ -42,6 +42,7 @@ for my $in_memory (0,1) {
$app->_handle_added_archives(['archive-1']);
# check database content
+ is($db->get_archive_row_count(), 15, 'correct row count (15 paths with timestamps)');
eq_or_diff($db->get_archives_for_path('.'), [{archive => 'archive-1', modification_time => undef},]);
eq_or_diff($db->get_archives_for_path('boot'), [{archive => 'archive-1', modification_time => 20},]);
eq_or_diff($db->get_archives_for_path('boot/foo'), [{archive => 'archive-1', modification_time => 19},]);
@@ -85,6 +86,7 @@ for my $in_memory (0,1) {
$app->_handle_added_archives(['archive-2']);
# check database content
+ is($db->get_archive_row_count(), 16, 'correct row count (16 paths with timestamps)');
eq_or_diff($db->get_archives_for_path('.'), [
{archive => 'archive-1', modification_time => undef},
{archive => 'archive-2', modification_time => undef},
@@ -162,6 +164,7 @@ for my $in_memory (0,1) {
$app->_handle_removed_archives(['archive-2']);
# check database contents
+ is($db->get_archive_row_count(), 15, 'correct row count (15 paths with timestamps)');
eq_or_diff($db->get_archives_for_path('.'), [{archive => 'archive-2', modification_time => undef},]);
eq_or_diff($db->get_archives_for_path('boot'), [{archive => 'archive-2', modification_time => 20},]);
eq_or_diff($db->get_archives_for_path('boot/foo'), [{archive => 'archive-2', modification_time => 19},]);
@@ -180,6 +183,52 @@ for my $in_memory (0,1) {
eq_or_diff($db->get_archives_for_path('etc/foo/bar'), [{archive => 'archive-2', modification_time => 1},]);
eq_or_diff($db->get_archives_for_path('etc/foo/blub'), [{archive => 'archive-2', modification_time => undef},]);
eq_or_diff($db->get_archives_for_path('lulz'), [{archive => 'archive-2', modification_time => undef},], 'test non-existant path');
+
+ # run remove again. shouldn't change anything
+ $app->_handle_removed_archives(['archive-2']);
+ is($db->get_archive_row_count(), 15, 'correct row count (15 paths with timestamps)');
+ eq_or_diff($db->get_archives_for_path('.'), [{archive => 'archive-2', modification_time => undef},]);
+ eq_or_diff($db->get_archives_for_path('boot'), [{archive => 'archive-2', modification_time => 20},]);
+ eq_or_diff($db->get_archives_for_path('boot/foo'), [{archive => 'archive-2', modification_time => 19},]);
+ eq_or_diff($db->get_archives_for_path('boot/foo/bar'), [{archive => 'archive-2', modification_time => 19},]);
+ eq_or_diff($db->get_archives_for_path('boot/foo/blub'), [{archive => 'archive-2', modification_time => 13},]);
+ eq_or_diff($db->get_archives_for_path('boot/grub'), [{archive => 'archive-2', modification_time => 20},]);
+ eq_or_diff($db->get_archives_for_path('boot/grub/grub.cfg'), [{archive => 'archive-2', modification_time => 8},]);
+ eq_or_diff($db->get_archives_for_path('boot/test1'), [{archive => 'archive-2', modification_time => 7},]);
+ eq_or_diff($db->get_archives_for_path('boot/test1/f1'), [{archive => 'archive-2', modification_time => 3},]);
+ eq_or_diff($db->get_archives_for_path('boot/test1/f2'), [{archive => 'archive-2', modification_time => 5},]);
+ eq_or_diff($db->get_archives_for_path('boot/test1/f3'), [{archive => 'archive-2', modification_time => 3},]);
+ eq_or_diff($db->get_archives_for_path('boot/test1/f4'), [{archive => 'archive-2', modification_time => 2},]);
+ eq_or_diff($db->get_archives_for_path('boot/test1/f5'), [{archive => 'archive-2', modification_time => 7},]);
+ eq_or_diff($db->get_archives_for_path('etc'), [{archive => 'archive-2', modification_time => 3},]);
+ eq_or_diff($db->get_archives_for_path('etc/foo'), [{archive => 'archive-2', modification_time => 2},]);
+ eq_or_diff($db->get_archives_for_path('etc/foo/bar'), [{archive => 'archive-2', modification_time => 1},]);
+ eq_or_diff($db->get_archives_for_path('etc/foo/blub'), [{archive => 'archive-2', modification_time => undef},]);
+ eq_or_diff($db->get_archives_for_path('lulz'), [{archive => 'archive-2', modification_time => undef},], 'test non-existant path');
+
+ # remove all archives from db (no overlap between archives in db and "current" archives)
+ $app->_handle_removed_archives(['archive-3']);
+
+ # check database contents
+ is($db->get_archive_row_count(), 0, 'db should be empty');
+ eq_or_diff($db->get_archives_for_path('.'), []);
+ eq_or_diff($db->get_archives_for_path('boot'), []);
+ eq_or_diff($db->get_archives_for_path('boot/foo'), []);
+ eq_or_diff($db->get_archives_for_path('boot/foo/bar'), []);
+ eq_or_diff($db->get_archives_for_path('boot/foo/blub'), []);
+ eq_or_diff($db->get_archives_for_path('boot/grub'), []);
+ eq_or_diff($db->get_archives_for_path('boot/grub/grub.cfg'), []);
+ eq_or_diff($db->get_archives_for_path('boot/test1'), []);
+ eq_or_diff($db->get_archives_for_path('boot/test1/f1'), []);
+ eq_or_diff($db->get_archives_for_path('boot/test1/f2'), []);
+ eq_or_diff($db->get_archives_for_path('boot/test1/f3'), []);
+ eq_or_diff($db->get_archives_for_path('boot/test1/f4'), []);
+ eq_or_diff($db->get_archives_for_path('boot/test1/f5'), []);
+ eq_or_diff($db->get_archives_for_path('etc'), []);
+ eq_or_diff($db->get_archives_for_path('etc/foo'), []);
+ eq_or_diff($db->get_archives_for_path('etc/foo/bar'), []);
+ eq_or_diff($db->get_archives_for_path('etc/foo/blub'), []);
+ eq_or_diff($db->get_archives_for_path('lulz'), []);
}