some shared pointer [skip ci]

This commit is contained in:
Hamed Masafi 2019-06-18 20:41:14 +04:30
parent a9bcc76663
commit b3193cf1c6
11 changed files with 276 additions and 83 deletions

View File

@ -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"

1
include/SqlModel Normal file
View File

@ -0,0 +1 @@
#include "../src/sqlmodel.h"

1
include/TableModel Normal file
View File

@ -0,0 +1 @@
#include "../src/tablemodel.h"

4
include/header_copier Normal file → Executable file
View File

@ -6,8 +6,7 @@ namespace_name="nut"
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
@ -38,5 +37,6 @@ while read line; do
echo "#include \"../$src_dir/$header.h\"" >> "$Ns"
echo "#include \"../$src_dir/$header.h\"" >> "$ns.h"
fi
echo $Ns
done <&3
exec 3<&-

View File

@ -1,6 +1,7 @@
#include "../src/table.h"
#include "../src/database.h"
#include "../src/sqlmodel.h"
#include "../src/tableset.h"
#include "../src/dbgeography.h"
#include "../src/tablemodel.h"
#include "../src/query.h"

1
include/sqlmodel.h Normal file
View File

@ -0,0 +1 @@
#include "../src/sqlmodel.h"

1
include/tablemodel.h Normal file
View File

@ -0,0 +1 @@
#include "../src/tablemodel.h"

View File

@ -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<type>) name READ name) \
NUT_WRAP_NAMESPACE(TableSet<type>) *m_##name; \
public: \
static const type *_##name; \
NUT_WRAP_NAMESPACE(TableSet<type>) *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<type>)& name ## Field(){ \
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) f = \
NUT_WRAP_NAMESPACE(FieldPhrase<type>) \
(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<type> name READ read WRITE write) \
NUT_DECLARE_FIELD(keytype, name##Id, read##Id, write##Id) \
NUT_INFO(__nut_FOREGION_KEY, name, type) \
Nut::Row<type> m_##name; \
public: \
Nut::Row<type> read() const { return m_##name ; } \
void write(Nut::Row<type> name){ \
m_##name = name; \
}
#define NUT_DECLARE_CHILD_TABLE(type, n) \
private: \
NUT_WRAP_NAMESPACE(TableSet)<type> *m_##n; \
public: \
static type *n##Table(); \
NUT_WRAP_NAMESPACE(TableSet)<type> *n();
#define NUT_IMPLEMENT_CHILD_TABLE(class, type, n) \
type *class::n##Table(){ \
static auto f = new type(); \
return f; \
} \
NUT_WRAP_NAMESPACE(TableSet)<type> *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,79 +194,37 @@ inline bool nutClassInfoInt(const QMetaClassInfo &classInfo,
}
}
#define NUT_FIELD_PERFIX
#define NUT_FIELD_POSTFIX Field
#ifdef NUT_SHARED_POINTER
template <class T>
using RowList = QList<QSharedPointer<T>>;
// Database
#define NUT_DB_VERSION(version) \
NUT_INFO(__nut_DB_VERSION, version, 0)
template <class T>
using RowSet = QSet<QSharedPointer<T>>;
#define NUT_DECLARE_TABLE(type, name) \
NUT_INFO(__nut_TABLE, type, name) \
Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet<type>) name READ name) \
NUT_WRAP_NAMESPACE(TableSet<type>) *m_##name; \
public: \
static const type *_##name; \
NUT_WRAP_NAMESPACE(TableSet<type>) *name() const \
{ return m_##name; } \
private:
template <typename T>
using Row = QSharedPointer<T>;
//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<type>)& name ## Field(){ \
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) f = \
NUT_WRAP_NAMESPACE(FieldPhrase<type>) \
(staticMetaObject.className(), #name); \
return f; \
} \
type read() const{ \
return m_##name; \
} \
void write(type name){ \
m_##name = name; \
propertyChanged(#name); \
}
template<class T>
inline Row<T> create() {
return QSharedPointer<T>(new T);
}
#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; \
}
#else
template <typename T>
using RowList = QList<T*>;
#define NUT_DECLARE_CHILD_TABLE(type, n) \
private: \
NUT_WRAP_NAMESPACE(TableSet)<type> *m_##n; \
public: \
static type *n##Table(); \
NUT_WRAP_NAMESPACE(TableSet)<type> *n();
template <typename T>
using RowSet = QSet<T*>;
#define NUT_IMPLEMENT_CHILD_TABLE(class, type, n) \
type *class::n##Table(){ \
static auto f = new type(); \
return f; \
} \
NUT_WRAP_NAMESPACE(TableSet)<type> *class::n(){ \
return m_##n; \
}
template <typename T>
using Row = T*;
#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)
template<class T>
inline Row<T> create() {
return new T;
}
#endif
NUT_END_NAMESPACE
#endif // SYNTAX_DEFINES_H

View File

@ -29,7 +29,11 @@
#include <QtSql/QSqlResult>
#include <QtSql/QSqlError>
#include <QtSql/QSqlQueryModel>
#include <QSqlQuery>
#include <QtSql/QSqlQuery>
#ifdef NUT_SHARED_POINTER
#include <QtCore/QSharedPointer>
#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 <class T>
bool m_autoDelete;
public:
//#ifdef NUT_SHARED_POINTER
// typedef QList<QSharedPointer<T>> RowList;
// typedef QSharedPointer<T> Row;
//#else
// typedef QList<T*> RowList;
// typedef T* Row;
//#endif
explicit Query(Database *database, TableSetBase *tableSet, bool autoDelete);
~Query();
@ -76,8 +89,8 @@ public:
Query<T> *setWhere(const ConditionalPhrase &ph);
//data selecting
T *first();
QList<T*> toList(int count = -1);
Row<T> first();
RowList<T> toList(int count = -1);
template <typename F>
QList<F> select(const FieldPhrase<F> 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<T>::~Query()
}
template <class T>
Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
{
Q_UNUSED(count);
Q_D(Query);
QList<T*> returnList;
RowList<T> returnList;
d->select = "*";
d->sql = d->database->sqlGenertor()->selectCommand(
@ -285,13 +299,17 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::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<T>(qobject_cast<T*>(table));
returnList.append(shp);
#else
returnList.append(dynamic_cast<T*>(table));
#endif
table->setParentTableSet(d->tableSet);
} else {
const QMetaObject *childMetaObject
= QMetaType::metaObjectForType(data.table->typeId());
table = qobject_cast<Table *>(childMetaObject->newInstance());
if (!table)
qFatal("Could not create instance of %s",
qPrintable(data.table->name()));
@ -323,8 +341,11 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::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<F> Query<T>::select(const FieldPhrase<F> f)
}
template <class T>
Q_OUTOFLINE_TEMPLATE T *Query<T>::first()
Q_OUTOFLINE_TEMPLATE Row<T> Query<T>::first()
{
skip(0);
take(1);
QList<T*> list = toList(1);
RowList<T> list = toList(1);
if (list.count())
return list.first();
@ -617,6 +638,43 @@ Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(QSqlQueryModel *model)
}
}
template<class T>
Q_OUTOFLINE_TEMPLATE void Query<T>::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 <class T>
Q_OUTOFLINE_TEMPLATE QString Query<T>::sqlCommand() const
{

View File

@ -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<QVariant (int, QVariant)> &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());
Row<Table> 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(RowList<Table> 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(Row<Table> table)
{
Q_D(SqlModel);
beginInsertRows(QModelIndex(), d->rows.count(), d->rows.count());
d->rows.append(table);
endInsertRows();
}
//void SqlModel::append(Table *table)
//{
// append(TableType<Table>::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

View File

@ -23,6 +23,8 @@
#include <QtCore/QAbstractTableModel>
#include "defines.h"
#include <QList>
#include <functional>
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 <QVariant(int, QVariant)> _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<class T>
void setTable(RowList<T> rows);
void setRows(RowList<Table> rows);
void append(Row<Table> 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<QVariant (int, QVariant)> &renderer);
private:
SqlModelPrivate *d_ptr;
Q_DECLARE_PRIVATE(SqlModel)
signals:
void beforeShowText(int col, QVariant &value);
};
template<class T>
Q_OUTOFLINE_TEMPLATE void SqlModel::setTable(RowList<T> rows)
{
Q_D(SqlModel);
RowList<Table> tab;
foreach (auto t, rows)
tab.append(t);
setRows(tab);
}
NUT_END_NAMESPACE
#endif // SQLMODEL_H