movable query

This commit is contained in:
Hamed Masafi 2020-08-10 11:12:06 +04:30
parent bc88cd246c
commit d39c6aee37
1 changed files with 104 additions and 56 deletions

View File

@ -48,34 +48,59 @@
NUT_BEGIN_NAMESPACE NUT_BEGIN_NAMESPACE
struct NUT_EXPORT QueryData {
QString sql;
QString className;
QString tableName;
QString select;
Database *database;
AbstractTableSet *tableSet;
QStringList joins;
QList<RelationModel*> relations;
int skip;
int take;
PhraseList orderPhrase, fieldPhrase;
ConditionalPhrase wherePhrase;
QueryData *clone() {
return new QueryData;
}
};
template <class T> template <class T>
class Query : public AbstractQuery class Query : public AbstractQuery
{ {
QueryData *d;
bool m_autoDelete; bool m_autoDelete;
public: public:
explicit Query(Database *database, AbstractTableSet *tableSet, bool autoDelete); explicit Query(Database *database, AbstractTableSet *tableSet, bool autoDelete);
Query (const Query<T> &other);
Query (Query<T> &&other);
~Query(); ~Query();
Query<T>& operator=(const Query<T> &q);
//ddl //ddl
Query<T> *join(const QString &className); Query<T> &join(const QString &className);
Query<T> *join(Table *c); Query<T> &join(Table *c);
template<class TABLE> template<class TABLE>
Query<T> *join() Query<T> &join()
{ {
join(TABLE::staticMetaObject.className()); join(TABLE::staticMetaObject.className());
return this; return *this;
} }
// Query<T> *orderBy(QString fieldName, QString type); // Query<T> &orderBy(QString fieldName, QString type);
Query<T> *skip(int n); Query<T> &skip(int n);
Query<T> *take(int n); Query<T> &take(int n);
Query<T> *fields(const PhraseList &ph); Query<T> &fields(const PhraseList &ph);
Query<T> *orderBy(const PhraseList &ph); Query<T> &orderBy(const PhraseList &ph);
Query<T> *where(const ConditionalPhrase &ph); Query<T> &where(const ConditionalPhrase &ph);
Query<T> *setWhere(const ConditionalPhrase &ph); Query<T> &setWhere(const ConditionalPhrase &ph);
//data selecting //data selecting
Row<T> first(); Row<T> first();
@ -110,7 +135,7 @@ template<typename T>
template<typename O> template<typename O>
Q_OUTOFLINE_TEMPLATE QList<O> Query<T>::select(const std::function<O (const QSqlQuery &)> allocator) Q_OUTOFLINE_TEMPLATE QList<O> Query<T>::select(const std::function<O (const QSqlQuery &)> allocator)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
QList<O> ret; QList<O> ret;
d->joins.prepend(d->tableName); d->joins.prepend(d->tableName);
@ -135,7 +160,7 @@ Q_OUTOFLINE_TEMPLATE QList<O> Query<T>::select(const std::function<O (const QSql
} }
//template <typename T> //template <typename T>
//inline Query<T> *createQuery(TableSet<T> *tableSet) //inline Query<T> &createQuery(TableSet<T> *tableSet)
//{ //{
// return tableSet->query(); // return tableSet->query();
//} //}
@ -143,9 +168,9 @@ Q_OUTOFLINE_TEMPLATE QList<O> Query<T>::select(const std::function<O (const QSql
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE Query<T>::Query(Database *database, AbstractTableSet *tableSet, Q_OUTOFLINE_TEMPLATE Query<T>::Query(Database *database, AbstractTableSet *tableSet,
bool autoDelete) bool autoDelete)
: AbstractQuery(database), m_autoDelete(autoDelete) : AbstractQuery(database), d(new QueryData), m_autoDelete(autoDelete)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->database = database; d->database = database;
d->tableSet = tableSet; d->tableSet = tableSet;
@ -156,17 +181,40 @@ Q_OUTOFLINE_TEMPLATE Query<T>::Query(Database *database, AbstractTableSet *table
->name(); ->name();
} }
template<class T>
Q_OUTOFLINE_TEMPLATE Query<T>::Query(const Query<T> &other) {
d = other.d->clone();
}
template<class T>
Q_OUTOFLINE_TEMPLATE Query<T>::Query(Query<T> &&other) {
d = std::move(other.d);
other._data = nullptr;
}
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE Query<T>::~Query() Q_OUTOFLINE_TEMPLATE Query<T>::~Query()
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
delete d; delete d;
} }
template<class T>
Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::operator=(const Query<T> &q)
{
if (this != &q)
{
T *p = q._data ? q._data->detach() : nullptr;
delete d;
d = p;
}
return *this;
}
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count) Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
RowList<T> returnList; RowList<T> returnList;
d->select = QStringLiteral("*"); d->select = QStringLiteral("*");
@ -343,7 +391,7 @@ template <typename T>
template <typename F> template <typename F>
Q_OUTOFLINE_TEMPLATE QList<F> Query<T>::select(const FieldPhrase<F> f) Q_OUTOFLINE_TEMPLATE QList<F> Query<T>::select(const FieldPhrase<F> f)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
QList<F> ret; QList<F> ret;
d->joins.prepend(d->tableName); d->joins.prepend(d->tableName);
@ -381,7 +429,7 @@ Q_OUTOFLINE_TEMPLATE Row<T> Query<T>::first()
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE int Query<T>::count() Q_OUTOFLINE_TEMPLATE int Query<T>::count()
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->joins.prepend(d->tableName); d->joins.prepend(d->tableName);
d->select = QStringLiteral("COUNT(*)"); d->select = QStringLiteral("COUNT(*)");
@ -401,7 +449,7 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::count()
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(const FieldPhrase<int> &f) Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(const FieldPhrase<int> &f)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->joins.prepend(d->tableName); d->joins.prepend(d->tableName);
d->sql = d->database->sqlGenerator()->selectCommand( d->sql = d->database->sqlGenerator()->selectCommand(
@ -419,7 +467,7 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(const FieldPhrase<int> &f)
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(const FieldPhrase<int> &f) Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(const FieldPhrase<int> &f)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->joins.prepend(d->tableName); d->joins.prepend(d->tableName);
d->sql = d->database->sqlGenerator()->selectCommand( d->sql = d->database->sqlGenerator()->selectCommand(
@ -437,7 +485,7 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(const FieldPhrase<int> &f)
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::sum(const FieldPhrase<int> &f) Q_OUTOFLINE_TEMPLATE QVariant Query<T>::sum(const FieldPhrase<int> &f)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->joins.prepend(d->tableName); d->joins.prepend(d->tableName);
d->sql = d->database->sqlGenerator()->selectCommand( d->sql = d->database->sqlGenerator()->selectCommand(
@ -455,7 +503,7 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::sum(const FieldPhrase<int> &f)
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::average(const FieldPhrase<int> &f) Q_OUTOFLINE_TEMPLATE QVariant Query<T>::average(const FieldPhrase<int> &f)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->joins.prepend(d->tableName); d->joins.prepend(d->tableName);
d->sql = d->database->sqlGenerator()->selectCommand( d->sql = d->database->sqlGenerator()->selectCommand(
@ -473,7 +521,7 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::average(const FieldPhrase<int> &f)
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::insert(const AssignmentPhraseList &p) Q_OUTOFLINE_TEMPLATE QVariant Query<T>::insert(const AssignmentPhraseList &p)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->sql = d->database->sqlGenerator() d->sql = d->database->sqlGenerator()
->insertCommand(d->tableName, p); ->insertCommand(d->tableName, p);
QSqlQuery q = d->database->exec(d->sql); QSqlQuery q = d->database->exec(d->sql);
@ -482,9 +530,9 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::insert(const AssignmentPhraseList &p)
} }
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::join(const QString &className) Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::join(const QString &className)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
RelationModel *rel = d->database->model() RelationModel *rel = d->database->model()
.relationByClassNames(d->className, className); .relationByClassNames(d->className, className);
@ -495,85 +543,85 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::join(const QString &className)
if (!rel) { if (!rel) {
qDebug() << "No relation between" << d->className qDebug() << "No relation between" << d->className
<< "and" << className; << "and" << className;
return this; return *this;
} }
d->relations.append(rel); d->relations.append(rel);
d->joins.append(className); d->joins.append(className);
return this; return *this;
} }
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::join(Table *c) Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::join(Table *c)
{ {
join(c->metaObject()->className()); join(c->metaObject()->className());
return this; return *this;
} }
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::where(const ConditionalPhrase &ph) Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::where(const ConditionalPhrase &ph)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
if (d->wherePhrase.data) if (d->wherePhrase.data)
d->wherePhrase = d->wherePhrase && ph; d->wherePhrase = d->wherePhrase && ph;
else else
d->wherePhrase = ph; d->wherePhrase = ph;
return this; return *this;
} }
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::setWhere(const ConditionalPhrase &ph) Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::setWhere(const ConditionalPhrase &ph)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->wherePhrase = ph; d->wherePhrase = ph;
return this; return *this;
} }
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::skip(int n) Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::skip(int n)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->skip = n; d->skip = n;
return this; return *this;
} }
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::take(int n) Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::take(int n)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->take = n; d->take = n;
return this; return *this;
} }
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::fields(const PhraseList &ph) Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::fields(const PhraseList &ph)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->fieldPhrase = ph; d->fieldPhrase = ph;
return this; return *this;
} }
//template <class T> //template <class T>
//Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(QString fieldName, //Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::orderBy(QString fieldName,
// QString type) // QString type)
//{ //{
// Q_D(AbstractQuery); // //Q_D(AbstractQuery);
// d->orderPhrases.append(fieldName, type); // d->orderPhrases.append(fieldName, type);
// return this; // return *this;
//} //}
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(const PhraseList &ph) Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::orderBy(const PhraseList &ph)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->orderPhrase = ph; d->orderPhrase = ph;
return this; return *this;
} }
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph) Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->sql = d->database->sqlGenerator()->updateCommand( d->sql = d->database->sqlGenerator()->updateCommand(
d->tableName, d->tableName,
@ -590,7 +638,7 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph)
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE int Query<T>::remove() Q_OUTOFLINE_TEMPLATE int Query<T>::remove()
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->sql = d->database->sqlGenerator()->deleteCommand( d->sql = d->database->sqlGenerator()->deleteCommand(
d->tableName, d->wherePhrase); d->tableName, d->wherePhrase);
@ -612,7 +660,7 @@ Q_OUTOFLINE_TEMPLATE QSqlQueryModel *Query<T>::toModel()
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(QSqlQueryModel *model) Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(QSqlQueryModel *model)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->sql = d->database->sqlGenerator()->selectCommand( d->sql = d->database->sqlGenerator()->selectCommand(
d->tableName, d->tableName,
@ -649,7 +697,7 @@ Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(QSqlQueryModel *model)
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(SqlModel *model) Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(SqlModel *model)
{ {
Q_D(AbstractQuery); //Q_D(AbstractQuery);
d->sql = d->database->sqlGenerator()->selectCommand( d->sql = d->database->sqlGenerator()->selectCommand(
d->tableName, d->tableName,
@ -686,7 +734,7 @@ Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(SqlModel *model)
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE QString Query<T>::sqlCommand() const Q_OUTOFLINE_TEMPLATE QString Query<T>::sqlCommand() const
{ {
Q_D(const AbstractQuery); //Q_D(const AbstractQuery);
return d->sql; return d->sql;
} }