PageRenderTime 219ms CodeModel.GetById 60ms app.highlight 76ms RepoModel.GetById 76ms app.codeStats 0ms

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