commit
48d5738915
|
|
@ -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
|
||||||
11
nut.pri
11
nut.pri
|
|
@ -18,12 +18,14 @@ HEADERS += \
|
||||||
$$PWD/src/tablesetbase_p.h \
|
$$PWD/src/tablesetbase_p.h \
|
||||||
$$PWD/src/querybase_p.h \
|
$$PWD/src/querybase_p.h \
|
||||||
$$PWD/src/tablemodel.h \
|
$$PWD/src/tablemodel.h \
|
||||||
$$PWD/src/wherephrase.h \
|
|
||||||
$$PWD/src/query_p.h \
|
$$PWD/src/query_p.h \
|
||||||
$$PWD/src/table.h \
|
$$PWD/src/table.h \
|
||||||
$$PWD/src/database.h \
|
$$PWD/src/database.h \
|
||||||
$$PWD/src/database_p.h \
|
$$PWD/src/database_p.h \
|
||||||
$$PWD/src/serializableobject.h
|
$$PWD/src/serializableobject.h \
|
||||||
|
$$PWD/src/sqlmodel.h \
|
||||||
|
$$PWD/src/sqlmodel_p.h \
|
||||||
|
$$PWD/src/phrase.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/src/generators/sqlgeneratorbase.cpp \
|
$$PWD/src/generators/sqlgeneratorbase.cpp \
|
||||||
|
|
@ -39,7 +41,8 @@ SOURCES += \
|
||||||
$$PWD/src/changelogtable.cpp \
|
$$PWD/src/changelogtable.cpp \
|
||||||
$$PWD/src/querybase.cpp \
|
$$PWD/src/querybase.cpp \
|
||||||
$$PWD/src/tablemodel.cpp \
|
$$PWD/src/tablemodel.cpp \
|
||||||
$$PWD/src/wherephrase.cpp \
|
|
||||||
$$PWD/src/table.cpp \
|
$$PWD/src/table.cpp \
|
||||||
$$PWD/src/database.cpp \
|
$$PWD/src/database.cpp \
|
||||||
$$PWD/src/serializableobject.cpp
|
$$PWD/src/serializableobject.cpp \
|
||||||
|
$$PWD/src/sqlmodel.cpp \
|
||||||
|
$$PWD/src/phrase.cpp
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <QtCore/QMetaProperty>
|
#include <QtCore/QMetaProperty>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QJsonDocument>
|
#include <QtCore/QJsonDocument>
|
||||||
#include <QtCore/QJsonObject>
|
#include <QtCore/QJsonObject>
|
||||||
|
|
||||||
|
|
@ -495,6 +496,12 @@ SqlGeneratorBase *Database::sqlGenertor() const
|
||||||
return d->sqlGenertor;
|
return d->sqlGenertor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSqlDatabase Database::database()
|
||||||
|
{
|
||||||
|
Q_D(Database);
|
||||||
|
return d->db;
|
||||||
|
}
|
||||||
|
|
||||||
void Database::databaseUpdated(QString oldVersion, QString newVersion)
|
void Database::databaseUpdated(QString oldVersion, QString newVersion)
|
||||||
{
|
{
|
||||||
Q_UNUSED(oldVersion);
|
Q_UNUSED(oldVersion);
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ public:
|
||||||
QString tableName(QString className);
|
QString tableName(QString className);
|
||||||
|
|
||||||
SqlGeneratorBase *sqlGenertor() const;
|
SqlGeneratorBase *sqlGenertor() const;
|
||||||
|
QSqlDatabase database();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//remove minor version
|
//remove minor version
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ public:
|
||||||
TableSet<ChangeLogTable> *changeLogs;
|
TableSet<ChangeLogTable> *changeLogs;
|
||||||
|
|
||||||
QT_DEPRECATED
|
QT_DEPRECATED
|
||||||
QHash<QString, QString> tables;
|
QMap<QString, QString> tables;
|
||||||
static QMap<QString, DatabaseModel> allTableMaps;
|
static QMap<QString, DatabaseModel> allTableMaps;
|
||||||
static qulonglong lastId;
|
static qulonglong lastId;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ public: \
|
||||||
#define NUT_AUTO_INCREMENT(x) NUT_INFO(__nut_AUTO_INCREMENT, x, 0)
|
#define NUT_AUTO_INCREMENT(x) NUT_INFO(__nut_AUTO_INCREMENT, x, 0)
|
||||||
#define NUT_PRIMARY_AUTO_INCREMENT(x) NUT_PRIMARY_KEY(x) \
|
#define NUT_PRIMARY_AUTO_INCREMENT(x) NUT_PRIMARY_KEY(x) \
|
||||||
NUT_AUTO_INCREMENT(x)
|
NUT_AUTO_INCREMENT(x)
|
||||||
|
#define NUT_DISPLAY_NAME(field, name) NUT_INFO(__nut_DISPLAY, field, name)
|
||||||
#define NUT_UNIQUE(x) NUT_INFO(__nut_UNIQUE, x, 0)
|
#define NUT_UNIQUE(x) NUT_INFO(__nut_UNIQUE, x, 0)
|
||||||
#define NUT_LEN(field, len) NUT_INFO(__nut_LEN, field, len)
|
#define NUT_LEN(field, len) NUT_INFO(__nut_LEN, field, len)
|
||||||
#define NUT_DEFAULT_VALUE(x, n) NUT_INFO(__nut_DEFAULT_VALUE, x, n)
|
#define NUT_DEFAULT_VALUE(x, n) NUT_INFO(__nut_DEFAULT_VALUE, x, n)
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
#define __nut_TABLE "table"
|
#define __nut_TABLE "table"
|
||||||
#define __nut_TABLE_NAME "table_name"
|
#define __nut_TABLE_NAME "table_name"
|
||||||
|
|
||||||
|
#define __nut_DISPLAY "display"
|
||||||
#define __nut_LEN "len"
|
#define __nut_LEN "len"
|
||||||
#define __nut_DEFAULT_VALUE "def"
|
#define __nut_DEFAULT_VALUE "def"
|
||||||
#define __nut_NOT_NULL "notnull"
|
#define __nut_NOT_NULL "notnull"
|
||||||
|
|
|
||||||
|
|
@ -123,35 +123,35 @@ QVariant MySqlGenerator::readValue(const QVariant::Type &type, const QVariant &d
|
||||||
return SqlGeneratorBase::readValue(type, dbValue);
|
return SqlGeneratorBase::readValue(type, dbValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MySqlGenerator::phrase(const PhraseData *d) const
|
//QString MySqlGenerator::phrase(const PhraseData *d) const
|
||||||
{
|
//{
|
||||||
if (d->operatorCond == PhraseData::Distance) {
|
// if (d->operatorCond == PhraseData::Distance) {
|
||||||
return QString("ST_Distance(%1, %2)")
|
// return QString("ST_Distance(%1, %2)")
|
||||||
.arg(d->left->text)
|
// .arg(d->left->text)
|
||||||
.arg(escapeValue(d->operand.toPointF()));
|
// .arg(escapeValue(d->operand.toPointF()));
|
||||||
}
|
// }
|
||||||
|
|
||||||
return SqlGeneratorBase::phrase(d);
|
// return SqlGeneratorBase::phrase(d);
|
||||||
}
|
//}
|
||||||
|
|
||||||
QString MySqlGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
//QString MySqlGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||||
QString agregateArg,
|
// QString agregateArg,
|
||||||
QString tableName,
|
// QString tableName,
|
||||||
QList<WherePhrase> &wheres,
|
// QList<WherePhrase> &wheres,
|
||||||
QList<WherePhrase> &orders,
|
// QList<WherePhrase> &orders,
|
||||||
QList<RelationModel*> joins,
|
// QList<RelationModel*> joins,
|
||||||
int skip, int take)
|
// int skip, int take)
|
||||||
{
|
//{
|
||||||
QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
// QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
||||||
tableName,
|
// tableName,
|
||||||
wheres, orders,
|
// wheres, orders,
|
||||||
joins, skip, take);
|
// joins, skip, take);
|
||||||
|
|
||||||
if (take != -1 && skip != -1)
|
// if (take != -1 && skip != -1)
|
||||||
command.append(QString(" LIMIT %1 OFFSET %2")
|
// command.append(QString(" LIMIT %1 OFFSET %2")
|
||||||
.arg(take)
|
// .arg(take)
|
||||||
.arg(skip));
|
// .arg(skip));
|
||||||
return command;
|
// return command;
|
||||||
}
|
//}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ public:
|
||||||
QString fieldType(FieldModel *field);
|
QString fieldType(FieldModel *field);
|
||||||
QString escapeValue(const QVariant &v) const;
|
QString escapeValue(const QVariant &v) const;
|
||||||
QVariant readValue(const QVariant::Type &type, const QVariant &dbValue);
|
QVariant readValue(const QVariant::Type &type, const QVariant &dbValue);
|
||||||
QString phrase(const PhraseData *d) const;
|
// 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 selectCommand(AgregateType t, QString agregateArg, QString tableName, QList<WherePhrase> &wheres, QList<WherePhrase> &orders, QList<RelationModel *> joins, int skip, int take);
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@
|
||||||
#include "../table.h"
|
#include "../table.h"
|
||||||
#include "../databasemodel.h"
|
#include "../databasemodel.h"
|
||||||
#include "../tablemodel.h"
|
#include "../tablemodel.h"
|
||||||
#include "../wherephrase.h"
|
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -355,10 +354,6 @@ QString SqlGeneratorBase::agregateText(const AgregateType &t,
|
||||||
const QString &arg) const
|
const QString &arg) const
|
||||||
{
|
{
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case SelectAll:
|
|
||||||
return "*";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Min:
|
case Min:
|
||||||
return "MIN(" + arg + ")";
|
return "MIN(" + arg + ")";
|
||||||
break;
|
break;
|
||||||
|
|
@ -426,48 +421,43 @@ QString SqlGeneratorBase::deleteRecords(QString tableName, QString where)
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
|
QString SqlGeneratorBase::selectCommand(const QString &tableName,
|
||||||
QString agregateArg,
|
const PhraseList &fields,
|
||||||
QString tableName,
|
const ConditionalPhrase &where,
|
||||||
QList<WherePhrase> &wheres,
|
const PhraseList &order,
|
||||||
QList<WherePhrase> &orders,
|
const QList<RelationModel*> joins,
|
||||||
QList<RelationModel*> joins,
|
const int skip,
|
||||||
int skip, int take)
|
const int take)
|
||||||
{
|
{
|
||||||
Q_UNUSED(take);
|
|
||||||
Q_UNUSED(skip);
|
Q_UNUSED(skip);
|
||||||
|
Q_UNUSED(take);
|
||||||
|
QString selectText;
|
||||||
|
|
||||||
QStringList joinedOrders;
|
if (!fields.isValid) {
|
||||||
QString select = agregateText(t, agregateArg);
|
|
||||||
|
|
||||||
//TODO: temporatory disabled
|
|
||||||
if (t == SelectAll) {
|
|
||||||
QSet<TableModel*> tables;
|
QSet<TableModel*> tables;
|
||||||
tables.insert(_database->model().tableByName(tableName));
|
tables.insert(_database->model().tableByName(tableName));
|
||||||
foreach (RelationModel *rel, joins)
|
foreach (RelationModel *rel, joins)
|
||||||
tables << rel->masterTable << rel->slaveTable;
|
tables << rel->masterTable << rel->slaveTable;
|
||||||
|
|
||||||
select = "";
|
selectText = "";
|
||||||
foreach (TableModel *t, tables) {
|
foreach (TableModel *t, tables) {
|
||||||
if (!select.isEmpty())
|
if (!selectText.isEmpty())
|
||||||
select.append(", ");
|
selectText.append(", ");
|
||||||
select.append(recordsPhrase(t));
|
selectText.append(recordsPhrase(t));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
QString from = join(tableName, joins, &joinedOrders);
|
selectText = createFieldPhrase(fields);
|
||||||
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;
|
QStringList joinedOrders;
|
||||||
|
QString orderText = createOrderPhrase(order);
|
||||||
|
QString whereText = createConditionalPhrase(where.data);
|
||||||
|
QString fromText = join(tableName, joins, &joinedOrders);
|
||||||
|
|
||||||
if (where != "")
|
QString sql = "SELECT " + selectText + " FROM " + fromText;
|
||||||
sql.append(" WHERE " + where);
|
|
||||||
|
if (whereText != "")
|
||||||
|
sql.append(" WHERE " + whereText);
|
||||||
|
|
||||||
if (orderText != "")
|
if (orderText != "")
|
||||||
sql.append(" ORDER BY " + orderText);
|
sql.append(" ORDER BY " + orderText);
|
||||||
|
|
@ -481,20 +471,149 @@ QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||||
return sql + " ";
|
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) {
|
QString sql = "SELECT " + selectText + " FROM " + fromText;
|
||||||
if (whereText != "")
|
|
||||||
whereText.append(" AND ");
|
|
||||||
|
|
||||||
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)
|
void SqlGeneratorBase::replaceTableNames(QString &command)
|
||||||
{
|
{
|
||||||
foreach (TableModel *m, TableModel::allModels())
|
foreach (TableModel *m, TableModel::allModels())
|
||||||
|
|
@ -508,44 +627,44 @@ void SqlGeneratorBase::removeTableNames(QString &command)
|
||||||
command = command.replace("[" + m->className() + "].", "");
|
command = command.replace("[" + m->className() + "].", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqlGeneratorBase::deleteCommand(QList<WherePhrase> &wheres,
|
//QString SqlGeneratorBase::deleteCommand(QList<WherePhrase> &wheres,
|
||||||
QString tableName)
|
// QString tableName)
|
||||||
{
|
//{
|
||||||
QString command = "DELETE FROM " + tableName;
|
// QString command = "DELETE FROM " + tableName;
|
||||||
QString where = createWhere(wheres);
|
// QString where = createWhere(wheres);
|
||||||
|
|
||||||
if (where != "")
|
// if (where != "")
|
||||||
command.append(" WHERE " + where);
|
// command.append(" WHERE " + where);
|
||||||
|
|
||||||
for (int i = 0; i < _database->model().count(); i++)
|
// for (int i = 0; i < _database->model().count(); i++)
|
||||||
command = command.replace(_database->model().at(i)->className() + ".",
|
// command = command.replace(_database->model().at(i)->className() + ".",
|
||||||
_database->model().at(i)->name() + ".");
|
// _database->model().at(i)->name() + ".");
|
||||||
|
|
||||||
replaceTableNames(command);
|
// replaceTableNames(command);
|
||||||
|
|
||||||
return command;
|
// return command;
|
||||||
}
|
//}
|
||||||
|
|
||||||
QString SqlGeneratorBase::updateCommand(WherePhrase &phrase,
|
//QString SqlGeneratorBase::updateCommand(WherePhrase &phrase,
|
||||||
QList<WherePhrase> &wheres,
|
// QList<WherePhrase> &wheres,
|
||||||
QString tableName)
|
// QString tableName)
|
||||||
{
|
//{
|
||||||
QString p = this->phrase(phrase.data());
|
// QString p = this->phrase(phrase.data());
|
||||||
QString where = createWhere(wheres);
|
// QString where = createWhere(wheres);
|
||||||
|
|
||||||
QString sql = "UPDATE " + tableName + " SET " + p;
|
// QString sql = "UPDATE " + tableName + " SET " + p;
|
||||||
|
|
||||||
if (where != "")
|
// if (where != "")
|
||||||
sql.append(" WHERE " + where);
|
// sql.append(" WHERE " + where);
|
||||||
|
|
||||||
for (int i = 0; i < _database->model().count(); i++)
|
// for (int i = 0; i < _database->model().count(); i++)
|
||||||
sql = sql.replace(_database->model().at(i)->className() + ".",
|
// sql = sql.replace(_database->model().at(i)->className() + ".",
|
||||||
_database->model().at(i)->name() + ".");
|
// _database->model().at(i)->name() + ".");
|
||||||
|
|
||||||
removeTableNames(sql);
|
// removeTableNames(sql);
|
||||||
|
|
||||||
return sql;
|
// return sql;
|
||||||
}
|
//}
|
||||||
|
|
||||||
QString SqlGeneratorBase::escapeValue(const QVariant &v) const
|
QString SqlGeneratorBase::escapeValue(const QVariant &v) const
|
||||||
{
|
{
|
||||||
|
|
@ -610,78 +729,13 @@ QVariant SqlGeneratorBase::readValue(const QVariant::Type &type,
|
||||||
return dbValue;
|
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 SqlGeneratorBase::phrase(const PhraseData *d) const
|
||||||
{
|
{
|
||||||
QString ret = "";
|
QString ret = "";
|
||||||
|
|
||||||
switch (d->type) {
|
switch (d->type) {
|
||||||
case PhraseData::Field:
|
case PhraseData::Field:
|
||||||
ret = d->text;
|
ret = d->toString();
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PhraseData::WithVariant:
|
case PhraseData::WithVariant:
|
||||||
|
|
@ -755,14 +809,139 @@ SqlGeneratorBase::operatorString(const PhraseData::Condition &cond) const
|
||||||
case PhraseData::Divide:
|
case PhraseData::Divide:
|
||||||
return "/";
|
return "/";
|
||||||
|
|
||||||
case PhraseData::Set:
|
// case PhraseData::Set:
|
||||||
return "=";
|
// return "=";
|
||||||
|
|
||||||
case PhraseData::Append:
|
// case PhraseData::Append:
|
||||||
return ",";
|
// return ",";
|
||||||
|
|
||||||
|
case PhraseData::Between:
|
||||||
|
return "BETWEEN";
|
||||||
|
|
||||||
|
case PhraseData::Mod:
|
||||||
|
return "MOD";
|
||||||
|
|
||||||
default:
|
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/qglobal.h>
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QStringList>
|
#include <QtCore/QStringList>
|
||||||
#include "../wherephrase.h"
|
#include "../phrase.h"
|
||||||
|
//#include "../wherephrase.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -47,7 +48,7 @@ public:
|
||||||
Delete
|
Delete
|
||||||
};
|
};
|
||||||
enum AgregateType{
|
enum AgregateType{
|
||||||
SelectAll,
|
// SelectAll,
|
||||||
Count,
|
Count,
|
||||||
Min,
|
Min,
|
||||||
Max,
|
Max,
|
||||||
|
|
@ -83,28 +84,51 @@ public:
|
||||||
virtual QString deleteRecord(Table *t, QString tableName);
|
virtual QString deleteRecord(Table *t, QString tableName);
|
||||||
virtual QString deleteRecords(QString tableName, QString where);
|
virtual QString deleteRecords(QString tableName, QString where);
|
||||||
|
|
||||||
virtual QString selectCommand(AgregateType t,
|
virtual QString selectCommand(const QString &tableName,
|
||||||
QString agregateArg, QString tableName,
|
const PhraseList &fields,
|
||||||
QList<WherePhrase> &wheres,
|
const ConditionalPhrase &where,
|
||||||
QList<WherePhrase> &orders,
|
const PhraseList &order,
|
||||||
QList<RelationModel*> joins,
|
const QList<RelationModel*> joins,
|
||||||
int skip = -1, int take = -1);
|
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 QString escapeValue(const QVariant &v) const;
|
||||||
virtual QVariant readValue(const QVariant::Type &type, const QVariant &dbValue);
|
virtual QVariant readValue(const QVariant::Type &type, const QVariant &dbValue);
|
||||||
virtual QString phrase(const PhraseData *d) const;
|
virtual QString phrase(const PhraseData *d) const;
|
||||||
virtual QString phraseUpdate(const PhraseData *d) const;
|
|
||||||
virtual QString operatorString(const PhraseData::Condition &cond) const;
|
virtual QString operatorString(const PhraseData::Condition &cond) const;
|
||||||
|
|
||||||
private:
|
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 agregateText(const AgregateType &t, const QString &arg = QString::null) const;
|
||||||
QString fromTableText(const QString &tableName, QString &joinClassName, QString &orderBy) const;
|
QString fromTableText(const QString &tableName, QString &joinClassName, QString &orderBy) const;
|
||||||
QString createWhere(QList<WherePhrase> &wheres);
|
// QString createWhere(QList<WherePhrase> &wheres);
|
||||||
QString phraseOrder(const PhraseData *d) const;
|
|
||||||
void replaceTableNames(QString &command);
|
void replaceTableNames(QString &command);
|
||||||
void removeTableNames(QString &command);
|
void removeTableNames(QString &command);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -71,24 +71,24 @@ QString SqliteGenerator::fieldType(FieldModel *field)
|
||||||
return dbType;
|
return dbType;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqliteGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
//QString SqliteGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||||
QString agregateArg,
|
// QString agregateArg,
|
||||||
QString tableName,
|
// QString tableName,
|
||||||
QList<WherePhrase> &wheres,
|
// QList<WherePhrase> &wheres,
|
||||||
QList<WherePhrase> &orders,
|
// QList<WherePhrase> &orders,
|
||||||
QList<RelationModel*> joins,
|
// QList<RelationModel*> joins,
|
||||||
int skip, int take)
|
// int skip, int take)
|
||||||
{
|
//{
|
||||||
QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
// QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
||||||
tableName,
|
// tableName,
|
||||||
wheres, orders,
|
// wheres, orders,
|
||||||
joins, skip, take);
|
// joins, skip, take);
|
||||||
|
|
||||||
if (take != -1 && skip != -1)
|
// if (take != -1 && skip != -1)
|
||||||
command.append(QString(" LIMIT %1 OFFSET %2")
|
// command.append(QString(" LIMIT %1 OFFSET %2")
|
||||||
.arg(take)
|
// .arg(take)
|
||||||
.arg(skip));
|
// .arg(skip));
|
||||||
return command;
|
// return command;
|
||||||
}
|
//}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,11 @@ public:
|
||||||
|
|
||||||
QString fieldType(FieldModel *field);
|
QString fieldType(FieldModel *field);
|
||||||
|
|
||||||
QString selectCommand(AgregateType t, QString agregateArg,
|
// QString selectCommand(AgregateType t, QString agregateArg,
|
||||||
QString tableName,
|
// QString tableName,
|
||||||
QList<WherePhrase> &wheres,
|
// QList<WherePhrase> &wheres,
|
||||||
QList<WherePhrase> &orders,
|
// QList<WherePhrase> &orders,
|
||||||
QList<RelationModel *> joins, int skip, int take);
|
// QList<RelationModel *> joins, int skip, int take);
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -133,23 +133,23 @@ QString SqlServerGenerator::escapeValue(const QVariant &v) const
|
||||||
return SqlGeneratorBase::escapeValue(v);
|
return SqlGeneratorBase::escapeValue(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqlServerGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
//QString SqlServerGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
|
||||||
QString agregateArg,
|
// QString agregateArg,
|
||||||
QString tableName,
|
// QString tableName,
|
||||||
QList<WherePhrase> &wheres,
|
// QList<WherePhrase> &wheres,
|
||||||
QList<WherePhrase> &orders,
|
// QList<WherePhrase> &orders,
|
||||||
QList<RelationModel*> joins, int skip, int take)
|
// QList<RelationModel*> joins, int skip, int take)
|
||||||
{
|
//{
|
||||||
QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
// QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
|
||||||
tableName,
|
// tableName,
|
||||||
wheres, orders,
|
// wheres, orders,
|
||||||
joins, skip, take);
|
// joins, skip, take);
|
||||||
|
|
||||||
if (take != -1 && skip != -1)
|
// if (take != -1 && skip != -1)
|
||||||
command.append(QString("OFFSET %1 ROWS FETCH NEXT %2 ROWS ONLY")
|
// command.append(QString("OFFSET %1 ROWS FETCH NEXT %2 ROWS ONLY")
|
||||||
.arg(skip)
|
// .arg(skip)
|
||||||
.arg(take));
|
// .arg(take));
|
||||||
return command;
|
// return command;
|
||||||
}
|
//}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,11 @@ public:
|
||||||
|
|
||||||
QString escapeValue(const QVariant &v) const;
|
QString escapeValue(const QVariant &v) const;
|
||||||
|
|
||||||
QString selectCommand(AgregateType t, QString agregateArg,
|
// QString selectCommand(AgregateType t, QString agregateArg,
|
||||||
QString tableName,
|
// QString tableName,
|
||||||
QList<WherePhrase> &wheres,
|
// QList<WherePhrase> &wheres,
|
||||||
QList<WherePhrase> &orders,
|
// QList<WherePhrase> &orders,
|
||||||
QList<RelationModel *> joins, int skip, int take);
|
// QList<RelationModel *> joins, int skip, int take);
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,377 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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(new PhraseData(l)), right(0), isNot(false)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o,
|
||||||
|
const PhraseData *r)
|
||||||
|
: className(0), fieldName(0),
|
||||||
|
type(WithOther), operatorCond(o), left(new PhraseData(l)), right(new PhraseData(r)), isNot(false)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o, QVariant r)
|
||||||
|
: className(0), fieldName(0),
|
||||||
|
type(WithVariant), operatorCond(o), left(new PhraseData(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;
|
||||||
|
isNot = other->isNot;
|
||||||
|
if (type != Field) {
|
||||||
|
qDebug() << "Bug";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 PhraseList &other)
|
||||||
|
{
|
||||||
|
data = qMove(other.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhraseList::PhraseList(const AbstractFieldPhrase &other) : isValid(true)
|
||||||
|
{
|
||||||
|
data.append(new PhraseData(other.data));
|
||||||
|
}
|
||||||
|
|
||||||
|
PhraseList::PhraseList(const AbstractFieldPhrase *left, const AbstractFieldPhrase &right)
|
||||||
|
: isValid(true)
|
||||||
|
{
|
||||||
|
data.append(new PhraseData(left->data));
|
||||||
|
data.append(new PhraseData(right.data));
|
||||||
|
}
|
||||||
|
|
||||||
|
PhraseList::PhraseList(PhraseList *left, PhraseList *right) : isValid(true)
|
||||||
|
{
|
||||||
|
data = qMove(left->data + right->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhraseList::PhraseList(PhraseList *left, const AbstractFieldPhrase *right)
|
||||||
|
: isValid(true)
|
||||||
|
{
|
||||||
|
data = left->data;
|
||||||
|
data.append(new PhraseData(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() : data(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &other)
|
||||||
|
{
|
||||||
|
qDebug() << "************* ctor called:";
|
||||||
|
this->data = new PhraseData(other.data);
|
||||||
|
// const_cast<ConditionalPhrase&>(other).data = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_COMPILER_RVALUE_REFS
|
||||||
|
ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &&other)
|
||||||
|
{
|
||||||
|
qDebug() << "************* ctor called:";
|
||||||
|
this->data = qMove(other.data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
this->data = new PhraseData(other.data);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
|
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 PhraseList &other);
|
||||||
|
PhraseList(const AbstractFieldPhrase &other);
|
||||||
|
PhraseList(const 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);
|
||||||
|
#ifdef Q_COMPILER_RVALUE_REFS
|
||||||
|
ConditionalPhrase(const ConditionalPhrase &&other);
|
||||||
|
#endif
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
#ifdef Q_COMPILER_INITIALIZER_LISTS
|
||||||
|
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
|
||||||
130
src/query.h
130
src/query.h
|
|
@ -28,6 +28,7 @@
|
||||||
#include <QtCore/QMetaObject>
|
#include <QtCore/QMetaObject>
|
||||||
#include <QtSql/QSqlResult>
|
#include <QtSql/QSqlResult>
|
||||||
#include <QtSql/QSqlError>
|
#include <QtSql/QSqlError>
|
||||||
|
#include <QtSql/QSqlQueryModel>
|
||||||
|
|
||||||
#include "query_p.h"
|
#include "query_p.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
@ -35,7 +36,7 @@
|
||||||
#include "tablesetbase_p.h"
|
#include "tablesetbase_p.h"
|
||||||
#include "generators/sqlgeneratorbase_p.h"
|
#include "generators/sqlgeneratorbase_p.h"
|
||||||
#include "querybase_p.h"
|
#include "querybase_p.h"
|
||||||
#include "wherephrase.h"
|
#include "phrase.h"
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
@ -53,7 +54,6 @@ public:
|
||||||
~Query();
|
~Query();
|
||||||
|
|
||||||
//ddl
|
//ddl
|
||||||
Query<T> *setWhere(WherePhrase where);
|
|
||||||
|
|
||||||
Query<T> *join(const QString &className);
|
Query<T> *join(const QString &className);
|
||||||
Query<T> *join(Table *c);
|
Query<T> *join(Table *c);
|
||||||
|
|
@ -68,7 +68,11 @@ public:
|
||||||
// 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> *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(TableSetBase *t);
|
||||||
Query<T> *include(Table *t);
|
Query<T> *include(Table *t);
|
||||||
|
|
||||||
|
|
@ -83,9 +87,12 @@ public:
|
||||||
QVariant average(const FieldPhrase<int> &f);
|
QVariant average(const FieldPhrase<int> &f);
|
||||||
|
|
||||||
//data mailpulation
|
//data mailpulation
|
||||||
int update(WherePhrase phrase);
|
int update(const AssignmentPhraseList &ph);
|
||||||
|
// int insert(const AssignmentPhraseList &ph);
|
||||||
int remove();
|
int remove();
|
||||||
|
|
||||||
|
QSqlQueryModel *toModal();
|
||||||
|
|
||||||
//debug purpose
|
//debug purpose
|
||||||
QString sqlCommand() const;
|
QString sqlCommand() const;
|
||||||
};
|
};
|
||||||
|
|
@ -118,6 +125,7 @@ Q_OUTOFLINE_TEMPLATE Query<T>::~Query()
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
Q_D(Query);
|
||||||
delete d;
|
delete d;
|
||||||
|
qDebug() << "~Query";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
@ -129,10 +137,9 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
|
||||||
d->select = "*";
|
d->select = "*";
|
||||||
|
|
||||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||||
SqlGeneratorBase::SelectAll, "",
|
d->tableName, d->fieldPhrase, d->wherePhrase, d->orderPhrase,
|
||||||
d->tableName,
|
d->relations, d->skip, d->take);
|
||||||
d->wheres, d->orderPhrases, d->relations,
|
qDebug() <<d->sql;
|
||||||
d->skip, d->take);
|
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
if (q.lastError().isValid()) {
|
if (q.lastError().isValid()) {
|
||||||
qDebug() << q.lastError().text();
|
qDebug() << q.lastError().text();
|
||||||
|
|
@ -144,7 +151,6 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
|
||||||
foreach (RelationModel *rel, d->relations)
|
foreach (RelationModel *rel, d->relations)
|
||||||
relatedTables << rel->slaveTable << rel->masterTable;
|
relatedTables << rel->slaveTable << rel->masterTable;
|
||||||
|
|
||||||
|
|
||||||
struct LevelData{
|
struct LevelData{
|
||||||
QList<int> masters;
|
QList<int> masters;
|
||||||
QList<int> slaves;
|
QList<int> slaves;
|
||||||
|
|
@ -251,6 +257,9 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
|
||||||
= QMetaType::metaObjectForType(data.table->typeId());
|
= QMetaType::metaObjectForType(data.table->typeId());
|
||||||
table = qobject_cast<Table *>(childMetaObject->newInstance());
|
table = qobject_cast<Table *>(childMetaObject->newInstance());
|
||||||
|
|
||||||
|
if (!table)
|
||||||
|
qFatal("Could not create instance of %s",
|
||||||
|
qPrintable(data.table->name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList childFields = data.table->fieldsNames();
|
QStringList childFields = data.table->fieldsNames();
|
||||||
|
|
@ -293,9 +302,11 @@ Q_OUTOFLINE_TEMPLATE QList<F> Query<T>::select(const FieldPhrase<F> f)
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||||
SqlGeneratorBase::SignleField, f.data()->text,
|
d->tableName,
|
||||||
d->tableName, d->wheres,
|
SqlGeneratorBase::SignleField, f.data->toString(),
|
||||||
d->orderPhrases, d->relations, d->skip, d->take);
|
d->wherePhrase,
|
||||||
|
d->relations,
|
||||||
|
d->skip, d->take);
|
||||||
|
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
|
|
@ -329,12 +340,12 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::count()
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->select = "COUNT(*)";
|
d->select = "COUNT(*)";
|
||||||
d->sql = d->database->sqlGenertor()->selectCommand(SqlGeneratorBase::Count,
|
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||||
QStringLiteral("*"),
|
d->tableName,
|
||||||
d->tableName,
|
SqlGeneratorBase::Count,
|
||||||
d->wheres,
|
QStringLiteral("*"),
|
||||||
d->orderPhrases,
|
d->wherePhrase,
|
||||||
d->relations);
|
d->relations);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
if (q.next())
|
if (q.next())
|
||||||
|
|
@ -349,8 +360,9 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(const FieldPhrase<int> &f)
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||||
SqlGeneratorBase::Max, f.data()->text, d->tableName,
|
d->tableName,
|
||||||
d->wheres, d->orderPhrases,
|
SqlGeneratorBase::Max, f.data->toString(),
|
||||||
|
d->wherePhrase,
|
||||||
d->relations);
|
d->relations);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
|
|
@ -366,8 +378,9 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(const FieldPhrase<int> &f)
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||||
SqlGeneratorBase::Min, f.data()->text, d->tableName,
|
d->tableName,
|
||||||
d->wheres, d->orderPhrases,
|
SqlGeneratorBase::Min, f.data->toString(),
|
||||||
|
d->wherePhrase,
|
||||||
d->relations);
|
d->relations);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
|
|
@ -383,8 +396,9 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::average(const FieldPhrase<int> &f)
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->sql = d->database->sqlGenertor()->selectCommand(
|
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||||
SqlGeneratorBase::Average, f.data()->text, d->tableName,
|
d->tableName,
|
||||||
d->wheres, d->orderPhrases,
|
SqlGeneratorBase::Average, f.data->toString(),
|
||||||
|
d->wherePhrase,
|
||||||
d->relations);
|
d->relations);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
|
|
@ -423,10 +437,21 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::join(Table *c)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
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);
|
Q_D(Query);
|
||||||
d->wheres.append(where);
|
if (d->wherePhrase.data)
|
||||||
|
d->wherePhrase = d->wherePhrase && ph;
|
||||||
|
else
|
||||||
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -446,6 +471,14 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::take(int n)
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::fields(const PhraseList &ph)
|
||||||
|
{
|
||||||
|
Q_D(Query);
|
||||||
|
d->fieldPhrase = ph;
|
||||||
|
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)
|
||||||
|
|
@ -456,10 +489,10 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::take(int n)
|
||||||
//}
|
//}
|
||||||
|
|
||||||
template <class T>
|
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);
|
Q_D(Query);
|
||||||
d->orderPhrases.append(phrase);
|
d->orderPhrase = ph;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -478,12 +511,14 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::include(Table *t)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class 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);
|
Q_D(Query);
|
||||||
|
|
||||||
d->sql = d->database->sqlGenertor()->updateCommand(phrase, d->wheres,
|
d->sql = d->database->sqlGenertor()->updateCommand(
|
||||||
d->tableName);
|
d->tableName,
|
||||||
|
ph,
|
||||||
|
d->wherePhrase);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
if (m_autoDelete)
|
if (m_autoDelete)
|
||||||
|
|
@ -496,7 +531,8 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::remove()
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
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);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
if (m_autoDelete)
|
if (m_autoDelete)
|
||||||
|
|
@ -504,6 +540,36 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::remove()
|
||||||
return q.numRowsAffected();
|
return q.numRowsAffected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE QSqlQueryModel *Query<T>::toModal()
|
||||||
|
{
|
||||||
|
Q_D(Query);
|
||||||
|
|
||||||
|
d->sql = d->database->sqlGenertor()->selectCommand(
|
||||||
|
d->tableName,
|
||||||
|
d->fieldPhrase,
|
||||||
|
d->wherePhrase, d->orderPhrase, d->relations,
|
||||||
|
d->skip, d->take);
|
||||||
|
|
||||||
|
DatabaseModel dbModel = d->database->model();
|
||||||
|
QSqlQueryModel *model = new QSqlQueryModel;
|
||||||
|
model->setQuery(d->sql, d->database->database());
|
||||||
|
|
||||||
|
int fieldIndex = 0;
|
||||||
|
foreach (const PhraseData *pd, d->fieldPhrase.data) {
|
||||||
|
QString displayName = dbModel.tableByClassName(pd->className)
|
||||||
|
->field(pd->fieldName)->displayName;
|
||||||
|
|
||||||
|
qDebug() << "Display name for"<<pd->className<<pd->fieldName
|
||||||
|
<<"="<<displayName;
|
||||||
|
model->setHeaderData(fieldIndex++,
|
||||||
|
Qt::Horizontal,
|
||||||
|
displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE QString Query<T>::sqlCommand() const
|
Q_OUTOFLINE_TEMPLATE QString Query<T>::sqlCommand() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#ifndef QUERY_P_H
|
#ifndef QUERY_P_H
|
||||||
#define QUERY_P_H
|
#define QUERY_P_H
|
||||||
|
|
||||||
#include "wherephrase.h"
|
#include "phrase.h"
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
@ -48,11 +48,15 @@ public:
|
||||||
TableSetBase *tableSet;
|
TableSetBase *tableSet;
|
||||||
QStringList joins;
|
QStringList joins;
|
||||||
QList<RelationModel*> relations;
|
QList<RelationModel*> relations;
|
||||||
QList<WherePhrase> wheres;
|
|
||||||
QList<WherePhrase> orderPhrases;
|
|
||||||
QHash<QString, QString> orders;
|
|
||||||
int skip;
|
int skip;
|
||||||
int take;
|
int take;
|
||||||
|
PhraseList orderPhrase, fieldPhrase;
|
||||||
|
ConditionalPhrase wherePhrase;
|
||||||
|
|
||||||
|
// QList<WherePhrase> wheres;
|
||||||
|
// QList<WherePhrase> orderPhrases;
|
||||||
|
// QList<WherePhrase> fields;
|
||||||
|
// QHash<QString, QString> orders;
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "database.h"
|
||||||
|
#include "tablesetbase_p.h"
|
||||||
|
#include "databasemodel.h"
|
||||||
|
|
||||||
|
#include "sqlmodel_p.h"
|
||||||
|
#include "sqlmodel.h"
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
SqlModel::SqlModel(Database *database, TableSetBase *tableSet, QObject *parent) :
|
||||||
|
QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
Q_D(SqlModel);
|
||||||
|
d->model = database->model()
|
||||||
|
.tableByClassName(tableSet->childClassName());
|
||||||
|
d->tableName = d->model->name();
|
||||||
|
|
||||||
|
// setQuery("SELECT * FROM " + d->tableName, database->databaseName());
|
||||||
|
}
|
||||||
|
|
||||||
|
int SqlModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
Q_D(const SqlModel);
|
||||||
|
return d->rows.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SqlModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
Q_D(const SqlModel);
|
||||||
|
return d->model->fields().count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant SqlModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
Q_D(const SqlModel);
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if (index.row() >= d->rows.count() || index.row() < 0)
|
||||||
|
return QVariant("-");
|
||||||
|
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
Table *t = d->rows.at(index.row());
|
||||||
|
return t->property(d->model->field(index.column())->name.toLocal8Bit().data());
|
||||||
|
// LogData *d = dataList.at(index.row());
|
||||||
|
|
||||||
|
// switch (index.column()) {
|
||||||
|
// case COL_ID:
|
||||||
|
// return index.row() + 1;
|
||||||
|
// case COL_Type: {
|
||||||
|
// return typeText(d->type);
|
||||||
|
// }
|
||||||
|
// case COL_TITLE:
|
||||||
|
// return d->title;
|
||||||
|
// case COL_File:
|
||||||
|
// return d->file;
|
||||||
|
// case COL_Function:
|
||||||
|
// return d->function;
|
||||||
|
// case COL_Line:
|
||||||
|
// return d->line;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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 SQLMODEL_H
|
||||||
|
#define SQLMODEL_H
|
||||||
|
|
||||||
|
#include <QtCore/QAbstractTableModel>
|
||||||
|
#include "defines.h"
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class Database;
|
||||||
|
class TableSetBase;
|
||||||
|
class SqlModelPrivate;
|
||||||
|
class Table;
|
||||||
|
class TableModel;
|
||||||
|
class SqlModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SqlModel(Database *database, TableSetBase *tableSet, QObject *parent = Q_NULLPTR);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent) const;
|
||||||
|
int columnCount(const QModelIndex &parent) const;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SqlModelPrivate *d_ptr;
|
||||||
|
Q_DECLARE_PRIVATE(SqlModel)
|
||||||
|
};
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // SQLMODEL_H
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef SQLMODEL_P_H
|
||||||
|
#define SQLMODEL_P_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include "defines.h"
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class SqlModel;
|
||||||
|
class Table;
|
||||||
|
class TableModel;
|
||||||
|
class SqlModelPrivate {
|
||||||
|
SqlModel *q_ptr;
|
||||||
|
Q_DECLARE_PUBLIC(SqlModel)
|
||||||
|
public:
|
||||||
|
QString tableName;
|
||||||
|
|
||||||
|
QList<Table*> rows;
|
||||||
|
TableModel *model;
|
||||||
|
};
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // SQLMODEL_P_H
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "wherephrase.h"
|
#include "phrase.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,14 @@ void TableModel::setTypeId(const int &typeId)
|
||||||
_typeId = typeId;
|
_typeId = typeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FieldModel *TableModel::field(int n) const
|
||||||
|
{
|
||||||
|
if (n < 0 || n >= _fields.count())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return _fields.at(n);
|
||||||
|
}
|
||||||
|
|
||||||
FieldModel *TableModel::field(QString name) const
|
FieldModel *TableModel::field(QString name) const
|
||||||
{
|
{
|
||||||
foreach (FieldModel *f, _fields)
|
foreach (FieldModel *f, _fields)
|
||||||
|
|
@ -195,7 +203,7 @@ TableModel::TableModel(int typeId, QString tableName)
|
||||||
|
|
||||||
if(type == __nut_FIELD){
|
if(type == __nut_FIELD){
|
||||||
FieldModel *f = new FieldModel;
|
FieldModel *f = new FieldModel;
|
||||||
f->name = name;
|
f->name = f->displayName = name;
|
||||||
_fields.append(f);
|
_fields.append(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -255,8 +263,8 @@ TableModel::TableModel(int typeId, QString tableName)
|
||||||
f->isAutoIncrement = true;
|
f->isAutoIncrement = true;
|
||||||
else if(type == __nut_UNIQUE)
|
else if(type == __nut_UNIQUE)
|
||||||
f->isUnique = true;
|
f->isUnique = true;
|
||||||
|
else if(type == __nut_DISPLAY)
|
||||||
|
f->displayName = value.mid(1, value.length() - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!findByTypeId(typeId) && !tableName.isNull())
|
if(!findByTypeId(typeId) && !tableName.isNull())
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ struct FieldModel{
|
||||||
bool isPrimaryKey;
|
bool isPrimaryKey;
|
||||||
bool isAutoIncrement;
|
bool isAutoIncrement;
|
||||||
bool isUnique;
|
bool isUnique;
|
||||||
|
QString displayName;
|
||||||
|
|
||||||
bool operator ==(const FieldModel &f) const{
|
bool operator ==(const FieldModel &f) const{
|
||||||
|
|
||||||
|
|
@ -88,6 +89,7 @@ public:
|
||||||
// static void createForegionKeys();
|
// static void createForegionKeys();
|
||||||
// static TableModel* model(QString className);
|
// static TableModel* model(QString className);
|
||||||
|
|
||||||
|
FieldModel *field(int n) const;
|
||||||
FieldModel *field(QString name) const;
|
FieldModel *field(QString name) const;
|
||||||
RelationModel *foregionKey(QString otherTable) const;
|
RelationModel *foregionKey(QString otherTable) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,3 +19,4 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "tableset.h"
|
#include "tableset.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@
|
||||||
#include <QtSql/QSqlQuery>
|
#include <QtSql/QSqlQuery>
|
||||||
|
|
||||||
#include "tablesetbase_p.h"
|
#include "tablesetbase_p.h"
|
||||||
//#include "database.h"
|
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include "wherephrase.h"
|
#include "phrase.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifndef PHRASE_H
|
#ifndef WHEREPHRASE_H
|
||||||
#define PHRASE_H
|
#define WHEREPHRASE_H
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
|
|
||||||
|
|
@ -39,58 +39,58 @@
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class SqlGeneratorBase;
|
class SqlGeneratorBase;
|
||||||
class PhraseData
|
//class PhraseData
|
||||||
{
|
//{
|
||||||
public:
|
//public:
|
||||||
enum Condition {
|
// enum Condition {
|
||||||
NotAssign = 0,
|
// NotAssign = 0,
|
||||||
Equal,
|
// Equal,
|
||||||
Less,
|
// Less,
|
||||||
LessEqual,
|
// LessEqual,
|
||||||
Null,
|
// Null,
|
||||||
In,
|
// In,
|
||||||
Like,
|
// Like,
|
||||||
|
|
||||||
Not = 10,
|
// Not = 10,
|
||||||
NotEqual,
|
// NotEqual,
|
||||||
GreaterEqual,
|
// GreaterEqual,
|
||||||
Greater,
|
// Greater,
|
||||||
NotNull,
|
// NotNull,
|
||||||
NotIn,
|
// NotIn,
|
||||||
NotLike,
|
// NotLike,
|
||||||
|
|
||||||
And = 20,
|
// And = 20,
|
||||||
Or,
|
// Or,
|
||||||
|
|
||||||
Append,
|
// Append,
|
||||||
Set,
|
// Set,
|
||||||
|
|
||||||
Add,
|
// Add,
|
||||||
Minus,
|
// Minus,
|
||||||
Multiple,
|
// Multiple,
|
||||||
Divide,
|
// Divide,
|
||||||
|
|
||||||
// special types
|
// // special types
|
||||||
Distance
|
// Distance
|
||||||
};
|
// };
|
||||||
|
|
||||||
enum Type { Field, WithVariant, WithOther, WithoutOperand };
|
// enum Type { Field, WithVariant, WithOther, WithoutOperand };
|
||||||
Type type;
|
// Type type;
|
||||||
|
|
||||||
Condition operatorCond;
|
// Condition operatorCond;
|
||||||
|
|
||||||
QString text;
|
// QString text;
|
||||||
const PhraseData *left;
|
// const PhraseData *left;
|
||||||
const PhraseData *right;
|
// const PhraseData *right;
|
||||||
QVariant operand;
|
// QVariant operand;
|
||||||
|
|
||||||
PhraseData(const char *className, const char *s);
|
// PhraseData(const char *className, const char *s);
|
||||||
PhraseData(PhraseData *l, Condition o);
|
// PhraseData(PhraseData *l, Condition o);
|
||||||
PhraseData(PhraseData *l, Condition o, const PhraseData *r);
|
// PhraseData(PhraseData *l, Condition o, const PhraseData *r);
|
||||||
PhraseData(PhraseData *l, Condition o, QVariant r);
|
// PhraseData(PhraseData *l, Condition o, QVariant r);
|
||||||
|
|
||||||
~PhraseData();
|
// ~PhraseData();
|
||||||
};
|
//};
|
||||||
|
|
||||||
class WherePhrase
|
class WherePhrase
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ void MainTest::initTestCase()
|
||||||
|
|
||||||
bool ok = db.open();
|
bool ok = db.open();
|
||||||
|
|
||||||
db.comments()->query()->remove();
|
db.commentTable()->query()->remove();
|
||||||
db.posts()->query()->remove();
|
db.postTable()->query()->remove();
|
||||||
|
|
||||||
QTEST_ASSERT(ok);
|
QTEST_ASSERT(ok);
|
||||||
}
|
}
|
||||||
|
|
@ -63,7 +63,7 @@ void MainTest::createUser()
|
||||||
user = new User;
|
user = new User;
|
||||||
user->setUsername("admin");
|
user->setUsername("admin");
|
||||||
user->setPassword("123456");
|
user->setPassword("123456");
|
||||||
db.users()->append(user);
|
db.userTable()->append(user);
|
||||||
db.saveChanges();
|
db.saveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ void MainTest::createPost()
|
||||||
newPost->setTitle("post title");
|
newPost->setTitle("post title");
|
||||||
newPost->setSaveDate(QDateTime::currentDateTime());
|
newPost->setSaveDate(QDateTime::currentDateTime());
|
||||||
|
|
||||||
db.posts()->append(newPost);
|
db.postTable()->append(newPost);
|
||||||
|
|
||||||
for(int i = 0 ; i < 3; i++){
|
for(int i = 0 ; i < 3; i++){
|
||||||
Comment *comment = new Comment;
|
Comment *comment = new Comment;
|
||||||
|
|
@ -102,7 +102,7 @@ void MainTest::createPost2()
|
||||||
newPost->setTitle("post title");
|
newPost->setTitle("post title");
|
||||||
newPost->setSaveDate(QDateTime::currentDateTime());
|
newPost->setSaveDate(QDateTime::currentDateTime());
|
||||||
|
|
||||||
db.posts()->append(newPost);
|
db.postTable()->append(newPost);
|
||||||
db.saveChanges();
|
db.saveChanges();
|
||||||
|
|
||||||
for(int i = 0 ; i < 3; i++){
|
for(int i = 0 ; i < 3; i++){
|
||||||
|
|
@ -111,7 +111,7 @@ void MainTest::createPost2()
|
||||||
comment->setSaveDate(QDateTime::currentDateTime());
|
comment->setSaveDate(QDateTime::currentDateTime());
|
||||||
comment->setAuthor(user);
|
comment->setAuthor(user);
|
||||||
comment->setPostId(newPost->id());
|
comment->setPostId(newPost->id());
|
||||||
db.comments()->append(comment);
|
db.commentTable()->append(comment);
|
||||||
}
|
}
|
||||||
db.saveChanges();
|
db.saveChanges();
|
||||||
|
|
||||||
|
|
@ -121,9 +121,9 @@ void MainTest::createPost2()
|
||||||
|
|
||||||
void MainTest::selectPosts()
|
void MainTest::selectPosts()
|
||||||
{
|
{
|
||||||
auto q = db.posts()->query()
|
auto q = db.postTable()->query()
|
||||||
->join<Comment>()//Comment::authorIdField() == Post::idField())
|
->join<Comment>()//Comment::authorIdField() == Post::idField())
|
||||||
->orderBy(!Post::saveDateField() & Post::bodyField())
|
->orderBy(!Post::saveDateField() | Post::bodyField())
|
||||||
->setWhere(Post::idField() == postId);
|
->setWhere(Post::idField() == postId);
|
||||||
|
|
||||||
auto posts = q->toList();
|
auto posts = q->toList();
|
||||||
|
|
@ -144,7 +144,7 @@ void MainTest::selectPosts()
|
||||||
|
|
||||||
void MainTest::selectScoreAverage()
|
void MainTest::selectScoreAverage()
|
||||||
{
|
{
|
||||||
auto a = db.scores()->query()
|
auto a = db.scoreTable()->query()
|
||||||
->join<Post>()
|
->join<Post>()
|
||||||
->setWhere(Post::idField() == 1)
|
->setWhere(Post::idField() == 1)
|
||||||
->average(Score::scoreField());
|
->average(Score::scoreField());
|
||||||
|
|
@ -153,7 +153,7 @@ void MainTest::selectScoreAverage()
|
||||||
|
|
||||||
void MainTest::selectFirst()
|
void MainTest::selectFirst()
|
||||||
{
|
{
|
||||||
auto posts = db.posts()->query()
|
auto posts = db.postTable()->query()
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
QTEST_ASSERT(posts != Q_NULLPTR);
|
QTEST_ASSERT(posts != Q_NULLPTR);
|
||||||
|
|
@ -161,7 +161,7 @@ void MainTest::selectFirst()
|
||||||
|
|
||||||
void MainTest::selectPostsWithoutTitle()
|
void MainTest::selectPostsWithoutTitle()
|
||||||
{
|
{
|
||||||
auto q = db.posts()->query();
|
auto q = db.postTable()->query();
|
||||||
q->setWhere(Post::titleField().isNull());
|
q->setWhere(Post::titleField().isNull());
|
||||||
auto count = q->count();
|
auto count = q->count();
|
||||||
QTEST_ASSERT(count == 0);
|
QTEST_ASSERT(count == 0);
|
||||||
|
|
@ -169,8 +169,9 @@ void MainTest::selectPostsWithoutTitle()
|
||||||
|
|
||||||
void MainTest::selectPostIds()
|
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);
|
QTEST_ASSERT(ids.count() == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,11 +185,11 @@ void MainTest::testDate()
|
||||||
newPost->setTitle("post title");
|
newPost->setTitle("post title");
|
||||||
newPost->setSaveDate(d);
|
newPost->setSaveDate(d);
|
||||||
|
|
||||||
db.posts()->append(newPost);
|
db.postTable()->append(newPost);
|
||||||
|
|
||||||
db.saveChanges();
|
db.saveChanges();
|
||||||
|
|
||||||
auto q = db.posts()->query()
|
auto q = db.postTable()->query()
|
||||||
->setWhere(Post::idField() == newPost->id())
|
->setWhere(Post::idField() == newPost->id())
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
|
|
@ -198,7 +199,7 @@ void MainTest::testDate()
|
||||||
void MainTest::join()
|
void MainTest::join()
|
||||||
{
|
{
|
||||||
TIC();
|
TIC();
|
||||||
auto q = db.comments()->query()
|
auto q = db.commentTable()->query()
|
||||||
->join<User>()
|
->join<User>()
|
||||||
->join<Post>();
|
->join<Post>();
|
||||||
|
|
||||||
|
|
@ -213,14 +214,14 @@ void MainTest::join()
|
||||||
|
|
||||||
void MainTest::selectWithInvalidRelation()
|
void MainTest::selectWithInvalidRelation()
|
||||||
{
|
{
|
||||||
auto q = db.posts()->query();
|
auto q = db.postTable()->query();
|
||||||
q->join("Invalid_Class_Name");
|
q->join("Invalid_Class_Name");
|
||||||
q->toList();
|
q->toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::modifyPost()
|
void MainTest::modifyPost()
|
||||||
{
|
{
|
||||||
auto q = db.posts()->query();
|
auto q = db.postTable()->query();
|
||||||
q->setWhere(Post::idField() == postId);
|
q->setWhere(Post::idField() == postId);
|
||||||
|
|
||||||
Post *post = q->first();
|
Post *post = q->first();
|
||||||
|
|
@ -230,7 +231,7 @@ void MainTest::modifyPost()
|
||||||
post->setTitle("new name");
|
post->setTitle("new name");
|
||||||
db.saveChanges();
|
db.saveChanges();
|
||||||
|
|
||||||
q = db.posts()->query()
|
q = db.postTable()->query()
|
||||||
->setWhere(Post::idField() == postId);
|
->setWhere(Post::idField() == postId);
|
||||||
|
|
||||||
post = q->first();
|
post = q->first();
|
||||||
|
|
@ -240,8 +241,8 @@ void MainTest::modifyPost()
|
||||||
|
|
||||||
void MainTest::emptyDatabase()
|
void MainTest::emptyDatabase()
|
||||||
{
|
{
|
||||||
auto commentsCount = db.comments()->query()->remove();
|
auto commentsCount = db.commentTable()->query()->remove();
|
||||||
auto postsCount = db.posts()->query()->remove();
|
auto postsCount = db.postTable()->query()->remove();
|
||||||
QTEST_ASSERT(postsCount == 3);
|
QTEST_ASSERT(postsCount == 3);
|
||||||
QTEST_ASSERT(commentsCount == 6);
|
QTEST_ASSERT(commentsCount == 6);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#define POST_H
|
#define POST_H
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
|
#include <QtCore/QDateTime>
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "databasemodel.h"
|
#include "databasemodel.h"
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@
|
||||||
#include "weblogdatabase.h"
|
#include "weblogdatabase.h"
|
||||||
|
|
||||||
WeblogDatabase::WeblogDatabase() : Database(),
|
WeblogDatabase::WeblogDatabase() : Database(),
|
||||||
m_posts(new TableSet<Post>(this)),
|
m_postTable(new TableSet<Post>(this)),
|
||||||
m_comments(new TableSet<Comment>(this)),
|
m_commentTable(new TableSet<Comment>(this)),
|
||||||
m_users(new TableSet<User>(this)),
|
m_userTable(new TableSet<User>(this)),
|
||||||
m_scores(new TableSet<Score>(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