1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-15 01:04:37 +02:00

Refactor storage modules with inline getters/setters.

Extended the pattern introduced in 79a2d02c to the storage modules: Storage, StorageRead, StorageWrite.
This commit is contained in:
David Steele
2021-04-07 14:04:38 -04:00
parent 79a2d02c9c
commit b715c70b46
22 changed files with 221 additions and 342 deletions

View File

@ -4,7 +4,7 @@ Azure Storage
#ifndef STORAGE_AZURE_STORAGE_H
#define STORAGE_AZURE_STORAGE_H
#include "storage/storage.intern.h"
#include "storage/storage.h"
/***********************************************************************************************************************************
Storage type

View File

@ -4,7 +4,7 @@ CIFS Storage
#ifndef STORAGE_CIFS_STORAGE_H
#define STORAGE_CIFS_STORAGE_H
#include "storage/storage.intern.h"
#include "storage/storage.h"
/***********************************************************************************************************************************
Storage type

View File

@ -4,7 +4,7 @@ GCS Storage
#ifndef STORAGE_GCS_STORAGE_H
#define STORAGE_GCS_STORAGE_H
#include "storage/storage.intern.h"
#include "storage/storage.h"
/***********************************************************************************************************************************
Storage type

View File

@ -9,7 +9,7 @@ Object type
***********************************************************************************************************************************/
typedef struct StoragePosix StoragePosix;
#include "storage/storage.intern.h"
#include "storage/storage.h"
/***********************************************************************************************************************************
Storage type

View File

@ -7,17 +7,16 @@ Storage Read Interface
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/object.h"
#include "storage/read.intern.h"
#include "storage/read.h"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct StorageRead
{
StorageReadPub pub; // Publicly accessible variables
MemContext *memContext; // Object mem context
void *driver;
const StorageReadInterface *interface;
IoRead *io;
};
OBJECT_DEFINE_MOVE(STORAGE_READ);
@ -49,85 +48,23 @@ storageReadNew(void *driver, const StorageReadInterface *interface)
*this = (StorageRead)
{
.memContext = memContextCurrent(),
.driver = driver,
.pub =
{
.interface = interface,
.io = ioReadNew(driver, interface->ioInterface),
},
.memContext = memContextCurrent(),
.driver = driver,
};
FUNCTION_LOG_RETURN(STORAGE_READ, this);
}
/**********************************************************************************************************************************/
bool
storageReadIgnoreMissing(const StorageRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->ignoreMissing);
}
/**********************************************************************************************************************************/
const Variant *
storageReadLimit(const StorageRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->limit);
}
/**********************************************************************************************************************************/
IoRead *
storageReadIo(const StorageRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/**********************************************************************************************************************************/
const String *
storageReadName(const StorageRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->name);
}
/**********************************************************************************************************************************/
const String *
storageReadType(const StorageRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_READ, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->type);
}
/**********************************************************************************************************************************/
String *
storageReadToLog(const StorageRead *this)
{
return strNewFmt(
"{type: %s, name: %s, ignoreMissing: %s}", strZ(this->interface->type), strZ(strToLog(this->interface->name)),
cvtBoolToConstZ(this->interface->ignoreMissing));
"{type: %s, name: %s, ignoreMissing: %s}", strZ(storageReadType(this)), strZ(strToLog(storageReadName(this))),
cvtBoolToConstZ(storageReadIgnoreMissing(this)));
}

View File

@ -13,6 +13,7 @@ Object type
typedef struct StorageRead StorageRead;
#include "common/io/read.h"
#include "storage/read.intern.h"
/***********************************************************************************************************************************
Functions
@ -22,20 +23,51 @@ StorageRead *storageReadMove(StorageRead *this, MemContext *parentNew);
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
typedef struct StorageReadPub
{
const StorageReadInterface *interface; // File data (name, driver type, etc.)
IoRead *io; // Read interface
} StorageReadPub;
// Should a missing file be ignored?
bool storageReadIgnoreMissing(const StorageRead *this);
__attribute__((always_inline)) static inline bool
storageReadIgnoreMissing(const StorageRead *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageReadPub *)this)->interface->ignoreMissing;
}
// Read interface
IoRead *storageReadIo(const StorageRead *this);
__attribute__((always_inline)) static inline IoRead *
storageReadIo(const StorageRead *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageReadPub *)this)->io;
}
// Is there a read limit? NULL for no limit.
const Variant *storageReadLimit(const StorageRead *this);
__attribute__((always_inline)) static inline const Variant *
storageReadLimit(const StorageRead *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageReadPub *)this)->interface->limit;
}
// File name
const String *storageReadName(const StorageRead *this);
__attribute__((always_inline)) static inline const String *
storageReadName(const StorageRead *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageReadPub *)this)->interface->name;
}
// Get file type
const String *storageReadType(const StorageRead *this);
__attribute__((always_inline)) static inline const String *
storageReadType(const StorageRead *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageReadPub *)this)->interface->type;
}
/***********************************************************************************************************************************
Destructor

View File

@ -5,7 +5,6 @@ Storage Read Interface Internal
#define STORAGE_READ_INTERN_H
#include "common/io/read.intern.h"
#include "storage/read.h"
/***********************************************************************************************************************************
Constructors

View File

@ -5,7 +5,7 @@ Remote Storage
#define STORAGE_REMOTE_STORAGE_H
#include "protocol/client.h"
#include "storage/storage.intern.h"
#include "storage/storage.h"
/***********************************************************************************************************************************
Storage type

View File

@ -4,7 +4,7 @@ S3 Storage
#ifndef STORAGE_S3_STORAGE_H
#define STORAGE_S3_STORAGE_H
#include "storage/storage.intern.h"
#include "storage/storage.h"
/***********************************************************************************************************************************
Storage type

View File

@ -14,18 +14,15 @@ Storage Interface
#include "common/type/object.h"
#include "common/regExp.h"
#include "common/wait.h"
#include "storage/storage.intern.h"
#include "storage/storage.h"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct Storage
{
StoragePub pub; // Publicly accessible variables
MemContext *memContext;
void *driver;
StorageInterface interface;
const String *type;
const String *path;
mode_t modeFile;
mode_t modePath;
@ -66,10 +63,13 @@ storageNew(
*this = (Storage)
{
.memContext = memContextCurrent(),
.pub =
{
.type = type,
.driver = driver,
.interface = interface,
.type = type,
},
.memContext = memContextCurrent(),
.path = strDup(path),
.modeFile = modeFile,
.modePath = modePath,
@ -242,7 +242,7 @@ storageInfo(const Storage *this, const String *fileExp, StorageInfoParam param)
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->interface.info != NULL);
ASSERT(this->pub.interface.info != NULL);
StorageInfo result = {0};
@ -263,7 +263,7 @@ storageInfo(const Storage *this, const String *fileExp, StorageInfoParam param)
}
// Else call the driver
else
result = storageInterfaceInfoP(this->driver, file, param.level, .followLink = param.followLink);
result = storageInterfaceInfoP(this->pub.driver, file, param.level, .followLink = param.followLink);
// Error if the file missing and not ignoring
if (!result.exists && !param.ignoreMissing)
@ -342,7 +342,7 @@ storageInfoListSort(
// If no sorting then use the callback directly
if (sortOrder == sortOrderNone)
{
result = storageInterfaceInfoListP(this->driver, path, level, callback, callbackData, .expression = expression);
result = storageInterfaceInfoListP(this->pub.driver, path, level, callback, callbackData, .expression = expression);
}
// Else sort the info before sending it to the callback
else
@ -355,7 +355,7 @@ storageInfoListSort(
};
result = storageInterfaceInfoListP(
this->driver, path, level, storageInfoListSortCallback, &data, .expression = expression);
this->pub.driver, path, level, storageInfoListSortCallback, &data, .expression = expression);
lstSort(data.infoList, sortOrder);
MEM_CONTEXT_TEMP_RESET_BEGIN()
@ -459,7 +459,7 @@ storageInfoList(
ASSERT(this != NULL);
ASSERT(callback != NULL);
ASSERT(this->interface.infoList != NULL);
ASSERT(this->pub.interface.infoList != NULL);
ASSERT(!param.errorOnMissing || storageFeature(this, storageFeaturePath));
bool result = false;
@ -574,29 +574,29 @@ storageMove(const Storage *this, StorageRead *source, StorageWrite *destination)
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->interface.move != NULL);
ASSERT(this->pub.interface.move != NULL);
ASSERT(source != NULL);
ASSERT(destination != NULL);
ASSERT(!storageReadIgnoreMissing(source));
ASSERT(strEq(this->type, storageReadType(source)));
ASSERT(strEq(storageType(this), storageReadType(source)));
ASSERT(strEq(storageReadType(source), storageWriteType(destination)));
MEM_CONTEXT_TEMP_BEGIN()
{
// If the file can't be moved it will need to be copied
if (!storageInterfaceMoveP(this->driver, source, destination))
if (!storageInterfaceMoveP(this->pub.driver, source, destination))
{
// Perform the copy
storageCopyP(source, destination);
// Remove the source file
storageInterfaceRemoveP(this->driver, storageReadName(source));
storageInterfaceRemoveP(this->pub.driver, storageReadName(source));
// Sync source path if the destination path was synced. We know the source and destination paths are different because
// the move did not succeed. This will need updating when drivers other than Posix/CIFS are implemented because there's
// no way to get coverage on it now.
if (storageWriteSyncPath(destination))
storageInterfacePathSyncP(this->driver, strPath(storageReadName(source)));
storageInterfacePathSyncP(this->pub.driver, strPath(storageReadName(source)));
}
}
MEM_CONTEXT_TEMP_END();
@ -626,7 +626,7 @@ storageNewRead(const Storage *this, const String *fileExp, StorageNewReadParam p
{
result = storageReadMove(
storageInterfaceNewReadP(
this->driver, storagePathP(this, fileExp), param.ignoreMissing, .compressible = param.compressible,
this->pub.driver, storagePathP(this, fileExp), param.ignoreMissing, .compressible = param.compressible,
.limit = param.limit),
memContextPrior());
}
@ -663,7 +663,7 @@ storageNewWrite(const Storage *this, const String *fileExp, StorageNewWriteParam
{
result = storageWriteMove(
storageInterfaceNewWriteP(
this->driver, storagePathP(this, fileExp), .modeFile = param.modeFile != 0 ? param.modeFile : this->modeFile,
this->pub.driver, storagePathP(this, fileExp), .modeFile = param.modeFile != 0 ? param.modeFile : this->modeFile,
.modePath = param.modePath != 0 ? param.modePath : this->modePath, .user = param.user, .group = param.group,
.timeModified = param.timeModified, .createPath = !param.noCreatePath, .syncFile = !param.noSyncFile,
.syncPath = !param.noSyncPath, .atomic = !param.noAtomic, .compressible = param.compressible),
@ -788,7 +788,7 @@ storagePathCreate(const Storage *this, const String *pathExp, StoragePathCreateP
FUNCTION_LOG_END();
ASSERT(this != NULL);
ASSERT(this->interface.pathCreate != NULL && storageFeature(this, storageFeaturePath));
ASSERT(this->pub.interface.pathCreate != NULL && storageFeature(this, storageFeaturePath));
ASSERT(this->write);
MEM_CONTEXT_TEMP_BEGIN()
@ -798,7 +798,7 @@ storagePathCreate(const Storage *this, const String *pathExp, StoragePathCreateP
// Call driver function
storageInterfacePathCreateP(
this->driver, path, param.errorOnExists, param.noParentCreate, param.mode != 0 ? param.mode : this->modePath);
this->pub.driver, path, param.errorOnExists, param.noParentCreate, param.mode != 0 ? param.mode : this->modePath);
}
MEM_CONTEXT_TEMP_END();
@ -846,7 +846,7 @@ storagePathRemove(const Storage *this, const String *pathExp, StoragePathRemoveP
String *path = storagePathP(this, pathExp);
// Call driver function
if (!storageInterfacePathRemoveP(this->driver, path, param.recurse) && param.errorOnMissing)
if (!storageInterfacePathRemoveP(this->pub.driver, path, param.recurse) && param.errorOnMissing)
{
THROW_FMT(PathRemoveError, STORAGE_ERROR_PATH_REMOVE_MISSING, strZ(path));
}
@ -868,11 +868,11 @@ void storagePathSync(const Storage *this, const String *pathExp)
ASSERT(this->write);
// Not all storage requires path sync so just do nothing if the function is not implemented
if (this->interface.pathSync != NULL)
if (this->pub.interface.pathSync != NULL)
{
MEM_CONTEXT_TEMP_BEGIN()
{
storageInterfacePathSyncP(this->driver, storagePathP(this, pathExp));
storageInterfacePathSyncP(this->pub.driver, storagePathP(this, pathExp));
}
MEM_CONTEXT_TEMP_END();
}
@ -917,70 +917,17 @@ storageRemove(const Storage *this, const String *fileExp, StorageRemoveParam par
String *file = storagePathP(this, fileExp);
// Call driver function
storageInterfaceRemoveP(this->driver, file, .errorOnMissing = param.errorOnMissing);
storageInterfaceRemoveP(this->pub.driver, file, .errorOnMissing = param.errorOnMissing);
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN_VOID();
}
/**********************************************************************************************************************************/
void *
storageDriver(const Storage *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->driver);
}
/**********************************************************************************************************************************/
bool
storageFeature(const Storage *this, StorageFeature feature)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE, this);
FUNCTION_TEST_PARAM(ENUM, feature);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface.feature >> feature & 1);
}
/**********************************************************************************************************************************/
StorageInterface
storageInterface(const Storage *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface);
}
/**********************************************************************************************************************************/
const String *
storageType(const Storage *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->type);
}
/**********************************************************************************************************************************/
String *
storageToLog(const Storage *this)
{
return strNewFmt(
"{type: %s, path: %s, write: %s}", strZ(this->type), strZ(strToLog(this->path)), cvtBoolToConstZ(this->write));
"{type: %s, path: %s, write: %s}", strZ(storageType(this)), strZ(strToLog(this->path)), cvtBoolToConstZ(this->write));
}

View File

@ -21,6 +21,7 @@ typedef struct Storage Storage;
#include "common/type/param.h"
#include "storage/info.h"
#include "storage/read.h"
#include "storage/storage.intern.h"
#include "storage/write.h"
/***********************************************************************************************************************************
@ -252,10 +253,20 @@ void storageRemove(const Storage *this, const String *fileExp, StorageRemovePara
Getters/Setters
***********************************************************************************************************************************/
// Is the feature supported by this storage?
bool storageFeature(const Storage *this, StorageFeature feature);
__attribute__((always_inline)) static inline bool
storageFeature(const Storage *this, StorageFeature feature)
{
ASSERT_INLINE(this != NULL);
return ((const StoragePub *)this)->interface.feature >> feature & 1;
}
// Storage type (posix, cifs, etc.)
const String *storageType(const Storage *this);
__attribute__((always_inline)) static inline const String *
storageType(const Storage *this)
{
ASSERT_INLINE(this != NULL);
return ((const StoragePub *)this)->type;
}
/***********************************************************************************************************************************
Macros for function logging

View File

@ -14,9 +14,9 @@ in the description of each function.
#define STORAGE_STORAGE_INTERN_H
#include "common/type/param.h"
#include "storage/read.intern.h"
#include "storage/storage.h"
#include "storage/write.intern.h"
#include "storage/info.h"
#include "storage/read.h"
#include "storage/write.h"
/***********************************************************************************************************************************
Default file and path modes
@ -157,8 +157,8 @@ typedef struct StorageInterfaceInfoListParam
} StorageInterfaceInfoListParam;
typedef bool StorageInterfaceInfoList(
void *thisVoid, const String *path, StorageInfoLevel level, StorageInfoListCallback callback, void *callbackData,
StorageInterfaceInfoListParam param);
void *thisVoid, const String *path, StorageInfoLevel level, void (*callback)(void *callbackData, const StorageInfo *info),
void *callbackData, StorageInterfaceInfoListParam param);
#define storageInterfaceInfoListP(thisVoid, path, level, callback, callbackData, ...) \
STORAGE_COMMON_INTERFACE(thisVoid).infoList( \
@ -282,11 +282,28 @@ typedef struct StorageCommon
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
typedef struct StoragePub
{
const String *type; // Storage type
void *driver; // Storage driver
StorageInterface interface; // Storage interface
} StoragePub;
// Storage driver
void *storageDriver(const Storage *this);
__attribute__((always_inline)) static inline void *
storageDriver(const Storage *this)
{
ASSERT_INLINE(this != NULL);
return ((const StoragePub *)this)->driver;
}
// Storage interface
StorageInterface storageInterface(const Storage *this);
__attribute__((always_inline)) static inline StorageInterface
storageInterface(const Storage *this)
{
ASSERT_INLINE(this != NULL);
return ((const StoragePub *)this)->interface;
}
/***********************************************************************************************************************************
Macros for function logging

View File

@ -7,17 +7,16 @@ Storage Write Interface
#include "common/log.h"
#include "common/memContext.h"
#include "common/type/object.h"
#include "storage/write.intern.h"
#include "storage/write.h"
/***********************************************************************************************************************************
Object type
***********************************************************************************************************************************/
struct StorageWrite
{
StorageWritePub pub; // Publicly accessible variables
MemContext *memContext; // Object mem context
void *driver;
const StorageWriteInterface *interface;
IoWrite *io;
};
OBJECT_DEFINE_MOVE(STORAGE_WRITE);
@ -50,132 +49,18 @@ storageWriteNew(void *driver, const StorageWriteInterface *interface)
*this = (StorageWrite)
{
.memContext = memContextCurrent(),
.driver = driver,
.pub =
{
.interface = interface,
.io = ioWriteNew(driver, interface->ioInterface),
},
.memContext = memContextCurrent(),
.driver = driver,
};
FUNCTION_LOG_RETURN(STORAGE_WRITE, this);
}
/**********************************************************************************************************************************/
bool
storageWriteAtomic(const StorageWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->atomic);
}
/**********************************************************************************************************************************/
bool
storageWriteCreatePath(const StorageWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->createPath);
}
/**********************************************************************************************************************************/
IoWrite *
storageWriteIo(const StorageWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->io);
}
/**********************************************************************************************************************************/
mode_t
storageWriteModeFile(const StorageWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->modeFile);
}
/**********************************************************************************************************************************/
mode_t
storageWriteModePath(const StorageWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->modePath);
}
/**********************************************************************************************************************************/
const String *
storageWriteName(const StorageWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->name);
}
/**********************************************************************************************************************************/
bool
storageWriteSyncFile(const StorageWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->syncFile);
}
/**********************************************************************************************************************************/
bool
storageWriteSyncPath(const StorageWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->syncPath);
}
/**********************************************************************************************************************************/
const String *
storageWriteType(const StorageWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_WRITE, this);
FUNCTION_TEST_END();
ASSERT(this != NULL);
FUNCTION_TEST_RETURN(this->interface->type);
}
/**********************************************************************************************************************************/
String *
storageWriteToLog(const StorageWrite *this)

View File

@ -15,6 +15,7 @@ typedef struct StorageWrite StorageWrite;
#include "common/io/write.h"
#include "common/type/buffer.h"
#include "common/type/string.h"
#include "storage/write.intern.h"
/***********************************************************************************************************************************
Functions
@ -25,33 +26,84 @@ StorageWrite *storageWriteMove(StorageWrite *this, MemContext *parentNew);
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
typedef struct StorageWritePub
{
const StorageWriteInterface *interface; // File data (name, driver type, etc.)
IoWrite *io; // Write interface
} StorageWritePub;
// Will the file be written atomically? Atomic writes means the file will be complete or be missing. Filesystems have different ways
// to accomplish this.
bool storageWriteAtomic(const StorageWrite *this);
__attribute__((always_inline)) static inline bool
storageWriteAtomic(const StorageWrite *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageWritePub *)this)->interface->atomic;
}
// Will the path be created if required?
bool storageWriteCreatePath(const StorageWrite *this);
__attribute__((always_inline)) static inline bool
storageWriteCreatePath(const StorageWrite *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageWritePub *)this)->interface->createPath;
}
// Write interface
IoWrite *storageWriteIo(const StorageWrite *this);
__attribute__((always_inline)) static inline IoWrite *
storageWriteIo(const StorageWrite *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageWritePub *)this)->io;
}
// File mode
mode_t storageWriteModeFile(const StorageWrite *this);
__attribute__((always_inline)) static inline mode_t
storageWriteModeFile(const StorageWrite *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageWritePub *)this)->interface->modeFile;
}
// Path mode (if the destination path needs to be create)
mode_t storageWriteModePath(const StorageWrite *this);
__attribute__((always_inline)) static inline mode_t
storageWriteModePath(const StorageWrite *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageWritePub *)this)->interface->modePath;
}
// File name
const String *storageWriteName(const StorageWrite *this);
__attribute__((always_inline)) static inline const String *
storageWriteName(const StorageWrite *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageWritePub *)this)->interface->name;
}
// Will the file be synced before it is closed?
bool storageWriteSyncFile(const StorageWrite *this);
__attribute__((always_inline)) static inline bool
storageWriteSyncFile(const StorageWrite *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageWritePub *)this)->interface->syncFile;
}
// Will the path be synced after the file is closed?
bool storageWriteSyncPath(const StorageWrite *this);
__attribute__((always_inline)) static inline bool
storageWriteSyncPath(const StorageWrite *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageWritePub *)this)->interface->syncPath;
}
// File type
const String *storageWriteType(const StorageWrite *this);
__attribute__((always_inline)) static inline const String *
storageWriteType(const StorageWrite *this)
{
ASSERT_INLINE(this != NULL);
return ((const StorageWritePub *)this)->interface->type;
}
/***********************************************************************************************************************************
Destructor

View File

@ -5,7 +5,6 @@ Storage Write Interface Internal
#define STORAGE_WRITE_INTERN_H
#include "common/io/write.intern.h"
#include "storage/write.h"
#include "version.h"
/***********************************************************************************************************************************

View File

@ -532,8 +532,8 @@ testRun(void)
// No prior checksum, no compression, no pageChecksum, no delta, no hasReference
// With the expected backupCopyResultCopy, unset the storageFeatureCompress bit for the storageRepo for code coverage
uint64_t feature = storageRepo()->interface.feature;
((Storage *)storageRepo())->interface.feature = feature & ((1 << storageFeatureCompress) ^ 0xFFFFFFFFFFFFFFFF);
uint64_t feature = storageRepo()->pub.interface.feature;
((Storage *)storageRepo())->pub.interface.feature = feature & ((1 << storageFeatureCompress) ^ 0xFFFFFFFFFFFFFFFF);
// Create tmp file to make it look like a prior backup file failed partway through to ensure that retries work
TEST_RESULT_VOID(
@ -547,7 +547,7 @@ testRun(void)
cipherTypeNone, NULL),
"pg file exists and shrunk, no repo file, no ignoreMissing, no pageChecksum, no delta, no hasReference");
((Storage *)storageRepo())->interface.feature = feature;
((Storage *)storageRepo())->pub.interface.feature = feature;
TEST_RESULT_UINT(result.copySize + result.repoSize, 18, " copy=repo=pgFile size");
TEST_RESULT_UINT(result.backupCopyResult, backupCopyResultCopy, " copy file");
@ -1898,18 +1898,18 @@ testRun(void)
strNewFmt(STORAGE_REPO_BACKUP "/%s/" BACKUP_MANIFEST_FILE INFO_COPY_EXT, strZ(resumeLabel)))));
// Disable storageFeaturePath so paths will not be created before files are copied
((Storage *)storageRepoWrite())->interface.feature ^= 1 << storageFeaturePath;
((Storage *)storageRepoWrite())->pub.interface.feature ^= 1 << storageFeaturePath;
// Disable storageFeaturePathSync so paths will not be synced
((Storage *)storageRepoWrite())->interface.feature ^= 1 << storageFeaturePathSync;
((Storage *)storageRepoWrite())->pub.interface.feature ^= 1 << storageFeaturePathSync;
// Run backup
testBackupPqScriptP(PG_VERSION_95, backupTimeStart);
TEST_RESULT_VOID(cmdBackup(), "backup");
// Enable storage features
((Storage *)storageRepoWrite())->interface.feature |= 1 << storageFeaturePath;
((Storage *)storageRepoWrite())->interface.feature |= 1 << storageFeaturePathSync;
((Storage *)storageRepoWrite())->pub.interface.feature |= 1 << storageFeaturePath;
((Storage *)storageRepoWrite())->pub.interface.feature |= 1 << storageFeaturePathSync;
TEST_RESULT_LOG(
"P00 INFO: execute exclusive pg_start_backup(): backup begins after the next regular checkpoint completes\n"
@ -2396,18 +2396,18 @@ testRun(void)
NULL);
// Disable storageFeatureSymLink so tablespace (and latest) symlinks will not be created
((Storage *)storageRepoWrite())->interface.feature ^= 1 << storageFeatureSymLink;
((Storage *)storageRepoWrite())->pub.interface.feature ^= 1 << storageFeatureSymLink;
// Disable storageFeatureHardLink so hardlinks will not be created
((Storage *)storageRepoWrite())->interface.feature ^= 1 << storageFeatureHardLink;
((Storage *)storageRepoWrite())->pub.interface.feature ^= 1 << storageFeatureHardLink;
// Run backup
testBackupPqScriptP(PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 3);
TEST_RESULT_VOID(cmdBackup(), "backup");
// Reset storage features
((Storage *)storageRepoWrite())->interface.feature |= 1 << storageFeatureSymLink;
((Storage *)storageRepoWrite())->interface.feature |= 1 << storageFeatureHardLink;
((Storage *)storageRepoWrite())->pub.interface.feature |= 1 << storageFeatureSymLink;
((Storage *)storageRepoWrite())->pub.interface.feature |= 1 << storageFeatureHardLink;
TEST_RESULT_LOG(
"P00 INFO: execute non-exclusive pg_start_backup(): backup begins after the next regular checkpoint completes\n"

View File

@ -188,13 +188,13 @@ testRun(void)
Storage *storage = NULL;
TEST_ASSIGN(storage, storageRepoGet(0, false), "get repo storage");
TEST_RESULT_STR_Z(storage->path, "/repo", " check path");
TEST_RESULT_STR(((StorageAzure *)storage->driver)->account, TEST_ACCOUNT_STR, " check account");
TEST_RESULT_STR(((StorageAzure *)storage->driver)->container, TEST_CONTAINER_STR, " check container");
TEST_RESULT_STR(((StorageAzure *)storageDriver(storage))->account, TEST_ACCOUNT_STR, " check account");
TEST_RESULT_STR(((StorageAzure *)storageDriver(storage))->container, TEST_CONTAINER_STR, " check container");
TEST_RESULT_STR(
strNewEncode(encodeBase64, ((StorageAzure *)storage->driver)->sharedKey), TEST_KEY_SHARED_STR, " check key");
TEST_RESULT_STR_Z(((StorageAzure *)storage->driver)->host, TEST_ACCOUNT ".blob.core.windows.net", " check host");
TEST_RESULT_STR_Z(((StorageAzure *)storage->driver)->pathPrefix, "/" TEST_CONTAINER, " check path prefix");
TEST_RESULT_UINT(((StorageAzure *)storage->driver)->blockSize, STORAGE_AZURE_BLOCKSIZE_MIN, " check block size");
strNewEncode(encodeBase64, ((StorageAzure *)storageDriver(storage))->sharedKey), TEST_KEY_SHARED_STR, " check key");
TEST_RESULT_STR_Z(((StorageAzure *)storageDriver(storage))->host, TEST_ACCOUNT ".blob.core.windows.net", " check host");
TEST_RESULT_STR_Z(((StorageAzure *)storageDriver(storage))->pathPrefix, "/" TEST_CONTAINER, " check path prefix");
TEST_RESULT_UINT(((StorageAzure *)storageDriver(storage))->blockSize, STORAGE_AZURE_BLOCKSIZE_MIN, " check block size");
TEST_RESULT_BOOL(storageFeature(storage, storageFeaturePath), false, " check path feature");
TEST_RESULT_BOOL(storageFeature(storage, storageFeatureCompress), false, " check compress feature");
}
@ -298,7 +298,7 @@ testRun(void)
Storage *storage = NULL;
TEST_ASSIGN(storage, storageRepoGet(0, true), "get repo storage");
driver = (StorageAzure *)storage->driver;
driver = (StorageAzure *)storageDriver(storage);
TEST_RESULT_STR(driver->host, hrnServerHost(), " check host");
TEST_RESULT_STR_Z(driver->pathPrefix, "/" TEST_ACCOUNT "/" TEST_CONTAINER, " check path prefix");
TEST_RESULT_BOOL(driver->fileId == 0, false, " check file id");
@ -735,7 +735,7 @@ testRun(void)
TEST_ASSIGN(storage, storageRepoGet(0, true), "get repo storage");
driver = (StorageAzure *)storage->driver;
driver = (StorageAzure *)storageDriver(storage);
TEST_RESULT_PTR_NE(driver->sasKey, NULL, "check sas key");
hrnServerScriptAccept(service);

View File

@ -24,7 +24,7 @@ testRun(void)
const Storage *storage = NULL;
TEST_ASSIGN(storage, storageRepoGet(0, true), "get cifs repo storage");
TEST_RESULT_STR_Z(storage->type, "cifs", "check storage type");
TEST_RESULT_STR_Z(storageType(storage), "cifs", "check storage type");
TEST_RESULT_BOOL(storageFeature(storage, storageFeaturePath), true, " check path feature");
TEST_RESULT_BOOL(storageFeature(storage, storageFeatureCompress), true, " check compress feature");

View File

@ -209,10 +209,10 @@ testRun(void)
Storage *storage = NULL;
TEST_ASSIGN(storage, storageRepoGet(0, false), "get repo storage");
TEST_RESULT_STR_Z(storage->path, "/repo", " check path");
TEST_RESULT_STR(((StorageGcs *)storage->driver)->bucket, TEST_BUCKET_STR, " check bucket");
TEST_RESULT_STR_Z(((StorageGcs *)storage->driver)->endpoint, "storage.googleapis.com", " check endpoint");
TEST_RESULT_UINT(((StorageGcs *)storage->driver)->chunkSize, STORAGE_GCS_CHUNKSIZE_DEFAULT, " check chunk size");
TEST_RESULT_STR(((StorageGcs *)storage->driver)->token, TEST_TOKEN_STR, " check token");
TEST_RESULT_STR(((StorageGcs *)storageDriver(storage))->bucket, TEST_BUCKET_STR, " check bucket");
TEST_RESULT_STR_Z(((StorageGcs *)storageDriver(storage))->endpoint, "storage.googleapis.com", " check endpoint");
TEST_RESULT_UINT(((StorageGcs *)storageDriver(storage))->chunkSize, STORAGE_GCS_CHUNKSIZE_DEFAULT, " check chunk size");
TEST_RESULT_STR(((StorageGcs *)storageDriver(storage))->token, TEST_TOKEN_STR, " check token");
TEST_RESULT_BOOL(storageFeature(storage, storageFeaturePath), false, " check path feature");
TEST_RESULT_BOOL(storageFeature(storage, storageFeatureCompress), false, " check compress feature");
}
@ -322,11 +322,11 @@ testRun(void)
TEST_ASSIGN(storage, storageRepoGet(0, true), "get repo storage");
// Tests need the chunk size to be 16
((StorageGcs *)storage->driver)->chunkSize = 16;
((StorageGcs *)storageDriver(storage))->chunkSize = 16;
// Generate the auth request. The JWT part will need to be ? since it can vary in content and size.
const char *const preamble = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=";
const String *const jwt = storageGcsAuthJwt(((StorageGcs *)storage->driver), time(NULL));
const String *const jwt = storageGcsAuthJwt(((StorageGcs *)storageDriver(storage)), time(NULL));
String *const authRequest = strNewFmt(
"POST /token HTTP/1.1\r\n"
@ -354,7 +354,7 @@ testRun(void)
testResponseP(service);
storageGcsRequestP(
(StorageGcs *)storage->driver, HTTP_VERB_POST_STR, .noBucket = true,
(StorageGcs *)storageDriver(storage), HTTP_VERB_POST_STR, .noBucket = true,
.content = BUFSTR(jsonFromKv(kvPut(kvNew(), GCS_JSON_NAME_VAR, VARSTRDEF("bucket")))));
// -----------------------------------------------------------------------------------------------------------------

View File

@ -102,9 +102,9 @@ testRun(void)
TEST_RESULT_BOOL(storageTest->write, true, " check write");
TEST_RESULT_BOOL(storageTest->pathExpressionFunction != NULL, true, " check expression function is set");
TEST_RESULT_PTR(storageInterface(storageTest).info, storageTest->interface.info, " check interface");
TEST_RESULT_PTR(storageDriver(storageTest), storageTest->driver, " check driver");
TEST_RESULT_STR(storageType(storageTest), storageTest->type, " check type");
TEST_RESULT_PTR(storageInterface(storageTest).info, storageTest->pub.interface.info, " check interface");
TEST_RESULT_PTR(storageDriver(storageTest), storageDriver(storageTest), " check driver");
TEST_RESULT_STR(storageType(storageTest), storageType(storageTest), " check type");
TEST_RESULT_BOOL(storageFeature(storageTest, storageFeaturePath), true, " check path feature");
TEST_RESULT_BOOL(storageFeature(storageTest, storageFeatureCompress), true, " check compress feature");

View File

@ -350,7 +350,7 @@ testRun(void)
storagePutP(storageNewWriteP(storageTest, strNew("repo/test.txt")), contentBuf);
// Disable protocol compression in the storage object to test no compression
((StorageRemote *)storageRemote->driver)->compressLevel = 0;
((StorageRemote *)storageDriver(storageRemote))->compressLevel = 0;
StorageRead *fileRead = NULL;
@ -370,7 +370,7 @@ testRun(void)
TEST_RESULT_UINT(((StorageReadRemote *)fileRead->driver)->protocolReadBytes, 11, " check read size");
// Enable protocol compression in the storage object
((StorageRemote *)storageRemote->driver)->compressLevel = 3;
((StorageRemote *)storageDriver(storageRemote))->compressLevel = 3;
TEST_ASSIGN(
fileRead, storageNewReadP(storageRemote, strNew("test.txt"), .compressible = true), "get file (protocol compress)");
@ -490,7 +490,7 @@ testRun(void)
ioBufferSizeSet(9999);
// Disable protocol compression in the storage object to test no compression
((StorageRemote *)storageRemote->driver)->compressLevel = 0;
((StorageRemote *)storageDriver(storageRemote))->compressLevel = 0;
StorageWrite *write = NULL;
TEST_ASSIGN(write, storageNewWriteP(storageRemote, strNew("test.txt")), "new write file");
@ -513,7 +513,7 @@ testRun(void)
bufEq(storageGetP(storageNewReadP(storageRemote, strNew("test.txt"))), contentBuf), true, "check file");
// Enable protocol compression in the storage object
((StorageRemote *)storageRemote->driver)->compressLevel = 3;
((StorageRemote *)storageDriver(storageRemote))->compressLevel = 3;
// Write the file again, but this time free it before close and make sure the .tmp file is left
// -------------------------------------------------------------------------------------------------------------------------

View File

@ -388,7 +388,7 @@ testRun(void)
harnessCfgLoad(cfgCmdArchivePush, argList);
Storage *s3 = storageRepoGet(0, true);
StorageS3 *driver = (StorageS3 *)s3->driver;
StorageS3 *driver = (StorageS3 *)storageDriver(s3);
TEST_RESULT_STR(s3->path, path, "check path");
TEST_RESULT_BOOL(storageFeature(s3, storageFeaturePath), false, "check path feature");
@ -446,7 +446,7 @@ testRun(void)
harnessCfgLoad(cfgCmdArchivePush, argList);
s3 = storageRepoGet(0, true);
driver = (StorageS3 *)s3->driver;
driver = (StorageS3 *)storageDriver(s3);
TEST_RESULT_STR(s3->path, path, "check path");
TEST_RESULT_STR(driver->credRole, credRole, "check role");
@ -1020,7 +1020,7 @@ testRun(void)
harnessCfgLoad(cfgCmdArchivePush, argList);
s3 = storageRepoGet(0, true);
driver = (StorageS3 *)s3->driver;
driver = (StorageS3 *)storageDriver(s3);
// Set deleteMax to a small value for testing
driver->deleteMax = 2;