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  return find(getTable<ElementType>(), keyword);
188  }
189 
199  QList<Uuid> findDevicesOfParts(const QString& keyword) const;
200 
211  QList<Part> findPartsOfDevice(const Uuid& device,
212  const QString& keyword) const;
213 
234  template <typename ElementType>
235  bool getTranslations(const FilePath& elemDir, const QStringList& localeOrder,
236  QString* name = nullptr, QString* description = nullptr,
237  QString* keywords = nullptr) const {
238  return getTranslations(getTable<ElementType>(), elemDir, localeOrder, name,
239  description, keywords);
240  }
241 
258  template <typename ElementType>
259  bool getMetadata(const FilePath elemDir, Uuid* uuid = nullptr,
260  Version* version = nullptr,
261  bool* deprecated = nullptr) const {
262  return getMetadata(getTable<ElementType>(), elemDir, uuid, version,
263  deprecated);
264  }
265 
279  bool getLibraryMetadata(const FilePath libDir, QPixmap* icon = nullptr,
280  QString* manufacturer = nullptr) const;
281 
294  template <typename ElementType>
295  bool getCategoryMetadata(const FilePath catDir,
296  tl::optional<Uuid>* parent = nullptr) const {
297  static_assert(std::is_same<ElementType, ComponentCategory>::value ||
298  std::is_same<ElementType, PackageCategory>::value,
299  "Unsupported ElementType");
300  return getCategoryMetadata(getTable<ElementType>(), catDir, parent);
301  }
302 
315  bool getDeviceMetadata(const FilePath& devDir, Uuid* cmpUuid = nullptr,
316  Uuid* pkgUuid = nullptr) const;
317 
331  template <typename ElementType>
332  QSet<Uuid> getChilds(const tl::optional<Uuid>& parent) const {
333  static_assert(std::is_same<ElementType, ComponentCategory>::value ||
334  std::is_same<ElementType, PackageCategory>::value,
335  "Unsupported ElementType");
336  return getChilds(getTable<ElementType>(), parent);
337  }
338 
356  template <typename ElementType>
357  QSet<Uuid> getByCategory(const tl::optional<Uuid>& category,
358  int limit = -1) const {
359  static_assert(std::is_same<ElementType, Symbol>::value ||
360  std::is_same<ElementType, Package>::value ||
361  std::is_same<ElementType, Component>::value ||
362  std::is_same<ElementType, Device>::value,
363  "Unsupported ElementType");
364  return getByCategory(getTable<ElementType>(),
365  getCategoryTable<ElementType>(), category, limit);
366  }
367 
375  QSet<Uuid> getComponentDevices(const Uuid& component) const;
376 
384  QList<Part> getDeviceParts(const Uuid& device) const;
385 
386  // General Methods
387 
391  void startLibraryRescan() noexcept;
392 
393  // Operator Overloadings
394  WorkspaceLibraryDb& operator=(const WorkspaceLibraryDb& rhs) = delete;
395 
396 signals:
397  void scanStarted();
398  void scanLibraryListUpdated(int libraryCount);
399  void scanProgressUpdate(int percent);
400  void scanSucceeded(int elementCount);
401  void scanFailed(QString errorMsg);
402  void scanFinished();
403 
404 private:
405  // Private Methods
406  QMultiMap<Version, FilePath> getAll(const QString& elementsTable,
407  const tl::optional<Uuid>& uuid,
408  const FilePath& lib) const;
410  const QMultiMap<Version, FilePath>& list) const noexcept;
411  QList<Uuid> find(const QString& elementsTable, const QString& keyword) const;
412  bool getTranslations(const QString& elementsTable, const FilePath& elemDir,
413  const QStringList& localeOrder, QString* name,
414  QString* description, QString* keywords) const;
415  bool getMetadata(const QString& elementsTable, const FilePath elemDir,
416  Uuid* uuid, Version* version, bool* deprecated) const;
417  bool getCategoryMetadata(const QString& categoriesTable,
418  const FilePath catDir,
419  tl::optional<Uuid>* parent) const;
420  AttributeList getPartAttributes(int partId) const;
421  QSet<Uuid> getChilds(const QString& categoriesTable,
422  const tl::optional<Uuid>& categoryUuid) const;
423  QSet<Uuid> getByCategory(const QString& elementsTable,
424  const QString& categoryTable,
425  const tl::optional<Uuid>& category, int limit) const;
426  static QSet<Uuid> getUuidSet(QSqlQuery& query);
427  int getDbVersion() const noexcept;
428  template <typename ElementType>
429  static QString getTable() noexcept;
430  template <typename ElementType>
431  static QString getCategoryTable() noexcept;
432 
433  // Attributes
436  QScopedPointer<SQLiteDatabase> mDb;
437  QScopedPointer<WorkspaceLibraryScanner> mLibraryScanner;
438 
439  // Constants
440  static const int sCurrentDbVersion = 5;
441 };
442 
443 /*******************************************************************************
444  * End of File
445  ******************************************************************************/
446 
447 } // namespace librepcb
448 
449 #endif
static QSet< Uuid > getUuidSet(QSqlQuery &query)
Definition: workspacelibrarydb.cpp:538
The Version class represents a version number in the format "1.42.7".
Definition: version.h:58
QList< Uuid > find(const QString &keyword) const
Find elements by keyword.
Definition: workspacelibrarydb.h:186
QSet< Uuid > getComponentDevices(const Uuid &component) const
Get all devices of a specific component.
Definition: workspacelibrarydb.cpp:235
QString manufacturer
Definition: workspacelibrarydb.h:63
static const int sCurrentDbVersion
Definition: workspacelibrarydb.h:440
std::shared_ptr< T > value(int index) noexcept
Definition: serializableobjectlist.h:251
void scanLibraryListUpdated(int libraryCount)
QList< Uuid > findDevicesOfParts(const QString &keyword) const
Find parts by keyword.
Definition: workspacelibrarydb.cpp:140
static QString getCategoryTable() noexcept
Definition: workspacelibrarydb.cpp:580
bool getLibraryMetadata(const FilePath libDir, QPixmap *icon=nullptr, QString *manufacturer=nullptr) const
Get additional metadata of a specific library.
Definition: workspacelibrarydb.cpp:184
Definition: occmodel.cpp:76
void scanFailed(QString errorMsg)
QList< Part > findPartsOfDevice(const Uuid &device, const QString &keyword) const
Find parts of device by keyword.
Definition: workspacelibrarydb.cpp:162
int count() const noexcept
Definition: serializableobjectlist.h:197
AttributeList getPartAttributes(int partId) const
Definition: workspacelibrarydb.cpp:453
int getDbVersion() const noexcept
Definition: workspacelibrarydb.cpp:546
const FilePath mFilePath
Path to the SQLite database file.
Definition: workspacelibrarydb.h:435
QSet< Uuid > getByCategory(const tl::optional< Uuid > &category, int limit=-1) const
Get elements of a specific category.
Definition: workspacelibrarydb.h:357
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:246
QScopedPointer< WorkspaceLibraryScanner > mLibraryScanner
Definition: workspacelibrarydb.h:437
~WorkspaceLibraryDb() noexcept
Definition: workspacelibrarydb.cpp:103
QString mpn
Definition: workspacelibrarydb.h:62
static QString getTable() noexcept
Definition: workspacelibrarydb.cpp:566
bool getCategoryMetadata(const FilePath catDir, tl::optional< Uuid > *parent=nullptr) const
Get additional metadata of a specific category.
Definition: workspacelibrarydb.h:295
QScopedPointer< SQLiteDatabase > mDb
The SQLite database.
Definition: workspacelibrarydb.h:436
void scanProgressUpdate(int percent)
AttributeList attributes
Definition: workspacelibrarydb.h:64
This class represents absolute, well-formatted paths to files or directories.
Definition: filepath.h:127
Definition: workspacelibrarydb.h:61
const FilePath mLibrariesPath
Path to workspace libraries directory.
Definition: workspacelibrarydb.h:434
bool getMetadata(const FilePath elemDir, Uuid *uuid=nullptr, Version *version=nullptr, bool *deprecated=nullptr) const
Get metadata of a specific element.
Definition: workspacelibrarydb.h:259
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:110
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:56
bool getDeviceMetadata(const FilePath &devDir, Uuid *cmpUuid=nullptr, Uuid *pkgUuid=nullptr) const
Get additional metadata of a specific device.
Definition: workspacelibrarydb.cpp:208
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:235
FilePath getLatestVersionFilePath(const QMultiMap< Version, FilePath > &list) const noexcept
Definition: workspacelibrarydb.cpp:326
WorkspaceLibraryDb & operator=(const WorkspaceLibraryDb &rhs)=delete
void startLibraryRescan() noexcept
Rescan the whole library directory and update the SQLite database.
Definition: workspacelibrarydb.cpp:269
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:332