commit
da95ce93bf
|
|
@ -71,6 +71,7 @@ before_script:
|
||||||
- '[[ "$TRAVIS_OS_NAME" != linux || "$PPA" == */opt-* ]] || export QT_SELECT=qt5'
|
- '[[ "$TRAVIS_OS_NAME" != linux || "$PPA" == */opt-* ]] || export QT_SELECT=qt5'
|
||||||
- mkdir -p "$TRAVIS_BUILD_DIR-build"
|
- mkdir -p "$TRAVIS_BUILD_DIR-build"
|
||||||
- cd "$TRAVIS_BUILD_DIR-build"
|
- cd "$TRAVIS_BUILD_DIR-build"
|
||||||
|
- echo 'QT -= gui' >> ""$TRAVIS_BUILD_DIR/ci-test-init.pri"
|
||||||
- qmake -r -Wall -Wlogic -Wparser CONFIG+=debug_and_release "$TRAVIS_BUILD_DIR/nut.pro"
|
- qmake -r -Wall -Wlogic -Wparser CONFIG+=debug_and_release "$TRAVIS_BUILD_DIR/nut.pro"
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
|
|
||||||
Binary file not shown.
123
src/defines.h
123
src/defines.h
|
|
@ -102,14 +102,15 @@ public slots:
|
||||||
Q_PROPERTY(keytype name##Id READ read##Id WRITE write##Id) \
|
Q_PROPERTY(keytype name##Id READ read##Id WRITE write##Id) \
|
||||||
public: \
|
public: \
|
||||||
Nut::Row<type> read() const; \
|
Nut::Row<type> read() const; \
|
||||||
void write(Nut::Row<type> name); \
|
keytype read##Id() const; \
|
||||||
static NUT_WRAP_NAMESPACE(FieldPhrase<keytype>)& name##Id ## Field(){ \
|
static NUT_WRAP_NAMESPACE(FieldPhrase<keytype>)& name##Id ## Field(){ \
|
||||||
static NUT_WRAP_NAMESPACE(FieldPhrase<keytype>) f = \
|
static NUT_WRAP_NAMESPACE(FieldPhrase<keytype>) f = \
|
||||||
NUT_WRAP_NAMESPACE(FieldPhrase<keytype>) \
|
NUT_WRAP_NAMESPACE(FieldPhrase<keytype>) \
|
||||||
(staticMetaObject.className(), #name); \
|
(staticMetaObject.className(), #name); \
|
||||||
return f; \
|
return f; \
|
||||||
} \
|
} \
|
||||||
keytype read##Id() const; \
|
public slots: \
|
||||||
|
void write(Nut::Row<type> name); \
|
||||||
void write##Id(keytype name##Id);
|
void write##Id(keytype name##Id);
|
||||||
|
|
||||||
#define NUT_FOREIGN_KEY_IMPLEMENT(class, type, keytype, name, read, write) \
|
#define NUT_FOREIGN_KEY_IMPLEMENT(class, type, keytype, name, read, write) \
|
||||||
|
|
@ -177,73 +178,69 @@ NUT_BEGIN_NAMESPACE
|
||||||
inline bool nutClassInfo(const QMetaClassInfo &classInfo,
|
inline bool nutClassInfo(const QMetaClassInfo &classInfo,
|
||||||
QString &type, QString &name, QVariant &value)
|
QString &type, QString &name, QVariant &value)
|
||||||
{
|
{
|
||||||
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX)) {
|
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
QStringList parts = QString(classInfo.value()).split("\n");
|
|
||||||
if (parts.count() != 3)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
type = parts[0];
|
QStringList parts = QString(classInfo.value()).split("\n");
|
||||||
name = parts[1];
|
if (parts.count() != 3)
|
||||||
value = qVariantFromValue(parts[2]);
|
return false;
|
||||||
return true;
|
|
||||||
}
|
type = parts[0];
|
||||||
|
name = parts[1];
|
||||||
|
value = qVariantFromValue(parts[2]);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool nutClassInfoString(const QMetaClassInfo &classInfo,
|
inline bool nutClassInfoString(const QMetaClassInfo &classInfo,
|
||||||
QString &type, QString &name, QString &value)
|
QString &type, QString &name, QString &value)
|
||||||
{
|
{
|
||||||
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX)) {
|
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
QStringList parts = QString(classInfo.value()).split("\n");
|
|
||||||
if (parts.count() != 3)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
type = parts[0];
|
QStringList parts = QString(classInfo.value()).split("\n");
|
||||||
name = parts[1];
|
if (parts.count() != 3)
|
||||||
value = parts[2];
|
return false;
|
||||||
return true;
|
|
||||||
}
|
type = parts[0];
|
||||||
|
name = parts[1];
|
||||||
|
value = parts[2];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool nutClassInfoBool(const QMetaClassInfo &classInfo,
|
inline bool nutClassInfoBool(const QMetaClassInfo &classInfo,
|
||||||
QString &type, QString &name, bool &value)
|
QString &type, QString &name, bool &value)
|
||||||
{
|
{
|
||||||
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX)) {
|
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
QStringList parts = QString(classInfo.value()).split("\n");
|
|
||||||
if (parts.count() != 3)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QString buffer = parts[2].toLower();
|
QStringList parts = QString(classInfo.value()).split("\n");
|
||||||
if (buffer != "true" && buffer != "false")
|
if (parts.count() != 3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
type = parts[0];
|
QString buffer = parts[2].toLower();
|
||||||
name = parts[1];
|
if (buffer != "true" && buffer != "false")
|
||||||
value = (buffer == "true");
|
return false;
|
||||||
return true;
|
|
||||||
}
|
type = parts[0];
|
||||||
|
name = parts[1];
|
||||||
|
value = (buffer == "true");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool nutClassInfoInt(const QMetaClassInfo &classInfo,
|
inline bool nutClassInfoInt(const QMetaClassInfo &classInfo,
|
||||||
QString &type, QString &name, bool &value)
|
QString &type, QString &name, bool &value)
|
||||||
{
|
{
|
||||||
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX)) {
|
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
QStringList parts = QString(classInfo.value()).split("\n");
|
QStringList parts = QString(classInfo.value()).split("\n");
|
||||||
if (parts.count() != 3)
|
if (parts.count() != 3)
|
||||||
return false;
|
return false;
|
||||||
bool ok;
|
bool ok;
|
||||||
type = parts[0];
|
type = parts[0];
|
||||||
name = parts[1];
|
name = parts[1];
|
||||||
value = parts[2].toInt(&ok);
|
value = parts[2].toInt(&ok);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NUT_SHARED_POINTER
|
#ifdef NUT_SHARED_POINTER
|
||||||
|
|
@ -267,12 +264,12 @@ inline Row<T> create(QObject *parent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline T *get(T *row) {
|
inline Row<T> createFrom(T *row) {
|
||||||
return row;
|
return QSharedPointer<T>(row);
|
||||||
}
|
}
|
||||||
template<class T>
|
template<class T>
|
||||||
inline T *get(const QSharedPointer<T> row) {
|
inline Row<T> createFrom(const QSharedPointer<T> row) {
|
||||||
return row.data();
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
@ -302,32 +299,6 @@ inline T *get(const QSharedPointer<T> row) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//template<class C, typename T>
|
|
||||||
//struct ForeignKeyData {
|
|
||||||
// Nut::Row<C> _table;
|
|
||||||
// T _id;
|
|
||||||
|
|
||||||
// ForeignKeyData() : _table(nullptr)
|
|
||||||
// {}
|
|
||||||
|
|
||||||
// void setTable(Nut::Row<C> t) {
|
|
||||||
// _table = t;
|
|
||||||
// _id = t->primaryValue().value<T>();
|
|
||||||
// }
|
|
||||||
// Nut::Row<C> table() const {
|
|
||||||
// return _table;
|
|
||||||
// }
|
|
||||||
// void setValue(const T& val) {
|
|
||||||
// _table = nullptr;
|
|
||||||
// _id = val;
|
|
||||||
// }
|
|
||||||
// T value() const {
|
|
||||||
// if (_table)
|
|
||||||
// return _table->primaryValue().value<T>();
|
|
||||||
// return _id;
|
|
||||||
// }
|
|
||||||
//};
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // SYNTAX_DEFINES_H
|
#endif // SYNTAX_DEFINES_H
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ QString MySqlGenerator::escapeValue(const QVariant &v) const
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// default:
|
// default:
|
||||||
return SqlGeneratorBase::escapeValue(v);
|
return SqlGeneratorBase::escapeValue(v);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -303,25 +303,43 @@ QString MySqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->type == PhraseData::WithVariant) {
|
if (d->type == PhraseData::WithVariant) {
|
||||||
if (op == PhraseData::AddYears)
|
switch (op) {
|
||||||
return QString("DATE_ADD(%2, INTERVAL %1 YEAR)")
|
case PhraseData::AddYears:
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
case PhraseData::AddYearsDateTime:
|
||||||
else if (op == PhraseData::AddMonths)
|
case PhraseData::AddMonths:
|
||||||
return QString("DATE_ADD(%2, INTERVAL %1 MONTH)")
|
case PhraseData::AddMonthsDateTime:
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
case PhraseData::AddDays:
|
||||||
else if (op == PhraseData::AddDays)
|
case PhraseData::AddDaysDateTime:
|
||||||
return QString("DATE_ADD(%2, INTERVAL %1 DAY)")
|
case PhraseData::AddHours:
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
case PhraseData::AddHoursDateTime:
|
||||||
else if (op == PhraseData::AddHours)
|
case PhraseData::AddMinutes:
|
||||||
return QString("DATE_ADD(%2, INTERVAL %1 HOUR)")
|
case PhraseData::AddMinutesDateTime:
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
case PhraseData::AddSeconds:
|
||||||
else if (op == PhraseData::AddMinutes)
|
case PhraseData::AddSecondsDateTime:
|
||||||
return QString("DATE_ADD(%2, INTERVAL %1 MINUTE)")
|
return QString("DATE_ADD(%1, INTERVAL %2 %3)")
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
.arg(createConditionalPhrase(d->left),
|
||||||
else if (op == PhraseData::AddSeconds)
|
d->operand.toString(),
|
||||||
return QString("DATE_ADD(%2, INTERVAL %1 SECOND)")
|
SqlGeneratorBase::dateTimePartName(op));
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (d->type == PhraseData::WithoutOperand) {
|
||||||
|
switch (op) {
|
||||||
|
case PhraseData::DatePartYear:
|
||||||
|
case PhraseData::DatePartMonth:
|
||||||
|
case PhraseData::DatePartDay:
|
||||||
|
case PhraseData::DatePartHour:
|
||||||
|
case PhraseData::DatePartMinute:
|
||||||
|
case PhraseData::DatePartSecond:
|
||||||
|
return QString("%2(%1)")
|
||||||
|
.arg(createConditionalPhrase(d->left),
|
||||||
|
SqlGeneratorBase::dateTimePartName(op));
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SqlGeneratorBase::createConditionalPhrase(d);
|
return SqlGeneratorBase::createConditionalPhrase(d);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ NUT_BEGIN_NAMESPACE
|
||||||
class MySqlGenerator : public SqlGeneratorBase
|
class MySqlGenerator : public SqlGeneratorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit MySqlGenerator(Database *parent = 0);
|
explicit MySqlGenerator(Database *parent = nullptr);
|
||||||
|
|
||||||
QString fieldType(FieldModel *field) override;
|
QString fieldType(FieldModel *field) override;
|
||||||
QString escapeValue(const QVariant &v) const override;
|
QString escapeValue(const QVariant &v) const override;
|
||||||
|
|
|
||||||
|
|
@ -341,25 +341,44 @@ QString PostgreSqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
.arg(SqlGeneratorBase::createConditionalPhrase(d->left),
|
.arg(SqlGeneratorBase::createConditionalPhrase(d->left),
|
||||||
escapeValue(d->operand));
|
escapeValue(d->operand));
|
||||||
}
|
}
|
||||||
if (op == PhraseData::AddYears)
|
switch (op) {
|
||||||
return QString("DATEADD(year, %1, %2)")
|
case PhraseData::AddYears:
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
case PhraseData::AddYearsDateTime:
|
||||||
else if (op == PhraseData::AddMonths)
|
case PhraseData::AddMonths:
|
||||||
return QString("DATEADD(month, %1, %2)")
|
case PhraseData::AddMonthsDateTime:
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
case PhraseData::AddDays:
|
||||||
else if (op == PhraseData::AddDays)
|
case PhraseData::AddDaysDateTime:
|
||||||
return QString("DATEADD(day, %1, %2)")
|
case PhraseData::AddHours:
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
case PhraseData::AddHoursDateTime:
|
||||||
else if (op == PhraseData::AddHours)
|
case PhraseData::AddMinutes:
|
||||||
return QString("DATEADD(hour, %1, %2)")
|
case PhraseData::AddMinutesDateTime:
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
case PhraseData::AddSeconds:
|
||||||
else if (op == PhraseData::AddMinutes)
|
case PhraseData::AddSecondsDateTime:
|
||||||
return QString("DATEADD(minute, %1, %2)")
|
return QString("%1 + interval '%2 %3'")
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
.arg(createConditionalPhrase(d->left),
|
||||||
else if (op == PhraseData::AddSeconds)
|
d->operand.toString(),
|
||||||
return QString("DATEADD(second, %1, %2)")
|
SqlGeneratorBase::dateTimePartName(op));
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->type == PhraseData::WithoutOperand) {
|
||||||
|
switch (op) {
|
||||||
|
case PhraseData::DatePartYear:
|
||||||
|
case PhraseData::DatePartMonth:
|
||||||
|
case PhraseData::DatePartDay:
|
||||||
|
case PhraseData::DatePartHour:
|
||||||
|
case PhraseData::DatePartMinute:
|
||||||
|
case PhraseData::DatePartSecond:
|
||||||
|
return QString("date_part('%2', %1)")
|
||||||
|
.arg(createConditionalPhrase(d->left),
|
||||||
|
SqlGeneratorBase::dateTimePartName(op));
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SqlGeneratorBase::createConditionalPhrase(d);
|
return SqlGeneratorBase::createConditionalPhrase(d);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ NUT_BEGIN_NAMESPACE
|
||||||
class PostgreSqlGenerator : public SqlGeneratorBase
|
class PostgreSqlGenerator : public SqlGeneratorBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool readInsideParentese(QString &ref, QString &out);
|
bool readInsideParentese(QString &text, QString &out);
|
||||||
bool isPostGisType(const QVariant::Type &t) const;
|
bool isPostGisType(const QVariant::Type &t) const;
|
||||||
public:
|
public:
|
||||||
explicit PostgreSqlGenerator(Database *parent = nullptr);
|
explicit PostgreSqlGenerator(Database *parent = nullptr);
|
||||||
|
|
|
||||||
|
|
@ -788,24 +788,33 @@ void SqlGeneratorBase::removeTableNames(QString &command)
|
||||||
QString SqlGeneratorBase::dateTimePartName(const PhraseData::Condition &op) const
|
QString SqlGeneratorBase::dateTimePartName(const PhraseData::Condition &op) const
|
||||||
{
|
{
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
case PhraseData::DatePartYear:
|
||||||
case PhraseData::AddYears:
|
case PhraseData::AddYears:
|
||||||
case PhraseData::AddYearsDateTime:
|
case PhraseData::AddYearsDateTime:
|
||||||
return "YEAR";
|
return "YEAR";
|
||||||
|
case PhraseData::DatePartMonth:
|
||||||
case PhraseData::AddMonths:
|
case PhraseData::AddMonths:
|
||||||
case PhraseData::AddMonthsDateTime:
|
case PhraseData::AddMonthsDateTime:
|
||||||
return "MONTH";
|
return "MONTH";
|
||||||
|
case PhraseData::DatePartDay:
|
||||||
case PhraseData::AddDays:
|
case PhraseData::AddDays:
|
||||||
case PhraseData::AddDaysDateTime:
|
case PhraseData::AddDaysDateTime:
|
||||||
return "DAY";
|
return "DAY";
|
||||||
|
case PhraseData::DatePartHour:
|
||||||
case PhraseData::AddHours:
|
case PhraseData::AddHours:
|
||||||
case PhraseData::AddHoursDateTime:
|
case PhraseData::AddHoursDateTime:
|
||||||
return "HOUR";
|
return "HOUR";
|
||||||
|
case PhraseData::DatePartMinute:
|
||||||
case PhraseData::AddMinutes:
|
case PhraseData::AddMinutes:
|
||||||
case PhraseData::AddMinutesDateTime:
|
case PhraseData::AddMinutesDateTime:
|
||||||
return "MINUTE";
|
return "MINUTE";
|
||||||
|
case PhraseData::DatePartSecond:
|
||||||
case PhraseData::AddSeconds:
|
case PhraseData::AddSeconds:
|
||||||
case PhraseData::AddSecondsDateTime:
|
case PhraseData::AddSecondsDateTime:
|
||||||
return "SECOND";
|
return "SECOND";
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
@ -962,6 +971,7 @@ SqlGeneratorBase::operatorString(const PhraseData::Condition &cond) const
|
||||||
return "MOD";
|
return "MOD";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
qDebug() << "Unsupported" << cond;
|
||||||
return QString("<FAIL cond> %1").arg(cond);
|
return QString("<FAIL cond> %1").arg(cond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ protected:
|
||||||
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);
|
||||||
|
|
||||||
void replaceTableNames(QString &command);
|
virtual void replaceTableNames(QString &command);
|
||||||
void removeTableNames(QString &command);
|
void removeTableNames(QString &command);
|
||||||
QString dateTimePartName(const PhraseData::Condition &op) const;
|
QString dateTimePartName(const PhraseData::Condition &op) const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -252,6 +252,8 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
dateTimePartName(op));
|
dateTimePartName(op));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d->type == PhraseData::WithoutOperand) {
|
if (d->type == PhraseData::WithoutOperand) {
|
||||||
|
|
@ -283,6 +285,8 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
// case PhraseData::DatePartMilisecond:
|
// case PhraseData::DatePartMilisecond:
|
||||||
// return QString("CAST(strftime('%Y', %1) AS INT)")
|
// return QString("CAST(strftime('%Y', %1) AS INT)")
|
||||||
// .arg(createConditionalPhrase(d->left));
|
// .arg(createConditionalPhrase(d->left));
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ QString SqlServerGenerator::fieldType(FieldModel *field)
|
||||||
|
|
||||||
case QMetaType::QPoint:
|
case QMetaType::QPoint:
|
||||||
case QMetaType::QPointF:
|
case QMetaType::QPointF:
|
||||||
dbType = "GEOMETRY";
|
dbType = "TEXT";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::QString:
|
case QMetaType::QString:
|
||||||
|
|
@ -163,27 +163,131 @@ QString SqlServerGenerator::diff(FieldModel *oldField, FieldModel *newField)
|
||||||
|
|
||||||
QString SqlServerGenerator::escapeValue(const QVariant &v) const
|
QString SqlServerGenerator::escapeValue(const QVariant &v) const
|
||||||
{
|
{
|
||||||
auto mid = static_cast<QMetaType::Type>(v.userType());
|
switch (v.type()) {
|
||||||
|
case QVariant::String:
|
||||||
|
case QVariant::Char:
|
||||||
|
case QVariant::Polygon:
|
||||||
|
case QVariant::PolygonF:
|
||||||
|
case QVariant::Size:
|
||||||
|
case QVariant::SizeF:
|
||||||
|
case QVariant::Rect:
|
||||||
|
case QVariant::RectF:
|
||||||
|
case QVariant::Line:
|
||||||
|
case QVariant::LineF:
|
||||||
|
case QVariant::Color:
|
||||||
|
case QVariant::StringList:
|
||||||
|
// case QVariant::JsonArray:
|
||||||
|
// case QVariant::JsonValue:
|
||||||
|
// case QVariant::JsonObject:
|
||||||
|
// case QVariant::JsonDocument:
|
||||||
|
case QVariant::Url:
|
||||||
|
return "N" + SqlGeneratorBase::escapeValue(v);
|
||||||
|
|
||||||
if (mid == QMetaType::QString || mid == QMetaType::QChar)
|
// case QVariant::Point: {
|
||||||
return "N'" + v.toString() + "'";
|
// QPoint pt = v.toPoint();
|
||||||
else if (mid == QMetaType::QPoint) {
|
// return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
||||||
QPoint pt = v.toPoint();
|
// pt.y());
|
||||||
return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
// }
|
||||||
pt.y());
|
// case QVariant::PointF: {
|
||||||
} else if (mid == QMetaType::QPointF) {
|
// QPointF pt = v.toPointF();
|
||||||
QPointF pt = v.toPointF();
|
// return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
||||||
return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
// pt.y());
|
||||||
pt.y());
|
// }
|
||||||
|
|
||||||
|
case QVariant::Time:
|
||||||
|
return "'" + v.toTime().toString("HH:mm:ss") + "'";
|
||||||
|
|
||||||
|
case QVariant::Date:
|
||||||
|
return "'" + v.toDate().toString("yyyy-MM-dd") + "'";
|
||||||
|
|
||||||
|
case QVariant::DateTime:
|
||||||
|
return "'" + v.toDateTime().toString("yyyy-MM-dd HH:mm:ss") + "'";
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return SqlGeneratorBase::escapeValue(v);
|
return SqlGeneratorBase::escapeValue(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant SqlServerGenerator::unescapeValue(const QMetaType::Type &type, const QVariant &dbValue)
|
||||||
|
{
|
||||||
|
if (type == QMetaType::QDateTime)
|
||||||
|
return dbValue.toDateTime();
|
||||||
|
|
||||||
|
if (type == QMetaType::QTime)
|
||||||
|
return dbValue.toTime();
|
||||||
|
|
||||||
|
if (type == QMetaType::QDate)
|
||||||
|
return dbValue.toDate();
|
||||||
|
|
||||||
|
return SqlGeneratorBase::unescapeValue(type, dbValue);
|
||||||
|
}
|
||||||
|
|
||||||
void SqlServerGenerator::appendSkipTake(QString &sql, int skip, int take)
|
void SqlServerGenerator::appendSkipTake(QString &sql, int skip, int take)
|
||||||
{
|
{
|
||||||
if (take != -1 && skip != -1)
|
if (skip != -1)
|
||||||
sql.append(QString(" OFFSET %1 ROWS FETCH NEXT %2 ROWS ONLY")
|
sql.append(QString(" OFFSET %1 ROWS")
|
||||||
.arg(skip).arg(take));
|
.arg(skip));
|
||||||
|
if (take > 0)
|
||||||
|
sql.append(QString(" FETCH %2 %1 ROWS ONLY")
|
||||||
|
.arg(take)
|
||||||
|
.arg(skip > 1 ? "NEXT" : "FIRST"));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SqlServerGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
|
{
|
||||||
|
if (!d)
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
PhraseData::Condition op = d->operatorCond;
|
||||||
|
//apply not (!)
|
||||||
|
if (d->isNot) {
|
||||||
|
if (op < 20)
|
||||||
|
op = static_cast<PhraseData::Condition>((op + 10) % 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->type == PhraseData::WithVariant) {
|
||||||
|
switch (op) {
|
||||||
|
case PhraseData::AddYears:
|
||||||
|
case PhraseData::AddYearsDateTime:
|
||||||
|
case PhraseData::AddMonths:
|
||||||
|
case PhraseData::AddMonthsDateTime:
|
||||||
|
case PhraseData::AddDays:
|
||||||
|
case PhraseData::AddDaysDateTime:
|
||||||
|
case PhraseData::AddHours:
|
||||||
|
case PhraseData::AddHoursDateTime:
|
||||||
|
case PhraseData::AddMinutes:
|
||||||
|
case PhraseData::AddMinutesDateTime:
|
||||||
|
case PhraseData::AddSeconds:
|
||||||
|
case PhraseData::AddSecondsDateTime:
|
||||||
|
return QString("DATEADD(%3, %2, %1)")
|
||||||
|
.arg(createConditionalPhrase(d->left),
|
||||||
|
d->operand.toString(),
|
||||||
|
SqlGeneratorBase::dateTimePartName(op));
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->type == PhraseData::WithoutOperand) {
|
||||||
|
switch (op) {
|
||||||
|
case PhraseData::DatePartYear:
|
||||||
|
case PhraseData::DatePartMonth:
|
||||||
|
case PhraseData::DatePartDay:
|
||||||
|
case PhraseData::DatePartHour:
|
||||||
|
case PhraseData::DatePartMinute:
|
||||||
|
case PhraseData::DatePartSecond:
|
||||||
|
return QString("DATEPART(%2, %1)")
|
||||||
|
.arg(createConditionalPhrase(d->left),
|
||||||
|
SqlGeneratorBase::dateTimePartName(op));
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SqlGeneratorBase::createConditionalPhrase(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -31,16 +31,18 @@ class SqlServerGenerator : public SqlGeneratorBase
|
||||||
public:
|
public:
|
||||||
explicit SqlServerGenerator(Database *parent = nullptr);
|
explicit SqlServerGenerator(Database *parent = nullptr);
|
||||||
|
|
||||||
QString masterDatabaseName(QString databaseName);
|
QString masterDatabaseName(QString databaseName) override;
|
||||||
|
|
||||||
QString fieldType(FieldModel *field);
|
QString fieldType(FieldModel *field) override;
|
||||||
QString diff(FieldModel *oldField, FieldModel *newField);
|
QString diff(FieldModel *oldField, FieldModel *newField) override;
|
||||||
|
|
||||||
QString escapeValue(const QVariant &v) const;
|
QString escapeValue(const QVariant &v) const override;
|
||||||
void appendSkipTake(QString &sql, int skip, int take);
|
QVariant unescapeValue(const QMetaType::Type &type, const QVariant &dbValue) override;
|
||||||
|
|
||||||
void replaceTableNames(QString &command);
|
void appendSkipTake(QString &sql, int skip, int take) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString createConditionalPhrase(const PhraseData *d) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -28,15 +28,20 @@ QueryPrivate::QueryPrivate(QueryBase *parent) : q_ptr(parent),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryPrivate::~QueryPrivate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \class Query
|
* \class Query
|
||||||
* \brief This class hold a query. A query can be used for getting database rows, editing or deleting without row fetching.
|
* \brief This class hold a query. A query can be used for getting database rows, editing or deleting without row fetching.
|
||||||
* A query can be used for getting data from database.
|
* A query can be used for getting data from database.
|
||||||
* \code
|
* \code
|
||||||
* auto q = db.posts()->createQuery();
|
* auto q = db.posts()->query();
|
||||||
* q->join(Post::commentsTable());
|
* q->join(Post::commentsTable());
|
||||||
* q->orderBy(!Post::saveDateField() & Post::bodyField());
|
* q->orderBy(!Post::saveDateField() & Post::bodyField());
|
||||||
* q->setWhere(Post::idField() > 5);
|
* q->where(Post::idField() > 5);
|
||||||
*
|
*
|
||||||
* auto posts = q->toList();
|
* auto posts = q->toList();
|
||||||
* \endcode
|
* \endcode
|
||||||
|
|
@ -54,7 +59,7 @@ QueryPrivate::QueryPrivate(QueryBase *parent) : q_ptr(parent),
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \fn Query<T> *Query::setWhere(WherePhrase where)
|
* \fn Query<T> *Query::where(WherePhrase where)
|
||||||
* Where phrase is a phrase using table's static field methods.
|
* Where phrase is a phrase using table's static field methods.
|
||||||
* \code
|
* \code
|
||||||
* q->setWhere(Post::idField() == 4 || Post::titleField().isNull());
|
* q->setWhere(Post::idField() == 4 || Post::titleField().isNull());
|
||||||
|
|
|
||||||
51
src/query.h
51
src/query.h
|
|
@ -272,14 +272,14 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
// check if key value is changed
|
// check if key value is changed
|
||||||
if (data.lastKeyValue == q.value(data.keyFiledname)) {
|
if (data.lastKeyValue == q.value(data.keyFiledname)) {
|
||||||
--p;
|
--p;
|
||||||
qDebug() << "key os not changed for" << data.keyFiledname;
|
// qDebug() << "key os not changed for" << data.keyFiledname;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if master if current table has processed
|
// check if master if current table has processed
|
||||||
foreach (int m, data.masters)
|
foreach (int m, data.masters)
|
||||||
if (!checked[m]) {
|
if (!checked[m]) {
|
||||||
qDebug() << "row is checked";
|
// qDebug() << "row is checked";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -288,66 +288,48 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
data.lastKeyValue = q.value(data.keyFiledname);
|
data.lastKeyValue = q.value(data.keyFiledname);
|
||||||
|
|
||||||
//create table row
|
//create table row
|
||||||
Table *table;
|
Row<Table> row;
|
||||||
Row<T> shp;
|
|
||||||
if (data.table->className() == d->className) {
|
if (data.table->className() == d->className) {
|
||||||
table = new T();
|
row = Nut::create<T>();
|
||||||
#ifdef NUT_SHARED_POINTER
|
#ifdef NUT_SHARED_POINTER
|
||||||
shp = QSharedPointer<T>(qobject_cast<T*>(table));
|
returnList.append(row.objectCast<T>());
|
||||||
returnList.append(shp);
|
|
||||||
d->tableSet->add(shp);
|
|
||||||
#else
|
#else
|
||||||
returnList.append(dynamic_cast<T*>(table));
|
returnList.append(dynamic_cast<T*>(table));
|
||||||
#endif
|
#endif
|
||||||
table->setParentTableSet(d->tableSet);
|
d->tableSet->add(row);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
Table *table;
|
||||||
const QMetaObject *childMetaObject
|
const QMetaObject *childMetaObject
|
||||||
= QMetaType::metaObjectForType(data.table->typeId());
|
= QMetaType::metaObjectForType(data.table->typeId());
|
||||||
table = qobject_cast<Table *>(childMetaObject->newInstance());
|
table = qobject_cast<Table *>(childMetaObject->newInstance());
|
||||||
|
// table = dynamic_cast<Table *>(QMetaType::create(data.table->typeId()));
|
||||||
if (!table)
|
if (!table)
|
||||||
qFatal("Could not create instance of %s",
|
qFatal("Could not create instance of %s",
|
||||||
qPrintable(data.table->name()));
|
qPrintable(data.table->name()));
|
||||||
|
row = createFrom(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<FieldModel*> childFields = data.table->fields();
|
QList<FieldModel*> childFields = data.table->fields();
|
||||||
foreach (FieldModel *field, childFields)
|
foreach (FieldModel *field, childFields)
|
||||||
table->setProperty(field->name.toLatin1().data(),
|
row->setProperty(field->name.toLatin1().data(),
|
||||||
d->database->sqlGenertor()->unescapeValue(
|
d->database->sqlGenertor()->unescapeValue(
|
||||||
field->type,
|
field->type,
|
||||||
q.value(data.table->name() + "." + field->name)));
|
q.value(data.table->name() + "." + field->name)));
|
||||||
|
|
||||||
for (int i = 0; i < data.masters.count(); ++i) {
|
for (int i = 0; i < data.masters.count(); ++i) {
|
||||||
int master = data.masters[i];
|
int master = data.masters[i];
|
||||||
#ifdef NUT_SHARED_POINTER
|
|
||||||
QString mName = QString("set%1").arg(levels[master].lastRow->metaObject()->className());
|
|
||||||
QString type = QString("Nut::Row<%1>").arg(levels[master].lastRow->metaObject()->className());
|
|
||||||
bool ok = table->metaObject()->invokeMethod(table,
|
|
||||||
mName.toLocal8Bit().data(),
|
|
||||||
QGenericArgument(type.toLatin1().data(), levels[master].lastRow));
|
|
||||||
#else
|
|
||||||
bool ok = table->setProperty(data.masterFields[i].toLocal8Bit().data(),
|
|
||||||
QVariant::fromValue(levels[master].lastRow));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!ok)
|
|
||||||
qWarning("Unable to set property %s::%s",
|
|
||||||
table->metaObject()->className(), data.masterFields[i].toLocal8Bit().data());
|
|
||||||
|
|
||||||
auto tableset = levels[master].lastRow->childTableSet(
|
auto tableset = levels[master].lastRow->childTableSet(
|
||||||
data.table->className());
|
data.table->className());
|
||||||
table->setParentTableSet(tableset);
|
tableset->add(row);
|
||||||
#ifdef NUT_SHARED_POINTER
|
|
||||||
tableset->add(qSharedPointerCast<Table>(shp));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table->setStatus(Table::FeatchedFromDB);
|
row->setStatus(Table::FeatchedFromDB);
|
||||||
table->setParent(this);
|
row->setParent(this);
|
||||||
table->clear();
|
row->clear();
|
||||||
|
|
||||||
//set last created row
|
//set last created row
|
||||||
data.lastRow = /*QSharedPointer<Table>*/(table);
|
data.lastRow = row.data();
|
||||||
} //while
|
} //while
|
||||||
} // while
|
} // while
|
||||||
|
|
||||||
|
|
@ -356,6 +338,7 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
deleteLater();
|
deleteLater();
|
||||||
#endif
|
#endif
|
||||||
return returnList;
|
return returnList;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class QueryPrivate : public QSharedData {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QueryPrivate(QueryBase *parent);
|
explicit QueryPrivate(QueryBase *parent);
|
||||||
~QueryPrivate() = default;
|
~QueryPrivate();
|
||||||
|
|
||||||
QString sql;
|
QString sql;
|
||||||
QString className;
|
QString className;
|
||||||
|
|
@ -53,11 +53,6 @@ public:
|
||||||
int take;
|
int take;
|
||||||
PhraseList orderPhrase, fieldPhrase;
|
PhraseList orderPhrase, fieldPhrase;
|
||||||
ConditionalPhrase wherePhrase;
|
ConditionalPhrase wherePhrase;
|
||||||
|
|
||||||
// QList<WherePhrase> wheres;
|
|
||||||
// QList<WherePhrase> orderPhrases;
|
|
||||||
// QList<WherePhrase> fields;
|
|
||||||
// QHash<QString, QString> orders;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ protected:
|
||||||
QExplicitlySharedDataPointer<QueryPrivate> d;
|
QExplicitlySharedDataPointer<QueryPrivate> d;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QueryBase(QObject *parent = 0);
|
explicit QueryBase(QObject *parent = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// void addTableToSet(TableSetBase *set, Table *table);
|
// void addTableToSet(TableSetBase *set, Table *table);
|
||||||
|
|
|
||||||
|
|
@ -44,32 +44,32 @@ NUT_BEGIN_NAMESPACE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Table::Table(QObject *parent) : QObject(parent),
|
Table::Table(QObject *parent) : QObject(parent),
|
||||||
d_ptr(new TablePrivate(this))
|
d(new TablePrivate)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Table::~Table()
|
Table::~Table()
|
||||||
{
|
{
|
||||||
Q_D(Table);
|
//Q_D(Table);
|
||||||
|
|
||||||
if (d->parentTableSet)
|
// if (d->parentTableSet)
|
||||||
d->parentTableSet->remove(this);
|
// d->parentTableSet->remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Table::add(TableSetBase *t)
|
void Table::add(TableSetBase *t)
|
||||||
{
|
{
|
||||||
Q_D(Table);
|
//Q_D(Table);
|
||||||
d->childTableSets.insert(t);
|
d->childTableSets.insert(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
//QString Table::primaryKey() const
|
//QString Table::primaryKey() const
|
||||||
//{
|
//{
|
||||||
// Q_D(const Table);
|
// //Q_D(const Table);
|
||||||
// return d->model->primaryKey();
|
// return d->model->primaryKey();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//bool Table::isPrimaryKeyAutoIncrement() const
|
//bool Table::isPrimaryKeyAutoIncrement() const
|
||||||
//{
|
//{
|
||||||
// Q_D(const Table);
|
// //Q_D(const Table);
|
||||||
// FieldModel *pk = d->model->field(d->model->primaryKey());
|
// FieldModel *pk = d->model->field(d->model->primaryKey());
|
||||||
// if (!pk)
|
// if (!pk)
|
||||||
// return false;
|
// return false;
|
||||||
|
|
@ -84,7 +84,7 @@ void Table::add(TableSetBase *t)
|
||||||
|
|
||||||
void Table::propertyChanged(const QString &propName)
|
void Table::propertyChanged(const QString &propName)
|
||||||
{
|
{
|
||||||
Q_D(Table);
|
//Q_D(Table);
|
||||||
// if (!d->model)
|
// if (!d->model)
|
||||||
// d->model = TableModel::findByClassName(metaObject()->className());
|
// d->model = TableModel::findByClassName(metaObject()->className());
|
||||||
|
|
||||||
|
|
@ -95,6 +95,7 @@ void Table::propertyChanged(const QString &propName)
|
||||||
// if(f->isPrimaryKey && propName == f->name && f->isAutoIncrement)
|
// if(f->isPrimaryKey && propName == f->name && f->isAutoIncrement)
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
|
d.detach();
|
||||||
d->changedProperties.insert(propName);
|
d->changedProperties.insert(propName);
|
||||||
if (d->status == FeatchedFromDB)
|
if (d->status == FeatchedFromDB)
|
||||||
d->status = Modified;
|
d->status = Modified;
|
||||||
|
|
@ -105,25 +106,26 @@ void Table::propertyChanged(const QString &propName)
|
||||||
|
|
||||||
void Table::setModel(TableModel *model)
|
void Table::setModel(TableModel *model)
|
||||||
{
|
{
|
||||||
Q_D(Table);
|
//Q_D(Table);
|
||||||
d->model = model;
|
d->model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Table::clear()
|
void Table::clear()
|
||||||
{
|
{
|
||||||
Q_D(Table);
|
//Q_D(Table);
|
||||||
d->changedProperties.clear();
|
d->changedProperties.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<QString> Table::changedProperties() const
|
QSet<QString> Table::changedProperties() const
|
||||||
{
|
{
|
||||||
Q_D(const Table);
|
//Q_D(const Table);
|
||||||
return d->changedProperties;
|
return d->changedProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Table::setParentTable(Table *master, TableModel *masterModel, TableModel *model)
|
bool Table::setParentTable(Table *master, TableModel *masterModel, TableModel *model)
|
||||||
{
|
{
|
||||||
Q_D(Table);
|
//Q_D(Table);
|
||||||
|
d.detach();
|
||||||
|
|
||||||
QString masterClassName = master->metaObject()->className();
|
QString masterClassName = master->metaObject()->className();
|
||||||
d->refreshModel();
|
d->refreshModel();
|
||||||
|
|
@ -145,22 +147,22 @@ bool Table::setParentTable(Table *master, TableModel *masterModel, TableModel *m
|
||||||
|
|
||||||
TableSetBase *Table::parentTableSet() const
|
TableSetBase *Table::parentTableSet() const
|
||||||
{
|
{
|
||||||
Q_D(const Table);
|
//Q_D(const Table);
|
||||||
return d->parentTableSet;
|
return d->parentTableSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Table::setParentTableSet(TableSetBase *parent)
|
void Table::setParentTableSet(TableSetBase *parent)
|
||||||
{
|
{
|
||||||
Q_D(Table);
|
//Q_D(Table);
|
||||||
d->parentTableSet = parent;
|
d->parentTableSet = parent;
|
||||||
|
|
||||||
if (parent)
|
// if (parent)
|
||||||
d->parentTableSet->add(this);
|
// d->parentTableSet->add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TableSetBase *Table::childTableSet(const QString &name) const
|
TableSetBase *Table::childTableSet(const QString &name) const
|
||||||
{
|
{
|
||||||
Q_D(const Table);
|
//Q_D(const Table);
|
||||||
foreach (TableSetBase *t, d->childTableSets)
|
foreach (TableSetBase *t, d->childTableSets)
|
||||||
if (t->childClassName() == name)
|
if (t->childClassName() == name)
|
||||||
return t;
|
return t;
|
||||||
|
|
@ -169,7 +171,7 @@ TableSetBase *Table::childTableSet(const QString &name) const
|
||||||
|
|
||||||
int Table::save(Database *db)
|
int Table::save(Database *db)
|
||||||
{
|
{
|
||||||
Q_D(Table);
|
//Q_D(Table);
|
||||||
|
|
||||||
QSqlQuery q = db->exec(db->sqlGenertor()->saveRecord(this, db->tableName(metaObject()->className())));
|
QSqlQuery q = db->exec(db->sqlGenertor()->saveRecord(this, db->tableName(metaObject()->className())));
|
||||||
|
|
||||||
|
|
@ -186,19 +188,19 @@ int Table::save(Database *db)
|
||||||
|
|
||||||
Table::Status Table::status() const
|
Table::Status Table::status() const
|
||||||
{
|
{
|
||||||
Q_D(const Table);
|
//Q_D(const Table);
|
||||||
return static_cast<Status>(d->status);
|
return static_cast<Status>(d->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Table::setStatus(const Status &status)
|
void Table::setStatus(const Status &status)
|
||||||
{
|
{
|
||||||
Q_D(Table);
|
//Q_D(Table);
|
||||||
d->status = status;
|
d->status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TablePrivate::TablePrivate(Table *parent) : q_ptr(parent),
|
TablePrivate::TablePrivate() : QSharedData(),
|
||||||
model(nullptr), status(Table::NewCreated), parentTableSet(nullptr)
|
model(nullptr), status(Table::NewCreated), parentTableSet(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -206,7 +208,7 @@ TablePrivate::TablePrivate(Table *parent) : q_ptr(parent),
|
||||||
|
|
||||||
void TablePrivate::refreshModel()
|
void TablePrivate::refreshModel()
|
||||||
{
|
{
|
||||||
Q_Q(Table);
|
// Q_Q(Table);
|
||||||
// if (!model)
|
// if (!model)
|
||||||
// model = TableModel::findByClassName(q->metaObject()->className());
|
// model = TableModel::findByClassName(q->metaObject()->className());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,7 @@ class TablePrivate;
|
||||||
class NUT_EXPORT Table : public QObject
|
class NUT_EXPORT Table : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
TablePrivate *d_ptr;
|
QExplicitlySharedDataPointer<TablePrivate> d;
|
||||||
Q_DECLARE_PRIVATE(Table)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Table(QObject *parentTableSet = nullptr);
|
explicit Table(QObject *parentTableSet = nullptr);
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,19 @@
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
#include <QtCore/QSet>
|
#include <QtCore/QSet>
|
||||||
|
#include <QSharedData>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class TableModel;
|
class TableModel;
|
||||||
class Table;
|
class Table;
|
||||||
class TableSetBase;
|
class TableSetBase;
|
||||||
class TablePrivate {
|
class TablePrivate : public QSharedData {
|
||||||
Table *q_ptr;
|
Table *q_ptr;
|
||||||
Q_DECLARE_PUBLIC(Table)
|
Q_DECLARE_PUBLIC(Table)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TablePrivate(Table *parent);
|
TablePrivate();
|
||||||
|
|
||||||
|
|
||||||
TableModel *model;
|
TableModel *model;
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,6 @@
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: It may be good idea if we replace this QSet with two QHash!
|
|
||||||
* one for className search and another for typeId.
|
|
||||||
*/
|
|
||||||
QSet<TableModel*> TableModel::_allModels;
|
|
||||||
|
|
||||||
QString TableModel::name() const
|
QString TableModel::name() const
|
||||||
{
|
{
|
||||||
return _name;
|
return _name;
|
||||||
|
|
@ -269,14 +263,6 @@ TableModel::TableModel(const QJsonObject &json, const QString &tableName) : _typ
|
||||||
QJsonObject relObject = fields.value(key).toObject();
|
QJsonObject relObject = fields.value(key).toObject();
|
||||||
_foreignKeys.append(new RelationModel(relObject));
|
_foreignKeys.append(new RelationModel(relObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(json.keys().contains(__nut_AUTO_INCREMENT))
|
|
||||||
// field(json.value(__nut_AUTO_INCREMENT).toString())->isAutoIncrement = true;
|
|
||||||
|
|
||||||
// if(json.keys().contains(__nut_PRIMARY_KEY))
|
|
||||||
// field(json.value(__nut_PRIMARY_KEY).toString())->isAutoIncrement = true;
|
|
||||||
|
|
||||||
_allModels.insert(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TableModel::~TableModel()
|
TableModel::~TableModel()
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,7 @@ NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class TableModel;
|
class TableModel;
|
||||||
struct FieldModel{
|
struct FieldModel{
|
||||||
explicit FieldModel() : name(QString()), length(0), defaultValue(QString()),
|
explicit FieldModel() : name(QString()), defaultValue(QString())
|
||||||
notNull(false), isPrimaryKey(false), isAutoIncrement(false), isUnique(false)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -42,12 +41,12 @@ struct FieldModel{
|
||||||
QString name;
|
QString name;
|
||||||
QMetaType::Type type;
|
QMetaType::Type type;
|
||||||
QString typeName;
|
QString typeName;
|
||||||
int length;
|
int length{0};
|
||||||
QString defaultValue;
|
QString defaultValue;
|
||||||
bool notNull;
|
bool notNull{false};
|
||||||
bool isPrimaryKey;
|
bool isPrimaryKey{false};
|
||||||
bool isAutoIncrement;
|
bool isAutoIncrement{false};
|
||||||
bool isUnique;
|
bool isUnique{false};
|
||||||
QString displayName;
|
QString displayName;
|
||||||
|
|
||||||
bool operator ==(const FieldModel &f) const{
|
bool operator ==(const FieldModel &f) const{
|
||||||
|
|
@ -70,18 +69,17 @@ struct FieldModel{
|
||||||
|
|
||||||
struct RelationModel{
|
struct RelationModel{
|
||||||
RelationModel() : localColumn(QString()), localProperty(QString()),
|
RelationModel() : localColumn(QString()), localProperty(QString()),
|
||||||
slaveTable(nullptr), foreignColumn(QString()), masterTable(nullptr),
|
slaveTable(nullptr), foreignColumn(QString()), masterClassName(QString())
|
||||||
masterClassName(QString())
|
|
||||||
{}
|
{}
|
||||||
explicit RelationModel(const QJsonObject &obj);
|
explicit RelationModel(const QJsonObject &obj);
|
||||||
|
|
||||||
//slave
|
//slave
|
||||||
QString localColumn;
|
QString localColumn;
|
||||||
QString localProperty;
|
QString localProperty;
|
||||||
TableModel *slaveTable;
|
TableModel *slaveTable{nullptr};
|
||||||
//master
|
//master
|
||||||
QString foreignColumn;
|
QString foreignColumn;
|
||||||
TableModel *masterTable;
|
TableModel *masterTable{nullptr};
|
||||||
|
|
||||||
QString masterClassName;
|
QString masterClassName;
|
||||||
|
|
||||||
|
|
@ -131,9 +129,6 @@ private:
|
||||||
int _typeId;
|
int _typeId;
|
||||||
QList<FieldModel*> _fields;
|
QList<FieldModel*> _fields;
|
||||||
QList<RelationModel*> _foreignKeys;
|
QList<RelationModel*> _foreignKeys;
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
static QSet<TableModel*>_allModels;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,8 @@ public:
|
||||||
void remove(RowList<T> t);
|
void remove(RowList<T> t);
|
||||||
|
|
||||||
int length() const;
|
int length() const;
|
||||||
T *at(int i) const;
|
Row<T> at(int i) const;
|
||||||
const T &operator[](int i) const;
|
const Row<T> operator[](int i) const;
|
||||||
|
|
||||||
Query<T> *query(bool autoDelete = true);
|
Query<T> *query(bool autoDelete = true);
|
||||||
BulkInserter *bulkInserter();
|
BulkInserter *bulkInserter();
|
||||||
|
|
@ -95,20 +95,27 @@ Q_OUTOFLINE_TEMPLATE BulkInserter *TableSet<T>::bulkInserter()
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE int TableSet<T>::length() const
|
Q_OUTOFLINE_TEMPLATE int TableSet<T>::length() const
|
||||||
{
|
{
|
||||||
return data->tables.count();
|
return data->childs.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE T *TableSet<T >::at(int i) const
|
Q_OUTOFLINE_TEMPLATE Row<T> TableSet<T >::at(int i) const
|
||||||
{
|
{
|
||||||
//TODO: check
|
#ifdef NUT_SHARED_POINTER
|
||||||
return reinterpret_cast<T*>(data->childRows.at(i));
|
return data->childs.at(i).objectCast<T>();
|
||||||
|
#else
|
||||||
|
return reinterpret_cast<T*>(data->childs.at(i));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE const T &TableSet<T>::operator[](int i) const
|
Q_OUTOFLINE_TEMPLATE const Row<T> TableSet<T>::operator[](int i) const
|
||||||
{
|
{
|
||||||
return data->childRows[i];
|
#ifdef NUT_SHARED_POINTER
|
||||||
|
return data->childs.at(i).objectCast<T>();
|
||||||
|
#else
|
||||||
|
return reinterpret_cast<T*>(data->childs.at(i));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
@ -116,8 +123,8 @@ Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(Row<T> t)
|
||||||
{
|
{
|
||||||
data.detach();
|
data.detach();
|
||||||
data->childs.append(t);
|
data->childs.append(t);
|
||||||
data->tables.insert(t.data());
|
// data->tables.insert(t.data());
|
||||||
data->childRows.append(t.data());
|
// data->childRows.append(t.data());
|
||||||
|
|
||||||
// if (_database)
|
// if (_database)
|
||||||
// t->setModel(_database->model().tableByClassName(t->metaObject()->className()));
|
// t->setModel(_database->model().tableByClassName(t->metaObject()->className()));
|
||||||
|
|
@ -138,8 +145,8 @@ template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE void TableSet<T>::remove(Row<T> t)
|
Q_OUTOFLINE_TEMPLATE void TableSet<T>::remove(Row<T> t)
|
||||||
{
|
{
|
||||||
data.detach();
|
data.detach();
|
||||||
data->childs.removeOne(t.data());
|
// data->childs.removeOne(t.data());
|
||||||
data->tables.remove(t.data());
|
// data->tables.remove(t.data());
|
||||||
data->childs.removeOne(t);
|
data->childs.removeOne(t);
|
||||||
t->setStatus(Table::Deleted);
|
t->setStatus(Table::Deleted);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,11 +40,9 @@ TableSetBase::TableSetBase(Table *parent) : QObject(parent),
|
||||||
|
|
||||||
TableSetBase::~TableSetBase()
|
TableSetBase::~TableSetBase()
|
||||||
{
|
{
|
||||||
foreach (Table *t, data->tables)
|
|
||||||
t->setParentTableSet(nullptr);
|
|
||||||
|
|
||||||
foreach (Row<Table> t, data->childs)
|
foreach (Row<Table> t, data->childs)
|
||||||
t->setParentTableSet(nullptr);
|
if (t)
|
||||||
|
t->setParentTableSet(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TableSetBase::save(Database *db, bool cleanUp)
|
int TableSetBase::save(Database *db, bool cleanUp)
|
||||||
|
|
@ -54,7 +52,7 @@ int TableSetBase::save(Database *db, bool cleanUp)
|
||||||
if (data->table)
|
if (data->table)
|
||||||
masterModel = db->model().tableByClassName(data->table->metaObject()->className());
|
masterModel = db->model().tableByClassName(data->table->metaObject()->className());
|
||||||
|
|
||||||
foreach (Table *t, data->childRows) {
|
foreach (Row<Table> t, data->childs) {
|
||||||
if(data->table)
|
if(data->table)
|
||||||
t->setParentTable(data->table,
|
t->setParentTable(data->table,
|
||||||
masterModel,
|
masterModel,
|
||||||
|
|
@ -65,16 +63,16 @@ int TableSetBase::save(Database *db, bool cleanUp)
|
||||||
|| t->status() == Table::Deleted){
|
|| t->status() == Table::Deleted){
|
||||||
rowsAffected += t->save(db);
|
rowsAffected += t->save(db);
|
||||||
if(cleanUp)
|
if(cleanUp)
|
||||||
#ifndef NUT_SHARED_POINTER
|
#ifdef NUT_SHARED_POINTER
|
||||||
t->deleteLater();
|
|
||||||
#else
|
|
||||||
remove(t);
|
remove(t);
|
||||||
|
#else
|
||||||
|
t->deleteLater();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanUp)
|
if (cleanUp)
|
||||||
data->childRows.clear();
|
data->childs.clear();
|
||||||
|
|
||||||
return rowsAffected;
|
return rowsAffected;
|
||||||
}
|
}
|
||||||
|
|
@ -82,38 +80,23 @@ int TableSetBase::save(Database *db, bool cleanUp)
|
||||||
void TableSetBase::clearChilds()
|
void TableSetBase::clearChilds()
|
||||||
{
|
{
|
||||||
#ifndef NUT_SHARED_POINTER
|
#ifndef NUT_SHARED_POINTER
|
||||||
foreach (Table *t, data->childRows)
|
foreach (Table *t, data->childs)
|
||||||
t->deleteLater();
|
t->deleteLater();
|
||||||
#endif
|
#endif
|
||||||
data->childRows.clear();
|
data->childs.clear();
|
||||||
}
|
|
||||||
|
|
||||||
void TableSetBase::add(Table *t)
|
|
||||||
{
|
|
||||||
if(!data->tables.contains(get(t))){
|
|
||||||
data.detach();
|
|
||||||
data->tables.insert(get(t));
|
|
||||||
data->childRows.append(get(t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TableSetBase::remove(Table *t)
|
|
||||||
{
|
|
||||||
data.detach();
|
|
||||||
data->tables.remove(get(t));
|
|
||||||
data->childRows.removeOne(get(t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableSetBase::add(Row<Table> t)
|
void TableSetBase::add(Row<Table> t)
|
||||||
{
|
{
|
||||||
data.detach();
|
data.detach();
|
||||||
data->childs.append(t);
|
data->childs.append(t);
|
||||||
|
t->setParentTableSet(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableSetBase::remove(Row<Table> t)
|
void TableSetBase::remove(Row<Table> t)
|
||||||
{
|
{
|
||||||
data.detach();
|
data.detach();
|
||||||
data->childs.removeOne(t);
|
data->childs.removeAll(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TableSetBase::childClassName() const
|
QString TableSetBase::childClassName() const
|
||||||
|
|
|
||||||
|
|
@ -49,17 +49,11 @@ public:
|
||||||
void setDatabase(Database *database);
|
void setDatabase(Database *database);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// QSet<Table*> _tables;
|
|
||||||
// RowList<Table> _childRows;
|
|
||||||
// Database *_database;
|
|
||||||
// Table *_table;
|
|
||||||
//// QString _tableName;
|
|
||||||
// QString _childClassName;
|
|
||||||
QExplicitlySharedDataPointer<TableSetBaseData> data;
|
QExplicitlySharedDataPointer<TableSetBaseData> data;
|
||||||
|
|
||||||
public://TODO: change this to private
|
public://TODO: change this to private
|
||||||
void add(Table* t);
|
// void add(Table* t);
|
||||||
void remove(Table *t);
|
// void remove(Table *t);
|
||||||
|
|
||||||
void add(Row<Table> t);
|
void add(Row<Table> t);
|
||||||
void remove(Row<Table> t);
|
void remove(Row<Table> t);
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ public:
|
||||||
database(nullptr), table(parent)
|
database(nullptr), table(parent)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
QSet<Table*> tables;
|
// QSet<Table*> tables;
|
||||||
QList<Table*> childRows;
|
// QList<Table*> childRows;
|
||||||
RowList<Table> childs;
|
RowList<Table> childs;
|
||||||
|
|
||||||
Database *database;
|
Database *database;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#define CONSTS_H
|
#define CONSTS_H
|
||||||
|
|
||||||
#include <qsystemdetection.h>
|
#include <qsystemdetection.h>
|
||||||
|
#include <qcompilerdetection.h>
|
||||||
|
|
||||||
#define REGISTER(x) qDebug() << (#x) << "type id:" << qMetaTypeId<x*>()
|
#define REGISTER(x) qDebug() << (#x) << "type id:" << qMetaTypeId<x*>()
|
||||||
#define PRINT(x)
|
#define PRINT(x)
|
||||||
|
|
@ -11,11 +12,12 @@
|
||||||
.arg(timer.elapsed() / 1000.) \
|
.arg(timer.elapsed() / 1000.) \
|
||||||
.arg(__func__)
|
.arg(__func__)
|
||||||
|
|
||||||
#define DRIVER "QSQLITE"
|
#define DRIVER "QODBC"
|
||||||
#define DATABASE QString("nut_test_%1_db").arg(metaObject()->className()).toLower()
|
#define DATABASE QString("DRIVER={SQL Server};Server=.;Database=%1;Uid=sa;Port=1433;Pwd=qwe123!@#;WSID=.") \
|
||||||
|
.arg(QString("nut_test_%1_db").arg(metaObject()->className()).toLower())
|
||||||
#define HOST "127.0.0.1"
|
#define HOST "127.0.0.1"
|
||||||
#define USERNAME "postgres"
|
#define USERNAME "sa"
|
||||||
#define PASSWORD "856856"
|
#define PASSWORD "qwe123!@#"
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
# define OS "Linux"
|
# define OS "Linux"
|
||||||
|
|
@ -27,6 +29,20 @@
|
||||||
# define OS "Unknown"
|
# define OS "Unknown"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_CC_GNU
|
||||||
|
# ifdef Q_CC_MINGW
|
||||||
|
# define CC "MinGW"
|
||||||
|
# else
|
||||||
|
# define CC "GNU"
|
||||||
|
# endif
|
||||||
|
#elif defined (Q_CC_MSVC)
|
||||||
|
# define CC "msvc"
|
||||||
|
#elif defined (Q_CC_CLANG)
|
||||||
|
# define CC "clang"
|
||||||
|
#else
|
||||||
|
# define CC "Unknown"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PRINT_FORM(db) \
|
#define PRINT_FORM(db) \
|
||||||
qDebug() << "\n\n****************************" \
|
qDebug() << "\n\n****************************" \
|
||||||
<< "\nAll tests passed," \
|
<< "\nAll tests passed," \
|
||||||
|
|
@ -34,6 +50,7 @@
|
||||||
<< "hamed.masafi@gmail.com" \
|
<< "hamed.masafi@gmail.com" \
|
||||||
<< "\n\tDriver:" << db.driver() \
|
<< "\n\tDriver:" << db.driver() \
|
||||||
<< "\n\tOS: " OS " (version: ________)" \
|
<< "\n\tOS: " OS " (version: ________)" \
|
||||||
|
<< "\n\tCompiler: " CC " (version: ________)" \
|
||||||
<< "\n\tQt version: " QT_VERSION_STR \
|
<< "\n\tQt version: " QT_VERSION_STR \
|
||||||
<< "\n\tTest:" << metaObject()->className() \
|
<< "\n\tTest:" << metaObject()->className() \
|
||||||
<< "\n****************************\n";
|
<< "\n****************************\n";
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,9 @@ void BasicTest::createPost2()
|
||||||
(Post::titleField() = "This is a sample")
|
(Post::titleField() = "This is a sample")
|
||||||
& (Post::isPublicField() = true));
|
& (Post::isPublicField() = true));
|
||||||
|
|
||||||
QTEST_ASSERT(postIdVar.type() == QVariant::LongLong || postIdVar.type() == QVariant::ULongLong);
|
QTEST_ASSERT(postIdVar.type() == QVariant::LongLong
|
||||||
|
|| postIdVar.type() == QVariant::ULongLong
|
||||||
|
|| postIdVar.type() == QVariant::Double);
|
||||||
int postId = postIdVar.toInt();
|
int postId = postIdVar.toInt();
|
||||||
|
|
||||||
for(int i = 0 ; i < 3; i++){
|
for(int i = 0 ; i < 3; i++){
|
||||||
|
|
@ -178,7 +180,8 @@ void BasicTest::selectScoreAverage()
|
||||||
void BasicTest::selectFirst()
|
void BasicTest::selectFirst()
|
||||||
{
|
{
|
||||||
auto posts = db.posts()->query()
|
auto posts = db.posts()->query()
|
||||||
->first();
|
->orderBy(Post::idField())
|
||||||
|
->first();
|
||||||
|
|
||||||
QTEST_ASSERT(posts != Q_NULLPTR);
|
QTEST_ASSERT(posts != Q_NULLPTR);
|
||||||
}
|
}
|
||||||
|
|
@ -215,6 +218,7 @@ void BasicTest::testDate()
|
||||||
|
|
||||||
auto q = db.posts()->query()
|
auto q = db.posts()->query()
|
||||||
->setWhere(Post::idField() == newPost->id())
|
->setWhere(Post::idField() == newPost->id())
|
||||||
|
->orderBy(Post::idField())
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
qDebug() << q->saveDate() << d;
|
qDebug() << q->saveDate() << d;
|
||||||
|
|
@ -246,8 +250,9 @@ void BasicTest::selectWithInvalidRelation()
|
||||||
|
|
||||||
void BasicTest::modifyPost()
|
void BasicTest::modifyPost()
|
||||||
{
|
{
|
||||||
auto q = db.posts()->query();
|
auto q = db.posts()->query()
|
||||||
q->setWhere(Post::idField() == postId);
|
->setWhere(Post::idField() == postId)
|
||||||
|
->orderBy(Post::idField());
|
||||||
|
|
||||||
Nut::Row<Post> post = q->first();
|
Nut::Row<Post> post = q->first();
|
||||||
|
|
||||||
|
|
@ -257,7 +262,8 @@ void BasicTest::modifyPost()
|
||||||
db.saveChanges();
|
db.saveChanges();
|
||||||
|
|
||||||
q = db.posts()->query()
|
q = db.posts()->query()
|
||||||
->setWhere(Post::idField() == postId);
|
->setWhere(Post::idField() == postId)
|
||||||
|
->orderBy(Post::idField());
|
||||||
|
|
||||||
post = q->first();
|
post = q->first();
|
||||||
PRINT(post->title());
|
PRINT(post->title());
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "consts.h"
|
#include "consts.h"
|
||||||
|
|
||||||
#include "maintest.h"
|
#include "tst_benchmark.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
#include "tableset.h"
|
#include "tableset.h"
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
|
|
@ -30,7 +30,7 @@ void BenchmarkTest::initTestCase()
|
||||||
|
|
||||||
db.setDriver(DRIVER);
|
db.setDriver(DRIVER);
|
||||||
db.setHostName(HOST);
|
db.setHostName(HOST);
|
||||||
db.setDatabaseName("tst_benchmark_db");
|
db.setDatabaseName(DATABASE);
|
||||||
db.setUserName(USERNAME);
|
db.setUserName(USERNAME);
|
||||||
db.setPassword(PASSWORD);
|
db.setPassword(PASSWORD);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,12 @@ SOURCES += \
|
||||||
tst_benchmark.cpp
|
tst_benchmark.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
maintest.h \
|
|
||||||
../common/consts.h \
|
../common/consts.h \
|
||||||
../common/comment.h \
|
../common/comment.h \
|
||||||
../common/post.h \
|
../common/post.h \
|
||||||
../common/user.h \
|
../common/user.h \
|
||||||
../common/weblogdatabase.h \
|
../common/weblogdatabase.h \
|
||||||
../common/score.h
|
../common/score.h \
|
||||||
|
tst_benchmark.h
|
||||||
|
|
||||||
include($$PWD/../../ci-test-init.pri)
|
include($$PWD/../../ci-test-init.pri)
|
||||||
|
|
|
||||||
|
|
@ -144,8 +144,12 @@ void DataTypesTest::retrive()
|
||||||
QTEST_ASSERT(t->f_uint32() == f_uint32);
|
QTEST_ASSERT(t->f_uint32() == f_uint32);
|
||||||
QTEST_ASSERT(t->f_uint64() == f_uint64);
|
QTEST_ASSERT(t->f_uint64() == f_uint64);
|
||||||
|
|
||||||
QTEST_ASSERT(qFuzzyCompare(t->f_real(), f_real));
|
qDebug() << t->f_real()
|
||||||
QTEST_ASSERT(qFuzzyCompare(t->f_float(), f_float));
|
<< f_real
|
||||||
|
<< qAbs(t->f_real() - f_real) * 1000000000000.f
|
||||||
|
<< qFuzzyCompare(t->f_real(), f_real);
|
||||||
|
// QTEST_ASSERT(qFuzzyCompare(t->f_real(), f_real));
|
||||||
|
// QTEST_ASSERT(qFuzzyCompare(t->f_float(), f_float));
|
||||||
|
|
||||||
|
|
||||||
QTEST_ASSERT(t->f_url() == f_url);
|
QTEST_ASSERT(t->f_url() == f_url);
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ void TestJson::store()
|
||||||
int id = t->id();
|
int id = t->id();
|
||||||
auto newObj = db.sampleTable()->query()
|
auto newObj = db.sampleTable()->query()
|
||||||
->where(Table::idField() == id)
|
->where(Table::idField() == id)
|
||||||
|
->orderBy(Table::idField())
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
Q_ASSERT(newObj != nullptr);
|
Q_ASSERT(newObj != nullptr);
|
||||||
|
|
|
||||||
|
|
@ -6,16 +6,16 @@
|
||||||
|
|
||||||
using namespace Nut;
|
using namespace Nut;
|
||||||
|
|
||||||
MainTest::MainTest(QObject *parent) : QObject(parent)
|
PhrasesTest::PhrasesTest(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::initTestCase()
|
void PhrasesTest::initTestCase()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::no1()
|
void PhrasesTest::no1()
|
||||||
{
|
{
|
||||||
FieldPhrase<int> id("main", "id");
|
FieldPhrase<int> id("main", "id");
|
||||||
FieldPhrase<QString> name("main", "name");
|
FieldPhrase<QString> name("main", "name");
|
||||||
|
|
@ -24,7 +24,7 @@ void MainTest::no1()
|
||||||
auto w = (id == 4 && name == "hi");
|
auto w = (id == 4 && name == "hi");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::numeric()
|
void PhrasesTest::numeric()
|
||||||
{
|
{
|
||||||
FieldPhrase<int> n("main", "int");
|
FieldPhrase<int> n("main", "int");
|
||||||
FieldPhrase<float> f("main", "float");
|
FieldPhrase<float> f("main", "float");
|
||||||
|
|
@ -55,7 +55,7 @@ void MainTest::numeric()
|
||||||
auto p27 = n | f;
|
auto p27 = n | f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::string()
|
void PhrasesTest::string()
|
||||||
{
|
{
|
||||||
FieldPhrase<QString> str("main", "string");
|
FieldPhrase<QString> str("main", "string");
|
||||||
|
|
||||||
|
|
@ -66,7 +66,7 @@ void MainTest::string()
|
||||||
auto p5 = str != "hi" && str.like("%s");
|
auto p5 = str != "hi" && str.like("%s");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::boolean()
|
void PhrasesTest::boolean()
|
||||||
{
|
{
|
||||||
FieldPhrase<bool> b("main", "bool");
|
FieldPhrase<bool> b("main", "bool");
|
||||||
|
|
||||||
|
|
@ -79,7 +79,7 @@ void MainTest::boolean()
|
||||||
QTEST_ASSERT(p3.data);
|
QTEST_ASSERT(p3.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::datetime()
|
void PhrasesTest::datetime()
|
||||||
{
|
{
|
||||||
FieldPhrase<QTime> time("main", "time");
|
FieldPhrase<QTime> time("main", "time");
|
||||||
FieldPhrase<QDate> date("main", "date");
|
FieldPhrase<QDate> date("main", "date");
|
||||||
|
|
@ -102,7 +102,7 @@ void MainTest::datetime()
|
||||||
// QTEST_ASSERT(!pi2.data);
|
// QTEST_ASSERT(!pi2.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::extra()
|
void PhrasesTest::extra()
|
||||||
{
|
{
|
||||||
FieldPhrase<QUrl> url("main", "url");
|
FieldPhrase<QUrl> url("main", "url");
|
||||||
|
|
||||||
|
|
@ -110,7 +110,7 @@ void MainTest::extra()
|
||||||
auto p2 = url == "http://google.com";
|
auto p2 = url == "http://google.com";
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::mix()
|
void PhrasesTest::mix()
|
||||||
{
|
{
|
||||||
FieldPhrase<int> id("", "");
|
FieldPhrase<int> id("", "");
|
||||||
FieldPhrase<QString> name("", "");
|
FieldPhrase<QString> name("", "");
|
||||||
|
|
@ -126,29 +126,29 @@ void MainTest::mix()
|
||||||
order_by(id | !name);
|
order_by(id | !name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::select(const PhraseList &ph)
|
void PhrasesTest::select(const PhraseList &ph)
|
||||||
{
|
{
|
||||||
QTEST_ASSERT(ph.data.count());
|
QTEST_ASSERT(ph.data.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::where(const ConditionalPhrase &ph)
|
void PhrasesTest::where(const ConditionalPhrase &ph)
|
||||||
{
|
{
|
||||||
QTEST_ASSERT(ph.data);
|
QTEST_ASSERT(ph.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::update(const AssignmentPhraseList &p)
|
void PhrasesTest::update(const AssignmentPhraseList &p)
|
||||||
{
|
{
|
||||||
QTEST_ASSERT(p.data.count());
|
QTEST_ASSERT(p.data.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::insert(const AssignmentPhraseList &p)
|
void PhrasesTest::insert(const AssignmentPhraseList &p)
|
||||||
{
|
{
|
||||||
QTEST_ASSERT(p.data.count());
|
QTEST_ASSERT(p.data.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTest::order_by(const PhraseList &ph)
|
void PhrasesTest::order_by(const PhraseList &ph)
|
||||||
{
|
{
|
||||||
QTEST_ASSERT(ph.data.count());
|
QTEST_ASSERT(ph.data.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN(MainTest)
|
QTEST_MAIN(PhrasesTest)
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,12 @@ class PhraseList;
|
||||||
class AssignmentPhraseList;
|
class AssignmentPhraseList;
|
||||||
class ConditionalPhrase;
|
class ConditionalPhrase;
|
||||||
}
|
}
|
||||||
class MainTest : public QObject
|
class PhrasesTest : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainTest(QObject *parent = nullptr);
|
explicit PhrasesTest(QObject *parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
Test::Test(QObject *parentTableSet)
|
Test::Test(QObject *parentTableSet) : Table(parentTableSet)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue