1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00
pgbackrest/lib/pgBackRest/Common/String.pm

241 lines
6.8 KiB
Perl
Raw Normal View History

####################################################################################################################################
# COMMON STRING MODULE
####################################################################################################################################
New simpler configuration and consistent project/exe/path naming. * The repo-path option now always refers to the repository where backups and archive are stored, whether local or remote, so the repo-remote-path option has been removed. The new spool-path option can be used to define a location for queueing WAL segments when archiving asynchronously. Otherwise, a local repository is no longer required. * Implemented a new config format which should be far simpler to use. See the User Guide and Configuration Reference for details but for a simple configuration all options can now be placed in the stanza section. Options that are shared between stanzas can be placed in the [global] section. More complex configurations can still make use of command sections though this should be a rare use case. * The default configuration filename is now pgbackrest.conf instead of pg_backrest.conf. This was done for consistency with other naming changes but also to prevent old config files from being loaded accidentally. * The default repository name was changed from /var/lib/backup to /var/lib/pgbackrest. * Lock files are now stored in /tmp/pgbackrest by default. These days /run/pgbackrest would be the preferred location but that would require init scripts which are not part of this release. The lock-path option can be used to configure the lock directory. * Log files are now stored in /var/log/pgbackrest by default and no longer have the date appended so they can be managed with logrotate. The log-path option can be used to configure the lock directory. * Executable filename changed from pg_backrest to pgbackrest.
2016-04-14 15:30:54 +02:00
package pgBackRest::Common::String;
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess longmess);
use Exporter qw(import);
our @EXPORT = qw();
use File::Basename qw(dirname);
####################################################################################################################################
# dataHashBuild
#
# Hash a delimited multi-line string with a header.
####################################################################################################################################
sub dataHashBuild
{
my $oHashRef = shift;
my $strData = shift;
my $strDelimiter = shift;
my $strUndefinedKey = shift;
my @stryFile = split("\n", $strData);
my @stryHeader = split($strDelimiter, $stryFile[0]);
for (my $iLineIdx = 1; $iLineIdx < scalar @stryFile; $iLineIdx++)
{
my @stryLine = split($strDelimiter, $stryFile[$iLineIdx]);
if (!defined($stryLine[0]) || $stryLine[0] eq '')
{
$stryLine[0] = $strUndefinedKey;
}
for (my $iColumnIdx = 1; $iColumnIdx < scalar @stryHeader; $iColumnIdx++)
{
if (defined(${$oHashRef}{"$stryLine[0]"}{"$stryHeader[$iColumnIdx]"}))
{
confess 'the first column must be unique to build the hash';
}
if (defined($stryLine[$iColumnIdx]) && $stryLine[$iColumnIdx] ne '')
{
if (scalar @stryHeader > 2)
{
$oHashRef->{$stryLine[0]}{$stryHeader[$iColumnIdx]} = $stryLine[$iColumnIdx];
}
else
{
$oHashRef->{$stryLine[0]} = $stryLine[$iColumnIdx];
}
}
}
}
}
push @EXPORT, qw(dataHashBuild);
####################################################################################################################################
# trim
#
# Trim whitespace.
####################################################################################################################################
sub trim
{
my $strBuffer = shift;
if (!defined($strBuffer))
{
return;
}
$strBuffer =~ s/^\s+|\s+$//g;
return $strBuffer;
}
push @EXPORT, qw(trim);
####################################################################################################################################
# commonPrefix
#
# Determine how much of two strings is the same from the beginning.
####################################################################################################################################
sub commonPrefix
{
my $strString1 = shift;
my $strString2 = shift;
my $iCommonLen = 0;
my $iCompareLen = length($strString1) < length($strString2) ? length($strString1) : length($strString2);
for (my $iIndex = 0; $iIndex < $iCompareLen; $iIndex++)
{
if (substr($strString1, $iIndex, 1) ne substr($strString2, $iIndex, 1))
{
last;
}
$iCommonLen++;
}
return $iCommonLen;
}
push @EXPORT, qw(commonPrefix);
####################################################################################################################################
# boolFormat
#
# Outut boolean as true or false.
####################################################################################################################################
sub boolFormat
{
my $bValue;
if ($bValue)
{
return 'true';
}
return 'false';
}
push @EXPORT, qw(boolFormat);
####################################################################################################################################
# fileSizeFormat
#
# Format file sizes in human-readable form.
####################################################################################################################################
sub fileSizeFormat
{
my $lFileSize = shift;
if ($lFileSize < 1024)
{
return $lFileSize . 'B';
}
if ($lFileSize < (1024 * 1024))
{
return (int($lFileSize / 102.4) / 10) . 'KB';
}
if ($lFileSize < (1024 * 1024 * 1024))
{
return (int($lFileSize / 1024 / 102.4) / 10) . 'MB';
}
return (int($lFileSize / 1024 / 1024 / 102.4) / 10) . 'GB';
}
push @EXPORT, qw(fileSizeFormat);
####################################################################################################################################
# timestampFormat
#
# Get standard timestamp format (or formatted as specified).
####################################################################################################################################
sub timestampFormat
{
my $strFormat = shift;
my $lTime = shift;
if (!defined($strFormat))
{
$strFormat = '%4d-%02d-%02d %02d:%02d:%02d';
}
if (!defined($lTime))
{
$lTime = time();
}
my ($iSecond, $iMinute, $iHour, $iMonthDay, $iMonth, $iYear, $iWeekDay, $iYearDay, $bIsDst) = localtime($lTime);
if ($strFormat eq "%4d")
{
return sprintf($strFormat, $iYear + 1900)
}
else
{
return sprintf($strFormat, $iYear + 1900, $iMonth + 1, $iMonthDay, $iHour, $iMinute, $iSecond);
}
}
push @EXPORT, qw(timestampFormat);
####################################################################################################################################
# timestampFileFormat
####################################################################################################################################
sub timestampFileFormat
{
my $strFormat = shift;
my $lTime = shift;
return timestampFormat(defined($strFormat) ? $strFormat : '%4d%02d%02d-%02d%02d%02d', $lTime);
}
push @EXPORT, qw(timestampFileFormat);
####################################################################################################################################
# stringSplit
####################################################################################################################################
sub stringSplit
{
my $strString = shift;
my $strChar = shift;
my $iLength = shift;
if (length($strString) <= $iLength)
{
return $strString, undef;
}
my $iPos = index($strString, $strChar);
if ($iPos == -1)
{
return $strString, undef;
}
my $iNewPos = $iPos;
while ($iNewPos != -1 && $iNewPos + 1 < $iLength)
{
$iPos = $iNewPos;
$iNewPos = index($strString, $strChar, $iPos + 1);
}
return substr($strString, 0, $iPos + 1), substr($strString, $iPos + 1);
}
push @EXPORT, qw(stringSplit);
1;