LibrePCB Developers Documentation
transactionalfilesystem.h
Go to the documentation of this file.
1/*
2 * LibrePCB - Professional EDA for everyone!
3 * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4 * https://librepcb.org/
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef LIBREPCB_CORE_TRANSACTIONALFILESYSTEM_H
21#define LIBREPCB_CORE_TRANSACTIONALFILESYSTEM_H
22
23/*******************************************************************************
24 * Includes
25 ******************************************************************************/
26#include "../exceptions.h"
27#include "directorylock.h"
28#include "filesystem.h"
29
30#include <QtCore>
31
32#include <memory>
33
34/*******************************************************************************
35 * Namespace / Forward Declarations
36 ******************************************************************************/
37
38class QuaZipFile;
39
40namespace librepcb {
41
42/*******************************************************************************
43 * Class TransactionalFileSystem
44 ******************************************************************************/
45
71class TransactionalFileSystem final : public FileSystem {
72 Q_OBJECT
73
74public:
83 typedef std::function<bool(const QString& filePath)> FilterFunction;
84
96 typedef std::function<bool(const FilePath& dir)> RestoreCallback;
97
104 struct RestoreMode {
112 static bool no(const FilePath& dir) {
113 Q_UNUSED(dir);
114 return false;
115 }
116
124 static bool yes(const FilePath& dir) {
125 Q_UNUSED(dir);
126 return true;
127 }
128
139 static bool abort(const FilePath& dir) {
140 throw RuntimeError(__FILE__, __LINE__,
141 QString("Autosave backup detected in directory '%1'.")
142 .arg(dir.toNative()));
143 }
144 };
145
146 // Constructors / Destructor
149 const FilePath& filepath, bool writable = false,
150 RestoreCallback restoreCallback = RestoreCallback(),
151 DirectoryLock::LockHandlerCallback lockCallback = nullptr,
152 QObject* parent = nullptr);
154 virtual ~TransactionalFileSystem() noexcept;
155
156 // Getters
157 const FilePath& getPath() const noexcept { return mFilePath; }
158 bool isWritable() const noexcept { return mIsWritable; }
159 bool isRestoredFromAutosave() const noexcept { return mRestoredFromAutosave; }
160
161 // Inherited from FileSystem
162 virtual FilePath getAbsPath(const QString& path = "") const noexcept override;
163 virtual QStringList getDirs(const QString& path = "") const noexcept override;
164 virtual QStringList getFiles(
165 const QString& path = "") const noexcept override;
166 virtual bool fileExists(const QString& path) const noexcept override;
167 virtual QByteArray read(const QString& path) const override;
168 virtual QByteArray readIfExists(const QString& path) const override;
169 virtual void write(const QString& path, const QByteArray& content) override;
170 virtual void renameFile(const QString& src, const QString& dst) override;
171 virtual void removeFile(const QString& path) override;
172 virtual void removeDirRecursively(const QString& path = "") override;
173
174 // General Methods
175 void loadFromZip(QByteArray content);
176 void loadFromZip(const FilePath& fp);
177 QByteArray exportToZip(FilterFunction filter = nullptr) const;
178 void exportToZip(const FilePath& fp, FilterFunction filter = nullptr) const;
179 void discardChanges() noexcept;
180 QStringList checkForModifications() const;
181 void autosave();
182 void save();
183 void releaseLock();
184
185 // Static Methods
186 static std::shared_ptr<TransactionalFileSystem> open(
187 const FilePath& filepath, bool writable,
188 RestoreCallback restoreCallback = &RestoreMode::no,
189 DirectoryLock::LockHandlerCallback lockCallback = nullptr,
190 QObject* parent = nullptr) {
191 return std::make_shared<TransactionalFileSystem>(
192 filepath, writable, restoreCallback, lockCallback, parent);
193 }
194 static std::shared_ptr<TransactionalFileSystem> openRO(
195 const FilePath& filepath,
196 RestoreCallback restoreCallback = &RestoreMode::no,
197 QObject* parent = nullptr) {
198 return open(filepath, false, restoreCallback, nullptr, parent);
199 }
200 static std::shared_ptr<TransactionalFileSystem> openRW(
201 const FilePath& filepath,
202 RestoreCallback restoreCallback = &RestoreMode::no,
203 DirectoryLock::LockHandlerCallback lockCallback = nullptr,
204 QObject* parent = nullptr) {
205 return open(filepath, true, restoreCallback, lockCallback, parent);
206 }
207 static QString cleanPath(QString path) noexcept;
208
209private: // Methods
210 bool isRemoved(const QString& path) const noexcept;
211 void exportDirToZip(QuaZipFile& file, const FilePath& zipFp,
212 const QString& dir, FilterFunction filter) const;
213 void saveDiff(const QString& type) const;
214 void loadDiff(const FilePath& fp);
215 void removeDiff(const QString& type);
216
217private: // Data
222#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
223 mutable QRecursiveMutex mMutex;
224#else
225 mutable QMutex mMutex;
226#endif
227
228 // File system modifications
229 QHash<QString, QByteArray> mModifiedFiles;
230 QSet<QString> mRemovedFiles;
231 QSet<QString> mRemovedDirs;
232};
233
234/*******************************************************************************
235 * End of File
236 ******************************************************************************/
237
238} // namespace librepcb
239
240#endif
This class can be used to implement file-based directory locks.
Definition: directorylock.h:154
std::function< bool(const FilePath &dir, LockStatus status, const QString &user)> LockHandlerCallback
Callback type used to determine whether a lock should be overridden or not.
Definition: directorylock.h:193
This class represents absolute, well-formatted paths to files or directories.
Definition: filepath.h:129
QString toNative() const noexcept
Get the absolute filepath with native directory separators.
Definition: filepath.cpp:108
Base class / interface for all file system implementations.
Definition: filesystem.h:45
The RuntimeError class.
Definition: exceptions.h:218
Transactional librepcb::FileSystem implementation.
Definition: transactionalfilesystem.h:71
DirectoryLock mLock
Definition: transactionalfilesystem.h:220
virtual void removeDirRecursively(const QString &path="") override
Definition: transactionalfilesystem.cpp:220
QRecursiveMutex mMutex
Definition: transactionalfilesystem.h:223
virtual bool fileExists(const QString &path) const noexcept override
Definition: transactionalfilesystem.cpp:162
void discardChanges() noexcept
Definition: transactionalfilesystem.cpp:322
bool mRestoredFromAutosave
Definition: transactionalfilesystem.h:221
void autosave()
Definition: transactionalfilesystem.cpp:362
virtual QStringList getFiles(const QString &path="") const noexcept override
Definition: transactionalfilesystem.cpp:134
virtual void renameFile(const QString &src, const QString &dst) override
Definition: transactionalfilesystem.cpp:207
void releaseLock()
Definition: transactionalfilesystem.cpp:410
virtual void write(const QString &path, const QByteArray &content) override
Definition: transactionalfilesystem.cpp:199
const FilePath & getPath() const noexcept
Definition: transactionalfilesystem.h:157
virtual QStringList getDirs(const QString &path="") const noexcept override
Definition: transactionalfilesystem.cpp:105
QStringList checkForModifications() const
Definition: transactionalfilesystem.cpp:329
QSet< QString > mRemovedFiles
Definition: transactionalfilesystem.h:230
static std::shared_ptr< TransactionalFileSystem > open(const FilePath &filepath, bool writable, RestoreCallback restoreCallback=&RestoreMode::no, DirectoryLock::LockHandlerCallback lockCallback=nullptr, QObject *parent=nullptr)
Definition: transactionalfilesystem.h:186
QByteArray exportToZip(FilterFunction filter=nullptr) const
Definition: transactionalfilesystem.cpp:280
void exportDirToZip(QuaZipFile &file, const FilePath &zipFp, const QString &dir, FilterFunction filter) const
Definition: transactionalfilesystem.cpp:445
virtual ~TransactionalFileSystem() noexcept
Definition: transactionalfilesystem.cpp:81
TransactionalFileSystem(const TransactionalFileSystem &other)=delete
void saveDiff(const QString &type) const
Definition: transactionalfilesystem.cpp:489
bool isRemoved(const QString &path) const noexcept
Definition: transactionalfilesystem.cpp:431
static std::shared_ptr< TransactionalFileSystem > openRW(const FilePath &filepath, RestoreCallback restoreCallback=&RestoreMode::no, DirectoryLock::LockHandlerCallback lockCallback=nullptr, QObject *parent=nullptr)
Definition: transactionalfilesystem.h:200
bool isRestoredFromAutosave() const noexcept
Definition: transactionalfilesystem.h:159
virtual void removeFile(const QString &path) override
Definition: transactionalfilesystem.cpp:213
virtual QByteArray read(const QString &path) const override
Definition: transactionalfilesystem.cpp:174
void loadDiff(const FilePath &fp)
Definition: transactionalfilesystem.cpp:526
bool mIsWritable
Definition: transactionalfilesystem.h:219
std::function< bool(const FilePath &dir)> RestoreCallback
Callback type used to determine whether a backup should be restored or not.
Definition: transactionalfilesystem.h:96
void save()
Definition: transactionalfilesystem.cpp:367
void removeDiff(const QString &type)
Definition: transactionalfilesystem.cpp:549
static std::shared_ptr< TransactionalFileSystem > openRO(const FilePath &filepath, RestoreCallback restoreCallback=&RestoreMode::no, QObject *parent=nullptr)
Definition: transactionalfilesystem.h:194
static QString cleanPath(QString path) noexcept
Definition: transactionalfilesystem.cpp:419
bool isWritable() const noexcept
Definition: transactionalfilesystem.h:158
std::function< bool(const QString &filePath)> FilterFunction
Function to filter files.
Definition: transactionalfilesystem.h:83
void loadFromZip(QByteArray content)
Definition: transactionalfilesystem.cpp:241
QSet< QString > mRemovedDirs
Definition: transactionalfilesystem.h:231
QHash< QString, QByteArray > mModifiedFiles
Definition: transactionalfilesystem.h:229
const FilePath mFilePath
Definition: transactionalfilesystem.h:218
virtual QByteArray readIfExists(const QString &path) const override
Definition: transactionalfilesystem.cpp:185
virtual FilePath getAbsPath(const QString &path="") const noexcept override
Definition: transactionalfilesystem.cpp:100
Definition: occmodel.cpp:77
Convenience class providing standard implementations for librepcb::TransactionalFileSystem::RestoreCa...
Definition: transactionalfilesystem.h:104
static bool yes(const FilePath &dir)
Always restore the backup, if there is any.
Definition: transactionalfilesystem.h:124
static bool abort(const FilePath &dir)
If there exists a backup, abort opening the directory by raising an exception.
Definition: transactionalfilesystem.h:139
static bool no(const FilePath &dir)
Never restore a backup.
Definition: transactionalfilesystem.h:112