File indexing completed on 2024-05-05 04:48:33
0001 /**************************************************************************************** 0002 * Copyright (c) 2013 Konrad Zemek <konrad.zemek@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #ifndef STATSYNCING_IMPORTER_SQL_CONNECTION_H 0018 #define STATSYNCING_IMPORTER_SQL_CONNECTION_H 0019 0020 #include <QObject> 0021 0022 #include "amarok_export.h" 0023 0024 #include <QList> 0025 #include <QMutex> 0026 #include <QPointer> 0027 #include <QSharedPointer> 0028 #include <QSqlDatabase> 0029 #include <QString> 0030 #include <QVariant> 0031 #include <QVariantList> 0032 #include <QVariantMap> 0033 0034 namespace StatSyncing 0035 { 0036 0037 /** 0038 * A helper class encapsulating communication with the database. It guarantees that 0039 * a connection is only used in thread that created it, as per 0040 * http://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module 0041 * This class is very basic, e.g. returns a whole query result as a list of lists, 0042 * so it may not be suitable for more advanced usage. 0043 */ 0044 class AMAROK_EXPORT ImporterSqlConnection : public QObject 0045 { 0046 Q_OBJECT 0047 0048 public: 0049 /** 0050 * Constructor. Creates a new external database connection characterized by parameters 0051 * given. See @see QSqlDatabase class for details. 0052 */ 0053 ImporterSqlConnection( const QString &driver, const QString &hostname, 0054 const quint16 port, const QString &dbName, const QString &user, 0055 const QString &password ); 0056 0057 /** 0058 * Constructor. Overload for creating a connection to SQLite database. 0059 */ 0060 explicit ImporterSqlConnection( const QString &dbPath ); 0061 0062 /** 0063 * Destructor. Removes connection created in the constructor. If a transaction was 0064 * in progress it is rolled back. 0065 */ 0066 ~ImporterSqlConnection() override; 0067 0068 /** 0069 * Executes a query given in QString @p query, first using QSqlQuery::bindValue 0070 * to bind parameters given in @p bindValues. If @p ok is not null the bool 0071 * it points at is set to true if the query was successful and false if error occurred. 0072 * Note that if no transaction is started, the connection is opened for the query and 0073 * then closed again. 0074 * @param query the query 0075 * @param bindValues the bind parameters 0076 * @param ok whether the query was successful 0077 * 0078 * @returns The result of the query. 0079 */ 0080 QList<QVariantList> query( const QString &query, 0081 const QVariantMap &bindValues = QVariantMap(), 0082 bool* const ok = nullptr ); 0083 0084 /** 0085 * Starts a transaction. Transaction is not started if the underlying driver has no 0086 * support for it. While transaction is started, the connection to the database 0087 * remains open and no other thread can use the ImporterSqlConnection object's api. 0088 */ 0089 void transaction(); 0090 0091 /** 0092 * Rolls the transaction back. Nothing happens if the transaction was not started. 0093 * This method must be used from the same thread that called @see transaction() . 0094 */ 0095 void rollback(); 0096 0097 /** 0098 * Commits the transaction. Nothing happens if the transaction was not started. 0099 * This method must be used from the same thread that called @see transaction() . 0100 */ 0101 void commit(); 0102 0103 protected: 0104 /** 0105 * Constructor. Use this overload if you don't want to create a new connection in 0106 * constructor of a derived class. 0107 */ 0108 ImporterSqlConnection(); 0109 0110 /** 0111 * Opens and returns current QSqlDatabase connection. Override this method if you need 0112 * to do something before the connection is used. This method should only be called 0113 * from object's main thread. 0114 */ 0115 virtual QSqlDatabase connection(); 0116 0117 /** 0118 * Returns true if transaction is in progress. This method should only be called 0119 * from object's main thread. 0120 */ 0121 bool isTransaction() const; 0122 0123 /** 0124 * Name of the current connection. 0125 */ 0126 const QString m_connectionName; 0127 0128 private: 0129 Q_DISABLE_COPY( ImporterSqlConnection ) 0130 0131 Qt::ConnectionType blockingConnectionType() const; 0132 0133 QMutex m_apiMutex; 0134 bool m_openTransaction; 0135 QList<QVariantList> m_result; 0136 0137 private Q_SLOTS: 0138 void slotQuery( const QString &query, const QVariantMap &bindValues, bool* const ok ); 0139 void slotTransaction(); 0140 void slotRollback(); 0141 void slotCommit(); 0142 }; 0143 0144 typedef QSharedPointer<ImporterSqlConnection> ImporterSqlConnectionPtr; 0145 0146 } // namespace StatSyncing 0147 0148 #endif // STATSYNCING_IMPORTER_SQL_CONNECTION_H