/************************************************************************** ** ** 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(); T *first(); int count(); QList toList(int count = -1); template QList select(const FieldPhrase f); QVariant max(FieldPhrase &f); QVariant min(FieldPhrase &f); QVariant average(FieldPhrase &f); Query *join(const QString &tableName); Query *setWhere(WherePhrase where); Query *join(Table *c){ join(c->metaObject()->className()); return this; } // Query *setWhere(const QString &where); Query *orderBy(QString fieldName, QString type); Query *orderBy(WherePhrase phrase); int update(WherePhrase phrase); int remove(); }; 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().modelByClass(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)); QString sql = d->database->sqlGenertor()->selectCommand( SqlGeneratorBase::SelectAll, "", d->wheres, d->orderPhrases, d->tableName, d->joinClassName); QSqlQuery q = d->database->exec(sql); // QString pk = TableModel::findByName(d->tableName)->primaryKey(); QString pk = d->database->model().model(d->tableName)->primaryKey(); QVariant lastPkValue = QVariant(); int childTypeId = 0; T *lastRow = 0; TableSetBase *childTableSet; //FIXME: getting table error // QStringList masterFields = TableModel::findByName(d->tableName)->fieldsNames(); QStringList masterFields = d->database->model().model(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().model(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; QString sql = d->database->sqlGenertor()->selectCommand( SqlGeneratorBase::SignleField, f.data()->text, d->wheres, d->orderPhrases, d->tableName, d->joinClassName); QSqlQuery q = d->database->exec(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(*)"; QSqlQuery q = d->database->exec(d->database->sqlGenertor()->selectCommand("COUNT(*)", d->wheres, d->orders, d->tableName, d->joinClassName)); if(q.next()) return q.value(0).toInt(); return 0; } template Q_OUTOFLINE_TEMPLATE QVariant Query::max(FieldPhrase &f){ Q_D(Query); QSqlQuery q = d->database->exec(d->database->sqlGenertor()->selectCommand("MAX(" + f.data()->text + ")", d->wheres, d->orders, d->tableName, d->joinClassName)); if(q.next()) return q.value(0).toInt(); return 0; } template Q_OUTOFLINE_TEMPLATE QVariant Query::min(FieldPhrase &f){ Q_D(Query); QSqlQuery q = d->database->exec(d->database->sqlGenertor()->selectCommand("MIN(" + f.data()->text + ")", d->wheres, d->orders, d->tableName, d->joinClassName)); if(q.next()) return q.value(0).toInt(); return 0; } template Q_OUTOFLINE_TEMPLATE QVariant Query::average(FieldPhrase &f) { Q_D(Query); QSqlQuery q = d->database->exec(d->database->sqlGenertor()->selectCommand("AVG(" + f.data()->text + ")", d->wheres, d->orders, d->tableName, d->joinClassName)); 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->orders.insert(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); QString sql = d->database->sqlGenertor()->updateCommand( phrase, d->wheres, d->tableName); QSqlQuery q = d->database->exec(sql); if (m_autoDelete) deleteLater(); return q.numRowsAffected(); } template Q_OUTOFLINE_TEMPLATE int Query::remove() { Q_D(Query); QString sql = d->database->sqlGenertor()->deleteCommand( d->wheres, d->tableName); QSqlQuery q = d->database->exec(sql); return q.numRowsAffected(); } NUT_END_NAMESPACE #endif // QUERY_H