Merge branch 'dev' of https://github.com/HamedMasafi/Nut into dev
This commit is contained in:
commit
9626e5f863
|
|
@ -1 +1 @@
|
||||||
QT -= gui
|
#QT -= gui
|
||||||
|
|
|
||||||
|
|
@ -625,6 +625,12 @@ void Database::add(TableSetBase *t)
|
||||||
int Database::saveChanges(bool cleanUp)
|
int Database::saveChanges(bool cleanUp)
|
||||||
{
|
{
|
||||||
Q_D(Database);
|
Q_D(Database);
|
||||||
|
|
||||||
|
if (!d->db.isOpen()) {
|
||||||
|
qWarning("Database is not open");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int rowsAffected = 0;
|
int rowsAffected = 0;
|
||||||
foreach (TableSetBase *ts, d->tableSets)
|
foreach (TableSetBase *ts, d->tableSets)
|
||||||
rowsAffected += ts->save(this, cleanUp);
|
rowsAffected += ts->save(this, cleanUp);
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ DatabaseModel::DatabaseModel(const QJsonObject &json) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TableModel *DatabaseModel::tableByName(QString tableName) const
|
TableModel *DatabaseModel::tableByName(const QString &tableName) const
|
||||||
{
|
{
|
||||||
for(int i = 0; i < size(); i++){
|
for(int i = 0; i < size(); i++){
|
||||||
TableModel *s = at(i);
|
TableModel *s = at(i);
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ public:
|
||||||
DatabaseModel(const QJsonObject &json);
|
DatabaseModel(const QJsonObject &json);
|
||||||
~DatabaseModel() = default;
|
~DatabaseModel() = default;
|
||||||
|
|
||||||
TableModel *tableByName(QString tableName) const;
|
TableModel *tableByName(const QString &tableName) const;
|
||||||
TableModel *tableByClassName(QString className) const;
|
TableModel *tableByClassName(QString className) const;
|
||||||
|
|
||||||
RelationModel *relationByClassNames(const QString &masterClassName,
|
RelationModel *relationByClassNames(const QString &masterClassName,
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ QString SqlGeneratorBase::fieldDeclare(FieldModel *field)
|
||||||
|
|
||||||
QStringList SqlGeneratorBase::constraints(TableModel *table)
|
QStringList SqlGeneratorBase::constraints(TableModel *table)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(table);
|
||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -439,7 +440,8 @@ QString SqlGeneratorBase::join(const QStringList &list, QStringList *order)
|
||||||
QString SqlGeneratorBase::insertRecord(Table *t, QString tableName)
|
QString SqlGeneratorBase::insertRecord(Table *t, QString tableName)
|
||||||
{
|
{
|
||||||
QString sql = QString();
|
QString sql = QString();
|
||||||
TableModel *model = _database->model().tableByName(tableName);
|
auto model = _database->model().tableByName(tableName);
|
||||||
|
|
||||||
QString key = model->isPrimaryKeyAutoIncrement() ? model->primaryKey() : QString();
|
QString key = model->isPrimaryKeyAutoIncrement() ? model->primaryKey() : QString();
|
||||||
|
|
||||||
QStringList values;
|
QStringList values;
|
||||||
|
|
|
||||||
|
|
@ -61,3 +61,6 @@ SOURCES += \
|
||||||
$$PWD/phrases/phrasedatalist.cpp \
|
$$PWD/phrases/phrasedatalist.cpp \
|
||||||
$$PWD/phrases/phraselist.cpp \
|
$$PWD/phrases/phraselist.cpp \
|
||||||
$$PWD/phrases/datephrase.cpp
|
$$PWD/phrases/datephrase.cpp
|
||||||
|
|
||||||
|
|
||||||
|
include($$PWD/../3rdparty/serializer/src/src.pri)
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,4 @@ CONFIG += staticlib
|
||||||
DEFINES += QT_DEPRECATED_WARNINGS NUT_COMPILE_STATIC
|
DEFINES += QT_DEPRECATED_WARNINGS NUT_COMPILE_STATIC
|
||||||
|
|
||||||
include($$PWD/src.pri)
|
include($$PWD/src.pri)
|
||||||
include($$PWD/../3rdparty/serializer/src/src.pri)
|
|
||||||
include($$PWD/../ci-test-init.pri)
|
include($$PWD/../ci-test-init.pri)
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ Table::Table(QObject *parent) : QObject(parent),
|
||||||
{
|
{
|
||||||
Q_D(Table);
|
Q_D(Table);
|
||||||
d->status = NewCreated;
|
d->status = NewCreated;
|
||||||
|
// d->model = TableModel::findByClassName(metaObject()->className());
|
||||||
}
|
}
|
||||||
|
|
||||||
Table::~Table()
|
Table::~Table()
|
||||||
|
|
@ -122,6 +123,9 @@ bool Table::setParentTable(Table *master)
|
||||||
QString masterClassName = master->metaObject()->className();
|
QString masterClassName = master->metaObject()->className();
|
||||||
d->refreshModel();
|
d->refreshModel();
|
||||||
|
|
||||||
|
if (!d->model)
|
||||||
|
d->model = TableModel::findByClassName(metaObject()->className());
|
||||||
|
|
||||||
foreach (RelationModel *r, d->model->foregionKeys())
|
foreach (RelationModel *r, d->model->foregionKeys())
|
||||||
if(r->masterClassName == masterClassName)
|
if(r->masterClassName == masterClassName)
|
||||||
{
|
{
|
||||||
|
|
@ -164,8 +168,9 @@ int Table::save(Database *db)
|
||||||
|
|
||||||
QSqlQuery q = db->exec(db->sqlGenertor()->saveRecord(this, db->tableName(metaObject()->className())));
|
QSqlQuery q = db->exec(db->sqlGenertor()->saveRecord(this, db->tableName(metaObject()->className())));
|
||||||
|
|
||||||
if(status() == Added && isPrimaryKeyAutoIncrement())
|
auto model = db->model().tableByClassName(metaObject()->className());
|
||||||
setProperty(primaryKey().toLatin1().data(), q.lastInsertId());
|
if(status() == Added && model->isPrimaryKeyAutoIncrement())
|
||||||
|
setProperty(model->primaryKey().toLatin1().data(), q.lastInsertId());
|
||||||
|
|
||||||
foreach(TableSetBase *ts, d->childTableSets)
|
foreach(TableSetBase *ts, d->childTableSets)
|
||||||
ts->save(db);
|
ts->save(db);
|
||||||
|
|
@ -189,7 +194,7 @@ void Table::setStatus(const Status &status)
|
||||||
|
|
||||||
|
|
||||||
TablePrivate::TablePrivate(Table *parent) : q_ptr(parent),
|
TablePrivate::TablePrivate(Table *parent) : q_ptr(parent),
|
||||||
status(Table::NewCreated), parentTableSet(nullptr)
|
model(nullptr), status(Table::NewCreated), parentTableSet(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -300,6 +300,7 @@ TableModel::TableModel(const QJsonObject &json, const QString &tableName) : _typ
|
||||||
QJsonObject relations = json.value(__FOREIGN_KEYS).toObject();
|
QJsonObject relations = json.value(__FOREIGN_KEYS).toObject();
|
||||||
foreach (QString key, fields.keys()) {
|
foreach (QString key, fields.keys()) {
|
||||||
QJsonObject fieldObject = fields.value(key).toObject();
|
QJsonObject fieldObject = fields.value(key).toObject();
|
||||||
|
//TODO: use FieldModel(QJsonObject) ctor
|
||||||
auto *f = new FieldModel;
|
auto *f = new FieldModel;
|
||||||
f->name = fieldObject.value(__NAME).toString();
|
f->name = fieldObject.value(__NAME).toString();
|
||||||
f->type = static_cast<QMetaType::Type>(QMetaType::type(fieldObject.value(__TYPE).toString().toLatin1().data()));
|
f->type = static_cast<QMetaType::Type>(QMetaType::type(fieldObject.value(__TYPE).toString().toLatin1().data()));
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef CONSTS_H
|
#ifndef CONSTS_H
|
||||||
#define CONSTS_H
|
#define CONSTS_H
|
||||||
|
|
||||||
|
#include <qsystemdetection.h>
|
||||||
|
|
||||||
#define REGISTER(x) qDebug() << (#x) << "type id:" << qMetaTypeId<x*>()
|
#define REGISTER(x) qDebug() << (#x) << "type id:" << qMetaTypeId<x*>()
|
||||||
#define PRINT(x) qDebug() << (#x "=") << (x);
|
#define PRINT(x) qDebug() << (#x "=") << (x);
|
||||||
#define TIC() QElapsedTimer timer; timer.start()
|
#define TIC() QElapsedTimer timer; timer.start()
|
||||||
|
|
@ -11,8 +13,8 @@
|
||||||
#define DRIVER "QPSQL"
|
#define DRIVER "QPSQL"
|
||||||
#define DATABASE QString("nut_test_%1_db").arg(metaObject()->className()).toLower()
|
#define DATABASE QString("nut_test_%1_db").arg(metaObject()->className()).toLower()
|
||||||
#define HOST "127.0.0.1"
|
#define HOST "127.0.0.1"
|
||||||
#define USERNAME "postgres"
|
#define USERNAME "nut"
|
||||||
#define PASSWORD ""
|
#define PASSWORD "856856"
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
# define OS "Linux"
|
# define OS "Linux"
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
win32 {
|
win32 {
|
||||||
CONFIG(debug,debug|release): LIBDIR = $$absolute_path($$OUT_PWD/../../src/debug)
|
CONFIG(debug,debug|release): LIBDIR = $$absolute_path($$OUT_PWD/../../src/debug)
|
||||||
CONFIG(release,debug|release): LIBDIR = $$absolute_path($$OUT_PWD/../../src/release)
|
CONFIG(release,debug|release): LIBDIR = $$absolute_path($$OUT_PWD/../../src/release)
|
||||||
} else {
|
} else {
|
||||||
LIBDIR = $$absolute_path($$OUT_PWD/../../src)
|
LIBDIR = $$absolute_path($$OUT_PWD/../../src)
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBS += -L$$LIBDIR -lnut
|
#LIBS += -L$$LIBDIR -lnut
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/../../src $$PWD/../common
|
INCLUDEPATH += $$PWD/../../src $$PWD/../common
|
||||||
|
include(../../src/src.pri)
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,6 @@ SUBDIRS += \
|
||||||
tst_phrases \
|
tst_phrases \
|
||||||
tst_quuid \
|
tst_quuid \
|
||||||
tst_generators \
|
tst_generators \
|
||||||
tst_upgrades
|
tst_upgrades \
|
||||||
|
tst_json
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -274,8 +274,8 @@ void BasicTest::emptyDatabase()
|
||||||
|
|
||||||
void BasicTest::cleanupTestCase()
|
void BasicTest::cleanupTestCase()
|
||||||
{
|
{
|
||||||
post->deleteLater();
|
// post->deleteLater();
|
||||||
user->deleteLater();
|
// user->deleteLater();
|
||||||
|
|
||||||
//release models before exiting
|
//release models before exiting
|
||||||
// qDeleteAll(TableModel::allModels());
|
// qDeleteAll(TableModel::allModels());
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
QT += testlib sql
|
QT += testlib sql
|
||||||
|
|
||||||
TARGET = tst_nut
|
TARGET = tst_basic
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
|
||||||
CONFIG += warn_on c++11
|
CONFIG += warn_on c++11
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "db.h"
|
||||||
|
|
||||||
|
#include "sampletable.h"
|
||||||
|
|
||||||
|
DB::DB() : Nut::Database (),
|
||||||
|
m_sampleTable(new Nut::TableSet<Table>(this))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef DB1_H
|
||||||
|
#define DB1_H
|
||||||
|
|
||||||
|
#include "database.h"
|
||||||
|
|
||||||
|
class Table;
|
||||||
|
|
||||||
|
class DB : public Nut::Database
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
NUT_DB_VERSION(1)
|
||||||
|
|
||||||
|
NUT_DECLARE_TABLE(Table, sampleTable)
|
||||||
|
|
||||||
|
public:
|
||||||
|
DB();
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(DB*)
|
||||||
|
|
||||||
|
#endif // DB1_H
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "sampletable.h"
|
||||||
|
|
||||||
|
|
||||||
|
Table::Table(QObject *parent) : Nut::Table (parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef TABLE1_H
|
||||||
|
#define TABLE1_H
|
||||||
|
|
||||||
|
#include "table.h"
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
class Table : public Nut::Table
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
NUT_PRIMARY_AUTO_INCREMENT(id)
|
||||||
|
NUT_DECLARE_FIELD(int, id, id, setId)
|
||||||
|
|
||||||
|
NUT_DECLARE_FIELD(QJsonDocument, doc, doc, setDoc)
|
||||||
|
|
||||||
|
public:
|
||||||
|
Q_INVOKABLE Table(QObject *parent = Q_NULLPTR);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(Table*)
|
||||||
|
|
||||||
|
#endif // TABLE1_H
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include <QtTest>
|
||||||
|
|
||||||
|
#include "db.h"
|
||||||
|
#include "sampletable.h"
|
||||||
|
#include "query.h"
|
||||||
|
|
||||||
|
#include "tst_json.h"
|
||||||
|
#include "consts.h"
|
||||||
|
|
||||||
|
void TestJson::initDb(Nut::Database &db)
|
||||||
|
{
|
||||||
|
db.setDriver(DRIVER);
|
||||||
|
db.setHostName(HOST);
|
||||||
|
db.setDatabaseName(DATABASE);
|
||||||
|
db.setUserName(USERNAME);
|
||||||
|
db.setPassword(PASSWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestJson::TestJson()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TestJson::~TestJson()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestJson::initTestCase()
|
||||||
|
{
|
||||||
|
QFile::remove(DATABASE);
|
||||||
|
REGISTER(DB);
|
||||||
|
REGISTER(Table);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestJson::store()
|
||||||
|
{
|
||||||
|
DB db;
|
||||||
|
initDb(db);
|
||||||
|
|
||||||
|
db.open();
|
||||||
|
|
||||||
|
Table *t = new Table;
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson("{a: 4, b:3.14}");
|
||||||
|
t->setDoc(doc);
|
||||||
|
db.sampleTable()->append(t);
|
||||||
|
db.saveChanges(true);
|
||||||
|
|
||||||
|
// QTEST_ASSERT(db.open());
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_APPLESS_MAIN(TestJson)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef TST_TESTJSON_H
|
||||||
|
#define TST_TESTJSON_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace Nut {
|
||||||
|
class Database;
|
||||||
|
}
|
||||||
|
class TestJson : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
void initDb(Nut::Database &db);
|
||||||
|
|
||||||
|
int id;
|
||||||
|
public:
|
||||||
|
TestJson();
|
||||||
|
~TestJson();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase();
|
||||||
|
|
||||||
|
void store();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TST_TESTJSON_H
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
QT += testlib sql
|
||||||
|
|
||||||
|
TARGET = tst_upgrades
|
||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += warn_on c++11
|
||||||
|
|
||||||
|
include(../common/nut-lib.pri)
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
tst_json.cpp \
|
||||||
|
db.cpp \
|
||||||
|
sampletable.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
tst_json.h \
|
||||||
|
db.h \
|
||||||
|
sampletable.h
|
||||||
|
|
||||||
|
include($$PWD/../../ci-test-init.pri)
|
||||||
Loading…
Reference in New Issue