File indexing completed on 2024-04-28 04:50:50

0001 /*
0002  * sqlinterface.h
0003  *
0004  * Copyright (C) 2009-2011 Christoph Pfister <christophpfister@gmail.com>
0005  *
0006  * This program is free software; you can redistribute it and/or modify
0007  * it under the terms of the GNU General Public License as published by
0008  * the Free Software Foundation; either version 2 of the License, or
0009  * (at your option) any later version.
0010  *
0011  * This program is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  * GNU General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU General Public License along
0017  * with this program; if not, write to the Free Software Foundation, Inc.,
0018  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0019  */
0020 
0021 #ifndef SQLINTERFACE_H
0022 #define SQLINTERFACE_H
0023 
0024 #include <QExplicitlySharedDataPointer>
0025 #include <QMap>
0026 #include <QSqlQuery>
0027 
0028 #if QT_VERSION >= 0x050a00
0029 #  include <QRandomGenerator>
0030 #endif
0031 
0032 class SqlHelper;
0033 
0034 class SqlKey
0035 {
0036 public:
0037     explicit SqlKey(quint32 key = 0) : sqlKey(key) { }
0038     ~SqlKey() { }
0039 
0040     bool isSqlKeyValid() const
0041     {
0042         return (sqlKey != 0);
0043     }
0044 
0045     void setSqlKey(const SqlKey &other)
0046     {
0047         sqlKey = other.sqlKey;
0048     }
0049 
0050     bool operator==(const SqlKey &other) const
0051     {
0052         return (sqlKey == other.sqlKey);
0053     }
0054 
0055     bool operator!=(const SqlKey &other) const
0056     {
0057         return (sqlKey != other.sqlKey);
0058     }
0059 
0060     bool operator<(const SqlKey &other) const
0061     {
0062         return (sqlKey < other.sqlKey);
0063     }
0064 
0065     quint32 sqlKey;
0066 };
0067 
0068 Q_DECLARE_TYPEINFO(SqlKey, Q_MOVABLE_TYPE);
0069 
0070 class SqlInterface
0071 {
0072 public:
0073     SqlInterface();
0074     virtual ~SqlInterface();
0075 
0076     void sqlInit(const QString &tableName, const QStringList &columnNames);
0077     void sqlInsert(SqlKey key);
0078     void sqlUpdate(SqlKey key);
0079     void sqlRemove(SqlKey key);
0080     void sqlFlush();
0081 
0082     /* for SqlHelper */
0083     void sqlSubmit();
0084 
0085     template<class Container> SqlKey sqlFindFreeKey(const Container &container) const
0086     {
0087         SqlKey sqlKey(1);
0088 
0089         if (!container.isEmpty()) {
0090             sqlKey = SqlKey((container.constEnd() - 1).key().sqlKey + 1);
0091 
0092             while (container.contains(sqlKey) || !sqlKey.isSqlKeyValid()) {
0093 #if QT_VERSION >= 0x050a00
0094                 quint32 rand = QRandomGenerator::global()->generate();
0095 #else
0096                 quint32 rand = qrand();
0097 #endif
0098                 sqlKey = SqlKey(rand);
0099             }
0100         }
0101 
0102         return sqlKey;
0103     }
0104 
0105 protected:
0106     virtual void bindToSqlQuery(SqlKey sqlKey, QSqlQuery &query, int index) const = 0;
0107     virtual bool insertFromSqlQuery(SqlKey sqlKey, const QSqlQuery &query, int index) = 0;
0108 
0109 private:
0110     enum PendingStatement {
0111         Nothing,
0112         RemoveAndInsert,
0113         Insert,
0114         Update,
0115         Remove
0116     };
0117 
0118     void requestSubmission();
0119 
0120     QExplicitlySharedDataPointer<SqlHelper> sqlHelper;
0121     QMap<SqlKey, PendingStatement> pendingStatements;
0122     bool createTable;
0123     bool hasPendingStatements;
0124 
0125     int sqlColumnCount;
0126     QString createStatement;
0127     QString insertStatement;
0128     QString updateStatement;
0129     QString deleteStatement;
0130     QSqlQuery insertQuery;
0131     QSqlQuery updateQuery;
0132     QSqlQuery deleteQuery;
0133 };
0134 
0135 #endif /* SQLINTERFACE_H */