From 9c0df27eea267c348a148520ec9dea2cbd00e59d Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Wed, 21 Feb 2018 19:11:45 +0330 Subject: [PATCH 01/20] skip and take new sign --- src/generators/sqlgeneratorbase.cpp | 6 ++++++ src/generators/sqlgeneratorbase_p.h | 2 +- src/generators/sqlitegenerator.cpp | 26 +++++++------------------- src/generators/sqlitegenerator.h | 6 +----- src/query.h | 2 +- 5 files changed, 16 insertions(+), 26 deletions(-) diff --git a/src/generators/sqlgeneratorbase.cpp b/src/generators/sqlgeneratorbase.cpp index 7cdbca8..07dd8b1 100644 --- a/src/generators/sqlgeneratorbase.cpp +++ b/src/generators/sqlgeneratorbase.cpp @@ -466,6 +466,7 @@ QString SqlGeneratorBase::selectCommand(const QString &tableName, sql = sql.replace(_database->model().at(i)->className() + ".", _database->model().at(i)->name() + "."); + appendSkipTake(sql, skip, take); replaceTableNames(sql); return sql + " "; @@ -495,6 +496,7 @@ QString SqlGeneratorBase::selectCommand(const QString &tableName, sql = sql.replace(_database->model().at(i)->className() + ".", _database->model().at(i)->name() + "."); + appendSkipTake(sql, skip, take); replaceTableNames(sql); return sql + " "; @@ -826,6 +828,10 @@ SqlGeneratorBase::operatorString(const PhraseData::Condition &cond) const } } +void SqlGeneratorBase::appendSkipTake(QString &sql, int skip, int take) +{ + +} QString SqlGeneratorBase::createConditionalPhrase(const PhraseData *d) const { diff --git a/src/generators/sqlgeneratorbase_p.h b/src/generators/sqlgeneratorbase_p.h index 897d251..ab9223c 100644 --- a/src/generators/sqlgeneratorbase_p.h +++ b/src/generators/sqlgeneratorbase_p.h @@ -119,7 +119,7 @@ public: virtual QVariant readValue(const QVariant::Type &type, const QVariant &dbValue); 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: QString createConditionalPhrase(const PhraseData *d) const; QString createFieldPhrase(const PhraseList &ph); diff --git a/src/generators/sqlitegenerator.cpp b/src/generators/sqlitegenerator.cpp index 9b71f2e..83ab286 100644 --- a/src/generators/sqlitegenerator.cpp +++ b/src/generators/sqlitegenerator.cpp @@ -71,24 +71,12 @@ QString SqliteGenerator::fieldType(FieldModel *field) return dbType; } -//QString SqliteGenerator::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(" LIMIT %1 OFFSET %2") -// .arg(take) -// .arg(skip)); -// return command; -//} +void SqliteGenerator::appendSkipTake(QString &sql, int skip, int take) +{ + if (take != -1 && skip != -1) + sql.append(QString(" LIMIT %1 OFFSET %2") + .arg(take) + .arg(skip)); +} NUT_END_NAMESPACE diff --git a/src/generators/sqlitegenerator.h b/src/generators/sqlitegenerator.h index d1140a9..1a28c32 100644 --- a/src/generators/sqlitegenerator.h +++ b/src/generators/sqlitegenerator.h @@ -33,11 +33,7 @@ public: QString fieldType(FieldModel *field); -// QString selectCommand(AgregateType t, QString agregateArg, -// QString tableName, -// QList &wheres, -// QList &orders, -// QList joins, int skip, int take); + void appendSkipTake(QString &sql, int skip, int take); }; NUT_END_NAMESPACE diff --git a/src/query.h b/src/query.h index 786f0e9..33e9174 100644 --- a/src/query.h +++ b/src/query.h @@ -307,7 +307,7 @@ Q_OUTOFLINE_TEMPLATE QList Query::select(const FieldPhrase f) d->wherePhrase, d->relations, d->skip, d->take); - +qDebug() << d->sql; QSqlQuery q = d->database->exec(d->sql); while (q.next()) { From fa21efde1b0195cf5fd010725a8857af17d45d3d Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Sat, 24 Feb 2018 19:13:15 +0330 Subject: [PATCH 02/20] 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 03/20] 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 04/20] 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 05/20] 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 06/20] 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 07/20] 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 08/20] 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 09/20] 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 10/20] 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 11/20] 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 12/20] 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 13/20] 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(); From bca26e70664f2227cd302b7196783021c2217e7c Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Tue, 27 Feb 2018 10:44:46 +0330 Subject: [PATCH 14/20] removed copy constructor from TableModel --- src/databasemodel.cpp | 5 ----- src/databasemodel.h | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/databasemodel.cpp b/src/databasemodel.cpp index 792cda1..e5adc6d 100644 --- a/src/databasemodel.cpp +++ b/src/databasemodel.cpp @@ -57,11 +57,6 @@ 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 e8342fd..066bed5 100644 --- a/src/databasemodel.h +++ b/src/databasemodel.h @@ -43,7 +43,7 @@ public: DatabaseModel(const QString &name = QString::null); DatabaseModel(const DatabaseModel &other); DatabaseModel(const QJsonObject &json); - DatabaseModel(DatabaseModel &model); +// DatabaseModel(DatabaseModel &model); TableModel *tableByName(QString tableName) const; TableModel *tableByClassName(QString className) const; From 3bdf6f294d8737946cf55fa00386a89bfeea4c96 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Tue, 27 Feb 2018 12:00:25 +0330 Subject: [PATCH 15/20] wip: memory leaks --- src/databasemodel.h | 1 - src/phrase.cpp | 21 ++++++++++++++------- src/phrase.h | 8 +++++--- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/databasemodel.h b/src/databasemodel.h index 066bed5..c4e25b8 100644 --- a/src/databasemodel.h +++ b/src/databasemodel.h @@ -43,7 +43,6 @@ 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/phrase.cpp b/src/phrase.cpp index 4a00030..c5e301f 100644 --- a/src/phrase.cpp +++ b/src/phrase.cpp @@ -84,6 +84,9 @@ PhraseData::~PhraseData() LOG(""); } +AbstractFieldPhrase::AbstractFieldPhrase(PhraseData *d) : data(d) +{ } + AbstractFieldPhrase::AbstractFieldPhrase(const char *className, const char *fieldName) :data(new PhraseData(className, fieldName)) { @@ -92,10 +95,16 @@ AbstractFieldPhrase::AbstractFieldPhrase(const char *className, const char *fiel AbstractFieldPhrase::AbstractFieldPhrase(const AbstractFieldPhrase &other) { - qDebug() <<"4444444444444444"; + qDebug() <<"Copy ctor"<toString(); data = new PhraseData(other.data); } +AbstractFieldPhrase::AbstractFieldPhrase(AbstractFieldPhrase &&other) +{ + data = other.data; + other.data = 0; +} + AbstractFieldPhrase::~AbstractFieldPhrase() { if (data) { @@ -148,13 +157,11 @@ AbstractFieldPhraseOperatorField(<=, PhraseData::LessEqual) AbstractFieldPhraseOperatorField(> , PhraseData::Greater) AbstractFieldPhraseOperatorField(>=, PhraseData::GreaterEqual) -AbstractFieldPhrase AbstractFieldPhrase::operator !() +AbstractFieldPhrase &AbstractFieldPhrase::operator !() { - //TODO: classname and s - AbstractFieldPhrase f(data->className, data->fieldName); - f.data = new PhraseData(data); - f.data->isNot = !data->isNot; - return f; + AbstractFieldPhrase *f = new AbstractFieldPhrase(new PhraseData(data)); + f->data->isNot = !data->isNot; + return *f; } AssignmentPhrase AbstractFieldPhrase::operator =(const QVariant &other) diff --git a/src/phrase.h b/src/phrase.h index df12f7b..4be512e 100644 --- a/src/phrase.h +++ b/src/phrase.h @@ -168,8 +168,8 @@ class ConditionalPhrase { public: PhraseData *data; - QSharedPointer leftDataPointer; - QSharedPointer rightDataPointer; +// QSharedPointer leftDataPointer; +// QSharedPointer rightDataPointer; ConditionalPhrase(); ConditionalPhrase(const ConditionalPhrase &other); #ifdef Q_COMPILER_RVALUE_REFS @@ -212,8 +212,10 @@ class AbstractFieldPhrase { public: PhraseData *data; + explicit AbstractFieldPhrase(PhraseData *d); AbstractFieldPhrase(const char *className, const char *fieldName); AbstractFieldPhrase(const AbstractFieldPhrase &other); + AbstractFieldPhrase(AbstractFieldPhrase &&other); virtual ~AbstractFieldPhrase(); @@ -251,7 +253,7 @@ public: ConditionalPhrase operator <=(const AbstractFieldPhrase &other); ConditionalPhrase operator >=(const AbstractFieldPhrase &other); - AbstractFieldPhrase operator !(); + AbstractFieldPhrase &operator !(); AssignmentPhrase operator =(const QVariant &other); AssignmentPhrase operator <<(const QVariant &other); }; From f1e29ba0a4957e29f53c0c25f31c1c277e42b3cf Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Sat, 3 Mar 2018 18:06:04 +0330 Subject: [PATCH 16/20] before new parent check --- src/databasemodel.cpp | 10 +++++ src/databasemodel.h | 2 + src/defines.h | 98 ++++++++++++++++++++++--------------------- src/defines_p.h | 8 ++-- src/phrase.cpp | 12 ++++-- src/phrase.h | 2 +- src/tablemodel.h | 2 +- 7 files changed, 77 insertions(+), 57 deletions(-) diff --git a/src/databasemodel.cpp b/src/databasemodel.cpp index e5adc6d..b732f3d 100644 --- a/src/databasemodel.cpp +++ b/src/databasemodel.cpp @@ -57,6 +57,10 @@ DatabaseModel::DatabaseModel(const QJsonObject &json) : } } +DatabaseModel::~DatabaseModel() +{ +} + TableModel *DatabaseModel::tableByName(QString tableName) const { for(int i = 0; i < size(); i++){ @@ -223,4 +227,10 @@ DatabaseModel *DatabaseModel::modelByName(const QString &name) return Q_NULLPTR; } +void DatabaseModel::deleteAllModels() +{ + qDeleteAll(_models.values()); + _models.clear(); +} + NUT_END_NAMESPACE diff --git a/src/databasemodel.h b/src/databasemodel.h index c4e25b8..746b86d 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(); TableModel *tableByName(QString tableName) const; TableModel *tableByClassName(QString className) const; @@ -69,6 +70,7 @@ public: void fixRelations(); static DatabaseModel *modelByName(const QString &name); + static void deleteAllModels(); }; NUT_END_NAMESPACE diff --git a/src/defines.h b/src/defines.h index c36ca4e..a779ccd 100644 --- a/src/defines.h +++ b/src/defines.h @@ -32,73 +32,77 @@ # define NUT_EXPORT Q_DECL_EXPORT #endif -#define NUT_INFO(type, name, value) \ - Q_CLASSINFO(__nut_NAME_PERFIX type #name #value, type "\n" #name "\n" #value) +#define NUT_INFO(type, name, value) \ + Q_CLASSINFO(__nut_NAME_PERFIX type #name #value, \ + type "\n" #name "\n" #value) // Database #define NUT_DB_VERSION(version) \ NUT_INFO(__nut_DB_VERSION, version, 0) -#define NUT_DECLARE_TABLE(type, name) \ +#define NUT_DECLARE_TABLE(type, name) \ NUT_INFO(__nut_TABLE, type, name) \ - Q_PROPERTY(type* name READ name) \ - Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet) name##Table READ name##Table) \ - type* m_##name; \ - NUT_WRAP_NAMESPACE(TableSet) *m_##name##Table; \ -public: \ - static const type _##name; \ - type* name() const{ return m_##name; } \ - NUT_WRAP_NAMESPACE(TableSet) *name##Table() const { return m_##name##Table; } + Q_PROPERTY(type* name READ name) \ + Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet) name##Table READ name##Table)\ + type* m_##name; \ + NUT_WRAP_NAMESPACE(TableSet) *m_##name##Table; \ +public: \ + static const type _##name; \ + type* name() const{ return m_##name; } \ + NUT_WRAP_NAMESPACE(TableSet) *name##Table() const \ + { return m_##name##Table; } //Table -#define NUT_DECLARE_FIELD(type, name, read, write) \ - Q_PROPERTY(type name READ read WRITE write) \ - NUT_INFO(__nut_FIELD, name, 0) \ - type m_##name; \ -public: \ - static NUT_WRAP_NAMESPACE(FieldPhrase) name ## Field(){ \ - static NUT_WRAP_NAMESPACE(FieldPhrase) f = NUT_WRAP_NAMESPACE(FieldPhrase)(staticMetaObject.className(), #name); \ - return f; \ - } \ - type read() const{ \ - return m_##name; \ - } \ - void write(type name){ \ - m_##name = name; \ - propertyChanged(#name); \ +#define NUT_DECLARE_FIELD(type, name, read, write) \ + Q_PROPERTY(type name READ read WRITE write) \ + NUT_INFO(__nut_FIELD, name, 0) \ + type m_##name; \ +public: \ + static NUT_WRAP_NAMESPACE(FieldPhrase) name ## Field(){ \ + static NUT_WRAP_NAMESPACE(FieldPhrase) f = \ + NUT_WRAP_NAMESPACE(FieldPhrase) \ + (staticMetaObject.className(), #name); \ + return f; \ + } \ + type read() const{ \ + return m_##name; \ + } \ + void write(type name){ \ + m_##name = name; \ + propertyChanged(#name); \ } -#define NUT_FOREGION_KEY(type, keytype, name, read, write) \ - Q_PROPERTY(type* name READ read WRITE write) \ - NUT_DECLARE_FIELD(keytype, name##Id, read##Id, write##Id) \ +#define NUT_FOREGION_KEY(type, keytype, name, read, write) \ + Q_PROPERTY(type* name READ read WRITE write) \ + NUT_DECLARE_FIELD(keytype, name##Id, read##Id, write##Id) \ NUT_INFO(__nut_FOREGION_KEY, name, type) \ - type *m_##name; \ -public: \ - type *read() const { return m_##name ; } \ - void write(type *name){ \ - m_##name = name; \ + type *m_##name; \ +public: \ + type *read() const { return m_##name ; } \ + void write(type *name){ \ + m_##name = name; \ } -#define NUT_DECLARE_CHILD_TABLE(type, n) \ - private: \ - NUT_WRAP_NAMESPACE(TableSet) *m_##n; \ - public: \ - static type *n##Table(); \ +#define NUT_DECLARE_CHILD_TABLE(type, n) \ + private: \ + NUT_WRAP_NAMESPACE(TableSet) *m_##n; \ + public: \ + static type *n##Table(); \ NUT_WRAP_NAMESPACE(TableSet) *n(); -#define NUT_IMPLEMENT_CHILD_TABLE(class, type, n) \ - type *class::n##Table(){ \ - static type *f = new type(); \ - return f; \ - } \ - NUT_WRAP_NAMESPACE(TableSet) *class::n(){ \ - return m_##n; \ +#define NUT_IMPLEMENT_CHILD_TABLE(class, type, n) \ + type *class::n##Table(){ \ + static type *f = new type(); \ + return f; \ + } \ + NUT_WRAP_NAMESPACE(TableSet) *class::n(){ \ + return m_##n; \ } #define NUT_PRIMARY_KEY(x) NUT_INFO(__nut_PRIMARY_KEY, x, 0) #define NUT_AUTO_INCREMENT(x) NUT_INFO(__nut_AUTO_INCREMENT, x, 0) -#define NUT_PRIMARY_AUTO_INCREMENT(x) NUT_PRIMARY_KEY(x) \ +#define NUT_PRIMARY_AUTO_INCREMENT(x) NUT_PRIMARY_KEY(x) \ NUT_AUTO_INCREMENT(x) #define NUT_DISPLAY_NAME(field, name) NUT_INFO(__nut_DISPLAY, field, name) #define NUT_UNIQUE(x) NUT_INFO(__nut_UNIQUE, x, 0) diff --git a/src/defines_p.h b/src/defines_p.h index e8b5f82..045d001 100644 --- a/src/defines_p.h +++ b/src/defines_p.h @@ -21,10 +21,10 @@ #ifndef DEFINES_P_H #define DEFINES_P_H -#define __NAME "name" -#define __TYPE "type" -#define __FIELDS "fields" -#define __FOREIGN_KEYS "foreign_keys" +#define __NAME "name" +#define __TYPE "type" +#define __FIELDS "fields" +#define __FOREIGN_KEYS "foreign_keys" #define __nut_FIELD "field" #define __nut_DB_VERSION "database_version" diff --git a/src/phrase.cpp b/src/phrase.cpp index c5e301f..b91b939 100644 --- a/src/phrase.cpp +++ b/src/phrase.cpp @@ -157,11 +157,11 @@ AbstractFieldPhraseOperatorField(<=, PhraseData::LessEqual) AbstractFieldPhraseOperatorField(> , PhraseData::Greater) AbstractFieldPhraseOperatorField(>=, PhraseData::GreaterEqual) -AbstractFieldPhrase &AbstractFieldPhrase::operator !() +AbstractFieldPhrase AbstractFieldPhrase::operator !() { - AbstractFieldPhrase *f = new AbstractFieldPhrase(new PhraseData(data)); - f->data->isNot = !data->isNot; - return *f; + AbstractFieldPhrase f(new PhraseData(data)); + f.data->isNot = !data->isNot; + return f; } AssignmentPhrase AbstractFieldPhrase::operator =(const QVariant &other) @@ -182,6 +182,7 @@ PhraseList::PhraseList() : isValid(false) PhraseList::PhraseList(const PhraseList &other) : isValid(true) { data = qMove(other.data); + const_cast(other).data.clear(); } PhraseList::PhraseList(const AbstractFieldPhrase &other) : isValid(true) @@ -199,6 +200,8 @@ PhraseList::PhraseList(const AbstractFieldPhrase *left, const AbstractFieldPhras PhraseList::PhraseList(PhraseList *left, PhraseList *right) : isValid(true) { data = qMove(left->data + right->data); + left->data.clear(); + right->data.clear(); } PhraseList::PhraseList(PhraseList *left, const AbstractFieldPhrase *right) @@ -210,6 +213,7 @@ PhraseList::PhraseList(PhraseList *left, const AbstractFieldPhrase *right) PhraseList::~PhraseList() { + qDeleteAll(data); // data.clear(); } diff --git a/src/phrase.h b/src/phrase.h index 4be512e..6ebcf48 100644 --- a/src/phrase.h +++ b/src/phrase.h @@ -253,7 +253,7 @@ public: ConditionalPhrase operator <=(const AbstractFieldPhrase &other); ConditionalPhrase operator >=(const AbstractFieldPhrase &other); - AbstractFieldPhrase &operator !(); + AbstractFieldPhrase operator !(); AssignmentPhrase operator =(const QVariant &other); AssignmentPhrase operator <<(const QVariant &other); }; diff --git a/src/tablemodel.h b/src/tablemodel.h index c2439c5..d504c78 100644 --- a/src/tablemodel.h +++ b/src/tablemodel.h @@ -89,7 +89,7 @@ struct RelationModel{ }; bool operator ==(const RelationModel &l, const RelationModel &r); bool operator !=(const RelationModel &l, const RelationModel &r); -class TableModel +class TableModel { public: explicit TableModel(int typeId, QString tableName = QString::null); From b9b80ebcf38aa104c226d7bd25b3c60347b7215c Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Sun, 11 Mar 2018 12:08:07 +0330 Subject: [PATCH 17/20] zc --- src/phrase.cpp | 265 +++++++++++++++++++++++++++++++++++-------------- src/phrase.h | 36 +++++-- src/query.h | 6 +- 3 files changed, 223 insertions(+), 84 deletions(-) diff --git a/src/phrase.cpp b/src/phrase.cpp index b91b939..a3885c1 100644 --- a/src/phrase.cpp +++ b/src/phrase.cpp @@ -29,42 +29,60 @@ NUT_BEGIN_NAMESPACE PhraseData::PhraseData() : className(""), fieldName(""), type(Field), operatorCond(NotAssign), - left(0), right(0), operand(QVariant::Invalid), isNot(false) + left(0), right(0), operand(QVariant::Invalid), isNot(false), parents(3) { } PhraseData::PhraseData(const char *className, const char *fieldName) : className(className), fieldName(fieldName), type(Field), operatorCond(NotAssign), - left(0), right(0), operand(QVariant::Invalid), isNot(false) + left(0), right(0), operand(QVariant::Invalid), isNot(false), parents(1) { } PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o) : className(0), fieldName(0), - type(WithoutOperand), operatorCond(o), left(new PhraseData(l)), right(0), isNot(false) -{ } + type(WithoutOperand), operatorCond(o), left(l), right(0), + isNot(false), parents(1) +{ + l->parents++; +} PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o, - const PhraseData *r) + PhraseData *r) : className(0), fieldName(0), - type(WithOther), operatorCond(o), left(new PhraseData(l)), right(new PhraseData(r)), isNot(false) -{ } + type(WithOther), operatorCond(o), + left(l), right(r), + isNot(false), parents(1) +{ + l->parents++; + r->parents++; +} PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o, QVariant r) : className(0), fieldName(0), - type(WithVariant), operatorCond(o), left(new PhraseData(l)), right(0), operand(r), isNot(false) + type(WithVariant), operatorCond(o), left(l), + right(0), operand(r), isNot(false), parents(1) { } -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::operator =(PhraseData *other) +{ + LOG(""); + other->parents++; + return other; +} -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), +// parents(other.parents + 1) +//{ } + +//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), +// parents(other->parents + 1) +//{ } QString PhraseData::toString() const { @@ -81,13 +99,34 @@ PhraseData::~PhraseData() // if (left) // delete left; // } + +// if (right && !--right->parents) +// delete right; + +// if (left && !--left->parents) +// delete left; + LOG(""); } +void PhraseData::cleanUp() +{ + cleanUp(this); +} + +void PhraseData::cleanUp(PhraseData *d) +{ + if (d->left) + cleanUp(d->left); + if (d->right) + cleanUp(d->right); +} + AbstractFieldPhrase::AbstractFieldPhrase(PhraseData *d) : data(d) { } -AbstractFieldPhrase::AbstractFieldPhrase(const char *className, const char *fieldName) +AbstractFieldPhrase::AbstractFieldPhrase(const char *className, + const char *fieldName) :data(new PhraseData(className, fieldName)) { qDebug() <<"AbstractFieldPhrase created"<toString(); - data = new PhraseData(other.data); + qDebug() <<"Copy ctor"<toString()<parents; + data = other.data; + data->parents++; } AbstractFieldPhrase::AbstractFieldPhrase(AbstractFieldPhrase &&other) @@ -109,13 +149,15 @@ AbstractFieldPhrase::~AbstractFieldPhrase() { if (data) { LOG(data->toString()); + qDebug() << data->parents; } else { LOG(""); } if (data) { - delete data; - data = 0; + --data->parents; + if (data->parents <= 0) + delete data; } } @@ -130,9 +172,11 @@ ConditionalPhrase AbstractFieldPhrase::isNull() } -ConditionalPhrase AbstractFieldPhrase::operator ==(const ConditionalPhrase &other) +ConditionalPhrase AbstractFieldPhrase::operator ==(const ConditionalPhrase + &other) { - return ConditionalPhrase(this, PhraseData::Equal, const_cast(other)); + return ConditionalPhrase(this, PhraseData::Equal, + const_cast(other)); } #define AbstractFieldPhraseOperatorVariant(class, op, cond) \ @@ -159,7 +203,7 @@ AbstractFieldPhraseOperatorField(>=, PhraseData::GreaterEqual) AbstractFieldPhrase AbstractFieldPhrase::operator !() { - AbstractFieldPhrase f(new PhraseData(data)); + AbstractFieldPhrase f(data->className, data->fieldName); f.data->isNot = !data->isNot; return f; } @@ -187,54 +231,67 @@ PhraseList::PhraseList(const PhraseList &other) : isValid(true) PhraseList::PhraseList(const AbstractFieldPhrase &other) : isValid(true) { - data.append(new PhraseData(other.data)); + data.append(other.data); + incAllDataParents(); } -PhraseList::PhraseList(const AbstractFieldPhrase *left, const AbstractFieldPhrase &right) +PhraseList::PhraseList(const AbstractFieldPhrase *left, + const AbstractFieldPhrase &right) : isValid(true) { - data.append(new PhraseData(left->data)); - data.append(new PhraseData(right.data)); + data.append(left->data); + data.append(right.data); + incAllDataParents(); } PhraseList::PhraseList(PhraseList *left, PhraseList *right) : isValid(true) { - data = qMove(left->data + right->data); - left->data.clear(); - right->data.clear(); +// data = qMove(left->data + right->data); + data.append(left->data); + data.append(right->data); +// left->data.clear(); +// right->data.clear(); } PhraseList::PhraseList(PhraseList *left, const AbstractFieldPhrase *right) : isValid(true) { data = left->data; - data.append(new PhraseData(right->data)); + data.append(right->data); + incAllDataParents(); } PhraseList::~PhraseList() -{ - qDeleteAll(data); -// data.clear(); -} +{ } PhraseList PhraseList::operator |(const AbstractFieldPhrase &other) { return PhraseList(this, &other); } +void PhraseList::incAllDataParents() +{ +// foreach (PhraseData *d, data) +// d->parents++; +} + PhraseList PhraseList::operator |(PhraseList &other) { return PhraseList(this, &other); } AssignmentPhrase::AssignmentPhrase(PhraseData *d) : data(d) -{ } +{ + d->parents++; +} AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, const QVariant r) { + data = new PhraseData(l->data, PhraseData::Equal, r); // l->data = 0; } -AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, const AssignmentPhrase *r) +AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, + const AssignmentPhrase *r) { data = new PhraseData(l->data, PhraseData::Equal, r->data); // l->data = 0; @@ -254,7 +311,8 @@ AssignmentPhrase::AssignmentPhrase(AssignmentPhrase *ph, const QVariant &v) AssignmentPhrase::~AssignmentPhrase() { if (data) - delete data; + if (!--data->parents) + delete data; } //AssignmentPhrase::AssignmentPhrase(AssignmentPhrase *l, const AssignmentPhrase *r) @@ -276,35 +334,52 @@ AssignmentPhraseList::AssignmentPhraseList() AssignmentPhraseList::AssignmentPhraseList(const AssignmentPhrase &l) { data.append(l.data); + incAllDataParents(); } -AssignmentPhraseList::AssignmentPhraseList(AssignmentPhraseList *l, const AssignmentPhrase *r) +AssignmentPhraseList::AssignmentPhraseList(AssignmentPhraseList *l, + const AssignmentPhrase *r) { data.append(l->data); data.append(r->data); + incAllDataParents(); } -AssignmentPhraseList::AssignmentPhraseList(AssignmentPhrase *l, const AssignmentPhrase *r) +AssignmentPhraseList::AssignmentPhraseList(AssignmentPhrase *l, + const AssignmentPhrase *r) { data.append(l->data); data.append(r->data); + incAllDataParents(); } -AssignmentPhraseList::AssignmentPhraseList(const AssignmentPhrase &r, const AssignmentPhrase &l) +AssignmentPhraseList::AssignmentPhraseList(const AssignmentPhrase &r, + const AssignmentPhrase &l) { data.append(l.data); data.append(r.data); + incAllDataParents(); } -AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase &ph) +AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase + &ph) { return AssignmentPhraseList(this, &ph); } AssignmentPhraseList::~AssignmentPhraseList() { + foreach (PhraseData *d, data) + if (!--d->parents) + delete d; // qDeleteAll(data); -// data.clear(); + // data.clear(); +} + +void AssignmentPhraseList::incAllDataParents() +{ + foreach (PhraseData *d, data) + d->parents++; } ConditionalPhrase::ConditionalPhrase() : data(0) @@ -313,7 +388,8 @@ ConditionalPhrase::ConditionalPhrase() : data(0) ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &other) { qDebug() << "************* ctor called:"; - this->data = new PhraseData(other.data); + data = other.data; + data->parents++; // const_cast(other).data = 0; } @@ -327,7 +403,8 @@ ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &&other) ConditionalPhrase::ConditionalPhrase(const PhraseData *data) { - this->data = new PhraseData(data); + this->data = const_cast(data); + this->data->parents++; } ConditionalPhrase::ConditionalPhrase(AbstractFieldPhrase *l, @@ -386,13 +463,17 @@ ConditionalPhrase::ConditionalPhrase(ConditionalPhrase *l, ConditionalPhrase::~ConditionalPhrase() { LOG(""); - if (data) - delete data; + if (data) { + data->cleanUp(); + if (!--data->parents) + delete data; + } } ConditionalPhrase &ConditionalPhrase::operator =(const ConditionalPhrase &other) { - this->data = new PhraseData(other.data); + data = other.data; + data->parents++; return *this; } @@ -419,33 +500,40 @@ ConditionalPhrase ConditionalPhrase::operator ==(const QVariant &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 operator op(const 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); \ + p.data->right = r.data; \ + l.data->parents++; \ + r.data->parents++; \ + return p; \ +} \ +ConditionalPhrase operator op(const 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->parents++; \ + r.data->parents++; \ + 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; \ + p.data->right = r.data; \ + l.data->parents++; \ + r.data->parents++; \ return p; \ } \ ConditionalPhrase operator op(ConditionalPhrase &&l, ConditionalPhrase &&r) \ @@ -455,7 +543,8 @@ ConditionalPhrase operator op(ConditionalPhrase &&l, ConditionalPhrase &&r) \ p.data->operatorCond = cond; \ p.data->left = l.data; \ p.data->right = r.data; \ - l.data = r.data = 0; \ + l.data->parents++; \ + r.data->parents++; \ return p; \ } @@ -470,6 +559,34 @@ ConditionalPhrase ConditionalPhrase::operator !() return f; } +PhraseDataList::PhraseDataList() : QList() +{ + +} + +void PhraseDataList::append(PhraseData *d) +{ + d->parents++; + QList::append(d); +} + +void PhraseDataList::append(QList &dl) +{ + foreach (PhraseData *d, dl) + d->parents++; + QList::append(dl); +} + +PhraseDataList::~PhraseDataList() +{ + QList::iterator i; + for (i = begin(); i != end(); ++i) { + (*i)->cleanUp(); + if (!--(*i)->parents) + delete *i; + } +} + //AssignmentPhraseList operator &(const AssignmentPhrase &l, const AssignmentPhrase &r) //{ // return AssignmentPhraseList(l, r); diff --git a/src/phrase.h b/src/phrase.h index 6ebcf48..7cf6fff 100644 --- a/src/phrase.h +++ b/src/phrase.h @@ -92,24 +92,40 @@ public: Type type; - const PhraseData *left; - const PhraseData *right; + PhraseData *left; + PhraseData *right; QVariant operand; Condition operatorCond; bool isNot; + quint16 parents; PhraseData(); PhraseData(const char *className, const char *fieldName); PhraseData(PhraseData *l, Condition o); - PhraseData(PhraseData *l, Condition o, const PhraseData *r); + PhraseData(PhraseData *l, Condition o, PhraseData *r); PhraseData(PhraseData *l, Condition o, QVariant r); - explicit PhraseData(const PhraseData &other); - explicit PhraseData(const PhraseData *other); +// explicit PhraseData(const PhraseData &other); +// explicit PhraseData(const PhraseData *other); + + PhraseData *operator =(PhraseData *other); QString toString() const; ~PhraseData(); + + void cleanUp(); +private: + void cleanUp(PhraseData *d); +}; + +class PhraseDataList : public QList +{ +public: + PhraseDataList(); + void append(PhraseData *d); + void append(QList &dl); + virtual ~PhraseDataList(); }; class AssignmentPhraseList @@ -125,6 +141,9 @@ public: AssignmentPhraseList operator &(const AssignmentPhrase &ph); ~AssignmentPhraseList(); + +private: + void incAllDataParents(); }; class AssignmentPhrase @@ -151,7 +170,7 @@ public: class PhraseList{ public: bool isValid; - QList data; + PhraseDataList data; explicit PhraseList(); PhraseList(const PhraseList &other); PhraseList(const AbstractFieldPhrase &other); @@ -162,6 +181,9 @@ public: PhraseList operator |(PhraseList &other); PhraseList operator |(const AbstractFieldPhrase &other); + +private: + void incAllDataParents(); }; class ConditionalPhrase @@ -350,7 +372,7 @@ public: FieldPhrase operator !() { FieldPhrase f(data->className, data->fieldName); - f.data = new PhraseData(data); +// f.data = new PhraseData(data); f.data->isNot = !data->isNot; return f; } diff --git a/src/query.h b/src/query.h index 29a5031..b8d0d3a 100644 --- a/src/query.h +++ b/src/query.h @@ -139,7 +139,7 @@ Q_OUTOFLINE_TEMPLATE QList Query::toList(int count) d->sql = d->database->sqlGenertor()->selectCommand( d->tableName, d->fieldPhrase, d->wherePhrase, d->orderPhrase, d->relations, d->skip, d->take); -qDebug() <sql; + QSqlQuery q = d->database->exec(d->sql); if (q.lastError().isValid()) { qDebug() << q.lastError().text(); @@ -307,7 +307,7 @@ Q_OUTOFLINE_TEMPLATE QList Query::select(const FieldPhrase f) d->wherePhrase, d->relations, d->skip, d->take); -qDebug() << d->sql; + QSqlQuery q = d->database->exec(d->sql); while (q.next()) { @@ -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(); From 9f712a55eafbf136b00f71bf955b181662d06ff2 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Sun, 11 Mar 2018 13:24:36 +0330 Subject: [PATCH 18/20] wip --- src/generators/sqlgeneratorbase.cpp | 4 ++- src/phrase.cpp | 55 ++++++++++++++++++++++------- src/phrase.h | 4 +++ 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/generators/sqlgeneratorbase.cpp b/src/generators/sqlgeneratorbase.cpp index 44efaec..ad64f94 100644 --- a/src/generators/sqlgeneratorbase.cpp +++ b/src/generators/sqlgeneratorbase.cpp @@ -931,7 +931,9 @@ SqlGeneratorBase::operatorString(const PhraseData::Condition &cond) const void SqlGeneratorBase::appendSkipTake(QString &sql, int skip, int take) { - + Q_UNUSED(sql); + Q_UNUSED(skip); + Q_UNUSED(take); } QString SqlGeneratorBase::createConditionalPhrase(const PhraseData *d) const diff --git a/src/phrase.cpp b/src/phrase.cpp index a3885c1..0c9f9bc 100644 --- a/src/phrase.cpp +++ b/src/phrase.cpp @@ -24,12 +24,12 @@ NUT_BEGIN_NAMESPACE -#define LOG(s) qDebug() << __func__ << s; +#define LOG(s) qDebug() << __func__ << s PhraseData::PhraseData() : className(""), fieldName(""), type(Field), operatorCond(NotAssign), - left(0), right(0), operand(QVariant::Invalid), isNot(false), parents(3) + left(0), right(0), operand(QVariant::Invalid), isNot(false), parents(1) { } PhraseData::PhraseData(const char *className, const char *fieldName) : @@ -70,6 +70,12 @@ PhraseData *PhraseData::operator =(PhraseData *other) return other; } +PhraseData &PhraseData::operator =(PhraseData &other) +{ + other.parents++; + return other; +} + //PhraseData::PhraseData(const PhraseData &other) : // left(other.left), right(other.right), operand(other.operand), // operatorCond(other.operatorCond), className(other.className), @@ -111,7 +117,7 @@ PhraseData::~PhraseData() void PhraseData::cleanUp() { - cleanUp(this); +// cleanUp(this); } void PhraseData::cleanUp(PhraseData *d) @@ -134,22 +140,22 @@ AbstractFieldPhrase::AbstractFieldPhrase(const char *className, AbstractFieldPhrase::AbstractFieldPhrase(const AbstractFieldPhrase &other) { - qDebug() <<"Copy ctor"<toString()<parents; data = other.data; data->parents++; + qDebug() <<"Copy ctor"<toString()<parents; } AbstractFieldPhrase::AbstractFieldPhrase(AbstractFieldPhrase &&other) { data = other.data; + data->parents++; other.data = 0; } AbstractFieldPhrase::~AbstractFieldPhrase() { if (data) { - LOG(data->toString()); - qDebug() << data->parents; + LOG(data->toString()) << data->parents; } else { LOG(""); } @@ -203,6 +209,7 @@ AbstractFieldPhraseOperatorField(>=, PhraseData::GreaterEqual) AbstractFieldPhrase AbstractFieldPhrase::operator !() { + AbstractFieldPhrase f(data->className, data->fieldName); f.data->isNot = !data->isNot; return f; @@ -225,10 +232,17 @@ PhraseList::PhraseList() : isValid(false) PhraseList::PhraseList(const PhraseList &other) : isValid(true) { + LOG(""); data = qMove(other.data); const_cast(other).data.clear(); } +PhraseList::PhraseList(PhraseList &&other) +{ + LOG(""); + data = other.data; +} + PhraseList::PhraseList(const AbstractFieldPhrase &other) : isValid(true) { data.append(other.data); @@ -256,13 +270,20 @@ PhraseList::PhraseList(PhraseList *left, PhraseList *right) : isValid(true) PhraseList::PhraseList(PhraseList *left, const AbstractFieldPhrase *right) : isValid(true) { - data = left->data; + data.append(left->data); data.append(right->data); incAllDataParents(); } PhraseList::~PhraseList() -{ } +{ + LOG(""); +} + +PhraseList &PhraseList::operator =(const PhraseData &other) +{ + return other; +} PhraseList PhraseList::operator |(const AbstractFieldPhrase &other) { return PhraseList(this, &other); @@ -564,6 +585,14 @@ PhraseDataList::PhraseDataList() : QList() } +PhraseDataList::PhraseDataList(const PhraseDataList &other) : QList() +{ + PhraseDataList &o = const_cast(other); + PhraseDataList::iterator i; + for (i = o.begin(); i != o.end(); ++i) + append(*i); +} + void PhraseDataList::append(PhraseData *d) { d->parents++; @@ -580,11 +609,11 @@ void PhraseDataList::append(QList &dl) PhraseDataList::~PhraseDataList() { QList::iterator i; - for (i = begin(); i != end(); ++i) { - (*i)->cleanUp(); - if (!--(*i)->parents) - delete *i; - } + for (i = begin(); i != end(); ++i) { + (*i)->cleanUp(); + if (!--(*i)->parents) + delete *i; + } } //AssignmentPhraseList operator &(const AssignmentPhrase &l, const AssignmentPhrase &r) diff --git a/src/phrase.h b/src/phrase.h index 7cf6fff..97e49d7 100644 --- a/src/phrase.h +++ b/src/phrase.h @@ -109,6 +109,7 @@ public: // explicit PhraseData(const PhraseData *other); PhraseData *operator =(PhraseData *other); + PhraseData &operator =(PhraseData &other); QString toString() const; @@ -123,6 +124,7 @@ class PhraseDataList : public QList { public: PhraseDataList(); + PhraseDataList(const PhraseDataList &other); void append(PhraseData *d); void append(QList &dl); virtual ~PhraseDataList(); @@ -173,12 +175,14 @@ public: PhraseDataList data; explicit PhraseList(); PhraseList(const PhraseList &other); + PhraseList(PhraseList &&other); PhraseList(const AbstractFieldPhrase &other); PhraseList(const AbstractFieldPhrase *left, const AbstractFieldPhrase &right); PhraseList(PhraseList *left, PhraseList *right); PhraseList(PhraseList *left, const AbstractFieldPhrase *right); virtual ~PhraseList(); + PhraseList &operator =(const PhraseData &other); PhraseList operator |(PhraseList &other); PhraseList operator |(const AbstractFieldPhrase &other); From 244778eb5015801d4daab9dff9050cdfbb86b5b0 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Sun, 11 Mar 2018 16:43:13 +0330 Subject: [PATCH 19/20] rc --- src/generators/sqlgeneratorbase_p.h | 2 +- src/phrase.cpp | 5 +++-- src/phrase.h | 2 +- src/query_p.h | 2 +- src/tablemodel.cpp | 6 ++++++ src/tablemodel.h | 1 + 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/generators/sqlgeneratorbase_p.h b/src/generators/sqlgeneratorbase_p.h index d0aa239..1c5d98f 100644 --- a/src/generators/sqlgeneratorbase_p.h +++ b/src/generators/sqlgeneratorbase_p.h @@ -34,7 +34,7 @@ struct FieldModel; class DatabaseModel; class TableModel; class Database; -class RelationModel; +struct RelationModel; class SqlGeneratorBase : public QObject { // Q_OBJECT diff --git a/src/phrase.cpp b/src/phrase.cpp index 0c9f9bc..274cdcc 100644 --- a/src/phrase.cpp +++ b/src/phrase.cpp @@ -280,9 +280,10 @@ PhraseList::~PhraseList() LOG(""); } -PhraseList &PhraseList::operator =(const PhraseData &other) +PhraseList &PhraseList::operator =(const PhraseList &other) { - return other; + data.append(const_cast(other).data); + return *this; } PhraseList PhraseList::operator |(const AbstractFieldPhrase &other) { diff --git a/src/phrase.h b/src/phrase.h index 97e49d7..c466d9d 100644 --- a/src/phrase.h +++ b/src/phrase.h @@ -182,7 +182,7 @@ public: PhraseList(PhraseList *left, const AbstractFieldPhrase *right); virtual ~PhraseList(); - PhraseList &operator =(const PhraseData &other); + PhraseList &operator =(const PhraseList &other); PhraseList operator |(PhraseList &other); PhraseList operator |(const AbstractFieldPhrase &other); diff --git a/src/query_p.h b/src/query_p.h index 1bb2b16..f7127cc 100644 --- a/src/query_p.h +++ b/src/query_p.h @@ -31,7 +31,7 @@ NUT_BEGIN_NAMESPACE class Database; class TableSetBase; class QueryBase; -class RelationModel; +struct RelationModel; class QueryPrivate{ QueryBase *q_ptr; Q_DECLARE_PUBLIC(QueryBase) diff --git a/src/tablemodel.cpp b/src/tablemodel.cpp index b42269a..b77c173 100644 --- a/src/tablemodel.cpp +++ b/src/tablemodel.cpp @@ -324,6 +324,12 @@ TableModel::TableModel(QJsonObject json, QString tableName) _allModels.insert(this); } +TableModel::~TableModel() +{ + qDeleteAll(_fields); + qDeleteAll(_foreignKeys); +} + QJsonObject TableModel::toJson() const { QJsonObject obj; diff --git a/src/tablemodel.h b/src/tablemodel.h index d504c78..3a4ec06 100644 --- a/src/tablemodel.h +++ b/src/tablemodel.h @@ -94,6 +94,7 @@ class TableModel public: explicit TableModel(int typeId, QString tableName = QString::null); explicit TableModel(QJsonObject json, QString tableName); + virtual ~TableModel(); QJsonObject toJson() const; From 23bc60e3cddbfadb0259712c2b583745a085740a Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Tue, 13 Mar 2018 11:29:11 +0330 Subject: [PATCH 20/20] zero copy ok for phrases --- src/database.cpp | 1 + src/databasemodel.cpp | 8 +++++++- src/query.h | 17 ----------------- test/basic/maintest.cpp | 11 ++++++++++- test/basic/maintest.h | 2 ++ 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/database.cpp b/src/database.cpp index 9d5983b..0e2518a 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -190,6 +190,7 @@ bool DatabasePrivate::getCurrectScheema() // TODO: change logs must not be in model int changeLogTypeId = qRegisterMetaType(); + currentModel.append( new TableModel(changeLogTypeId, __CHANGE_LOG_TABLE_NAME)); tables.insert(ChangeLogTable::staticMetaObject.className(), diff --git a/src/databasemodel.cpp b/src/databasemodel.cpp index b732f3d..0902b7d 100644 --- a/src/databasemodel.cpp +++ b/src/databasemodel.cpp @@ -229,7 +229,13 @@ DatabaseModel *DatabaseModel::modelByName(const QString &name) void DatabaseModel::deleteAllModels() { - qDeleteAll(_models.values()); + QMapIterator i(_models); + while (i.hasNext()) { + i.next(); +// cout << i.key() << ": " << i.value() << endl; + delete i.value(); + } +// qDeleteAll(_models.values()); _models.clear(); } diff --git a/src/query.h b/src/query.h index b8d0d3a..8ab8c54 100644 --- a/src/query.h +++ b/src/query.h @@ -73,9 +73,6 @@ public: Query *where(const ConditionalPhrase &ph); Query *setWhere(const ConditionalPhrase &ph); - Query *include(TableSetBase *t); - Query *include(Table *t); - //data selecting T *first(); QList toList(int count = -1); @@ -496,20 +493,6 @@ Q_OUTOFLINE_TEMPLATE Query *Query::orderBy(const PhraseList &ph) return this; } -template -Q_OUTOFLINE_TEMPLATE Query *Query::include(TableSetBase *t) -{ - Q_D(Query); - return this; -} - -template -Q_OUTOFLINE_TEMPLATE Query *Query::include(Table *t) -{ - Q_D(Query); - return this; -} - template Q_OUTOFLINE_TEMPLATE int Query::update(const AssignmentPhraseList &ph) { diff --git a/test/basic/maintest.cpp b/test/basic/maintest.cpp index a8a75be..74f5d14 100644 --- a/test/basic/maintest.cpp +++ b/test/basic/maintest.cpp @@ -209,7 +209,7 @@ void MainTest::testDate() db.postTable()->append(newPost); - db.saveChanges(); + db.saveChanges(true); auto q = db.postTable()->query() ->setWhere(Post::idField() == newPost->id()) @@ -269,4 +269,13 @@ void MainTest::emptyDatabase() QTEST_ASSERT(commentsCount == 6); } +void MainTest::cleanupTestCase() +{ + post->deleteLater(); + user->deleteLater(); + + qDeleteAll(TableModel::allModels()); + DatabaseModel::deleteAllModels(); +} + QTEST_MAIN(MainTest) diff --git a/test/basic/maintest.h b/test/basic/maintest.h index c79ce1a..67ec06b 100644 --- a/test/basic/maintest.h +++ b/test/basic/maintest.h @@ -39,6 +39,8 @@ private slots: void selectWithInvalidRelation(); void modifyPost(); void emptyDatabase(); + + void cleanupTestCase(); }; #endif // MAINTEST_H