/**************************************************************************
**
** 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