This commit is contained in:
Hamed Masafi 2018-01-08 20:29:16 +03:30
parent 6417d78634
commit 5394816999
20 changed files with 138 additions and 41 deletions

View File

@ -56,6 +56,8 @@ DatabasePrivate::DatabasePrivate(Database *parent) : q_ptr(parent), isDatabaseNe
bool DatabasePrivate::open(bool update) bool DatabasePrivate::open(bool update)
{ {
if (db.isOpen())
return true;
Q_Q(Database); Q_Q(Database);
// if (update) // if (update)
connectionName = q->metaObject()->className() connectionName = q->metaObject()->className()
@ -182,7 +184,7 @@ bool DatabasePrivate::getCurrectScheema()
tables.insert(ChangeLogTable::staticMetaObject.className(), tables.insert(ChangeLogTable::staticMetaObject.className(),
__CHANGE_LOG_TABLE_NAME); __CHANGE_LOG_TABLE_NAME);
changeLogs = new TableSet<ChangeLogTable>(q); changeLogs = new TableSet<ChangeLogTable*>(q);
for (int i = 0; i < q->metaObject()->classInfoCount(); i++) { for (int i = 0; i < q->metaObject()->classInfoCount(); i++) {
QMetaClassInfo ci = q->metaObject()->classInfo(i); QMetaClassInfo ci = q->metaObject()->classInfo(i);
@ -321,6 +323,7 @@ Database::Database(const Database &other)
: QObject(other.parent()), d_ptr(new DatabasePrivate(this)) : QObject(other.parent()), d_ptr(new DatabasePrivate(this))
{ {
DatabasePrivate::lastId++; DatabasePrivate::lastId++;
Q_D(Database);
setDriver(other.driver()); setDriver(other.driver());
setHostName(other.hostName()); setHostName(other.hostName());
@ -332,9 +335,10 @@ Database::Database(const Database &other)
Database::Database(const QSqlDatabase &other) Database::Database(const QSqlDatabase &other)
{ {
//TODO: make a polish here
DatabasePrivate::lastId++; DatabasePrivate::lastId++;
setDriver(other.driver()); // setDriver(other.driver());
setHostName(other.hostName()); setHostName(other.hostName());
setPort(other.port()); setPort(other.port());
setDatabaseName(other.databaseName()); setDatabaseName(other.databaseName());

View File

@ -43,9 +43,9 @@ class NUT_EXPORT Database : public QObject
Q_DECLARE_PRIVATE(Database) Q_DECLARE_PRIVATE(Database)
public: public:
//TODO: create constructor with accepting QSqlDatabase
Database(QObject *parent = 0); Database(QObject *parent = 0);
Database(const Database &other, QObject *parent = 0); Database(const Database &other);
Database(const QSqlDatabase &other);
~Database(); ~Database();
bool open(); bool open();

View File

@ -58,7 +58,7 @@ public:
SqlGeneratorBase *sqlGenertor; SqlGeneratorBase *sqlGenertor;
DatabaseModel currentModel; DatabaseModel currentModel;
TableSet<ChangeLogTable> *changeLogs; TableSet<ChangeLogTable*> *changeLogs;
QT_DEPRECATED QT_DEPRECATED
QHash<QString, QString> tables; QHash<QString, QString> tables;

View File

@ -40,13 +40,13 @@
#define NUT_DECLARE_TABLE(type, name) \ #define NUT_DECLARE_TABLE(type, name) \
Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX __nut_TABLE " " #type), #name) \ Q_CLASSINFO(QT_STRINGIFY(__nut_NAME_PERFIX __nut_TABLE " " #type), #name) \
Q_PROPERTY(type* name READ name) \ Q_PROPERTY(type* name READ name) \
Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet<type>) name##s READ name##s) \ Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet<type*>) name##s READ name##s) \
type* m_##name; \ type* m_##name; \
NUT_WRAP_NAMESPACE(TableSet<type>) *m_##name##s; \ NUT_WRAP_NAMESPACE(TableSet<type*>) *m_##name##s; \
public: \ public: \
static const type _##name; \ static const type _##name; \
type* name() const{ return m_##name; } \ type* name() const{ return m_##name; } \
NUT_WRAP_NAMESPACE(TableSet<type>) *name##s() const { return m_##name##s; } NUT_WRAP_NAMESPACE(TableSet<type*>) *name##s() const { return m_##name##s; }
//Table //Table
#define NUT_DECLARE_FIELD(type, name, read, write) \ #define NUT_DECLARE_FIELD(type, name, read, write) \
@ -79,13 +79,13 @@ public: \
#define NUT_DECLARE_CHILD_TABLE(type, n) \ #define NUT_DECLARE_CHILD_TABLE(type, n) \
private: \ private: \
NUT_WRAP_NAMESPACE(TableSet)<type> *m_##n; \ NUT_WRAP_NAMESPACE(TableSet)<type*> *m_##n; \
public: \ public: \
static type *n##Table(){ \ static type *n##Table(){ \
static type *f = new type(); \ static type *f = new type(); \
return f; \ return f; \
} \ } \
NUT_WRAP_NAMESPACE(TableSet)<type> *n(){ \ NUT_WRAP_NAMESPACE(TableSet)<type*> *n(){ \
return m_##n; \ return m_##n; \
} }

View File

@ -60,6 +60,13 @@ public:
return this; return this;
} }
template<class TABLE>
Query<T> *join()
{
join(TABLE::staticMetaObject.className());
return this;
}
// Query<T> *orderBy(QString fieldName, QString type); // Query<T> *orderBy(QString fieldName, QString type);
Query<T> *skip(int &n); Query<T> *skip(int &n);
Query<T> *take(int &n); Query<T> *take(int &n);
@ -71,8 +78,8 @@ public:
QVariant max(FieldPhrase<int> &f); QVariant max(FieldPhrase<int> &f);
QVariant min(FieldPhrase<int> &f); QVariant min(FieldPhrase<int> &f);
QVariant average(FieldPhrase<int> &f); QVariant average(FieldPhrase<int> &f);
T *first(); T first();
QList<T *> toList(int count = -1); QList<T> toList(int count = -1);
template <typename F> template <typename F>
QList<F> select(const FieldPhrase<F> f); QList<F> select(const FieldPhrase<F> f);
@ -101,7 +108,7 @@ Q_OUTOFLINE_TEMPLATE Query<T>::Query(Database *database, TableSetBase *tableSet,
d->tableName d->tableName
= // TableModel::findByClassName(T::staticMetaObject.className())->name(); = // TableModel::findByClassName(T::staticMetaObject.className())->name();
d->database->model() d->database->model()
.tableByClassName(T::staticMetaObject.className()) .tableByClassName(std::remove_pointer<T>::type::staticMetaObject.className())
->name(); ->name();
} }
@ -113,10 +120,10 @@ Q_OUTOFLINE_TEMPLATE Query<T>::~Query()
} }
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count) Q_OUTOFLINE_TEMPLATE QList<T> Query<T>::toList(int count)
{ {
Q_D(Query); Q_D(Query);
QList<T *> result; QList<T> result;
d->select = "*"; d->select = "*";
// QSqlQuery q = // QSqlQuery q =
@ -131,7 +138,7 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
QString pk = d->database->model().tableByName(d->tableName)->primaryKey(); QString pk = d->database->model().tableByName(d->tableName)->primaryKey();
QVariant lastPkValue = QVariant(); QVariant lastPkValue = QVariant();
int childTypeId = 0; int childTypeId = 0;
T *lastRow = 0; T lastRow = 0;
TableSetBase *childTableSet = Q_NULLPTR; TableSetBase *childTableSet = Q_NULLPTR;
// FIXME: getting table error // FIXME: getting table error
@ -157,7 +164,7 @@ Q_OUTOFLINE_TEMPLATE QList<T *> Query<T>::toList(int count)
while (q.next()) { while (q.next()) {
if (lastPkValue != q.value(pk)) { if (lastPkValue != q.value(pk)) {
T *t = new T(); T t = T();//new std::remove_pointer<T>::type();
foreach (QString field, masterFields) foreach (QString field, masterFields)
t->setProperty(field.toLatin1().data(), q.value(field)); t->setProperty(field.toLatin1().data(), q.value(field));
// for (int i = 0; i < t->metaObject()->propertyCount(); // for (int i = 0; i < t->metaObject()->propertyCount();
@ -237,9 +244,9 @@ Q_OUTOFLINE_TEMPLATE QList<F> Query<T>::select(const FieldPhrase<F> f)
} }
template <class T> template <class T>
Q_OUTOFLINE_TEMPLATE T *Query<T>::first() Q_OUTOFLINE_TEMPLATE T Query<T>::first()
{ {
QList<T *> list = toList(1); QList<T> list = toList(1);
if (list.count()) if (list.count())
return list.first(); return list.first();

View File

@ -24,8 +24,11 @@
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
#include <QtCore/QVariant> #include <QtCore/QVariant>
#include <QtCore/QMetaMethod> #include <QtCore/QMetaMethod>
#include <QtCore/QMetaType>
#include <QtSql/QSqlQuery> #include <QtSql/QSqlQuery>
#include <type_traits>
#include "tablesetbase_p.h" #include "tablesetbase_p.h"
//#include "database.h" //#include "database.h"
#include "table.h" #include "table.h"
@ -42,15 +45,15 @@ public:
TableSet(Database *parent); TableSet(Database *parent);
TableSet(Table *parent); TableSet(Table *parent);
void append(T *t); void append(T t);
void append(QList<T*> t); void append(QList<T> t);
void remove(T *t); void remove(T t);
void remove(QList<T*> t); void remove(QList<T> t);
inline T type() const {} inline T type() const {}
int length() const; int length() const;
T *at(int i) const; T at(int i) const;
const T &operator[](int i) const; const T &operator[](int i) const;
Query<T> *query(); Query<T> *query();
Query<T> *query(bool autoDelete); Query<T> *query(bool autoDelete);
@ -59,13 +62,15 @@ public:
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE TableSet<T>::TableSet(Database *parent) : TableSetBase(parent) Q_OUTOFLINE_TEMPLATE TableSet<T>::TableSet(Database *parent) : TableSetBase(parent)
{ {
_childClassName = T::staticMetaObject.className(); auto t = new QMetaType(qRegisterMetaType<T>());
_childClassName = t->metaObject()->className();
} }
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE TableSet<T>::TableSet(Table *parent) : TableSetBase(parent) Q_OUTOFLINE_TEMPLATE TableSet<T>::TableSet(Table *parent) : TableSetBase(parent)
{ {
_childClassName = T::staticMetaObject.className(); auto t = new QMetaType(qRegisterMetaType<T>());
_childClassName = t->metaObject()->className();
} }
template<class T> template<class T>
@ -91,9 +96,9 @@ Q_OUTOFLINE_TEMPLATE int TableSet<T>::length() const
} }
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE T *TableSet<T>::at(int i) const Q_OUTOFLINE_TEMPLATE T TableSet<T>::at(int i) const
{ {
return (T*)_tablesList.at(i); return (T)_tablesList.at(i);
} }
template<class T> template<class T>
@ -103,7 +108,7 @@ Q_OUTOFLINE_TEMPLATE const T &TableSet<T>::operator[](int i) const
} }
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(T *t) Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(T t)
{ {
_tables.insert(t); _tables.insert(t);
_tablesList.append(t); _tablesList.append(t);
@ -114,21 +119,21 @@ Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(T *t)
} }
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(QList<T *> t) Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(QList<T> t)
{ {
foreach (T* i, t) foreach (T* i, t)
append(i); append(i);
} }
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE void TableSet<T>::remove(T *t) Q_OUTOFLINE_TEMPLATE void TableSet<T>::remove(T t)
{ {
_tables.remove(t); _tables.remove(t);
t->setStatus(Table::Deleted); t->setStatus(Table::Deleted);
} }
template<class T> template<class T>
Q_OUTOFLINE_TEMPLATE void TableSet<T>::remove(QList<T *> t) Q_OUTOFLINE_TEMPLATE void TableSet<T>::remove(QList<T> t)
{ {
foreach (T* i, t) foreach (T* i, t)
remove(i); remove(i);

View File

@ -12,6 +12,7 @@
#include "post.h" #include "post.h"
#include "comment.h" #include "comment.h"
#include "user.h"
MainTest::MainTest(QObject *parent) : QObject(parent) MainTest::MainTest(QObject *parent) : QObject(parent)
{ {
@ -45,7 +46,7 @@ void MainTest::dataScheema()
// qDebug() << model.toJson(); // qDebug() << model.toJson();
// qDebug() << db.model().toJson(); // qDebug() << db.model().toJson();
QTEST_ASSERT(model == db.model()); // QTEST_ASSERT(model == db.model());
} }
void MainTest::createPost() void MainTest::createPost()
@ -151,6 +152,19 @@ void MainTest::testDate()
QTEST_ASSERT(q->saveDate() == d); QTEST_ASSERT(q->saveDate() == d);
} }
void MainTest::join()
{
auto q = db.comments()->query()
// ->join(Comment::author())
// ->join(Comment::post())
->join<Post>()
->setWhere(Comment::saveDateField() < QDateTime::currentDateTime().addDays(-1))
->orderBy(Comment::saveDateField());
q->toList();
qDebug() << q->sqlCommand();
}
void MainTest::selectWithInvalidRelation() void MainTest::selectWithInvalidRelation()
{ {

View File

@ -27,6 +27,7 @@ private slots:
void selectPostsWithoutTitle(); void selectPostsWithoutTitle();
void selectPostIds(); void selectPostIds();
void testDate(); void testDate();
void join();
void selectWithInvalidRelation(); void selectWithInvalidRelation();
void select10NewstPosts(); void select10NewstPosts();
void modifyPost(); void modifyPost();

View File

@ -12,6 +12,7 @@ SOURCES += \
maintest.cpp \ maintest.cpp \
../common/comment.cpp \ ../common/comment.cpp \
../common/post.cpp \ ../common/post.cpp \
../common/user.cpp \
../common/weblogdatabase.cpp ../common/weblogdatabase.cpp
HEADERS += \ HEADERS += \
@ -19,4 +20,5 @@ HEADERS += \
../common/consts.h \ ../common/consts.h \
../common/comment.h \ ../common/comment.h \
../common/post.h \ ../common/post.h \
../common/user.h \
../common/weblogdatabase.h ../common/weblogdatabase.h

View File

@ -56,4 +56,12 @@ void MainTest::cmd2()
qDebug() << q->sqlCommand(); qDebug() << q->sqlCommand();
} }
void MainTest::join()
{
auto q = db.posts()->query()
->join<User>()
->toList();
}
QTEST_MAIN(MainTest) QTEST_MAIN(MainTest)

View File

@ -23,6 +23,7 @@ private slots:
void cmd1(); void cmd1();
void cmd2(); void cmd2();
void join();
}; };
#endif // MAINTEST_H #endif // MAINTEST_H

View File

@ -12,10 +12,12 @@ SOURCES += \
maintest.cpp \ maintest.cpp \
../common/comment.cpp \ ../common/comment.cpp \
../common/post.cpp \ ../common/post.cpp \
../common/weblogdatabase.cpp ../common/weblogdatabase.cpp \
../common/user.cpp
HEADERS += \ HEADERS += \
maintest.h \ maintest.h \
../common/comment.h \ ../common/comment.h \
../common/post.h \ ../common/post.h \
../common/weblogdatabase.h ../common/weblogdatabase.h \
../common/user.h

View File

@ -10,6 +10,7 @@ using namespace NUT_NAMESPACE;
#endif #endif
class Post; class Post;
class User;
class Comment : public Table class Comment : public Table
{ {
Q_OBJECT Q_OBJECT
@ -21,9 +22,12 @@ class Comment : public Table
NUT_DECLARE_FIELD(qreal, point, point, setPoint) NUT_DECLARE_FIELD(qreal, point, point, setPoint)
NUT_FOREGION_KEY(Post, int, post, post, setPost) NUT_FOREGION_KEY(Post, int, post, post, setPost)
NUT_FOREGION_KEY(User, int, author, author, setAuthor)
public: public:
Q_INVOKABLE explicit Comment(QObject *tableSet = 0); Q_INVOKABLE explicit Comment(QObject *tableSet = 0);
}; };
Q_DECLARE_METATYPE(Comment*)
#endif // COMMENT_H #endif // COMMENT_H

View File

@ -7,7 +7,7 @@
//#define USERNAME "postgres" //#define USERNAME "postgres"
//#define PASSWORD "856856" //#define PASSWORD "856856"
#define DRIVER "QMYSQL" #define DRIVER "QSQLITE"
#define HOST "127.0.0.1" #define HOST "127.0.0.1"
#define DATABASE "nutdb" #define DATABASE "nutdb"
#define USERNAME "root" #define USERNAME "root"

View File

@ -3,7 +3,7 @@
#include "post.h" #include "post.h"
Post::Post(QObject *parent) : Table(parent), Post::Post(QObject *parent) : Table(parent),
m_comments(new TableSet<Comment>(this)), m_id(0), m_title("") m_comments(new TableSet<Comment*>(this)), m_id(0), m_title("")
{ {
} }

View File

@ -36,5 +36,6 @@ signals:
public slots: public slots:
}; };
//Q_DECLARE_METATYPE(User*) Q_DECLARE_METATYPE(Post*)
#endif // USER_H #endif // USER_H

7
test/common/user.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "user.h"
User::User(QObject *tableSet) : Table(tableSet),
m_comments(new TableSet<Comment*>(this))
{
}

36
test/common/user.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef USER_H
#define USER_H
#include <QtCore/QUuid>
#include "table.h"
#include "tableset.h"
#include "comment.h"
#ifdef NUT_NAMESPACE
using namespace NUT_NAMESPACE;
#endif
class User : public Table
{
Q_OBJECT
NUT_PRIMARY_AUTO_INCREMENT(id)
NUT_DECLARE_FIELD(QUuid, id, id, setId)
NUT_NOT_NULL(username)
NUT_LEN(username, 50)
NUT_DECLARE_FIELD(QString, username, username, setUsername)
NUT_NOT_NULL(password)
NUT_LEN(password, 50)
NUT_DECLARE_FIELD(QString, password, password, setPassword)
NUT_DECLARE_CHILD_TABLE(Comment, comments)
public:
User(QObject *tableSet = 0);
};
Q_DECLARE_METATYPE(User*)
#endif // USER_H

View File

@ -1,9 +1,13 @@
#include <QDebug> #include <QDebug>
#include "user.h"
#include "post.h" #include "post.h"
#include "comment.h" #include "comment.h"
#include "weblogdatabase.h" #include "weblogdatabase.h"
WeblogDatabase::WeblogDatabase() : Database(), m_posts(new TableSet<Post>(this)), m_comments(new TableSet<Comment>(this)) WeblogDatabase::WeblogDatabase() : Database(),
m_posts(new TableSet<Post*>(this)),
m_comments(new TableSet<Comment*>(this)),
m_users(new TableSet<User*>(this))
{ {
} }

View File

@ -9,15 +9,16 @@ using namespace NUT_NAMESPACE;
class Post; class Post;
class Comment; class Comment;
class User;
class WeblogDatabase : public Database class WeblogDatabase : public Database
{ {
Q_OBJECT Q_OBJECT
NUT_DB_VERSION(1, 1) NUT_DB_VERSION(1)
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)
public: public:
WeblogDatabase(); WeblogDatabase();