join test created
This commit is contained in:
parent
02037ba2b2
commit
4b0e3e4371
|
|
@ -30,17 +30,20 @@ QMap<QString, DatabaseModel*> DatabaseModel::_models;
|
||||||
|
|
||||||
#define NODE_VERSION "version"
|
#define NODE_VERSION "version"
|
||||||
#define NODE_TABLES "tables"
|
#define NODE_TABLES "tables"
|
||||||
DatabaseModel::DatabaseModel(const QString &name) : QList<TableModel*>(), _databaseClassName(name), _version(QString::null)
|
DatabaseModel::DatabaseModel(const QString &name) :
|
||||||
|
QList<TableModel*>(), _databaseClassName(name), _version(QString::null)
|
||||||
{
|
{
|
||||||
_models.insert(name, this);
|
_models.insert(name, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseModel::DatabaseModel(const DatabaseModel &other) : QList<TableModel*>(other), _version(QString::null)
|
DatabaseModel::DatabaseModel(const DatabaseModel &other) :
|
||||||
|
QList<TableModel*>(other), _version(QString::null)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseModel::DatabaseModel(const QJsonObject &json) : QList<TableModel*>()
|
DatabaseModel::DatabaseModel(const QJsonObject &json) :
|
||||||
|
QList<TableModel*>()
|
||||||
{
|
{
|
||||||
setVersion(json.value(NODE_VERSION).toString());
|
setVersion(json.value(NODE_VERSION).toString());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QueryPrivate::QueryPrivate(QueryBase *parent) : q_ptr(parent),
|
QueryPrivate::QueryPrivate(QueryBase *parent) : q_ptr(parent),
|
||||||
joinClassName(QString::null), skip(-1), take(-1)
|
skip(-1), take(-1)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
31
src/query.h
31
src/query.h
|
|
@ -128,7 +128,7 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
|
||||||
{
|
{
|
||||||
Q_UNUSED(count);
|
Q_UNUSED(count);
|
||||||
Q_D(Query);
|
Q_D(Query);
|
||||||
QList<T*> result;
|
QList<T*> returnList;
|
||||||
d->select = "*";
|
d->select = "*";
|
||||||
QElapsedTimer t;
|
QElapsedTimer t;
|
||||||
t.start();
|
t.start();
|
||||||
|
|
@ -140,22 +140,29 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
|
||||||
d->wheres, d->orderPhrases, d->relations,
|
d->wheres, d->orderPhrases, d->relations,
|
||||||
d->skip, d->take);
|
d->skip, d->take);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
if (q.lastError().isValid())
|
if (q.lastError().isValid()) {
|
||||||
qDebug() << q.lastError().text();
|
qDebug() << q.lastError().text();
|
||||||
|
return returnList;
|
||||||
|
}
|
||||||
|
|
||||||
QSet<QString> relatedTables;
|
QSet<QString> relatedTables;
|
||||||
foreach (RelationModel *rel, d->relations)
|
foreach (RelationModel *rel, d->relations)
|
||||||
relatedTables << rel->slaveTable->name() << rel->masterTable->name();
|
relatedTables << rel->slaveTable->name() << rel->masterTable->name();
|
||||||
|
|
||||||
|
|
||||||
QStringList childTables, masterTables;
|
QSet<QString> childTables, masterTables;
|
||||||
QMap<QString, Table*> lastClassRow;
|
QMap<QString, Table*> lastClassRow;
|
||||||
|
|
||||||
foreach (RelationModel *rel, d->relations) {
|
foreach (RelationModel *rel, d->relations) {
|
||||||
childTables.append(rel->slaveTable->name());
|
childTables.insert(rel->slaveTable->name());
|
||||||
masterTables.append(rel->masterTable->name());
|
masterTables.insert(rel->masterTable->name());
|
||||||
}
|
}
|
||||||
|
foreach (QString ch, childTables) {
|
||||||
|
if (masterTables.contains(ch))
|
||||||
|
childTables.remove(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "TABLES:";
|
||||||
qDebug() << childTables;
|
qDebug() << childTables;
|
||||||
qDebug() << masterTables;
|
qDebug() << masterTables;
|
||||||
|
|
||||||
|
|
@ -173,7 +180,6 @@ qDebug() << masterTables;
|
||||||
Table *lastRow;
|
Table *lastRow;
|
||||||
};
|
};
|
||||||
QVector<LevelData> levels;
|
QVector<LevelData> levels;
|
||||||
QList<T*> returnList;
|
|
||||||
QList<RelationModel*>::iterator i;
|
QList<RelationModel*>::iterator i;
|
||||||
for (int i = 0; i < d->relations.count(); ++i) {
|
for (int i = 0; i < d->relations.count(); ++i) {
|
||||||
LevelData data;
|
LevelData data;
|
||||||
|
|
@ -378,12 +384,13 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::join(const QString &className)
|
||||||
if (!rel)
|
if (!rel)
|
||||||
rel = d->database->model().relationByClassNames(className, d->className);
|
rel = d->database->model().relationByClassNames(className, d->className);
|
||||||
|
|
||||||
if (!rel)
|
if (!rel) {
|
||||||
qFatal("No relation beyween %s and %s",
|
qInfo("No relation between %s and %s",
|
||||||
qPrintable(d->className), qPrintable(className));
|
qPrintable(d->className), qPrintable(className));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
d->relations.append(rel);
|
d->relations.append(rel);
|
||||||
d->joinClassName = className;
|
|
||||||
d->joins.append(className);
|
d->joins.append(className);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -440,7 +447,6 @@ template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::include(TableSetBase *t)
|
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::include(TableSetBase *t)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
Q_D(Query);
|
||||||
d->joinClassName = t->childClassName();
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -448,7 +454,6 @@ template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::include(Table *t)
|
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::include(Table *t)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
Q_D(Query);
|
||||||
d->joinClassName = t->metaObject()->className();
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ public:
|
||||||
QString select;
|
QString select;
|
||||||
Database *database;
|
Database *database;
|
||||||
TableSetBase *tableSet;
|
TableSetBase *tableSet;
|
||||||
QString joinClassName;
|
|
||||||
QStringList joins;
|
QStringList joins;
|
||||||
QList<RelationModel*> relations;
|
QList<RelationModel*> relations;
|
||||||
QList<WherePhrase> wheres;
|
QList<WherePhrase> wheres;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ SOURCES += \
|
||||||
../common/comment.cpp \
|
../common/comment.cpp \
|
||||||
../common/post.cpp \
|
../common/post.cpp \
|
||||||
../common/user.cpp \
|
../common/user.cpp \
|
||||||
../common/weblogdatabase.cpp
|
../common/weblogdatabase.cpp \
|
||||||
|
../common/score.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
maintest.h \
|
maintest.h \
|
||||||
|
|
@ -21,4 +22,5 @@ HEADERS += \
|
||||||
../common/comment.h \
|
../common/comment.h \
|
||||||
../common/post.h \
|
../common/post.h \
|
||||||
../common/user.h \
|
../common/user.h \
|
||||||
../common/weblogdatabase.h
|
../common/weblogdatabase.h \
|
||||||
|
../common/score.h
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
#include "post.h"
|
#include "post.h"
|
||||||
#include "comment.h"
|
#include "comment.h"
|
||||||
|
#include "score.h"
|
||||||
#include "tableset.h"
|
#include "tableset.h"
|
||||||
|
|
||||||
Post::Post(QObject *parent) : Table(parent),
|
Post::Post(QObject *parent) : Table(parent),
|
||||||
m_id(0), m_title(""), m_comments(new TableSet<Comment>(this))
|
m_id(0), m_title(""),
|
||||||
|
m_comments(new TableSet<Comment>(this)),
|
||||||
|
m_scores(new TableSet<Score>(this))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using namespace NUT_NAMESPACE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Comment;
|
class Comment;
|
||||||
|
class Score;
|
||||||
class Post : public Table
|
class Post : public Table
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -27,6 +28,7 @@ class Post : public Table
|
||||||
NUT_DECLARE_FIELD(QString, body, body, setBody)
|
NUT_DECLARE_FIELD(QString, body, body, setBody)
|
||||||
|
|
||||||
NUT_DECLARE_CHILD_TABLE(Comment, comments)
|
NUT_DECLARE_CHILD_TABLE(Comment, comments)
|
||||||
|
NUT_DECLARE_CHILD_TABLE(Score, scores)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q_INVOKABLE Post(QObject *tableSet = 0);
|
Q_INVOKABLE Post(QObject *tableSet = 0);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
#include "score.h"
|
||||||
|
|
||||||
|
Score::Score(QObject *parent) : Nut::Table(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef SCORE_H
|
||||||
|
#define SCORE_H
|
||||||
|
|
||||||
|
#include "table.h"
|
||||||
|
|
||||||
|
class User;
|
||||||
|
class Post;
|
||||||
|
class Score : public Nut::Table
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
NUT_PRIMARY_AUTO_INCREMENT(id)
|
||||||
|
NUT_DECLARE_FIELD(int, id, id, setId)
|
||||||
|
|
||||||
|
NUT_DECLARE_FIELD(int, score, score, setScore)
|
||||||
|
|
||||||
|
NUT_FOREGION_KEY(Post, int, post, post, setPost)
|
||||||
|
NUT_FOREGION_KEY(User, int, user, user, setUser)
|
||||||
|
|
||||||
|
public:
|
||||||
|
Q_INVOKABLE Score(QObject *parent = Q_NULLPTR);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SCORE_H
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
|
#include "comment.h"
|
||||||
|
#include "score.h"
|
||||||
|
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
#include "comment.h"
|
|
||||||
|
|
||||||
User::User(QObject *tableSet) : Table(tableSet),
|
User::User(QObject *tableSet) : Table(tableSet),
|
||||||
m_comments(new TableSet<Comment>(this))
|
m_comments(new TableSet<Comment>(this)),
|
||||||
|
m_scores(new TableSet<Score>(this))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ using namespace NUT_NAMESPACE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Comment;
|
class Comment;
|
||||||
|
class Score;
|
||||||
class User : public Nut::Table
|
class User : public Nut::Table
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -28,6 +29,7 @@ class User : public Nut::Table
|
||||||
NUT_DECLARE_FIELD(QString, password, password, setPassword)
|
NUT_DECLARE_FIELD(QString, password, password, setPassword)
|
||||||
|
|
||||||
NUT_DECLARE_CHILD_TABLE(Comment, comments)
|
NUT_DECLARE_CHILD_TABLE(Comment, comments)
|
||||||
|
NUT_DECLARE_CHILD_TABLE(Score, scores)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q_INVOKABLE User(QObject *tableSet = 0);
|
Q_INVOKABLE User(QObject *tableSet = 0);
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,13 @@
|
||||||
#include "post.h"
|
#include "post.h"
|
||||||
#include "comment.h"
|
#include "comment.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
#include "score.h"
|
||||||
#include "weblogdatabase.h"
|
#include "weblogdatabase.h"
|
||||||
|
|
||||||
WeblogDatabase::WeblogDatabase() : Database(),
|
WeblogDatabase::WeblogDatabase() : Database(),
|
||||||
m_posts(new TableSet<Post>(this)),
|
m_posts(new TableSet<Post>(this)),
|
||||||
m_comments(new TableSet<Comment>(this)),
|
m_comments(new TableSet<Comment>(this)),
|
||||||
m_users(new TableSet<User>(this))
|
m_users(new TableSet<User>(this)),
|
||||||
|
m_scores(new TableSet<Score>(this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ using namespace NUT_NAMESPACE;
|
||||||
class Post;
|
class Post;
|
||||||
class Comment;
|
class Comment;
|
||||||
class User;
|
class User;
|
||||||
|
class Score;
|
||||||
class WeblogDatabase : public Database
|
class WeblogDatabase : public Database
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -19,6 +20,7 @@ class WeblogDatabase : public Database
|
||||||
NUT_DECLARE_TABLE(Post, post)
|
NUT_DECLARE_TABLE(Post, post)
|
||||||
NUT_DECLARE_TABLE(Comment, comment)
|
NUT_DECLARE_TABLE(Comment, comment)
|
||||||
NUT_DECLARE_TABLE(User, user)
|
NUT_DECLARE_TABLE(User, user)
|
||||||
|
NUT_DECLARE_TABLE(Score, score)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WeblogDatabase();
|
WeblogDatabase();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
#include <QtTest>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QSqlError>
|
||||||
|
|
||||||
|
#include "consts.h"
|
||||||
|
|
||||||
|
#include "jointest.h"
|
||||||
|
#include "query.h"
|
||||||
|
#include "tableset.h"
|
||||||
|
#include "tablemodel.h"
|
||||||
|
#include "databasemodel.h"
|
||||||
|
|
||||||
|
#include "user.h"
|
||||||
|
#include "post.h"
|
||||||
|
#include "comment.h"
|
||||||
|
#include "score.h"
|
||||||
|
|
||||||
|
#define PRINT(x) qDebug() << #x "=" << x;
|
||||||
|
JoinTest::JoinTest(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoinTest::initTestCase()
|
||||||
|
{
|
||||||
|
qDebug() << "User type id:" << qRegisterMetaType<User*>();
|
||||||
|
qDebug() << "Post type id:" << qRegisterMetaType<Post*>();
|
||||||
|
qDebug() << "Comment type id:" << qRegisterMetaType<Comment*>();
|
||||||
|
qDebug() << "Score type id:" << qRegisterMetaType<Score*>();
|
||||||
|
qDebug() << "DB type id:" << qRegisterMetaType<WeblogDatabase*>();
|
||||||
|
|
||||||
|
db.setDriver(DRIVER);
|
||||||
|
db.setHostName(HOST);
|
||||||
|
db.setDatabaseName("nut_tst_join.db");
|
||||||
|
db.setUserName(USERNAME);
|
||||||
|
db.setPassword(PASSWORD);
|
||||||
|
|
||||||
|
bool ok = db.open();
|
||||||
|
|
||||||
|
// db.comments()->query()->remove();
|
||||||
|
// db.posts()->query()->remove();
|
||||||
|
|
||||||
|
QTEST_ASSERT(ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoinTest::join()
|
||||||
|
{
|
||||||
|
auto q = db.comments()->query()
|
||||||
|
->join<User>()
|
||||||
|
->join<Post>();
|
||||||
|
|
||||||
|
// Comment *comment = q->first();
|
||||||
|
auto comments = q->toList();
|
||||||
|
// Comment *comment = q->toList().first();
|
||||||
|
qDebug() << q->sqlCommand();
|
||||||
|
QTEST_ASSERT(comments.length());
|
||||||
|
QTEST_ASSERT(comments[0]->author());
|
||||||
|
QTEST_ASSERT(comments[0]->author()->username() == "admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoinTest::join2()
|
||||||
|
{
|
||||||
|
auto q = db.users()->query()
|
||||||
|
->join<Score>()
|
||||||
|
->join<Post>();
|
||||||
|
|
||||||
|
// Comment *comment = q->first();
|
||||||
|
auto comments = q->toList();
|
||||||
|
// Comment *comment = q->toList().first();
|
||||||
|
// qDebug() << q->sqlCommand();
|
||||||
|
// QTEST_ASSERT(comments.length());
|
||||||
|
// QTEST_ASSERT(comments[0]->author());
|
||||||
|
// QTEST_ASSERT(comments[0]->author()->username() == "admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(JoinTest)
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef JOINTEST_H
|
||||||
|
#define JOINTEST_H
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/qglobal.h>
|
||||||
|
|
||||||
|
#include "weblogdatabase.h"
|
||||||
|
|
||||||
|
class JoinTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
WeblogDatabase db;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit JoinTest(QObject *parent = 0);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase();
|
||||||
|
|
||||||
|
void join2();
|
||||||
|
void join();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // JOINTEST_H
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
QT += qml quick testlib sql
|
||||||
|
QT -= gui
|
||||||
|
|
||||||
|
TARGET = tst_nut
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
CONFIG += warn_on qmltestcase c++11
|
||||||
|
INCLUDEPATH += $$PWD/../../src $$PWD/../common
|
||||||
|
include(../../nut.pri)
|
||||||
|
IMPORTPATH += $$OUT_PWD/../src/imports
|
||||||
|
SOURCES += \
|
||||||
|
jointest.cpp \
|
||||||
|
../common/comment.cpp \
|
||||||
|
../common/post.cpp \
|
||||||
|
../common/user.cpp \
|
||||||
|
../common/weblogdatabase.cpp \
|
||||||
|
../common/score.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
jointest.h \
|
||||||
|
../common/consts.h \
|
||||||
|
../common/comment.h \
|
||||||
|
../common/post.h \
|
||||||
|
../common/user.h \
|
||||||
|
../common/weblogdatabase.h \
|
||||||
|
../common/score.h
|
||||||
Loading…
Reference in New Issue