/src/libtomahawk/database/Database.h

http://github.com/tomahawk-player/tomahawk · C Header · 149 lines · 86 code · 34 blank · 29 comment · 0 complexity · b55c20e8e6570edf3975d3530338559f MD5 · raw file

  1. /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2. *
  3. * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4. * Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
  5. *
  6. * Tomahawk 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. * Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #pragma once
  20. #ifndef DATABASE_H
  21. #define DATABASE_H
  22. #include "DllMacro.h"
  23. #include "Typedefs.h"
  24. #include <QMutex>
  25. #include <QVariant>
  26. namespace Tomahawk
  27. {
  28. class DatabaseImpl;
  29. class DatabaseCommand;
  30. class DatabaseWorkerThread;
  31. class DatabaseWorker;
  32. class IdThreadWorker;
  33. class DLLEXPORT DatabaseCommandFactory : public QObject
  34. {
  35. Q_OBJECT
  36. friend class Database;
  37. public:
  38. virtual ~DatabaseCommandFactory() {}
  39. dbcmd_ptr newInstance();
  40. signals:
  41. void created( const Tomahawk::dbcmd_ptr& command );
  42. protected:
  43. void notifyCreated( const Tomahawk::dbcmd_ptr& command );
  44. virtual DatabaseCommand* create() const = 0;
  45. };
  46. template <class COMMAND>
  47. class DatabaseCommandFactoryImplementation : public DatabaseCommandFactory
  48. {
  49. protected:
  50. virtual COMMAND* create() const { return new COMMAND(); }
  51. };
  52. /*
  53. This class is really a firewall/pimpl - the public functions of LibraryImpl
  54. are the ones that operate on the database, without any locks.
  55. HOWEVER, we're using the command pattern to serialize access to the database
  56. and provide an async api. You create a DatabaseCommand object, and add it to
  57. the queue of work. There is a threadpool responsible for exec'ing all
  58. the non-mutating (readonly) commands and one separate thread for mutating ones,
  59. so sqlite doesn't write to the Database from multiple threads.
  60. */
  61. class DLLEXPORT Database : public QObject
  62. {
  63. Q_OBJECT
  64. public:
  65. static Database* instance();
  66. explicit Database( const QString& dbname, QObject* parent = 0 );
  67. ~Database();
  68. void loadIndex();
  69. bool isReady() const { return m_ready; }
  70. DatabaseImpl* impl();
  71. dbcmd_ptr createCommandInstance( const QVariant& op, const Tomahawk::source_ptr& source );
  72. // Template implementations need to stay in header!
  73. template<typename T> void registerCommand()
  74. {
  75. registerCommand( new DatabaseCommandFactoryImplementation<T>() );
  76. }
  77. template<typename T> DatabaseCommandFactory* commandFactory()
  78. {
  79. return commandFactoryByClassName( T::staticMetaObject.className() );
  80. }
  81. signals:
  82. void indexStarted();
  83. void indexReady();
  84. void ready();
  85. void newJobRO( Tomahawk::dbcmd_ptr );
  86. void newJobRW( Tomahawk::dbcmd_ptr );
  87. void waitingForWorkers();
  88. void workersFinished();
  89. public slots:
  90. void enqueue( const Tomahawk::dbcmd_ptr& lc );
  91. void enqueue( const QList< Tomahawk::dbcmd_ptr >& lc );
  92. private slots:
  93. void markAsReady();
  94. private:
  95. void registerCommand( DatabaseCommandFactory* commandFactory );
  96. DatabaseCommandFactory* commandFactoryByClassName( const QString& className );
  97. DatabaseCommandFactory* commandFactoryByCommandName( const QString& commandName );
  98. dbcmd_ptr createCommandInstance( const QString& commandName );
  99. bool m_ready;
  100. DatabaseImpl* m_impl;
  101. QPointer< DatabaseWorkerThread > m_workerRW;
  102. QList< QPointer< DatabaseWorkerThread > > m_workerThreads;
  103. IdThreadWorker* m_idWorker;
  104. int m_maxConcurrentThreads;
  105. QHash< QString, DatabaseCommandFactory* > m_commandFactories;
  106. QHash< QString, QString> m_commandNameClassNameMapping;
  107. QHash< QThread*, DatabaseImpl* > m_implHash;
  108. QMutex m_mutex;
  109. static Database* s_instance;
  110. friend class Tomahawk::Artist;
  111. friend class Tomahawk::Album;
  112. };
  113. }
  114. #endif // DATABASE_H