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 
38 class QuaZipFile;
39 
40 namespace librepcb {
41 
42 /*******************************************************************************
43  * Class TransactionalFileSystem
44  ******************************************************************************/
45 
71 class TransactionalFileSystem final : public FileSystem {
72  Q_OBJECT
73 
74 public:
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
147  TransactionalFileSystem() = delete;
149  const FilePath& filepath, bool writable = false,
150  RestoreCallback restoreCallback = RestoreCallback(),
151  DirectoryLock::LockHandlerCallback lockCallback = nullptr,
152  QObject* parent = nullptr);
153  TransactionalFileSystem(const TransactionalFileSystem& other) = delete;
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(const QString& path = "") const
165  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 removeFile(const QString& path) override;
171  virtual void removeDirRecursively(const QString& path = "") override;
172 
173  // General Methods
174  void loadFromZip(QByteArray content);
175  void loadFromZip(const FilePath& fp);
176  QByteArray exportToZip(FilterFunction filter = nullptr) const;
177  void exportToZip(const FilePath& fp, FilterFunction filter = nullptr) const;
178  void discardChanges() noexcept;
179  QStringList checkForModifications() const;
180  void autosave();
181  void save();
182 
183  // Static Methods
184  static std::shared_ptr<TransactionalFileSystem> open(
185  const FilePath& filepath, bool writable,
186  RestoreCallback restoreCallback = &RestoreMode::no,
187  DirectoryLock::LockHandlerCallback lockCallback = nullptr,
188  QObject* parent = nullptr) {
189  return std::make_shared<TransactionalFileSystem>(
190  filepath, writable, restoreCallback, lockCallback, parent);
191  }
192  static std::shared_ptr<TransactionalFileSystem> openRO(
193  const FilePath& filepath,
194  RestoreCallback restoreCallback = &RestoreMode::no,
195  QObject* parent = nullptr) {
196  return open(filepath, false, restoreCallback, nullptr, parent);
197  }
198  static std::shared_ptr<TransactionalFileSystem> openRW(
199  const FilePath& filepath,
200  RestoreCallback restoreCallback = &RestoreMode::no,
201  DirectoryLock::LockHandlerCallback lockCallback = nullptr,
202  QObject* parent = nullptr) {
203  return open(filepath, true, restoreCallback, lockCallback, parent);
204  }
205  static QString cleanPath(QString path) noexcept;
206 
207 private: // Methods
208  bool isRemoved(const QString& path) const noexcept;
209  void exportDirToZip(QuaZipFile& file, const FilePath& zipFp,
210  const QString& dir, FilterFunction filter) const;
211  void saveDiff(const QString& type) const;
212  void loadDiff(const FilePath& fp);
213  void removeDiff(const QString& type);
214 
215 private: // Data
217  const bool mIsWritable;
220  mutable QMutex mMutex;
221 
222  // File system modifications
223  QHash<QString, QByteArray> mModifiedFiles;
224  QSet<QString> mRemovedFiles;
225  QSet<QString> mRemovedDirs;
226 };
227 
228 /*******************************************************************************
229  * End of File
230  ******************************************************************************/
231 
232 } // namespace librepcb
233 
234 #endif
const FilePath mFilePath
Definition: transactionalfilesystem.h:216
virtual QByteArray readIfExists(const QString &path) const override
Definition: transactionalfilesystem.cpp:180
Transactional librepcb::FileSystem implementation.
Definition: transactionalfilesystem.h:71
void exportDirToZip(QuaZipFile &file, const FilePath &zipFp, const QString &dir, FilterFunction filter) const
Definition: transactionalfilesystem.cpp:429
Definition: occmodel.cpp:76
void discardChanges() noexcept
Definition: transactionalfilesystem.cpp:311
const bool mIsWritable
Definition: transactionalfilesystem.h:217
void loadDiff(const FilePath &fp)
Definition: transactionalfilesystem.cpp:509
void removeDiff(const QString &type)
Definition: transactionalfilesystem.cpp:532
virtual void write(const QString &path, const QByteArray &content) override
Definition: transactionalfilesystem.cpp:194
virtual FilePath getAbsPath(const QString &path="") const noexcept override
Definition: transactionalfilesystem.cpp:95
static bool yes(const FilePath &dir)
Always restore the backup, if there is any.
Definition: transactionalfilesystem.h:124
void loadFromZip(QByteArray content)
Definition: transactionalfilesystem.cpp: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:184
QByteArray exportToZip(FilterFunction filter=nullptr) const
Definition: transactionalfilesystem.cpp:269
bool isWritable() const noexcept
Definition: transactionalfilesystem.h:158
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
virtual ~TransactionalFileSystem() noexcept
Definition: transactionalfilesystem.cpp:76
QStringList checkForModifications() const
Definition: transactionalfilesystem.cpp:318
virtual QByteArray read(const QString &path) const override
Definition: transactionalfilesystem.cpp:169
void save()
Definition: transactionalfilesystem.cpp:356
virtual QStringList getDirs(const QString &path="") const noexcept override
Definition: transactionalfilesystem.cpp:100
const FilePath & getPath() const noexcept
Definition: transactionalfilesystem.h:157
DirectoryLock mLock
Definition: transactionalfilesystem.h:218
virtual bool fileExists(const QString &path) const noexcept override
Definition: transactionalfilesystem.cpp:157
The RuntimeError class.
Definition: exceptions.h:216
QHash< QString, QByteArray > mModifiedFiles
Definition: transactionalfilesystem.h:223
static std::shared_ptr< TransactionalFileSystem > openRW(const FilePath &filepath, RestoreCallback restoreCallback=&RestoreMode::no, DirectoryLock::LockHandlerCallback lockCallback=nullptr, QObject *parent=nullptr)
Definition: transactionalfilesystem.h:198
This class represents absolute, well-formatted paths to files or directories.
Definition: filepath.h:127
Convenience class providing standard implementations for librepcb::TransactionalFileSystem::RestoreCa...
Definition: transactionalfilesystem.h:104
QString toNative() const noexcept
Get the absolute filepath with native directory separators.
Definition: filepath.cpp:108
static bool abort(const FilePath &dir)
If there exists a backup, abort opening the directory by raising an exception.
Definition: transactionalfilesystem.h:139
std::function< bool(const QString &filePath)> FilterFunction
Function to filter files.
Definition: transactionalfilesystem.h:83
bool mRestoredFromAutosave
Definition: transactionalfilesystem.h:219
virtual void removeFile(const QString &path) override
Definition: transactionalfilesystem.cpp:202
QMutex mMutex
Definition: transactionalfilesystem.h:220
QSet< QString > mRemovedFiles
Definition: transactionalfilesystem.h:224
QSet< QString > mRemovedDirs
Definition: transactionalfilesystem.h:225
Base class / interface for all file system implementations.
Definition: filesystem.h:45
bool isRestoredFromAutosave() const noexcept
Definition: transactionalfilesystem.h:159
std::function< bool(const FilePath &dir)> RestoreCallback
Callback type used to determine whether a backup should be restored or not.
Definition: transactionalfilesystem.h:96
static bool no(const FilePath &dir)
Never restore a backup.
Definition: transactionalfilesystem.h:112
bool isRemoved(const QString &path) const noexcept
Definition: transactionalfilesystem.cpp:415
static QString cleanPath(QString path) noexcept
Definition: transactionalfilesystem.cpp:403
static std::shared_ptr< TransactionalFileSystem > openRO(const FilePath &filepath, RestoreCallback restoreCallback=&RestoreMode::no, QObject *parent=nullptr)
Definition: transactionalfilesystem.h:192
virtual QStringList getFiles(const QString &path="") const noexcept override
Definition: transactionalfilesystem.cpp:129
virtual void removeDirRecursively(const QString &path="") override
Definition: transactionalfilesystem.cpp:209
This class can be used to implement file-based directory locks.
Definition: directorylock.h:154
void autosave()
Definition: transactionalfilesystem.cpp:351
void saveDiff(const QString &type) const
Definition: transactionalfilesystem.cpp:473