Merge pull request #11 from HamedMasafi/dev

Dev
This commit is contained in:
Hamed Masafi 2018-02-19 18:27:24 +03:30 committed by GitHub
commit 48d5738915
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 1645 additions and 344 deletions

6
appveyor.yml Normal file
View File

@ -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

0
include/header_copier Executable file → Normal file
View File

11
nut.pri
View File

@ -18,12 +18,14 @@ HEADERS += \
$$PWD/src/tablesetbase_p.h \
$$PWD/src/querybase_p.h \
$$PWD/src/tablemodel.h \
$$PWD/src/wherephrase.h \
$$PWD/src/query_p.h \
$$PWD/src/table.h \
$$PWD/src/database.h \
$$PWD/src/database_p.h \
$$PWD/src/serializableobject.h
$$PWD/src/serializableobject.h \
$$PWD/src/sqlmodel.h \
$$PWD/src/sqlmodel_p.h \
$$PWD/src/phrase.h
SOURCES += \
$$PWD/src/generators/sqlgeneratorbase.cpp \
@ -39,7 +41,8 @@ SOURCES += \
$$PWD/src/changelogtable.cpp \
$$PWD/src/querybase.cpp \
$$PWD/src/tablemodel.cpp \
$$PWD/src/wherephrase.cpp \
$$PWD/src/table.cpp \
$$PWD/src/database.cpp \
$$PWD/src/serializableobject.cpp
$$PWD/src/serializableobject.cpp \
$$PWD/src/sqlmodel.cpp \
$$PWD/src/phrase.cpp

View File

@ -20,6 +20,7 @@
#include <QtCore/QMetaProperty>
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
@ -495,6 +496,12 @@ SqlGeneratorBase *Database::sqlGenertor() const
return d->sqlGenertor;
}
QSqlDatabase Database::database()
{
Q_D(Database);
return d->db;
}
void Database::databaseUpdated(QString oldVersion, QString newVersion)
{
Q_UNUSED(oldVersion);

View File

@ -69,6 +69,7 @@ public:
QString tableName(QString className);
SqlGeneratorBase *sqlGenertor() const;
QSqlDatabase database();
protected:
//remove minor version

View File

@ -63,7 +63,7 @@ public:
TableSet<ChangeLogTable> *changeLogs;
QT_DEPRECATED
QHash<QString, QString> tables;
QMap<QString, QString> tables;
static QMap<QString, DatabaseModel> allTableMaps;
static qulonglong lastId;

View File

@ -100,6 +100,7 @@ public: \
#define NUT_AUTO_INCREMENT(x) NUT_INFO(__nut_AUTO_INCREMENT, x, 0)
#define NUT_PRIMARY_AUTO_INCREMENT(x) NUT_PRIMARY_KEY(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_LEN(field, len) NUT_INFO(__nut_LEN, field, len)
#define NUT_DEFAULT_VALUE(x, n) NUT_INFO(__nut_DEFAULT_VALUE, x, n)

View File

@ -34,6 +34,7 @@
#define __nut_TABLE "table"
#define __nut_TABLE_NAME "table_name"
#define __nut_DISPLAY "display"
#define __nut_LEN "len"
#define __nut_DEFAULT_VALUE "def"
#define __nut_NOT_NULL "notnull"

View File

@ -123,35 +123,35 @@ QVariant MySqlGenerator::readValue(const QVariant::Type &type, const QVariant &d
return SqlGeneratorBase::readValue(type, dbValue);
}
QString MySqlGenerator::phrase(const PhraseData *d) const
{
if (d->operatorCond == PhraseData::Distance) {
return QString("ST_Distance(%1, %2)")
.arg(d->left->text)
.arg(escapeValue(d->operand.toPointF()));
}
//QString MySqlGenerator::phrase(const PhraseData *d) const
//{
// if (d->operatorCond == PhraseData::Distance) {
// return QString("ST_Distance(%1, %2)")
// .arg(d->left->text)
// .arg(escapeValue(d->operand.toPointF()));
// }
return SqlGeneratorBase::phrase(d);
}
// return SqlGeneratorBase::phrase(d);
//}
QString MySqlGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
QString agregateArg,
QString tableName,
QList<WherePhrase> &wheres,
QList<WherePhrase> &orders,
QList<RelationModel*> joins,
int skip, int take)
{
QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
tableName,
wheres, orders,
joins, skip, take);
//QString MySqlGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
// QString agregateArg,
// QString tableName,
// QList<WherePhrase> &wheres,
// QList<WherePhrase> &orders,
// QList<RelationModel*> joins,
// int skip, int take)
//{
// QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
// tableName,
// wheres, orders,
// joins, skip, take);
if (take != -1 && skip != -1)
command.append(QString(" LIMIT %1 OFFSET %2")
.arg(take)
.arg(skip));
return command;
}
// if (take != -1 && skip != -1)
// command.append(QString(" LIMIT %1 OFFSET %2")
// .arg(take)
// .arg(skip));
// return command;
//}
NUT_END_NAMESPACE

View File

@ -34,8 +34,8 @@ public:
QString fieldType(FieldModel *field);
QString escapeValue(const QVariant &v) const;
QVariant readValue(const QVariant::Type &type, const QVariant &dbValue);
QString phrase(const PhraseData *d) const;
QString selectCommand(AgregateType t, QString agregateArg, QString tableName, QList<WherePhrase> &wheres, QList<WherePhrase> &orders, QList<RelationModel *> joins, int skip, int take);
// QString phrase(const PhraseData *d) const;
// QString selectCommand(AgregateType t, QString agregateArg, QString tableName, QList<WherePhrase> &wheres, QList<WherePhrase> &orders, QList<RelationModel *> joins, int skip, int take);
};
NUT_END_NAMESPACE

View File

@ -31,7 +31,6 @@
#include "../table.h"
#include "../databasemodel.h"
#include "../tablemodel.h"
#include "../wherephrase.h"
NUT_BEGIN_NAMESPACE
@ -355,10 +354,6 @@ QString SqlGeneratorBase::agregateText(const AgregateType &t,
const QString &arg) const
{
switch (t) {
case SelectAll:
return "*";
break;
case Min:
return "MIN(" + arg + ")";
break;
@ -426,48 +421,43 @@ QString SqlGeneratorBase::deleteRecords(QString tableName, QString where)
return sql;
}
QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
QString agregateArg,
QString tableName,
QList<WherePhrase> &wheres,
QList<WherePhrase> &orders,
QList<RelationModel*> joins,
int skip, int take)
QString SqlGeneratorBase::selectCommand(const QString &tableName,
const PhraseList &fields,
const ConditionalPhrase &where,
const PhraseList &order,
const QList<RelationModel*> joins,
const int skip,
const int take)
{
Q_UNUSED(take);
Q_UNUSED(skip);
Q_UNUSED(take);
QString selectText;
QStringList joinedOrders;
QString select = agregateText(t, agregateArg);
//TODO: temporatory disabled
if (t == SelectAll) {
if (!fields.isValid) {
QSet<TableModel*> tables;
tables.insert(_database->model().tableByName(tableName));
foreach (RelationModel *rel, joins)
tables << rel->masterTable << rel->slaveTable;
select = "";
selectText = "";
foreach (TableModel *t, tables) {
if (!select.isEmpty())
select.append(", ");
select.append(recordsPhrase(t));
if (!selectText.isEmpty())
selectText.append(", ");
selectText.append(recordsPhrase(t));
}
}
QString from = join(tableName, joins, &joinedOrders);
QString where = createWhere(wheres);
QString orderText = joinedOrders.join(", ");
foreach (WherePhrase p, orders) {
if (orderText != "")
orderText.append(", ");
orderText.append(phraseOrder(p.data()));
} else {
selectText = createFieldPhrase(fields);
}
QString sql = "SELECT " + select + " FROM " + from;
QStringList joinedOrders;
QString orderText = createOrderPhrase(order);
QString whereText = createConditionalPhrase(where.data);
QString fromText = join(tableName, joins, &joinedOrders);
if (where != "")
sql.append(" WHERE " + where);
QString sql = "SELECT " + selectText + " FROM " + fromText;
if (whereText != "")
sql.append(" WHERE " + whereText);
if (orderText != "")
sql.append(" ORDER BY " + orderText);
@ -481,20 +471,149 @@ QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
return sql + " ";
}
QString SqlGeneratorBase::createWhere(QList<WherePhrase> &wheres)
QString SqlGeneratorBase::selectCommand(const QString &tableName,
const SqlGeneratorBase::AgregateType &t,
const QString &agregateArg,
const ConditionalPhrase &where,
const QList<RelationModel *> &joins,
const int skip,
const int take)
{
QString whereText = "";
Q_UNUSED(skip);
Q_UNUSED(take);
QStringList joinedOrders;
QString selectText = agregateText(t, agregateArg);
QString whereText = createConditionalPhrase(where.data);
QString fromText = join(tableName, joins, &joinedOrders);
QString sql = "SELECT " + selectText + " FROM " + fromText;
foreach (WherePhrase w, wheres) {
if (whereText != "")
whereText.append(" AND ");
sql.append(" WHERE " + whereText);
whereText.append(phrase(w.data()));
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 + " ";
}
return whereText;
QString SqlGeneratorBase::deleteCommand(const QString &tableName,
const ConditionalPhrase &where)
{
QString command = "DELETE FROM " + tableName;
QString whereText = createConditionalPhrase(where.data);
if (whereText != "")
command.append(" WHERE " + whereText);
for (int i = 0; i < _database->model().count(); i++)
command = command.replace(_database->model().at(i)->className() + ".",
_database->model().at(i)->name() + ".");
replaceTableNames(command);
return command;
}
QString SqlGeneratorBase::updateCommand(const QString &tableName,
const AssignmentPhraseList &assigments,
const ConditionalPhrase &where)
{
QString assigmentTexts = "";
foreach (PhraseData *d, assigments.data) {
if (assigmentTexts != "")
assigmentTexts.append(", ");
assigmentTexts.append(createConditionalPhrase(d));
}
QString whereText = createConditionalPhrase(where.data);
QString sql = "UPDATE " + tableName + " SET " + assigmentTexts;
if (whereText != "")
sql.append(" WHERE " + whereText);
for (int i = 0; i < _database->model().count(); i++)
sql = sql.replace(_database->model().at(i)->className() + ".",
_database->model().at(i)->name() + ".");
removeTableNames(sql);
return sql;
}
//QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
// QString agregateArg,
// QString tableName,
// QList<WherePhrase> &wheres,
// QList<WherePhrase> &orders,
// QList<RelationModel*> joins,
// int skip, int take)
//{
// Q_UNUSED(take);
// Q_UNUSED(skip);
// QStringList joinedOrders;
// QString select = agregateText(t, agregateArg);
// //TODO: temporatory disabled
// if (t == SelectAll) {
// QSet<TableModel*> tables;
// tables.insert(_database->model().tableByName(tableName));
// foreach (RelationModel *rel, joins)
// tables << rel->masterTable << rel->slaveTable;
// select = "";
// foreach (TableModel *t, tables) {
// if (!select.isEmpty())
// select.append(", ");
// select.append(recordsPhrase(t));
// }
// }
// QString from = join(tableName, joins, &joinedOrders);
// QString where = createWhere(wheres);
// QString orderText = joinedOrders.join(", ");
// foreach (WherePhrase p, orders) {
// if (orderText != "")
// orderText.append(", ");
// orderText.append(phraseOrder(p.data()));
// }
// QString sql = "SELECT " + select + " FROM " + from;
// if (where != "")
// sql.append(" WHERE " + where);
// if (orderText != "")
// sql.append(" ORDER BY " + orderText);
// for (int i = 0; i < _database->model().count(); i++)
// sql = sql.replace(_database->model().at(i)->className() + ".",
// _database->model().at(i)->name() + ".");
// replaceTableNames(sql);
// return sql + " ";
//}
//QString SqlGeneratorBase::createWhere(QList<WherePhrase> &wheres)
//{
// QString whereText = "";
// foreach (WherePhrase w, wheres) {
// if (whereText != "")
// whereText.append(" AND ");
// whereText.append(phrase(w.data()));
// }
// return whereText;
//}
void SqlGeneratorBase::replaceTableNames(QString &command)
{
foreach (TableModel *m, TableModel::allModels())
@ -508,44 +627,44 @@ void SqlGeneratorBase::removeTableNames(QString &command)
command = command.replace("[" + m->className() + "].", "");
}
QString SqlGeneratorBase::deleteCommand(QList<WherePhrase> &wheres,
QString tableName)
{
QString command = "DELETE FROM " + tableName;
QString where = createWhere(wheres);
//QString SqlGeneratorBase::deleteCommand(QList<WherePhrase> &wheres,
// QString tableName)
//{
// QString command = "DELETE FROM " + tableName;
// QString where = createWhere(wheres);
if (where != "")
command.append(" WHERE " + where);
// if (where != "")
// command.append(" WHERE " + where);
for (int i = 0; i < _database->model().count(); i++)
command = command.replace(_database->model().at(i)->className() + ".",
_database->model().at(i)->name() + ".");
// for (int i = 0; i < _database->model().count(); i++)
// command = command.replace(_database->model().at(i)->className() + ".",
// _database->model().at(i)->name() + ".");
replaceTableNames(command);
// replaceTableNames(command);
return command;
}
// return command;
//}
QString SqlGeneratorBase::updateCommand(WherePhrase &phrase,
QList<WherePhrase> &wheres,
QString tableName)
{
QString p = this->phrase(phrase.data());
QString where = createWhere(wheres);
//QString SqlGeneratorBase::updateCommand(WherePhrase &phrase,
// QList<WherePhrase> &wheres,
// QString tableName)
//{
// QString p = this->phrase(phrase.data());
// QString where = createWhere(wheres);
QString sql = "UPDATE " + tableName + " SET " + p;
// QString sql = "UPDATE " + tableName + " SET " + p;
if (where != "")
sql.append(" WHERE " + where);
// if (where != "")
// sql.append(" WHERE " + where);
for (int i = 0; i < _database->model().count(); i++)
sql = sql.replace(_database->model().at(i)->className() + ".",
_database->model().at(i)->name() + ".");
// for (int i = 0; i < _database->model().count(); i++)
// sql = sql.replace(_database->model().at(i)->className() + ".",
// _database->model().at(i)->name() + ".");
removeTableNames(sql);
// removeTableNames(sql);
return sql;
}
// return sql;
//}
QString SqlGeneratorBase::escapeValue(const QVariant &v) const
{
@ -610,78 +729,13 @@ QVariant SqlGeneratorBase::readValue(const QVariant::Type &type,
return dbValue;
}
QString SqlGeneratorBase::phraseOrder(const PhraseData *d) const
{
QString ret = "";
switch (d->type) {
case PhraseData::Field:
if (d->operatorCond == PhraseData::Not)
ret = d->text + " DESC";
else
ret = d->text;
break;
case PhraseData::WithOther:
if (d->operatorCond != PhraseData::Append)
qFatal("Order phease can only have & operator");
ret = phraseOrder(d->left) + ", " + phraseOrder(d->right);
break;
case PhraseData::WithoutOperand:
case PhraseData::WithVariant:
break;
}
return ret;
}
QString SqlGeneratorBase::phrase(const PhraseData *d) const
{
QString ret = "";
switch (d->type) {
case PhraseData::Field:
ret = d->text;
break;
case PhraseData::WithVariant:
ret = phrase(d->left) + " " + operatorString(d->operatorCond) + " "
+ escapeValue(d->operand);
break;
case PhraseData::WithOther:
ret = phrase(d->left) + " " + operatorString(d->operatorCond) + " "
+ phrase(d->right);
break;
case PhraseData::WithoutOperand:
ret = phrase(d->left) + " " + operatorString(d->operatorCond);
break;
default:
ret = "<FAIL>";
}
if (d->operatorCond == PhraseData::And || d->operatorCond == PhraseData::Or)
ret = "(" + ret + ")";
return ret;
}
QString SqlGeneratorBase::phraseUpdate(const PhraseData *d) const
{
QString ret = "";
if (d->operatorCond != PhraseData::And
&& d->operatorCond != PhraseData::Equal)
qFatal("Update command does not accept any phrase else &, =");
switch (d->type) {
case PhraseData::Field:
ret = d->text;
ret = d->toString();
break;
case PhraseData::WithVariant:
@ -755,14 +809,139 @@ SqlGeneratorBase::operatorString(const PhraseData::Condition &cond) const
case PhraseData::Divide:
return "/";
case PhraseData::Set:
return "=";
// case PhraseData::Set:
// return "=";
case PhraseData::Append:
return ",";
// case PhraseData::Append:
// return ",";
case PhraseData::Between:
return "BETWEEN";
case PhraseData::Mod:
return "MOD";
default:
return QString("<FAIL>");
return QString("<FAIL cond> %1").arg(cond);
}
}
QString SqlGeneratorBase::createConditionalPhrase(const PhraseData *d) const
{
if (!d)
return "";
QString ret = "";
PhraseData::Condition op = d->operatorCond;
//apply not (!)
if (d->isNot) {
if (op < 20)
op = (PhraseData::Condition)((op + 10) % 20);
}
switch (d->type) {
case PhraseData::Field:
ret = d->toString();
break;
case PhraseData::WithVariant:
if (op == PhraseData::AddYears)
ret = QString("DATEADD(year, %1, %2)")
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
else if (op == PhraseData::AddMonths)
ret = QString("DATEADD(month, %1, %2)")
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
else if (op == PhraseData::AddYears)
ret = QString("DATEADD(day, %1, %2)")
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
else if (op == PhraseData::AddHours)
ret = QString("DATEADD(hour, %1, %2)")
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
else if (op == PhraseData::AddMinutes)
ret = QString("DATEADD(minute, %1, %2)")
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
else if (op == PhraseData::AddSeconds)
ret = QString("DATEADD(second, %1, %2)")
.arg(d->operand.toString()).arg(createConditionalPhrase(d->left));
else
ret = createConditionalPhrase(d->left) + " " + operatorString(op) + " "
+ escapeValue(d->operand);
break;
case PhraseData::WithOther:
ret = createConditionalPhrase(d->left) + " " + operatorString(op) + " "
+ createConditionalPhrase(d->right);
break;
case PhraseData::WithoutOperand:
ret = createConditionalPhrase(d->left) + " " + operatorString(op);
break;
default:
ret = "<FAIL phrase>";
}
if (d->operatorCond == PhraseData::And || d->operatorCond == PhraseData::Or)
ret = "(" + ret + ")";
return ret;
}
QString SqlGeneratorBase::createOrderPhrase(const PhraseList &ph)
{
QString ret = "";
foreach (const PhraseData *d, ph.data) {
if (ret != "")
ret.append(", ");
ret.append(d->toString());
if (d->isNot)
ret.append(" DESC");
}
return ret;
}
QString SqlGeneratorBase::createFieldPhrase(const PhraseList &ph)
{
QString ret = "";
foreach (const PhraseData *d, ph.data) {
if (ret != "")
ret.append(", ");
ret.append(d->toString());
if (d->isNot)
qDebug() << "Operator ! is ignored in fields phrase";
}
return ret;
}
void SqlGeneratorBase::createInsertPhrase(const AssignmentPhraseList &ph, QString &fields, QString &values)
{
foreach (PhraseData *d, ph.data) {
if (fields != "")
fields.append(", ");
if (values != "")
values.append(", ");
switch (d->type) {
case PhraseData::WithVariant:
fields.append(d->left->toString());
values.append(escapeValue(d->operand));
// ret = createConditionalPhrase(d->left->toString()) + " " + operatorString(d->operatorCond) + " "
// + escapeValue(d->operand);
break;
case PhraseData::WithOther:
fields.append(d->left->toString());
values.append(d->right->toString());
break;
case PhraseData::Field:
case PhraseData::WithoutOperand:
default:
qFatal("Invalid insert command");
}
}
}

View File

@ -24,7 +24,8 @@
#include <QtCore/qglobal.h>
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include "../wherephrase.h"
#include "../phrase.h"
//#include "../wherephrase.h"
NUT_BEGIN_NAMESPACE
@ -47,7 +48,7 @@ public:
Delete
};
enum AgregateType{
SelectAll,
// SelectAll,
Count,
Min,
Max,
@ -83,28 +84,51 @@ public:
virtual QString deleteRecord(Table *t, QString tableName);
virtual QString deleteRecords(QString tableName, QString where);
virtual QString selectCommand(AgregateType t,
QString agregateArg, QString tableName,
QList<WherePhrase> &wheres,
QList<WherePhrase> &orders,
QList<RelationModel*> joins,
int skip = -1, int take = -1);
virtual QString selectCommand(const QString &tableName,
const PhraseList &fields,
const ConditionalPhrase &where,
const PhraseList &order,
const QList<RelationModel*> joins,
const int skip = -1,
const int take = -1);
virtual QString deleteCommand(QList<WherePhrase> &wheres, QString tableName);
virtual QString selectCommand(const QString &tableName,
const AgregateType &t, const QString &agregateArg,
const ConditionalPhrase &where,
const QList<RelationModel *> &joins,
const int skip = -1,
const int take = -1);
virtual QString updateCommand(WherePhrase &phrase, QList<WherePhrase> &wheres, QString tableName);
virtual QString deleteCommand(const QString &tableName,
const ConditionalPhrase &where);
virtual QString updateCommand(const QString &tableName,
const AssignmentPhraseList &assigments,
const ConditionalPhrase &where);
// virtual QString selectCommand(AgregateType t,
// QString agregateArg, QString tableName,
// QList<WherePhrase> &wheres,
// QList<WherePhrase> &orders,
// QList<RelationModel*> joins,
// int skip = -1, int take = -1);
// virtual QString deleteCommand(QList<WherePhrase> &wheres, QString tableName);
// virtual QString updateCommand(WherePhrase &phrase, QList<WherePhrase> &wheres, QString tableName);
virtual QString escapeValue(const QVariant &v) const;
virtual QVariant readValue(const QVariant::Type &type, const QVariant &dbValue);
virtual QString phrase(const PhraseData *d) const;
virtual QString phraseUpdate(const PhraseData *d) const;
virtual QString operatorString(const PhraseData::Condition &cond) const;
private:
QString createConditionalPhrase(const PhraseData *d) const;
QString createFieldPhrase(const PhraseList &ph);
QString createOrderPhrase(const PhraseList &ph);
void createInsertPhrase(const AssignmentPhraseList &ph, QString &fields, QString &values);
QString agregateText(const AgregateType &t, const QString &arg = QString::null) const;
QString fromTableText(const QString &tableName, QString &joinClassName, QString &orderBy) const;
QString createWhere(QList<WherePhrase> &wheres);
QString phraseOrder(const PhraseData *d) const;
// QString createWhere(QList<WherePhrase> &wheres);
void replaceTableNames(QString &command);
void removeTableNames(QString &command);
};

View File

@ -71,24 +71,24 @@ QString SqliteGenerator::fieldType(FieldModel *field)
return dbType;
}
QString SqliteGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
QString agregateArg,
QString tableName,
QList<WherePhrase> &wheres,
QList<WherePhrase> &orders,
QList<RelationModel*> joins,
int skip, int take)
{
QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
tableName,
wheres, orders,
joins, skip, take);
//QString SqliteGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
// QString agregateArg,
// QString tableName,
// QList<WherePhrase> &wheres,
// QList<WherePhrase> &orders,
// QList<RelationModel*> joins,
// int skip, int take)
//{
// QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
// tableName,
// wheres, orders,
// joins, skip, take);
if (take != -1 && skip != -1)
command.append(QString(" LIMIT %1 OFFSET %2")
.arg(take)
.arg(skip));
return command;
}
// if (take != -1 && skip != -1)
// command.append(QString(" LIMIT %1 OFFSET %2")
// .arg(take)
// .arg(skip));
// return command;
//}
NUT_END_NAMESPACE

View File

@ -33,11 +33,11 @@ public:
QString fieldType(FieldModel *field);
QString selectCommand(AgregateType t, QString agregateArg,
QString tableName,
QList<WherePhrase> &wheres,
QList<WherePhrase> &orders,
QList<RelationModel *> joins, int skip, int take);
// QString selectCommand(AgregateType t, QString agregateArg,
// QString tableName,
// QList<WherePhrase> &wheres,
// QList<WherePhrase> &orders,
// QList<RelationModel *> joins, int skip, int take);
};
NUT_END_NAMESPACE

View File

@ -133,23 +133,23 @@ QString SqlServerGenerator::escapeValue(const QVariant &v) const
return SqlGeneratorBase::escapeValue(v);
}
QString SqlServerGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
QString agregateArg,
QString tableName,
QList<WherePhrase> &wheres,
QList<WherePhrase> &orders,
QList<RelationModel*> joins, int skip, int take)
{
QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
tableName,
wheres, orders,
joins, skip, take);
//QString SqlServerGenerator::selectCommand(SqlGeneratorBase::AgregateType t,
// QString agregateArg,
// QString tableName,
// QList<WherePhrase> &wheres,
// QList<WherePhrase> &orders,
// QList<RelationModel*> joins, int skip, int take)
//{
// QString command = SqlGeneratorBase::selectCommand(t, agregateArg,
// tableName,
// wheres, orders,
// joins, skip, take);
if (take != -1 && skip != -1)
command.append(QString("OFFSET %1 ROWS FETCH NEXT %2 ROWS ONLY")
.arg(skip)
.arg(take));
return command;
}
// if (take != -1 && skip != -1)
// command.append(QString("OFFSET %1 ROWS FETCH NEXT %2 ROWS ONLY")
// .arg(skip)
// .arg(take));
// return command;
//}
NUT_END_NAMESPACE

View File

@ -38,11 +38,11 @@ public:
QString escapeValue(const QVariant &v) const;
QString selectCommand(AgregateType t, QString agregateArg,
QString tableName,
QList<WherePhrase> &wheres,
QList<WherePhrase> &orders,
QList<RelationModel *> joins, int skip, int take);
// QString selectCommand(AgregateType t, QString agregateArg,
// QString tableName,
// QList<WherePhrase> &wheres,
// QList<WherePhrase> &orders,
// QList<RelationModel *> joins, int skip, int take);
};
NUT_END_NAMESPACE

377
src/phrase.cpp Normal file
View File

@ -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

391
src/phrase.h Normal file
View File

@ -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

View File

@ -28,6 +28,7 @@
#include <QtCore/QMetaObject>
#include <QtSql/QSqlResult>
#include <QtSql/QSqlError>
#include <QtSql/QSqlQueryModel>
#include "query_p.h"
#include "database.h"
@ -35,7 +36,7 @@
#include "tablesetbase_p.h"
#include "generators/sqlgeneratorbase_p.h"
#include "querybase_p.h"
#include "wherephrase.h"
#include "phrase.h"
#include "tablemodel.h"
NUT_BEGIN_NAMESPACE
@ -53,7 +54,6 @@ public:
~Query();
//ddl
Query<T> *setWhere(WherePhrase where);
Query<T> *join(const QString &className);
Query<T> *join(Table *c);
@ -68,7 +68,11 @@ public:
// Query<T> *orderBy(QString fieldName, QString type);
Query<T> *skip(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(Table *t);
@ -83,9 +87,12 @@ public:
QVariant average(const FieldPhrase<int> &f);
//data mailpulation
int update(WherePhrase phrase);
int update(const AssignmentPhraseList &ph);
// int insert(const AssignmentPhraseList &ph);
int remove();
QSqlQueryModel *toModal();
//debug purpose
QString sqlCommand() const;
};
@ -118,6 +125,7 @@ Q_OUTOFLINE_TEMPLATE Query<T>::~Query()
{
Q_D(Query);
delete d;
qDebug() << "~Query";
}
template <class T>
@ -129,10 +137,9 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
d->select = "*";
d->sql = d->database->sqlGenertor()->selectCommand(
SqlGeneratorBase::SelectAll, "",
d->tableName,
d->wheres, d->orderPhrases, d->relations,
d->skip, d->take);
d->tableName, d->fieldPhrase, d->wherePhrase, d->orderPhrase,
d->relations, d->skip, d->take);
qDebug() <<d->sql;
QSqlQuery q = d->database->exec(d->sql);
if (q.lastError().isValid()) {
qDebug() << q.lastError().text();
@ -144,7 +151,6 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
foreach (RelationModel *rel, d->relations)
relatedTables << rel->slaveTable << rel->masterTable;
struct LevelData{
QList<int> masters;
QList<int> slaves;
@ -251,6 +257,9 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
= QMetaType::metaObjectForType(data.table->typeId());
table = qobject_cast<Table *>(childMetaObject->newInstance());
if (!table)
qFatal("Could not create instance of %s",
qPrintable(data.table->name()));
}
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->sql = d->database->sqlGenertor()->selectCommand(
SqlGeneratorBase::SignleField, f.data()->text,
d->tableName, d->wheres,
d->orderPhrases, d->relations, d->skip, d->take);
d->tableName,
SqlGeneratorBase::SignleField, f.data->toString(),
d->wherePhrase,
d->relations,
d->skip, d->take);
QSqlQuery q = d->database->exec(d->sql);
@ -329,11 +340,11 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::count()
d->joins.prepend(d->tableName);
d->select = "COUNT(*)";
d->sql = d->database->sqlGenertor()->selectCommand(SqlGeneratorBase::Count,
QStringLiteral("*"),
d->sql = d->database->sqlGenertor()->selectCommand(
d->tableName,
d->wheres,
d->orderPhrases,
SqlGeneratorBase::Count,
QStringLiteral("*"),
d->wherePhrase,
d->relations);
QSqlQuery q = d->database->exec(d->sql);
@ -349,8 +360,9 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(const FieldPhrase<int> &f)
d->joins.prepend(d->tableName);
d->sql = d->database->sqlGenertor()->selectCommand(
SqlGeneratorBase::Max, f.data()->text, d->tableName,
d->wheres, d->orderPhrases,
d->tableName,
SqlGeneratorBase::Max, f.data->toString(),
d->wherePhrase,
d->relations);
QSqlQuery q = d->database->exec(d->sql);
@ -366,8 +378,9 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(const FieldPhrase<int> &f)
d->joins.prepend(d->tableName);
d->sql = d->database->sqlGenertor()->selectCommand(
SqlGeneratorBase::Min, f.data()->text, d->tableName,
d->wheres, d->orderPhrases,
d->tableName,
SqlGeneratorBase::Min, f.data->toString(),
d->wherePhrase,
d->relations);
QSqlQuery q = d->database->exec(d->sql);
@ -383,8 +396,9 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::average(const FieldPhrase<int> &f)
d->joins.prepend(d->tableName);
d->sql = d->database->sqlGenertor()->selectCommand(
SqlGeneratorBase::Average, f.data()->text, d->tableName,
d->wheres, d->orderPhrases,
d->tableName,
SqlGeneratorBase::Average, f.data->toString(),
d->wherePhrase,
d->relations);
QSqlQuery q = d->database->exec(d->sql);
@ -423,10 +437,21 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::join(Table *c)
}
template <class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::setWhere(WherePhrase where)
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::where(const ConditionalPhrase &ph)
{
Q_D(Query);
d->wheres.append(where);
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;
}
@ -446,6 +471,14 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::take(int n)
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>
//Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(QString fieldName,
// QString type)
@ -456,10 +489,10 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::take(int n)
//}
template <class T>
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(WherePhrase phrase)
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(const PhraseList &ph)
{
Q_D(Query);
d->orderPhrases.append(phrase);
d->orderPhrase = ph;
return this;
}
@ -478,12 +511,14 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::include(Table *t)
}
template <class T>
Q_OUTOFLINE_TEMPLATE int Query<T>::update(WherePhrase phrase)
Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph)
{
Q_D(Query);
d->sql = d->database->sqlGenertor()->updateCommand(phrase, d->wheres,
d->tableName);
d->sql = d->database->sqlGenertor()->updateCommand(
d->tableName,
ph,
d->wherePhrase);
QSqlQuery q = d->database->exec(d->sql);
if (m_autoDelete)
@ -496,7 +531,8 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::remove()
{
Q_D(Query);
d->sql = d->database->sqlGenertor()->deleteCommand(d->wheres, d->tableName);
d->sql = d->database->sqlGenertor()->deleteCommand(
d->tableName, d->wherePhrase);
QSqlQuery q = d->database->exec(d->sql);
if (m_autoDelete)
@ -504,6 +540,36 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::remove()
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>
Q_OUTOFLINE_TEMPLATE QString Query<T>::sqlCommand() const
{

View File

@ -21,7 +21,7 @@
#ifndef QUERY_P_H
#define QUERY_P_H
#include "wherephrase.h"
#include "phrase.h"
#include <QList>
#include <QString>
@ -48,11 +48,15 @@ public:
TableSetBase *tableSet;
QStringList joins;
QList<RelationModel*> relations;
QList<WherePhrase> wheres;
QList<WherePhrase> orderPhrases;
QHash<QString, QString> orders;
int skip;
int take;
PhraseList orderPhrase, fieldPhrase;
ConditionalPhrase wherePhrase;
// QList<WherePhrase> wheres;
// QList<WherePhrase> orderPhrases;
// QList<WherePhrase> fields;
// QHash<QString, QString> orders;
};
NUT_END_NAMESPACE

88
src/sqlmodel.cpp Normal file
View File

@ -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

52
src/sqlmodel.h Normal file
View File

@ -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

24
src/sqlmodel_p.h Normal file
View File

@ -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

View File

@ -27,7 +27,7 @@
#include "tablemodel.h"
#include "defines.h"
#include "wherephrase.h"
#include "phrase.h"
NUT_BEGIN_NAMESPACE

View File

@ -66,6 +66,14 @@ void TableModel::setTypeId(const int &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
{
foreach (FieldModel *f, _fields)
@ -195,7 +203,7 @@ TableModel::TableModel(int typeId, QString tableName)
if(type == __nut_FIELD){
FieldModel *f = new FieldModel;
f->name = name;
f->name = f->displayName = name;
_fields.append(f);
}
}
@ -255,8 +263,8 @@ TableModel::TableModel(int typeId, QString tableName)
f->isAutoIncrement = true;
else if(type == __nut_UNIQUE)
f->isUnique = true;
else if(type == __nut_DISPLAY)
f->displayName = value.mid(1, value.length() - 2);
}
if(!findByTypeId(typeId) && !tableName.isNull())

View File

@ -47,6 +47,7 @@ struct FieldModel{
bool isPrimaryKey;
bool isAutoIncrement;
bool isUnique;
QString displayName;
bool operator ==(const FieldModel &f) const{
@ -88,6 +89,7 @@ public:
// static void createForegionKeys();
// static TableModel* model(QString className);
FieldModel *field(int n) const;
FieldModel *field(QString name) const;
RelationModel *foregionKey(QString otherTable) const;

View File

@ -19,3 +19,4 @@
**************************************************************************/
#include "tableset.h"

View File

@ -28,7 +28,6 @@
#include <QtSql/QSqlQuery>
#include "tablesetbase_p.h"
//#include "database.h"
#include "table.h"
NUT_BEGIN_NAMESPACE

View File

@ -21,7 +21,7 @@
#include <QDataStream>
#include <QDebug>
#include "wherephrase.h"
#include "phrase.h"
NUT_BEGIN_NAMESPACE

View File

@ -18,8 +18,8 @@
**
**************************************************************************/
#ifndef PHRASE_H
#define PHRASE_H
#ifndef WHEREPHRASE_H
#define WHEREPHRASE_H
#include <QtCore/qglobal.h>
@ -39,58 +39,58 @@
NUT_BEGIN_NAMESPACE
class SqlGeneratorBase;
class PhraseData
{
public:
enum Condition {
NotAssign = 0,
Equal,
Less,
LessEqual,
Null,
In,
Like,
//class PhraseData
//{
//public:
// enum Condition {
// NotAssign = 0,
// Equal,
// Less,
// LessEqual,
// Null,
// In,
// Like,
Not = 10,
NotEqual,
GreaterEqual,
Greater,
NotNull,
NotIn,
NotLike,
// Not = 10,
// NotEqual,
// GreaterEqual,
// Greater,
// NotNull,
// NotIn,
// NotLike,
And = 20,
Or,
// And = 20,
// Or,
Append,
Set,
// Append,
// Set,
Add,
Minus,
Multiple,
Divide,
// Add,
// Minus,
// Multiple,
// Divide,
// special types
Distance
};
// // special types
// Distance
// };
enum Type { Field, WithVariant, WithOther, WithoutOperand };
Type type;
// enum Type { Field, WithVariant, WithOther, WithoutOperand };
// Type type;
Condition operatorCond;
// Condition operatorCond;
QString text;
const PhraseData *left;
const PhraseData *right;
QVariant operand;
// QString text;
// const PhraseData *left;
// const PhraseData *right;
// QVariant operand;
PhraseData(const char *className, const char *s);
PhraseData(PhraseData *l, Condition o);
PhraseData(PhraseData *l, Condition o, const PhraseData *r);
PhraseData(PhraseData *l, Condition o, QVariant r);
// PhraseData(const char *className, const char *s);
// PhraseData(PhraseData *l, Condition o);
// PhraseData(PhraseData *l, Condition o, const PhraseData *r);
// PhraseData(PhraseData *l, Condition o, QVariant r);
~PhraseData();
};
// ~PhraseData();
//};
class WherePhrase
{

View File

@ -42,8 +42,8 @@ void MainTest::initTestCase()
bool ok = db.open();
db.comments()->query()->remove();
db.posts()->query()->remove();
db.commentTable()->query()->remove();
db.postTable()->query()->remove();
QTEST_ASSERT(ok);
}
@ -63,7 +63,7 @@ void MainTest::createUser()
user = new User;
user->setUsername("admin");
user->setPassword("123456");
db.users()->append(user);
db.userTable()->append(user);
db.saveChanges();
}
@ -73,7 +73,7 @@ void MainTest::createPost()
newPost->setTitle("post title");
newPost->setSaveDate(QDateTime::currentDateTime());
db.posts()->append(newPost);
db.postTable()->append(newPost);
for(int i = 0 ; i < 3; i++){
Comment *comment = new Comment;
@ -102,7 +102,7 @@ void MainTest::createPost2()
newPost->setTitle("post title");
newPost->setSaveDate(QDateTime::currentDateTime());
db.posts()->append(newPost);
db.postTable()->append(newPost);
db.saveChanges();
for(int i = 0 ; i < 3; i++){
@ -111,7 +111,7 @@ void MainTest::createPost2()
comment->setSaveDate(QDateTime::currentDateTime());
comment->setAuthor(user);
comment->setPostId(newPost->id());
db.comments()->append(comment);
db.commentTable()->append(comment);
}
db.saveChanges();
@ -121,9 +121,9 @@ void MainTest::createPost2()
void MainTest::selectPosts()
{
auto q = db.posts()->query()
auto q = db.postTable()->query()
->join<Comment>()//Comment::authorIdField() == Post::idField())
->orderBy(!Post::saveDateField() & Post::bodyField())
->orderBy(!Post::saveDateField() | Post::bodyField())
->setWhere(Post::idField() == postId);
auto posts = q->toList();
@ -144,7 +144,7 @@ void MainTest::selectPosts()
void MainTest::selectScoreAverage()
{
auto a = db.scores()->query()
auto a = db.scoreTable()->query()
->join<Post>()
->setWhere(Post::idField() == 1)
->average(Score::scoreField());
@ -153,7 +153,7 @@ void MainTest::selectScoreAverage()
void MainTest::selectFirst()
{
auto posts = db.posts()->query()
auto posts = db.postTable()->query()
->first();
QTEST_ASSERT(posts != Q_NULLPTR);
@ -161,7 +161,7 @@ void MainTest::selectFirst()
void MainTest::selectPostsWithoutTitle()
{
auto q = db.posts()->query();
auto q = db.postTable()->query();
q->setWhere(Post::titleField().isNull());
auto count = q->count();
QTEST_ASSERT(count == 0);
@ -169,8 +169,9 @@ void MainTest::selectPostsWithoutTitle()
void MainTest::selectPostIds()
{
auto ids = db.posts()->query()->select(Post::idField());
auto q = db.postTable()->query();
auto ids = q->select(Post::idField());
qDebug() << q->sqlCommand();
QTEST_ASSERT(ids.count() == 2);
}
@ -184,11 +185,11 @@ void MainTest::testDate()
newPost->setTitle("post title");
newPost->setSaveDate(d);
db.posts()->append(newPost);
db.postTable()->append(newPost);
db.saveChanges();
auto q = db.posts()->query()
auto q = db.postTable()->query()
->setWhere(Post::idField() == newPost->id())
->first();
@ -198,7 +199,7 @@ void MainTest::testDate()
void MainTest::join()
{
TIC();
auto q = db.comments()->query()
auto q = db.commentTable()->query()
->join<User>()
->join<Post>();
@ -213,14 +214,14 @@ void MainTest::join()
void MainTest::selectWithInvalidRelation()
{
auto q = db.posts()->query();
auto q = db.postTable()->query();
q->join("Invalid_Class_Name");
q->toList();
}
void MainTest::modifyPost()
{
auto q = db.posts()->query();
auto q = db.postTable()->query();
q->setWhere(Post::idField() == postId);
Post *post = q->first();
@ -230,7 +231,7 @@ void MainTest::modifyPost()
post->setTitle("new name");
db.saveChanges();
q = db.posts()->query()
q = db.postTable()->query()
->setWhere(Post::idField() == postId);
post = q->first();
@ -240,8 +241,8 @@ void MainTest::modifyPost()
void MainTest::emptyDatabase()
{
auto commentsCount = db.comments()->query()->remove();
auto postsCount = db.posts()->query()->remove();
auto commentsCount = db.commentTable()->query()->remove();
auto postsCount = db.postTable()->query()->remove();
QTEST_ASSERT(postsCount == 3);
QTEST_ASSERT(commentsCount == 6);
}

View File

@ -2,6 +2,7 @@
#define POST_H
#include <QtCore/qglobal.h>
#include <QtCore/QDateTime>
#include "table.h"
#include "database.h"
#include "databasemodel.h"

View File

@ -8,9 +8,9 @@
#include "weblogdatabase.h"
WeblogDatabase::WeblogDatabase() : Database(),
m_posts(new TableSet<Post>(this)),
m_comments(new TableSet<Comment>(this)),
m_users(new TableSet<User>(this)),
m_scores(new TableSet<Score>(this))
m_postTable(new TableSet<Post>(this)),
m_commentTable(new TableSet<Comment>(this)),
m_userTable(new TableSet<User>(this)),
m_scoreTable(new TableSet<Score>(this))
{
}

27
test/phrases/maintest.cpp Normal file
View File

@ -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)

23
test/phrases/maintest.h Normal file
View File

@ -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

View File

@ -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