From fa21efde1b0195cf5fd010725a8857af17d45d3d Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Sat, 24 Feb 2018 19:13:15 +0330 Subject: [PATCH 01/12] wip: detect and apply foreign keys --- src/database.cpp | 2 +- src/defines_p.h | 1 + src/generators/sqlgeneratorbase.cpp | 123 +++++++++++++++++++++++--- src/generators/sqlgeneratorbase_p.h | 5 +- src/generators/sqlservergenerator.cpp | 25 ++---- src/generators/sqlservergenerator.h | 6 +- src/tablemodel.cpp | 101 ++++++++++++++++++--- src/tablemodel.h | 20 ++++- 8 files changed, 231 insertions(+), 52 deletions(-) diff --git a/src/database.cpp b/src/database.cpp index 749aa83..d8ac915 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -141,7 +141,7 @@ bool DatabasePrivate::updateDatabase() qDebug("Databse is changed"); QStringList sql = sqlGenertor->diff(last, current); - +qDebug()<<"database Sql =\n"<name + " " + fieldType(field) + (field->notNull ? " NOT NULL" : ""); } +QString SqlGeneratorBase::relationDeclare(const RelationModel *relation) +{ + return QString("FOREIGN KEY (FK_%1) REFERENCES %2(%1)") + .arg(relation->localColumn) + .arg(relation->slaveTable->name()); +} + QStringList SqlGeneratorBase::diff(DatabaseModel lastModel, DatabaseModel newModel) { @@ -125,9 +132,11 @@ QStringList SqlGeneratorBase::diff(DatabaseModel lastModel, TableModel *oldTable = lastModel.tableByName(table->name()); TableModel *newTable = newModel.tableByName(table->name()); QString sql = diff(oldTable, newTable); - if (!sql.isEmpty()) ret << sql; +// QString sqlRel = diffRelation(oldTable, newTable); +// if (!sqlRel.isEmpty()) +// ret << sqlRel; } return ret; @@ -161,14 +170,24 @@ QString SqlGeneratorBase::diff(TableModel *oldTable, TableModel *newTable) if (!newTable) return "DROP TABLE " + oldTable->name(); - QSet fieldNames; + QList fieldNames; + QList relations; - if (oldTable) + if (oldTable) { foreach (FieldModel *f, oldTable->fields()) - fieldNames.insert(f->name); + if (!fieldNames.contains(f->name)) + fieldNames.append(f->name); + foreach (RelationModel *r, oldTable->foregionKeys()) + if (!relations.contains(r->localColumn)) + relations.append(r->localColumn); + } foreach (FieldModel *f, newTable->fields()) - fieldNames.insert(f->name); + if (!fieldNames.contains(f->name)) + fieldNames.append(f->name); + foreach (RelationModel *r, newTable->foregionKeys()) + if (!relations.contains(r->localColumn)) + relations.append(r->localColumn); QStringList columnSql; foreach (QString fieldName, fieldNames) { @@ -183,22 +202,104 @@ QString SqlGeneratorBase::diff(TableModel *oldTable, TableModel *newTable) columnSql << fieldDeclare(newField); } } +// foreach (QString fieldName, relations) { +// RelationModel *newRelation = newTable->foregionKeyByField(fieldName); +// if (oldTable) { +// RelationModel *oldRelation = oldTable->foregionKeyByField(fieldName); + +// QString buffer = diff(oldRelation, newRelation); +// if (!buffer.isNull()) +// columnSql << buffer; +// } else { +// columnSql << relationDeclare(newRelation); +// } +// } QString sql; if (oldTable) { - sql = QString("ALTER TABLE %1 \n%2").arg(newTable->name()).arg( - columnSql.join(",\n")); + sql = QString("ALTER TABLE %1 \n%2") + .arg(newTable->name()) + .arg(columnSql.join(",\n")); } else { if (!newTable->primaryKey().isNull()) columnSql << QString("CONSTRAINT pk_%1 PRIMARY KEY (%2)") .arg(newTable->name()) .arg(newTable->primaryKey()); - sql = QString("CREATE TABLE %1 \n(%2)").arg(newTable->name()).arg( - columnSql.join(",\n")); + sql = QString("CREATE TABLE %1 \n(%2)") + .arg(newTable->name()) + .arg(columnSql.join(",\n")); } return sql; } +QString SqlGeneratorBase::diffRelation(TableModel *oldTable, TableModel *newTable) +{ + if (!newTable) + return ""; + + QList relations; + + if (oldTable) + foreach (RelationModel *r, oldTable->foregionKeys()) + if (!relations.contains(r->localColumn)) + relations.append(r->localColumn); + + foreach (RelationModel *r, newTable->foregionKeys()) + if (!relations.contains(r->localColumn)) + relations.append(r->localColumn); + + QStringList columnSql; + foreach (QString fieldName, relations) { + RelationModel *newRelation = newTable->foregionKeyByField(fieldName); + RelationModel *oldRelation = 0; + if (oldTable) + oldRelation = oldTable->foregionKeyByField(fieldName); + + QString buffer = diff(oldRelation, newRelation); + if (!buffer.isNull()) + columnSql << buffer; + } + + if (columnSql.count()) + return "ALTER TABLE " + newTable->name() + "\n" + + columnSql.join(",\n"); + else + return ""; + +} + +QString SqlGeneratorBase::diff(RelationModel *oldRel, RelationModel *newRel) +{ + /* + CONSTRAINT FK_PersonOrder FOREIGN KEY (PersonID) + REFERENCES Persons(PersonID) + + ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) REFERENCES %2(%3) + + return QString("ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) " + "REFERENCES %2(%3)") + .arg(newRelation->localColumn) + .arg(newRelation->masterTable->name()) + .arg(newRelation->foreignColumn); + */ + if (!oldRel) + return QString("ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) " + "REFERENCES %2(%3)") + .arg(newRel->localColumn) + .arg(newRel->masterTable->name()) + .arg(newRel->foreignColumn); + + if (!newRel) + return QString("ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) " + "REFERENCES %2(%3)") + .arg(oldRel->localColumn) + .arg(oldRel->masterTable->name()) + .arg(oldRel->foreignColumn); + +// if (*oldRel == *newRel) + return ""; +} + QString SqlGeneratorBase::join(const QString &mainTable, const QList list, QStringList *order) @@ -235,7 +336,7 @@ QString SqlGeneratorBase::join(const QStringList &list, QStringList *order) //TODO: make this ungly code better and bugless :-) /* * Known issues: - * Support onle near joins, far supports with medium table finding not support yet + * Support only near joins, far supports with medium table finding not support yet */ if (!list.count()) diff --git a/src/generators/sqlgeneratorbase_p.h b/src/generators/sqlgeneratorbase_p.h index ab9223c..650caba 100644 --- a/src/generators/sqlgeneratorbase_p.h +++ b/src/generators/sqlgeneratorbase_p.h @@ -65,10 +65,13 @@ public: virtual QString fieldType(FieldModel *field) = 0; virtual QString fieldDeclare(FieldModel *field); + virtual QString relationDeclare(const RelationModel *relation); virtual QStringList diff(DatabaseModel lastModel, DatabaseModel newModel); virtual QString diff(FieldModel *oldField, FieldModel *newField); virtual QString diff(TableModel *oldTable, TableModel *newTable); + virtual QString diffRelation(TableModel *oldTable, TableModel *newTable); + virtual QString diff(RelationModel *oldRel, RelationModel *newRel); virtual QString join(const QString &mainTable, const QList list, @@ -120,7 +123,7 @@ public: virtual QString phrase(const PhraseData *d) const; virtual QString operatorString(const PhraseData::Condition &cond) const; virtual void appendSkipTake(QString &sql, int skip = -1, int take = -1); -private: +protected: QString createConditionalPhrase(const PhraseData *d) const; QString createFieldPhrase(const PhraseList &ph); QString createOrderPhrase(const PhraseList &ph); diff --git a/src/generators/sqlservergenerator.cpp b/src/generators/sqlservergenerator.cpp index 13f43fd..549312b 100644 --- a/src/generators/sqlservergenerator.cpp +++ b/src/generators/sqlservergenerator.cpp @@ -91,6 +91,7 @@ QString SqlServerGenerator::fieldType(FieldModel *field) break; default: + Q_UNREACHABLE(); dbType = ""; } @@ -133,23 +134,11 @@ QString SqlServerGenerator::escapeValue(const QVariant &v) const return SqlGeneratorBase::escapeValue(v); } -//QString SqlServerGenerator::selectCommand(SqlGeneratorBase::AgregateType t, -// QString agregateArg, -// QString tableName, -// QList &wheres, -// QList &orders, -// QList 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; -//} +void SqlServerGenerator::appendSkipTake(QString &sql, int skip, int take) +{ + if (take != -1 && skip != -1) + sql.append(QString(" OFFSET %1 ROWS FETCH NEXT %2 ROWS ONLY") + .arg(skip).arg(take)); +} NUT_END_NAMESPACE diff --git a/src/generators/sqlservergenerator.h b/src/generators/sqlservergenerator.h index db47268..28f6dca 100644 --- a/src/generators/sqlservergenerator.h +++ b/src/generators/sqlservergenerator.h @@ -37,12 +37,8 @@ public: QString diff(FieldModel *oldField, FieldModel *newField); QString escapeValue(const QVariant &v) const; + void appendSkipTake(QString &sql, int skip, int take); -// QString selectCommand(AgregateType t, QString agregateArg, -// QString tableName, -// QList &wheres, -// QList &orders, -// QList joins, int skip, int take); }; NUT_END_NAMESPACE diff --git a/src/tablemodel.cpp b/src/tablemodel.cpp index 4f428bc..882edd7 100644 --- a/src/tablemodel.cpp +++ b/src/tablemodel.cpp @@ -90,7 +90,7 @@ QList TableModel::fields() const QList TableModel::foregionKeys() const { - return _foregionKeys; + return _foreignKeys; } QStringList TableModel::fieldsNames() const @@ -237,9 +237,9 @@ TableModel::TableModel(int typeId, QString tableName) fk->slaveTable = this; fk->localColumn = name + "Id"; fk->localProperty = name; - fk->foregionColumn = value; + fk->foreignColumn = value; fk->masterClassName = value; - _foregionKeys.append(fk); + _foreignKeys.append(fk); } if(type == __nut_FIELD){ @@ -292,6 +292,7 @@ TableModel::TableModel(QJsonObject json, QString tableName) _name = tableName; QJsonObject fields = json.value(__FIELDS).toObject(); + QJsonObject relations = json.value(__FOREIGN_KEYS).toObject(); foreach (QString key, fields.keys()) { QJsonObject fieldObject = fields.value(key).toObject(); FieldModel *f = new FieldModel; @@ -309,11 +310,16 @@ TableModel::TableModel(QJsonObject json, QString tableName) _fields.append(f); } - if(json.keys().contains(__nut_AUTO_INCREMENT)) - field(json.value(__nut_AUTO_INCREMENT).toString())->isAutoIncrement = true; + foreach (QString key, relations.keys()) { + QJsonObject relObject = fields.value(key).toObject(); + _foreignKeys.append(new RelationModel(relObject)); + } - if(json.keys().contains(__nut_PRIMARY_KEY)) - field(json.value(__nut_PRIMARY_KEY).toString())->isAutoIncrement = true; +// 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); } @@ -322,6 +328,7 @@ QJsonObject TableModel::toJson() const { QJsonObject obj; QJsonObject fieldsObj; + QJsonObject foreignKeysObj; foreach (FieldModel *f, _fields) { QJsonObject fieldObj; @@ -337,28 +344,41 @@ QJsonObject TableModel::toJson() const if(!f->defaultValue.isNull()) fieldObj.insert(__nut_DEFAULT_VALUE, f->defaultValue); - fieldsObj.insert(f->name, fieldObj); - if(f->isAutoIncrement) - obj.insert(__nut_PRIMARY_KEY, f->name); + obj.insert(__nut_AUTO_INCREMENT, f->name); if(f->isPrimaryKey) - obj.insert(__nut_AUTO_INCREMENT, f->name); + obj.insert(__nut_PRIMARY_KEY, f->name); + + fieldsObj.insert(f->name, fieldObj); } + foreach (RelationModel *rel, _foreignKeys) + foreignKeysObj.insert(rel->localColumn, rel->toJson()); + obj.insert(__FIELDS, fieldsObj); + obj.insert(__FOREIGN_KEYS, foreignKeysObj); return obj; } -RelationModel *TableModel::foregionKey(QString otherTable) const +RelationModel *TableModel::foregionKey(const QString &otherTable) const { - foreach (RelationModel *fk, _foregionKeys) + foreach (RelationModel *fk, _foreignKeys) if(fk->masterClassName == otherTable) return fk; return 0; } +RelationModel *TableModel::foregionKeyByField(const QString &fieldName) const +{ + foreach (RelationModel *fk, _foreignKeys) + if(fk->localColumn == fieldName) + return fk; + + return 0; +} + QString TableModel::toString() const { QStringList sl; @@ -379,4 +399,59 @@ QString TableModel::primaryKey() const return QString::null; } +FieldModel::FieldModel(const QJsonObject &json) +{ + name = json.value(__NAME).toString(); + type = static_cast(json.value(__TYPE).toInt()); + length = json.value(__nut_LEN).toInt(); + notNull = json.value(__nut_NOT_NULL).toBool(); + isAutoIncrement = json.value(__nut_AUTO_INCREMENT).toBool(); + isPrimaryKey = json.value(__nut_PRIMARY_KEY).toBool(); + defaultValue = json.value(__nut_DEFAULT_VALUE).toString(); +} + +QJsonObject FieldModel::toJson() const +{ + QJsonObject fieldObj; + fieldObj.insert(__NAME, name); + fieldObj.insert(__TYPE, QString(QVariant::typeToName(type))); + fieldObj.insert(__nut_LEN, length); + fieldObj.insert(__nut_NOT_NULL, notNull); + fieldObj.insert(__nut_AUTO_INCREMENT, isAutoIncrement); + fieldObj.insert(__nut_PRIMARY_KEY, isPrimaryKey); + fieldObj.insert(__nut_DEFAULT_VALUE, defaultValue); + return fieldObj; +} + +RelationModel::RelationModel(const QJsonObject &obj) +{ + localColumn = obj.value("localColumn").toString(); + localProperty = obj.value("localProperty").toString(); + masterClassName = obj.value("masterClassName").toString(); + foreignColumn = obj.value("foreignColumn").toString(); +} + +QJsonObject RelationModel::toJson() const +{ + QJsonObject o; + o.insert("localColumn", localColumn); + o.insert("localProperty", localProperty); + o.insert("masterClassName", masterClassName); + o.insert("foreignColumn", foreignColumn); + return o; +} + +bool operator ==(const RelationModel &l, const RelationModel &r) +{ + return r.foreignColumn == l.foreignColumn + && r.localColumn == l.localColumn + && r.localProperty == l.localColumn + && r.masterClassName == l.masterClassName; +} + +bool operator !=(const RelationModel &l, const RelationModel &r) +{ + return !(l == r); +} + NUT_END_NAMESPACE diff --git a/src/tablemodel.h b/src/tablemodel.h index e089ed2..4fe2f66 100644 --- a/src/tablemodel.h +++ b/src/tablemodel.h @@ -37,6 +37,8 @@ struct FieldModel{ } + FieldModel(const QJsonObject &json); + QString name; //TODO: QMetaType::Type?? QVariant::Type type; @@ -63,19 +65,30 @@ struct FieldModel{ bool operator !=(const FieldModel &f) const{ return !(*this == f); } + + QJsonObject toJson() const; }; struct RelationModel{ + RelationModel() : localColumn(""), localProperty(""), slaveTable(0), + foreignColumn(""), masterTable(0), masterClassName("") + {} + RelationModel(const QJsonObject &obj); + //slave QString localColumn; QString localProperty; TableModel *slaveTable; //master - QString foregionColumn; + QString foreignColumn; TableModel *masterTable; QString masterClassName; + + QJsonObject toJson() const; }; +bool operator ==(const RelationModel &l, const RelationModel &r); +bool operator !=(const RelationModel &l, const RelationModel &r); class TableModel { public: @@ -91,7 +104,8 @@ public: FieldModel *field(int n) const; FieldModel *field(QString name) const; - RelationModel *foregionKey(QString otherTable) const; + RelationModel *foregionKey(const QString &otherTable) const; + RelationModel *foregionKeyByField(const QString &fieldName) const; QString toString() const; @@ -122,7 +136,7 @@ private: QString _className; int _typeId; QList _fields; - QList _foregionKeys; + QList _foreignKeys; static QSet_allModels; bool checkClassInfo(const QMetaClassInfo &classInfo, QString &type, QString &name, QString &value); From f0fa6bd6bf02f63af5e87240d1c315cda47e1f27 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Sun, 25 Feb 2018 18:47:49 +0330 Subject: [PATCH 02/12] CONFIG += c++11 --- nut.pri | 2 ++ src/generators/sqlgeneratorbase_p.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/nut.pri b/nut.pri index d479e7d..15b253b 100644 --- a/nut.pri +++ b/nut.pri @@ -1,5 +1,7 @@ QT += core sql +CONFIG += c++11 + INCLUDEPATH += $$PWD/include HEADERS += \ diff --git a/src/generators/sqlgeneratorbase_p.h b/src/generators/sqlgeneratorbase_p.h index 650caba..d8a2e8f 100644 --- a/src/generators/sqlgeneratorbase_p.h +++ b/src/generators/sqlgeneratorbase_p.h @@ -41,6 +41,7 @@ class SqlGeneratorBase : public QObject Database *_database; public: + //TODO: remove this enum enum CommandType{ Select, Insert, @@ -96,7 +97,8 @@ public: const int take = -1); virtual QString selectCommand(const QString &tableName, - const AgregateType &t, const QString &agregateArg, + const AgregateType &t, + const QString &agregateArg, const ConditionalPhrase &where, const QList &joins, const int skip = -1, From 71a59ac0a2503525dfa3c30d9d979c95cd83c7b5 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Sun, 25 Feb 2018 18:51:42 +0330 Subject: [PATCH 03/12] changed qinfo syntax for travis error --- src/query.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/query.h b/src/query.h index 33e9174..28fb454 100644 --- a/src/query.h +++ b/src/query.h @@ -419,8 +419,8 @@ Q_OUTOFLINE_TEMPLATE Query *Query::join(const QString &className) .relationByClassNames(className, d->className); if (!rel) { - qInfo("No relation between %s and %s", - qPrintable(d->className), qPrintable(className)); + qInfo() << "No relation between" << d->className + << "and" << className; return this; } From 253064567b52d5dcedff56cc4d031182b46de665 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Sun, 25 Feb 2018 19:03:51 +0330 Subject: [PATCH 04/12] CONFIG += c++11 in pro file --- nut.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/nut.pro b/nut.pro index 9603a19..9302c34 100644 --- a/nut.pro +++ b/nut.pro @@ -3,6 +3,7 @@ QT -= gui TARGET = nut TEMPLATE = lib +CONFIG += c++11 DEFINES += QT_DEPRECATED_WARNINGS From d0f73c167374a352b74c6179dc7686afa53a46e5 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Sun, 25 Feb 2018 20:14:01 +0330 Subject: [PATCH 05/12] new travic yml --- .travis.yml | 84 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 528bb2a..7fe3b3d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,81 @@ +#Based on https://github.com/pcolby/libqtaws/blob/master/.travis.yml +language: cpp + +os: + - linux + - osx + +dist: trusty + +compiler: + - clang + - gcc + +env: + matrix: + - QT=5 BREW= + - QT=5 BREW=ex PPA=ubuntu-sdk-team/ppa + - QT=51 BREW=ex PPA=beineri/opt-qt511-trusty + - QT=52 BREW=ex PPA=beineri/opt-qt521-trusty + - QT=53 BREW=ex PPA=beineri/opt-qt532-trusty + - QT=54 BREW=ex PPA=beineri/opt-qt542-trusty + - QT=55 BREW=@5.5 PPA=beineri/opt-qt551-trusty + - QT=56 BREW=ex PPA=beineri/opt-qt562-trusty + - QT=56 BREW=ex PPA=beineri/opt-qt563-trusty + - QT=57 BREW=@5.7 PPA=beineri/opt-qt571-trusty + - QT=58 BREW=ex PPA=beineri/opt-qt58-trusty + - QT=59 BREW=@5.9 PPA=beineri/opt-qt591-trusty + +matrix: + exclude: + - { os: osx, env: QT=5 BREW=ex PPA=ubuntu-sdk-team/ppa } + - { os: osx, env: QT=51 BREW=ex PPA=beineri/opt-qt511-trusty } + - { os: osx, env: QT=52 BREW=ex PPA=beineri/opt-qt521-trusty } + - { os: osx, env: QT=53 BREW=ex PPA=beineri/opt-qt532-trusty } + - { os: osx, env: QT=54 BREW=ex PPA=beineri/opt-qt542-trusty } + - { os: osx, env: QT=56 BREW=ex PPA=beineri/opt-qt562-trusty } + - { os: osx, env: QT=56 BREW=ex PPA=beineri/opt-qt563-trusty } + - { os: osx, env: QT=58 BREW=ex PPA=beineri/opt-qt58-trusty } + +addons: + coverity_scan: + project: + name: "HamedMasafi/Nut" + description: "Build submitted via Travis CI" + # notification_email: em@h + build_command_prepend: > + cp -a "$TRAVIS_BUILD_DIR" "$TRAVIS_BUILD_DIR-scan" && + pushd "$TRAVIS_BUILD_DIR-scan" && + qmake -qt=qt5 -Wall -Wlogic -Wparser CONFIG+=debug_and_release + build_command: make all + #branch_pattern: coverity + before_install: - - sudo add-apt-repository --yes ppa:ubuntu-sdk-team/ppa - - sudo apt-get update -qq - - sudo apt-get install qtbase5-dev qtdeclarative5-dev libqt5webkit5-dev libsqlite3-dev - - sudo apt-get install qt5-default qttools5-dev-tools + - '[[ "$TRAVIS_OS_NAME" != linux || -z "$PPA" ]] || sudo add-apt-repository -y ppa:$PPA' + - '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-get -qy update' + - '[ "$TRAVIS_OS_NAME" != osx ] || brew update' + +install: + - '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-get -qy install cppcheck doxygen graphviz lcov' + - '[[ "$TRAVIS_OS_NAME" != linux || "$PPA" != */opt-* ]] || sudo apt-get -qy install qt${QT}base qt${QT}xmlpatterns' + - '[[ "$TRAVIS_OS_NAME" != linux || "$PPA" == */opt-* ]] || sudo apt-get -qy install qt5-qmake qtbase5-dev libqt5xmlpatterns5-dev' + - '[ "$TRAVIS_OS_NAME" != linux ] || gem install lcoveralls' + - '[ "$TRAVIS_OS_NAME" != osx ] || brew install cppcheck doxygen graphviz qt$BREW' + - '[ "$TRAVIS_OS_NAME" != osx ] || brew link --force qt$BREW' + - qmake -v + +before_script: + - cppcheck --error-exitcode=1 --quiet + . + - '[[ "$TRAVIS_OS_NAME" != linux || "$CXX" != clang++ ]] || export QMAKESPEC=linux-clang' + - '[[ "$TRAVIS_OS_NAME" != linux || "$CXX" != g++ ]] || export QMAKESPEC=linux-g++' + - '[[ "$TRAVIS_OS_NAME" != osx || "$CXX" != clang++ ]] || export QMAKESPEC=macx-clang' + - '[[ "$TRAVIS_OS_NAME" != osx || "$CXX" != g++ ]] || export QMAKESPEC=macx-g++' + - '[[ "$TRAVIS_OS_NAME" != linux || "$PPA" != */opt-* ]] || . /opt/qt$QT/bin/qt$QT-env.sh' + - '[[ "$TRAVIS_OS_NAME" != linux || "$PPA" == */opt-* ]] || export QT_SELECT=qt5' + - mkdir -p "$TRAVIS_BUILD_DIR-build" + - qmake -o "$TRAVIS_BUILD_DIR-build" -r -Wall -Wlogic -Wparser CONFIG+=debug_and_release "$TRAVIS_BUILD_DIR" script: - - qmake nut.pro - - make + - make -C "$TRAVIS_BUILD_DIR-build" all + - make -C "$TRAVIS_BUILD_DIR-build" -j2 check TESTARGS=-silent From e049a4409abf9dd7a704e183321a0ed5f26f57e4 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Sun, 25 Feb 2018 20:54:29 +0330 Subject: [PATCH 06/12] phrase better operators [skip ci] --- src/phrase.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++----- src/phrase.h | 12 +++++++++++- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/phrase.cpp b/src/phrase.cpp index 9c1ab02..8a5800e 100644 --- a/src/phrase.cpp +++ b/src/phrase.cpp @@ -223,15 +223,26 @@ AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhras // l->data = 0; } +AssignmentPhrase::~AssignmentPhrase() +{ + if (data) + delete data; +} + //AssignmentPhrase::AssignmentPhrase(AssignmentPhrase *l, const AssignmentPhrase *r) //{ //// data = new PhraseData(l->data, PhraseData::Append, r->data); // qFatal("SS"); //} -AssignmentPhraseList AssignmentPhrase::operator &(const AssignmentPhrase &other) +//AssignmentPhraseList AssignmentPhrase::operator &(const AssignmentPhrase &other) +//{ +// return AssignmentPhraseList(this, &other); +//} + +AssignmentPhraseList::AssignmentPhraseList() { - return AssignmentPhraseList(this, &other); + } AssignmentPhraseList::AssignmentPhraseList(const AssignmentPhrase &l) @@ -245,10 +256,10 @@ AssignmentPhraseList::AssignmentPhraseList(AssignmentPhraseList *l, const Assign data.append(r->data); } -AssignmentPhraseList::AssignmentPhraseList(AssignmentPhrase *l, const AssignmentPhrase *r) +AssignmentPhraseList::AssignmentPhraseList(const AssignmentPhrase &r, const AssignmentPhrase &l) { - data.append(l->data); - data.append(r->data); + data.append(l.data); + data.append(r.data); } AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase &ph) @@ -256,6 +267,11 @@ AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase &ph return AssignmentPhraseList(this, &ph); } +AssignmentPhraseList::~AssignmentPhraseList() +{ + qDeleteAll(data); +} + ConditionalPhrase::ConditionalPhrase() : data(0) { } @@ -374,4 +390,27 @@ ConditionalPhrase ConditionalPhrase::operator !() return f; } +AssignmentPhraseList operator &(const AssignmentPhrase &l, const AssignmentPhrase &r) +{ + return AssignmentPhraseList(l, r); +} + +AssignmentPhraseList operator &(const AssignmentPhrase &l, AssignmentPhrase &&r) +{ + r.data = 0; + return AssignmentPhraseList(l, r); +} + +AssignmentPhraseList operator &(AssignmentPhrase &&l, const AssignmentPhrase &r) +{ + l.data = 0; + return AssignmentPhraseList(l, r); +} + +AssignmentPhraseList operator &(AssignmentPhrase &&l, AssignmentPhrase &&r) +{ + r.data = l.data = 0; + return AssignmentPhraseList(l, r); +} + NUT_END_NAMESPACE diff --git a/src/phrase.h b/src/phrase.h index 2e45c25..53b5326 100644 --- a/src/phrase.h +++ b/src/phrase.h @@ -115,11 +115,15 @@ class AssignmentPhraseList { public: QList data; + AssignmentPhraseList(); AssignmentPhraseList(const AssignmentPhrase &l); AssignmentPhraseList(AssignmentPhraseList *l, const AssignmentPhrase *r); AssignmentPhraseList(AssignmentPhrase *l, const AssignmentPhrase *r); + AssignmentPhraseList(const AssignmentPhrase &r, const AssignmentPhrase &l); AssignmentPhraseList operator &(const AssignmentPhrase &ph); + + ~AssignmentPhraseList(); }; class AssignmentPhrase @@ -128,12 +132,18 @@ public: PhraseData *data; AssignmentPhrase(AbstractFieldPhrase *l, QVariant r); AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhrase *r); + ~AssignmentPhrase(); // AssignmentPhrase(AssignmentPhrase *l, const AssignmentPhrase *r); - AssignmentPhraseList operator &(const AssignmentPhrase &other); +// AssignmentPhraseList operator &(const AssignmentPhrase &other); }; +AssignmentPhraseList operator &(const AssignmentPhrase &l, const AssignmentPhrase &r); +AssignmentPhraseList operator &(const AssignmentPhrase &l, AssignmentPhrase &&r); +AssignmentPhraseList operator &(AssignmentPhrase &&l, const AssignmentPhrase &r); +AssignmentPhraseList operator &(AssignmentPhrase &&l, AssignmentPhrase &&r); + class PhraseList{ public: bool isValid; From 6820886a2b5f00a61da094372007fb73282c63e5 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Mon, 26 Feb 2018 10:17:05 +0330 Subject: [PATCH 07/12] disabled cppcheck --- .travis.yml | 2 +- src/phrase.h | 17 +++++++++++++++++ test/basic/maintest.cpp | 8 ++++++++ test/basic/maintest.h | 1 + test/common/post.h | 1 + 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7fe3b3d..ab6919a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -65,7 +65,7 @@ install: - qmake -v before_script: - - cppcheck --error-exitcode=1 --quiet + #- cppcheck --error-exitcode=1 --quiet . - '[[ "$TRAVIS_OS_NAME" != linux || "$CXX" != clang++ ]] || export QMAKESPEC=linux-clang' - '[[ "$TRAVIS_OS_NAME" != linux || "$CXX" != g++ ]] || export QMAKESPEC=linux-g++' diff --git a/src/phrase.h b/src/phrase.h index 53b5326..8b22dfb 100644 --- a/src/phrase.h +++ b/src/phrase.h @@ -319,6 +319,23 @@ SPECIALIZATION_NUMERIC(qreal) return ConditionalPhrase(this, cond, val); \ } +template<> +class FieldPhrase : public AbstractFieldPhrase +{ +public: + FieldPhrase(const char *className, const char *s) : + AbstractFieldPhrase(className, s) + {} + + AssignmentPhrase operator =(const bool &other) { + return AssignmentPhrase(this, other); + } + operator ConditionalPhrase() + { + return ConditionalPhrase(this, PhraseData::Equal, !data->isNot); + } +}; + template<> class FieldPhrase : public AbstractFieldPhrase { diff --git a/test/basic/maintest.cpp b/test/basic/maintest.cpp index 5bc22f3..f7e491a 100644 --- a/test/basic/maintest.cpp +++ b/test/basic/maintest.cpp @@ -119,6 +119,14 @@ void MainTest::createPost2() qDebug() << "New post2 inserted with id:" << newPost->id(); } +void MainTest::selectPublicts() +{ + auto q = db.postTable()->query() + ->where(Post::isPublicField()) + ->toList(); + +} + void MainTest::selectPosts() { auto q = db.postTable()->query() diff --git a/test/basic/maintest.h b/test/basic/maintest.h index 5a56759..f03b91f 100644 --- a/test/basic/maintest.h +++ b/test/basic/maintest.h @@ -27,6 +27,7 @@ private slots: void createUser(); void createPost(); void createPost2(); + void selectPublicts(); void join(); void selectPosts(); void selectScoreAverage(); diff --git a/test/common/post.h b/test/common/post.h index ddf7936..7759b8c 100644 --- a/test/common/post.h +++ b/test/common/post.h @@ -27,6 +27,7 @@ class Post : public Table NUT_DECLARE_FIELD(QDateTime, saveDate, saveDate, setSaveDate) NUT_DECLARE_FIELD(QString, body, body, setBody) + NUT_DECLARE_FIELD(bool, isPublic, isPublic, setPublic) NUT_DECLARE_CHILD_TABLE(Comment, comments) NUT_DECLARE_CHILD_TABLE(Score, scores) From cd07c580f66dec3e7abdcd6192ae7e0c4f0b487c Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Mon, 26 Feb 2018 10:23:50 +0330 Subject: [PATCH 08/12] FieldPhrase specialization --- src/phrase.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/phrase.h b/src/phrase.h index 8b22dfb..d56b1dc 100644 --- a/src/phrase.h +++ b/src/phrase.h @@ -25,7 +25,7 @@ #include #include #include -#if __cplusplus >= 201103L +#ifdef Q_COMPILER_INITIALIZER_LISTS # include #endif @@ -330,6 +330,15 @@ public: AssignmentPhrase operator =(const bool &other) { return AssignmentPhrase(this, other); } + + FieldPhrase operator !() + { + FieldPhrase f(data->className, data->fieldName); + f.data = new PhraseData(data); + f.data->isNot = !data->isNot; + return f; + } + operator ConditionalPhrase() { return ConditionalPhrase(this, PhraseData::Equal, !data->isNot); From 465aee8998c4f5a8eb8487c687f9ee7902b60813 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Mon, 26 Feb 2018 13:44:36 +0330 Subject: [PATCH 09/12] some polish --- src/changelogtable.h | 2 +- src/database.cpp | 4 +- src/database.h | 6 +- src/database_p.h | 2 +- src/databasemodel.cpp | 5 ++ src/databasemodel.h | 1 + src/generators/mysqlgenerator.h | 2 +- src/generators/postgresqlgenerator.h | 2 +- src/generators/sqlgeneratorbase.cpp | 2 +- src/generators/sqlgeneratorbase_p.h | 2 +- src/generators/sqlitegenerator.h | 2 +- src/generators/sqlservergenerator.cpp | 2 +- src/generators/sqlservergenerator.h | 2 +- src/phrase.cpp | 102 +++++++++++++++----------- src/phrase.h | 31 ++++---- src/query.cpp | 2 +- src/query.h | 4 +- src/query_p.h | 2 +- src/sqlmodel.cpp | 5 ++ src/sqlmodel.h | 2 +- src/sqlmodel_p.h | 2 + src/table.cpp | 2 +- src/tablemodel.cpp | 2 + src/tablemodel.h | 11 ++- src/tableset.h | 4 +- src/tablesetbase_p.h | 4 +- src/types/dbgeography.h | 4 +- test/basic/maintest.cpp | 14 ++++ test/basic/maintest.h | 1 + 29 files changed, 139 insertions(+), 87 deletions(-) diff --git a/src/changelogtable.h b/src/changelogtable.h index 27c4f70..84475a5 100644 --- a/src/changelogtable.h +++ b/src/changelogtable.h @@ -38,7 +38,7 @@ class ChangeLogTable : public Table NUT_DECLARE_FIELD(QString, version, version, setVersion) public: - ChangeLogTable(QObject *parentTableSet = Q_NULLPTR); + explicit ChangeLogTable(QObject *parentTableSet = Q_NULLPTR); }; NUT_END_NAMESPACE diff --git a/src/database.cpp b/src/database.cpp index d8ac915..9d5983b 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -52,7 +52,9 @@ NUT_BEGIN_NAMESPACE qulonglong DatabasePrivate::lastId = 0; QMap DatabasePrivate::allTableMaps; -DatabasePrivate::DatabasePrivate(Database *parent) : q_ptr(parent), isDatabaseNew(false) +DatabasePrivate::DatabasePrivate(Database *parent) : q_ptr(parent), + port(0), sqlGenertor(0), changeLogs(0), + isDatabaseNew(false) { } diff --git a/src/database.h b/src/database.h index 9dbc08e..1885be5 100644 --- a/src/database.h +++ b/src/database.h @@ -43,9 +43,9 @@ class NUT_EXPORT Database : public QObject Q_DECLARE_PRIVATE(Database) public: - Database(QObject *parent = 0); - Database(const Database &other); - Database(const QSqlDatabase &other); + explicit Database(QObject *parent = 0); + explicit Database(const Database &other); + explicit Database(const QSqlDatabase &other); ~Database(); bool open(); diff --git a/src/database_p.h b/src/database_p.h index 7c8709d..3299e4a 100644 --- a/src/database_p.h +++ b/src/database_p.h @@ -35,7 +35,7 @@ class DatabasePrivate Q_DECLARE_PUBLIC(Database) public: - DatabasePrivate(Database *parent); + explicit DatabasePrivate(Database *parent); bool open(bool updateDatabase); diff --git a/src/databasemodel.cpp b/src/databasemodel.cpp index e5adc6d..792cda1 100644 --- a/src/databasemodel.cpp +++ b/src/databasemodel.cpp @@ -57,6 +57,11 @@ DatabaseModel::DatabaseModel(const QJsonObject &json) : } } +DatabaseModel::DatabaseModel(DatabaseModel &model) +{ + +} + TableModel *DatabaseModel::tableByName(QString tableName) const { for(int i = 0; i < size(); i++){ diff --git a/src/databasemodel.h b/src/databasemodel.h index c4e25b8..e8342fd 100644 --- a/src/databasemodel.h +++ b/src/databasemodel.h @@ -43,6 +43,7 @@ public: DatabaseModel(const QString &name = QString::null); DatabaseModel(const DatabaseModel &other); DatabaseModel(const QJsonObject &json); + DatabaseModel(DatabaseModel &model); TableModel *tableByName(QString tableName) const; TableModel *tableByClassName(QString className) const; diff --git a/src/generators/mysqlgenerator.h b/src/generators/mysqlgenerator.h index d2224f4..c5916ba 100644 --- a/src/generators/mysqlgenerator.h +++ b/src/generators/mysqlgenerator.h @@ -29,7 +29,7 @@ NUT_BEGIN_NAMESPACE class MySqlGenerator : public SqlGeneratorBase { public: - MySqlGenerator(Database *parent = 0); + explicit MySqlGenerator(Database *parent = 0); QString fieldType(FieldModel *field); QString escapeValue(const QVariant &v) const; diff --git a/src/generators/postgresqlgenerator.h b/src/generators/postgresqlgenerator.h index 903cca8..028cea4 100644 --- a/src/generators/postgresqlgenerator.h +++ b/src/generators/postgresqlgenerator.h @@ -29,7 +29,7 @@ NUT_BEGIN_NAMESPACE class PostgreSqlGenerator : public SqlGeneratorBase { public: - PostgreSqlGenerator(Database *parent); + explicit PostgreSqlGenerator(Database *parent); QString fieldType(FieldModel *field); diff --git a/src/generators/sqlgeneratorbase.cpp b/src/generators/sqlgeneratorbase.cpp index 686c3d8..44efaec 100644 --- a/src/generators/sqlgeneratorbase.cpp +++ b/src/generators/sqlgeneratorbase.cpp @@ -959,7 +959,7 @@ QString SqlGeneratorBase::createConditionalPhrase(const PhraseData *d) const else if (op == PhraseData::AddMonths) ret = QString("DATEADD(month, %1, %2)") .arg(d->operand.toString()).arg(createConditionalPhrase(d->left)); - else if (op == PhraseData::AddYears) + else if (op == PhraseData::AddDays) ret = QString("DATEADD(day, %1, %2)") .arg(d->operand.toString()).arg(createConditionalPhrase(d->left)); else if (op == PhraseData::AddHours) diff --git a/src/generators/sqlgeneratorbase_p.h b/src/generators/sqlgeneratorbase_p.h index d8a2e8f..d0aa239 100644 --- a/src/generators/sqlgeneratorbase_p.h +++ b/src/generators/sqlgeneratorbase_p.h @@ -57,7 +57,7 @@ public: SignleField }; - SqlGeneratorBase(Database *parent); + explicit SqlGeneratorBase(Database *parent); virtual ~SqlGeneratorBase(); virtual QString masterDatabaseName(QString databaseName); diff --git a/src/generators/sqlitegenerator.h b/src/generators/sqlitegenerator.h index 1a28c32..5969cde 100644 --- a/src/generators/sqlitegenerator.h +++ b/src/generators/sqlitegenerator.h @@ -29,7 +29,7 @@ NUT_BEGIN_NAMESPACE class SqliteGenerator : public SqlGeneratorBase { public: - SqliteGenerator(Database *parent = 0); + explicit SqliteGenerator(Database *parent = 0); QString fieldType(FieldModel *field); diff --git a/src/generators/sqlservergenerator.cpp b/src/generators/sqlservergenerator.cpp index 549312b..7d0e128 100644 --- a/src/generators/sqlservergenerator.cpp +++ b/src/generators/sqlservergenerator.cpp @@ -126,7 +126,7 @@ QString SqlServerGenerator::escapeValue(const QVariant &v) const QPoint pt = v.toPoint(); return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg( pt.y()); - } else if (v.type() == QVariant::Point) { + } else if (v.type() == QVariant::PointF) { QPointF pt = v.toPointF(); return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg( pt.y()); diff --git a/src/generators/sqlservergenerator.h b/src/generators/sqlservergenerator.h index 28f6dca..4ef2f7c 100644 --- a/src/generators/sqlservergenerator.h +++ b/src/generators/sqlservergenerator.h @@ -29,7 +29,7 @@ NUT_BEGIN_NAMESPACE class SqlServerGenerator : public SqlGeneratorBase { public: - SqlServerGenerator(Database *parent = 0); + explicit SqlServerGenerator(Database *parent = 0); QString masterDatabaseName(QString databaseName); diff --git a/src/phrase.cpp b/src/phrase.cpp index 8a5800e..e70f01b 100644 --- a/src/phrase.cpp +++ b/src/phrase.cpp @@ -45,23 +45,20 @@ PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o, 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) + type(WithVariant), operatorCond(o), left(new PhraseData(l)), right(0), 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"; - } -} +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) +{ } + +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) +{ } QString PhraseData::toString() const { @@ -169,7 +166,7 @@ PhraseList::PhraseList() : isValid(false) } -PhraseList::PhraseList(const PhraseList &other) +PhraseList::PhraseList(const PhraseList &other) : isValid(true) { data = qMove(other.data); } @@ -211,7 +208,10 @@ PhraseList PhraseList::operator |(PhraseList &other) { return PhraseList(this, &other); } -AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, QVariant r) +AssignmentPhrase::AssignmentPhrase(PhraseData *d) : data(d) +{ } + +AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, const QVariant r) { data = new PhraseData(l->data, PhraseData::Equal, r); // l->data = 0; @@ -223,6 +223,17 @@ AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhras // l->data = 0; } +AssignmentPhrase::AssignmentPhrase(AssignmentPhrase *ph, const QVariant &v) +{ + data = new PhraseData(ph->data, PhraseData::Equal, v); +} + +//AssignmentPhrase::AssignmentPhrase(AssignmentPhrase &other) +//{ +// data = other.data; +// other.data = 0; +//} + AssignmentPhrase::~AssignmentPhrase() { if (data) @@ -235,10 +246,10 @@ AssignmentPhrase::~AssignmentPhrase() // qFatal("SS"); //} -//AssignmentPhraseList AssignmentPhrase::operator &(const AssignmentPhrase &other) -//{ -// return AssignmentPhraseList(this, &other); -//} +AssignmentPhraseList AssignmentPhrase::operator &(const AssignmentPhrase &other) +{ + return AssignmentPhraseList(this, &other); +} AssignmentPhraseList::AssignmentPhraseList() { @@ -256,6 +267,12 @@ AssignmentPhraseList::AssignmentPhraseList(AssignmentPhraseList *l, const Assign data.append(r->data); } +AssignmentPhraseList::AssignmentPhraseList(AssignmentPhrase *l, const AssignmentPhrase *r) +{ + data.append(l->data); + data.append(r->data); +} + AssignmentPhraseList::AssignmentPhraseList(const AssignmentPhrase &r, const AssignmentPhrase &l) { data.append(l.data); @@ -269,7 +286,8 @@ AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase &ph AssignmentPhraseList::~AssignmentPhraseList() { - qDeleteAll(data); +// qDeleteAll(data); +// data.clear(); } ConditionalPhrase::ConditionalPhrase() : data(0) @@ -355,7 +373,7 @@ ConditionalPhrase::~ConditionalPhrase() delete data; } -ConditionalPhrase ConditionalPhrase::operator =(const ConditionalPhrase &other) +ConditionalPhrase &ConditionalPhrase::operator =(const ConditionalPhrase &other) { this->data = new PhraseData(other.data); return *this; @@ -390,27 +408,27 @@ ConditionalPhrase ConditionalPhrase::operator !() return f; } -AssignmentPhraseList operator &(const AssignmentPhrase &l, const AssignmentPhrase &r) -{ - return AssignmentPhraseList(l, r); -} +//AssignmentPhraseList operator &(const AssignmentPhrase &l, const AssignmentPhrase &r) +//{ +// return AssignmentPhraseList(l, r); +//} -AssignmentPhraseList operator &(const AssignmentPhrase &l, AssignmentPhrase &&r) -{ - r.data = 0; - return AssignmentPhraseList(l, r); -} +//AssignmentPhraseList operator &(const AssignmentPhrase &l, AssignmentPhrase &&r) +//{ +// r.data = 0; +// return AssignmentPhraseList(l, r); +//} -AssignmentPhraseList operator &(AssignmentPhrase &&l, const AssignmentPhrase &r) -{ - l.data = 0; - return AssignmentPhraseList(l, r); -} +//AssignmentPhraseList operator &(AssignmentPhrase &&l, const AssignmentPhrase &r) +//{ +// l.data = 0; +// return AssignmentPhraseList(l, r); +//} -AssignmentPhraseList operator &(AssignmentPhrase &&l, AssignmentPhrase &&r) -{ - r.data = l.data = 0; - return AssignmentPhraseList(l, r); -} +//AssignmentPhraseList operator &(AssignmentPhrase &&l, AssignmentPhrase &&r) +//{ +// r.data = l.data = 0; +// return AssignmentPhraseList(l, r); +//} NUT_END_NAMESPACE diff --git a/src/phrase.h b/src/phrase.h index d56b1dc..2535384 100644 --- a/src/phrase.h +++ b/src/phrase.h @@ -103,8 +103,8 @@ public: PhraseData(PhraseData *l, Condition o); PhraseData(PhraseData *l, Condition o, const PhraseData *r); PhraseData(PhraseData *l, Condition o, QVariant r); - - PhraseData(const PhraseData *other); + explicit PhraseData(const PhraseData &other); + explicit PhraseData(const PhraseData *other); QString toString() const; @@ -115,7 +115,7 @@ class AssignmentPhraseList { public: QList data; - AssignmentPhraseList(); + explicit AssignmentPhraseList(); AssignmentPhraseList(const AssignmentPhrase &l); AssignmentPhraseList(AssignmentPhraseList *l, const AssignmentPhrase *r); AssignmentPhraseList(AssignmentPhrase *l, const AssignmentPhrase *r); @@ -130,25 +130,28 @@ class AssignmentPhrase { public: PhraseData *data; - AssignmentPhrase(AbstractFieldPhrase *l, QVariant r); - AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhrase *r); + explicit AssignmentPhrase(PhraseData *d); + explicit AssignmentPhrase(AbstractFieldPhrase *l, const QVariant r); + explicit AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhrase *r); + explicit AssignmentPhrase(AssignmentPhrase *ph, const QVariant &v); +// explicit AssignmentPhrase(AssignmentPhrase &other); ~AssignmentPhrase(); // AssignmentPhrase(AssignmentPhrase *l, const AssignmentPhrase *r); -// AssignmentPhraseList operator &(const AssignmentPhrase &other); + AssignmentPhraseList operator &(const AssignmentPhrase &other); }; -AssignmentPhraseList operator &(const AssignmentPhrase &l, const AssignmentPhrase &r); -AssignmentPhraseList operator &(const AssignmentPhrase &l, AssignmentPhrase &&r); -AssignmentPhraseList operator &(AssignmentPhrase &&l, const AssignmentPhrase &r); -AssignmentPhraseList operator &(AssignmentPhrase &&l, AssignmentPhrase &&r); +//AssignmentPhraseList operator &(const AssignmentPhrase &l, const AssignmentPhrase &r); +//AssignmentPhraseList operator &(const AssignmentPhrase &l, AssignmentPhrase &&r); +//AssignmentPhraseList operator &(AssignmentPhrase &&l, const AssignmentPhrase &r); +//AssignmentPhraseList operator &(AssignmentPhrase &&l, AssignmentPhrase &&r); class PhraseList{ public: bool isValid; QList data; - PhraseList(); + explicit PhraseList(); PhraseList(const PhraseList &other); PhraseList(const AbstractFieldPhrase &other); PhraseList(const AbstractFieldPhrase *left, const AbstractFieldPhrase &right); @@ -181,7 +184,7 @@ public: ConditionalPhrase(ConditionalPhrase *l, PhraseData::Condition cond, ConditionalPhrase &r); virtual ~ConditionalPhrase(); - ConditionalPhrase operator =(const ConditionalPhrase &other); + ConditionalPhrase &operator =(const ConditionalPhrase &other); ConditionalPhrase operator ==(const QVariant &other); ConditionalPhrase operator ==(const AbstractFieldPhrase &other); ConditionalPhrase operator &&(const ConditionalPhrase &other); @@ -267,8 +270,8 @@ public: return ConditionalPhrase(this, PhraseData::Like, term); } - AssignmentPhrase operator =(const QVariant &other) { - return AssignmentPhrase(this, other); + AssignmentPhrase operator =(const QVariant &v) { + return AssignmentPhrase(this, v); } }; diff --git a/src/query.cpp b/src/query.cpp index eacf1ba..f8c79fd 100644 --- a/src/query.cpp +++ b/src/query.cpp @@ -23,7 +23,7 @@ NUT_BEGIN_NAMESPACE QueryPrivate::QueryPrivate(QueryBase *parent) : q_ptr(parent), - skip(-1), take(-1) + database(0), tableSet(0), skip(-1), take(-1) { } diff --git a/src/query.h b/src/query.h index 28fb454..765d599 100644 --- a/src/query.h +++ b/src/query.h @@ -50,7 +50,7 @@ template bool m_autoDelete; public: - Query(Database *database, TableSetBase *tableSet, bool autoDelete); + explicit Query(Database *database, TableSetBase *tableSet, bool autoDelete); ~Query(); //ddl @@ -520,7 +520,7 @@ Q_OUTOFLINE_TEMPLATE int Query::update(const AssignmentPhraseList &ph) ph, d->wherePhrase); QSqlQuery q = d->database->exec(d->sql); - +qDebug() << d->sql; if (m_autoDelete) deleteLater(); return q.numRowsAffected(); diff --git a/src/query_p.h b/src/query_p.h index 75c8f3b..1bb2b16 100644 --- a/src/query_p.h +++ b/src/query_p.h @@ -37,7 +37,7 @@ class QueryPrivate{ Q_DECLARE_PUBLIC(QueryBase) public: - QueryPrivate(QueryBase *parent); + explicit QueryPrivate(QueryBase *parent); ~QueryPrivate(); QString sql; diff --git a/src/sqlmodel.cpp b/src/sqlmodel.cpp index ff40fa3..9f1a870 100644 --- a/src/sqlmodel.cpp +++ b/src/sqlmodel.cpp @@ -85,4 +85,9 @@ QVariant SqlModel::data(const QModelIndex &index, int role) const return QVariant(); } +SqlModelPrivate::SqlModelPrivate() +{ + +} + NUT_END_NAMESPACE diff --git a/src/sqlmodel.h b/src/sqlmodel.h index e7c5e60..e8c2590 100644 --- a/src/sqlmodel.h +++ b/src/sqlmodel.h @@ -36,7 +36,7 @@ class SqlModel : public QAbstractTableModel Q_OBJECT public: - SqlModel(Database *database, TableSetBase *tableSet, QObject *parent = Q_NULLPTR); + explicit SqlModel(Database *database, TableSetBase *tableSet, QObject *parent = Q_NULLPTR); int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; diff --git a/src/sqlmodel_p.h b/src/sqlmodel_p.h index edd8dc8..7b68e88 100644 --- a/src/sqlmodel_p.h +++ b/src/sqlmodel_p.h @@ -13,6 +13,8 @@ class SqlModelPrivate { SqlModel *q_ptr; Q_DECLARE_PUBLIC(SqlModel) public: + explicit SqlModelPrivate(); + QString tableName; QList rows; diff --git a/src/table.cpp b/src/table.cpp index eeea6ec..e3deae5 100644 --- a/src/table.cpp +++ b/src/table.cpp @@ -39,7 +39,7 @@ NUT_BEGIN_NAMESPACE * This should be fixed to v1.2 */ -Table::Table(QObject *parent) : QObject(parent), myModel(0) +Table::Table(QObject *parent) : QObject(parent), myModel(0), _parentTableSet(0) { setStatus(NewCreated); } diff --git a/src/tablemodel.cpp b/src/tablemodel.cpp index 882edd7..b42269a 100644 --- a/src/tablemodel.cpp +++ b/src/tablemodel.cpp @@ -408,6 +408,7 @@ FieldModel::FieldModel(const QJsonObject &json) isAutoIncrement = json.value(__nut_AUTO_INCREMENT).toBool(); isPrimaryKey = json.value(__nut_PRIMARY_KEY).toBool(); defaultValue = json.value(__nut_DEFAULT_VALUE).toString(); + isUnique = json.value(__nut_UNIQUE).toBool(); } QJsonObject FieldModel::toJson() const @@ -429,6 +430,7 @@ RelationModel::RelationModel(const QJsonObject &obj) localProperty = obj.value("localProperty").toString(); masterClassName = obj.value("masterClassName").toString(); foreignColumn = obj.value("foreignColumn").toString(); + slaveTable = masterTable = 0; } QJsonObject RelationModel::toJson() const diff --git a/src/tablemodel.h b/src/tablemodel.h index 4fe2f66..c2439c5 100644 --- a/src/tablemodel.h +++ b/src/tablemodel.h @@ -31,13 +31,13 @@ NUT_BEGIN_NAMESPACE class TableModel; struct FieldModel{ - FieldModel() : name(QString::null), length(0), defaultValue(QString::null), + explicit FieldModel() : name(QString::null), length(0), defaultValue(QString::null), notNull(false), isPrimaryKey(false), isAutoIncrement(false), isUnique(false) { } - FieldModel(const QJsonObject &json); + explicit FieldModel(const QJsonObject &json); QString name; //TODO: QMetaType::Type?? @@ -73,7 +73,7 @@ struct RelationModel{ RelationModel() : localColumn(""), localProperty(""), slaveTable(0), foreignColumn(""), masterTable(0), masterClassName("") {} - RelationModel(const QJsonObject &obj); + explicit RelationModel(const QJsonObject &obj); //slave QString localColumn; @@ -92,9 +92,8 @@ bool operator !=(const RelationModel &l, const RelationModel &r); class TableModel { public: - - TableModel(int typeId, QString tableName = QString::null); - TableModel(QJsonObject json, QString tableName); + explicit TableModel(int typeId, QString tableName = QString::null); + explicit TableModel(QJsonObject json, QString tableName); QJsonObject toJson() const; diff --git a/src/tableset.h b/src/tableset.h index d62fe73..8034a09 100644 --- a/src/tableset.h +++ b/src/tableset.h @@ -39,8 +39,8 @@ template class NUT_EXPORT TableSet : public TableSetBase { public: - TableSet(Database *parent); - TableSet(Table *parent); + explicit TableSet(Database *parent); + explicit TableSet(Table *parent); void append(T *t); void append(QList t); diff --git a/src/tablesetbase_p.h b/src/tablesetbase_p.h index 801c11b..df95a71 100644 --- a/src/tablesetbase_p.h +++ b/src/tablesetbase_p.h @@ -35,8 +35,8 @@ class TableSetBase : public QObject { public: - TableSetBase(Database *parent); - TableSetBase(Table *parent); + explicit TableSetBase(Database *parent); + explicit TableSetBase(Table *parent); virtual int save(Database *db, bool cleanUp = false); void clearChilds(); diff --git a/src/types/dbgeography.h b/src/types/dbgeography.h index 9a7dfd0..3fd834a 100644 --- a/src/types/dbgeography.h +++ b/src/types/dbgeography.h @@ -35,8 +35,8 @@ class NUT_EXPORT DbGeography public: explicit DbGeography(); - DbGeography(const DbGeography &other); - DbGeography(const QVariant &value); + explicit DbGeography(const DbGeography &other); + explicit DbGeography(const QVariant &value); qreal longitude() const; qreal latitude() const; diff --git a/test/basic/maintest.cpp b/test/basic/maintest.cpp index f7e491a..a8a75be 100644 --- a/test/basic/maintest.cpp +++ b/test/basic/maintest.cpp @@ -69,6 +69,7 @@ void MainTest::createUser() void MainTest::createPost() { + TIC(); Post *newPost = new Post; newPost->setTitle("post title"); newPost->setSaveDate(QDateTime::currentDateTime()); @@ -93,6 +94,7 @@ void MainTest::createPost() postId = newPost->id(); QTEST_ASSERT(newPost->id() != 0); + TOC(); qDebug() << "New post inserted with id:" << newPost->id(); } @@ -119,12 +121,24 @@ void MainTest::createPost2() qDebug() << "New post2 inserted with id:" << newPost->id(); } +void MainTest::updatePostOnTheFly() +{ + auto c = db.postTable()->query() + ->where(Post::idField() == postId) + ->update(Post::titleField() = "New title"); + + QTEST_ASSERT(c == 1); +} + void MainTest::selectPublicts() { auto q = db.postTable()->query() ->where(Post::isPublicField()) ->toList(); + auto q2 = db.postTable()->query() + ->where(!Post::isPublicField()) + ->toList(); } void MainTest::selectPosts() diff --git a/test/basic/maintest.h b/test/basic/maintest.h index f03b91f..87eaab0 100644 --- a/test/basic/maintest.h +++ b/test/basic/maintest.h @@ -27,6 +27,7 @@ private slots: void createUser(); void createPost(); void createPost2(); + void updatePostOnTheFly(); void selectPublicts(); void join(); void selectPosts(); From afc22008e26532bf4a0c64c2f62e19f0c162417c Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Mon, 26 Feb 2018 13:48:44 +0330 Subject: [PATCH 10/12] travis yml error fix --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ab6919a..dc854ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -65,8 +65,6 @@ install: - qmake -v before_script: - #- cppcheck --error-exitcode=1 --quiet - . - '[[ "$TRAVIS_OS_NAME" != linux || "$CXX" != clang++ ]] || export QMAKESPEC=linux-clang' - '[[ "$TRAVIS_OS_NAME" != linux || "$CXX" != g++ ]] || export QMAKESPEC=linux-g++' - '[[ "$TRAVIS_OS_NAME" != osx || "$CXX" != clang++ ]] || export QMAKESPEC=macx-clang' From 84e219f6b304a354f1fe81af28fb0daf5d73e431 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Mon, 26 Feb 2018 13:58:01 +0330 Subject: [PATCH 11/12] removed fucking qInfo !!! --- src/query.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query.h b/src/query.h index 765d599..d2c7ece 100644 --- a/src/query.h +++ b/src/query.h @@ -419,7 +419,7 @@ Q_OUTOFLINE_TEMPLATE Query *Query::join(const QString &className) .relationByClassNames(className, d->className); if (!rel) { - qInfo() << "No relation between" << d->className + qDebug() << "No relation between" << d->className << "and" << className; return this; } From a8feb39ab7b80886ccf1bfffae67a949f5b4f3ae Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Mon, 26 Feb 2018 20:01:51 +0330 Subject: [PATCH 12/12] wherephrase removed [skip ci] --- src/phrase.cpp | 79 +++++-- src/phrase.h | 19 +- src/query.h | 2 +- src/wherephrase.cpp | 234 ------------------- src/wherephrase.h | 515 ------------------------------------------ test/basic/maintest.h | 2 +- 6 files changed, 82 insertions(+), 769 deletions(-) delete mode 100644 src/wherephrase.cpp delete mode 100644 src/wherephrase.h diff --git a/src/phrase.cpp b/src/phrase.cpp index e70f01b..4a00030 100644 --- a/src/phrase.cpp +++ b/src/phrase.cpp @@ -26,6 +26,12 @@ NUT_BEGIN_NAMESPACE #define LOG(s) qDebug() << __func__ << s; +PhraseData::PhraseData() : + className(""), fieldName(""), + type(Field), operatorCond(NotAssign), + left(0), right(0), operand(QVariant::Invalid), isNot(false) +{ } + PhraseData::PhraseData(const char *className, const char *fieldName) : className(className), fieldName(fieldName), type(Field), operatorCond(NotAssign), @@ -384,22 +390,67 @@ 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 AbstractFieldPhrase &other) +//{ +// return ConditionalPhrase(this, PhraseData::Equal, other); +//} + +//ConditionalPhrase ConditionalPhrase::operator &&(const ConditionalPhrase &other) +//{ +// return ConditionalPhrase(this, PhraseData::And, +// const_cast(other)); +//} + +//ConditionalPhrase ConditionalPhrase::operator ||(const ConditionalPhrase &other) +//{ +// return ConditionalPhrase(this, PhraseData::Or, +// const_cast(other)); +//} + +#define DECLARE_CONDITIONALPHRASE_OPERATORS(op, cond) \ +ConditionalPhrase operator op(const ConditionalPhrase &l, const ConditionalPhrase &r) \ +{ \ + ConditionalPhrase p; \ + p.data = new PhraseData; \ + p.data->operatorCond = cond; \ + p.data->left = new PhraseData(l.data); \ + p.data->right = new PhraseData(r.data); \ + return p; \ +} \ +ConditionalPhrase operator op(const ConditionalPhrase &l, ConditionalPhrase &&r) \ +{ \ + ConditionalPhrase p; \ + p.data = new PhraseData; \ + p.data->operatorCond = cond; \ + p.data->left = new PhraseData(l.data); \ + p.data->right = r.data; \ + r.data = 0; \ + return p; \ +} \ +ConditionalPhrase operator op(ConditionalPhrase &&l, const ConditionalPhrase &r) \ +{ \ + ConditionalPhrase p; \ + p.data = new PhraseData; \ + p.data->operatorCond = cond; \ + p.data->left = l.data; \ + l.data = 0; \ + p.data->right = new PhraseData(r.data); \ + return p; \ +} \ +ConditionalPhrase operator op(ConditionalPhrase &&l, ConditionalPhrase &&r) \ +{ \ + ConditionalPhrase p; \ + p.data = new PhraseData; \ + p.data->operatorCond = cond; \ + p.data->left = l.data; \ + p.data->right = r.data; \ + l.data = r.data = 0; \ + return p; \ } -ConditionalPhrase ConditionalPhrase::operator &&(const ConditionalPhrase &other) -{ - return ConditionalPhrase(this, PhraseData::And, - const_cast(other)); -} - -ConditionalPhrase ConditionalPhrase::operator ||(const ConditionalPhrase &other) -{ - return ConditionalPhrase(this, PhraseData::Or, - const_cast(other)); -} +DECLARE_CONDITIONALPHRASE_OPERATORS(==, PhraseData::Equal) +DECLARE_CONDITIONALPHRASE_OPERATORS(||, PhraseData::Or) +DECLARE_CONDITIONALPHRASE_OPERATORS(&&, PhraseData::And) ConditionalPhrase ConditionalPhrase::operator !() { diff --git a/src/phrase.h b/src/phrase.h index 2535384..df12f7b 100644 --- a/src/phrase.h +++ b/src/phrase.h @@ -91,14 +91,15 @@ public: const char *fieldName; Type type; - Condition operatorCond; const PhraseData *left; const PhraseData *right; QVariant operand; + Condition operatorCond; bool isNot; + PhraseData(); PhraseData(const char *className, const char *fieldName); PhraseData(PhraseData *l, Condition o); PhraseData(PhraseData *l, Condition o, const PhraseData *r); @@ -186,9 +187,9 @@ public: 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 ==(const AbstractFieldPhrase &other); +// ConditionalPhrase operator &&(const ConditionalPhrase &other); +// ConditionalPhrase operator ||(const ConditionalPhrase &other); ConditionalPhrase operator !(); SPECIALIZATION_NUMERIC_MEMBER(type, <, PhraseData::Less) @@ -197,6 +198,16 @@ public: SPECIALIZATION_NUMERIC_MEMBER(type, >=, PhraseData::GreaterEqual) }; +#define DECLARE_CONDITIONALPHRASE_OPERATORS(op) \ +ConditionalPhrase operator op(const ConditionalPhrase &l, const ConditionalPhrase &r); \ +ConditionalPhrase operator op(const ConditionalPhrase &l, ConditionalPhrase &&r); \ +ConditionalPhrase operator op(ConditionalPhrase &&l, const ConditionalPhrase &r); \ +ConditionalPhrase operator op(ConditionalPhrase &&l, ConditionalPhrase &&r); + +DECLARE_CONDITIONALPHRASE_OPERATORS(==) +DECLARE_CONDITIONALPHRASE_OPERATORS(&&) +DECLARE_CONDITIONALPHRASE_OPERATORS(||) + class AbstractFieldPhrase { public: diff --git a/src/query.h b/src/query.h index d2c7ece..29a5031 100644 --- a/src/query.h +++ b/src/query.h @@ -124,8 +124,8 @@ template Q_OUTOFLINE_TEMPLATE Query::~Query() { Q_D(Query); + qDebug() << "~Query";// << d->sql; delete d; - qDebug() << "~Query"; } template diff --git a/src/wherephrase.cpp b/src/wherephrase.cpp deleted file mode 100644 index 3a3213e..0000000 --- a/src/wherephrase.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/************************************************************************** -** -** 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 . -** -**************************************************************************/ - -#include -#include - -#include "phrase.h" - -NUT_BEGIN_NAMESPACE - -PhraseData::PhraseData(const char *className, const char *s) -{ - Q_UNUSED(className) - text = QString("[%1].%2").arg(className).arg(s); - type = Field; - operatorCond = NotAssign; -} - -PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o) : left(l) -{ - operatorCond = o; - type = WithoutOperand; -} - -PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o, - const PhraseData *r) - : left(l), right(r) -{ - operatorCond = o; - type = WithOther; -} - -PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o, QVariant r) - : left(l), operand(r) -{ - operatorCond = o; - type = WithVariant; -} - -PhraseData::~PhraseData() -{ - if (type == WithOther) { - delete left; - delete right; - } - if (type == WithVariant) { - if (left) - delete left; - } -} - -PhraseData *WherePhrase::data() const -{ - return _data; -} - -WherePhrase::WherePhrase(const char *className, const char *s) -{ - _data = new PhraseData(className, s); -} - -WherePhrase::WherePhrase(const WherePhrase &l) -{ - _data = l._data; - _dataPointer = QSharedPointer(l._dataPointer); -} - -WherePhrase::WherePhrase(WherePhrase *l) -{ - _data = l->_data; - - l->_data = 0; - l->_dataPointer.reset(0); -} - -WherePhrase::WherePhrase(WherePhrase *l, PhraseData::Condition o) -{ - _data = new PhraseData(l->_data, o); - l->_data = 0; - l->_dataPointer.reset(0); -} - -WherePhrase::WherePhrase(WherePhrase *l, PhraseData::Condition o, - WherePhrase *r) -{ - _data = new PhraseData(l->_data, o, r->_data); - l->_data = 0; - r->_data = 0; - - l->_dataPointer.reset(0); - r->_dataPointer.reset(0); -} - -WherePhrase::WherePhrase(WherePhrase *l, PhraseData::Condition o, QVariant r) -{ - _data = new PhraseData(l->_data, o, r); - l->_data = 0; - l->_dataPointer.reset(0); -} - -WherePhrase::~WherePhrase() -{ -} - -WherePhrase WherePhrase::operator==(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::Equal, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator!=(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::NotEqual, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator<(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::Less, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator>(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::Greater, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator<=(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::LessEqual, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator>=(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::GreaterEqual, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator!() -{ - if (_data->operatorCond < 20) - _data->operatorCond - = (PhraseData::Condition)((_data->operatorCond + 10) % 20); - else - qFatal("Operator ! can not aplied to non condition statements"); - - return this; // WherePhrase(this, PhraseData::Not); -} - -WherePhrase WherePhrase::operator=(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::Set, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator+(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::Add, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator-(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::Minus, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator*(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::Multiple, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator/(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::Divide, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator&&(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::And, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator||(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::Or, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator&(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::Append, (WherePhrase *)&other); -} - -WherePhrase WherePhrase::operator==(const QVariant &other) -{ - return WherePhrase(this, PhraseData::Equal, other); -} - -WherePhrase WherePhrase::operator!=(const QVariant &other) -{ - return WherePhrase(this, PhraseData::NotEqual, other); -} - -WherePhrase WherePhrase::operator<(const QVariant &other) -{ - return WherePhrase(this, PhraseData::Less, other); -} - -WherePhrase WherePhrase::operator>(const QVariant &other) -{ - return WherePhrase(this, PhraseData::Greater, other); -} - -WherePhrase WherePhrase::operator<=(const QVariant &other) -{ - return WherePhrase(this, PhraseData::LessEqual, other); -} - -WherePhrase WherePhrase::operator>=(const QVariant &other) -{ - return WherePhrase(this, PhraseData::GreaterEqual, other); -} - - -NUT_END_NAMESPACE diff --git a/src/wherephrase.h b/src/wherephrase.h deleted file mode 100644 index 8d33b75..0000000 --- a/src/wherephrase.h +++ /dev/null @@ -1,515 +0,0 @@ -/************************************************************************** -** -** 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 . -** -**************************************************************************/ - -#ifndef WHEREPHRASE_H -#define WHEREPHRASE_H - -#include - -#include -#include -#include -#include -#include -#include -#include "defines.h" -#include "types/dbgeography.h" - -#if __cplusplus >= 201103L -#include -#endif - -NUT_BEGIN_NAMESPACE - -class SqlGeneratorBase; -//class PhraseData -//{ -//public: -// enum Condition { -// NotAssign = 0, -// Equal, -// Less, -// LessEqual, -// Null, -// In, -// Like, - -// Not = 10, -// NotEqual, -// GreaterEqual, -// Greater, -// NotNull, -// NotIn, -// NotLike, - -// And = 20, -// Or, - -// Append, -// Set, - -// Add, -// Minus, -// Multiple, -// Divide, - -// // special types -// Distance -// }; - -// enum Type { Field, WithVariant, WithOther, WithoutOperand }; -// Type type; - -// Condition operatorCond; - -// 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(); -//}; - -class WherePhrase -{ -protected: - PhraseData *_data; - QSharedPointer _dataPointer; - -public: - WherePhrase(const char *className, const char *s); - - WherePhrase(const WherePhrase &l); - WherePhrase(WherePhrase *l); - WherePhrase(WherePhrase *l, PhraseData::Condition o); - WherePhrase(WherePhrase *l, PhraseData::Condition o, WherePhrase *r); - WherePhrase(WherePhrase *l, PhraseData::Condition o, QVariant r); - - ~WherePhrase(); - - WherePhrase operator==(const WherePhrase &other); - WherePhrase operator!=(const WherePhrase &other); - WherePhrase operator<(const WherePhrase &other); - WherePhrase operator>(const WherePhrase &other); - WherePhrase operator<=(const WherePhrase &other); - WherePhrase operator>=(const WherePhrase &other); - - WherePhrase operator==(const QVariant &other); - WherePhrase operator!=(const QVariant &other); - WherePhrase operator<(const QVariant &other); - WherePhrase operator>(const QVariant &other); - WherePhrase operator<=(const QVariant &other); - WherePhrase operator>=(const QVariant &other); - - WherePhrase operator!(); - WherePhrase operator=(const WherePhrase &other); - - WherePhrase operator+(const WherePhrase &other); - WherePhrase operator-(const WherePhrase &other); - WherePhrase operator*(const WherePhrase &other); - WherePhrase operator/(const WherePhrase &other); - - WherePhrase operator&&(const WherePhrase &other); - WherePhrase operator||(const WherePhrase &other); - - WherePhrase operator&(const WherePhrase &other); - - PhraseData *data() const; -}; - -template -class FieldPhrase : public WherePhrase -{ -public: - FieldPhrase(const char *className, const char *s); - - WherePhrase operator=(const FieldPhrase &other); - - WherePhrase operator=(const WherePhrase &other); - WherePhrase operator=(const QVariant &other); - WherePhrase operator+(const QVariant &other); - WherePhrase operator!(); - - WherePhrase operator==(const QVariant &other); - WherePhrase operator!=(const QVariant &other); - WherePhrase operator<(const QVariant &other); - WherePhrase operator>(const QVariant &other); - WherePhrase operator<=(const QVariant &other); - WherePhrase operator>=(const QVariant &other); - - WherePhrase isNull(); - WherePhrase in(QList list); - // WherePhrase in(QStringList list); - WherePhrase like(QString pattern); -}; - -template -Q_OUTOFLINE_TEMPLATE FieldPhrase::FieldPhrase(const char *className, - const char *s) - : WherePhrase(className, s) -{ - // qDebug() << "(" << this << ")" << "FieldPhrase ctor" << className << - // s; -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase:: -operator=(const QVariant &other) -{ - return WherePhrase(this, PhraseData::Set, other); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase -FieldPhrase::operator=(const FieldPhrase &other) -{ - return WherePhrase(this, PhraseData::Equal, &other); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase:: -operator=(const WherePhrase &other) -{ - return WherePhrase(this, PhraseData::Set, &other); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase:: -operator+(const QVariant &other) -{ - return WherePhrase(this, PhraseData::Add, other); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase::operator!() -{ - if (_data->operatorCond < 20) - _data->operatorCond - = (PhraseData::Condition)((_data->operatorCond + 10) % 20); - else - qFatal("Operator ! can not aplied to non condition statements"); - - return this; // WherePhrase(this, PhraseData::Not); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase:: -operator==(const QVariant &other) -{ - return WherePhrase(this, PhraseData::Equal, other); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase:: -operator!=(const QVariant &other) -{ - return WherePhrase(this, PhraseData::NotEqual, other); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase:: -operator<(const QVariant &other) -{ - return WherePhrase(this, PhraseData::Less, other); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase:: -operator>(const QVariant &other) -{ - return WherePhrase(this, PhraseData::Greater, other); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase:: -operator<=(const QVariant &other) -{ - return WherePhrase(this, PhraseData::LessEqual, other); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase:: -operator>=(const QVariant &other) -{ - return WherePhrase(this, PhraseData::GreaterEqual, other); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase::isNull() -{ - return WherePhrase(this, PhraseData::Null); -} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase::in(QList list) -{ - QVariantList vlist; - foreach (T t, list) - vlist.append(QVariant::fromValue(t)); - - return WherePhrase(this, PhraseData::In, vlist); -} - -// template -// Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase::in(QStringList list) -//{ -// return WherePhrase(this, PhraseData::In, list); -//} - -template -Q_OUTOFLINE_TEMPLATE WherePhrase FieldPhrase::like(QString pattern) -{ - return WherePhrase(this, PhraseData::Like, pattern); -} - -// Custom types -template <> -class FieldPhrase : public WherePhrase -{ -public: - FieldPhrase(const char *className, const char *s) - : WherePhrase(className, s) - { - } - - WherePhrase distance(const DbGeography &geo) - { - return WherePhrase(this, PhraseData::Distance, - QVariant::fromValue(geo)); - } -}; - -// Custom types -template <> -class FieldPhrase : public WherePhrase -{ -public: - FieldPhrase(const char *className, const char *s) - : WherePhrase(className, s) - { - } - - WherePhrase distance(const QPoint &geo) - { - return WherePhrase(this, PhraseData::Distance, - QVariant::fromValue(geo)); - } - WherePhrase operator=(const QPoint &other) - { - return WherePhrase(this, PhraseData::Set, other); - } -}; - -// Custom types -template <> -class FieldPhrase : public WherePhrase -{ -public: - FieldPhrase(const char *className, const char *s) - : WherePhrase(className, s) - { - } - - WherePhrase distance(const QPointF &geo) - { - return WherePhrase(this, PhraseData::Distance, - QVariant::fromValue(geo)); - } - WherePhrase operator=(const QPointF &other) - { - return WherePhrase(this, PhraseData::Set, other); - } -}; - -// template<> -// class FieldPhrase: public WherePhrase { -// public: -// FieldPhrase(const char *className, const char* s) : WherePhrase(className, -// s){ - -// } - -// WherePhrase like(QString pattern) -// { -// return WherePhrase(this, PhraseData::Like, pattern); -// } -//}; - -template <> -class FieldPhrase : public WherePhrase -{ -public: - FieldPhrase(const char *className, const char *s) - : WherePhrase(className, s) - { - } - - WherePhrase operator==(const bool &other) - { - return WherePhrase(this, PhraseData::Equal, other ? 1 : 0); - } - - WherePhrase operator=(const bool &other) - { - return WherePhrase(this, PhraseData::Set, other ? 1 : 0); - } - - WherePhrase operator!() - { - return WherePhrase(this, PhraseData::Equal, 0); - } -}; - -class NumericFieldPhrase : public WherePhrase -{ -public: - NumericFieldPhrase(const char *className, const char *s) - : WherePhrase(className, s) - { - } - - WherePhrase operator=(const QVariant &other) - { - return WherePhrase(this, PhraseData::Set, other); - } - - WherePhrase operator+(const QVariant &other) - { - return WherePhrase(this, PhraseData::Add, other); - } - - WherePhrase operator-(const QVariant &other) - { - return WherePhrase(this, PhraseData::Minus, other); - } - - WherePhrase operator++() - { - return WherePhrase(this, PhraseData::Add, 1); - } - - WherePhrase operator--() - { - return WherePhrase(this, PhraseData::Minus, 1); - } - - WherePhrase operator==(const QVariant &other) - { - return WherePhrase(this, PhraseData::Equal, other); - } - - WherePhrase operator!=(const QVariant &other) - { - return WherePhrase(this, PhraseData::NotEqual, other); - } - - WherePhrase operator<(const QVariant &other) - { - return WherePhrase(this, PhraseData::Less, other); - } - - WherePhrase operator>(const QVariant &other) - { - return WherePhrase(this, PhraseData::Greater, other); - } - - WherePhrase operator<=(const QVariant &other) - { - return WherePhrase(this, PhraseData::LessEqual, other); - } - - WherePhrase operator>=(const QVariant &other) - { - return WherePhrase(this, PhraseData::GreaterEqual, other); - } - - WherePhrase isNull() - { - return WherePhrase(this, PhraseData::Null); - } - - template - WherePhrase in(QList list) - { - QVariantList vlist; - foreach (T t, list) - vlist.append(QVariant::fromValue(t)); - return WherePhrase(this, PhraseData::In, vlist); - } - -#if __cplusplus >= 201103L - template - WherePhrase in(std::initializer_list list) - { - return in(QList(list)); - } -#endif - - WherePhrase in(int count, ...) - { - QVariantList vlist; - - va_list ap; - va_start(ap, count); - - for (int i = 0; i < count; ++i) - vlist.append(QVariant::fromValue(va_arg(ap, int))); - - va_end(ap); - - return WherePhrase(this, PhraseData::In, vlist); - } -}; - -#define SPECIALIZATION_NUMERIC(type) \ - template <> \ - class FieldPhrase : public NumericFieldPhrase \ - { \ - public: \ - FieldPhrase(const char *className, const char *s) \ - : NumericFieldPhrase(className, s) \ - { \ - } \ - WherePhrase operator=(const WherePhrase &other) \ - { \ - return WherePhrase(this, PhraseData::Set, (WherePhrase *)&other); \ - } \ - }; - -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) - -NUT_END_NAMESPACE - -#endif // PHRASE_H diff --git a/test/basic/maintest.h b/test/basic/maintest.h index 87eaab0..c79ce1a 100644 --- a/test/basic/maintest.h +++ b/test/basic/maintest.h @@ -27,7 +27,6 @@ private slots: void createUser(); void createPost(); void createPost2(); - void updatePostOnTheFly(); void selectPublicts(); void join(); void selectPosts(); @@ -35,6 +34,7 @@ private slots: void selectFirst(); void selectPostsWithoutTitle(); void selectPostIds(); + void updatePostOnTheFly(); void testDate(); void selectWithInvalidRelation(); void modifyPost();