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_TRANSACTIONALFILESYSTEM_H
21 #define LIBREPCB_TRANSACTIONALFILESYSTEM_H
22 
23 /*******************************************************************************
24  * Includes
25  ******************************************************************************/
26 #include "directorylock.h"
27 #include "filesystem.h"
28 
29 #include <QtCore>
30 
31 #include <memory>
32 
33 /*******************************************************************************
34  * Namespace / Forward Declarations
35  ******************************************************************************/
36 
37 class QuaZipFile;
38 
39 namespace librepcb {
40 
41 /*******************************************************************************
42  * Class TransactionalFileSystem
43  ******************************************************************************/
44 
63 class TransactionalFileSystem final : public FileSystem {
64  Q_OBJECT
65 
66 public:
78  typedef std::function<bool(const FilePath& dir)> RestoreCallback;
79 
86  struct RestoreMode {
94  static bool no(const FilePath& dir) {
95  Q_UNUSED(dir);
96  return false;
97  }
98 
106  static bool yes(const FilePath& dir) {
107  Q_UNUSED(dir);
108  return true;
109  }
110 
121  static bool abort(const FilePath& dir) {
122  throw RuntimeError(__FILE__, __LINE__,
123  QString("Autosave backup detected in directory '%1'.")
124  .arg(dir.toNative()));
125  }
126  };
127 
128  // Constructors / Destructor
129  TransactionalFileSystem() = delete;
131  const FilePath& filepath, bool writable = false,
132  RestoreCallback restoreCallback = RestoreCallback(),
133  DirectoryLock::LockHandlerCallback lockCallback = nullptr,
134  QObject* parent = nullptr);
135  TransactionalFileSystem(const TransactionalFileSystem& other) = delete;
136  virtual ~TransactionalFileSystem() noexcept;
137 
138  // Getters
139  const FilePath& getPath() const noexcept { return mFilePath; }
140  bool isWritable() const noexcept { return mIsWritable; }
141  bool isRestoredFromAutosave() const noexcept { return mRestoredFromAutosave; }
142 
143  // Inherited from FileSystem
144  virtual FilePath getAbsPath(const QString& path = "") const noexcept override;
145  virtual QStringList getDirs(const QString& path = "") const noexcept override;
146  virtual QStringList getFiles(const QString& path = "") const
147  noexcept override;
148  virtual bool fileExists(const QString& path) const noexcept override;
149  virtual QByteArray read(const QString& path) const override;
150  virtual void write(const QString& path, const QByteArray& content) override;
151  virtual void removeFile(const QString& path) override;
152  virtual void removeDirRecursively(const QString& path = "") override;
153 
154  // General Methods
155  void loadFromZip(QByteArray content);
156  void loadFromZip(const FilePath& fp);
157  QByteArray exportToZip() const;
158  void exportToZip(const FilePath& fp) const;
159  void discardChanges() noexcept;
160  QStringList checkForModifications() const;
161  void autosave();
162  void save();
163 
164  // Static Methods
165  static std::shared_ptr<TransactionalFileSystem> open(
166  const FilePath& filepath, bool writable,
167  RestoreCallback restoreCallback = &RestoreMode::no,
168  DirectoryLock::LockHandlerCallback lockCallback = nullptr,
169  QObject* parent = nullptr) {
170  return std::make_shared<TransactionalFileSystem>(
171  filepath, writable, restoreCallback, lockCallback, parent);
172  }
173  static std::shared_ptr<TransactionalFileSystem> openRO(
174  const FilePath& filepath,
175  RestoreCallback restoreCallback = &RestoreMode::no,
176  QObject* parent = nullptr) {
177  return open(filepath, false, restoreCallback, nullptr, parent);
178  }
179  static std::shared_ptr<TransactionalFileSystem> openRW(
180  const FilePath& filepath,
181  RestoreCallback restoreCallback = &RestoreMode::no,
182  DirectoryLock::LockHandlerCallback lockCallback = nullptr,
183  QObject* parent = nullptr) {
184  return open(filepath, true, restoreCallback, lockCallback, parent);
185  }
186  static QString cleanPath(QString path) noexcept;
187 
188 private: // Methods
189  bool isRemoved(const QString& path) const noexcept;
190  void exportDirToZip(QuaZipFile& file, const FilePath& zipFp,
191  const QString& dir) const;
192  void saveDiff(const QString& type) const;
193  void loadDiff(const FilePath& fp);
194  void removeDiff(const QString& type);
195 
196 private: // Data
201 
202  // File system modifications
203  QHash<QString, QByteArray> mModifiedFiles;
204  QSet<QString> mRemovedFiles;
205  QSet<QString> mRemovedDirs;
206 };
207 
208 /*******************************************************************************
209  * End of File
210  ******************************************************************************/
211 
212 } // namespace librepcb
213 
214 #endif // LIBREPCB_TRANSACTIONALFILESYSTEM_H
Transactional librepcb::FileSystem implementation.
Definition: transactionalfilesystem.h:63
Definition: airwiresbuilder.cpp:32
void discardChanges() noexcept
Definition: transactionalfilesystem.cpp:287
void loadDiff(const FilePath &fp)
Definition: transactionalfilesystem.cpp:471
QByteArray exportToZip() const
Definition: transactionalfilesystem.cpp:248
void removeDiff(const QString &type)
Definition: transactionalfilesystem.cpp:494
virtual void write(const QString &path, const QByteArray &content) override
Definition: transactionalfilesystem.cpp:184
virtual FilePath getAbsPath(const QString &path="") const noexcept override
Definition: transactionalfilesystem.cpp:100
static bool yes(const FilePath &dir)
Always restore the backup, if there is any.
Definition: transactionalfilesystem.h:106
void loadFromZip(QByteArray content)
Definition: transactionalfilesystem.cpp:217
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:165
bool isWritable() const noexcept
Definition: transactionalfilesystem.h:140
void exportDirToZip(QuaZipFile &file, const FilePath &zipFp, const QString &dir) const
Definition: transactionalfilesystem.cpp:400
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:194
virtual ~TransactionalFileSystem() noexcept
Definition: transactionalfilesystem.cpp:81
QStringList checkForModifications() const
Definition: transactionalfilesystem.cpp:293
virtual QByteArray read(const QString &path) const override
Definition: transactionalfilesystem.cpp:171
void save()
Definition: transactionalfilesystem.cpp:329
virtual QStringList getDirs(const QString &path="") const noexcept override
Definition: transactionalfilesystem.cpp:105
const FilePath & getPath() const noexcept
Definition: transactionalfilesystem.h:139
DirectoryLock mLock
Definition: transactionalfilesystem.h:199
virtual bool fileExists(const QString &path) const noexcept override
Definition: transactionalfilesystem.cpp:160
The RuntimeError class.
Definition: exceptions.h:216
QHash< QString, QByteArray > mModifiedFiles
Definition: transactionalfilesystem.h:203
static std::shared_ptr< TransactionalFileSystem > openRW(const FilePath &filepath, RestoreCallback restoreCallback=&RestoreMode::no, DirectoryLock::LockHandlerCallback lockCallback=nullptr, QObject *parent=nullptr)
Definition: transactionalfilesystem.h:179
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:86
QString toNative() const noexcept
Get the absolute filepath with native directory separators.
Definition: filepath.cpp:103
static bool abort(const FilePath &dir)
If there exists a backup, abort opening the directory by raising an exception.
Definition: transactionalfilesystem.h:121
FilePath mFilePath
Definition: transactionalfilesystem.h:197
bool mRestoredFromAutosave
Definition: transactionalfilesystem.h:200
virtual void removeFile(const QString &path) override
Definition: transactionalfilesystem.cpp:191
QSet< QString > mRemovedFiles
Definition: transactionalfilesystem.h:204
QSet< QString > mRemovedDirs
Definition: transactionalfilesystem.h:205
Base class / interface for all file system implementations.
Definition: filesystem.h:43
bool isRestoredFromAutosave() const noexcept
Definition: transactionalfilesystem.h:141
std::function< bool(const FilePath &dir)> RestoreCallback
Callback type used to determine whether a backup should be restored or not.
Definition: transactionalfilesystem.h:78
static bool no(const FilePath &dir)
Never restore a backup.
Definition: transactionalfilesystem.h:94
bool isRemoved(const QString &path) const noexcept
Definition: transactionalfilesystem.cpp:386
static QString cleanPath(QString path) noexcept
Definition: transactionalfilesystem.cpp:374
static std::shared_ptr< TransactionalFileSystem > openRO(const FilePath &filepath, RestoreCallback restoreCallback=&RestoreMode::no, QObject *parent=nullptr)
Definition: transactionalfilesystem.h:173
bool mIsWritable
Definition: transactionalfilesystem.h:198
virtual QStringList getFiles(const QString &path="") const noexcept override
Definition: transactionalfilesystem.cpp:133
virtual void removeDirRecursively(const QString &path="") override
Definition: transactionalfilesystem.cpp:197
This class can be used to implement file-based directory locks.
Definition: directorylock.h:155
void autosave()
Definition: transactionalfilesystem.cpp:325
void saveDiff(const QString &type) const
Definition: transactionalfilesystem.cpp:441