wip: phrases polish
This commit is contained in:
parent
eb44eea463
commit
0762e647fb
|
|
@ -0,0 +1,6 @@
|
|||
install:
|
||||
- set QTDIR=C:\Qt\5.9.2\winrt_x64_msvc2017
|
||||
- set PATH=%PATH%;%QTDIR%\bin;C:\MinGW\bin
|
||||
build_script:
|
||||
- qmake
|
||||
- mingw32-make
|
||||
8
nut.pri
8
nut.pri
|
|
@ -18,14 +18,14 @@ HEADERS += \
|
|||
$$PWD/src/tablesetbase_p.h \
|
||||
$$PWD/src/querybase_p.h \
|
||||
$$PWD/src/tablemodel.h \
|
||||
$$PWD/src/wherephrase.h \
|
||||
$$PWD/src/query_p.h \
|
||||
$$PWD/src/table.h \
|
||||
$$PWD/src/database.h \
|
||||
$$PWD/src/database_p.h \
|
||||
$$PWD/src/serializableobject.h \
|
||||
$$PWD/src/sqlmodel.h \
|
||||
$$PWD/src/sqlmodel_p.h
|
||||
$$PWD/src/sqlmodel_p.h \
|
||||
$$PWD/src/phrase.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/src/generators/sqlgeneratorbase.cpp \
|
||||
|
|
@ -41,8 +41,8 @@ SOURCES += \
|
|||
$$PWD/src/changelogtable.cpp \
|
||||
$$PWD/src/querybase.cpp \
|
||||
$$PWD/src/tablemodel.cpp \
|
||||
$$PWD/src/wherephrase.cpp \
|
||||
$$PWD/src/table.cpp \
|
||||
$$PWD/src/database.cpp \
|
||||
$$PWD/src/serializableobject.cpp \
|
||||
$$PWD/src/sqlmodel.cpp
|
||||
$$PWD/src/sqlmodel.cpp \
|
||||
$$PWD/src/phrase.cpp
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <QtCore/QMetaProperty>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
|
||||
|
|
|
|||
|
|
@ -123,35 +123,35 @@ QVariant MySqlGenerator::readValue(const QVariant::Type &type, const QVariant &d
|
|||
return SqlGeneratorBase::readValue(type, dbValue);
|
||||
}
|
||||
|
||||
QString MySqlGenerator::phrase(const PhraseData *d) const
|
||||
{
|
||||
if (d->operatorCond == PhraseData::Distance) {
|
||||
return QString("ST_Distance(%1, %2)")
|
||||
.arg(d->left->text)
|
||||
.arg(escapeValue(d->operand.toPointF()));
|
||||
}
|
||||
//QString MySqlGenerator::phrase(const PhraseData *d) const
|
||||
//{
|
||||
// if (d->operatorCond == PhraseData::Distance) {
|
||||
// return QString("ST_Distance(%1, %2)")
|
||||
// .arg(d->left->text)
|
||||
// .arg(escapeValue(d->operand.toPointF()));
|
||||
// }
|
||||
|
||||
return SqlGeneratorBase::phrase(d);
|
||||
}
|
||||
// return SqlGeneratorBase::phrase(d);
|
||||
//}
|
||||
|
||||
QString MySqlGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||
QString agregateArg,
|
||||
QString tableName,
|
||||
QList<WherePhrase> &wheres,
|
||||
QList<WherePhrase> &orders,
|
||||
QList<RelationModel*> joins,
|
||||
int skip, int take)
|
||||
{
|
||||
QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
||||
tableName,
|
||||
wheres, orders,
|
||||
joins, skip, take);
|
||||
//QString MySqlGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||
// QString agregateArg,
|
||||
// QString tableName,
|
||||
// QList<WherePhrase> &wheres,
|
||||
// QList<WherePhrase> &orders,
|
||||
// QList<RelationModel*> joins,
|
||||
// int skip, int take)
|
||||
//{
|
||||
// QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
||||
// tableName,
|
||||
// wheres, orders,
|
||||
// joins, skip, take);
|
||||
|
||||
if (take != -1 && skip != -1)
|
||||
command.append(QString(" LIMIT %1 OFFSET %2")
|
||||
.arg(take)
|
||||
.arg(skip));
|
||||
return command;
|
||||
}
|
||||
// if (take != -1 && skip != -1)
|
||||
// command.append(QString(" LIMIT %1 OFFSET %2")
|
||||
// .arg(take)
|
||||
// .arg(skip));
|
||||
// return command;
|
||||
//}
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ public:
|
|||
QString fieldType(FieldModel *field);
|
||||
QString escapeValue(const QVariant &v) const;
|
||||
QVariant readValue(const QVariant::Type &type, const QVariant &dbValue);
|
||||
QString phrase(const PhraseData *d) const;
|
||||
QString selectCommand(AgregateType t, QString agregateArg, QString tableName, QList<WherePhrase> &wheres, QList<WherePhrase> &orders, QList<RelationModel *> joins, int skip, int take);
|
||||
// QString phrase(const PhraseData *d) const;
|
||||
// QString selectCommand(AgregateType t, QString agregateArg, QString tableName, QList<WherePhrase> &wheres, QList<WherePhrase> &orders, QList<RelationModel *> joins, int skip, int take);
|
||||
};
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#include "../table.h"
|
||||
#include "../databasemodel.h"
|
||||
#include "../tablemodel.h"
|
||||
#include "../wherephrase.h"
|
||||
|
||||
NUT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -355,10 +354,6 @@ QString SqlGeneratorBase::agregateText(const AgregateType &t,
|
|||
const QString &arg) const
|
||||
{
|
||||
switch (t) {
|
||||
case SelectAll:
|
||||
return "*";
|
||||
break;
|
||||
|
||||
case Min:
|
||||
return "MIN(" + arg + ")";
|
||||
break;
|
||||
|
|
@ -426,48 +421,43 @@ QString SqlGeneratorBase::deleteRecords(QString tableName, QString where)
|
|||
return sql;
|
||||
}
|
||||
|
||||
QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||
QString agregateArg,
|
||||
QString tableName,
|
||||
QList<WherePhrase> &wheres,
|
||||
QList<WherePhrase> &orders,
|
||||
QList<RelationModel*> joins,
|
||||
int skip, int take)
|
||||
QString SqlGeneratorBase::selectCommand(const QString &tableName,
|
||||
const PhraseList &fields,
|
||||
const ConditionalPhrase &where,
|
||||
const PhraseList &order,
|
||||
const QList<RelationModel*> joins,
|
||||
const int skip,
|
||||
const int take)
|
||||
{
|
||||
Q_UNUSED(take);
|
||||
Q_UNUSED(skip);
|
||||
Q_UNUSED(take);
|
||||
QString selectText;
|
||||
|
||||
QStringList joinedOrders;
|
||||
QString select = agregateText(t, agregateArg);
|
||||
|
||||
//TODO: temporatory disabled
|
||||
if (t == SelectAll) {
|
||||
if (!fields.isValid) {
|
||||
QSet<TableModel*> tables;
|
||||
tables.insert(_database->model().tableByName(tableName));
|
||||
foreach (RelationModel *rel, joins)
|
||||
tables << rel->masterTable << rel->slaveTable;
|
||||
|
||||
select = "";
|
||||
selectText = "";
|
||||
foreach (TableModel *t, tables) {
|
||||
if (!select.isEmpty())
|
||||
select.append(", ");
|
||||
select.append(recordsPhrase(t));
|
||||
if (!selectText.isEmpty())
|
||||
selectText.append(", ");
|
||||
selectText.append(recordsPhrase(t));
|
||||
}
|
||||
}
|
||||
QString from = join(tableName, joins, &joinedOrders);
|
||||
QString where = createWhere(wheres);
|
||||
QString orderText = joinedOrders.join(", ");
|
||||
|
||||
foreach (WherePhrase p, orders) {
|
||||
if (orderText != "")
|
||||
orderText.append(", ");
|
||||
orderText.append(phraseOrder(p.data()));
|
||||
} else {
|
||||
selectText = createFieldPhrase(fields);
|
||||
}
|
||||
|
||||
QString sql = "SELECT " + select + " FROM " + from;
|
||||
QStringList joinedOrders;
|
||||
QString orderText = createOrderPhrase(order);
|
||||
QString whereText = createConditionalPhrase(where.data);
|
||||
QString fromText = join(tableName, joins, &joinedOrders);
|
||||
|
||||
if (where != "")
|
||||
sql.append(" WHERE " + where);
|
||||
QString sql = "SELECT " + selectText + " FROM " + fromText;
|
||||
|
||||
if (whereText != "")
|
||||
sql.append(" WHERE " + whereText);
|
||||
|
||||
if (orderText != "")
|
||||
sql.append(" ORDER BY " + orderText);
|
||||
|
|
@ -481,20 +471,149 @@ QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
|
|||
return sql + " ";
|
||||
}
|
||||
|
||||
QString SqlGeneratorBase::createWhere(QList<WherePhrase> &wheres)
|
||||
QString SqlGeneratorBase::selectCommand(const QString &tableName,
|
||||
const SqlGeneratorBase::AgregateType &t,
|
||||
const QString &agregateArg,
|
||||
const ConditionalPhrase &where,
|
||||
const QList<RelationModel *> &joins,
|
||||
const int skip,
|
||||
const int take)
|
||||
{
|
||||
QString whereText = "";
|
||||
Q_UNUSED(skip);
|
||||
Q_UNUSED(take);
|
||||
QStringList joinedOrders;
|
||||
QString selectText = agregateText(t, agregateArg);
|
||||
QString whereText = createConditionalPhrase(where.data);
|
||||
QString fromText = join(tableName, joins, &joinedOrders);
|
||||
|
||||
foreach (WherePhrase w, wheres) {
|
||||
if (whereText != "")
|
||||
whereText.append(" AND ");
|
||||
QString sql = "SELECT " + selectText + " FROM " + fromText;
|
||||
|
||||
whereText.append(phrase(w.data()));
|
||||
}
|
||||
if (whereText != "")
|
||||
sql.append(" WHERE " + whereText);
|
||||
|
||||
return whereText;
|
||||
for (int i = 0; i < _database->model().count(); i++)
|
||||
sql = sql.replace(_database->model().at(i)->className() + ".",
|
||||
_database->model().at(i)->name() + ".");
|
||||
|
||||
replaceTableNames(sql);
|
||||
|
||||
return sql + " ";
|
||||
}
|
||||
|
||||
QString SqlGeneratorBase::deleteCommand(const QString &tableName,
|
||||
const ConditionalPhrase &where)
|
||||
{
|
||||
QString command = "DELETE FROM " + tableName;
|
||||
QString whereText = createConditionalPhrase(where.data);
|
||||
|
||||
if (whereText != "")
|
||||
command.append(" WHERE " + whereText);
|
||||
|
||||
for (int i = 0; i < _database->model().count(); i++)
|
||||
command = command.replace(_database->model().at(i)->className() + ".",
|
||||
_database->model().at(i)->name() + ".");
|
||||
|
||||
replaceTableNames(command);
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
QString SqlGeneratorBase::updateCommand(const QString &tableName,
|
||||
const AssignmentPhraseList &assigments,
|
||||
const ConditionalPhrase &where)
|
||||
{
|
||||
QString assigmentTexts = "";
|
||||
foreach (PhraseData *d, assigments.data) {
|
||||
if (assigmentTexts != "")
|
||||
assigmentTexts.append(", ");
|
||||
|
||||
assigmentTexts.append(createConditionalPhrase(d));
|
||||
}
|
||||
QString whereText = createConditionalPhrase(where.data);
|
||||
|
||||
QString sql = "UPDATE " + tableName + " SET " + assigmentTexts;
|
||||
|
||||
if (whereText != "")
|
||||
sql.append(" WHERE " + whereText);
|
||||
|
||||
for (int i = 0; i < _database->model().count(); i++)
|
||||
sql = sql.replace(_database->model().at(i)->className() + ".",
|
||||
_database->model().at(i)->name() + ".");
|
||||
|
||||
removeTableNames(sql);
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
//QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||
// QString agregateArg,
|
||||
// QString tableName,
|
||||
// QList<WherePhrase> &wheres,
|
||||
// QList<WherePhrase> &orders,
|
||||
// QList<RelationModel*> joins,
|
||||
// int skip, int take)
|
||||
//{
|
||||
// Q_UNUSED(take);
|
||||
// Q_UNUSED(skip);
|
||||
|
||||
// QStringList joinedOrders;
|
||||
// QString select = agregateText(t, agregateArg);
|
||||
|
||||
// //TODO: temporatory disabled
|
||||
// if (t == SelectAll) {
|
||||
// QSet<TableModel*> tables;
|
||||
// tables.insert(_database->model().tableByName(tableName));
|
||||
// foreach (RelationModel *rel, joins)
|
||||
// tables << rel->masterTable << rel->slaveTable;
|
||||
|
||||
// select = "";
|
||||
// foreach (TableModel *t, tables) {
|
||||
// if (!select.isEmpty())
|
||||
// select.append(", ");
|
||||
// select.append(recordsPhrase(t));
|
||||
// }
|
||||
// }
|
||||
// QString from = join(tableName, joins, &joinedOrders);
|
||||
// QString where = createWhere(wheres);
|
||||
// QString orderText = joinedOrders.join(", ");
|
||||
|
||||
// foreach (WherePhrase p, orders) {
|
||||
// if (orderText != "")
|
||||
// orderText.append(", ");
|
||||
// orderText.append(phraseOrder(p.data()));
|
||||
// }
|
||||
|
||||
// QString sql = "SELECT " + select + " FROM " + from;
|
||||
|
||||
// if (where != "")
|
||||
// sql.append(" WHERE " + where);
|
||||
|
||||
// if (orderText != "")
|
||||
// sql.append(" ORDER BY " + orderText);
|
||||
|
||||
// for (int i = 0; i < _database->model().count(); i++)
|
||||
// sql = sql.replace(_database->model().at(i)->className() + ".",
|
||||
// _database->model().at(i)->name() + ".");
|
||||
|
||||
// replaceTableNames(sql);
|
||||
|
||||
// return sql + " ";
|
||||
//}
|
||||
|
||||
//QString SqlGeneratorBase::createWhere(QList<WherePhrase> &wheres)
|
||||
//{
|
||||
// QString whereText = "";
|
||||
|
||||
// foreach (WherePhrase w, wheres) {
|
||||
// if (whereText != "")
|
||||
// whereText.append(" AND ");
|
||||
|
||||
// whereText.append(phrase(w.data()));
|
||||
// }
|
||||
|
||||
// return whereText;
|
||||
//}
|
||||
|
||||
void SqlGeneratorBase::replaceTableNames(QString &command)
|
||||
{
|
||||
foreach (TableModel *m, TableModel::allModels())
|
||||
|
|
@ -508,44 +627,44 @@ void SqlGeneratorBase::removeTableNames(QString &command)
|
|||
command = command.replace("[" + m->className() + "].", "");
|
||||
}
|
||||
|
||||
QString SqlGeneratorBase::deleteCommand(QList<WherePhrase> &wheres,
|
||||
QString tableName)
|
||||
{
|
||||
QString command = "DELETE FROM " + tableName;
|
||||
QString where = createWhere(wheres);
|
||||
//QString SqlGeneratorBase::deleteCommand(QList<WherePhrase> &wheres,
|
||||
// QString tableName)
|
||||
//{
|
||||
// QString command = "DELETE FROM " + tableName;
|
||||
// QString where = createWhere(wheres);
|
||||
|
||||
if (where != "")
|
||||
command.append(" WHERE " + where);
|
||||
// if (where != "")
|
||||
// command.append(" WHERE " + where);
|
||||
|
||||
for (int i = 0; i < _database->model().count(); i++)
|
||||
command = command.replace(_database->model().at(i)->className() + ".",
|
||||
_database->model().at(i)->name() + ".");
|
||||
// for (int i = 0; i < _database->model().count(); i++)
|
||||
// command = command.replace(_database->model().at(i)->className() + ".",
|
||||
// _database->model().at(i)->name() + ".");
|
||||
|
||||
replaceTableNames(command);
|
||||
// replaceTableNames(command);
|
||||
|
||||
return command;
|
||||
}
|
||||
// return command;
|
||||
//}
|
||||
|
||||
QString SqlGeneratorBase::updateCommand(WherePhrase &phrase,
|
||||
QList<WherePhrase> &wheres,
|
||||
QString tableName)
|
||||
{
|
||||
QString p = this->phrase(phrase.data());
|
||||
QString where = createWhere(wheres);
|
||||
//QString SqlGeneratorBase::updateCommand(WherePhrase &phrase,
|
||||
// QList<WherePhrase> &wheres,
|
||||
// QString tableName)
|
||||
//{
|
||||
// QString p = this->phrase(phrase.data());
|
||||
// QString where = createWhere(wheres);
|
||||
|
||||
QString sql = "UPDATE " + tableName + " SET " + p;
|
||||
// QString sql = "UPDATE " + tableName + " SET " + p;
|
||||
|
||||
if (where != "")
|
||||
sql.append(" WHERE " + where);
|
||||
// if (where != "")
|
||||
// sql.append(" WHERE " + where);
|
||||
|
||||
for (int i = 0; i < _database->model().count(); i++)
|
||||
sql = sql.replace(_database->model().at(i)->className() + ".",
|
||||
_database->model().at(i)->name() + ".");
|
||||
// for (int i = 0; i < _database->model().count(); i++)
|
||||
// sql = sql.replace(_database->model().at(i)->className() + ".",
|
||||
// _database->model().at(i)->name() + ".");
|
||||
|
||||
removeTableNames(sql);
|
||||
// removeTableNames(sql);
|
||||
|
||||
return sql;
|
||||
}
|
||||
// return sql;
|
||||
//}
|
||||
|
||||
QString SqlGeneratorBase::escapeValue(const QVariant &v) const
|
||||
{
|
||||
|
|
@ -610,78 +729,13 @@ QVariant SqlGeneratorBase::readValue(const QVariant::Type &type,
|
|||
return dbValue;
|
||||
}
|
||||
|
||||
QString SqlGeneratorBase::phraseOrder(const PhraseData *d) const
|
||||
{
|
||||
|
||||
QString ret = "";
|
||||
|
||||
switch (d->type) {
|
||||
case PhraseData::Field:
|
||||
if (d->operatorCond == PhraseData::Not)
|
||||
ret = d->text + " DESC";
|
||||
else
|
||||
ret = d->text;
|
||||
break;
|
||||
|
||||
case PhraseData::WithOther:
|
||||
if (d->operatorCond != PhraseData::Append)
|
||||
qFatal("Order phease can only have & operator");
|
||||
|
||||
ret = phraseOrder(d->left) + ", " + phraseOrder(d->right);
|
||||
break;
|
||||
|
||||
case PhraseData::WithoutOperand:
|
||||
case PhraseData::WithVariant:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString SqlGeneratorBase::phrase(const PhraseData *d) const
|
||||
{
|
||||
QString ret = "";
|
||||
|
||||
switch (d->type) {
|
||||
case PhraseData::Field:
|
||||
ret = d->text;
|
||||
break;
|
||||
|
||||
case PhraseData::WithVariant:
|
||||
ret = phrase(d->left) + " " + operatorString(d->operatorCond) + " "
|
||||
+ escapeValue(d->operand);
|
||||
break;
|
||||
|
||||
case PhraseData::WithOther:
|
||||
ret = phrase(d->left) + " " + operatorString(d->operatorCond) + " "
|
||||
+ phrase(d->right);
|
||||
break;
|
||||
|
||||
case PhraseData::WithoutOperand:
|
||||
ret = phrase(d->left) + " " + operatorString(d->operatorCond);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = "<FAIL>";
|
||||
}
|
||||
|
||||
if (d->operatorCond == PhraseData::And || d->operatorCond == PhraseData::Or)
|
||||
ret = "(" + ret + ")";
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString SqlGeneratorBase::phraseUpdate(const PhraseData *d) const
|
||||
{
|
||||
QString ret = "";
|
||||
|
||||
if (d->operatorCond != PhraseData::And
|
||||
&& d->operatorCond != PhraseData::Equal)
|
||||
qFatal("Update command does not accept any phrase else &, =");
|
||||
|
||||
switch (d->type) {
|
||||
case PhraseData::Field:
|
||||
ret = d->text;
|
||||
ret = d->toString();
|
||||
break;
|
||||
|
||||
case PhraseData::WithVariant:
|
||||
|
|
@ -755,14 +809,139 @@ SqlGeneratorBase::operatorString(const PhraseData::Condition &cond) const
|
|||
case PhraseData::Divide:
|
||||
return "/";
|
||||
|
||||
case PhraseData::Set:
|
||||
return "=";
|
||||
// case PhraseData::Set:
|
||||
// return "=";
|
||||
|
||||
case PhraseData::Append:
|
||||
return ",";
|
||||
// case PhraseData::Append:
|
||||
// return ",";
|
||||
|
||||
case PhraseData::Between:
|
||||
return "BETWEEN";
|
||||
|
||||
case PhraseData::Mod:
|
||||
return "MOD";
|
||||
|
||||
default:
|
||||
return QString("<FAIL>");
|
||||
return QString("<FAIL cond> %1").arg(cond);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString SqlGeneratorBase::createConditionalPhrase(const PhraseData *d) const
|
||||
{
|
||||
if (!d)
|
||||
return "";
|
||||
|
||||
QString ret = "";
|
||||
|
||||
PhraseData::Condition op = d->operatorCond;
|
||||
//apply not (!)
|
||||
if (d->isNot) {
|
||||
if (op < 20)
|
||||
op = (PhraseData::Condition)((op + 10) % 20);
|
||||
}
|
||||
switch (d->type) {
|
||||
case PhraseData::Field:
|
||||
ret = d->toString();
|
||||
break;
|
||||
|
||||
case PhraseData::WithVariant:
|
||||
if (op == PhraseData::AddYears)
|
||||
ret = QString("DATEADD(year, %1, %2)")
|
||||
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
|
||||
else if (op == PhraseData::AddMonths)
|
||||
ret = QString("DATEADD(month, %1, %2)")
|
||||
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
|
||||
else if (op == PhraseData::AddYears)
|
||||
ret = QString("DATEADD(day, %1, %2)")
|
||||
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
|
||||
else if (op == PhraseData::AddHours)
|
||||
ret = QString("DATEADD(hour, %1, %2)")
|
||||
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
|
||||
else if (op == PhraseData::AddMinutes)
|
||||
ret = QString("DATEADD(minute, %1, %2)")
|
||||
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
|
||||
else if (op == PhraseData::AddSeconds)
|
||||
ret = QString("DATEADD(second, %1, %2)")
|
||||
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
|
||||
else
|
||||
ret = createConditionalPhrase(d->left) + " " + operatorString(op) + " "
|
||||
+ escapeValue(d->operand);
|
||||
break;
|
||||
|
||||
case PhraseData::WithOther:
|
||||
ret = createConditionalPhrase(d->left) + " " + operatorString(op) + " "
|
||||
+ createConditionalPhrase(d->right);
|
||||
break;
|
||||
|
||||
case PhraseData::WithoutOperand:
|
||||
ret = createConditionalPhrase(d->left) + " " + operatorString(op);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = "<FAIL phrase>";
|
||||
}
|
||||
|
||||
if (d->operatorCond == PhraseData::And || d->operatorCond == PhraseData::Or)
|
||||
ret = "(" + ret + ")";
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString SqlGeneratorBase::createOrderPhrase(const PhraseList &ph)
|
||||
{
|
||||
QString ret = "";
|
||||
foreach (const PhraseData *d, ph.data) {
|
||||
if (ret != "")
|
||||
ret.append(", ");
|
||||
ret.append(d->toString());
|
||||
if (d->isNot)
|
||||
ret.append(" DESC");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString SqlGeneratorBase::createFieldPhrase(const PhraseList &ph)
|
||||
{
|
||||
QString ret = "";
|
||||
foreach (const PhraseData *d, ph.data) {
|
||||
if (ret != "")
|
||||
ret.append(", ");
|
||||
ret.append(d->toString());
|
||||
if (d->isNot)
|
||||
qDebug() << "Operator ! is ignored in fields phrase";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SqlGeneratorBase::createInsertPhrase(const AssignmentPhraseList &ph, QString &fields, QString &values)
|
||||
{
|
||||
foreach (PhraseData *d, ph.data) {
|
||||
if (fields != "")
|
||||
fields.append(", ");
|
||||
|
||||
if (values != "")
|
||||
values.append(", ");
|
||||
|
||||
switch (d->type) {
|
||||
case PhraseData::WithVariant:
|
||||
fields.append(d->left->toString());
|
||||
values.append(escapeValue(d->operand));
|
||||
// ret = createConditionalPhrase(d->left->toString()) + " " + operatorString(d->operatorCond) + " "
|
||||
// + escapeValue(d->operand);
|
||||
break;
|
||||
|
||||
case PhraseData::WithOther:
|
||||
fields.append(d->left->toString());
|
||||
values.append(d->right->toString());
|
||||
break;
|
||||
|
||||
case PhraseData::Field:
|
||||
case PhraseData::WithoutOperand:
|
||||
default:
|
||||
qFatal("Invalid insert command");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@
|
|||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QStringList>
|
||||
#include "../wherephrase.h"
|
||||
#include "../phrase.h"
|
||||
//#include "../wherephrase.h"
|
||||
|
||||
NUT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -47,7 +48,7 @@ public:
|
|||
Delete
|
||||
};
|
||||
enum AgregateType{
|
||||
SelectAll,
|
||||
// SelectAll,
|
||||
Count,
|
||||
Min,
|
||||
Max,
|
||||
|
|
@ -83,28 +84,51 @@ public:
|
|||
virtual QString deleteRecord(Table *t, QString tableName);
|
||||
virtual QString deleteRecords(QString tableName, QString where);
|
||||
|
||||
virtual QString selectCommand(AgregateType t,
|
||||
QString agregateArg, QString tableName,
|
||||
QList<WherePhrase> &wheres,
|
||||
QList<WherePhrase> &orders,
|
||||
QList<RelationModel*> joins,
|
||||
int skip = -1, int take = -1);
|
||||
virtual QString selectCommand(const QString &tableName,
|
||||
const PhraseList &fields,
|
||||
const ConditionalPhrase &where,
|
||||
const PhraseList &order,
|
||||
const QList<RelationModel*> joins,
|
||||
const int skip = -1,
|
||||
const int take = -1);
|
||||
|
||||
virtual QString deleteCommand(QList<WherePhrase> &wheres, QString tableName);
|
||||
virtual QString selectCommand(const QString &tableName,
|
||||
const AgregateType &t, const QString &agregateArg,
|
||||
const ConditionalPhrase &where,
|
||||
const QList<RelationModel *> &joins,
|
||||
const int skip = -1,
|
||||
const int take = -1);
|
||||
|
||||
virtual QString updateCommand(WherePhrase &phrase, QList<WherePhrase> &wheres, QString tableName);
|
||||
virtual QString deleteCommand(const QString &tableName,
|
||||
const ConditionalPhrase &where);
|
||||
virtual QString updateCommand(const QString &tableName,
|
||||
const AssignmentPhraseList &assigments,
|
||||
const ConditionalPhrase &where);
|
||||
// virtual QString selectCommand(AgregateType t,
|
||||
// QString agregateArg, QString tableName,
|
||||
// QList<WherePhrase> &wheres,
|
||||
// QList<WherePhrase> &orders,
|
||||
// QList<RelationModel*> joins,
|
||||
// int skip = -1, int take = -1);
|
||||
|
||||
// virtual QString deleteCommand(QList<WherePhrase> &wheres, QString tableName);
|
||||
|
||||
// virtual QString updateCommand(WherePhrase &phrase, QList<WherePhrase> &wheres, QString tableName);
|
||||
|
||||
virtual QString escapeValue(const QVariant &v) const;
|
||||
virtual QVariant readValue(const QVariant::Type &type, const QVariant &dbValue);
|
||||
virtual QString phrase(const PhraseData *d) const;
|
||||
virtual QString phraseUpdate(const PhraseData *d) const;
|
||||
virtual QString operatorString(const PhraseData::Condition &cond) const;
|
||||
|
||||
QString phraseOrder(const PhraseData *d) const;
|
||||
private:
|
||||
QString createConditionalPhrase(const PhraseData *d) const;
|
||||
QString createFieldPhrase(const PhraseList &ph);
|
||||
QString createOrderPhrase(const PhraseList &ph);
|
||||
void createInsertPhrase(const AssignmentPhraseList &ph, QString &fields, QString &values);
|
||||
|
||||
QString agregateText(const AgregateType &t, const QString &arg = QString::null) const;
|
||||
QString fromTableText(const QString &tableName, QString &joinClassName, QString &orderBy) const;
|
||||
QString createWhere(QList<WherePhrase> &wheres);
|
||||
// QString createWhere(QList<WherePhrase> &wheres);
|
||||
void replaceTableNames(QString &command);
|
||||
void removeTableNames(QString &command);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -71,24 +71,24 @@ QString SqliteGenerator::fieldType(FieldModel *field)
|
|||
return dbType;
|
||||
}
|
||||
|
||||
QString SqliteGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||
QString agregateArg,
|
||||
QString tableName,
|
||||
QList<WherePhrase> &wheres,
|
||||
QList<WherePhrase> &orders,
|
||||
QList<RelationModel*> joins,
|
||||
int skip, int take)
|
||||
{
|
||||
QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
||||
tableName,
|
||||
wheres, orders,
|
||||
joins, skip, take);
|
||||
//QString SqliteGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||
// QString agregateArg,
|
||||
// QString tableName,
|
||||
// QList<WherePhrase> &wheres,
|
||||
// QList<WherePhrase> &orders,
|
||||
// QList<RelationModel*> joins,
|
||||
// int skip, int take)
|
||||
//{
|
||||
// QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
||||
// tableName,
|
||||
// wheres, orders,
|
||||
// joins, skip, take);
|
||||
|
||||
if (take != -1 && skip != -1)
|
||||
command.append(QString(" LIMIT %1 OFFSET %2")
|
||||
.arg(take)
|
||||
.arg(skip));
|
||||
return command;
|
||||
}
|
||||
// if (take != -1 && skip != -1)
|
||||
// command.append(QString(" LIMIT %1 OFFSET %2")
|
||||
// .arg(take)
|
||||
// .arg(skip));
|
||||
// return command;
|
||||
//}
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ public:
|
|||
|
||||
QString fieldType(FieldModel *field);
|
||||
|
||||
QString selectCommand(AgregateType t, QString agregateArg,
|
||||
QString tableName,
|
||||
QList<WherePhrase> &wheres,
|
||||
QList<WherePhrase> &orders,
|
||||
QList<RelationModel *> joins, int skip, int take);
|
||||
// QString selectCommand(AgregateType t, QString agregateArg,
|
||||
// QString tableName,
|
||||
// QList<WherePhrase> &wheres,
|
||||
// QList<WherePhrase> &orders,
|
||||
// QList<RelationModel *> joins, int skip, int take);
|
||||
};
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -133,23 +133,23 @@ QString SqlServerGenerator::escapeValue(const QVariant &v) const
|
|||
return SqlGeneratorBase::escapeValue(v);
|
||||
}
|
||||
|
||||
QString SqlServerGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||
QString agregateArg,
|
||||
QString tableName,
|
||||
QList<WherePhrase> &wheres,
|
||||
QList<WherePhrase> &orders,
|
||||
QList<RelationModel*> joins, int skip, int take)
|
||||
{
|
||||
QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
||||
tableName,
|
||||
wheres, orders,
|
||||
joins, skip, take);
|
||||
//QString SqlServerGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||
// QString agregateArg,
|
||||
// QString tableName,
|
||||
// QList<WherePhrase> &wheres,
|
||||
// QList<WherePhrase> &orders,
|
||||
// QList<RelationModel*> joins, int skip, int take)
|
||||
//{
|
||||
// QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
||||
// tableName,
|
||||
// wheres, orders,
|
||||
// joins, skip, take);
|
||||
|
||||
if (take != -1 && skip != -1)
|
||||
command.append(QString("OFFSET %1 ROWS FETCH NEXT %2 ROWS ONLY")
|
||||
.arg(skip)
|
||||
.arg(take));
|
||||
return command;
|
||||
}
|
||||
// if (take != -1 && skip != -1)
|
||||
// command.append(QString("OFFSET %1 ROWS FETCH NEXT %2 ROWS ONLY")
|
||||
// .arg(skip)
|
||||
// .arg(take));
|
||||
// return command;
|
||||
//}
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -38,11 +38,11 @@ public:
|
|||
|
||||
QString escapeValue(const QVariant &v) const;
|
||||
|
||||
QString selectCommand(AgregateType t, QString agregateArg,
|
||||
QString tableName,
|
||||
QList<WherePhrase> &wheres,
|
||||
QList<WherePhrase> &orders,
|
||||
QList<RelationModel *> joins, int skip, int take);
|
||||
// QString selectCommand(AgregateType t, QString agregateArg,
|
||||
// QString tableName,
|
||||
// QList<WherePhrase> &wheres,
|
||||
// QList<WherePhrase> &orders,
|
||||
// QList<RelationModel *> joins, int skip, int take);
|
||||
};
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -0,0 +1,367 @@
|
|||
/**************************************************************************
|
||||
**
|
||||
** 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/>.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "phrase.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
NUT_BEGIN_NAMESPACE
|
||||
|
||||
#define LOG(s) qDebug() << __func__ << s;
|
||||
|
||||
PhraseData::PhraseData(const char *className, const char *fieldName) :
|
||||
className(className), fieldName(fieldName),
|
||||
type(Field), operatorCond(NotAssign),
|
||||
left(0), right(0), operand(QVariant::Invalid), isNot(false)
|
||||
{ }
|
||||
|
||||
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o)
|
||||
: className(0), fieldName(0),
|
||||
type(WithoutOperand), operatorCond(o), left(l), right(0), isNot(false)
|
||||
{ }
|
||||
|
||||
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o,
|
||||
const PhraseData *r)
|
||||
: className(0), fieldName(0),
|
||||
type(WithOther), operatorCond(o), left(l), right(r), isNot(false)
|
||||
{ }
|
||||
|
||||
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o, QVariant r)
|
||||
: className(0), fieldName(0),
|
||||
type(WithVariant), operatorCond(o), left(l), operand(r), isNot(false)
|
||||
{ }
|
||||
|
||||
PhraseData::PhraseData(const PhraseData *other)
|
||||
{
|
||||
left = other->left;
|
||||
right = other->right;
|
||||
operand = other->operand;
|
||||
operatorCond = other->operatorCond;
|
||||
className = other->className;
|
||||
fieldName = other->fieldName;
|
||||
type = other->type;
|
||||
}
|
||||
|
||||
QString PhraseData::toString() const
|
||||
{
|
||||
return QString("[%1].%2").arg(className).arg(fieldName);
|
||||
}
|
||||
|
||||
PhraseData::~PhraseData()
|
||||
{
|
||||
// if (type == WithOther) {
|
||||
// delete left;
|
||||
// delete right;
|
||||
// }
|
||||
// if (type == WithVariant) {
|
||||
// if (left)
|
||||
// delete left;
|
||||
// }
|
||||
LOG("");
|
||||
}
|
||||
|
||||
AbstractFieldPhrase::AbstractFieldPhrase(const char *className, const char *fieldName)
|
||||
:data(new PhraseData(className, fieldName))
|
||||
{
|
||||
qDebug() <<"AbstractFieldPhrase created"<<className<<fieldName;
|
||||
}
|
||||
|
||||
AbstractFieldPhrase::AbstractFieldPhrase(const AbstractFieldPhrase &other)
|
||||
{
|
||||
qDebug() <<"4444444444444444";
|
||||
data = new PhraseData(other.data);
|
||||
}
|
||||
|
||||
AbstractFieldPhrase::~AbstractFieldPhrase()
|
||||
{
|
||||
if (data) {
|
||||
LOG(data->toString());
|
||||
} else {
|
||||
LOG("");
|
||||
}
|
||||
|
||||
if (data) {
|
||||
delete data;
|
||||
data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PhraseList AbstractFieldPhrase::operator |(const AbstractFieldPhrase &other) {
|
||||
return PhraseList(this, &other);
|
||||
}
|
||||
|
||||
ConditionalPhrase AbstractFieldPhrase::isNull()
|
||||
{
|
||||
return ConditionalPhrase(this, PhraseData::Null);
|
||||
}
|
||||
|
||||
|
||||
ConditionalPhrase AbstractFieldPhrase::operator ==(const ConditionalPhrase &other)
|
||||
{
|
||||
return ConditionalPhrase(this, PhraseData::Equal, const_cast<ConditionalPhrase&>(other));
|
||||
}
|
||||
|
||||
#define AbstractFieldPhraseOperatorVariant(class, op, cond) \
|
||||
ConditionalPhrase class::operator op(const QVariant &other) \
|
||||
{ \
|
||||
return ConditionalPhrase(this, cond, other); \
|
||||
}
|
||||
|
||||
AbstractFieldPhraseOperatorVariant(AbstractFieldPhrase, ==, PhraseData::Equal)
|
||||
AbstractFieldPhraseOperatorVariant(AbstractFieldPhrase, !=, PhraseData::NotEqual)
|
||||
|
||||
#define AbstractFieldPhraseOperatorField(op, cond) \
|
||||
ConditionalPhrase AbstractFieldPhrase::operator op(const AbstractFieldPhrase &other) \
|
||||
{ \
|
||||
return ConditionalPhrase(this, cond, other); \
|
||||
}
|
||||
|
||||
AbstractFieldPhraseOperatorField(==, PhraseData::Equal)
|
||||
AbstractFieldPhraseOperatorField(!=, PhraseData::NotEqual)
|
||||
AbstractFieldPhraseOperatorField(< , PhraseData::Less)
|
||||
AbstractFieldPhraseOperatorField(<=, PhraseData::LessEqual)
|
||||
AbstractFieldPhraseOperatorField(> , PhraseData::Greater)
|
||||
AbstractFieldPhraseOperatorField(>=, PhraseData::GreaterEqual)
|
||||
|
||||
AbstractFieldPhrase AbstractFieldPhrase::operator !()
|
||||
{
|
||||
//TODO: classname and s
|
||||
AbstractFieldPhrase f(data->className, data->fieldName);
|
||||
f.data = new PhraseData(data);
|
||||
f.data->isNot = !data->isNot;
|
||||
return f;
|
||||
}
|
||||
|
||||
AssignmentPhrase AbstractFieldPhrase::operator =(const QVariant &other)
|
||||
{
|
||||
return AssignmentPhrase(this, other);
|
||||
}
|
||||
|
||||
AssignmentPhrase AbstractFieldPhrase::operator <<(const QVariant &other)
|
||||
{
|
||||
return AssignmentPhrase(this, other);
|
||||
}
|
||||
|
||||
PhraseList::PhraseList() : isValid(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PhraseList::PhraseList(const AbstractFieldPhrase &other) : isValid(true)
|
||||
{
|
||||
data.append(other.data);
|
||||
}
|
||||
|
||||
PhraseList::PhraseList(AbstractFieldPhrase *left, const AbstractFieldPhrase *right)
|
||||
: isValid(true)
|
||||
{
|
||||
data.append(left->data);
|
||||
data.append(right->data);
|
||||
}
|
||||
|
||||
PhraseList::PhraseList(PhraseList *left, PhraseList *right) : isValid(true)
|
||||
{
|
||||
data = left->data;
|
||||
data.append(right->data);
|
||||
}
|
||||
|
||||
PhraseList::PhraseList(PhraseList *left, const AbstractFieldPhrase *right)
|
||||
: isValid(true)
|
||||
{
|
||||
data = left->data;
|
||||
data.append(right->data);
|
||||
}
|
||||
|
||||
PhraseList::~PhraseList()
|
||||
{
|
||||
data.clear();
|
||||
}
|
||||
|
||||
PhraseList PhraseList::operator |(const AbstractFieldPhrase &other) {
|
||||
return PhraseList(this, &other);
|
||||
}
|
||||
|
||||
PhraseList PhraseList::operator |(PhraseList &other) {
|
||||
return PhraseList(this, &other);
|
||||
}
|
||||
|
||||
AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, QVariant r)
|
||||
{
|
||||
data = new PhraseData(l->data, PhraseData::Equal, r);
|
||||
// l->data = 0;
|
||||
}
|
||||
|
||||
AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhrase *r)
|
||||
{
|
||||
data = new PhraseData(l->data, PhraseData::Equal, r->data);
|
||||
// l->data = 0;
|
||||
}
|
||||
|
||||
//AssignmentPhrase::AssignmentPhrase(AssignmentPhrase *l, const AssignmentPhrase *r)
|
||||
//{
|
||||
//// data = new PhraseData(l->data, PhraseData::Append, r->data);
|
||||
// qFatal("SS");
|
||||
//}
|
||||
|
||||
AssignmentPhraseList AssignmentPhrase::operator &(const AssignmentPhrase &other)
|
||||
{
|
||||
return AssignmentPhraseList(this, &other);
|
||||
}
|
||||
|
||||
AssignmentPhraseList::AssignmentPhraseList(const AssignmentPhrase &l)
|
||||
{
|
||||
data.append(l.data);
|
||||
}
|
||||
|
||||
AssignmentPhraseList::AssignmentPhraseList(AssignmentPhraseList *l, const AssignmentPhrase *r)
|
||||
{
|
||||
data.append(l->data);
|
||||
data.append(r->data);
|
||||
}
|
||||
|
||||
AssignmentPhraseList::AssignmentPhraseList(AssignmentPhrase *l, const AssignmentPhrase *r)
|
||||
{
|
||||
data.append(l->data);
|
||||
data.append(r->data);
|
||||
}
|
||||
|
||||
AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase &ph)
|
||||
{
|
||||
return AssignmentPhraseList(this, &ph);
|
||||
}
|
||||
|
||||
ConditionalPhrase::ConditionalPhrase()
|
||||
{
|
||||
this->data = 0;
|
||||
}
|
||||
|
||||
ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &other)
|
||||
{
|
||||
qDebug() << "************* ctor called:";
|
||||
this->data = new PhraseData(other.data);
|
||||
}
|
||||
|
||||
ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &&other)
|
||||
{
|
||||
qDebug() << "************* ctor called:";
|
||||
this->data = new PhraseData(other.data);
|
||||
}
|
||||
|
||||
ConditionalPhrase::ConditionalPhrase(const PhraseData *data)
|
||||
{
|
||||
this->data = new PhraseData(data);
|
||||
}
|
||||
|
||||
ConditionalPhrase::ConditionalPhrase(AbstractFieldPhrase *l,
|
||||
PhraseData::Condition cond)
|
||||
{
|
||||
data = new PhraseData(l->data, cond);
|
||||
}
|
||||
|
||||
ConditionalPhrase::ConditionalPhrase(AbstractFieldPhrase *l,
|
||||
PhraseData::Condition cond,
|
||||
const QVariant &v)
|
||||
{
|
||||
data = new PhraseData(l->data, cond, v);
|
||||
}
|
||||
|
||||
ConditionalPhrase::ConditionalPhrase(AbstractFieldPhrase *l,
|
||||
PhraseData::Condition cond,
|
||||
const AbstractFieldPhrase &other)
|
||||
{
|
||||
data = new PhraseData(l->data, cond, other.data);
|
||||
}
|
||||
|
||||
ConditionalPhrase::ConditionalPhrase(AbstractFieldPhrase *l,
|
||||
PhraseData::Condition cond,
|
||||
ConditionalPhrase &r)
|
||||
{
|
||||
data = new PhraseData(l->data, cond, r.data);
|
||||
r.data = 0;
|
||||
}
|
||||
|
||||
ConditionalPhrase::ConditionalPhrase(ConditionalPhrase *l,
|
||||
PhraseData::Condition cond,
|
||||
const AbstractFieldPhrase &r)
|
||||
{
|
||||
data = new PhraseData(l->data, cond, r.data);
|
||||
l->data = 0;
|
||||
}
|
||||
|
||||
ConditionalPhrase::ConditionalPhrase(ConditionalPhrase *l,
|
||||
PhraseData::Condition cond,
|
||||
const QVariant &r)
|
||||
{
|
||||
data = new PhraseData(l->data, cond, r);
|
||||
l->data = 0;
|
||||
}
|
||||
|
||||
ConditionalPhrase::ConditionalPhrase(ConditionalPhrase *l,
|
||||
PhraseData::Condition cond,
|
||||
ConditionalPhrase &r)
|
||||
{
|
||||
data = new PhraseData(l->data, cond, r.data);
|
||||
l->data = 0;
|
||||
r.data = 0;
|
||||
}
|
||||
|
||||
ConditionalPhrase::~ConditionalPhrase()
|
||||
{
|
||||
LOG("");
|
||||
if (data)
|
||||
delete data;
|
||||
}
|
||||
|
||||
ConditionalPhrase ConditionalPhrase::operator =(const ConditionalPhrase &other)
|
||||
{
|
||||
return ConditionalPhrase(other.data);
|
||||
const_cast<ConditionalPhrase&>(other).data = 0;
|
||||
}
|
||||
|
||||
ConditionalPhrase ConditionalPhrase::operator ==(const QVariant &other)
|
||||
{
|
||||
return ConditionalPhrase(this, PhraseData::Equal, other);
|
||||
}
|
||||
|
||||
ConditionalPhrase ConditionalPhrase::operator ==(const AbstractFieldPhrase &other)
|
||||
{
|
||||
return ConditionalPhrase(this, PhraseData::Equal, other);
|
||||
}
|
||||
|
||||
ConditionalPhrase ConditionalPhrase::operator &&(const ConditionalPhrase &other)
|
||||
{
|
||||
return ConditionalPhrase(this, PhraseData::And,
|
||||
const_cast<ConditionalPhrase&>(other));
|
||||
}
|
||||
|
||||
ConditionalPhrase ConditionalPhrase::operator ||(const ConditionalPhrase &other)
|
||||
{
|
||||
return ConditionalPhrase(this, PhraseData::Or,
|
||||
const_cast<ConditionalPhrase&>(other));
|
||||
}
|
||||
|
||||
ConditionalPhrase ConditionalPhrase::operator !()
|
||||
{
|
||||
ConditionalPhrase f(data);
|
||||
f.data->isNot = !data->isNot;
|
||||
return f;
|
||||
}
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,391 @@
|
|||
/**************************************************************************
|
||||
**
|
||||
** 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
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <QtGlobal>
|
||||
#if __cplusplus >= 201103L
|
||||
# include <initializer_list>
|
||||
#endif
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
NUT_BEGIN_NAMESPACE
|
||||
|
||||
#define SPECIALIZATION_NUMERIC_MEMBER(type, op, cond) \
|
||||
ConditionalPhrase operator op(const QVariant &other) \
|
||||
{ \
|
||||
return ConditionalPhrase(this, cond, other); \
|
||||
}
|
||||
|
||||
class AbstractFieldPhrase;
|
||||
class AssignmentPhrase;
|
||||
class PhraseList;
|
||||
|
||||
class PhraseData
|
||||
{
|
||||
public:
|
||||
enum Condition {
|
||||
NotAssign = 0,
|
||||
Equal,
|
||||
Less,
|
||||
LessEqual,
|
||||
Null,
|
||||
In,
|
||||
Like,
|
||||
|
||||
Not = 10,
|
||||
NotEqual,
|
||||
GreaterEqual,
|
||||
Greater,
|
||||
NotNull,
|
||||
NotIn,
|
||||
NotLike,
|
||||
|
||||
And = 20,
|
||||
Or,
|
||||
|
||||
// Append,
|
||||
// Set,
|
||||
|
||||
Add,
|
||||
Minus,
|
||||
Multiple,
|
||||
Divide,
|
||||
Mod,
|
||||
|
||||
Between,
|
||||
|
||||
//date and time
|
||||
AddYears,
|
||||
AddMonths,
|
||||
AddDays,
|
||||
AddHours,
|
||||
AddMinutes,
|
||||
AddSeconds
|
||||
// // special types
|
||||
// Distance
|
||||
};
|
||||
|
||||
enum Type { Field, WithVariant, WithOther, WithoutOperand };
|
||||
|
||||
const char *className;
|
||||
const char *fieldName;
|
||||
|
||||
Type type;
|
||||
Condition operatorCond;
|
||||
|
||||
const PhraseData *left;
|
||||
const PhraseData *right;
|
||||
|
||||
QVariant operand;
|
||||
bool isNot;
|
||||
|
||||
PhraseData(const char *className, const char *fieldName);
|
||||
PhraseData(PhraseData *l, Condition o);
|
||||
PhraseData(PhraseData *l, Condition o, const PhraseData *r);
|
||||
PhraseData(PhraseData *l, Condition o, QVariant r);
|
||||
|
||||
PhraseData(const PhraseData *other);
|
||||
|
||||
QString toString() const;
|
||||
|
||||
~PhraseData();
|
||||
};
|
||||
|
||||
class AssignmentPhraseList
|
||||
{
|
||||
public:
|
||||
QList<PhraseData*> data;
|
||||
AssignmentPhraseList(const AssignmentPhrase &l);
|
||||
AssignmentPhraseList(AssignmentPhraseList *l, const AssignmentPhrase *r);
|
||||
AssignmentPhraseList(AssignmentPhrase *l, const AssignmentPhrase *r);
|
||||
|
||||
AssignmentPhraseList operator &(const AssignmentPhrase &ph);
|
||||
};
|
||||
|
||||
class AssignmentPhrase
|
||||
{
|
||||
public:
|
||||
PhraseData *data;
|
||||
AssignmentPhrase(AbstractFieldPhrase *l, QVariant r);
|
||||
AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhrase *r);
|
||||
// AssignmentPhrase(AssignmentPhrase *l, const AssignmentPhrase *r);
|
||||
|
||||
AssignmentPhraseList operator &(const AssignmentPhrase &other);
|
||||
|
||||
};
|
||||
|
||||
class PhraseList{
|
||||
public:
|
||||
bool isValid;
|
||||
QList<const PhraseData*> data;
|
||||
PhraseList();
|
||||
PhraseList(const AbstractFieldPhrase &other);
|
||||
PhraseList(AbstractFieldPhrase *left, const AbstractFieldPhrase *right);
|
||||
PhraseList(PhraseList *left, PhraseList *right);
|
||||
PhraseList(PhraseList *left, const AbstractFieldPhrase *right);
|
||||
virtual ~PhraseList();
|
||||
|
||||
PhraseList operator |(PhraseList &other);
|
||||
PhraseList operator |(const AbstractFieldPhrase &other);
|
||||
};
|
||||
|
||||
class ConditionalPhrase
|
||||
{
|
||||
public:
|
||||
PhraseData *data;
|
||||
QSharedPointer<PhraseData> leftDataPointer;
|
||||
QSharedPointer<PhraseData> rightDataPointer;
|
||||
ConditionalPhrase();
|
||||
ConditionalPhrase(const ConditionalPhrase &other);
|
||||
ConditionalPhrase(const ConditionalPhrase &&other);
|
||||
ConditionalPhrase(const PhraseData *data);
|
||||
ConditionalPhrase(AbstractFieldPhrase *, PhraseData::Condition);
|
||||
ConditionalPhrase(AbstractFieldPhrase *, PhraseData::Condition, const QVariant &v);
|
||||
ConditionalPhrase(AbstractFieldPhrase *, PhraseData::Condition, const AbstractFieldPhrase &v);
|
||||
ConditionalPhrase(AbstractFieldPhrase *l, PhraseData::Condition cond, ConditionalPhrase &r);
|
||||
ConditionalPhrase(ConditionalPhrase *l, PhraseData::Condition cond, const AbstractFieldPhrase &r);
|
||||
ConditionalPhrase(ConditionalPhrase *l, PhraseData::Condition cond, const QVariant &r);
|
||||
ConditionalPhrase(ConditionalPhrase *l, PhraseData::Condition cond, ConditionalPhrase &r);
|
||||
virtual ~ConditionalPhrase();
|
||||
|
||||
ConditionalPhrase operator =(const ConditionalPhrase &other);
|
||||
ConditionalPhrase operator ==(const QVariant &other);
|
||||
ConditionalPhrase operator ==(const AbstractFieldPhrase &other);
|
||||
ConditionalPhrase operator &&(const ConditionalPhrase &other);
|
||||
ConditionalPhrase operator ||(const ConditionalPhrase &other);
|
||||
ConditionalPhrase operator !();
|
||||
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, <, PhraseData::Less)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, <=, PhraseData::LessEqual)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, >, PhraseData::Greater)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, >=, PhraseData::GreaterEqual)
|
||||
};
|
||||
|
||||
class AbstractFieldPhrase
|
||||
{
|
||||
public:
|
||||
PhraseData *data;
|
||||
AbstractFieldPhrase(const char *className, const char *fieldName);
|
||||
AbstractFieldPhrase(const AbstractFieldPhrase &other);
|
||||
|
||||
virtual ~AbstractFieldPhrase();
|
||||
|
||||
PhraseList operator |(const AbstractFieldPhrase &other);
|
||||
|
||||
template<typename T>
|
||||
ConditionalPhrase in(QList<T> list)
|
||||
{
|
||||
QVariantList vlist;
|
||||
foreach (T t, list)
|
||||
vlist.append(QVariant::fromValue(t));
|
||||
|
||||
return ConditionalPhrase(this, PhraseData::In, vlist);
|
||||
}
|
||||
#if __cplusplus >= 201103L
|
||||
ConditionalPhrase in(std::initializer_list<int> list) {
|
||||
QVariantList vlist;
|
||||
std::initializer_list<int>::iterator it;
|
||||
for (it = list.begin(); it != list.end(); ++it)
|
||||
vlist.append(*it);
|
||||
return ConditionalPhrase(this, PhraseData::In, vlist);
|
||||
}
|
||||
#endif
|
||||
|
||||
ConditionalPhrase isNull();
|
||||
|
||||
ConditionalPhrase operator ==(const QVariant &other);
|
||||
ConditionalPhrase operator ==(const ConditionalPhrase &other);
|
||||
ConditionalPhrase operator !=(const QVariant &other);
|
||||
|
||||
ConditionalPhrase operator ==(const AbstractFieldPhrase &other);
|
||||
ConditionalPhrase operator !=(const AbstractFieldPhrase &other);
|
||||
ConditionalPhrase operator <(const AbstractFieldPhrase &other);
|
||||
ConditionalPhrase operator >(const AbstractFieldPhrase &other);
|
||||
ConditionalPhrase operator <=(const AbstractFieldPhrase &other);
|
||||
ConditionalPhrase operator >=(const AbstractFieldPhrase &other);
|
||||
|
||||
AbstractFieldPhrase operator !();
|
||||
AssignmentPhrase operator =(const QVariant &other);
|
||||
AssignmentPhrase operator <<(const QVariant &other);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class FieldPhrase : public AbstractFieldPhrase
|
||||
{
|
||||
public:
|
||||
FieldPhrase(const char *className, const char *s) :
|
||||
AbstractFieldPhrase(className, s)
|
||||
{}
|
||||
|
||||
AssignmentPhrase operator =(const QVariant &other) {
|
||||
return AssignmentPhrase(this, other);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class FieldPhrase<QString> : public AbstractFieldPhrase
|
||||
{
|
||||
public:
|
||||
FieldPhrase(const char *className, const char *s) :
|
||||
AbstractFieldPhrase(className, s)
|
||||
{}
|
||||
|
||||
ConditionalPhrase like(const QString &term) {
|
||||
return ConditionalPhrase(this, PhraseData::Like, term);
|
||||
}
|
||||
|
||||
AssignmentPhrase operator =(const QVariant &other) {
|
||||
return AssignmentPhrase(this, other);
|
||||
}
|
||||
};
|
||||
|
||||
#define SPECIALIZATION_NUMERIC(type) \
|
||||
template<> \
|
||||
class FieldPhrase<type> : public AbstractFieldPhrase \
|
||||
{ \
|
||||
public: \
|
||||
FieldPhrase(const char *className, const char *s) : \
|
||||
AbstractFieldPhrase(className, s) \
|
||||
{} \
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, <, PhraseData::Less) \
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, <=, PhraseData::LessEqual) \
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, >, PhraseData::Greater) \
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, >=, PhraseData::GreaterEqual) \
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, %, PhraseData::Mod) \
|
||||
\
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, +, PhraseData::Add) \
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, -, PhraseData::Minus) \
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, *, PhraseData::Multiple) \
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, /, PhraseData::Divide) \
|
||||
AssignmentPhrase operator =(const QVariant &other) { \
|
||||
return AssignmentPhrase(this, other); \
|
||||
} \
|
||||
ConditionalPhrase between(const QVariant &min, const QVariant &max) \
|
||||
{ \
|
||||
return ConditionalPhrase(this, PhraseData::Between, \
|
||||
QVariantList() << min << max); \
|
||||
} \
|
||||
};
|
||||
|
||||
SPECIALIZATION_NUMERIC(qint8)
|
||||
SPECIALIZATION_NUMERIC(qint16)
|
||||
SPECIALIZATION_NUMERIC(qint32)
|
||||
SPECIALIZATION_NUMERIC(qint64)
|
||||
|
||||
SPECIALIZATION_NUMERIC(quint8)
|
||||
SPECIALIZATION_NUMERIC(quint16)
|
||||
SPECIALIZATION_NUMERIC(quint32)
|
||||
SPECIALIZATION_NUMERIC(quint64)
|
||||
|
||||
SPECIALIZATION_NUMERIC(qreal)
|
||||
|
||||
//Date and time
|
||||
#define CONDITIONAL_VARIANT_METHOD(name, cond) \
|
||||
ConditionalPhrase name(int val) \
|
||||
{ \
|
||||
return ConditionalPhrase(this, cond, val); \
|
||||
}
|
||||
|
||||
template<>
|
||||
class FieldPhrase<QDate> : public AbstractFieldPhrase
|
||||
{
|
||||
public:
|
||||
FieldPhrase(const char *className, const char *s) :
|
||||
AbstractFieldPhrase(className, s)
|
||||
{}
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, <, PhraseData::Less)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, <=, PhraseData::LessEqual)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, >, PhraseData::Greater)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, >=, PhraseData::GreaterEqual)
|
||||
AssignmentPhrase operator =(const QDate &other) {
|
||||
return AssignmentPhrase(this, other);
|
||||
}
|
||||
ConditionalPhrase between(const QDate &min, const QDate &max)
|
||||
{
|
||||
return ConditionalPhrase(this, PhraseData::Between,
|
||||
QVariantList() << min << max);
|
||||
}
|
||||
CONDITIONAL_VARIANT_METHOD(addYears, PhraseData::AddYears)
|
||||
CONDITIONAL_VARIANT_METHOD(addMonths, PhraseData::AddMonths)
|
||||
CONDITIONAL_VARIANT_METHOD(addDays, PhraseData::AddDays)
|
||||
};
|
||||
|
||||
template<>
|
||||
class FieldPhrase<QTime> : public AbstractFieldPhrase
|
||||
{
|
||||
public:
|
||||
FieldPhrase(const char *className, const char *s) :
|
||||
AbstractFieldPhrase(className, s)
|
||||
{}
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, <, PhraseData::Less)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, <=, PhraseData::LessEqual)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, >, PhraseData::Greater)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, >=, PhraseData::GreaterEqual)
|
||||
AssignmentPhrase operator =(const QTime &other) {
|
||||
return AssignmentPhrase(this, other);
|
||||
}
|
||||
ConditionalPhrase between(const QTime &min, const QTime &max)
|
||||
{
|
||||
return ConditionalPhrase(this, PhraseData::Between,
|
||||
QVariantList() << min << max);
|
||||
}
|
||||
|
||||
CONDITIONAL_VARIANT_METHOD(addHours, PhraseData::AddHours)
|
||||
CONDITIONAL_VARIANT_METHOD(addMinutes, PhraseData::AddMinutes)
|
||||
CONDITIONAL_VARIANT_METHOD(addSeconds, PhraseData::AddSeconds)
|
||||
};
|
||||
|
||||
template<>
|
||||
class FieldPhrase<QDateTime> : public AbstractFieldPhrase
|
||||
{
|
||||
public:
|
||||
FieldPhrase(const char *className, const char *s) :
|
||||
AbstractFieldPhrase(className, s)
|
||||
{}
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, <, PhraseData::Less)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, <=, PhraseData::LessEqual)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, >, PhraseData::Greater)
|
||||
SPECIALIZATION_NUMERIC_MEMBER(type, >=, PhraseData::GreaterEqual)
|
||||
AssignmentPhrase operator =(const QDateTime &other) {
|
||||
return AssignmentPhrase(this, other);
|
||||
}
|
||||
ConditionalPhrase between(const QDateTime &min, const QDateTime &max)
|
||||
{
|
||||
return ConditionalPhrase(this, PhraseData::Between,
|
||||
QVariantList() << min << max);
|
||||
}
|
||||
CONDITIONAL_VARIANT_METHOD(addYears, PhraseData::AddYears)
|
||||
CONDITIONAL_VARIANT_METHOD(addMonths, PhraseData::AddMonths)
|
||||
CONDITIONAL_VARIANT_METHOD(addDays, PhraseData::AddDays)
|
||||
|
||||
CONDITIONAL_VARIANT_METHOD(addHours, PhraseData::AddHours)
|
||||
CONDITIONAL_VARIANT_METHOD(addMinutes, PhraseData::AddMinutes)
|
||||
CONDITIONAL_VARIANT_METHOD(addSeconds, PhraseData::AddSeconds)
|
||||
};
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
||||
#endif // PHRASE_H
|
||||
129
src/query.h
129
src/query.h
|
|
@ -36,7 +36,7 @@
|
|||
#include "tablesetbase_p.h"
|
||||
#include "generators/sqlgeneratorbase_p.h"
|
||||
#include "querybase_p.h"
|
||||
#include "wherephrase.h"
|
||||
#include "phrase.h"
|
||||
#include "tablemodel.h"
|
||||
|
||||
NUT_BEGIN_NAMESPACE
|
||||
|
|
@ -54,7 +54,6 @@ public:
|
|||
~Query();
|
||||
|
||||
//ddl
|
||||
Query<T> *setWhere(WherePhrase where);
|
||||
|
||||
Query<T> *join(const QString &className);
|
||||
Query<T> *join(Table *c);
|
||||
|
|
@ -69,8 +68,11 @@ public:
|
|||
// Query<T> *orderBy(QString fieldName, QString type);
|
||||
Query<T> *skip(int n);
|
||||
Query<T> *take(int n);
|
||||
Query<T> *fields(WherePhrase phrase);
|
||||
Query<T> *orderBy(WherePhrase phrase);
|
||||
Query<T> *fields(const PhraseList &ph);
|
||||
Query<T> *orderBy(const PhraseList &ph);
|
||||
Query<T> *where(const ConditionalPhrase &ph);
|
||||
Query<T> *setWhere(const ConditionalPhrase &ph);
|
||||
|
||||
Query<T> *include(TableSetBase *t);
|
||||
Query<T> *include(Table *t);
|
||||
|
||||
|
|
@ -85,7 +87,8 @@ public:
|
|||
QVariant average(const FieldPhrase<int> &f);
|
||||
|
||||
//data mailpulation
|
||||
int update(WherePhrase phrase);
|
||||
int update(const AssignmentPhraseList &ph);
|
||||
// int insert(const AssignmentPhraseList &ph);
|
||||
int remove();
|
||||
|
||||
QSqlQueryModel *toModal();
|
||||
|
|
@ -122,6 +125,7 @@ Q_OUTOFLINE_TEMPLATE Query<T>::~Query()
|
|||
{
|
||||
Q_D(Query);
|
||||
delete d;
|
||||
qDebug() << "~Query";
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
|
@ -133,10 +137,9 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
|
|||
d->select = "*";
|
||||
|
||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||
SqlGeneratorBase::SelectAll, "",
|
||||
d->tableName,
|
||||
d->wheres, d->orderPhrases, d->relations,
|
||||
d->skip, d->take);
|
||||
d->tableName, d->fieldPhrase, d->wherePhrase, d->orderPhrase,
|
||||
d->relations, d->skip, d->take);
|
||||
|
||||
QSqlQuery q = d->database->exec(d->sql);
|
||||
if (q.lastError().isValid()) {
|
||||
qDebug() << q.lastError().text();
|
||||
|
|
@ -300,9 +303,11 @@ Q_OUTOFLINE_TEMPLATE QList<F> Query<T>::select(const FieldPhrase<F> f)
|
|||
|
||||
d->joins.prepend(d->tableName);
|
||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||
SqlGeneratorBase::SignleField, f.data()->text,
|
||||
d->tableName, d->wheres,
|
||||
d->orderPhrases, d->relations, d->skip, d->take);
|
||||
d->tableName,
|
||||
SqlGeneratorBase::SignleField, f.data->toString(),
|
||||
d->wherePhrase,
|
||||
d->relations,
|
||||
d->skip, d->take);
|
||||
|
||||
QSqlQuery q = d->database->exec(d->sql);
|
||||
|
||||
|
|
@ -336,12 +341,12 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::count()
|
|||
|
||||
d->joins.prepend(d->tableName);
|
||||
d->select = "COUNT(*)";
|
||||
d->sql = d->database->sqlGenertor()->selectCommand(SqlGeneratorBase::Count,
|
||||
QStringLiteral("*"),
|
||||
d->tableName,
|
||||
d->wheres,
|
||||
d->orderPhrases,
|
||||
d->relations);
|
||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||
d->tableName,
|
||||
SqlGeneratorBase::Count,
|
||||
QStringLiteral("*"),
|
||||
d->wherePhrase,
|
||||
d->relations);
|
||||
QSqlQuery q = d->database->exec(d->sql);
|
||||
|
||||
if (q.next())
|
||||
|
|
@ -356,8 +361,9 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(const FieldPhrase<int> &f)
|
|||
|
||||
d->joins.prepend(d->tableName);
|
||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||
SqlGeneratorBase::Max, f.data()->text, d->tableName,
|
||||
d->wheres, d->orderPhrases,
|
||||
d->tableName,
|
||||
SqlGeneratorBase::Max, f.data->toString(),
|
||||
d->wherePhrase,
|
||||
d->relations);
|
||||
QSqlQuery q = d->database->exec(d->sql);
|
||||
|
||||
|
|
@ -373,8 +379,9 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(const FieldPhrase<int> &f)
|
|||
|
||||
d->joins.prepend(d->tableName);
|
||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||
SqlGeneratorBase::Min, f.data()->text, d->tableName,
|
||||
d->wheres, d->orderPhrases,
|
||||
d->tableName,
|
||||
SqlGeneratorBase::Min, f.data->toString(),
|
||||
d->wherePhrase,
|
||||
d->relations);
|
||||
QSqlQuery q = d->database->exec(d->sql);
|
||||
|
||||
|
|
@ -390,8 +397,9 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::average(const FieldPhrase<int> &f)
|
|||
|
||||
d->joins.prepend(d->tableName);
|
||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||
SqlGeneratorBase::Average, f.data()->text, d->tableName,
|
||||
d->wheres, d->orderPhrases,
|
||||
d->tableName,
|
||||
SqlGeneratorBase::Average, f.data->toString(),
|
||||
d->wherePhrase,
|
||||
d->relations);
|
||||
QSqlQuery q = d->database->exec(d->sql);
|
||||
|
||||
|
|
@ -430,10 +438,18 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::join(Table *c)
|
|||
}
|
||||
|
||||
template <class T>
|
||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::setWhere(WherePhrase where)
|
||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::where(const ConditionalPhrase &ph)
|
||||
{
|
||||
Q_D(Query);
|
||||
d->wheres.append(where);
|
||||
d->wherePhrase = d->wherePhrase && ph;
|
||||
return this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::setWhere(const ConditionalPhrase &ph)
|
||||
{
|
||||
Q_D(Query);
|
||||
d->wherePhrase = ph;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -454,10 +470,10 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::take(int n)
|
|||
}
|
||||
|
||||
template<class T>
|
||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::fields(WherePhrase phrase)
|
||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::fields(const PhraseList &ph)
|
||||
{
|
||||
Q_D(Query);
|
||||
d->fields.append(phrase);
|
||||
d->fieldPhrase = ph;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -471,10 +487,10 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::fields(WherePhrase phrase)
|
|||
//}
|
||||
|
||||
template <class T>
|
||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(WherePhrase phrase)
|
||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(const PhraseList &ph)
|
||||
{
|
||||
Q_D(Query);
|
||||
d->orderPhrases.append(phrase);
|
||||
d->orderPhrase = ph;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -493,12 +509,14 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::include(Table *t)
|
|||
}
|
||||
|
||||
template <class T>
|
||||
Q_OUTOFLINE_TEMPLATE int Query<T>::update(WherePhrase phrase)
|
||||
Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph)
|
||||
{
|
||||
Q_D(Query);
|
||||
|
||||
d->sql = d->database->sqlGenertor()->updateCommand(phrase, d->wheres,
|
||||
d->tableName);
|
||||
d->sql = d->database->sqlGenertor()->updateCommand(
|
||||
d->tableName,
|
||||
ph,
|
||||
d->wherePhrase);
|
||||
QSqlQuery q = d->database->exec(d->sql);
|
||||
|
||||
if (m_autoDelete)
|
||||
|
|
@ -511,7 +529,8 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::remove()
|
|||
{
|
||||
Q_D(Query);
|
||||
|
||||
d->sql = d->database->sqlGenertor()->deleteCommand(d->wheres, d->tableName);
|
||||
d->sql = d->database->sqlGenertor()->deleteCommand(
|
||||
d->tableName, d->wherePhrase);
|
||||
QSqlQuery q = d->database->exec(d->sql);
|
||||
|
||||
if (m_autoDelete)
|
||||
|
|
@ -522,32 +541,32 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::remove()
|
|||
template <class T>
|
||||
Q_OUTOFLINE_TEMPLATE QSqlQueryModel *Query<T>::toModal()
|
||||
{
|
||||
Q_D(Query);
|
||||
// Q_D(Query);
|
||||
|
||||
|
||||
QString fff = "";
|
||||
// QString fff = "";
|
||||
|
||||
foreach (WherePhrase p, d->fields) {
|
||||
if (fff != "")
|
||||
fff.append(", ");
|
||||
fff.append(d->database->sqlGenertor()->phraseOrder(p.data()));
|
||||
}
|
||||
// foreach (WherePhrase p, d->fields) {
|
||||
// if (fff != "")
|
||||
// fff.append(", ");
|
||||
// fff.append(d->database->sqlGenertor()->phraseOrder(p.data()));
|
||||
// }
|
||||
|
||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||
SqlGeneratorBase::SelectAll, "",
|
||||
d->tableName,
|
||||
d->wheres, d->orderPhrases, d->relations,
|
||||
d->skip, d->take);
|
||||
qDebug()<<"Model to" << fff;
|
||||
QSqlQueryModel *model = new QSqlQueryModel;
|
||||
TableModel *tableModel = d->database->model().tableByName(d->tableName);
|
||||
model->setQuery(d->sql, d->database->database());
|
||||
// d->sql = d->database->sqlGenertor()->selectCommand(
|
||||
// SqlGeneratorBase::SelectAll, "",
|
||||
// d->tableName,
|
||||
// d->wheres, d->orderPhrases, d->relations,
|
||||
// d->skip, d->take);
|
||||
// qDebug()<<"Model to" << fff;
|
||||
// QSqlQueryModel *model = new QSqlQueryModel;
|
||||
// TableModel *tableModel = d->database->model().tableByName(d->tableName);
|
||||
// model->setQuery(d->sql, d->database->database());
|
||||
|
||||
int fieldIndex = 0;
|
||||
foreach (FieldModel *f, tableModel->fields()) {
|
||||
model->setHeaderData(fieldIndex++, Qt::Horizontal, f->displayName);
|
||||
}
|
||||
return model;
|
||||
// int fieldIndex = 0;
|
||||
// foreach (FieldModel *f, tableModel->fields()) {
|
||||
// model->setHeaderData(fieldIndex++, Qt::Horizontal, f->displayName);
|
||||
// }
|
||||
// return model;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#ifndef QUERY_P_H
|
||||
#define QUERY_P_H
|
||||
|
||||
#include "wherephrase.h"
|
||||
#include "phrase.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
|
@ -48,12 +48,15 @@ public:
|
|||
TableSetBase *tableSet;
|
||||
QStringList joins;
|
||||
QList<RelationModel*> relations;
|
||||
QList<WherePhrase> wheres;
|
||||
QList<WherePhrase> orderPhrases;
|
||||
QList<WherePhrase> fields;
|
||||
QHash<QString, QString> orders;
|
||||
int skip;
|
||||
int take;
|
||||
PhraseList orderPhrase, fieldPhrase;
|
||||
ConditionalPhrase wherePhrase;
|
||||
|
||||
// QList<WherePhrase> wheres;
|
||||
// QList<WherePhrase> orderPhrases;
|
||||
// QList<WherePhrase> fields;
|
||||
// QHash<QString, QString> orders;
|
||||
};
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "tablemodel.h"
|
||||
#include "defines.h"
|
||||
#include "wherephrase.h"
|
||||
#include "phrase.h"
|
||||
|
||||
NUT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include <QDataStream>
|
||||
#include <QDebug>
|
||||
|
||||
#include "wherephrase.h"
|
||||
#include "phrase.h"
|
||||
|
||||
NUT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef PHRASE_H
|
||||
#define PHRASE_H
|
||||
#ifndef WHEREPHRASE_H
|
||||
#define WHEREPHRASE_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
|
|
@ -39,58 +39,58 @@
|
|||
NUT_BEGIN_NAMESPACE
|
||||
|
||||
class SqlGeneratorBase;
|
||||
class PhraseData
|
||||
{
|
||||
public:
|
||||
enum Condition {
|
||||
NotAssign = 0,
|
||||
Equal,
|
||||
Less,
|
||||
LessEqual,
|
||||
Null,
|
||||
In,
|
||||
Like,
|
||||
//class PhraseData
|
||||
//{
|
||||
//public:
|
||||
// enum Condition {
|
||||
// NotAssign = 0,
|
||||
// Equal,
|
||||
// Less,
|
||||
// LessEqual,
|
||||
// Null,
|
||||
// In,
|
||||
// Like,
|
||||
|
||||
Not = 10,
|
||||
NotEqual,
|
||||
GreaterEqual,
|
||||
Greater,
|
||||
NotNull,
|
||||
NotIn,
|
||||
NotLike,
|
||||
// Not = 10,
|
||||
// NotEqual,
|
||||
// GreaterEqual,
|
||||
// Greater,
|
||||
// NotNull,
|
||||
// NotIn,
|
||||
// NotLike,
|
||||
|
||||
And = 20,
|
||||
Or,
|
||||
// And = 20,
|
||||
// Or,
|
||||
|
||||
Append,
|
||||
Set,
|
||||
// Append,
|
||||
// Set,
|
||||
|
||||
Add,
|
||||
Minus,
|
||||
Multiple,
|
||||
Divide,
|
||||
// Add,
|
||||
// Minus,
|
||||
// Multiple,
|
||||
// Divide,
|
||||
|
||||
// special types
|
||||
Distance
|
||||
};
|
||||
// // special types
|
||||
// Distance
|
||||
// };
|
||||
|
||||
enum Type { Field, WithVariant, WithOther, WithoutOperand };
|
||||
Type type;
|
||||
// enum Type { Field, WithVariant, WithOther, WithoutOperand };
|
||||
// Type type;
|
||||
|
||||
Condition operatorCond;
|
||||
// Condition operatorCond;
|
||||
|
||||
QString text;
|
||||
const PhraseData *left;
|
||||
const PhraseData *right;
|
||||
QVariant operand;
|
||||
// QString text;
|
||||
// const PhraseData *left;
|
||||
// const PhraseData *right;
|
||||
// QVariant operand;
|
||||
|
||||
PhraseData(const char *className, const char *s);
|
||||
PhraseData(PhraseData *l, Condition o);
|
||||
PhraseData(PhraseData *l, Condition o, const PhraseData *r);
|
||||
PhraseData(PhraseData *l, Condition o, QVariant r);
|
||||
// PhraseData(const char *className, const char *s);
|
||||
// PhraseData(PhraseData *l, Condition o);
|
||||
// PhraseData(PhraseData *l, Condition o, const PhraseData *r);
|
||||
// PhraseData(PhraseData *l, Condition o, QVariant r);
|
||||
|
||||
~PhraseData();
|
||||
};
|
||||
// ~PhraseData();
|
||||
//};
|
||||
|
||||
class WherePhrase
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ void MainTest::initTestCase()
|
|||
|
||||
bool ok = db.open();
|
||||
|
||||
db.comments()->query()->remove();
|
||||
db.posts()->query()->remove();
|
||||
db.commentTable()->query()->remove();
|
||||
db.postTable()->query()->remove();
|
||||
|
||||
QTEST_ASSERT(ok);
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ void MainTest::createUser()
|
|||
user = new User;
|
||||
user->setUsername("admin");
|
||||
user->setPassword("123456");
|
||||
db.users()->append(user);
|
||||
db.userTable()->append(user);
|
||||
db.saveChanges();
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ void MainTest::createPost()
|
|||
newPost->setTitle("post title");
|
||||
newPost->setSaveDate(QDateTime::currentDateTime());
|
||||
|
||||
db.posts()->append(newPost);
|
||||
db.postTable()->append(newPost);
|
||||
|
||||
for(int i = 0 ; i < 3; i++){
|
||||
Comment *comment = new Comment;
|
||||
|
|
@ -102,7 +102,7 @@ void MainTest::createPost2()
|
|||
newPost->setTitle("post title");
|
||||
newPost->setSaveDate(QDateTime::currentDateTime());
|
||||
|
||||
db.posts()->append(newPost);
|
||||
db.postTable()->append(newPost);
|
||||
db.saveChanges();
|
||||
|
||||
for(int i = 0 ; i < 3; i++){
|
||||
|
|
@ -111,7 +111,7 @@ void MainTest::createPost2()
|
|||
comment->setSaveDate(QDateTime::currentDateTime());
|
||||
comment->setAuthor(user);
|
||||
comment->setPostId(newPost->id());
|
||||
db.comments()->append(comment);
|
||||
db.commentTable()->append(comment);
|
||||
}
|
||||
db.saveChanges();
|
||||
|
||||
|
|
@ -121,9 +121,9 @@ void MainTest::createPost2()
|
|||
|
||||
void MainTest::selectPosts()
|
||||
{
|
||||
auto q = db.posts()->query()
|
||||
auto q = db.postTable()->query()
|
||||
->join<Comment>()//Comment::authorIdField() == Post::idField())
|
||||
->orderBy(!Post::saveDateField() & Post::bodyField())
|
||||
->orderBy(!Post::saveDateField() | Post::bodyField())
|
||||
->setWhere(Post::idField() == postId);
|
||||
|
||||
auto posts = q->toList();
|
||||
|
|
@ -144,7 +144,7 @@ void MainTest::selectPosts()
|
|||
|
||||
void MainTest::selectScoreAverage()
|
||||
{
|
||||
auto a = db.scores()->query()
|
||||
auto a = db.scoreTable()->query()
|
||||
->join<Post>()
|
||||
->setWhere(Post::idField() == 1)
|
||||
->average(Score::scoreField());
|
||||
|
|
@ -153,7 +153,7 @@ void MainTest::selectScoreAverage()
|
|||
|
||||
void MainTest::selectFirst()
|
||||
{
|
||||
auto posts = db.posts()->query()
|
||||
auto posts = db.postTable()->query()
|
||||
->first();
|
||||
|
||||
QTEST_ASSERT(posts != Q_NULLPTR);
|
||||
|
|
@ -161,7 +161,7 @@ void MainTest::selectFirst()
|
|||
|
||||
void MainTest::selectPostsWithoutTitle()
|
||||
{
|
||||
auto q = db.posts()->query();
|
||||
auto q = db.postTable()->query();
|
||||
q->setWhere(Post::titleField().isNull());
|
||||
auto count = q->count();
|
||||
QTEST_ASSERT(count == 0);
|
||||
|
|
@ -169,8 +169,9 @@ void MainTest::selectPostsWithoutTitle()
|
|||
|
||||
void MainTest::selectPostIds()
|
||||
{
|
||||
auto ids = db.posts()->query()->select(Post::idField());
|
||||
|
||||
auto q = db.postTable()->query();
|
||||
auto ids = q->select(Post::idField());
|
||||
qDebug() << q->sqlCommand();
|
||||
QTEST_ASSERT(ids.count() == 2);
|
||||
}
|
||||
|
||||
|
|
@ -184,11 +185,11 @@ void MainTest::testDate()
|
|||
newPost->setTitle("post title");
|
||||
newPost->setSaveDate(d);
|
||||
|
||||
db.posts()->append(newPost);
|
||||
db.postTable()->append(newPost);
|
||||
|
||||
db.saveChanges();
|
||||
|
||||
auto q = db.posts()->query()
|
||||
auto q = db.postTable()->query()
|
||||
->setWhere(Post::idField() == newPost->id())
|
||||
->first();
|
||||
|
||||
|
|
@ -198,7 +199,7 @@ void MainTest::testDate()
|
|||
void MainTest::join()
|
||||
{
|
||||
TIC();
|
||||
auto q = db.comments()->query()
|
||||
auto q = db.commentTable()->query()
|
||||
->join<User>()
|
||||
->join<Post>();
|
||||
|
||||
|
|
@ -213,14 +214,14 @@ void MainTest::join()
|
|||
|
||||
void MainTest::selectWithInvalidRelation()
|
||||
{
|
||||
auto q = db.posts()->query();
|
||||
auto q = db.postTable()->query();
|
||||
q->join("Invalid_Class_Name");
|
||||
q->toList();
|
||||
}
|
||||
|
||||
void MainTest::modifyPost()
|
||||
{
|
||||
auto q = db.posts()->query();
|
||||
auto q = db.postTable()->query();
|
||||
q->setWhere(Post::idField() == postId);
|
||||
|
||||
Post *post = q->first();
|
||||
|
|
@ -230,7 +231,7 @@ void MainTest::modifyPost()
|
|||
post->setTitle("new name");
|
||||
db.saveChanges();
|
||||
|
||||
q = db.posts()->query()
|
||||
q = db.postTable()->query()
|
||||
->setWhere(Post::idField() == postId);
|
||||
|
||||
post = q->first();
|
||||
|
|
@ -240,8 +241,8 @@ void MainTest::modifyPost()
|
|||
|
||||
void MainTest::emptyDatabase()
|
||||
{
|
||||
auto commentsCount = db.comments()->query()->remove();
|
||||
auto postsCount = db.posts()->query()->remove();
|
||||
auto commentsCount = db.commentTable()->query()->remove();
|
||||
auto postsCount = db.postTable()->query()->remove();
|
||||
QTEST_ASSERT(postsCount == 3);
|
||||
QTEST_ASSERT(commentsCount == 6);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define POST_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/QDateTime>
|
||||
#include "table.h"
|
||||
#include "database.h"
|
||||
#include "databasemodel.h"
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
#include "weblogdatabase.h"
|
||||
|
||||
WeblogDatabase::WeblogDatabase() : Database(),
|
||||
m_posts(new TableSet<Post>(this)),
|
||||
m_comments(new TableSet<Comment>(this)),
|
||||
m_users(new TableSet<User>(this)),
|
||||
m_scores(new TableSet<Score>(this))
|
||||
m_postTable(new TableSet<Post>(this)),
|
||||
m_commentTable(new TableSet<Comment>(this)),
|
||||
m_userTable(new TableSet<User>(this)),
|
||||
m_scoreTable(new TableSet<Score>(this))
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
#include <QtTest>
|
||||
#include <QDate>
|
||||
|
||||
#include "maintest.h"
|
||||
#include "phrase.h"
|
||||
|
||||
using namespace Nut;
|
||||
|
||||
MainTest::MainTest(QObject *parent) : QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void MainTest::initTestCase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MainTest::no1()
|
||||
{
|
||||
FieldPhrase<int> id("main", "id");
|
||||
FieldPhrase<QString> name("main", "name");
|
||||
FieldPhrase<QString> last_name("main", "last_name");
|
||||
FieldPhrase<QDate> date("main", "date");
|
||||
auto w = id == 4 && name == "salam";
|
||||
}
|
||||
|
||||
QTEST_MAIN(MainTest)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef MAINTEST_H
|
||||
#define MAINTEST_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
class Post;
|
||||
class User;
|
||||
class MainTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainTest(QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void no1();
|
||||
};
|
||||
|
||||
#endif // MAINTEST_H
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
QT += qml quick testlib sql
|
||||
QT -= gui
|
||||
|
||||
TARGET = tst_phrases
|
||||
TEMPLATE = app
|
||||
|
||||
CONFIG += warn_on qmltestcase c++11
|
||||
INCLUDEPATH += $$PWD/../../src $$PWD/../common
|
||||
include(../../nut.pri)
|
||||
IMPORTPATH += $$OUT_PWD/../src/imports
|
||||
SOURCES += \
|
||||
maintest.cpp
|
||||
|
||||
HEADERS += \
|
||||
maintest.h
|
||||
Loading…
Reference in New Issue