Nut/src/wherephrase.h

503 lines
13 KiB
C
Raw Normal View History

2016-05-21 16:09:03 +08:00
/**************************************************************************
**
** 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 <http://www.gnu.org/licenses/>.
**
**************************************************************************/
#ifndef PHRASE_H
#define PHRASE_H
2016-05-20 21:13:49 +08:00
#include <QtCore/qglobal.h>
2016-05-21 16:09:03 +08:00
#include <QVariant>
#include <QDate>
#include <QDateTime>
#include <QTime>
2017-06-12 00:50:43 +08:00
#include <QPoint>
2016-06-05 20:22:26 +08:00
#include <QSharedPointer>
2017-02-01 18:01:21 +08:00
#include "defines.h"
2018-01-08 17:08:10 +08:00
#include "types/dbgeography.h"
2016-05-21 16:09:03 +08:00
2017-07-27 00:01:35 +08:00
#include <initializer_list>
2017-02-01 18:01:21 +08:00
NUT_BEGIN_NAMESPACE
2016-05-21 16:09:03 +08:00
class SqlGeneratorBase;
2017-07-27 00:01:35 +08:00
class PhraseData
{
2016-06-05 20:22:26 +08:00
public:
2017-07-27 00:01:35 +08:00
enum Condition {
2016-06-05 20:22:26 +08:00
NotAssign = 0,
Equal,
2016-05-21 16:09:03 +08:00
Less,
LessEqual,
Null,
In,
Like,
2016-06-05 20:22:26 +08:00
Not = 10,
NotEqual,
2016-05-21 16:09:03 +08:00
GreaterEqual,
Greater,
NotNull,
NotIn,
NotLike,
And = 20,
Or,
Append,
Set,
Add,
Minus,
Multiple,
2017-05-25 23:46:54 +08:00
Divide,
2017-07-27 00:01:35 +08:00
// special types
2017-05-25 23:46:54 +08:00
Distance
2016-05-21 16:09:03 +08:00
};
2017-07-27 00:01:35 +08:00
enum Type { Field, WithVariant, WithOther, WithoutOperand };
2016-05-21 16:09:03 +08:00
Type type;
Condition operatorCond;
QString text;
const PhraseData *left;
const PhraseData *right;
QVariant operand;
2017-07-27 00:01:35 +08:00
PhraseData(const char *className, const char *s);
2016-05-21 16:09:03 +08:00
PhraseData(PhraseData *l, Condition o);
PhraseData(PhraseData *l, Condition o, const PhraseData *r);
PhraseData(PhraseData *l, Condition o, QVariant r);
~PhraseData();
};
2017-07-27 00:01:35 +08:00
class WherePhrase
{
2016-05-24 14:47:37 +08:00
protected:
2016-06-05 20:22:26 +08:00
PhraseData *_data;
QSharedPointer<PhraseData> _dataPointer;
2016-05-24 14:47:37 +08:00
2016-05-20 21:13:49 +08:00
public:
2017-07-27 00:01:35 +08:00
WherePhrase(const char *className, const char *s);
2016-05-21 16:09:03 +08:00
2016-06-05 20:22:26 +08:00
WherePhrase(const WherePhrase &l);
WherePhrase(WherePhrase *l);
WherePhrase(WherePhrase *l, PhraseData::Condition o);
WherePhrase(WherePhrase *l, PhraseData::Condition o, WherePhrase *r);
WherePhrase(WherePhrase *l, PhraseData::Condition o, QVariant r);
2016-05-21 16:09:03 +08:00
2016-05-24 14:47:37 +08:00
~WherePhrase();
2016-05-21 16:09:03 +08:00
2017-07-27 00:01:35 +08:00
WherePhrase operator==(const WherePhrase &other);
WherePhrase operator!=(const WherePhrase &other);
WherePhrase operator<(const WherePhrase &other);
WherePhrase operator>(const WherePhrase &other);
WherePhrase operator<=(const WherePhrase &other);
WherePhrase operator>=(const WherePhrase &other);
2016-05-24 14:47:37 +08:00
2017-07-27 00:01:35 +08:00
WherePhrase operator==(const QVariant &other);
WherePhrase operator!=(const QVariant &other);
WherePhrase operator<(const QVariant &other);
WherePhrase operator>(const QVariant &other);
WherePhrase operator<=(const QVariant &other);
WherePhrase operator>=(const QVariant &other);
2016-05-24 14:47:37 +08:00
2017-07-27 00:01:35 +08:00
WherePhrase operator!();
WherePhrase operator=(const WherePhrase &other);
2016-05-21 16:09:03 +08:00
2017-07-27 00:01:35 +08:00
WherePhrase operator+(const WherePhrase &other);
WherePhrase operator-(const WherePhrase &other);
WherePhrase operator*(const WherePhrase &other);
WherePhrase operator/(const WherePhrase &other);
2016-05-21 16:09:03 +08:00
2017-07-27 00:01:35 +08:00
WherePhrase operator&&(const WherePhrase &other);
WherePhrase operator||(const WherePhrase &other);
WherePhrase operator&(const WherePhrase &other);
2016-05-21 16:09:03 +08:00
2016-06-05 20:22:26 +08:00
PhraseData *data() const;
2016-05-24 14:47:37 +08:00
};
2017-07-27 00:01:35 +08:00
template <typename T>
class FieldPhrase : public WherePhrase
{
2016-05-24 14:47:37 +08:00
public:
2017-07-27 00:01:35 +08:00
FieldPhrase(const char *className, const char *s);
2016-05-21 16:09:03 +08:00
2017-07-27 00:01:35 +08:00
WherePhrase operator=(const WherePhrase &other);
WherePhrase operator=(const QVariant &other);
WherePhrase operator+(const QVariant &other);
WherePhrase operator!();
2016-05-21 16:09:03 +08:00
2017-07-27 00:01:35 +08:00
WherePhrase operator==(const QVariant &other);
WherePhrase operator!=(const QVariant &other);
WherePhrase operator<(const QVariant &other);
WherePhrase operator>(const QVariant &other);
WherePhrase operator<=(const QVariant &other);
WherePhrase operator>=(const QVariant &other);
2017-07-24 16:27:52 +08:00
2016-05-24 14:47:37 +08:00
WherePhrase isNull();
2017-05-31 00:19:37 +08:00
WherePhrase in(QList<T> list);
2017-07-27 00:01:35 +08:00
// WherePhrase in(QStringList list);
2016-05-24 14:47:37 +08:00
WherePhrase like(QString pattern);
2016-05-20 21:13:49 +08:00
};
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE FieldPhrase<T>::FieldPhrase(const char *className,
const char *s)
: WherePhrase(className, s)
2017-05-25 23:46:54 +08:00
{
2017-07-27 00:01:35 +08:00
// qDebug() << "(" << this << ")" << "FieldPhrase ctor" << className <<
// s;
2017-05-25 23:46:54 +08:00
}
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
operator=(const QVariant &other)
2017-05-25 23:46:54 +08:00
{
return WherePhrase(this, PhraseData::Set, other);
}
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
operator=(const WherePhrase &other)
2017-06-12 00:50:43 +08:00
{
return WherePhrase(this, PhraseData::Set, &other);
}
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
operator+(const QVariant &other)
2017-06-12 00:50:43 +08:00
{
return WherePhrase(this, PhraseData::Add, other);
}
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::operator!()
2017-05-25 23:46:54 +08:00
{
2017-07-27 00:01:35 +08:00
if (_data->operatorCond < 20)
_data->operatorCond
= (PhraseData::Condition)((_data->operatorCond + 10) % 20);
2017-05-25 23:46:54 +08:00
else
qFatal("Operator ! can not aplied to non condition statements");
2017-07-27 00:01:35 +08:00
return this; // WherePhrase(this, PhraseData::Not);
2017-05-25 23:46:54 +08:00
}
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
operator==(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::Equal, other);
}
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
operator!=(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::NotEqual, other);
}
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
operator<(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::Less, other);
}
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
operator>(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::Greater, other);
}
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
operator<=(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::LessEqual, other);
}
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::
operator>=(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::GreaterEqual, other);
}
2017-07-27 00:01:35 +08:00
template <typename T>
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::isNull()
{
2017-05-25 23:46:54 +08:00
return WherePhrase(this, PhraseData::Null);
}
2017-07-27 00:01:35 +08:00
template <typename T>
2017-05-31 00:19:37 +08:00
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::in(QList<T> list)
2017-05-25 23:46:54 +08:00
{
2017-05-31 00:19:37 +08:00
QVariantList vlist;
foreach (T t, list)
vlist.append(QVariant::fromValue(t));
2017-05-25 23:46:54 +08:00
2017-05-31 00:19:37 +08:00
return WherePhrase(this, PhraseData::In, vlist);
2017-05-25 23:46:54 +08:00
}
2017-07-27 00:01:35 +08:00
// template<typename T>
// Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::in(QStringList list)
2017-05-31 00:19:37 +08:00
//{
// return WherePhrase(this, PhraseData::In, list);
//}
2017-07-27 00:01:35 +08:00
template <typename T>
2017-05-25 23:46:54 +08:00
Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase<T>::like(QString pattern)
{
return WherePhrase(this, PhraseData::Like, pattern);
}
2017-06-05 00:04:17 +08:00
// Custom types
2017-07-27 00:01:35 +08:00
template <>
class FieldPhrase<DbGeography> : public WherePhrase
{
2017-05-25 23:46:54 +08:00
public:
2017-07-27 00:01:35 +08:00
FieldPhrase(const char *className, const char *s)
: WherePhrase(className, s)
{
2017-05-25 23:46:54 +08:00
}
2017-07-27 00:01:35 +08:00
WherePhrase distance(const DbGeography &geo)
{
return WherePhrase(this, PhraseData::Distance,
QVariant::fromValue(geo));
2017-05-25 23:46:54 +08:00
}
};
2017-06-12 00:50:43 +08:00
// Custom types
2017-07-27 00:01:35 +08:00
template <>
class FieldPhrase<QPoint> : public WherePhrase
{
2017-06-12 00:50:43 +08:00
public:
2017-07-27 00:01:35 +08:00
FieldPhrase(const char *className, const char *s)
: WherePhrase(className, s)
{
2017-06-12 00:50:43 +08:00
}
2017-07-27 00:01:35 +08:00
WherePhrase distance(const QPoint &geo)
{
return WherePhrase(this, PhraseData::Distance,
QVariant::fromValue(geo));
2017-06-12 00:50:43 +08:00
}
2017-07-27 00:01:35 +08:00
WherePhrase operator=(const QPoint &other)
{
2017-06-12 00:50:43 +08:00
return WherePhrase(this, PhraseData::Set, other);
}
};
// Custom types
2017-07-27 00:01:35 +08:00
template <>
class FieldPhrase<QPointF> : public WherePhrase
{
2017-06-12 00:50:43 +08:00
public:
2017-07-27 00:01:35 +08:00
FieldPhrase(const char *className, const char *s)
: WherePhrase(className, s)
{
2017-06-12 00:50:43 +08:00
}
2017-07-27 00:01:35 +08:00
WherePhrase distance(const QPointF &geo)
{
return WherePhrase(this, PhraseData::Distance,
QVariant::fromValue(geo));
2017-06-12 00:50:43 +08:00
}
2017-07-27 00:01:35 +08:00
WherePhrase operator=(const QPointF &other)
{
2017-06-12 00:50:43 +08:00
return WherePhrase(this, PhraseData::Set, other);
}
};
2017-07-27 00:01:35 +08:00
// template<>
// class FieldPhrase<QString>: public WherePhrase {
// public:
// FieldPhrase(const char *className, const char* s) : WherePhrase(className,
// s){
2017-07-24 16:27:52 +08:00
// }
// WherePhrase like(QString pattern)
// {
// return WherePhrase(this, PhraseData::Like, pattern);
// }
//};
2017-07-27 00:01:35 +08:00
template <>
class FieldPhrase<bool> : public WherePhrase
{
2017-06-05 00:04:17 +08:00
public:
2017-07-27 00:01:35 +08:00
FieldPhrase(const char *className, const char *s)
: WherePhrase(className, s)
{
2017-06-05 00:04:17 +08:00
}
2017-07-27 00:01:35 +08:00
WherePhrase operator==(const bool &other)
{
2017-06-05 00:04:17 +08:00
return WherePhrase(this, PhraseData::Equal, other ? 1 : 0);
}
2017-07-27 00:01:35 +08:00
WherePhrase operator=(const bool &other)
{
2017-06-05 00:04:17 +08:00
return WherePhrase(this, PhraseData::Set, other ? 1 : 0);
}
2017-07-27 00:01:35 +08:00
WherePhrase operator!()
{
2017-06-05 00:04:17 +08:00
return WherePhrase(this, PhraseData::Equal, 0);
}
};
2017-05-25 23:46:54 +08:00
2017-07-27 00:01:35 +08:00
class NumericFieldPhrase : public WherePhrase
{
2017-07-24 16:27:52 +08:00
public:
2017-07-27 00:01:35 +08:00
NumericFieldPhrase(const char *className, const char *s)
: WherePhrase(className, s)
{
}
2017-07-24 16:27:52 +08:00
2017-07-27 00:01:35 +08:00
WherePhrase operator=(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::Set, other);
}
2017-07-27 00:01:35 +08:00
WherePhrase operator+(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::Add, other);
}
2017-07-27 00:01:35 +08:00
WherePhrase operator-(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::Minus, other);
}
2017-07-27 00:01:35 +08:00
WherePhrase operator++()
{
return WherePhrase(this, PhraseData::Add, 1);
}
2017-07-24 16:27:52 +08:00
2017-07-27 00:01:35 +08:00
WherePhrase operator--()
{
return WherePhrase(this, PhraseData::Minus, 1);
}
WherePhrase operator==(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::Equal, other);
}
2017-07-27 00:01:35 +08:00
WherePhrase operator!=(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::NotEqual, other);
}
2017-07-27 00:01:35 +08:00
WherePhrase operator<(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::Less, other);
}
2017-07-27 00:01:35 +08:00
WherePhrase operator>(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::Greater, other);
}
2017-07-27 00:01:35 +08:00
WherePhrase operator<=(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::LessEqual, other);
}
2017-07-27 00:01:35 +08:00
WherePhrase operator>=(const QVariant &other)
2017-07-24 16:27:52 +08:00
{
return WherePhrase(this, PhraseData::GreaterEqual, other);
}
WherePhrase isNull()
{
return WherePhrase(this, PhraseData::Null);
}
2017-07-27 00:01:35 +08:00
template<typename T>
WherePhrase in(QList<T> list)
{
QVariantList vlist;
foreach (T t, list)
vlist.append(QVariant::fromValue(t));
return WherePhrase(this, PhraseData::In, vlist);
}
template<typename T>
WherePhrase in(std::initializer_list<T> list)
{
return in(QList<T>(list));
}
WherePhrase in(int count, ...)
{
QVariantList vlist;
va_list ap;
va_start(ap, count);
for (int i = 0; i < count; ++i)
vlist.append(QVariant::fromValue(va_arg(ap, int)));
va_end(ap);
return WherePhrase(this, PhraseData::In, vlist);
}
2017-07-24 16:27:52 +08:00
};
2017-07-25 22:10:43 +08:00
#define SPECIALIZATION_NUMERIC(type) \
2017-07-27 00:01:35 +08:00
template <> \
class FieldPhrase<type> : public NumericFieldPhrase \
{ \
2017-07-24 16:27:52 +08:00
public: \
2017-07-27 00:01:35 +08:00
FieldPhrase(const char *className, const char *s) \
: NumericFieldPhrase(className, s) \
2017-07-24 16:27:52 +08:00
{ \
} \
2017-07-27 00:01:35 +08:00
WherePhrase operator=(const WherePhrase &other) \
2017-07-24 16:27:52 +08:00
{ \
2017-07-27 00:01:35 +08:00
return WherePhrase(this, PhraseData::Set, (WherePhrase *)&other); \
2017-07-24 16:27:52 +08:00
} \
};
2017-07-25 22:10:43 +08:00
SPECIALIZATION_NUMERIC(qint8)
2017-07-24 16:27:52 +08:00
SPECIALIZATION_NUMERIC(qint16)
SPECIALIZATION_NUMERIC(qint32)
SPECIALIZATION_NUMERIC(qint64)
2017-07-25 22:10:43 +08:00
SPECIALIZATION_NUMERIC(quint8)
SPECIALIZATION_NUMERIC(quint16)
SPECIALIZATION_NUMERIC(quint32)
SPECIALIZATION_NUMERIC(quint64)
2017-07-24 16:27:52 +08:00
SPECIALIZATION_NUMERIC(qreal)
2017-02-01 18:01:21 +08:00
NUT_END_NAMESPACE
2016-05-21 16:09:03 +08:00
#endif // PHRASE_H