diff options
-rw-r--r-- | Changes | 11 | ||||
-rw-r--r-- | META.json | 13 | ||||
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | cpanfile | 3 | ||||
-rw-r--r-- | lib/App/BorgRestore.pm | 2 | ||||
-rw-r--r-- | lib/App/BorgRestore/Borg.pm | 9 | ||||
-rw-r--r-- | lib/App/BorgRestore/DB.pm | 30 | ||||
-rw-r--r-- | lib/App/BorgRestore/PathTimeTable/DB.pm | 6 | ||||
-rwxr-xr-x | script/borg-restore.pl | 2 |
9 files changed, 69 insertions, 13 deletions
@@ -1,6 +1,17 @@ Revision history for Perl extension App-BorgRestore {{$NEXT}} + +3.4.5 2023-09-03T11:58:14Z + - Fix deprecation warning with borg 1.2.x + +3.4.4 2020-10-14T12:37:04Z + - Require DBD::SQLite 1.60 or newer to fix issues with schema migration 2 + on old systems. + - Reduce database size for databases that contained data from before + migrations 3 and 4. + +3.4.3 2020-09-27T13:53:54Z - Add database migration for change from 3.4.2 3.4.2 2020-09-27T13:50:47Z @@ -1,10 +1,10 @@ { "abstract" : "Restore paths from borg backups", "author" : [ - "-2018 Florian Pritz <bluewind@xinu.at>" + "Florian Pritz <bluewind@xinu.at>" ], "dynamic_config" : 0, - "generated_by" : "Minilla/v3.1.10, CPAN::Meta::Converter version 2.150010", + "generated_by" : "Minilla/v3.1.22, CPAN::Meta::Converter version 2.150010", "license" : [ "gpl_3" ], @@ -43,7 +43,8 @@ }, "runtime" : { "requires" : { - "DBD::SQLite" : "0", + "Carp::Assert" : "0", + "DBD::SQLite" : "1.60", "DBI" : "0", "Date::Parse" : "0", "File::pushd" : "0", @@ -89,11 +90,11 @@ "homepage" : "https://github.com/Bluewind/App-BorgRestore", "repository" : { "type" : "git", - "url" : "git://github.com/Bluewind/App-BorgRestore.git", + "url" : "https://github.com/Bluewind/App-BorgRestore.git", "web" : "https://github.com/Bluewind/App-BorgRestore" } }, - "version" : "3.4.2", - "x_serialization_backend" : "JSON::PP version 4.04", + "version" : "3.4.5", + "x_serialization_backend" : "JSON::PP version 4.07", "x_static_install" : 0 } @@ -55,7 +55,7 @@ passed and restore it without further user interaction. **borg-restore.pl --update-cache** has to be executed regularly, ideally after creating or removing backups. -[App::BorgRestore](https://metacpan.org/pod/App::BorgRestore) provides the base features used to implement this script. +[App::BorgRestore](https://metacpan.org/pod/App%3A%3ABorgRestore) provides the base features used to implement this script. It can be used to build your own restoration script. # OPTIONS @@ -125,11 +125,11 @@ It can be used to build your own restoration script. # CONFIGURATION -For configuration options please see [App::BorgRestore::Settings](https://metacpan.org/pod/App::BorgRestore::Settings). +For configuration options please see [App::BorgRestore::Settings](https://metacpan.org/pod/App%3A%3ABorgRestore%3A%3ASettings). # LICENSE -Copyright (C) 2016-2018 Florian Pritz <bluewind@xinu.at> +Copyright (C) 2016-2023 Florian Pritz <bluewind@xinu.at> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1,4 +1,5 @@ -requires 'DBD::SQLite'; +requires 'Carp::Assert'; +requires 'DBD::SQLite', '1.60'; requires 'DBI'; requires 'Date::Parse'; requires 'File::pushd'; diff --git a/lib/App/BorgRestore.pm b/lib/App/BorgRestore.pm index 5e57c16..971e709 100644 --- a/lib/App/BorgRestore.pm +++ b/lib/App/BorgRestore.pm @@ -2,7 +2,7 @@ package App::BorgRestore; use v5.14; use strictures 2; -our $VERSION = "3.4.2"; +our $VERSION = "3.4.5"; use App::BorgRestore::Borg; use App::BorgRestore::DB; diff --git a/lib/App/BorgRestore/Borg.pm b/lib/App/BorgRestore/Borg.pm index 04ad89c..9884b21 100644 --- a/lib/App/BorgRestore/Borg.pm +++ b/lib/App/BorgRestore/Borg.pm @@ -55,7 +55,14 @@ method borg_list() { my @archives; my $backup_prefix = $self->{backup_prefix}; - if (Version::Compare::version_compare($self->{borg_version}, "1.1") >= 0) { + if (Version::Compare::version_compare($self->{borg_version}, "1.2") >= 0) { + $log->debug("Getting archive list via json"); + run [qw(borg list --glob-archives), "$backup_prefix*", qw(--json), $self->{borg_repo}], '>', \my $output or die $log->error("borg list returned $?")."\n"; + my $json = decode_json($output); + for my $archive (@{$json->{archives}}) { + push @archives, $archive->{archive}; + } + } elsif (Version::Compare::version_compare($self->{borg_version}, "1.1") >= 0) { $log->debug("Getting archive list via json"); run [qw(borg list --prefix), $backup_prefix, qw(--json), $self->{borg_repo}], '>', \my $output or die $log->error("borg list returned $?")."\n"; my $json = decode_json($output); diff --git a/lib/App/BorgRestore/DB.pm b/lib/App/BorgRestore/DB.pm index 3d1d6ad..2999eb4 100644 --- a/lib/App/BorgRestore/DB.pm +++ b/lib/App/BorgRestore/DB.pm @@ -95,7 +95,32 @@ method _migrate() { $self->{dbh}->do('delete from `archives`'); $self->{dbh}->do('delete from `files`'); }, + 5 => sub { + # Remove columns left over by migrations 3 and 4 from files tables + my @archive_ids; + my $st = $self->{dbh}->prepare("select `id` from `archives`;"); + $st->execute(); + while (my $result = $st->fetchrow_hashref) { + push @archive_ids, $result->{id}; + } + + $self->{dbh}->do('create table `files_new` (`path` text, primary key (`path`)) without rowid;'); + for my $archive_id (@archive_ids) { + $archive_id = untaint($archive_id, qr(.*)); + $self->{dbh}->do('alter table `files_new` add column `'.$archive_id.'` integer;'); + } + + if (@archive_ids > 0) { + my @columns_to_copy = map {'`'.$_.'`'} @archive_ids; + @columns_to_copy = ('`path`', @columns_to_copy); + $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 $ran_migrations = 0; for my $target_version (sort { $a <=> $b } keys %$schema) { if ($version < $target_version) { @@ -105,8 +130,13 @@ method _migrate() { $self->_set_db_version($target_version); $self->{dbh}->commit(); $log->debugf("Schema upgrade to version %s complete", $target_version); + $ran_migrations = 1; } } + if ($ran_migrations) { + $log->debug("Vacuuming database"); + $self->{dbh}->do("vacuum"); + } } method _get_db_version() { diff --git a/lib/App/BorgRestore/PathTimeTable/DB.pm b/lib/App/BorgRestore/PathTimeTable/DB.pm index 069d991..685c7b9 100644 --- a/lib/App/BorgRestore/PathTimeTable/DB.pm +++ b/lib/App/BorgRestore/PathTimeTable/DB.pm @@ -1,6 +1,7 @@ package App::BorgRestore::PathTimeTable::DB; use strictures 2; +use Carp::Assert; use Function::Parameters; BEGIN { use Log::Any qw($log); @@ -130,6 +131,11 @@ method save_nodes() { for my $key (keys %{$self->{stats}}) { $log->debugf("Performance counter %s = %s", $key, $self->{stats}->{$key}); } + + # +2 because: + # - borg list gives us `.` as the first path and we essentially skip it + # - we call `add_path` with `.` at the beginning of this method + assert($self->{stats}->{real_calls_to_db_class} + 2 == $self->{stats}->{total_paths}, "All files were actually added to the database"); } 1; diff --git a/script/borg-restore.pl b/script/borg-restore.pl index f03fa22..0e67439 100755 --- a/script/borg-restore.pl +++ b/script/borg-restore.pl @@ -138,7 +138,7 @@ For configuration options please see L<App::BorgRestore::Settings>. =head1 LICENSE -Copyright (C) 2016-2018 Florian Pritz <bluewind@xinu.at> +Copyright (C) 2016-2023 Florian Pritz <bluewind@xinu.at> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by |