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;
130  TransactionalFileSystem(const FilePath& filepath, bool writable = false,
131  RestoreCallback restoreCallback = RestoreCallback(),
132  QObject* parent = nullptr);
133  TransactionalFileSystem(const TransactionalFileSystem& other) = delete;
134  virtual ~TransactionalFileSystem() noexcept;
135 
136  // Getters
137  const FilePath& getPath() const noexcept { return mFilePath; }
138  bool isWritable() const noexcept { return mIsWritable; }
139  bool isRestoredFromAutosave() const noexcept { return mRestoredFromAutosave; }
140 
141  // Inherited from FileSystem
142  virtual FilePath getAbsPath(const QString& path = "") const noexcept override;
143  virtual QStringList getDirs(const QString& path = "") const noexcept override;
144  virtual QStringList getFiles(const QString& path = "") const
145  noexcept override;
146  virtual bool fileExists(const QString& path) const noexcept override;
147  virtual QByteArray read(const QString& path) const override;
148  virtual void write(const QString& path, const QByteArray& content) override;
149  virtual void removeFile(const QString& path) override;
150  virtual void removeDirRecursively(const QString& path = "") override;
151 
152  // General Methods
153  void loadFromZip(const FilePath& fp);
154  void exportToZip(const FilePath& fp) const;
155  void discardChanges() noexcept;
156  QStringList checkForModifications() const;
157  void autosave();
158  void save();
159 
160  // Static Methods
161  static std::shared_ptr<TransactionalFileSystem> open(
162  const FilePath& filepath, bool writable,
163  RestoreCallback restoreCallback = &RestoreMode::no,
164  QObject* parent = nullptr) {
165  return std::make_shared<TransactionalFileSystem>(filepath, writable,
166  restoreCallback, parent);
167  }
168  static std::shared_ptr<TransactionalFileSystem> openRO(
169  const FilePath& filepath,
170  RestoreCallback restoreCallback = &RestoreMode::no,
171  QObject* parent = nullptr) {
172  return open(filepath, false, restoreCallback, parent);
173  }
174  static std::shared_ptr<TransactionalFileSystem> openRW(
175  const FilePath& filepath,
176  RestoreCallback restoreCallback = &RestoreMode::no,
177  QObject* parent = nullptr) {
178  return open(filepath, true, restoreCallback, parent);
179  }
180  static QString cleanPath(QString path) noexcept;
181 
182 private: // Methods
183  bool isRemoved(const QString& path) const noexcept;
184  void exportDirToZip(QuaZipFile& file, const FilePath& zipFp,
185  const QString& dir) const;
186  void saveDiff(const QString& type) const;
187  void loadDiff(const FilePath& fp);
188  void removeDiff(const QString& type);
189 
190 private: // Data
195 
196  // File system modifications
197  QHash<QString, QByteArray> mModifiedFiles;
198  QSet<QString> mRemovedFiles;
199  QSet<QString> mRemovedDirs;
200 };
201 
202 /*******************************************************************************
203  * End of File
204  ******************************************************************************/
205 
206 } // namespace librepcb
207 
208 #endif // LIBREPCB_TRANSACTIONALFILESYSTEM_H
void exportToZip(const FilePath &fp) const
Definition: transactionalfilesystem.cpp:233
Transactional librepcb::FileSystem implementation.
Definition: transactionalfilesystem.h:63
Definition: airwiresbuilder.cpp:32
void discardChanges() noexcept
Definition: transactionalfilesystem.cpp:252
void loadDiff(const FilePath &fp)
Definition: transactionalfilesystem.cpp:436
void removeDiff(const QString &type)
Definition: transactionalfilesystem.cpp:459
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
bool isWritable() const noexcept
Definition: transactionalfilesystem.h:138
void exportDirToZip(QuaZipFile &file, const FilePath &zipFp, const QString &dir) const
Definition: transactionalfilesystem.cpp:365
virtual ~TransactionalFileSystem() noexcept
Definition: transactionalfilesystem.cpp:81
void loadFromZip(const FilePath &fp)
Definition: transactionalfilesystem.cpp:217
QStringList checkForModifications() const
Definition: transactionalfilesystem.cpp:258
virtual QByteArray read(const QString &path) const override
Definition: transactionalfilesystem.cpp:171
void save()
Definition: transactionalfilesystem.cpp:294
virtual QStringList getDirs(const QString &path="") const noexcept override
Definition: transactionalfilesystem.cpp:105
static std::shared_ptr< TransactionalFileSystem > openRW(const FilePath &filepath, RestoreCallback restoreCallback=&RestoreMode::no, QObject *parent=nullptr)
Definition: transactionalfilesystem.h:174
const FilePath & getPath() const noexcept
Definition: transactionalfilesystem.h:137
DirectoryLock mLock
Definition: transactionalfilesystem.h:193
virtual bool fileExists(const QString &path) const noexcept override
Definition: transactionalfilesystem.cpp:160
The RuntimeError class.
Definition: exceptions.h:219
QHash< QString, QByteArray > mModifiedFiles
Definition: transactionalfilesystem.h:197
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:191
static std::shared_ptr< TransactionalFileSystem > open(const FilePath &filepath, bool writable, RestoreCallback restoreCallback=&RestoreMode::no, QObject *parent=nullptr)
Definition: transactionalfilesystem.h:161
bool mRestoredFromAutosave
Definition: transactionalfilesystem.h:194
virtual void removeFile(const QString &path) override
Definition: transactionalfilesystem.cpp:191
QSet< QString > mRemovedFiles
Definition: transactionalfilesystem.h:198
QSet< QString > mRemovedDirs
Definition: transactionalfilesystem.h:199
Base class / interface for all file system implementations.
Definition: filesystem.h:43
bool isRestoredFromAutosave() const noexcept
Definition: transactionalfilesystem.h:139
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:351
static QString cleanPath(QString path) noexcept
Definition: transactionalfilesystem.cpp:339
static std::shared_ptr< TransactionalFileSystem > openRO(const FilePath &filepath, RestoreCallback restoreCallback=&RestoreMode::no, QObject *parent=nullptr)
Definition: transactionalfilesystem.h:168
bool mIsWritable
Definition: transactionalfilesystem.h:192
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:159
void autosave()
Definition: transactionalfilesystem.cpp:290
void saveDiff(const QString &type) const
Definition: transactionalfilesystem.cpp:406