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 e5adc6d..0902b7d 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,16 @@ DatabaseModel *DatabaseModel::modelByName(const QString &name) return Q_NULLPTR; } +void DatabaseModel::deleteAllModels() +{ + QMapIterator i(_models); + while (i.hasNext()) { + i.next(); +// cout << i.key() << ": " << i.value() << endl; + delete i.value(); + } +// qDeleteAll(_models.values()); + _models.clear(); +} + NUT_END_NAMESPACE diff --git a/src/databasemodel.h b/src/databasemodel.h index 066bed5..746b86d 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(); TableModel *tableByName(QString tableName) const; TableModel *tableByClassName(QString className) const; @@ -70,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/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/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 4a00030..274cdcc 100644 --- a/src/phrase.cpp +++ b/src/phrase.cpp @@ -24,47 +24,71 @@ 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) + left(0), right(0), operand(QVariant::Invalid), isNot(false), parents(1) { } 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::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), +// 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,10 +105,34 @@ PhraseData::~PhraseData() // if (left) // delete left; // } + +// if (right && !--right->parents) +// delete right; + +// if (left && !--left->parents) +// delete left; + LOG(""); } -AbstractFieldPhrase::AbstractFieldPhrase(const char *className, const char *fieldName) +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) :data(new PhraseData(className, fieldName)) { qDebug() <<"AbstractFieldPhrase created"<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()); + LOG(data->toString()) << data->parents; } else { LOG(""); } if (data) { - delete data; - data = 0; + --data->parents; + if (data->parents <= 0) + delete data; } } @@ -121,9 +178,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) \ @@ -150,9 +209,8 @@ AbstractFieldPhraseOperatorField(>=, PhraseData::GreaterEqual) AbstractFieldPhrase AbstractFieldPhrase::operator !() { - //TODO: classname and s + AbstractFieldPhrase f(data->className, data->fieldName); - f.data = new PhraseData(data); f.data->isNot = !data->isNot; return f; } @@ -174,56 +232,88 @@ 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(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); +// 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(left->data); + data.append(right->data); + incAllDataParents(); } PhraseList::~PhraseList() { -// data.clear(); + LOG(""); +} + +PhraseList &PhraseList::operator =(const PhraseList &other) +{ + data.append(const_cast(other).data); + return *this; } 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; @@ -243,7 +333,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) @@ -265,35 +356,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) @@ -302,7 +410,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; } @@ -316,7 +425,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, @@ -375,13 +485,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; } @@ -408,33 +522,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) \ @@ -444,7 +565,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; \ } @@ -459,6 +581,42 @@ ConditionalPhrase ConditionalPhrase::operator !() return f; } +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++; + 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 df12f7b..c466d9d 100644 --- a/src/phrase.h +++ b/src/phrase.h @@ -92,24 +92,42 @@ 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); + PhraseData &operator =(PhraseData &other); QString toString() const; ~PhraseData(); + + void cleanUp(); +private: + void cleanUp(PhraseData *d); +}; + +class PhraseDataList : public QList +{ +public: + PhraseDataList(); + PhraseDataList(const PhraseDataList &other); + void append(PhraseData *d); + void append(QList &dl); + virtual ~PhraseDataList(); }; class AssignmentPhraseList @@ -125,6 +143,9 @@ public: AssignmentPhraseList operator &(const AssignmentPhrase &ph); ~AssignmentPhraseList(); + +private: + void incAllDataParents(); }; class AssignmentPhrase @@ -151,25 +172,30 @@ public: class PhraseList{ public: bool isValid; - QList data; + 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 PhraseList &other); PhraseList operator |(PhraseList &other); PhraseList operator |(const AbstractFieldPhrase &other); + +private: + void incAllDataParents(); }; 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 +238,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(); @@ -348,7 +376,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..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); @@ -139,7 +136,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 +304,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()) { @@ -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) { @@ -520,7 +503,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 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 c2439c5..3a4ec06 100644 --- a/src/tablemodel.h +++ b/src/tablemodel.h @@ -89,11 +89,12 @@ 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); explicit TableModel(QJsonObject json, QString tableName); + virtual ~TableModel(); QJsonObject toJson() const; 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