/************************************************************************** ** ** This file is part of Nut project. ** https://github.com/HamedMasafi/Nut ** ** Nut is free software: you can redistribute it and/or modify ** it under the terms of the GNU Lesser General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** Nut is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU Lesser General Public License for more details. ** ** You should have received a copy of the GNU Lesser General Public License ** along with Nut. If not, see . ** **************************************************************************/ #ifndef QUERY_H #define QUERY_H #include #include #include #include #include #include "query_p.h" #include "database.h" #include "databasemodel.h" #include "tablesetbase_p.h" #include "sqlgeneratorbase_p.h" #include "querybase_p.h" #include "wherephrase.h" #include "tablemodel.h" NUT_BEGIN_NAMESPACE template class NUT_EXPORT Query : public QueryBase { QueryPrivate *d_ptr; Q_DECLARE_PRIVATE(Query) bool m_autoDelete; public: Query(Database *database, TableSetBase *tableSet, bool autoDelete); ~Query(); Query *join(const QString &tableName); Query *setWhere(WherePhrase where); Query *join(Table *c) { join(c->metaObject()->className()); return this; } // Query *orderBy(QString fieldName, QString type); Query *orderBy(WherePhrase phrase); int count(); QVariant max(FieldPhrase &f); QVariant min(FieldPhrase &f); QVariant average(FieldPhrase &f); T *first(); QList toList(int count = -1); template QList select(const FieldPhrase f); int update(WherePhrase phrase); int remove(); QString sqlCommand() const; }; template inline Query *createQuery(TableSet *tableSet) { } template Q_OUTOFLINE_TEMPLATE Query::Query(Database *database, TableSetBase *tableSet, bool autoDelete) : QueryBase(database), d_ptr(new QueryPrivate(this)), m_autoDelete(autoDelete) { Q_D(Query); d->database = database; d->tableSet = tableSet; d->tableName = // TableModel::findByClassName(T::staticMetaObject.className())->name(); d->database->model() .tableByClassName(T::staticMetaObject.className()) ->name(); } template Q_OUTOFLINE_TEMPLATE Query::~Query() { Q_D(Query); delete d; } template Q_OUTOFLINE_TEMPLATE QList Query::toList(int count) { Q_D(Query); QList result; d->select = "*"; // QSqlQuery q = // d->database->exec(d->database->sqlGenertor()->selectCommand(d->wheres, // d->orders, d->tableName, d->joinClassName)); d->sql = d->database->sqlGenertor()->selectCommand( SqlGeneratorBase::SelectAll, "", d->wheres, d->orderPhrases, d->tableName, d->joinClassName); QSqlQuery q = d->database->exec(d->sql); // QString pk = TableModel::findByName(d->tableName)->primaryKey(); QString pk = d->database->model().tableByName(d->tableName)->primaryKey(); QVariant lastPkValue = QVariant(); int childTypeId = 0; T *lastRow = 0; TableSetBase *childTableSet = Q_NULLPTR; // FIXME: getting table error // QStringList masterFields = // TableModel::findByName(d->tableName)->fieldsNames(); QStringList masterFields = d->database->model().tableByName(d->tableName)->fieldsNames(); QStringList childFields; if (!d->joinClassName.isNull()) { TableModel *joinTableModel = TableModel::findByClassName(d->joinClassName); if (joinTableModel) { // childFields = // d->database->model().modelByClass(d->joinClassName)->fieldsNames(); childFields = TableModel::findByClassName(d->joinClassName)->fieldsNames(); QString joinTableName = d->database->tableName(d->joinClassName); childTypeId = d->database->model().tableByName(joinTableName)->typeId(); // childTypeId = // TableModel::findByName(joinTableName)->typeId(); } } while (q.next()) { if (lastPkValue != q.value(pk)) { T *t = new T(); foreach (QString field, masterFields) t->setProperty(field.toLatin1().data(), q.value(field)); // for (int i = 0; i < t->metaObject()->propertyCount(); // i++) { // const QMetaProperty p = // t->metaObject()->property(i); // p.write(t, // d->database->sqlGenertor()->readValue(p.type(), // q.value(p.name()))); // } t->setTableSet(d->tableSet); t->setStatus(Table::FeatchedFromDB); t->setParent(this); t->clear(); result.append(t); lastRow = t; if (childTypeId) { QSet tableSets = t->tableSets; foreach (TableSetBase *ts, tableSets) if (ts->childClassName() == d->joinClassName) childTableSet = ts; } } if (childTypeId) { const QMetaObject *childMetaObject = QMetaType::metaObjectForType(childTypeId); Table *childTable = qobject_cast(childMetaObject->newInstance()); foreach (QString field, childFields) childTable->setProperty(field.toLatin1().data(), q.value(field)); // TODO: set database for table childTable->setParent(this); childTable->setParentTable(lastRow); childTable->setStatus(Table::FeatchedFromDB); childTable->setTableSet(childTableSet); childTable->clear(); childTableSet->add(childTable); } lastPkValue = q.value(pk); if (!--count) break; } if (m_autoDelete) deleteLater(); return result; } template template Q_OUTOFLINE_TEMPLATE QList Query::select(const FieldPhrase f) { Q_D(Query); QList ret; d->sql = d->database->sqlGenertor()->selectCommand( SqlGeneratorBase::SignleField, f.data()->text, d->wheres, d->orderPhrases, d->tableName, d->joinClassName); QSqlQuery q = d->database->exec(d->sql); while (q.next()) { QVariant v = q.value(f.data()->text); ret.append(v.value()); } if (m_autoDelete) deleteLater(); return ret; } template Q_OUTOFLINE_TEMPLATE T *Query::first() { QList list = toList(1); if (list.count()) return list.first(); else return 0; } template Q_OUTOFLINE_TEMPLATE int Query::count() { Q_D(Query); d->select = "COUNT(*)"; d->sql = d->database->sqlGenertor()->selectCommand(SqlGeneratorBase::Count, QStringLiteral("*"), d->wheres, d->orderPhrases, d->tableName, d->joinClassName); QSqlQuery q = d->database->exec(d->sql); if (q.next()) return q.value(0).toInt(); return 0; } template Q_OUTOFLINE_TEMPLATE QVariant Query::max(FieldPhrase &f) { Q_D(Query); d->sql = d->database->sqlGenertor()->selectCommand( SqlGeneratorBase::Max, f.data()->text, d->wheres, d->orderPhrases, d->tableName, d->joinClassName); QSqlQuery q = d->database->exec(d->sql); if (q.next()) return q.value(0).toInt(); return 0; } template Q_OUTOFLINE_TEMPLATE QVariant Query::min(FieldPhrase &f) { Q_D(Query); d->sql = d->database->sqlGenertor()->selectCommand( SqlGeneratorBase::Min, f.data()->text, d->wheres, d->orderPhrases, d->tableName, d->joinClassName); QSqlQuery q = d->database->exec(d->sql); if (q.next()) return q.value(0).toInt(); return 0; } template Q_OUTOFLINE_TEMPLATE QVariant Query::average(FieldPhrase &f) { Q_D(Query); d->sql = d->database->sqlGenertor()->selectCommand( SqlGeneratorBase::Average, f.data()->text, d->wheres, d->orderPhrases, d->tableName, d->joinClassName); QSqlQuery q = d->database->exec(d->sql); if (q.next()) return q.value(0).toInt(); return 0; } template Q_OUTOFLINE_TEMPLATE Query *Query::join(const QString &tableName) { Q_D(Query); d->joinClassName = tableName; return this; } template Q_OUTOFLINE_TEMPLATE Query *Query::setWhere(WherePhrase where) { Q_D(Query); d->wheres.append(where); return this; } //template //Q_OUTOFLINE_TEMPLATE Query *Query::orderBy(QString fieldName, // QString type) //{ // Q_D(Query); // d->orderPhrases.append(fieldName, type); // return this; //} template Q_OUTOFLINE_TEMPLATE Query *Query::orderBy(WherePhrase phrase) { Q_D(Query); d->orderPhrases.append(phrase); return this; } template Q_OUTOFLINE_TEMPLATE int Query::update(WherePhrase phrase) { Q_D(Query); d->sql = d->database->sqlGenertor()->updateCommand(phrase, d->wheres, d->tableName); QSqlQuery q = d->database->exec(d->sql); if (m_autoDelete) deleteLater(); return q.numRowsAffected(); } template Q_OUTOFLINE_TEMPLATE int Query::remove() { Q_D(Query); d->sql = d->database->sqlGenertor()->deleteCommand(d->wheres, d->tableName); QSqlQuery q = d->database->exec(d->sql); if (m_autoDelete) deleteLater(); return q.numRowsAffected(); } template Q_OUTOFLINE_TEMPLATE QString Query::sqlCommand() const { Q_D(const Query); return d->sql; } NUT_END_NAMESPACE #endif // QUERY_H