mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-02-07 13:42:41 +02:00
181 lines
5.5 KiB
Perl
181 lines
5.5 KiB
Perl
####################################################################################################################################
|
|
# Protocol File
|
|
####################################################################################################################################
|
|
package pgBackRest::Protocol::Storage::File;
|
|
use parent 'pgBackRest::Common::Io::Base';
|
|
|
|
use strict;
|
|
use warnings FATAL => qw(all);
|
|
use Carp qw(confess);
|
|
use English '-no_match_vars';
|
|
|
|
use Exporter qw(import);
|
|
our @EXPORT = qw();
|
|
|
|
use pgBackRest::Common::Exception;
|
|
use pgBackRest::Common::Log;
|
|
|
|
####################################################################################################################################
|
|
# CONSTRUCTOR
|
|
####################################################################################################################################
|
|
sub new
|
|
{
|
|
my $class = shift;
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
my
|
|
(
|
|
$strOperation,
|
|
$oProtocol, # Master or minion protocol
|
|
$oFileIo, # File whose results will be returned via protocol
|
|
) =
|
|
logDebugParam
|
|
(
|
|
__PACKAGE__ . '->new', \@_,
|
|
{name => 'oProtocol', trace => true},
|
|
{name => 'oFileIo', required => false, trace => true},
|
|
);
|
|
|
|
# Create class
|
|
my $self = $class->SUPER::new($oProtocol->io()->id() . ' file');
|
|
bless $self, $class;
|
|
|
|
# Set variables
|
|
$self->{oProtocol} = $oProtocol;
|
|
$self->{oFileIo} = $oFileIo;
|
|
|
|
# Set read/write
|
|
$self->{bWrite} = false;
|
|
|
|
# Initialize EOF to false
|
|
$self->eofSet(false);
|
|
|
|
# Return from function and log return values if any
|
|
return logDebugReturn
|
|
(
|
|
$strOperation,
|
|
{name => 'self', value => $self}
|
|
);
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# eof - have reads reached eof?
|
|
####################################################################################################################################
|
|
sub eof
|
|
{
|
|
return shift->{bEOF};
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# eofSet - set eof
|
|
####################################################################################################################################
|
|
sub eofSet
|
|
{
|
|
my $self = shift;
|
|
my $bEOF = shift;
|
|
|
|
$self->{bEOF} = $bEOF;
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# read - read block from protocol
|
|
####################################################################################################################################
|
|
sub read
|
|
{
|
|
my $self = shift;
|
|
my $rtBuffer = shift;
|
|
|
|
# After EOF always return 0
|
|
return 0 if $self->eof();
|
|
|
|
my $lBlockSize;
|
|
|
|
# Read the block header and make sure it's valid
|
|
my $strBlockHeader = $self->{oProtocol}->io()->readLine();
|
|
|
|
if ($strBlockHeader !~ /^BRBLOCK[0-9]+$/)
|
|
{
|
|
confess &log(ERROR, "invalid block header '${strBlockHeader}'", ERROR_FILE_READ);
|
|
}
|
|
|
|
# Get block size from the header
|
|
$lBlockSize = substr($strBlockHeader, 7);
|
|
|
|
# Read block if size > 0
|
|
if ($lBlockSize > 0)
|
|
{
|
|
$self->{oProtocol}->io()->read($rtBuffer, $lBlockSize, true);
|
|
}
|
|
else
|
|
{
|
|
$self->eofSet(true);
|
|
}
|
|
|
|
# Return the block size
|
|
return $lBlockSize;
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# write - write block to protocol
|
|
####################################################################################################################################
|
|
sub write
|
|
{
|
|
my $self = shift;
|
|
my $rtBuffer = shift;
|
|
|
|
# Set write
|
|
$self->{bWrite} = true;
|
|
|
|
# Get the buffer size
|
|
my $lBlockSize = defined($rtBuffer) ? length($$rtBuffer) : 0;
|
|
|
|
# Write if size > 0 (0 ends the copy stream so it should only be done in close())
|
|
if ($lBlockSize > 0)
|
|
{
|
|
# Write block header to the protocol stream
|
|
$self->{oProtocol}->io()->writeLine("BRBLOCK${lBlockSize}");
|
|
|
|
# Write block if size
|
|
$self->{oProtocol}->io()->write($rtBuffer);
|
|
}
|
|
|
|
return length($$rtBuffer);
|
|
}
|
|
|
|
####################################################################################################################################
|
|
# close - set the result hash
|
|
####################################################################################################################################
|
|
sub close
|
|
{
|
|
my $self = shift;
|
|
|
|
# Close if protocol is defined (to prevent this from running more than once)
|
|
if (defined($self->{oProtocol}))
|
|
{
|
|
# If writing output terminator
|
|
if ($self->{bWrite})
|
|
{
|
|
$self->{oProtocol}->io()->writeLine("BRBLOCK0");
|
|
}
|
|
|
|
# On master read the results
|
|
if ($self->{oProtocol}->master())
|
|
{
|
|
($self->{rhResult}) = $self->{oProtocol}->outputRead();
|
|
|
|
# Minion will send one more output message after file is closed which can be ignored
|
|
$self->{oProtocol}->outputRead();
|
|
}
|
|
# On minion write the results
|
|
else
|
|
{
|
|
$self->{oProtocol}->outputWrite($self->{oFileIo}->resultAll());
|
|
}
|
|
|
|
# Delete protocol to prevent close from running again
|
|
delete($self->{oProtocol});
|
|
}
|
|
}
|
|
|
|
1;
|