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; };