Introduce AtomicFiles

Introduce AtomicFile and a test of this module to the code.

AtomicFile is like File, except all writes go to temporary files until
the class method finalize_all () is called and the temporary files are
copied over the real files. If any writes fail, like when there is no
more space on the filesystem, none of the files in the database will be
modified.

Since we need version 1.00 of libfiu, I have only added it to the debian
testing container, which includes libfiu-1.00 in the default repository.

Related to #155
This commit is contained in:
Shaun Ruffell 2020-02-16 12:52:10 -06:00 committed by lauft
parent 6db1d2b859
commit 8e99c07d85
9 changed files with 1039 additions and 6 deletions

78
src/AtomicFile.h Normal file
View file

@ -0,0 +1,78 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2020, Shaun Ruffell, Thomas Lauf.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// https://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_ATOMICFILE
#define INCLUDED_ATOMICFILE
#include <memory>
#include <vector>
class Path;
class AtomicFile
{
public:
AtomicFile (const Path& path);
AtomicFile (std::string path);
AtomicFile (const AtomicFile&) = delete;
AtomicFile (AtomicFile&&);
AtomicFile& operator= (const AtomicFile&) = delete;
AtomicFile& operator= (AtomicFile&&);
~AtomicFile ();
std::string name () const;
const std::string& path () const;
bool exists () const;
bool open ();
void close ();
void truncate ();
void read (std::string& content);
void read (std::vector <std::string>& lines);
void append (const std::string& content);
void write_raw (const std::string& content);
static void append (const std::string& path, const std::string& data);
static void append (const Path& path, const std::string& data);
static void write (const std::string& path, const std::string& data);
static void write (const Path& path, const std::string& data);
static void write (const Path& path, const std::vector <std::string>& lines);
static void read (const std::string& path, std::string& content);
static void read (const Path& path, std::string& content);
static void read (const Path& path, std::vector <std::string>& lines);
static void finalize_all ();
static void reset ();
public:
struct impl;
private:
std::shared_ptr <impl> pimpl;
};
#endif // INCLUDED_ATOMICFILE