parent
e70f68dfab
commit
424ecf7683
|
|
@ -1,3 +1,6 @@
|
|||
[submodule "src/nut/3rdparty/serializer"]
|
||||
path = src/nut/3rdparty/serializer
|
||||
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:
|
||||
|
||||
//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) \
|
||||
Q_PROPERTY(type name READ read WRITE write) \
|
||||
NUT_INFO(__nut_FIELD, name, 0) \
|
||||
|
|
@ -113,7 +124,7 @@ public slots: \
|
|||
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) \
|
||||
public: \
|
||||
QVariant primaryValue() const override { \
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ HEADERS += \
|
|||
$$PWD/changelogtable.h \
|
||||
$$PWD/database.h \
|
||||
$$PWD/database_p.h \
|
||||
$$PWD/propertysignalmapper.h \
|
||||
$$PWD/query.h \
|
||||
$$PWD/table.h \
|
||||
$$PWD/table_p.h \
|
||||
|
|
@ -18,6 +19,7 @@ SOURCES += \
|
|||
$$PWD/bulkinserter.cpp \
|
||||
$$PWD/changelogtable.cpp \
|
||||
$$PWD/database.cpp \
|
||||
$$PWD/propertysignalmapper.cpp \
|
||||
$$PWD/query.cpp \
|
||||
$$PWD/table.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 "abstractsqlgenerator.h"
|
||||
#include "abstracttableset.h"
|
||||
#include "propertysignalmapper.h"
|
||||
|
||||
NUT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -149,6 +150,17 @@ bool Table::setParentTable(Table *master, TableModel *masterModel, TableModel *m
|
|||
return false;
|
||||
}
|
||||
|
||||
void Table::propertyChanged()
|
||||
{
|
||||
auto pname = PropertySignalMapper::changedProperty(this, senderSignalIndex());
|
||||
propertyChanged(pname);
|
||||
}
|
||||
|
||||
void Table::init()
|
||||
{
|
||||
PropertySignalMapper::map(this);
|
||||
}
|
||||
|
||||
AbstractTableSet *Table::parentTableSet() const
|
||||
{
|
||||
//Q_D(const Table);
|
||||
|
|
|
|||
|
|
@ -72,11 +72,15 @@ public:
|
|||
signals:
|
||||
|
||||
public slots:
|
||||
void propertyChanged();
|
||||
|
||||
protected:
|
||||
void init();
|
||||
void propertyChanged(const QString &propName);
|
||||
|
||||
private:
|
||||
bool _is_signals_mapped{false};
|
||||
|
||||
void setModel(TableModel *model);
|
||||
// TableModel *myModel;
|
||||
// Status _status;
|
||||
|
|
@ -94,6 +98,7 @@ private:
|
|||
template<class T>
|
||||
friend class TableSet;
|
||||
friend class AbstractTableSet;
|
||||
friend class PropertySignalMapper;
|
||||
};
|
||||
|
||||
NUT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ public:
|
|||
explicit TableSet(Database *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(RowList<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);
|
||||
}
|
||||
|
||||
#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>
|
||||
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(Row<T> t)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ SUBDIRS += \
|
|||
tst_benckmark \
|
||||
tst_datatypes \
|
||||
tst_phrases \
|
||||
tst_properties \
|
||||
tst_quuid \
|
||||
tst_generators \
|
||||
tst_upgrades \
|
||||
|
|
|
|||
|
|
@ -4,7 +4,64 @@
|
|||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -15,17 +15,44 @@ class Comment : public Table
|
|||
{
|
||||
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_DECLARE_FIELD(int, id, id, setId)
|
||||
NUT_DECLARE_FIELD(QString, message, message, setMessage)
|
||||
NUT_DECLARE_FIELD(QDateTime, saveDate, saveDate, setSaveDate)
|
||||
NUT_DECLARE_FIELD(qreal, point, point, setPoint)
|
||||
NUT_FIELD(int, id)
|
||||
NUT_FIELD(QString, message)
|
||||
NUT_FIELD(QDateTime, saveDate)
|
||||
NUT_FIELD(qreal, point)
|
||||
|
||||
NUT_FOREIGN_KEY_DECLARE(Post, int, post, post, setPost)
|
||||
NUT_FOREIGN_KEY_DECLARE(User, int, author, author, setAuthor)
|
||||
|
||||
int m_id;
|
||||
QString m_message;
|
||||
QDateTime m_saveDate;
|
||||
qreal m_point;
|
||||
|
||||
public:
|
||||
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*)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,77 @@ Post::Post(QObject *parent) : Table(parent),
|
|||
m_comments(new TableSet<Comment>(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)
|
||||
|
|
|
|||
|
|
@ -17,27 +17,55 @@ class Post : public Table
|
|||
{
|
||||
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_DECLARE_FIELD(int, id, id, setId)
|
||||
NUT_FIELD(int, id)
|
||||
|
||||
NUT_NOT_NULL(title)
|
||||
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_DECLARE_FIELD(bool, isPublic, isPublic, setPublic)
|
||||
NUT_FIELD(QString, body)
|
||||
NUT_FIELD(bool, isPublic)
|
||||
|
||||
NUT_DECLARE_CHILD_TABLE(Comment, comments)
|
||||
NUT_DECLARE_CHILD_TABLE(Score, scores)
|
||||
|
||||
int m_id;
|
||||
QString m_title;
|
||||
QDateTime m_saveDate;
|
||||
QString m_body;
|
||||
bool m_isPublic;
|
||||
|
||||
public:
|
||||
Q_INVOKABLE Post(QObject *parentTableSet = nullptr);
|
||||
|
||||
int id() const;
|
||||
QString title() const;
|
||||
QDateTime saveDate() const;
|
||||
QString body() const;
|
||||
bool isPublic() const;
|
||||
|
||||
signals:
|
||||
void idChanged(int id);
|
||||
void titleChanged(QString title);
|
||||
void saveDateChanged(QDateTime saveDate);
|
||||
void bodyChanged(QString body);
|
||||
void isPublicChanged(bool isPublic);
|
||||
|
||||
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*)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,49 @@ User::User(QObject *tableSet) : Table(tableSet),
|
|||
m_comments(new TableSet<Comment>(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)
|
||||
|
|
|
|||
|
|
@ -17,22 +17,44 @@ class User : public Nut::Table
|
|||
{
|
||||
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_DECLARE_FIELD(int, id, id, setId)
|
||||
NUT_FIELD(int, id)
|
||||
|
||||
NUT_NOT_NULL(username)
|
||||
NUT_LEN(username, 50)
|
||||
NUT_DECLARE_FIELD(QString, username, username, setUsername)
|
||||
NUT_FIELD(QString, username)
|
||||
|
||||
NUT_NOT_NULL(password)
|
||||
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(Score, scores)
|
||||
|
||||
int m_id;
|
||||
QString m_username;
|
||||
QString m_password;
|
||||
|
||||
public:
|
||||
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*)
|
||||
|
|
|
|||
|
|
@ -139,16 +139,16 @@ void BasicTest::updatePostOnTheFly()
|
|||
|
||||
void BasicTest::selectPublicts()
|
||||
{
|
||||
auto q = db.posts()->query()
|
||||
auto publinPostsCount = db.posts()->query()
|
||||
.where(Post::isPublicField())
|
||||
.count();
|
||||
|
||||
auto q2 = db.posts()->query()
|
||||
auto nonPublicPostsCount = db.posts()->query()
|
||||
.where(!Post::isPublicField())
|
||||
.count();
|
||||
|
||||
QCOMPARE(q, 1);
|
||||
QCOMPARE(q2, 1);
|
||||
QCOMPARE(publinPostsCount, 1);
|
||||
QCOMPARE(nonPublicPostsCount, 1);
|
||||
}
|
||||
|
||||
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