LibrePCB Developers Documentation
workspacelibrarydb.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_WORKSPACELIBRARYDB_H
21 #define LIBREPCB_CORE_WORKSPACELIBRARYDB_H
22 
23 /*******************************************************************************
24  * Includes
25  ******************************************************************************/
26 #include "../attribute/attribute.h"
27 #include "../attribute/attributetype.h"
28 #include "../fileio/filepath.h"
29 #include "../types/uuid.h"
30 #include "../types/version.h"
31 
32 #include <QtCore>
33 
34 /*******************************************************************************
35  * Namespace / Forward Declarations
36  ******************************************************************************/
37 class QSqlQuery;
38 
39 namespace librepcb {
40 
41 class Component;
42 class ComponentCategory;
43 class Device;
44 class Package;
45 class PackageCategory;
46 class SQLiteDatabase;
47 class Symbol;
48 class WorkspaceLibraryScanner;
49 
50 /*******************************************************************************
51  * Class WorkspaceLibraryDb
52  ******************************************************************************/
53 
57 class WorkspaceLibraryDb final : public QObject {
58  Q_OBJECT
59 
60 public:
61  struct Part {
62  QString mpn;
63  QString manufacturer;
65 
66  bool operator==(const Part& rhs) const noexcept {
67  return (mpn == rhs.mpn) && (manufacturer == rhs.manufacturer) &&
68  (attributes == rhs.attributes);
69  }
70  bool operator<(const Part& rhs) const noexcept {
71  if (mpn.isEmpty() != rhs.mpn.isEmpty()) {
72  return mpn.count() < rhs.mpn.count();
73  }
74  if (mpn != rhs.mpn) {
75  return mpn < rhs.mpn;
76  }
77  if (manufacturer != rhs.manufacturer) {
78  return manufacturer < rhs.manufacturer;
79  }
80  QCollator collator;
81  collator.setNumericMode(true);
82  collator.setCaseSensitivity(Qt::CaseInsensitive);
83  collator.setIgnorePunctuation(false);
84  for (int i = 0; i < std::max(attributes.count(), rhs.attributes.count());
85  ++i) {
86  auto a = attributes.value(i);
87  auto b = rhs.attributes.value(i);
88  if (a && (!b)) {
89  return false;
90  } else if ((!a) && b) {
91  return true;
92  } else if (a->getKey() != b->getKey()) {
93  return a->getKey() < b->getKey();
94  } else if (&a->getType() != &b->getType()) {
95  return a->getType().getName() < b->getType().getName();
96  } else if (a->getValueTr(true) != b->getValueTr(true)) {
97  return collator(a->getValueTr(true), b->getValueTr(true));
98  }
99  }
100  return false;
101  }
102  };
103 
104  // Constructors / Destructor
105  WorkspaceLibraryDb() = delete;
106  WorkspaceLibraryDb(const WorkspaceLibraryDb& other) = delete;
107 
116  explicit WorkspaceLibraryDb(const FilePath& librariesPath);
117  ~WorkspaceLibraryDb() noexcept;
118 
119  // Getters
120 
126  const FilePath& getFilePath() const noexcept { return mFilePath; }
127 
133  bool isScanInProgress() const noexcept {
134  return getScanProgressPercent() < 100;
135  }
136 
142  int getScanProgressPercent() const noexcept;
143 
155  template <typename ElementType>
156  QMultiMap<Version, FilePath> getAll(
157  const tl::optional<Uuid>& uuid = tl::nullopt,
158  const FilePath& lib = FilePath()) const {
159  return getAll(getTable<ElementType>(), uuid, lib);
160  }
161 
171  template <typename ElementType>
172  FilePath getLatest(const Uuid& uuid) const {
173  return getLatestVersionFilePath(getAll<ElementType>(uuid));
174  }
175 
185  template <typename ElementType>
186  QList<Uuid> find(const QString& keyword) const;
187 
197  QList<Uuid> findDevicesOfParts(const QString& keyword) const;
198 
209  QList<Part> findPartsOfDevice(const Uuid& device,
210  const QString& keyword) const;
211 
232  template <typename ElementType>
233  bool getTranslations(const FilePath& elemDir, const QStringList& localeOrder,
234  QString* name = nullptr, QString* description = nullptr,
235  QString* keywords = nullptr) const {
236  return getTranslations(getTable<ElementType>(), elemDir, localeOrder, name,
237  description, keywords);
238  }
239 
256  template <typename ElementType>
257  bool getMetadata(const FilePath elemDir, Uuid* uuid = nullptr,
258  Version* version = nullptr,
259  bool* deprecated = nullptr) const {
260  return getMetadata(getTable<ElementType>(), elemDir, uuid, version,
261  deprecated);
262  }
263 
277  bool getLibraryMetadata(const FilePath libDir, QPixmap* icon = nullptr,
278  QString* manufacturer = nullptr) const;
279 
292  template <typename ElementType>
293  bool getCategoryMetadata(const FilePath catDir,
294  tl::optional<Uuid>* parent = nullptr) const {
295  static_assert(std::is_same<ElementType, ComponentCategory>::value ||
296  std::is_same<ElementType, PackageCategory>::value,
297  "Unsupported ElementType");
298  return getCategoryMetadata(getTable<ElementType>(), catDir, parent);
299  }
300 
313  bool getDeviceMetadata(const FilePath& devDir, Uuid* cmpUuid = nullptr,
314  Uuid* pkgUuid = nullptr) const;
315 
329  template <typename ElementType>
330  QSet<Uuid> getChilds(const tl::optional<Uuid>& parent) const {
331  static_assert(std::is_same<ElementType, ComponentCategory>::value ||
332  std::is_same<ElementType, PackageCategory>::value,
333  "Unsupported ElementType");
334  return getChilds(getTable<ElementType>(), parent);
335  }
336 
354  template <typename ElementType>
355  QSet<Uuid> getByCategory(const tl::optional<Uuid>& category,
356  int limit = -1) const {
357  static_assert(std::is_same<ElementType, Symbol>::value ||
358  std::is_same<ElementType, Package>::value ||
359  std::is_same<ElementType, Component>::value ||
360  std::is_same<ElementType, Device>::value,
361  "Unsupported ElementType");
362  return getByCategory(getTable<ElementType>(),
363  getCategoryTable<ElementType>(), category, limit);
364  }
365 
373  QSet<Uuid> getComponentDevices(const Uuid& component) const;
374 
382  QList<Part> getDeviceParts(const Uuid& device) const;
383 
384  // General Methods
385 
389  void startLibraryRescan() noexcept;
390 
391  // Operator Overloadings
392  WorkspaceLibraryDb& operator=(const WorkspaceLibraryDb& rhs) = delete;
393 
394 signals:
395  void scanStarted();
396  void scanLibraryListUpdated(int libraryCount);
397  void scanProgressUpdate(int percent);
398  void scanSucceeded(int elementCount);
399  void scanFailed(QString errorMsg);
400  void scanFinished();
401 
402 private:
403  // Private Methods
404  QMultiMap<Version, FilePath> getAll(const QString& elementsTable,
405  const tl::optional<Uuid>& uuid,
406  const FilePath& lib) const;
408  const QMultiMap<Version, FilePath>& list) const noexcept;
409  QList<Uuid> find(const QString& elementsTable, const QString& keyword) const;
410  bool getTranslations(const QString& elementsTable, const FilePath& elemDir,
411  const QStringList& localeOrder, QString* name,
412  QString* description, QString* keywords) const;
413  bool getMetadata(const QString& elementsTable, const FilePath elemDir,
414  Uuid* uuid, Version* version, bool* deprecated) const;
415  bool getCategoryMetadata(const QString& categoriesTable,
416  const FilePath catDir,
417  tl::optional<Uuid>* parent) const;
418  AttributeList getPartAttributes(int partId) const;
419  QSet<Uuid> getChilds(const QString& categoriesTable,
420  const tl::optional<Uuid>& categoryUuid) const;
421  QSet<Uuid> getByCategory(const QString& elementsTable,
422  const QString& categoryTable,
423  const tl::optional<Uuid>& category, int limit) const;
424  static QSet<Uuid> getUuidSet(QSqlQuery& query);
425  int getDbVersion() const noexcept;
426  template <typename ElementType>
427  static QString getTable() noexcept;
428  template <typename ElementType>
429  static QString getCategoryTable() noexcept;
430 
431  // Attributes
434  QScopedPointer<SQLiteDatabase> mDb;
435  QScopedPointer<WorkspaceLibraryScanner> mLibraryScanner;
436 
437  // Constants
438  static const int sCurrentDbVersion = 5;
439 };
440 
441 /*******************************************************************************
442  * End of File
443  ******************************************************************************/
444 
445 } // namespace librepcb
446 
447 #endif
static QSet< Uuid > getUuidSet(QSqlQuery &query)
Definition: workspacelibrarydb.cpp:553
The Version class represents a version number in the format "1.42.7".
Definition: version.h:58
QSet< Uuid > getComponentDevices(const Uuid &component) const
Get all devices of a specific component.
Definition: workspacelibrarydb.cpp:250
QString manufacturer
Definition: workspacelibrarydb.h:63
static const int sCurrentDbVersion
Definition: workspacelibrarydb.h:438
std::shared_ptr< T > value(int index) noexcept
Definition: serializableobjectlist.h:254
void scanLibraryListUpdated(int libraryCount)
QList< Uuid > findDevicesOfParts(const QString &keyword) const
Find parts by keyword.
Definition: workspacelibrarydb.cpp:155
static QString getCategoryTable() noexcept
Definition: workspacelibrarydb.cpp:595
bool getLibraryMetadata(const FilePath libDir, QPixmap *icon=nullptr, QString *manufacturer=nullptr) const
Get additional metadata of a specific library.
Definition: workspacelibrarydb.cpp:199
Definition: occmodel.cpp:77
void scanFailed(QString errorMsg)
QList< Part > findPartsOfDevice(const Uuid &device, const QString &keyword) const
Find parts of device by keyword.
Definition: workspacelibrarydb.cpp:177
int count() const noexcept
Definition: serializableobjectlist.h:199
AttributeList getPartAttributes(int partId) const
Definition: workspacelibrarydb.cpp:468
int getDbVersion() const noexcept
Definition: workspacelibrarydb.cpp:561
const FilePath mFilePath
Path to the SQLite database file.
Definition: workspacelibrarydb.h:433
QSet< Uuid > getByCategory(const tl::optional< Uuid > &category, int limit=-1) const
Get elements of a specific category.
Definition: workspacelibrarydb.h:355
const FilePath & getFilePath() const noexcept
Get the file path of the SQLite database.
Definition: workspacelibrarydb.h:126
void scanSucceeded(int elementCount)
QMultiMap< Version, FilePath > getAll(const tl::optional< Uuid > &uuid=tl::nullopt, const FilePath &lib=FilePath()) const
Get elements, optionally matching some criteria.
Definition: workspacelibrarydb.h:156
bool isScanInProgress() const noexcept
Check if there is currently a library scan in progress.
Definition: workspacelibrarydb.h:133
QList< Part > getDeviceParts(const Uuid &device) const
Get all parts of a specific device.
Definition: workspacelibrarydb.cpp:261
QScopedPointer< WorkspaceLibraryScanner > mLibraryScanner
Definition: workspacelibrarydb.h:435
~WorkspaceLibraryDb() noexcept
Definition: workspacelibrarydb.cpp:104
QString mpn
Definition: workspacelibrarydb.h:62
static QString getTable() noexcept
Definition: workspacelibrarydb.cpp:581
bool getCategoryMetadata(const FilePath catDir, tl::optional< Uuid > *parent=nullptr) const
Get additional metadata of a specific category.
Definition: workspacelibrarydb.h:293
QScopedPointer< SQLiteDatabase > mDb
The SQLite database.
Definition: workspacelibrarydb.h:434
void scanProgressUpdate(int percent)
AttributeList attributes
Definition: workspacelibrarydb.h:64
This class represents absolute, well-formatted paths to files or directories.
Definition: filepath.h:129
Definition: workspacelibrarydb.h:61
const FilePath mLibrariesPath
Path to workspace libraries directory.
Definition: workspacelibrarydb.h:432
bool getMetadata(const FilePath elemDir, Uuid *uuid=nullptr, Version *version=nullptr, bool *deprecated=nullptr) const
Get metadata of a specific element.
Definition: workspacelibrarydb.h:257
QList< Uuid > find(const QString &keyword) const
Find elements by keyword.
Definition: workspacelibrarydb.cpp:116
bool operator<(const Part &rhs) const noexcept
Definition: workspacelibrarydb.h:70
int getScanProgressPercent() const noexcept
Get the current progress of the library rescan.
Definition: workspacelibrarydb.cpp:111
bool operator==(const Part &rhs) const noexcept
Definition: workspacelibrarydb.h:66
The Uuid class is a replacement for QUuid to get UUID strings without {} braces.
Definition: uuid.h:58
bool getDeviceMetadata(const FilePath &devDir, Uuid *cmpUuid=nullptr, Uuid *pkgUuid=nullptr) const
Get additional metadata of a specific device.
Definition: workspacelibrarydb.cpp:223
FilePath getLatest(const Uuid &uuid) const
Get an element of a specific UUID and the highest version.
Definition: workspacelibrarydb.h:172
bool getTranslations(const FilePath &elemDir, const QStringList &localeOrder, QString *name=nullptr, QString *description=nullptr, QString *keywords=nullptr) const
Get translations of a specific element.
Definition: workspacelibrarydb.h:233
FilePath getLatestVersionFilePath(const QMultiMap< Version, FilePath > &list) const noexcept
Definition: workspacelibrarydb.cpp:341
WorkspaceLibraryDb & operator=(const WorkspaceLibraryDb &rhs)=delete
void startLibraryRescan() noexcept
Rescan the whole library directory and update the SQLite database.
Definition: workspacelibrarydb.cpp:284
The WorkspaceLibraryDb class.
Definition: workspacelibrarydb.h:57
QSet< Uuid > getChilds(const tl::optional< Uuid > &parent) const
Get children categories of a specific category.
Definition: workspacelibrarydb.h:330