From e946a54753ac3a3d6d863803262627f39bb82a14 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Tue, 18 Jun 2019 18:10:40 +0430 Subject: [PATCH 1/5] initial --- include/Nut | 2 + include/SqlModel | 1 + include/TableModel | 1 + include/header_copier | 5 +- include/sqlmodel.h | 1 + include/tablemodel.h | 1 + nut.pro | 1 - src/database.cpp | 2 +- src/defines.h | 28 +++++++++++ src/generators/sqlgeneratorbase.cpp | 3 ++ src/query.h | 76 +++++++++++++++++++++++++---- src/query_p.h | 7 +-- src/querybase_p.h | 7 +++ src/sqlmodel.cpp | 67 +++++++++++++++++++++++-- src/sqlmodel.h | 34 ++++++++++++- src/sqlmodel_p.h | 5 +- 16 files changed, 218 insertions(+), 23 deletions(-) create mode 100644 include/SqlModel create mode 100644 include/TableModel mode change 100644 => 100755 include/header_copier create mode 100644 include/sqlmodel.h create mode 100644 include/tablemodel.h diff --git a/include/Nut b/include/Nut index 5b89c95..c5cf95c 100644 --- a/include/Nut +++ b/include/Nut @@ -1,5 +1,7 @@ #include "../src/table.h" #include "../src/database.h" +#include "../src/sqlmodel.h" #include "../src/tableset.h" +#include "../src/tablemodel.h" #include "../src/query.h" diff --git a/include/SqlModel b/include/SqlModel new file mode 100644 index 0000000..c15f192 --- /dev/null +++ b/include/SqlModel @@ -0,0 +1 @@ +#include "../src/sqlmodel.h" diff --git a/include/TableModel b/include/TableModel new file mode 100644 index 0000000..3bc108b --- /dev/null +++ b/include/TableModel @@ -0,0 +1 @@ +#include "../src/tablemodel.h" diff --git a/include/header_copier b/include/header_copier old mode 100644 new mode 100755 index e228c19..92cdcc2 --- a/include/header_copier +++ b/include/header_copier @@ -3,11 +3,10 @@ src_dir="src" namespace_name="nut" -ns=$(echo $namespace_name|awk '{print tolower($0)}') +#ns=$(echo $namespace_name|awk '{print tolower($0)}') Ns="Nut" NS=$(echo $namespace_name|awk '{print toupper($0)}') -echo $NS -exit + create_sub_folder=true diff --git a/include/sqlmodel.h b/include/sqlmodel.h new file mode 100644 index 0000000..c15f192 --- /dev/null +++ b/include/sqlmodel.h @@ -0,0 +1 @@ +#include "../src/sqlmodel.h" diff --git a/include/tablemodel.h b/include/tablemodel.h new file mode 100644 index 0000000..3bc108b --- /dev/null +++ b/include/tablemodel.h @@ -0,0 +1 @@ +#include "../src/tablemodel.h" diff --git a/nut.pro b/nut.pro index 3a52ab6..5a35529 100644 --- a/nut.pro +++ b/nut.pro @@ -4,4 +4,3 @@ SUBDIRS += \ src \ test - diff --git a/src/database.cpp b/src/database.cpp index 7f26b8d..0c0b3bb 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -278,7 +278,7 @@ bool DatabasePrivate::getCurrectScheema() DatabaseModel DatabasePrivate::getLastScheema() { - ChangeLogTable *u = changeLogs->query() + typename TableType::Row u = changeLogs->query() ->orderBy(!ChangeLogTable::idField()) ->first(); diff --git a/src/defines.h b/src/defines.h index cd9bf42..a26d7bb 100644 --- a/src/defines.h +++ b/src/defines.h @@ -192,4 +192,32 @@ public: \ #define NUT_NOT_NULL(x) NUT_INFO(__nut_NOT_NULL, x, 1) #define NUT_INDEX(name, field, order) +template +struct TableType +{ +#ifdef NUT_SHARED_POINTER + typedef QList> RowList; + typedef QSet> RowSet; + typedef QSharedPointer Row; +#else + typedef QList RowList; + typedef QSet RowSet; + typedef T* Row; +#endif +}; + +//#ifdef NUT_SHARED_POINTER +// template +// using RowList = typename QList>; + +// template +// using Row = typename QSharedPointer; +//#else +// template +// using RowList = typename QList; + +// template +// using Row = typename T* +//#endif + #endif // SYNTAX_DEFINES_H diff --git a/src/generators/sqlgeneratorbase.cpp b/src/generators/sqlgeneratorbase.cpp index 52ff9df..0f9590d 100644 --- a/src/generators/sqlgeneratorbase.cpp +++ b/src/generators/sqlgeneratorbase.cpp @@ -834,6 +834,9 @@ QString SqlGeneratorBase::escapeValue(const QVariant &v) const return QString(); } + if (v.type() == QVariant::List) + return serialized; + return "'" + serialized + "'"; } diff --git a/src/query.h b/src/query.h index 4a31cd9..8739eae 100644 --- a/src/query.h +++ b/src/query.h @@ -29,7 +29,11 @@ #include #include #include -#include +#include + +#ifdef NUT_SHARED_POINTER +#include +#endif #include "table.h" #include "query_p.h" @@ -40,6 +44,7 @@ #include "querybase_p.h" #include "phrase.h" #include "tablemodel.h" +#include "sqlmodel.h" NUT_BEGIN_NAMESPACE @@ -52,6 +57,14 @@ template bool m_autoDelete; public: +//#ifdef NUT_SHARED_POINTER +// typedef QList> RowList; +// typedef QSharedPointer Row; +//#else +// typedef QList RowList; +// typedef T* Row; +//#endif + explicit Query(Database *database, TableSetBase *tableSet, bool autoDelete); ~Query(); @@ -76,8 +89,8 @@ public: Query *setWhere(const ConditionalPhrase &ph); //data selecting - T *first(); - QList toList(int count = -1); + typename TableType::Row first(); + typename TableType::RowList toList(int count = -1); template QList select(const FieldPhrase f); @@ -98,6 +111,7 @@ public: QSqlQueryModel *toModel(); void toModel(QSqlQueryModel *model); + void toModel(SqlModel *model); //debug purpose QString sqlCommand() const; @@ -161,11 +175,11 @@ Q_OUTOFLINE_TEMPLATE Query::~Query() } template -Q_OUTOFLINE_TEMPLATE QList Query::toList(int count) +Q_OUTOFLINE_TEMPLATE typename TableType::RowList Query::toList(int count) { Q_UNUSED(count); Q_D(Query); - QList returnList; + typename TableType::RowList returnList; d->select = "*"; d->sql = d->database->sqlGenertor()->selectCommand( @@ -285,13 +299,17 @@ Q_OUTOFLINE_TEMPLATE QList Query::toList(int count) Table *table; if (data.table->className() == d->className) { table = new T(); - table->setParentTableSet(d->tableSet); +#ifdef NUT_SHARED_POINTER + auto shp = QSharedPointer(qobject_cast(table)); + returnList.append(shp); +#else returnList.append(dynamic_cast(table)); +#endif + table->setParentTableSet(d->tableSet); } else { const QMetaObject *childMetaObject = QMetaType::metaObjectForType(data.table->typeId()); table = qobject_cast(childMetaObject->newInstance()); - if (!table) qFatal("Could not create instance of %s", qPrintable(data.table->name())); @@ -323,8 +341,11 @@ Q_OUTOFLINE_TEMPLATE QList Query::toList(int count) data.lastRow = table; } //while } // while + +#ifndef NUT_SHARED_POINTER if (m_autoDelete) deleteLater(); +#endif return returnList; } @@ -357,11 +378,11 @@ Q_OUTOFLINE_TEMPLATE QList Query::select(const FieldPhrase f) } template -Q_OUTOFLINE_TEMPLATE T *Query::first() +Q_OUTOFLINE_TEMPLATE typename TableType::Row Query::first() { skip(0); take(1); - QList list = toList(1); + typename TableType::RowList list = toList(1); if (list.count()) return list.first(); @@ -617,6 +638,43 @@ Q_OUTOFLINE_TEMPLATE void Query::toModel(QSqlQueryModel *model) } } +template +Q_OUTOFLINE_TEMPLATE void Query::toModel(SqlModel *model) +{ + Q_D(Query); + + d->sql = d->database->sqlGenertor()->selectCommand( + d->tableName, + d->fieldPhrase, + d->wherePhrase, d->orderPhrase, d->relations, + d->skip, d->take); + + model->setTable(toList()); + /* + DatabaseModel dbModel = d->database->model(); + model->setQuery(d->sql, d->database->database()); + + int fieldIndex = 0; + + if (d->fieldPhrase.data.count()) { + foreach (const PhraseData *pd, d->fieldPhrase.data) { + QString displayName = dbModel.tableByClassName(pd->className) + ->field(pd->fieldName)->displayName; + + model->setHeaderData(fieldIndex++, + Qt::Horizontal, + displayName); + } + } else { + TableModel *tbl = d->database->model().tableByName(d->tableName); + foreach (FieldModel *f, tbl->fields()) { + model->setHeaderData(fieldIndex++, + Qt::Horizontal, + f->displayName); + } + }*/ +} + template Q_OUTOFLINE_TEMPLATE QString Query::sqlCommand() const { diff --git a/src/query_p.h b/src/query_p.h index 7fe9eec..b0b3c4a 100644 --- a/src/query_p.h +++ b/src/query_p.h @@ -23,8 +23,9 @@ #include "phrase.h" -#include -#include +#include +#include +#include NUT_BEGIN_NAMESPACE @@ -32,7 +33,7 @@ class Database; class TableSetBase; class QueryBase; struct RelationModel; -class QueryPrivate{ +class QueryPrivate : public QSharedData { QueryBase *q_ptr; Q_DECLARE_PUBLIC(QueryBase) diff --git a/src/querybase_p.h b/src/querybase_p.h index 4d53ce3..8607145 100644 --- a/src/querybase_p.h +++ b/src/querybase_p.h @@ -23,7 +23,10 @@ #include #include +#include + #include "defines.h" +#include "query_p.h" NUT_BEGIN_NAMESPACE @@ -33,6 +36,10 @@ class TableSetBase; class QueryBase : public QObject { Q_OBJECT + +protected: + QExplicitlySharedDataPointer d; + public: explicit QueryBase(QObject *parent = 0); diff --git a/src/sqlmodel.cpp b/src/sqlmodel.cpp index ea2b27e..331b180 100644 --- a/src/sqlmodel.cpp +++ b/src/sqlmodel.cpp @@ -25,17 +25,29 @@ #include "table.h" #include "sqlmodel_p.h" #include "sqlmodel.h" +#include "query.h" NUT_BEGIN_NAMESPACE +//SqlModel::SqlModel(Query *q) : QAbstractItemModel(q.) +//{ + +//} + +void SqlModel::setRenderer(const std::function &renderer) +{ + _renderer = renderer; +} + SqlModel::SqlModel(Database *database, TableSetBase *tableSet, QObject *parent) : - QAbstractTableModel(parent) + QAbstractTableModel(parent), d_ptr(new SqlModelPrivate(this)), _renderer(nullptr) { Q_D(SqlModel); d->model = database->model() .tableByClassName(tableSet->childClassName()); d->tableName = d->model->name(); + // setQuery("SELECT * FROM " + d->tableName, database->databaseName()); } @@ -63,8 +75,12 @@ QVariant SqlModel::data(const QModelIndex &index, int role) const return QVariant("-"); if (role == Qt::DisplayRole) { - Table *t = d->rows.at(index.row()); - return t->property(d->model->field(index.column())->name.toLocal8Bit().data()); + TableType
::Row t = d->rows.at(index.row()); + QVariant v = t->property(d->model->field(index.column())->name.toLocal8Bit().data()); +// emit beforeShowText(index.column(), v); + if (_renderer != nullptr) + v = _renderer(index.column(), v); + return v; // LogData *d = dataList.at(index.row()); // switch (index.column()) { @@ -86,4 +102,49 @@ QVariant SqlModel::data(const QModelIndex &index, int role) const return QVariant(); } +void SqlModel::setRows(TableType
::RowList rows) +{ + Q_D(SqlModel); + beginRemoveRows(QModelIndex(), 0, d->rows.count()); + d->rows.clear(); + endRemoveRows(); + beginInsertRows(QModelIndex(), 0, rows.count()); + d->rows = rows; + endInsertRows(); +} + +void SqlModel::append(TableType
::Row table) +{ + Q_D(SqlModel); + beginInsertRows(QModelIndex(), d->rows.count(), d->rows.count()); + d->rows.append(table); + endInsertRows(); +} + +//void SqlModel::append(Table *table) +//{ +// append(TableType
::Row(table)); +//} + +QVariant SqlModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + Q_D(const SqlModel); + return d->model->field(section)->displayName; + } + return QAbstractItemModel::headerData(section, orientation, role); +} + +Table *SqlModel::at(const int &i) const +{ + Q_D(const SqlModel); + return d->rows.at(i).data(); +} + +SqlModelPrivate::SqlModelPrivate(SqlModel *parent) : q_ptr(parent) +{ + +} + + NUT_END_NAMESPACE diff --git a/src/sqlmodel.h b/src/sqlmodel.h index e8c2590..061f56b 100644 --- a/src/sqlmodel.h +++ b/src/sqlmodel.h @@ -23,6 +23,8 @@ #include #include "defines.h" +#include +#include NUT_BEGIN_NAMESPACE @@ -31,22 +33,52 @@ class TableSetBase; class SqlModelPrivate; class Table; class TableModel; -class SqlModel : public QAbstractTableModel + +class NUT_EXPORT SqlModel : public QAbstractTableModel { Q_OBJECT + std::function _renderer; + public: +// explicit SqlModel(Query *q); explicit SqlModel(Database *database, TableSetBase *tableSet, QObject *parent = Q_NULLPTR); int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; + template + void setTable(QList> rows); + + void setRows(TableType
::RowList rows); + void append(TableType
::Row table); +// void append(Table *table); + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + Table *at(const int &i) const; + + void setRenderer(const std::function &renderer); + private: SqlModelPrivate *d_ptr; Q_DECLARE_PRIVATE(SqlModel) + +signals: + void beforeShowText(int col, QVariant &value); }; +template +Q_OUTOFLINE_TEMPLATE void SqlModel::setTable(QList > rows) +{ + Q_D(SqlModel); + + TableType
::RowList tab; + foreach (auto t, rows) + tab.append(t); + setRows(tab); +} + + NUT_END_NAMESPACE #endif // SQLMODEL_H diff --git a/src/sqlmodel_p.h b/src/sqlmodel_p.h index f359445..cf8bb93 100644 --- a/src/sqlmodel_p.h +++ b/src/sqlmodel_p.h @@ -1,6 +1,7 @@ #ifndef SQLMODEL_P_H #define SQLMODEL_P_H +#include #include #include "defines.h" @@ -13,11 +14,11 @@ class SqlModelPrivate { SqlModel *q_ptr; Q_DECLARE_PUBLIC(SqlModel) public: - explicit SqlModelPrivate() = default; + explicit SqlModelPrivate(SqlModel *parent); QString tableName; - QList rows; + TableType
::RowList rows; TableModel *model; }; From 5e5471fdeb9b0b681c7f884adb55d066e63a5888 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Tue, 18 Jun 2019 20:07:03 +0430 Subject: [PATCH 2/5] working :-( [skip ci] --- nut.pri | 1 + src/database.cpp | 4 +- src/defines.h | 201 ++++++++++++++------------- src/query.h | 12 +- src/querybase.cpp | 8 +- src/querybase_p.h | 2 +- src/sqlmodel.cpp | 6 +- src/sqlmodel.h | 6 +- src/sqlmodel_p.h | 2 +- src/src.pri | 3 + src/tableset.h | 33 ++--- src/tablesetbase.cpp | 46 +++--- src/tablesetbase_p.h | 19 +-- src/tablesetbasedata.h | 50 +++++++ test/common/consts.h | 2 +- test/common/nut-lib.pri | 2 + test/tst_basic/tst_basic.cpp | 14 +- test/tst_basic/tst_basic.h | 4 +- test/tst_benckmark/tst_benchmark.cpp | 2 +- test/tst_datatypes/tst_datatypes.cpp | 63 ++++----- test/tst_json/tst_json.cpp | 2 +- test/tst_quuid/tst_uuid.cpp | 8 +- test/tst_upgrades/tst_upgrades.cpp | 8 +- 23 files changed, 285 insertions(+), 213 deletions(-) create mode 100644 src/tablesetbasedata.h diff --git a/nut.pri b/nut.pri index b0f235b..b0931d8 100644 --- a/nut.pri +++ b/nut.pri @@ -3,6 +3,7 @@ QT += core sql CONFIG += c++11 INCLUDEPATH += $$PWD/include +DEFINES += NUT_SHARED_POINTER include(3rdparty/serializer/src/src.pri) HEADERS += \ diff --git a/src/database.cpp b/src/database.cpp index 0c0b3bb..e804ef4 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -278,7 +278,7 @@ bool DatabasePrivate::getCurrectScheema() DatabaseModel DatabasePrivate::getLastScheema() { - typename TableType::Row u = changeLogs->query() + Row u = changeLogs->query() ->orderBy(!ChangeLogTable::idField()) ->first(); @@ -321,7 +321,7 @@ bool DatabasePrivate::putModelToDatabase() DatabaseModel current = currentModel; /*current.remove(__CHANGE_LOG_TABLE_NAME)*/; - auto *changeLog = new ChangeLogTable(); + auto changeLog = create(); changeLog->setData(QJsonDocument(current.toJson()).toJson(QJsonDocument::Compact)); changeLog->setVersion(current.version()); changeLogs->append(changeLog); diff --git a/src/defines.h b/src/defines.h index a26d7bb..86a96a3 100644 --- a/src/defines.h +++ b/src/defines.h @@ -45,6 +45,83 @@ Q_CLASSINFO(__nut_NAME_PERFIX type #name #value, \ type "\n" #name "\n" value) +#define NUT_FIELD_PERFIX +#define NUT_FIELD_POSTFIX Field + +// Database +#define NUT_DB_VERSION(version) \ + NUT_INFO(__nut_DB_VERSION, version, 0) + +#define NUT_DECLARE_TABLE(type, name) \ + NUT_INFO(__nut_TABLE, type, name) \ + Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet) name READ name) \ + NUT_WRAP_NAMESPACE(TableSet) *m_##name; \ + public: \ + static const type *_##name; \ + NUT_WRAP_NAMESPACE(TableSet) *name() const \ + { return m_##name; } \ + private: + +//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_FOREGION_KEY(type, keytype, name, read, write) \ + Q_PROPERTY(Nut::Row name READ read WRITE write) \ + NUT_DECLARE_FIELD(keytype, name##Id, read##Id, write##Id) \ + NUT_INFO(__nut_FOREGION_KEY, name, type) \ + Nut::Row m_##name; \ +public: \ + Nut::Row read() const { return m_##name ; } \ + void write(Nut::Row name){ \ + m_##name = name; \ + } + +#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 auto f = new type(); \ + return f; \ + } \ + NUT_WRAP_NAMESPACE(TableSet) *class::n(){ \ + return m_##n; \ + } + +#define NUT_FIELD(name) NUT_INFO(__nut_FIELD, name, 0) +#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_INFO(__nut_PRIMARY_KEY_AI, x, 0) +#define NUT_DISPLAY_NAME(field, name) NUT_INFO(__nut_DISPLAY, field, name) +#define NUT_UNIQUE(x) NUT_INFO(__nut_UNIQUE, x, 0) +#define NUT_LEN(field, len) NUT_INFO(__nut_LEN, field, len) +#define NUT_DEFAULT_VALUE(x, n) NUT_INFO(__nut_DEFAULT_VALUE, x, n) +#define NUT_NOT_NULL(x) NUT_INFO(__nut_NOT_NULL, x, 1) +#define NUT_INDEX(name, field, order) + +NUT_BEGIN_NAMESPACE + inline bool nutClassInfo(const QMetaClassInfo &classInfo, QString &type, QString &name, QVariant &value) { @@ -117,107 +194,37 @@ inline bool nutClassInfoInt(const QMetaClassInfo &classInfo, } } -#define NUT_FIELD_PERFIX -#define NUT_FIELD_POSTFIX Field - -// Database -#define NUT_DB_VERSION(version) \ - NUT_INFO(__nut_DB_VERSION, version, 0) - -#define NUT_DECLARE_TABLE(type, name) \ - NUT_INFO(__nut_TABLE, type, name) \ - Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet) name READ name) \ - NUT_WRAP_NAMESPACE(TableSet) *m_##name; \ - public: \ - static const type *_##name; \ - NUT_WRAP_NAMESPACE(TableSet) *name() const \ - { return m_##name; } \ - private: - -//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_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; \ - } - -#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 auto f = new type(); \ - return f; \ - } \ - NUT_WRAP_NAMESPACE(TableSet) *class::n(){ \ - return m_##n; \ - } - -#define NUT_FIELD(name) NUT_INFO(__nut_FIELD, name, 0) -#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_INFO(__nut_PRIMARY_KEY_AI, x, 0) -#define NUT_DISPLAY_NAME(field, name) NUT_INFO(__nut_DISPLAY, field, name) -#define NUT_UNIQUE(x) NUT_INFO(__nut_UNIQUE, x, 0) -#define NUT_LEN(field, len) NUT_INFO(__nut_LEN, field, len) -#define NUT_DEFAULT_VALUE(x, n) NUT_INFO(__nut_DEFAULT_VALUE, x, n) -#define NUT_NOT_NULL(x) NUT_INFO(__nut_NOT_NULL, x, 1) -#define NUT_INDEX(name, field, order) +#ifdef NUT_SHARED_POINTER +template +using RowList = QList>; template -struct TableType -{ -#ifdef NUT_SHARED_POINTER - typedef QList> RowList; - typedef QSet> RowSet; - typedef QSharedPointer Row; +using RowSet = QSet>; + +template +using Row = QSharedPointer; + +template +inline Row create() { + return QSharedPointer(new T); +} + #else - typedef QList RowList; - typedef QSet RowSet; - typedef T* Row; +template +using RowList = QList; + +template +using RowSet = QSet; + +template +using Row = T*; + +template +inline Row create() { + return new T; +} #endif -}; -//#ifdef NUT_SHARED_POINTER -// template -// using RowList = typename QList>; - -// template -// using Row = typename QSharedPointer; -//#else -// template -// using RowList = typename QList; - -// template -// using Row = typename T* -//#endif +NUT_END_NAMESPACE #endif // SYNTAX_DEFINES_H diff --git a/src/query.h b/src/query.h index 8739eae..e4c0c9a 100644 --- a/src/query.h +++ b/src/query.h @@ -89,8 +89,8 @@ public: Query *setWhere(const ConditionalPhrase &ph); //data selecting - typename TableType::Row first(); - typename TableType::RowList toList(int count = -1); + Row first(); + RowList toList(int count = -1); template QList select(const FieldPhrase f); @@ -175,11 +175,11 @@ Q_OUTOFLINE_TEMPLATE Query::~Query() } template -Q_OUTOFLINE_TEMPLATE typename TableType::RowList Query::toList(int count) +Q_OUTOFLINE_TEMPLATE RowList Query::toList(int count) { Q_UNUSED(count); Q_D(Query); - typename TableType::RowList returnList; + RowList returnList; d->select = "*"; d->sql = d->database->sqlGenertor()->selectCommand( @@ -378,11 +378,11 @@ Q_OUTOFLINE_TEMPLATE QList Query::select(const FieldPhrase f) } template -Q_OUTOFLINE_TEMPLATE typename TableType::Row Query::first() +Q_OUTOFLINE_TEMPLATE Row Query::first() { skip(0); take(1); - typename TableType::RowList list = toList(1); + RowList list = toList(1); if (list.count()) return list.first(); diff --git a/src/querybase.cpp b/src/querybase.cpp index 5a9526d..f14f16e 100644 --- a/src/querybase.cpp +++ b/src/querybase.cpp @@ -11,9 +11,9 @@ QueryBase::QueryBase(QObject *parent) : QObject(parent) } -void QueryBase::addTableToSet(TableSetBase *set, Table *table) -{ - set->add(table); -} +//void QueryBase::addTableToSet(TableSetBase *set, Table *table) +//{ +// set->add(table); +//} NUT_END_NAMESPACE diff --git a/src/querybase_p.h b/src/querybase_p.h index 8607145..2ef0386 100644 --- a/src/querybase_p.h +++ b/src/querybase_p.h @@ -44,7 +44,7 @@ public: explicit QueryBase(QObject *parent = 0); protected: - void addTableToSet(TableSetBase *set, Table *table); +// void addTableToSet(TableSetBase *set, Table *table); public slots: }; diff --git a/src/sqlmodel.cpp b/src/sqlmodel.cpp index 331b180..7ee2dbd 100644 --- a/src/sqlmodel.cpp +++ b/src/sqlmodel.cpp @@ -75,7 +75,7 @@ QVariant SqlModel::data(const QModelIndex &index, int role) const return QVariant("-"); if (role == Qt::DisplayRole) { - TableType
::Row t = d->rows.at(index.row()); + Row
t = d->rows.at(index.row()); QVariant v = t->property(d->model->field(index.column())->name.toLocal8Bit().data()); // emit beforeShowText(index.column(), v); if (_renderer != nullptr) @@ -102,7 +102,7 @@ QVariant SqlModel::data(const QModelIndex &index, int role) const return QVariant(); } -void SqlModel::setRows(TableType
::RowList rows) +void SqlModel::setRows(RowList
rows) { Q_D(SqlModel); beginRemoveRows(QModelIndex(), 0, d->rows.count()); @@ -113,7 +113,7 @@ void SqlModel::setRows(TableType
::RowList rows) endInsertRows(); } -void SqlModel::append(TableType
::Row table) +void SqlModel::append(Row
table) { Q_D(SqlModel); beginInsertRows(QModelIndex(), d->rows.count(), d->rows.count()); diff --git a/src/sqlmodel.h b/src/sqlmodel.h index 061f56b..55ed774 100644 --- a/src/sqlmodel.h +++ b/src/sqlmodel.h @@ -51,8 +51,8 @@ public: template void setTable(QList> rows); - void setRows(TableType
::RowList rows); - void append(TableType
::Row table); + void setRows(RowList
rows); + void append(Row
table); // void append(Table *table); QVariant headerData(int section, Qt::Orientation orientation, int role) const; Table *at(const int &i) const; @@ -72,7 +72,7 @@ Q_OUTOFLINE_TEMPLATE void SqlModel::setTable(QList > rows) { Q_D(SqlModel); - TableType
::RowList tab; + RowList
tab; foreach (auto t, rows) tab.append(t); setRows(tab); diff --git a/src/sqlmodel_p.h b/src/sqlmodel_p.h index cf8bb93..1991d9c 100644 --- a/src/sqlmodel_p.h +++ b/src/sqlmodel_p.h @@ -18,7 +18,7 @@ public: QString tableName; - TableType
::RowList rows; + RowList
rows; TableModel *model; }; diff --git a/src/src.pri b/src/src.pri index 84d9a48..79319e3 100644 --- a/src/src.pri +++ b/src/src.pri @@ -1,9 +1,12 @@ +DEFINES += NUT_SHARED_POINTER + HEADERS += \ $$PWD/generators/sqlgeneratorbase_p.h \ $$PWD/generators/postgresqlgenerator.h \ $$PWD/generators/mysqlgenerator.h \ $$PWD/generators/sqlitegenerator.h \ $$PWD/generators/sqlservergenerator.h \ + $$PWD/tablesetbasedata.h \ $$PWD/types/dbgeography.h \ $$PWD/tableset.h \ $$PWD/defines_p.h \ diff --git a/src/tableset.h b/src/tableset.h index 7748614..af02003 100644 --- a/src/tableset.h +++ b/src/tableset.h @@ -32,6 +32,7 @@ #include "bulkinserter.h" //#include "database.h" #include "databasemodel.h" +#include "tablesetbasedata.h" NUT_BEGIN_NAMESPACE @@ -47,8 +48,8 @@ public: explicit TableSet(Database *parent); explicit TableSet(Table *parent); - void append(T *t); - void append(QList t); + void append(Row t); + void append(RowList t); void remove(T *t); void remove(QList t); @@ -65,19 +66,19 @@ public: template Q_OUTOFLINE_TEMPLATE TableSet::TableSet(Database *parent) : TableSetBase(parent) { - _childClassName = T::staticMetaObject.className(); + data->childClassName = T::staticMetaObject.className(); } template Q_OUTOFLINE_TEMPLATE TableSet::TableSet(Table *parent) : TableSetBase(parent) { - _childClassName = T::staticMetaObject.className(); + data->childClassName = T::staticMetaObject.className(); } template Q_OUTOFLINE_TEMPLATE Query *TableSet::query(bool autoDelete) { - Query *q = new Query(_database, this, autoDelete); + Query *q = new Query(data->database, this, autoDelete); return q; } @@ -85,34 +86,34 @@ Q_OUTOFLINE_TEMPLATE Query *TableSet::query(bool autoDelete) template Q_OUTOFLINE_TEMPLATE BulkInserter *TableSet::bulkInserter() { - BulkInserter *bi = new BulkInserter(_database, _childClassName); + BulkInserter *bi = new BulkInserter(data->database, data->childClassName); return bi; - } template Q_OUTOFLINE_TEMPLATE int TableSet::length() const { - return _tables.count(); + return data->tables.count(); } template Q_OUTOFLINE_TEMPLATE T *TableSet::at(int i) const { - return reinterpret_cast(_childRows.at(i)); + //TODO: check + return reinterpret_cast(data->childRows.at(i)); } template Q_OUTOFLINE_TEMPLATE const T &TableSet::operator[](int i) const { - return _childRows[i]; + return data->childRows[i]; } template -Q_OUTOFLINE_TEMPLATE void TableSet::append(T *t) +Q_OUTOFLINE_TEMPLATE void TableSet::append(Row t) { - _tables.insert(t); - _childRows.append(t); + data->tables.insert(t.data()); + data->childRows.append(t.data()); // if (_database) // t->setModel(_database->model().tableByClassName(t->metaObject()->className())); @@ -123,16 +124,16 @@ Q_OUTOFLINE_TEMPLATE void TableSet::append(T *t) } template -Q_OUTOFLINE_TEMPLATE void TableSet::append(QList t) +Q_OUTOFLINE_TEMPLATE void TableSet::append(RowList t) { - foreach (T* i, t) + foreach (Row i, t) append(i); } template Q_OUTOFLINE_TEMPLATE void TableSet::remove(T *t) { - _tables.remove(t); + data->tables.remove(t); t->setStatus(Table::Deleted); } diff --git a/src/tablesetbase.cpp b/src/tablesetbase.cpp index 9b04a7a..15289ab 100644 --- a/src/tablesetbase.cpp +++ b/src/tablesetbase.cpp @@ -22,24 +22,25 @@ #include "database.h" #include "tablesetbase_p.h" #include "databasemodel.h" +#include "tablesetbasedata.h" NUT_BEGIN_NAMESPACE TableSetBase::TableSetBase(Database *parent) : QObject(parent), - _database(parent), _table(nullptr)//, _tableName(QString()) + data(new TableSetBaseData(parent)) { parent->add(this); } TableSetBase::TableSetBase(Table *parent) : QObject(parent), - _database(nullptr), _table(parent)//, _tableName(QString()) + data(new TableSetBaseData(parent)) { parent->add(this); } TableSetBase::~TableSetBase() { - foreach (Table *t, _tables) + foreach (Table *t, data->tables) t->setParentTableSet(nullptr); } @@ -47,12 +48,13 @@ int TableSetBase::save(Database *db, bool cleanUp) { int rowsAffected = 0; TableModel *masterModel = nullptr; - if (_table) - masterModel = db->model().tableByClassName(_table->metaObject()->className()); + if (data->table) + masterModel = db->model().tableByClassName(data->table->metaObject()->className()); - foreach (Table *t, _childRows) { - if(_table) - t->setParentTable(_table, masterModel, + foreach (Row
t, data->childRows) { + if(data->table) + t->setParentTable(data->table, + masterModel, db->model().tableByClassName(t->metaObject()->className())); if(t->status() == Table::Added @@ -66,45 +68,47 @@ int TableSetBase::save(Database *db, bool cleanUp) } if (cleanUp) - _childRows.clear(); + data->childRows.clear(); return rowsAffected; } void TableSetBase::clearChilds() { - foreach (Table *t, _childRows) +#ifndef NUT_SHARED_POINTER + foreach (Table *t, data->_childRows) t->deleteLater(); - _childRows.clear(); +#endif + data->childRows.clear(); } -void TableSetBase::add(Table *t) +void TableSetBase::add(Row
t) { - if(!_tables.contains(t)){ - _tables.insert(t); - _childRows.append(t); + if(!data->tables.contains(t.data())){ + data->tables.insert(t.data()); + data->childRows.append(t); } } -void TableSetBase::remove(Table *t) +void TableSetBase::remove(Row
t) { - _tables.remove(t); - _childRows.removeOne(t); + data->tables.remove(t.data()); + data->childRows.removeOne(t); } QString TableSetBase::childClassName() const { - return _childClassName; + return data->childClassName; } Database *TableSetBase::database() const { - return _database; + return data->database; } void TableSetBase::setDatabase(Database *database) { - _database = database; + data->database = database; } NUT_END_NAMESPACE diff --git a/src/tablesetbase_p.h b/src/tablesetbase_p.h index 114f458..c04072e 100644 --- a/src/tablesetbase_p.h +++ b/src/tablesetbase_p.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "defines.h" @@ -31,6 +32,7 @@ NUT_BEGIN_NAMESPACE class Table; class Database; +class TableSetBaseData; class TableSetBase : public QObject { @@ -47,16 +49,17 @@ public: void setDatabase(Database *database); protected: - QSet _tables; - QList _childRows; - Database *_database; - Table *_table; -// QString _tableName; - QString _childClassName; +// QSet _tables; +// RowList
_childRows; +// Database *_database; +// Table *_table; +//// QString _tableName; +// QString _childClassName; + QExplicitlySharedDataPointer data; private: - void add(Table* t); - void remove(Table* t); + void add(Row
t); + void remove(Row
t); friend class Table; friend class QueryBase; diff --git a/src/tablesetbasedata.h b/src/tablesetbasedata.h new file mode 100644 index 0000000..7e132ed --- /dev/null +++ b/src/tablesetbasedata.h @@ -0,0 +1,50 @@ +/************************************************************************** +** +** 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 TABLESETBASEDATA_H +#define TABLESETBASEDATA_H + +#include +#include "defines.h" + +NUT_BEGIN_NAMESPACE + +class Table; +class Database; +class TableSetBaseData : public QSharedData +{ +public: + TableSetBaseData(Database *parent) : + database(parent), table(nullptr) + { } + TableSetBaseData(Table *parent) : + database(nullptr), table(parent) + { } + + QSet tables; + QList childRows; + Database *database; + Table *table; + QString childClassName; +}; + +NUT_END_NAMESPACE + +#endif // TABLESETBASEDATA_H diff --git a/test/common/consts.h b/test/common/consts.h index 5b34315..ca49e2e 100644 --- a/test/common/consts.h +++ b/test/common/consts.h @@ -11,7 +11,7 @@ .arg(timer.elapsed() / 1000.) \ .arg(__func__) -#define DRIVER "QPSQL" +#define DRIVER "QSQLITE" #define DATABASE QString("nut_test_%1_db").arg(metaObject()->className()).toLower() #define HOST "127.0.0.1" #define USERNAME "postgres" diff --git a/test/common/nut-lib.pri b/test/common/nut-lib.pri index 47b0640..ade3e61 100644 --- a/test/common/nut-lib.pri +++ b/test/common/nut-lib.pri @@ -8,3 +8,5 @@ win32 { LIBS += -L$$LIBDIR -lnut INCLUDEPATH += $$PWD/../../src $$PWD/../common #include(../../src/src.pri) + +DEFINES += NUT_SHARED_POINTER diff --git a/test/tst_basic/tst_basic.cpp b/test/tst_basic/tst_basic.cpp index df3c568..55d59c3 100644 --- a/test/tst_basic/tst_basic.cpp +++ b/test/tst_basic/tst_basic.cpp @@ -56,7 +56,7 @@ void BasicTest::dataScheema() void BasicTest::createUser() { - user = new User; + user = Nut::create(); user->setUsername("admin"); user->setPassword("123456"); db.users()->append(user); @@ -66,7 +66,7 @@ void BasicTest::createUser() void BasicTest::createPost() { TIC(); - Post *newPost = new Post; + auto newPost = Nut::create(); newPost->setTitle("post title"); newPost->setSaveDate(QDateTime::currentDateTime()); newPost->setPublic(false); @@ -74,14 +74,14 @@ void BasicTest::createPost() db.posts()->append(newPost); for(int i = 0 ; i < 3; i++){ - auto *comment = new Comment; + auto comment = Nut::create(); comment->setMessage("comment #" + QString::number(i)); comment->setSaveDate(QDateTime::currentDateTime()); comment->setAuthorId(user->id()); newPost->comments()->append(comment); } for (int i = 0; i < 10; ++i) { - auto *score = new Score; + auto score = Nut::create(); score->setScore(i % 5); newPost->scores()->append(score); } @@ -106,7 +106,7 @@ void BasicTest::createPost2() int postId = postIdVar.toInt(); for(int i = 0 ; i < 3; i++){ - auto *comment = new Comment; + auto comment = Nut::create(); comment->setMessage("comment #" + QString::number(i + 2)); comment->setSaveDate(QDateTime::currentDateTime()); comment->setAuthor(user); @@ -205,7 +205,7 @@ void BasicTest::testDate() QTime t = QTime(d.time().hour(), d.time().minute(), d.time().second()); d.setTime(t); - Post *newPost = new Post; + auto newPost = Nut::create(); newPost->setTitle("post title"); newPost->setSaveDate(d); @@ -249,7 +249,7 @@ void BasicTest::modifyPost() auto q = db.posts()->query(); q->setWhere(Post::idField() == postId); - Post *post = q->first(); + Nut::Row post = q->first(); QTEST_ASSERT(post != nullptr); diff --git a/test/tst_basic/tst_basic.h b/test/tst_basic/tst_basic.h index d682b91..89b59a9 100644 --- a/test/tst_basic/tst_basic.h +++ b/test/tst_basic/tst_basic.h @@ -12,8 +12,8 @@ class BasicTest : public QObject Q_OBJECT WeblogDatabase db; int postId; - Post *post; - User *user; + Nut::Row post; + Nut::Row user; public: explicit BasicTest(QObject *parent = nullptr); diff --git a/test/tst_benckmark/tst_benchmark.cpp b/test/tst_benckmark/tst_benchmark.cpp index 157bb83..2618f14 100644 --- a/test/tst_benckmark/tst_benchmark.cpp +++ b/test/tst_benckmark/tst_benchmark.cpp @@ -45,7 +45,7 @@ void BenchmarkTest::insert1kPost() t.start(); for (int i = 0; i < 100; ++i) { - Post *newPost = new Post; + auto newPost = Nut::create(); newPost->setTitle("post title"); newPost->setSaveDate(QDateTime::currentDateTime()); diff --git a/test/tst_datatypes/tst_datatypes.cpp b/test/tst_datatypes/tst_datatypes.cpp index 4696244..2016137 100644 --- a/test/tst_datatypes/tst_datatypes.cpp +++ b/test/tst_datatypes/tst_datatypes.cpp @@ -85,53 +85,54 @@ void DataTypesTest::initTestCase() void DataTypesTest::insert() { - SampleTable t; - t.setInt8(f_int8); - t.setInt16(f_int16); - t.setInt32(f_int32); - t.setInt64(f_int64); + auto t = Nut::create(); - t.setUint8(f_uint8); - t.setUint16(f_uint16); - t.setUint32(f_uint32); - t.setUint64(f_uint64); + t->setInt8(f_int8); + t->setInt16(f_int16); + t->setInt32(f_int32); + t->setInt64(f_int64); - t.setReal(f_real); - t.setFloat(f_float); + t->setUint8(f_uint8); + t->setUint16(f_uint16); + t->setUint32(f_uint32); + t->setUint64(f_uint64); - t.setUrl(f_url); + t->setReal(f_real); + t->setFloat(f_float); - t.setTime(f_time); - t.setDate(f_date); - t.setDateTime(f_dateTime); - t.setUuid(f_uuid); + t->setUrl(f_url); - t.setJsonDoc(f_jsonDoc); - t.setJsonObj(f_jsonObj); - t.setJsonArray(f_jsonArray); - t.setJsonValue(f_jsonValue); + t->setTime(f_time); + t->setDate(f_date); + t->setDateTime(f_dateTime); + t->setUuid(f_uuid); - t.setString(f_string); - t.setStringList(f_stringList); - t.setQchar(f_qchar); + t->setJsonDoc(f_jsonDoc); + t->setJsonObj(f_jsonObj); + t->setJsonArray(f_jsonArray); + t->setJsonValue(f_jsonValue); + + t->setString(f_string); + t->setStringList(f_stringList); + t->setQchar(f_qchar); #ifdef QT_GUI_LIB - t.setColor(f_color); + t->setColor(f_color); - t.setPoint(f_point); - t.setPointf(f_pointf); + t->setPoint(f_point); + t->setPointf(f_pointf); - t.setPolygon(f_polygon); - t.setPolygonf(f_polygonf); + t->setPolygon(f_polygon); + t->setPolygonf(f_polygonf); #endif - db.sampleTables()->append(&t); + db.sampleTables()->append(t); db.saveChanges(); } void DataTypesTest::retrive() { - QList list = db.sampleTables()->query()->toList(); + Nut::RowList list = db.sampleTables()->query()->toList(); QTEST_ASSERT(list.count() == 1); - SampleTable *t = list.first(); + Nut::Row t = list.first(); QTEST_ASSERT(t->f_int8() == f_int8); QTEST_ASSERT(t->f_int16() == f_int16); diff --git a/test/tst_json/tst_json.cpp b/test/tst_json/tst_json.cpp index 4b56f3d..81c2977 100644 --- a/test/tst_json/tst_json.cpp +++ b/test/tst_json/tst_json.cpp @@ -39,7 +39,7 @@ void TestJson::store() db.open(); - Table *t = new Table; + auto t = Nut::create
(); QJsonParseError e; QJsonDocument doc = QJsonDocument::fromJson(R"({"a": 4, "b":3.14})", &e); qDebug() << e.errorString(); diff --git a/test/tst_quuid/tst_uuid.cpp b/test/tst_quuid/tst_uuid.cpp index 446ad38..3337e34 100644 --- a/test/tst_quuid/tst_uuid.cpp +++ b/test/tst_quuid/tst_uuid.cpp @@ -41,10 +41,10 @@ void UuidTest::initTestCase() void UuidTest::save() { TIC(); - Test t; - t.setId(QUuid::createUuid()); - t.setUuid(uuid); - db.tests()->append(&t); + auto t = Nut::create(); + t->setId(QUuid::createUuid()); + t->setUuid(uuid); + db.tests()->append(t); int n = db.saveChanges(); TOC(); diff --git a/test/tst_upgrades/tst_upgrades.cpp b/test/tst_upgrades/tst_upgrades.cpp index 602f9c6..c91576b 100644 --- a/test/tst_upgrades/tst_upgrades.cpp +++ b/test/tst_upgrades/tst_upgrades.cpp @@ -58,11 +58,11 @@ void Upgrades::version2() initDb(db); QTEST_ASSERT(db.open()); - Table2 t; - t.setStr("0"); - db.sampleTable()->append(&t); + auto t = Nut::create(); + t->setStr("0"); + db.sampleTable()->append(t); db.saveChanges(); - id = t.id(); + id = t->id(); } void Upgrades::version3() From dc99f3ed012f2c1fd29c682f35bfd6918f77a912 Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Wed, 19 Jun 2019 01:02:27 +0430 Subject: [PATCH 3/5] Workinsg --- 3rdparty/serializer | 2 +- src/defines.h | 20 ++++++++++++++++++++ src/query.h | 4 ++-- src/tableset.h | 5 +++-- src/tablesetbase.cpp | 19 +++++++++++-------- src/tablesetbase_p.h | 4 ++-- src/tablesetbasedata.h | 2 ++ test/tst_basic/tst_basic.cpp | 2 +- 8 files changed, 42 insertions(+), 16 deletions(-) diff --git a/3rdparty/serializer b/3rdparty/serializer index e2d8a72..b3c550c 160000 --- a/3rdparty/serializer +++ b/3rdparty/serializer @@ -1 +1 @@ -Subproject commit e2d8a726ef1396c47bf35347ea8b55ca47c6af3b +Subproject commit b3c550c5bb7c570b1b10492fcedf287c1915af39 diff --git a/src/defines.h b/src/defines.h index 86a96a3..22efbb0 100644 --- a/src/defines.h +++ b/src/defines.h @@ -209,6 +209,15 @@ inline Row create() { return QSharedPointer(new T); } +template +inline T *get(T *row) { + return row; +} +template +inline T *get(const QSharedPointer row) { + return row.data(); +} + #else template using RowList = QList; @@ -223,6 +232,17 @@ template inline Row create() { return new T; } + +template +inline T *get(const Row row) { + return row; +} + +template +inline T *get(const QSharedPointer row) { + return row.data(); +} + #endif NUT_END_NAMESPACE diff --git a/src/query.h b/src/query.h index e4c0c9a..1eca189 100644 --- a/src/query.h +++ b/src/query.h @@ -185,7 +185,7 @@ Q_OUTOFLINE_TEMPLATE RowList 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(); @@ -346,7 +346,7 @@ Q_OUTOFLINE_TEMPLATE RowList Query::toList(int count) if (m_autoDelete) deleteLater(); #endif - +qDebug() << "len="< class NUT_EXPORT TableSet : public TableSetBase { @@ -114,7 +114,7 @@ Q_OUTOFLINE_TEMPLATE void TableSet::append(Row t) { data->tables.insert(t.data()); data->childRows.append(t.data()); - + data->rowList.append(t); // if (_database) // t->setModel(_database->model().tableByClassName(t->metaObject()->className())); @@ -133,6 +133,7 @@ Q_OUTOFLINE_TEMPLATE void TableSet::append(RowList t) template Q_OUTOFLINE_TEMPLATE void TableSet::remove(T *t) { + data->rowList.removeOne(t); data->tables.remove(t); t->setStatus(Table::Deleted); } diff --git a/src/tablesetbase.cpp b/src/tablesetbase.cpp index 15289ab..1cf0b0d 100644 --- a/src/tablesetbase.cpp +++ b/src/tablesetbase.cpp @@ -51,7 +51,7 @@ int TableSetBase::save(Database *db, bool cleanUp) if (data->table) masterModel = db->model().tableByClassName(data->table->metaObject()->className()); - foreach (Row
t, data->childRows) { + foreach (Table *t, data->childRows) { if(data->table) t->setParentTable(data->table, masterModel, @@ -82,18 +82,20 @@ void TableSetBase::clearChilds() data->childRows.clear(); } -void TableSetBase::add(Row
t) +void TableSetBase::add(Table *t) { - if(!data->tables.contains(t.data())){ - data->tables.insert(t.data()); - data->childRows.append(t); + if(!data->tables.contains(get(t))){ + data.detach(); + data->tables.insert(get(t)); + data->childRows.append(get(t)); } } -void TableSetBase::remove(Row
t) +void TableSetBase::remove(Table *t) { - data->tables.remove(t.data()); - data->childRows.removeOne(t); + data.detach(); + data->tables.remove(get(t)); + data->childRows.removeOne(get(t)); } QString TableSetBase::childClassName() const @@ -108,6 +110,7 @@ Database *TableSetBase::database() const void TableSetBase::setDatabase(Database *database) { + data.detach(); data->database = database; } diff --git a/src/tablesetbase_p.h b/src/tablesetbase_p.h index c04072e..15f74df 100644 --- a/src/tablesetbase_p.h +++ b/src/tablesetbase_p.h @@ -58,8 +58,8 @@ protected: QExplicitlySharedDataPointer data; private: - void add(Row
t); - void remove(Row
t); + void add(Nut::Table *t); + void remove(Nut::Table *t); friend class Table; friend class QueryBase; diff --git a/src/tablesetbasedata.h b/src/tablesetbasedata.h index 7e132ed..01ccfeb 100644 --- a/src/tablesetbasedata.h +++ b/src/tablesetbasedata.h @@ -34,6 +34,7 @@ public: TableSetBaseData(Database *parent) : database(parent), table(nullptr) { } + TableSetBaseData(Table *parent) : database(nullptr), table(parent) { } @@ -43,6 +44,7 @@ public: Database *database; Table *table; QString childClassName; + RowList
rowList; }; NUT_END_NAMESPACE diff --git a/test/tst_basic/tst_basic.cpp b/test/tst_basic/tst_basic.cpp index 55d59c3..f728887 100644 --- a/test/tst_basic/tst_basic.cpp +++ b/test/tst_basic/tst_basic.cpp @@ -78,7 +78,7 @@ void BasicTest::createPost() comment->setMessage("comment #" + QString::number(i)); comment->setSaveDate(QDateTime::currentDateTime()); comment->setAuthorId(user->id()); - newPost->comments()->append(comment); + db.comments()->append(comment); } for (int i = 0; i < 10; ++i) { auto score = Nut::create(); From d3b4698b3edb4567693be617ec8a06443f92d32c Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Wed, 19 Jun 2019 11:22:00 +0430 Subject: [PATCH 4/5] fix uuid as primary key on sqlite [skip ci] --- src/defines.h | 5 +++++ src/generators/sqlitegenerator.cpp | 2 +- src/sqlmodel.cpp | 4 ++-- src/sqlmodel.h | 2 +- src/tableset.h | 10 ++++++++-- src/tablesetbase.cpp | 16 ++++++++++------ src/tablesetbase_p.h | 4 ++-- src/tablesetbasedata.h | 2 ++ test/tst_quuid/tst_uuid.cpp | 1 - 9 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/defines.h b/src/defines.h index 86a96a3..d0a75dc 100644 --- a/src/defines.h +++ b/src/defines.h @@ -209,6 +209,11 @@ inline Row create() { return QSharedPointer(new T); } +template +inline Row create(QObject *parent) { + return QSharedPointer(new T(parent)); +} + #else template using RowList = QList; diff --git a/src/generators/sqlitegenerator.cpp b/src/generators/sqlitegenerator.cpp index d62f895..e97687b 100644 --- a/src/generators/sqlitegenerator.cpp +++ b/src/generators/sqlitegenerator.cpp @@ -95,7 +95,7 @@ QString SqliteGenerator::fieldDeclare(FieldModel *field) if (type.isEmpty()) return type; - if (field->isPrimaryKey) { + if (isNumeric(field->type) && field->isPrimaryKey) { type = "INTEGER PRIMARY KEY"; if (field->isAutoIncrement) type.append(" AUTOINCREMENT"); diff --git a/src/sqlmodel.cpp b/src/sqlmodel.cpp index 7ee2dbd..153b892 100644 --- a/src/sqlmodel.cpp +++ b/src/sqlmodel.cpp @@ -135,10 +135,10 @@ QVariant SqlModel::headerData(int section, Qt::Orientation orientation, int role return QAbstractItemModel::headerData(section, orientation, role); } -Table *SqlModel::at(const int &i) const +Row
SqlModel::at(const int &i) const { Q_D(const SqlModel); - return d->rows.at(i).data(); + return d->rows.at(i); } SqlModelPrivate::SqlModelPrivate(SqlModel *parent) : q_ptr(parent) diff --git a/src/sqlmodel.h b/src/sqlmodel.h index 55ed774..6a3ca84 100644 --- a/src/sqlmodel.h +++ b/src/sqlmodel.h @@ -55,7 +55,7 @@ public: void append(Row
table); // void append(Table *table); QVariant headerData(int section, Qt::Orientation orientation, int role) const; - Table *at(const int &i) const; + Row at(const int &i) const; void setRenderer(const std::function &renderer); diff --git a/src/tableset.h b/src/tableset.h index af02003..95a88a6 100644 --- a/src/tableset.h +++ b/src/tableset.h @@ -45,6 +45,10 @@ template class NUT_EXPORT TableSet : public TableSetBase { public: + typedef T value_type; + typedef T *pointer; + typedef T &reference; + explicit TableSet(Database *parent); explicit TableSet(Table *parent); @@ -53,8 +57,6 @@ public: void remove(T *t); void remove(QList t); - inline T *type() const {} - int length() const; T *at(int i) const; const T &operator[](int i) const; @@ -112,6 +114,8 @@ Q_OUTOFLINE_TEMPLATE const T &TableSet::operator[](int i) const template Q_OUTOFLINE_TEMPLATE void TableSet::append(Row t) { + data.detach(); + data->childs.append(t); data->tables.insert(t.data()); data->childRows.append(t.data()); @@ -133,6 +137,8 @@ Q_OUTOFLINE_TEMPLATE void TableSet::append(RowList t) template Q_OUTOFLINE_TEMPLATE void TableSet::remove(T *t) { + data.detach(); + data->childs.removeOne(t); data->tables.remove(t); t->setStatus(Table::Deleted); } diff --git a/src/tablesetbase.cpp b/src/tablesetbase.cpp index 15289ab..41cc254 100644 --- a/src/tablesetbase.cpp +++ b/src/tablesetbase.cpp @@ -51,7 +51,7 @@ int TableSetBase::save(Database *db, bool cleanUp) if (data->table) masterModel = db->model().tableByClassName(data->table->metaObject()->className()); - foreach (Row
t, data->childRows) { + foreach (Table *t, data->childRows) { if(data->table) t->setParentTable(data->table, masterModel, @@ -82,18 +82,22 @@ void TableSetBase::clearChilds() data->childRows.clear(); } -void TableSetBase::add(Row
t) +void TableSetBase::add(Table *t) { - if(!data->tables.contains(t.data())){ - data->tables.insert(t.data()); + if(!data->tables.contains(t)){ + data.detach(); + data->tables.insert(t); data->childRows.append(t); +// data->childs.append(t); } } -void TableSetBase::remove(Row
t) +void TableSetBase::remove(Table *t) { - data->tables.remove(t.data()); + data.detach(); + data->tables.remove(t); data->childRows.removeOne(t); +// data->childs.removeOne(t); } QString TableSetBase::childClassName() const diff --git a/src/tablesetbase_p.h b/src/tablesetbase_p.h index c04072e..cb8c6d2 100644 --- a/src/tablesetbase_p.h +++ b/src/tablesetbase_p.h @@ -58,8 +58,8 @@ protected: QExplicitlySharedDataPointer data; private: - void add(Row
t); - void remove(Row
t); + void add(Table* t); + void remove(Table *t); friend class Table; friend class QueryBase; diff --git a/src/tablesetbasedata.h b/src/tablesetbasedata.h index 7e132ed..4ab1203 100644 --- a/src/tablesetbasedata.h +++ b/src/tablesetbasedata.h @@ -40,6 +40,8 @@ public: QSet tables; QList childRows; + RowList
childs; + Database *database; Table *table; QString childClassName; diff --git a/test/tst_quuid/tst_uuid.cpp b/test/tst_quuid/tst_uuid.cpp index 3337e34..21dadae 100644 --- a/test/tst_quuid/tst_uuid.cpp +++ b/test/tst_quuid/tst_uuid.cpp @@ -48,7 +48,6 @@ void UuidTest::save() int n = db.saveChanges(); TOC(); - TOC(); QTEST_ASSERT(n == 1); } From c4e1b6198442e52622140edc601ad353af4e3a7d Mon Sep 17 00:00:00 2001 From: Hamed Masafi Date: Wed, 19 Jun 2019 11:27:49 +0430 Subject: [PATCH 5/5] serializer updated to latest version [skip ci] --- 3rdparty/serializer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/serializer b/3rdparty/serializer index e2d8a72..f9d81fc 160000 --- a/3rdparty/serializer +++ b/3rdparty/serializer @@ -1 +1 @@ -Subproject commit e2d8a726ef1396c47bf35347ea8b55ca47c6af3b +Subproject commit f9d81fcc6244271b3926891b0c86554e1e6b967e