first commit
This commit is contained in:
56
test/qxBlogPImpl/CMakeLists.txt
Normal file
56
test/qxBlogPImpl/CMakeLists.txt
Normal file
@@ -0,0 +1,56 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
project(qxBlogPImpl LANGUAGES CXX)
|
||||
|
||||
include(../../QxOrm.cmake)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_DEBUG_POSTFIX "d")
|
||||
|
||||
set(HEADERS
|
||||
./include/precompiled.h
|
||||
./include/export.h
|
||||
./include/author.h
|
||||
./include/blog.h
|
||||
./include/category.h
|
||||
./include/comment.h
|
||||
)
|
||||
|
||||
set(SRCS
|
||||
./src/author.cpp
|
||||
./src/blog.cpp
|
||||
./src/category.cpp
|
||||
./src/comment.cpp
|
||||
./src/main.cpp
|
||||
)
|
||||
|
||||
add_executable(qxBlogPImpl ${SRCS} ${HEADERS})
|
||||
|
||||
target_compile_definitions(qxBlogPImpl PRIVATE -D_BUILDING_QX_BLOG)
|
||||
|
||||
if(COMMAND target_precompile_headers)
|
||||
target_precompile_headers(qxBlogPImpl PRIVATE ./include/precompiled.h)
|
||||
endif() # (COMMAND target_precompile_headers)
|
||||
|
||||
target_link_libraries(qxBlogPImpl ${QX_LIBRARIES} QxOrm)
|
||||
|
||||
set_target_properties(qxBlogPImpl PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_CURRENT_SOURCE_DIR}/../_bin"
|
||||
)
|
||||
|
||||
set_target_properties(qxBlogPImpl PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
7
test/qxBlogPImpl/debug/.gitignore
vendored
Normal file
7
test/qxBlogPImpl/debug/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# git does not allow empty directories.
|
||||
# Yet, we need to add this empty directory on git.
|
||||
# To achieve that, we created this .gitignore file, so that the directory will not be empty thus enabling us to commit it.
|
||||
# Since we want all generated files/folders in this directory to be ignored by git, we add a rule for this.
|
||||
*
|
||||
# And then add an exception for this specifc file (so that we can commit it).
|
||||
!.gitignore
|
||||
48
test/qxBlogPImpl/include/author.h
Normal file
48
test/qxBlogPImpl/include/author.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef _QX_BLOG_AUTHOR_H_
|
||||
#define _QX_BLOG_AUTHOR_H_
|
||||
|
||||
class QX_BLOG_DLL_EXPORT author
|
||||
{
|
||||
|
||||
QX_REGISTER_FRIEND_CLASS(author)
|
||||
|
||||
private:
|
||||
|
||||
struct author_impl;
|
||||
std::unique_ptr<author_impl> m_pImpl; //!< Private implementation idiom
|
||||
|
||||
public:
|
||||
|
||||
enum enum_sex { male, female, unknown };
|
||||
|
||||
author();
|
||||
virtual ~author();
|
||||
|
||||
author(const author & other);
|
||||
author & operator=(const author & other);
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
author(author && other) Q_DECL_NOEXCEPT;
|
||||
author & operator=(author && other) Q_DECL_NOEXCEPT;
|
||||
#endif // Q_COMPILER_RVALUE_REFS
|
||||
|
||||
int age() const;
|
||||
QString id() const;
|
||||
QString name() const;
|
||||
QDate birthdate() const;
|
||||
enum_sex sex() const;
|
||||
|
||||
void setId(const QString & s);
|
||||
void setName(const QString & s);
|
||||
void setBirthdate(const QDate & d);
|
||||
void setSex(enum_sex e);
|
||||
|
||||
};
|
||||
|
||||
QX_REGISTER_PRIMARY_KEY(author, QString)
|
||||
QX_REGISTER_HPP_QX_BLOG(author, qx::trait::no_base_class_defined, 0)
|
||||
|
||||
typedef std::shared_ptr<author> author_ptr;
|
||||
typedef qx::QxCollection<QString, author_ptr> list_author;
|
||||
|
||||
#endif // _QX_BLOG_AUTHOR_H_
|
||||
50
test/qxBlogPImpl/include/blog.h
Normal file
50
test/qxBlogPImpl/include/blog.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef _QX_BLOG_BLOG_H_
|
||||
#define _QX_BLOG_BLOG_H_
|
||||
|
||||
class author;
|
||||
class comment;
|
||||
class category;
|
||||
|
||||
class QX_BLOG_DLL_EXPORT blog
|
||||
{
|
||||
|
||||
QX_REGISTER_FRIEND_CLASS(blog)
|
||||
|
||||
private:
|
||||
|
||||
struct blog_impl;
|
||||
std::unique_ptr<blog_impl> m_pImpl; //!< Private implementation idiom
|
||||
|
||||
public:
|
||||
|
||||
blog();
|
||||
virtual ~blog();
|
||||
|
||||
blog(const blog & other);
|
||||
blog & operator=(const blog & other);
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
blog(blog && other) Q_DECL_NOEXCEPT;
|
||||
blog & operator=(blog && other) Q_DECL_NOEXCEPT;
|
||||
#endif // Q_COMPILER_RVALUE_REFS
|
||||
|
||||
long id() const;
|
||||
QString text() const;
|
||||
QDateTime dateCreation() const;
|
||||
|
||||
void setId(long l);
|
||||
void setText(const QString & s);
|
||||
void setDateCreation(const QDateTime & d);
|
||||
|
||||
std::shared_ptr<author> & getAuthor();
|
||||
QList< std::shared_ptr<comment> > & listOfComments();
|
||||
qx::QxCollection<long, QSharedPointer<category> > & listOfCategories();
|
||||
|
||||
};
|
||||
|
||||
QX_REGISTER_HPP_QX_BLOG(blog, qx::trait::no_base_class_defined, 0)
|
||||
|
||||
typedef std::shared_ptr<blog> blog_ptr;
|
||||
typedef std::vector<blog_ptr> list_blog;
|
||||
|
||||
#endif // _QX_BLOG_BLOG_H_
|
||||
46
test/qxBlogPImpl/include/category.h
Normal file
46
test/qxBlogPImpl/include/category.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef _QX_BLOG_CATEGORY_H_
|
||||
#define _QX_BLOG_CATEGORY_H_
|
||||
|
||||
class blog;
|
||||
|
||||
class QX_BLOG_DLL_EXPORT category
|
||||
{
|
||||
|
||||
QX_REGISTER_FRIEND_CLASS(category)
|
||||
|
||||
private:
|
||||
|
||||
struct category_impl;
|
||||
std::unique_ptr<category_impl> m_pImpl; //!< Private implementation idiom
|
||||
|
||||
public:
|
||||
|
||||
category();
|
||||
virtual ~category();
|
||||
|
||||
category(const category & other);
|
||||
category & operator=(const category & other);
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
category(category && other) Q_DECL_NOEXCEPT;
|
||||
category & operator=(category && other) Q_DECL_NOEXCEPT;
|
||||
#endif // Q_COMPILER_RVALUE_REFS
|
||||
|
||||
long id() const;
|
||||
QString name() const;
|
||||
QString desc() const;
|
||||
|
||||
void setId(long l);
|
||||
void setName(const QString & s);
|
||||
void setDesc(const QString & s);
|
||||
|
||||
qx::QxCollection<long, std::shared_ptr<blog> > & listOfBlogs();
|
||||
|
||||
};
|
||||
|
||||
QX_REGISTER_HPP_QX_BLOG(category, qx::trait::no_base_class_defined, 0)
|
||||
|
||||
typedef QSharedPointer<category> category_ptr;
|
||||
typedef qx::QxCollection<long, category_ptr> list_category;
|
||||
|
||||
#endif // _QX_BLOG_CATEGORY_H_
|
||||
46
test/qxBlogPImpl/include/comment.h
Normal file
46
test/qxBlogPImpl/include/comment.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef _QX_BLOG_COMMENT_H_
|
||||
#define _QX_BLOG_COMMENT_H_
|
||||
|
||||
class blog;
|
||||
|
||||
class QX_BLOG_DLL_EXPORT comment
|
||||
{
|
||||
|
||||
QX_REGISTER_FRIEND_CLASS(comment)
|
||||
|
||||
private:
|
||||
|
||||
struct comment_impl;
|
||||
std::unique_ptr<comment_impl> m_pImpl; //!< Private implementation idiom
|
||||
|
||||
public:
|
||||
|
||||
comment();
|
||||
virtual ~comment();
|
||||
|
||||
comment(const comment & other);
|
||||
comment & operator=(const comment & other);
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
comment(comment && other) Q_DECL_NOEXCEPT;
|
||||
comment & operator=(comment && other) Q_DECL_NOEXCEPT;
|
||||
#endif // Q_COMPILER_RVALUE_REFS
|
||||
|
||||
long id() const;
|
||||
QString text() const;
|
||||
QDateTime dateCreation() const;
|
||||
|
||||
void setId(long l);
|
||||
void setText(const QString & s);
|
||||
void setDateCreation(const QDateTime & d);
|
||||
|
||||
std::shared_ptr<blog> & getBlog();
|
||||
|
||||
};
|
||||
|
||||
QX_REGISTER_HPP_QX_BLOG(comment, qx::trait::no_base_class_defined, 0)
|
||||
|
||||
typedef std::shared_ptr<comment> comment_ptr;
|
||||
typedef QList<comment_ptr> list_comment;
|
||||
|
||||
#endif // _QX_BLOG_COMMENT_H_
|
||||
18
test/qxBlogPImpl/include/export.h
Normal file
18
test/qxBlogPImpl/include/export.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef _QX_BLOG_EXPORT_H_
|
||||
#define _QX_BLOG_EXPORT_H_
|
||||
|
||||
#ifdef _BUILDING_QX_BLOG
|
||||
#define QX_BLOG_DLL_EXPORT QX_DLL_EXPORT_HELPER
|
||||
#else // _BUILDING_QX_BLOG
|
||||
#define QX_BLOG_DLL_EXPORT QX_DLL_IMPORT_HELPER
|
||||
#endif // _BUILDING_QX_BLOG
|
||||
|
||||
#ifdef _BUILDING_QX_BLOG
|
||||
#define QX_REGISTER_HPP_QX_BLOG QX_REGISTER_HPP_EXPORT_DLL
|
||||
#define QX_REGISTER_CPP_QX_BLOG QX_REGISTER_CPP_EXPORT_DLL
|
||||
#else // _BUILDING_QX_BLOG
|
||||
#define QX_REGISTER_HPP_QX_BLOG QX_REGISTER_HPP_IMPORT_DLL
|
||||
#define QX_REGISTER_CPP_QX_BLOG QX_REGISTER_CPP_IMPORT_DLL
|
||||
#endif // _BUILDING_QX_BLOG
|
||||
|
||||
#endif // _QX_BLOG_EXPORT_H_
|
||||
8
test/qxBlogPImpl/include/precompiled.h
Normal file
8
test/qxBlogPImpl/include/precompiled.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef _QX_BLOG_PRECOMPILED_HEADER_H_
|
||||
#define _QX_BLOG_PRECOMPILED_HEADER_H_
|
||||
|
||||
#include <QxOrm.h>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
#endif // _QX_BLOG_PRECOMPILED_HEADER_H_
|
||||
7
test/qxBlogPImpl/qt/moc/.gitignore
vendored
Normal file
7
test/qxBlogPImpl/qt/moc/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# git does not allow empty directories.
|
||||
# Yet, we need to add this empty directory on git.
|
||||
# To achieve that, we created this .gitignore file, so that the directory will not be empty thus enabling us to commit it.
|
||||
# Since we want all generated files/folders in this directory to be ignored by git, we add a rule for this.
|
||||
*
|
||||
# And then add an exception for this specifc file (so that we can commit it).
|
||||
!.gitignore
|
||||
34
test/qxBlogPImpl/qxBlog.pro
Normal file
34
test/qxBlogPImpl/qxBlog.pro
Normal file
@@ -0,0 +1,34 @@
|
||||
include(../../QxOrm.pri)
|
||||
|
||||
TEMPLATE = app
|
||||
DEFINES += _BUILDING_QX_BLOG
|
||||
INCLUDEPATH += ../../../QxOrm/include/
|
||||
DESTDIR = ../../../QxOrm/test/_bin/
|
||||
LIBS += -L"../../../QxOrm/lib"
|
||||
|
||||
!contains(DEFINES, _QX_NO_PRECOMPILED_HEADER) {
|
||||
PRECOMPILED_HEADER = ./include/precompiled.h
|
||||
} # !contains(DEFINES, _QX_NO_PRECOMPILED_HEADER)
|
||||
|
||||
macx:CONFIG-=app_bundle
|
||||
|
||||
CONFIG(debug, debug|release) {
|
||||
TARGET = qxBlogPImpld
|
||||
LIBS += -l"QxOrmd"
|
||||
} else {
|
||||
TARGET = qxBlogPImpl
|
||||
LIBS += -l"QxOrm"
|
||||
} # CONFIG(debug, debug|release)
|
||||
|
||||
HEADERS += ./include/precompiled.h
|
||||
HEADERS += ./include/export.h
|
||||
HEADERS += ./include/author.h
|
||||
HEADERS += ./include/blog.h
|
||||
HEADERS += ./include/category.h
|
||||
HEADERS += ./include/comment.h
|
||||
|
||||
SOURCES += ./src/author.cpp
|
||||
SOURCES += ./src/blog.cpp
|
||||
SOURCES += ./src/category.cpp
|
||||
SOURCES += ./src/comment.cpp
|
||||
SOURCES += ./src/main.cpp
|
||||
7
test/qxBlogPImpl/release/.gitignore
vendored
Normal file
7
test/qxBlogPImpl/release/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# git does not allow empty directories.
|
||||
# Yet, we need to add this empty directory on git.
|
||||
# To achieve that, we created this .gitignore file, so that the directory will not be empty thus enabling us to commit it.
|
||||
# Since we want all generated files/folders in this directory to be ignored by git, we add a rule for this.
|
||||
*
|
||||
# And then add an exception for this specifc file (so that we can commit it).
|
||||
!.gitignore
|
||||
75
test/qxBlogPImpl/src/author.cpp
Normal file
75
test/qxBlogPImpl/src/author.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "../include/precompiled.h"
|
||||
|
||||
#include "../include/author.h"
|
||||
#include "../include/blog.h"
|
||||
|
||||
#include <QxOrm_Impl.h>
|
||||
|
||||
QX_REGISTER_CPP_QX_BLOG(author)
|
||||
|
||||
struct Q_DECL_HIDDEN author::author_impl
|
||||
{
|
||||
QString m_id;
|
||||
QString m_name;
|
||||
QDate m_birthdate;
|
||||
author::enum_sex m_sex;
|
||||
list_blog m_blogX;
|
||||
|
||||
author_impl() : m_sex(author::unknown) { ; }
|
||||
~author_impl() { ; }
|
||||
};
|
||||
|
||||
namespace qx {
|
||||
template <> void register_class(QxClass<author> & t)
|
||||
{
|
||||
IxDataMember * pImpl = t.pimpl(& author::m_pImpl);
|
||||
|
||||
t.id(& author::author_impl::m_id, "author_id", 0, pImpl);
|
||||
|
||||
t.data(& author::author_impl::m_name, "name", 0, true, true, pImpl);
|
||||
t.data(& author::author_impl::m_birthdate, "birthdate", 0, true, true, pImpl);
|
||||
t.data(& author::author_impl::m_sex, "sex", 0, true, true, pImpl);
|
||||
|
||||
t.relationOneToMany(& author::author_impl::m_blogX, "list_blog", "author_id", 0, pImpl);
|
||||
|
||||
t.fct_0<int>(std::mem_fn(& author::age), "age"); // using std::mem_fn() here is just a workaround for an issue with some versions of MSVC, it is not required with a full compliant C++11 compiler (http://stackoverflow.com/questions/23778883/vs2013-stdfunction-with-member-function)
|
||||
}}
|
||||
|
||||
author::author() : m_pImpl(new author_impl()) { ; }
|
||||
|
||||
author::~author() { ; }
|
||||
|
||||
author::author(const author & other) : m_pImpl(new author_impl(* other.m_pImpl)) { ; }
|
||||
|
||||
author & author::operator=(const author & other)
|
||||
{
|
||||
if (this != (& other)) { (* m_pImpl) = (* other.m_pImpl); }
|
||||
return (* this);
|
||||
}
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
author::author(author && other) Q_DECL_NOEXCEPT : m_pImpl(std::move(other.m_pImpl)) { ; }
|
||||
author & author::operator=(author && other) Q_DECL_NOEXCEPT { if (this != (& other)) { m_pImpl = std::move(other.m_pImpl); }; return (* this); }
|
||||
#endif // Q_COMPILER_RVALUE_REFS
|
||||
|
||||
int author::age() const
|
||||
{
|
||||
if (! m_pImpl->m_birthdate.isValid()) { return -1; }
|
||||
return (QDate::currentDate().year() - m_pImpl->m_birthdate.year());
|
||||
}
|
||||
|
||||
QString author::id() const { return m_pImpl->m_id; }
|
||||
|
||||
QString author::name() const { return m_pImpl->m_name; }
|
||||
|
||||
QDate author::birthdate() const { return m_pImpl->m_birthdate; }
|
||||
|
||||
author::enum_sex author::sex() const { return m_pImpl->m_sex; }
|
||||
|
||||
void author::setId(const QString & s) { m_pImpl->m_id = s; }
|
||||
|
||||
void author::setName(const QString & s) { m_pImpl->m_name = s; }
|
||||
|
||||
void author::setBirthdate(const QDate & d) { m_pImpl->m_birthdate = d; }
|
||||
|
||||
void author::setSex(enum_sex e) { m_pImpl->m_sex = e; }
|
||||
73
test/qxBlogPImpl/src/blog.cpp
Normal file
73
test/qxBlogPImpl/src/blog.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "../include/precompiled.h"
|
||||
|
||||
#include "../include/blog.h"
|
||||
#include "../include/author.h"
|
||||
#include "../include/comment.h"
|
||||
#include "../include/category.h"
|
||||
|
||||
#include <QxOrm_Impl.h>
|
||||
|
||||
QX_REGISTER_CPP_QX_BLOG(blog)
|
||||
|
||||
struct Q_DECL_HIDDEN blog::blog_impl
|
||||
{
|
||||
long m_id;
|
||||
QString m_text;
|
||||
QDateTime m_dt_creation;
|
||||
author_ptr m_author;
|
||||
list_comment m_commentX;
|
||||
list_category m_categoryX;
|
||||
|
||||
blog_impl() : m_id(0) { ; }
|
||||
~blog_impl() { ; }
|
||||
};
|
||||
|
||||
namespace qx {
|
||||
template <> void register_class(QxClass<blog> & t)
|
||||
{
|
||||
IxDataMember * pImpl = t.pimpl(& blog::m_pImpl);
|
||||
|
||||
t.id(& blog::blog_impl::m_id, "blog_id", 0, pImpl);
|
||||
|
||||
t.data(& blog::blog_impl::m_text, "blog_text", 0, true, true, pImpl);
|
||||
t.data(& blog::blog_impl::m_dt_creation, "date_creation", 0, true, true, pImpl);
|
||||
|
||||
t.relationManyToOne(& blog::blog_impl::m_author, "author_id", 0, pImpl);
|
||||
t.relationOneToMany(& blog::blog_impl::m_commentX, "list_comment", "blog_id", 0, pImpl);
|
||||
t.relationManyToMany(& blog::blog_impl::m_categoryX, "list_category", "category_blog", "blog_id", "category_id", 0, pImpl);
|
||||
}}
|
||||
|
||||
blog::blog() : m_pImpl(new blog_impl()) { ; }
|
||||
|
||||
blog::~blog() { ; }
|
||||
|
||||
blog::blog(const blog & other) : m_pImpl(new blog_impl(* other.m_pImpl)) { ; }
|
||||
|
||||
blog & blog::operator=(const blog & other)
|
||||
{
|
||||
if (this != (& other)) { (* m_pImpl) = (* other.m_pImpl); }
|
||||
return (* this);
|
||||
}
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
blog::blog(blog && other) Q_DECL_NOEXCEPT : m_pImpl(std::move(other.m_pImpl)) { ; }
|
||||
blog & blog::operator=(blog && other) Q_DECL_NOEXCEPT { if (this != (& other)) { m_pImpl = std::move(other.m_pImpl); }; return (* this); }
|
||||
#endif // Q_COMPILER_RVALUE_REFS
|
||||
|
||||
long blog::id() const { return m_pImpl->m_id; }
|
||||
|
||||
QString blog::text() const { return m_pImpl->m_text; }
|
||||
|
||||
QDateTime blog::dateCreation() const { return m_pImpl->m_dt_creation; }
|
||||
|
||||
void blog::setId(long l) { m_pImpl->m_id = l; }
|
||||
|
||||
void blog::setText(const QString & s) { m_pImpl->m_text = s; }
|
||||
|
||||
void blog::setDateCreation(const QDateTime & d) { m_pImpl->m_dt_creation = d; }
|
||||
|
||||
std::shared_ptr<author> & blog::getAuthor() { return m_pImpl->m_author; }
|
||||
|
||||
QList< std::shared_ptr<comment> > & blog::listOfComments() { return m_pImpl->m_commentX; }
|
||||
|
||||
qx::QxCollection<long, QSharedPointer<category> > & blog::listOfCategories() { return m_pImpl->m_categoryX; }
|
||||
65
test/qxBlogPImpl/src/category.cpp
Normal file
65
test/qxBlogPImpl/src/category.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "../include/precompiled.h"
|
||||
|
||||
#include "../include/category.h"
|
||||
#include "../include/blog.h"
|
||||
|
||||
#include <QxOrm_Impl.h>
|
||||
|
||||
QX_REGISTER_CPP_QX_BLOG(category)
|
||||
|
||||
struct Q_DECL_HIDDEN category::category_impl
|
||||
{
|
||||
typedef qx::QxCollection<long, blog_ptr> list_blog;
|
||||
|
||||
long m_id;
|
||||
QString m_name;
|
||||
QString m_desc;
|
||||
list_blog m_blogX;
|
||||
|
||||
category_impl() : m_id(0) { ; }
|
||||
~category_impl() { ; }
|
||||
};
|
||||
|
||||
namespace qx {
|
||||
template <> void register_class(QxClass<category> & t)
|
||||
{
|
||||
IxDataMember * pImpl = t.pimpl(& category::m_pImpl);
|
||||
|
||||
t.id(& category::category_impl::m_id, "category_id", 0, pImpl);
|
||||
|
||||
t.data(& category::category_impl::m_name, "name", 0, true, true, pImpl);
|
||||
t.data(& category::category_impl::m_desc, "description", 0, true, true, pImpl);
|
||||
|
||||
t.relationManyToMany(& category::category_impl::m_blogX, "list_blog", "category_blog", "category_id", "blog_id", 0, pImpl);
|
||||
}}
|
||||
|
||||
category::category() : m_pImpl(new category_impl()) { ; }
|
||||
|
||||
category::~category() { ; }
|
||||
|
||||
category::category(const category & other) : m_pImpl(new category_impl(* other.m_pImpl)) { ; }
|
||||
|
||||
category & category::operator=(const category & other)
|
||||
{
|
||||
if (this != (& other)) { (* m_pImpl) = (* other.m_pImpl); }
|
||||
return (* this);
|
||||
}
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
category::category(category && other) Q_DECL_NOEXCEPT : m_pImpl(std::move(other.m_pImpl)) { ; }
|
||||
category & category::operator=(category && other) Q_DECL_NOEXCEPT { if (this != (& other)) { m_pImpl = std::move(other.m_pImpl); }; return (* this); }
|
||||
#endif // Q_COMPILER_RVALUE_REFS
|
||||
|
||||
long category::id() const { return m_pImpl->m_id; }
|
||||
|
||||
QString category::name() const { return m_pImpl->m_name; }
|
||||
|
||||
QString category::desc() const { return m_pImpl->m_desc; }
|
||||
|
||||
void category::setId(long l) { m_pImpl->m_id = l; }
|
||||
|
||||
void category::setName(const QString & s) { m_pImpl->m_name = s; }
|
||||
|
||||
void category::setDesc(const QString & s) { m_pImpl->m_desc = s; }
|
||||
|
||||
qx::QxCollection<long, std::shared_ptr<blog> > & category::listOfBlogs() { return m_pImpl->m_blogX; }
|
||||
63
test/qxBlogPImpl/src/comment.cpp
Normal file
63
test/qxBlogPImpl/src/comment.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "../include/precompiled.h"
|
||||
|
||||
#include "../include/comment.h"
|
||||
#include "../include/blog.h"
|
||||
|
||||
#include <QxOrm_Impl.h>
|
||||
|
||||
QX_REGISTER_CPP_QX_BLOG(comment)
|
||||
|
||||
struct Q_DECL_HIDDEN comment::comment_impl
|
||||
{
|
||||
long m_id;
|
||||
QString m_text;
|
||||
QDateTime m_dt_create;
|
||||
blog_ptr m_blog;
|
||||
|
||||
comment_impl() : m_id(0) { ; }
|
||||
~comment_impl() { ; }
|
||||
};
|
||||
|
||||
namespace qx {
|
||||
template <> void register_class(QxClass<comment> & t)
|
||||
{
|
||||
IxDataMember * pImpl = t.pimpl(& comment::m_pImpl);
|
||||
|
||||
t.id(& comment::comment_impl::m_id, "comment_id", 0, pImpl);
|
||||
|
||||
t.data(& comment::comment_impl::m_text, "comment_text", 0, true, true, pImpl);
|
||||
t.data(& comment::comment_impl::m_dt_create, "date_creation", 0, true, true, pImpl);
|
||||
|
||||
t.relationManyToOne(& comment::comment_impl::m_blog, "blog_id", 0, pImpl);
|
||||
}}
|
||||
|
||||
comment::comment() : m_pImpl(new comment_impl()) { ; }
|
||||
|
||||
comment::~comment() { ; }
|
||||
|
||||
comment::comment(const comment & other) : m_pImpl(new comment_impl(* other.m_pImpl)) { ; }
|
||||
|
||||
comment & comment::operator=(const comment & other)
|
||||
{
|
||||
if (this != (& other)) { (* m_pImpl) = (* other.m_pImpl); }
|
||||
return (* this);
|
||||
}
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
comment::comment(comment && other) Q_DECL_NOEXCEPT : m_pImpl(std::move(other.m_pImpl)) { ; }
|
||||
comment & comment::operator=(comment && other) Q_DECL_NOEXCEPT { if (this != (& other)) { m_pImpl = std::move(other.m_pImpl); }; return (* this); }
|
||||
#endif // Q_COMPILER_RVALUE_REFS
|
||||
|
||||
long comment::id() const { return m_pImpl->m_id; }
|
||||
|
||||
QString comment::text() const { return m_pImpl->m_text; }
|
||||
|
||||
QDateTime comment::dateCreation() const { return m_pImpl->m_dt_create; }
|
||||
|
||||
void comment::setId(long l) { m_pImpl->m_id = l; }
|
||||
|
||||
void comment::setText(const QString & s) { m_pImpl->m_text = s; }
|
||||
|
||||
void comment::setDateCreation(const QDateTime & d) { m_pImpl->m_dt_create = d; }
|
||||
|
||||
std::shared_ptr<blog> & comment::getBlog() { return m_pImpl->m_blog; }
|
||||
372
test/qxBlogPImpl/src/main.cpp
Normal file
372
test/qxBlogPImpl/src/main.cpp
Normal file
@@ -0,0 +1,372 @@
|
||||
#include "../include/precompiled.h"
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
|
||||
#include "../include/blog.h"
|
||||
#include "../include/author.h"
|
||||
#include "../include/comment.h"
|
||||
#include "../include/category.h"
|
||||
|
||||
#include <QxOrm_Impl.h>
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
// Qt application
|
||||
QCoreApplication app(argc, argv);
|
||||
QFile::remove("./qxBlogPImpl.sqlite");
|
||||
|
||||
// Parameters to connect to database
|
||||
qx::QxSqlDatabase::getSingleton()->setDriverName("QSQLITE");
|
||||
qx::QxSqlDatabase::getSingleton()->setDatabaseName("./qxBlogPImpl.sqlite");
|
||||
qx::QxSqlDatabase::getSingleton()->setHostName("localhost");
|
||||
qx::QxSqlDatabase::getSingleton()->setUserName("root");
|
||||
qx::QxSqlDatabase::getSingleton()->setPassword("");
|
||||
qx::QxSqlDatabase::getSingleton()->setFormatSqlQueryBeforeLogging(true);
|
||||
qx::QxSqlDatabase::getSingleton()->setDisplayTimerDetails(true);
|
||||
|
||||
// Only for debug purpose : assert if invalid offset detected fetching a relation
|
||||
qx::QxSqlDatabase::getSingleton()->setVerifyOffsetRelation(true);
|
||||
|
||||
// Create all tables in database
|
||||
QSqlError daoError = qx::dao::create_table<author>();
|
||||
daoError = qx::dao::create_table<comment>();
|
||||
daoError = qx::dao::create_table<category>();
|
||||
daoError = qx::dao::create_table<blog>();
|
||||
|
||||
// Create a list of 3 author
|
||||
author_ptr author_1; author_1.reset(new author());
|
||||
author_ptr author_2; author_2.reset(new author());
|
||||
author_ptr author_3; author_3.reset(new author());
|
||||
|
||||
author_1->setId("author_id_1"); author_1->setName("author_1");
|
||||
author_1->setSex(author::male); author_1->setBirthdate(QDate::currentDate());
|
||||
author_2->setId("author_id_2"); author_2->setName("author_2");
|
||||
author_2->setSex(author::female); author_2->setBirthdate(QDate::currentDate());
|
||||
author_3->setId("author_id_3"); author_3->setName("author_3");
|
||||
author_3->setSex(author::female); author_3->setBirthdate(QDate::currentDate());
|
||||
|
||||
list_author authorX;
|
||||
authorX.insert(author_1->id(), author_1);
|
||||
authorX.insert(author_2->id(), author_2);
|
||||
authorX.insert(author_3->id(), author_3);
|
||||
|
||||
// Insert list of 3 author into database
|
||||
daoError = qx::dao::insert(authorX);
|
||||
qAssert(qx::dao::count<author>() == 3);
|
||||
|
||||
// Clone author 2 : 'author_id_2'
|
||||
author_ptr author_clone = qx::clone(* author_2);
|
||||
qAssert(author_clone->id() == "author_id_2");
|
||||
qAssert(author_clone->sex() == author::female);
|
||||
|
||||
// Create a query to fetch only female author : 'author_id_2' and 'author_id_3'
|
||||
qx::QxSqlQuery query("WHERE author.sex = :sex");
|
||||
query.bind(":sex", author::female);
|
||||
|
||||
list_author list_of_female_author;
|
||||
daoError = qx::dao::fetch_by_query(query, list_of_female_author);
|
||||
qAssert(list_of_female_author.count() == 2);
|
||||
|
||||
// Dump list of female author (xml serialization)
|
||||
qx::dump(list_of_female_author, false);
|
||||
qx::dump(list_of_female_author, true);
|
||||
|
||||
// Test qx::QxSqlQuery::freeText() with/without placeholders
|
||||
query = qx_query(); query.freeText("WHERE author.sex = " + QString::number(static_cast<int>(author::female)));
|
||||
daoError = qx::dao::fetch_by_query(query, list_of_female_author);
|
||||
qAssert(list_of_female_author.count() == 2);
|
||||
query = qx_query(); query.freeText("WHERE author.sex = :sex", QVariantList() << author::female);
|
||||
daoError = qx::dao::fetch_by_query(query, list_of_female_author);
|
||||
qAssert(list_of_female_author.count() == 2);
|
||||
query = qx_query(); query.freeText("WHERE author.sex=:sex AND author.author_id=:author_id", QVariantList() << author::female << "author_id_2");
|
||||
daoError = qx::dao::fetch_by_query(query, list_of_female_author);
|
||||
qAssert(list_of_female_author.count() == 1);
|
||||
query = qx_query(); query.freeText("WHERE (author.sex = :sex) AND (author.author_id = :author_id)", QVariantList() << author::female << "author_id_2");
|
||||
daoError = qx::dao::fetch_by_query(query, list_of_female_author);
|
||||
qAssert(list_of_female_author.count() == 1);
|
||||
|
||||
// Create 3 categories
|
||||
category_ptr category_1 = category_ptr(new category());
|
||||
category_ptr category_2 = category_ptr(new category());
|
||||
category_ptr category_3 = category_ptr(new category());
|
||||
|
||||
category_1->setName("category_1"); category_1->setDesc("desc_1");
|
||||
category_2->setName("category_2"); category_2->setDesc("desc_2");
|
||||
category_3->setName("category_3"); category_3->setDesc("desc_3");
|
||||
|
||||
{ // Create a scope to destroy temporary connexion to database
|
||||
|
||||
// Open a transaction to database
|
||||
QSqlDatabase db = qx::QxSqlDatabase::getDatabase();
|
||||
bool bCommit = db.transaction();
|
||||
|
||||
// Insert 3 categories into database, use 'db' parameter for the transaction
|
||||
daoError = qx::dao::insert(category_1, (& db)); bCommit = (bCommit && ! daoError.isValid());
|
||||
daoError = qx::dao::insert(category_2, (& db)); bCommit = (bCommit && ! daoError.isValid());
|
||||
daoError = qx::dao::insert(category_3, (& db)); bCommit = (bCommit && ! daoError.isValid());
|
||||
|
||||
qAssert(bCommit);
|
||||
qAssert(category_1->id() != 0);
|
||||
qAssert(category_2->id() != 0);
|
||||
qAssert(category_3->id() != 0);
|
||||
|
||||
// Terminate transaction => commit or rollback if there is error
|
||||
if (bCommit) { db.commit(); }
|
||||
else { db.rollback(); }
|
||||
|
||||
} // End of scope : 'db' is destroyed
|
||||
|
||||
// Create a blog with the class name (factory)
|
||||
qx::any blog_any = qx::create("blog");
|
||||
blog_ptr blog_1;
|
||||
try { blog_1 = qx::any_cast<blog_ptr>(blog_any); }
|
||||
catch (...) { blog_1.reset(new blog()); }
|
||||
blog_1->setText("blog_text_1");
|
||||
blog_1->setDateCreation(QDateTime::currentDateTime());
|
||||
blog_1->getAuthor() = author_1;
|
||||
|
||||
// Insert 'blog_1' into database with 'save()' method
|
||||
daoError = qx::dao::save(blog_1);
|
||||
|
||||
// Modify 'blog_1' properties and save into database
|
||||
blog_1->setText("update blog_text_1");
|
||||
blog_1->getAuthor() = author_2;
|
||||
daoError = qx::dao::save(blog_1);
|
||||
|
||||
// Add 2 comments to 'blog_1'
|
||||
comment_ptr comment_1; comment_1.reset(new comment());
|
||||
comment_ptr comment_2; comment_2.reset(new comment());
|
||||
|
||||
comment_1->setText("comment_1 text");
|
||||
comment_1->setDateCreation(QDateTime::currentDateTime());
|
||||
comment_1->getBlog() = blog_1;
|
||||
comment_2->setText("comment_2 text");
|
||||
comment_2->setDateCreation(QDateTime::currentDateTime());
|
||||
comment_2->getBlog() = blog_1;
|
||||
|
||||
daoError = qx::dao::insert(comment_1);
|
||||
daoError = qx::dao::insert(comment_2);
|
||||
qAssert(qx::dao::count<comment>() == 2);
|
||||
|
||||
// Add 2 categories to 'blog_1' => must insert into extra-table 'category_blog'
|
||||
blog_1->listOfCategories().insert(category_1->id(), category_1);
|
||||
blog_1->listOfCategories().insert(category_3->id(), category_3);
|
||||
daoError = qx::dao::save_with_relation("list_category", blog_1);
|
||||
|
||||
// Fetch blog into a new variable with all relation : 'author', 'comment' and 'category'
|
||||
blog_ptr blog_tmp; blog_tmp.reset(new blog());
|
||||
blog_tmp->setId(blog_1->id());
|
||||
daoError = qx::dao::fetch_by_id_with_all_relation(blog_tmp);
|
||||
|
||||
qAssert(blog_tmp->listOfComments().count() == 2);
|
||||
qAssert(blog_tmp->listOfCategories().count() == 2);
|
||||
qAssert(blog_tmp->text() == "update blog_text_1");
|
||||
qAssert(blog_tmp->getAuthor() && blog_tmp->getAuthor()->id() == "author_id_2");
|
||||
|
||||
// Fetch blog into a new variable with many relations using "*->*->*->*" (4 levels of relationships)
|
||||
blog_tmp.reset(new blog());
|
||||
blog_tmp->setId(blog_1->id());
|
||||
daoError = qx::dao::fetch_by_id_with_relation("*->*->*->*", blog_tmp);
|
||||
|
||||
qAssert(blog_tmp->listOfComments().count() == 2);
|
||||
qAssert(blog_tmp->listOfCategories().count() == 2);
|
||||
qAssert(blog_tmp->text() == "update blog_text_1");
|
||||
qAssert(blog_tmp->getAuthor() && blog_tmp->getAuthor()->id() == "author_id_2");
|
||||
|
||||
// Dump 'blog_tmp' result from database (xml serialization)
|
||||
qx::dump(blog_tmp, false);
|
||||
qx::dump(blog_tmp, true);
|
||||
|
||||
// Fetch relations defining columns to fetch with syntax { col_1, col_2, etc... }
|
||||
list_blog lstBlogComplexRelation;
|
||||
daoError = qx::dao::fetch_all_with_relation(QStringList() << "{ blog_text }" << "author_id { name, birthdate }" << "list_comment { comment_text } -> blog_id -> *", lstBlogComplexRelation);
|
||||
qx::dump(lstBlogComplexRelation);
|
||||
qAssert(lstBlogComplexRelation.size() > 0);
|
||||
qAssert(lstBlogComplexRelation[0]->text() != ""); // Fetched
|
||||
qAssert(lstBlogComplexRelation[0]->dateCreation().isNull()); // Not fetched
|
||||
qAssert(lstBlogComplexRelation[0]->getAuthor()->sex() == author::unknown); // Not fetched
|
||||
qAssert(lstBlogComplexRelation[0]->getAuthor()->name() != ""); // Fetched
|
||||
qAssert(lstBlogComplexRelation[0]->listOfComments().size() > 0);
|
||||
qAssert(lstBlogComplexRelation[0]->listOfComments()[0]->dateCreation().isNull()); // Not fetched
|
||||
qAssert(lstBlogComplexRelation[0]->listOfComments()[0]->text() != ""); // Fetched
|
||||
qAssert(lstBlogComplexRelation[0]->listOfComments()[0]->getBlog());
|
||||
|
||||
// Fetch relations defining columns to remove before fetching with syntax -{ col_1, col_2, etc... }
|
||||
list_blog lstBlogComplexRelation2;
|
||||
daoError = qx::dao::fetch_all_with_relation(QStringList() << "-{ blog_text }" << "author_id -{ name, birthdate }" << "list_comment -{ comment_text } -> blog_id -> *", lstBlogComplexRelation2);
|
||||
qx::dump(lstBlogComplexRelation2);
|
||||
qAssert(lstBlogComplexRelation2.size() > 0);
|
||||
qAssert(lstBlogComplexRelation2[0]->text() == ""); // Not fetched
|
||||
qAssert(! lstBlogComplexRelation2[0]->dateCreation().isNull()); // Fetched
|
||||
qAssert(lstBlogComplexRelation2[0]->getAuthor()->sex() != author::unknown); // Fetched
|
||||
qAssert(lstBlogComplexRelation2[0]->getAuthor()->name() == ""); // Not fetched
|
||||
qAssert(lstBlogComplexRelation2[0]->listOfComments().size() > 0);
|
||||
qAssert(! lstBlogComplexRelation2[0]->listOfComments()[0]->dateCreation().isNull()); // Fetched
|
||||
qAssert(lstBlogComplexRelation2[0]->listOfComments()[0]->text() == ""); // Not fetched
|
||||
qAssert(lstBlogComplexRelation2[0]->listOfComments()[0]->getBlog());
|
||||
|
||||
#ifndef _QX_NO_JSON
|
||||
// Custom JSON serialization process
|
||||
QString customJsonFull = qx::serialization::json::to_string(blog_tmp, 1);
|
||||
QString customJsonFiltered = qx::serialization::json::to_string(blog_tmp, 1, "filter: { blog_text } | author_id { name, birthdate } | list_comment { comment_text } -> blog_id -> *");
|
||||
qDebug("[QxOrm] custom JSON serialization process (full) : \n%s", qPrintable(customJsonFull));
|
||||
qDebug("[QxOrm] custom JSON serialization process (filtered) : \n%s", qPrintable(customJsonFiltered));
|
||||
|
||||
blog_ptr blogFromJsonFull; blogFromJsonFull.reset(new blog());
|
||||
blog_ptr blogFromJsonFiltered; blogFromJsonFiltered.reset(new blog());
|
||||
qx::serialization::json::from_string(blogFromJsonFull, customJsonFull, 1);
|
||||
qx::serialization::json::from_string(blogFromJsonFiltered, customJsonFull, 1, "filter: { blog_text } | author_id { name, birthdate } | list_comment { comment_text } -> blog_id -> *");
|
||||
|
||||
qx::dump(blogFromJsonFull);
|
||||
qAssert(blogFromJsonFull->listOfComments().count() == 2);
|
||||
qAssert(blogFromJsonFull->listOfCategories().count() == 2);
|
||||
qAssert(blogFromJsonFull->text() == "update blog_text_1");
|
||||
qAssert(blogFromJsonFull->getAuthor() && blogFromJsonFull->getAuthor()->id() == "author_id_2");
|
||||
|
||||
qx::dump(blogFromJsonFiltered);
|
||||
qAssert(blogFromJsonFiltered->text() != ""); // Fetched
|
||||
qAssert(blogFromJsonFiltered->dateCreation().isNull()); // Not fetched
|
||||
qAssert(blogFromJsonFiltered->getAuthor()->sex() == author::unknown); // Not fetched
|
||||
qAssert(blogFromJsonFiltered->getAuthor()->name() != ""); // Fetched
|
||||
qAssert(blogFromJsonFiltered->listOfComments().size() > 0);
|
||||
qAssert(blogFromJsonFiltered->listOfComments()[0]->dateCreation().isNull()); // Not fetched
|
||||
qAssert(blogFromJsonFiltered->listOfComments()[0]->text() != ""); // Fetched
|
||||
qAssert(blogFromJsonFiltered->listOfComments()[0]->getBlog());
|
||||
#endif // _QX_NO_JSON
|
||||
|
||||
// Fetch relations defining columns to fetch with syntax { col_1, col_2, etc... } + custom table alias using syntax <my_table_alias> + custom table alias suffix using syntax <..._my_alias_suffix>
|
||||
list_blog lstBlogComplexRelation3;
|
||||
daoError = qx::dao::fetch_all_with_relation(QStringList() << "<blog_alias> { blog_text }" << "author_id <author_alias> { name, birthdate }" << "list_comment <list_comment_alias> { comment_text } -> blog_id <blog_alias_2> -> * <..._my_alias_suffix>", lstBlogComplexRelation3);
|
||||
qx::dump(lstBlogComplexRelation3);
|
||||
qAssert(lstBlogComplexRelation3.size() > 0);
|
||||
qAssert(lstBlogComplexRelation3[0]->text() != ""); // Fetched
|
||||
qAssert(lstBlogComplexRelation3[0]->dateCreation().isNull()); // Not fetched
|
||||
qAssert(lstBlogComplexRelation3[0]->getAuthor()->sex() == author::unknown); // Not fetched
|
||||
qAssert(lstBlogComplexRelation3[0]->getAuthor()->name() != ""); // Fetched
|
||||
qAssert(lstBlogComplexRelation3[0]->listOfComments().size() > 0);
|
||||
qAssert(lstBlogComplexRelation3[0]->listOfComments()[0]->dateCreation().isNull()); // Not fetched
|
||||
qAssert(lstBlogComplexRelation3[0]->listOfComments()[0]->text() != ""); // Fetched
|
||||
qAssert(lstBlogComplexRelation3[0]->listOfComments()[0]->getBlog());
|
||||
|
||||
// Test to add join SQL sub-queries (inside LEFT OUTER JOIN or INNER JOIN)
|
||||
list_blog lstBlogWithJoinQueries;
|
||||
query = qx_query().where("blog_alias.blog_text").isEqualTo("update blog_text_1");
|
||||
query.addJoinQuery("list_comment_alias", "AND list_comment_alias.comment_text IS NOT NULL");
|
||||
query.addJoinQuery("author_alias", qx_query().freeText("AND author_alias.sex = :sex", QVariantList() << author::female));
|
||||
daoError = qx::dao::fetch_by_query_with_relation(QStringList() << "<blog_alias> { blog_text }" << "author_id <author_alias> { name, birthdate, sex }" << "list_comment <list_comment_alias> { comment_text }", query, lstBlogWithJoinQueries);
|
||||
qx::dump(lstBlogWithJoinQueries);
|
||||
qAssert(lstBlogWithJoinQueries.size() > 0);
|
||||
qAssert(lstBlogWithJoinQueries[0]->text() == "update blog_text_1");
|
||||
qAssert(lstBlogWithJoinQueries[0]->getAuthor()->sex() == author::female);
|
||||
|
||||
// When join SQL sub-queries are used, then relationships should keep user defined order (in this example : 'list_comment' before 'author')
|
||||
lstBlogWithJoinQueries.clear();
|
||||
query = qx_query().where("blog_alias.blog_text").isEqualTo("update blog_text_1");
|
||||
query.addJoinQuery("list_comment_alias", "AND list_comment_alias.comment_text IS NOT NULL");
|
||||
query.addJoinQuery("author_alias", qx_query("AND author_alias.sex = :sex", QVariantList() << author::female));
|
||||
daoError = qx::dao::fetch_by_query_with_relation(QStringList() << "<blog_alias> { blog_text }" << "list_comment <list_comment_alias> { comment_text }" << "author_id <author_alias> { name, birthdate, sex }", query, lstBlogWithJoinQueries);
|
||||
qx::dump(lstBlogWithJoinQueries);
|
||||
qAssert(lstBlogWithJoinQueries.size() > 0);
|
||||
qAssert(lstBlogWithJoinQueries[0]->text() == "update blog_text_1");
|
||||
qAssert(lstBlogWithJoinQueries[0]->getAuthor()->sex() == author::female);
|
||||
|
||||
// Check qx::dao::save_with_relation_recursive() function
|
||||
daoError = qx::dao::save_with_relation_recursive(blog_tmp);
|
||||
qAssert(! daoError.isValid());
|
||||
daoError = qx::dao::save_with_relation_recursive(blog_tmp, qx::dao::save_mode::e_update_only);
|
||||
qAssert(! daoError.isValid());
|
||||
|
||||
// Call 'age()' method with class name and method name (reflexion)
|
||||
qx_bool bInvokeOk = qx::QxClassX::invoke("author", "age", author_1);
|
||||
qAssert(bInvokeOk);
|
||||
|
||||
// Check count with relations and filter
|
||||
long lBlogCountWithRelation = 0; qx_query queryBlogCountWithRelation;
|
||||
daoError = qx::dao::count_with_relation<blog>(lBlogCountWithRelation, QStringList() << "author_id" << "list_comment -> blog_id -> *", queryBlogCountWithRelation);
|
||||
qAssert(! daoError.isValid() && (lBlogCountWithRelation > 0));
|
||||
|
||||
// Test 'isDirty()' method
|
||||
qx::dao::ptr<blog> blog_isdirty = qx::dao::ptr<blog>(new blog());
|
||||
blog_isdirty->setId(blog_1->id());
|
||||
daoError = qx::dao::fetch_by_id(blog_isdirty);
|
||||
qAssert(! daoError.isValid() && ! blog_isdirty.isDirty());
|
||||
|
||||
blog_isdirty->setText("blog property 'text' modified => blog is dirty !!!");
|
||||
QStringList lstDiff; bool bDirty = blog_isdirty.isDirty(lstDiff);
|
||||
qAssert(bDirty && (lstDiff.count() == 1) && (lstDiff.at(0) == "blog_text"));
|
||||
if (bDirty) { qDebug("[QxOrm] test dirty 1 : blog is dirty => '%s'", qPrintable(lstDiff.join("|"))); }
|
||||
|
||||
// Update only property 'm_text' of 'blog_isdirty'
|
||||
daoError = qx::dao::update_optimized(blog_isdirty);
|
||||
qAssert(! daoError.isValid() && ! blog_isdirty.isDirty());
|
||||
qx::dump(blog_isdirty, false);
|
||||
qx::dump(blog_isdirty, true);
|
||||
|
||||
// Test 'isDirty()' method with a container
|
||||
typedef qx::dao::ptr< QList<author_ptr> > type_lst_author_test_is_dirty;
|
||||
type_lst_author_test_is_dirty container_isdirty = type_lst_author_test_is_dirty(new QList<author_ptr>());
|
||||
daoError = qx::dao::fetch_all(container_isdirty);
|
||||
qAssert(! daoError.isValid() && ! container_isdirty.isDirty() && (container_isdirty->count() == 3));
|
||||
|
||||
author_ptr author_ptr_dirty = container_isdirty->at(1);
|
||||
author_ptr_dirty->setName("author name modified at index 1 => container is dirty !!!");
|
||||
bDirty = container_isdirty.isDirty(lstDiff);
|
||||
qAssert(bDirty && (lstDiff.count() == 1));
|
||||
if (bDirty) { qDebug("[QxOrm] test dirty 2 : container is dirty => '%s'", qPrintable(lstDiff.join("|"))); }
|
||||
|
||||
author_ptr_dirty = container_isdirty->at(2);
|
||||
author_ptr_dirty->setBirthdate(QDate(1998, 03, 06));
|
||||
bDirty = container_isdirty.isDirty(lstDiff);
|
||||
qAssert(bDirty && (lstDiff.count() == 2));
|
||||
if (bDirty) { qDebug("[QxOrm] test dirty 3 : container is dirty => '%s'", qPrintable(lstDiff.join("|"))); }
|
||||
|
||||
// Update only property 'm_name' at position 1, only property 'm_birthdate' at position 2 and nothing at position 0
|
||||
daoError = qx::dao::update_optimized(container_isdirty);
|
||||
qAssert(! daoError.isValid() && ! container_isdirty.isDirty());
|
||||
qx::dump(container_isdirty, false);
|
||||
qx::dump(container_isdirty, true);
|
||||
|
||||
// Fetch only property 'm_dt_creation' of blog
|
||||
QStringList lstColumns = QStringList() << "date_creation";
|
||||
list_blog lst_blog_with_only_date_creation;
|
||||
daoError = qx::dao::fetch_all(lst_blog_with_only_date_creation, NULL, lstColumns);
|
||||
qAssert(! daoError.isValid() && (lst_blog_with_only_date_creation.size() > 0));
|
||||
if ((lst_blog_with_only_date_creation.size() > 0) && (lst_blog_with_only_date_creation[0].get() != NULL))
|
||||
{ qAssert(lst_blog_with_only_date_creation[0]->text().isEmpty()); }
|
||||
qx::dump(lst_blog_with_only_date_creation, false);
|
||||
qx::dump(lst_blog_with_only_date_creation, true);
|
||||
|
||||
// Dump all registered classes into QxOrm context (introspection engine)
|
||||
qx::QxClassX::dumpAllClasses();
|
||||
|
||||
// Call a custom SQL query or a stored procedure
|
||||
qx_query testStoredProc("SELECT * FROM author");
|
||||
daoError = qx::dao::call_query(testStoredProc);
|
||||
qAssert(! daoError.isValid());
|
||||
testStoredProc.dumpSqlResult();
|
||||
|
||||
// Call a custom SQL query or a stored procedure and fetch automatically properties (with a collection of items)
|
||||
qx_query testStoredProcBis("SELECT * FROM author");
|
||||
authorX.clear();
|
||||
daoError = qx::dao::execute_query(testStoredProcBis, authorX);
|
||||
qAssert(! daoError.isValid()); qAssert(authorX.count() > 0);
|
||||
qx::dump(authorX, false);
|
||||
qx::dump(authorX, true);
|
||||
|
||||
// Call a custom SQL query or a stored procedure and fetch automatically properties
|
||||
qx_query testStoredProcThird("SELECT name, category_id FROM category");
|
||||
category_ptr category_tmp = category_ptr(new category());
|
||||
daoError = qx::dao::execute_query(testStoredProcThird, category_tmp);
|
||||
qAssert(! daoError.isValid()); qAssert(category_tmp->id() != 0);
|
||||
qx::dump(category_tmp, false);
|
||||
qx::dump(category_tmp, true);
|
||||
|
||||
// Test SQL DISTINCT keyword
|
||||
QList<blog> listOfBlogDistinct;
|
||||
qx_query queryDistinct; queryDistinct.distinct().limit(10);
|
||||
daoError = qx::dao::fetch_by_query(queryDistinct, listOfBlogDistinct, NULL, QStringList() << "blog_text");
|
||||
qAssert(! daoError.isValid()); qAssert((listOfBlogDistinct.count() > 0) && (listOfBlogDistinct.at(0).id() == 0) && (! listOfBlogDistinct.at(0).text().isEmpty()));
|
||||
qx::dump(listOfBlogDistinct);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user