parent
e70f68dfab
commit
424ecf7683
|
|
@ -1,3 +1,6 @@
|
||||||
[submodule "src/nut/3rdparty/serializer"]
|
[submodule "src/nut/3rdparty/serializer"]
|
||||||
path = src/nut/3rdparty/serializer
|
path = src/nut/3rdparty/serializer
|
||||||
url = https://github.com/HamedMasafi/Serializer.git
|
url = https://github.com/HamedMasafi/Serializer.git
|
||||||
|
[submodule "3rdparty/serializer"]
|
||||||
|
path = 3rdparty/serializer
|
||||||
|
url = https://github.com/HamedMasafi/Serializer.git
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 0e794d6317595d077e95e8a06f1f3a8c92543b05
|
||||||
|
|
@ -28,6 +28,17 @@
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//Table
|
//Table
|
||||||
|
#define NUT_FIELD(type, name) \
|
||||||
|
private: \
|
||||||
|
NUT_INFO(__nut_FIELD, name, 0) \
|
||||||
|
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; \
|
||||||
|
}
|
||||||
|
|
||||||
#define NUT_DECLARE_FIELD(type, name, read, write) \
|
#define NUT_DECLARE_FIELD(type, name, read, write) \
|
||||||
Q_PROPERTY(type name READ read WRITE write) \
|
Q_PROPERTY(type name READ read WRITE write) \
|
||||||
NUT_INFO(__nut_FIELD, name, 0) \
|
NUT_INFO(__nut_FIELD, name, 0) \
|
||||||
|
|
@ -113,7 +124,7 @@ public slots: \
|
||||||
return m_##n; \
|
return m_##n; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUT_FIELD(name) NUT_INFO(__nut_FIELD, name, 0)
|
//#define NUT_FIELD(name) NUT_INFO(__nut_FIELD, name, 0)
|
||||||
#define NUT_PRIMARY_KEY(x) NUT_INFO(__nut_PRIMARY_KEY, x, 0) \
|
#define NUT_PRIMARY_KEY(x) NUT_INFO(__nut_PRIMARY_KEY, x, 0) \
|
||||||
public: \
|
public: \
|
||||||
QVariant primaryValue() const override { \
|
QVariant primaryValue() const override { \
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ HEADERS += \
|
||||||
$$PWD/changelogtable.h \
|
$$PWD/changelogtable.h \
|
||||||
$$PWD/database.h \
|
$$PWD/database.h \
|
||||||
$$PWD/database_p.h \
|
$$PWD/database_p.h \
|
||||||
|
$$PWD/propertysignalmapper.h \
|
||||||
$$PWD/query.h \
|
$$PWD/query.h \
|
||||||
$$PWD/table.h \
|
$$PWD/table.h \
|
||||||
$$PWD/table_p.h \
|
$$PWD/table_p.h \
|
||||||
|
|
@ -18,6 +19,7 @@ SOURCES += \
|
||||||
$$PWD/bulkinserter.cpp \
|
$$PWD/bulkinserter.cpp \
|
||||||
$$PWD/changelogtable.cpp \
|
$$PWD/changelogtable.cpp \
|
||||||
$$PWD/database.cpp \
|
$$PWD/database.cpp \
|
||||||
|
$$PWD/propertysignalmapper.cpp \
|
||||||
$$PWD/query.cpp \
|
$$PWD/query.cpp \
|
||||||
$$PWD/table.cpp \
|
$$PWD/table.cpp \
|
||||||
$$PWD/tableset.cpp
|
$$PWD/tableset.cpp
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "propertysignalmapper.h"
|
||||||
|
#include "table.h"
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
QMap<QString, PropertySignalMapper::ClassData*> PropertySignalMapper::_data;
|
||||||
|
|
||||||
|
void PropertySignalMapper::map(Table *obj)
|
||||||
|
{
|
||||||
|
if (obj->_is_signals_mapped)
|
||||||
|
return;
|
||||||
|
ClassData *d;
|
||||||
|
const QMetaObject *mo = obj->metaObject();
|
||||||
|
auto className = QString::fromUtf8(mo->className());
|
||||||
|
|
||||||
|
if (_data.contains(className)) {
|
||||||
|
d = _data.value(className);
|
||||||
|
|
||||||
|
for (auto &p: d->properties)
|
||||||
|
QObject::connect(obj, p.notifySignal(), obj, d->propertyChanged);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
d = new ClassData;
|
||||||
|
d->propertyChanged = mo->method(mo->indexOfSlot("propertyChanged()"));
|
||||||
|
|
||||||
|
for (int i = 0; i < mo->propertyCount(); ++i) {
|
||||||
|
QMetaProperty p = mo->property(i);
|
||||||
|
if (!strcmp(p.name(), "objectName"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (p.hasNotifySignal()) {
|
||||||
|
d->signalMaps.insert(QLatin1String(p.notifySignal().name()),
|
||||||
|
QLatin1String(p.name()));
|
||||||
|
d->properties.append(p);
|
||||||
|
QObject::connect(obj, p.notifySignal(), obj, d->propertyChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_data.insert(className, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->_is_signals_mapped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PropertySignalMapper::changedProperty(QObject *obj, int senderSignalIndex)
|
||||||
|
{
|
||||||
|
return _data.value(QString::fromUtf8(obj->metaObject()->className()))
|
||||||
|
->signalMaps.value(
|
||||||
|
QString::fromUtf8(obj->metaObject()->method(senderSignalIndex).name())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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 <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef PROPERTYSIGNALMAPPER_H
|
||||||
|
#define PROPERTYSIGNALMAPPER_H
|
||||||
|
|
||||||
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
|
#include <QMetaMethod>
|
||||||
|
#include <QMetaProperty>
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class Table;
|
||||||
|
class PropertySignalMapper
|
||||||
|
{
|
||||||
|
struct ClassData
|
||||||
|
{
|
||||||
|
QMetaMethod propertyChanged;
|
||||||
|
QList<QMetaProperty> properties;
|
||||||
|
QMap<QString, QString> signalMaps;
|
||||||
|
};
|
||||||
|
static QMap<QString, ClassData*> _data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void map(Table *obj);
|
||||||
|
static QString changedProperty(QObject *obj, int senderSignalIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // PROPERTYSIGNALMAPPER_H
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include "databasemodel.h"
|
#include "databasemodel.h"
|
||||||
#include "abstractsqlgenerator.h"
|
#include "abstractsqlgenerator.h"
|
||||||
#include "abstracttableset.h"
|
#include "abstracttableset.h"
|
||||||
|
#include "propertysignalmapper.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -149,6 +150,17 @@ bool Table::setParentTable(Table *master, TableModel *masterModel, TableModel *m
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Table::propertyChanged()
|
||||||
|
{
|
||||||
|
auto pname = PropertySignalMapper::changedProperty(this, senderSignalIndex());
|
||||||
|
propertyChanged(pname);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Table::init()
|
||||||
|
{
|
||||||
|
PropertySignalMapper::map(this);
|
||||||
|
}
|
||||||
|
|
||||||
AbstractTableSet *Table::parentTableSet() const
|
AbstractTableSet *Table::parentTableSet() const
|
||||||
{
|
{
|
||||||
//Q_D(const Table);
|
//Q_D(const Table);
|
||||||
|
|
|
||||||
|
|
@ -72,11 +72,15 @@ public:
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void propertyChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void init();
|
||||||
void propertyChanged(const QString &propName);
|
void propertyChanged(const QString &propName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool _is_signals_mapped{false};
|
||||||
|
|
||||||
void setModel(TableModel *model);
|
void setModel(TableModel *model);
|
||||||
// TableModel *myModel;
|
// TableModel *myModel;
|
||||||
// Status _status;
|
// Status _status;
|
||||||
|
|
@ -94,6 +98,7 @@ private:
|
||||||
template<class T>
|
template<class T>
|
||||||
friend class TableSet;
|
friend class TableSet;
|
||||||
friend class AbstractTableSet;
|
friend class AbstractTableSet;
|
||||||
|
friend class PropertySignalMapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,10 @@ public:
|
||||||
explicit TableSet(Database *parent);
|
explicit TableSet(Database *parent);
|
||||||
explicit TableSet(Table *parent);
|
explicit TableSet(Table *parent);
|
||||||
|
|
||||||
|
#ifndef NUT_RAW_POINTER
|
||||||
|
void append(T *t);
|
||||||
|
void append(QList<T*> t);
|
||||||
|
#endif
|
||||||
void append(Row<T> t);
|
void append(Row<T> t);
|
||||||
void append(RowList<T> t);
|
void append(RowList<T> t);
|
||||||
void remove(Row<T> t);
|
void remove(Row<T> t);
|
||||||
|
|
@ -113,6 +117,21 @@ Q_OUTOFLINE_TEMPLATE Row<T> TableSet<T>::operator[](int i) const
|
||||||
return at(i);
|
return at(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NUT_RAW_POINTER
|
||||||
|
template<class T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(T *t)
|
||||||
|
{
|
||||||
|
append(QSharedPointer<T>(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(QList<T*> t)
|
||||||
|
{
|
||||||
|
for (auto &table: t)
|
||||||
|
append(table);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(Row<T> t)
|
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(Row<T> t)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ SUBDIRS += \
|
||||||
tst_benckmark \
|
tst_benckmark \
|
||||||
tst_datatypes \
|
tst_datatypes \
|
||||||
tst_phrases \
|
tst_phrases \
|
||||||
|
tst_properties \
|
||||||
tst_quuid \
|
tst_quuid \
|
||||||
tst_generators \
|
tst_generators \
|
||||||
tst_upgrades \
|
tst_upgrades \
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,64 @@
|
||||||
|
|
||||||
Comment::Comment(QObject *parent) : Table(parent)
|
Comment::Comment(QObject *parent) : Table(parent)
|
||||||
{
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Comment::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Comment::message() const
|
||||||
|
{
|
||||||
|
return m_message;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime Comment::saveDate() const
|
||||||
|
{
|
||||||
|
return m_saveDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal Comment::point() const
|
||||||
|
{
|
||||||
|
return m_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Comment::setId(int id)
|
||||||
|
{
|
||||||
|
if (m_id == id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_id = id;
|
||||||
|
emit idChanged(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Comment::setMessage(QString message)
|
||||||
|
{
|
||||||
|
if (m_message == message)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_message = message;
|
||||||
|
emit messageChanged(m_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Comment::setSaveDate(QDateTime saveDate)
|
||||||
|
{
|
||||||
|
if (m_saveDate == saveDate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_saveDate = saveDate;
|
||||||
|
emit saveDateChanged(m_saveDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Comment::setPoint(qreal point)
|
||||||
|
{
|
||||||
|
qWarning("Floating point comparison needs context sanity check");
|
||||||
|
if (qFuzzyCompare(m_point, point))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_point = point;
|
||||||
|
emit pointChanged(m_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_FOREIGN_KEY_IMPLEMENT(Comment, Post, int, post, post, setPost)
|
NUT_FOREIGN_KEY_IMPLEMENT(Comment, Post, int, post, post, setPost)
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,44 @@ class Comment : public Table
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(int id READ id WRITE setId NOTIFY idChanged)
|
||||||
|
Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged)
|
||||||
|
Q_PROPERTY(QDateTime saveDate READ saveDate WRITE setSaveDate NOTIFY saveDateChanged)
|
||||||
|
Q_PROPERTY(qreal point READ point WRITE setPoint NOTIFY pointChanged)
|
||||||
|
|
||||||
NUT_PRIMARY_AUTO_INCREMENT(id)
|
NUT_PRIMARY_AUTO_INCREMENT(id)
|
||||||
NUT_DECLARE_FIELD(int, id, id, setId)
|
NUT_FIELD(int, id)
|
||||||
NUT_DECLARE_FIELD(QString, message, message, setMessage)
|
NUT_FIELD(QString, message)
|
||||||
NUT_DECLARE_FIELD(QDateTime, saveDate, saveDate, setSaveDate)
|
NUT_FIELD(QDateTime, saveDate)
|
||||||
NUT_DECLARE_FIELD(qreal, point, point, setPoint)
|
NUT_FIELD(qreal, point)
|
||||||
|
|
||||||
NUT_FOREIGN_KEY_DECLARE(Post, int, post, post, setPost)
|
NUT_FOREIGN_KEY_DECLARE(Post, int, post, post, setPost)
|
||||||
NUT_FOREIGN_KEY_DECLARE(User, int, author, author, setAuthor)
|
NUT_FOREIGN_KEY_DECLARE(User, int, author, author, setAuthor)
|
||||||
|
|
||||||
|
int m_id;
|
||||||
|
QString m_message;
|
||||||
|
QDateTime m_saveDate;
|
||||||
|
qreal m_point;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q_INVOKABLE explicit Comment(QObject *parentTableSet = nullptr);
|
Q_INVOKABLE explicit Comment(QObject *parentTableSet = nullptr);
|
||||||
|
|
||||||
|
int id() const;
|
||||||
|
QString message() const;
|
||||||
|
QDateTime saveDate() const;
|
||||||
|
qreal point() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setId(int id);
|
||||||
|
void setMessage(QString message);
|
||||||
|
void setSaveDate(QDateTime saveDate);
|
||||||
|
void setPoint(qreal point);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void idChanged(int id);
|
||||||
|
void messageChanged(QString message);
|
||||||
|
void saveDateChanged(QDateTime saveDate);
|
||||||
|
void pointChanged(qreal point);
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Comment*)
|
Q_DECLARE_METATYPE(Comment*)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,77 @@ Post::Post(QObject *parent) : Table(parent),
|
||||||
m_comments(new TableSet<Comment>(this)),
|
m_comments(new TableSet<Comment>(this)),
|
||||||
m_scores(new TableSet<Score>(this))
|
m_scores(new TableSet<Score>(this))
|
||||||
{
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Post::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Post::title() const
|
||||||
|
{
|
||||||
|
return m_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime Post::saveDate() const
|
||||||
|
{
|
||||||
|
return m_saveDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Post::body() const
|
||||||
|
{
|
||||||
|
return m_body;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Post::isPublic() const
|
||||||
|
{
|
||||||
|
return m_isPublic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Post::setId(int id)
|
||||||
|
{
|
||||||
|
if (m_id == id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_id = id;
|
||||||
|
emit idChanged(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Post::setTitle(QString title)
|
||||||
|
{
|
||||||
|
if (m_title == title)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_title = title;
|
||||||
|
emit titleChanged(m_title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Post::setSaveDate(QDateTime saveDate)
|
||||||
|
{
|
||||||
|
if (m_saveDate == saveDate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_saveDate = saveDate;
|
||||||
|
emit saveDateChanged(m_saveDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Post::setBody(QString body)
|
||||||
|
{
|
||||||
|
if (m_body == body)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_body = body;
|
||||||
|
emit bodyChanged(m_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Post::setPublic(bool isPublic)
|
||||||
|
{
|
||||||
|
if (m_isPublic == isPublic)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_isPublic = isPublic;
|
||||||
|
emit isPublicChanged(m_isPublic);
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_IMPLEMENT_CHILD_TABLE(Post, Comment, comments)
|
NUT_IMPLEMENT_CHILD_TABLE(Post, Comment, comments)
|
||||||
|
|
|
||||||
|
|
@ -17,27 +17,55 @@ class Post : public Table
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(int id READ id WRITE setId NOTIFY idChanged)
|
||||||
|
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
|
||||||
|
Q_PROPERTY(QDateTime saveDate READ saveDate WRITE setSaveDate NOTIFY saveDateChanged)
|
||||||
|
Q_PROPERTY(QString body READ body WRITE setBody NOTIFY bodyChanged)
|
||||||
|
Q_PROPERTY(bool isPublic READ isPublic WRITE setPublic NOTIFY isPublicChanged)
|
||||||
|
|
||||||
NUT_PRIMARY_AUTO_INCREMENT(id)
|
NUT_PRIMARY_AUTO_INCREMENT(id)
|
||||||
NUT_DECLARE_FIELD(int, id, id, setId)
|
NUT_FIELD(int, id)
|
||||||
|
|
||||||
NUT_NOT_NULL(title)
|
NUT_NOT_NULL(title)
|
||||||
NUT_LEN(title, 50)
|
NUT_LEN(title, 50)
|
||||||
NUT_DECLARE_FIELD(QString, title, title, setTitle)
|
NUT_FIELD(QString, title)
|
||||||
|
|
||||||
NUT_DECLARE_FIELD(QDateTime, saveDate, saveDate, setSaveDate)
|
NUT_FIELD(QDateTime, saveDate)
|
||||||
|
|
||||||
NUT_DECLARE_FIELD(QString, body, body, setBody)
|
NUT_FIELD(QString, body)
|
||||||
NUT_DECLARE_FIELD(bool, isPublic, isPublic, setPublic)
|
NUT_FIELD(bool, isPublic)
|
||||||
|
|
||||||
NUT_DECLARE_CHILD_TABLE(Comment, comments)
|
NUT_DECLARE_CHILD_TABLE(Comment, comments)
|
||||||
NUT_DECLARE_CHILD_TABLE(Score, scores)
|
NUT_DECLARE_CHILD_TABLE(Score, scores)
|
||||||
|
|
||||||
|
int m_id;
|
||||||
|
QString m_title;
|
||||||
|
QDateTime m_saveDate;
|
||||||
|
QString m_body;
|
||||||
|
bool m_isPublic;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q_INVOKABLE Post(QObject *parentTableSet = nullptr);
|
Q_INVOKABLE Post(QObject *parentTableSet = nullptr);
|
||||||
|
|
||||||
|
int id() const;
|
||||||
|
QString title() const;
|
||||||
|
QDateTime saveDate() const;
|
||||||
|
QString body() const;
|
||||||
|
bool isPublic() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void idChanged(int id);
|
||||||
|
void titleChanged(QString title);
|
||||||
|
void saveDateChanged(QDateTime saveDate);
|
||||||
|
void bodyChanged(QString body);
|
||||||
|
void isPublicChanged(bool isPublic);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void setId(int id);
|
||||||
|
void setTitle(QString title);
|
||||||
|
void setSaveDate(QDateTime saveDate);
|
||||||
|
void setBody(QString body);
|
||||||
|
void setPublic(bool isPublic);
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Post*)
|
Q_DECLARE_METATYPE(Post*)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,49 @@ User::User(QObject *tableSet) : Table(tableSet),
|
||||||
m_comments(new TableSet<Comment>(this)),
|
m_comments(new TableSet<Comment>(this)),
|
||||||
m_scores(new TableSet<Score>(this))
|
m_scores(new TableSet<Score>(this))
|
||||||
{
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
int User::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString User::username() const
|
||||||
|
{
|
||||||
|
return m_username;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString User::password() const
|
||||||
|
{
|
||||||
|
return m_password;
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::setId(int id)
|
||||||
|
{
|
||||||
|
if (m_id == id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_id = id;
|
||||||
|
emit idChanged(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::setUsername(QString username)
|
||||||
|
{
|
||||||
|
if (m_username == username)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_username = username;
|
||||||
|
emit usernameChanged(m_username);
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::setPassword(QString password)
|
||||||
|
{
|
||||||
|
if (m_password == password)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_password = password;
|
||||||
|
emit passwordChanged(m_password);
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_IMPLEMENT_CHILD_TABLE(User, Comment, comments)
|
NUT_IMPLEMENT_CHILD_TABLE(User, Comment, comments)
|
||||||
|
|
|
||||||
|
|
@ -17,22 +17,44 @@ class User : public Nut::Table
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(int id READ id WRITE setId NOTIFY idChanged)
|
||||||
|
Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged)
|
||||||
|
Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged)
|
||||||
|
|
||||||
NUT_PRIMARY_AUTO_INCREMENT(id)
|
NUT_PRIMARY_AUTO_INCREMENT(id)
|
||||||
NUT_DECLARE_FIELD(int, id, id, setId)
|
NUT_FIELD(int, id)
|
||||||
|
|
||||||
NUT_NOT_NULL(username)
|
NUT_NOT_NULL(username)
|
||||||
NUT_LEN(username, 50)
|
NUT_LEN(username, 50)
|
||||||
NUT_DECLARE_FIELD(QString, username, username, setUsername)
|
NUT_FIELD(QString, username)
|
||||||
|
|
||||||
NUT_NOT_NULL(password)
|
NUT_NOT_NULL(password)
|
||||||
NUT_LEN(password, 50)
|
NUT_LEN(password, 50)
|
||||||
NUT_DECLARE_FIELD(QString, password, password, setPassword)
|
NUT_FIELD(QString, password)
|
||||||
|
|
||||||
NUT_DECLARE_CHILD_TABLE(Comment, comments)
|
NUT_DECLARE_CHILD_TABLE(Comment, comments)
|
||||||
NUT_DECLARE_CHILD_TABLE(Score, scores)
|
NUT_DECLARE_CHILD_TABLE(Score, scores)
|
||||||
|
|
||||||
|
int m_id;
|
||||||
|
QString m_username;
|
||||||
|
QString m_password;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q_INVOKABLE User(QObject *parentTableSet = nullptr);
|
Q_INVOKABLE User(QObject *parentTableSet = nullptr);
|
||||||
|
|
||||||
|
int id() const;
|
||||||
|
QString username() const;
|
||||||
|
QString password() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setId(int id);
|
||||||
|
void setUsername(QString username);
|
||||||
|
void setPassword(QString password);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void idChanged(int id);
|
||||||
|
void usernameChanged(QString username);
|
||||||
|
void passwordChanged(QString password);
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(User*)
|
Q_DECLARE_METATYPE(User*)
|
||||||
|
|
|
||||||
|
|
@ -139,16 +139,16 @@ void BasicTest::updatePostOnTheFly()
|
||||||
|
|
||||||
void BasicTest::selectPublicts()
|
void BasicTest::selectPublicts()
|
||||||
{
|
{
|
||||||
auto q = db.posts()->query()
|
auto publinPostsCount = db.posts()->query()
|
||||||
.where(Post::isPublicField())
|
.where(Post::isPublicField())
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
auto q2 = db.posts()->query()
|
auto nonPublicPostsCount = db.posts()->query()
|
||||||
.where(!Post::isPublicField())
|
.where(!Post::isPublicField())
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
QCOMPARE(q, 1);
|
QCOMPARE(publinPostsCount, 1);
|
||||||
QCOMPARE(q2, 1);
|
QCOMPARE(nonPublicPostsCount, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicTest::selectPosts()
|
void BasicTest::selectPosts()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include "sampledatabase.h"
|
||||||
|
#include "sampletable.h"
|
||||||
|
|
||||||
|
SampleDataBase::SampleDataBase() : Nut::Database()
|
||||||
|
, m_items(new Nut::TableSet<SampleTable>(this))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef SAMPLEDATABASE_H
|
||||||
|
#define SAMPLEDATABASE_H
|
||||||
|
|
||||||
|
#include <QtNut/Database>
|
||||||
|
|
||||||
|
class SampleTable;
|
||||||
|
class SampleDataBase : public Nut::Database
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
NUT_DB_VERSION(1)
|
||||||
|
NUT_DECLARE_TABLE(SampleTable, items)
|
||||||
|
|
||||||
|
public:
|
||||||
|
SampleDataBase();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SAMPLEDATABASE_H
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include "sampletable.h"
|
||||||
|
|
||||||
|
SampleTable::SampleTable(QObject *parent) : Nut::Table(parent)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SampleTable::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SampleTable::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SampleTable::lastName() const
|
||||||
|
{
|
||||||
|
return m_lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SampleTable::setId(int id)
|
||||||
|
{
|
||||||
|
if (m_id == id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_id = id;
|
||||||
|
emit idChanged(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SampleTable::setName(QString name)
|
||||||
|
{
|
||||||
|
if (m_name == name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_name = name;
|
||||||
|
emit nameChanged(m_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SampleTable::setLastName(QString lastName)
|
||||||
|
{
|
||||||
|
if (m_lastName == lastName)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_lastName = lastName;
|
||||||
|
emit lastNameChanged(m_lastName);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef SAMPLETABLE_H
|
||||||
|
#define SAMPLETABLE_H
|
||||||
|
|
||||||
|
#include <QtNut/table.h>
|
||||||
|
|
||||||
|
class SampleTable : public Nut::Table
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int id READ id WRITE setId NOTIFY idChanged)
|
||||||
|
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
|
||||||
|
Q_PROPERTY(QString lastName READ lastName WRITE setLastName NOTIFY lastNameChanged)
|
||||||
|
|
||||||
|
int m_id;
|
||||||
|
QString m_name;
|
||||||
|
QString m_lastName;
|
||||||
|
|
||||||
|
NUT_PRIMARY_KEY(id)
|
||||||
|
NUT_FIELD(int, id)
|
||||||
|
NUT_FIELD(QString, name)
|
||||||
|
NUT_FIELD(QString, lastName)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SampleTable(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
int id() const;
|
||||||
|
QString name() const;
|
||||||
|
QString lastName() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setId(int id);
|
||||||
|
void setName(QString name);
|
||||||
|
void setLastName(QString lastName);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void idChanged(int id);
|
||||||
|
void nameChanged(QString name);
|
||||||
|
void lastNameChanged(QString lastName);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SAMPLETABLE_H
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include <QtTest>
|
||||||
|
#include "tst_properties.h"
|
||||||
|
#include "sampledatabase.h"
|
||||||
|
#include "sampletable.h"
|
||||||
|
#include "../common/consts.h"
|
||||||
|
#include <QtNut/Query>
|
||||||
|
|
||||||
|
PropertiesTest::PropertiesTest(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertiesTest::initTestCase()
|
||||||
|
{
|
||||||
|
|
||||||
|
REGISTER(SampleTable);
|
||||||
|
REGISTER(SampleDataBase);
|
||||||
|
|
||||||
|
db.setDriver(DRIVER);
|
||||||
|
db.setHostName(HOST);
|
||||||
|
db.setDatabaseName(DATABASE);
|
||||||
|
db.setUserName(USERNAME);
|
||||||
|
db.setPassword(PASSWORD);
|
||||||
|
|
||||||
|
bool ok = db.open();
|
||||||
|
QVERIFY(ok);
|
||||||
|
|
||||||
|
db.items()->query().remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertiesTest::insert()
|
||||||
|
{
|
||||||
|
auto s = new SampleTable;
|
||||||
|
s->setId(1);
|
||||||
|
s->setName("hamed");
|
||||||
|
s->setLastName("masafi");
|
||||||
|
db.items()->append(s);
|
||||||
|
auto c = db.saveChanges();
|
||||||
|
QCOMPARE(c, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertiesTest::select()
|
||||||
|
{
|
||||||
|
auto item = db.items()->query()
|
||||||
|
.first();
|
||||||
|
QCOMPARE(item->name(), "hamed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertiesTest::parallelUpdate()
|
||||||
|
{
|
||||||
|
auto item1 = db.items()->query()
|
||||||
|
.first();
|
||||||
|
{
|
||||||
|
auto item2 = db.items()->query()
|
||||||
|
.first();
|
||||||
|
|
||||||
|
item2->setLastName("masafi 2");
|
||||||
|
db.saveChanges();
|
||||||
|
}
|
||||||
|
item1->setName("hamed 2");
|
||||||
|
db.saveChanges();
|
||||||
|
|
||||||
|
auto item = db.items()->query()
|
||||||
|
.first();
|
||||||
|
|
||||||
|
QCOMPARE(item->name(), "hamed 2");
|
||||||
|
QCOMPARE(item->lastName(), "masafi 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(PropertiesTest)
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef TST_PROPERTIES_H
|
||||||
|
#define TST_PROPERTIES_H
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/qglobal.h>
|
||||||
|
|
||||||
|
#include "sampledatabase.h"
|
||||||
|
|
||||||
|
class PropertiesTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
SampleDataBase db;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PropertiesTest(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase();
|
||||||
|
void insert();
|
||||||
|
void select();
|
||||||
|
void parallelUpdate();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TST_PROPERTIES_H
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
QT += testlib sql
|
||||||
|
|
||||||
|
TARGET = tst_basic
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
CONFIG += warn_on c++11
|
||||||
|
|
||||||
|
include(../common/nut-lib.pri)
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
sampledatabase.cpp \
|
||||||
|
sampletable.cpp \
|
||||||
|
tst_properties.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
sampledatabase.h \
|
||||||
|
sampletable.h \
|
||||||
|
tst_properties.h
|
||||||
|
|
||||||
Loading…
Reference in New Issue