first commit
This commit is contained in:
56
test/qxBlogCpp11/CMakeLists.txt
Normal file
56
test/qxBlogCpp11/CMakeLists.txt
Normal file
@@ -0,0 +1,56 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
project(qxBlogCpp11 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(qxBlogCpp11 ${SRCS} ${HEADERS})
|
||||
|
||||
target_compile_definitions(qxBlogCpp11 PRIVATE -D_BUILDING_QX_BLOG)
|
||||
|
||||
if(COMMAND target_precompile_headers)
|
||||
target_precompile_headers(qxBlogCpp11 PRIVATE ./include/precompiled.h)
|
||||
endif() # (COMMAND target_precompile_headers)
|
||||
|
||||
target_link_libraries(qxBlogCpp11 ${QX_LIBRARIES} QxOrm)
|
||||
|
||||
set_target_properties(qxBlogCpp11 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(qxBlogCpp11 PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
7
test/qxBlogCpp11/debug/.gitignore
vendored
Normal file
7
test/qxBlogCpp11/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
|
||||
57
test/qxBlogCpp11/include/author.h
Normal file
57
test/qxBlogCpp11/include/author.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef _QX_BLOG_AUTHOR_H_
|
||||
#define _QX_BLOG_AUTHOR_H_
|
||||
|
||||
class blog;
|
||||
|
||||
class QX_BLOG_DLL_EXPORT author
|
||||
{
|
||||
|
||||
QX_REGISTER_FRIEND_CLASS(author)
|
||||
|
||||
public:
|
||||
|
||||
// -- composite key (multi-column primary key in database)
|
||||
typedef QX_TUPLE<QString, long, QString> type_composite_key;
|
||||
static QString str_composite_key() { return "author_id_0|author_id_1|author_id_2"; }
|
||||
|
||||
// -- typedef
|
||||
typedef std::shared_ptr<blog> blog_ptr;
|
||||
typedef std::vector<blog_ptr> list_blog;
|
||||
|
||||
// -- enum
|
||||
enum enum_sex { male, female, unknown };
|
||||
|
||||
// -- properties
|
||||
type_composite_key m_id;
|
||||
QString m_name;
|
||||
QDate m_birthdate;
|
||||
enum_sex m_sex;
|
||||
list_blog m_blogX;
|
||||
|
||||
// -- contructor, virtual destructor
|
||||
author() : m_id("", 0, ""), m_sex(unknown) { ; }
|
||||
virtual ~author() { ; }
|
||||
|
||||
// -- methods
|
||||
int age() const;
|
||||
|
||||
// -- methods "get" to composite key
|
||||
type_composite_key getId() const { return m_id; }
|
||||
QString getId_0() const { return QX_TUPLE_GET<0>(m_id); }
|
||||
long getId_1() const { return QX_TUPLE_GET<1>(m_id); }
|
||||
QString getId_2() const { return QX_TUPLE_GET<2>(m_id); }
|
||||
|
||||
// -- methods "set" to composite key
|
||||
void setId_0(const QString & s) { QX_TUPLE_GET<0>(m_id) = s; }
|
||||
void setId_1(long l) { QX_TUPLE_GET<1>(m_id) = l; }
|
||||
void setId_2(const QString & s) { QX_TUPLE_GET<2>(m_id) = s; }
|
||||
|
||||
};
|
||||
|
||||
QX_REGISTER_PRIMARY_KEY(author, author::type_composite_key)
|
||||
QX_REGISTER_HPP_QX_BLOG(author, qx::trait::no_base_class_defined, 0)
|
||||
|
||||
typedef std::shared_ptr<author> author_ptr;
|
||||
typedef qx::QxCollection<author::type_composite_key, author_ptr> list_author;
|
||||
|
||||
#endif // _QX_BLOG_AUTHOR_H_
|
||||
48
test/qxBlogCpp11/include/blog.h
Normal file
48
test/qxBlogCpp11/include/blog.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef _QX_BLOG_BLOG_H_
|
||||
#define _QX_BLOG_BLOG_H_
|
||||
|
||||
#include "author.h"
|
||||
#include "comment.h"
|
||||
#include "category.h"
|
||||
|
||||
class QX_BLOG_DLL_EXPORT blog
|
||||
{
|
||||
|
||||
QX_REGISTER_FRIEND_CLASS(blog)
|
||||
|
||||
public:
|
||||
|
||||
// -- composite key (multi-column primary key in database)
|
||||
typedef QPair<long, QString> type_composite_key;
|
||||
static QString str_composite_key() { return "blog_id_0|blog_id_1"; }
|
||||
|
||||
// -- properties
|
||||
type_composite_key m_id;
|
||||
QString m_text;
|
||||
QDateTime m_dt_creation;
|
||||
author_ptr m_author;
|
||||
list_comment m_commentX;
|
||||
list_category m_categoryX;
|
||||
|
||||
// -- contructor, virtual destructor
|
||||
blog() : m_id(0, "") { ; }
|
||||
virtual ~blog() { ; }
|
||||
|
||||
// -- methods "get" to composite key
|
||||
type_composite_key getId() const { return m_id; }
|
||||
long getId_0() const { return m_id.first; }
|
||||
QString getId_1() const { return m_id.second; }
|
||||
|
||||
// -- methods "set" to composite key
|
||||
void setId_0(long l) { m_id.first = l; }
|
||||
void setId_1(const QString & s) { m_id.second = s; }
|
||||
|
||||
};
|
||||
|
||||
QX_REGISTER_PRIMARY_KEY(blog, blog::type_composite_key)
|
||||
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_
|
||||
52
test/qxBlogCpp11/include/category.h
Normal file
52
test/qxBlogCpp11/include/category.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef _QX_BLOG_CATEGORY_H_
|
||||
#define _QX_BLOG_CATEGORY_H_
|
||||
|
||||
class blog;
|
||||
|
||||
class QX_BLOG_DLL_EXPORT category
|
||||
{
|
||||
|
||||
QX_REGISTER_FRIEND_CLASS(category)
|
||||
|
||||
public:
|
||||
|
||||
// -- composite key (multi-column primary key in database)
|
||||
typedef QX_TUPLE<QString, long, QString, long> type_composite_key;
|
||||
static QString str_composite_key() { return "category_id_0|category_id_1|category_id_2|category_id_3"; }
|
||||
|
||||
// -- typedef
|
||||
typedef std::shared_ptr<blog> blog_ptr;
|
||||
typedef qx::QxCollection<long, blog_ptr> list_blog;
|
||||
|
||||
// -- properties
|
||||
type_composite_key m_id;
|
||||
QString m_name;
|
||||
QString m_desc;
|
||||
list_blog m_blogX;
|
||||
|
||||
// -- contructor, virtual destructor
|
||||
category() : m_id("", 0, "", 0) { ; }
|
||||
virtual ~category() { ; }
|
||||
|
||||
// -- methods "get" to composite key
|
||||
type_composite_key getId() const { return m_id; }
|
||||
QString getId_0() const { return QX_TUPLE_GET<0>(m_id); }
|
||||
long getId_1() const { return QX_TUPLE_GET<1>(m_id); }
|
||||
QString getId_2() const { return QX_TUPLE_GET<2>(m_id); }
|
||||
long getId_3() const { return QX_TUPLE_GET<3>(m_id); }
|
||||
|
||||
// -- methods "set" to composite key
|
||||
void setId_0(const QString & s) { QX_TUPLE_GET<0>(m_id) = s; }
|
||||
void setId_1(long l) { QX_TUPLE_GET<1>(m_id) = l; }
|
||||
void setId_2(const QString & s) { QX_TUPLE_GET<2>(m_id) = s; }
|
||||
void setId_3(long l) { QX_TUPLE_GET<3>(m_id) = l; }
|
||||
|
||||
};
|
||||
|
||||
QX_REGISTER_PRIMARY_KEY(category, category::type_composite_key)
|
||||
QX_REGISTER_HPP_QX_BLOG(category, qx::trait::no_base_class_defined, 0)
|
||||
|
||||
typedef QSharedPointer<category> category_ptr;
|
||||
typedef qx::QxCollection<category::type_composite_key, category_ptr> list_category;
|
||||
|
||||
#endif // _QX_BLOG_CATEGORY_H_
|
||||
47
test/qxBlogCpp11/include/comment.h
Normal file
47
test/qxBlogCpp11/include/comment.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef _QX_BLOG_COMMENT_H_
|
||||
#define _QX_BLOG_COMMENT_H_
|
||||
|
||||
class blog;
|
||||
|
||||
class QX_BLOG_DLL_EXPORT comment
|
||||
{
|
||||
|
||||
QX_REGISTER_FRIEND_CLASS(comment)
|
||||
|
||||
public:
|
||||
|
||||
// -- composite key (multi-column primary key in database)
|
||||
typedef QX_TUPLE<long, QString> type_composite_key;
|
||||
static QString str_composite_key() { return "comment_id_0|comment_id_1"; }
|
||||
|
||||
// -- typedef
|
||||
typedef std::shared_ptr<blog> blog_ptr;
|
||||
|
||||
// -- properties
|
||||
type_composite_key m_id;
|
||||
QString m_text;
|
||||
QDateTime m_dt_create;
|
||||
blog_ptr m_blog;
|
||||
|
||||
// -- contructor, virtual destructor
|
||||
comment() : m_id(0, "") { ; }
|
||||
virtual ~comment() { ; }
|
||||
|
||||
// -- methods "get" to composite key
|
||||
type_composite_key getId() const { return m_id; }
|
||||
long getId_0() const { return QX_TUPLE_GET<0>(m_id); }
|
||||
QString getId_1() const { return QX_TUPLE_GET<1>(m_id); }
|
||||
|
||||
// -- methods "set" to composite key
|
||||
void setId_0(long l) { QX_TUPLE_GET<0>(m_id) = l; }
|
||||
void setId_1(const QString & s) { QX_TUPLE_GET<1>(m_id) = s; }
|
||||
|
||||
};
|
||||
|
||||
QX_REGISTER_PRIMARY_KEY(comment, comment::type_composite_key)
|
||||
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/qxBlogCpp11/include/export.h
Normal file
18
test/qxBlogCpp11/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_
|
||||
24
test/qxBlogCpp11/include/precompiled.h
Normal file
24
test/qxBlogCpp11/include/precompiled.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef _QX_BLOG_PRECOMPILED_HEADER_H_
|
||||
#define _QX_BLOG_PRECOMPILED_HEADER_H_
|
||||
|
||||
#include <QxOrm.h>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
/*
|
||||
// To resolve a problem with MSVC++ 2010 and MSVC++ 2012 (and later ?) :
|
||||
// These compilers provide a tuple header but BOOST_NO_CXX11_HDR_TUPLE macro is defined !
|
||||
// This is because these compilers doesn't provide variadic templates
|
||||
#if (defined(_QX_CPP_11_TUPLE) && !defined(BOOST_NO_CXX11_HDR_TUPLE))
|
||||
#define QX_TUPLE std::tuple
|
||||
#define QX_TUPLE_GET std::get
|
||||
#else // (defined(_QX_CPP_11_TUPLE) && !defined(BOOST_NO_CXX11_HDR_TUPLE))
|
||||
#define QX_TUPLE boost::tuple
|
||||
#define QX_TUPLE_GET boost::tuples::get
|
||||
#endif // (defined(_QX_CPP_11_TUPLE) && !defined(BOOST_NO_CXX11_HDR_TUPLE))
|
||||
*/
|
||||
|
||||
#define QX_TUPLE std::tuple
|
||||
#define QX_TUPLE_GET std::get
|
||||
|
||||
#endif // _QX_BLOG_PRECOMPILED_HEADER_H_
|
||||
7
test/qxBlogCpp11/qt/moc/.gitignore
vendored
Normal file
7
test/qxBlogCpp11/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
|
||||
36
test/qxBlogCpp11/qxBlog.pro
Normal file
36
test/qxBlogCpp11/qxBlog.pro
Normal file
@@ -0,0 +1,36 @@
|
||||
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)
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
macx:CONFIG-=app_bundle
|
||||
|
||||
CONFIG(debug, debug|release) {
|
||||
TARGET = qxBlogCpp11d
|
||||
LIBS += -l"QxOrmd"
|
||||
} else {
|
||||
TARGET = qxBlogCpp11
|
||||
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/qxBlogCpp11/release/.gitignore
vendored
Normal file
7
test/qxBlogCpp11/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
|
||||
28
test/qxBlogCpp11/src/author.cpp
Normal file
28
test/qxBlogCpp11/src/author.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "../include/precompiled.h"
|
||||
|
||||
#include "../include/author.h"
|
||||
#include "../include/blog.h"
|
||||
|
||||
#include <QxOrm_Impl.h>
|
||||
|
||||
QX_REGISTER_CPP_QX_BLOG(author)
|
||||
|
||||
namespace qx {
|
||||
template <> void register_class(QxClass<author> & t)
|
||||
{
|
||||
t.id(& author::m_id, author::str_composite_key());
|
||||
|
||||
t.data(& author::m_name, "name");
|
||||
t.data(& author::m_birthdate, "birthdate");
|
||||
t.data(& author::m_sex, "sex");
|
||||
|
||||
t.relationOneToMany(& author::m_blogX, blog::str_composite_key(), author::str_composite_key());
|
||||
|
||||
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)
|
||||
}}
|
||||
|
||||
int author::age() const
|
||||
{
|
||||
if (! m_birthdate.isValid()) { return -1; }
|
||||
return (QDate::currentDate().year() - m_birthdate.year());
|
||||
}
|
||||
20
test/qxBlogCpp11/src/blog.cpp
Normal file
20
test/qxBlogCpp11/src/blog.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "../include/precompiled.h"
|
||||
|
||||
#include "../include/blog.h"
|
||||
|
||||
#include <QxOrm_Impl.h>
|
||||
|
||||
QX_REGISTER_CPP_QX_BLOG(blog)
|
||||
|
||||
namespace qx {
|
||||
template <> void register_class(QxClass<blog> & t)
|
||||
{
|
||||
t.id(& blog::m_id, blog::str_composite_key());
|
||||
|
||||
t.data(& blog::m_text, "blog_text");
|
||||
t.data(& blog::m_dt_creation, "date_creation");
|
||||
|
||||
t.relationManyToOne(& blog::m_author, author::str_composite_key());
|
||||
t.relationOneToMany(& blog::m_commentX, comment::str_composite_key(), blog::str_composite_key());
|
||||
t.relationManyToMany(& blog::m_categoryX, "list_category", "category_blog", blog::str_composite_key(), category::str_composite_key());
|
||||
}}
|
||||
19
test/qxBlogCpp11/src/category.cpp
Normal file
19
test/qxBlogCpp11/src/category.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "../include/precompiled.h"
|
||||
|
||||
#include "../include/category.h"
|
||||
#include "../include/blog.h"
|
||||
|
||||
#include <QxOrm_Impl.h>
|
||||
|
||||
QX_REGISTER_CPP_QX_BLOG(category)
|
||||
|
||||
namespace qx {
|
||||
template <> void register_class(QxClass<category> & t)
|
||||
{
|
||||
t.id(& category::m_id, category::str_composite_key());
|
||||
|
||||
t.data(& category::m_name, "name");
|
||||
t.data(& category::m_desc, "description");
|
||||
|
||||
t.relationManyToMany(& category::m_blogX, "list_blog", "category_blog", category::str_composite_key(), blog::str_composite_key());
|
||||
}}
|
||||
19
test/qxBlogCpp11/src/comment.cpp
Normal file
19
test/qxBlogCpp11/src/comment.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "../include/precompiled.h"
|
||||
|
||||
#include "../include/comment.h"
|
||||
#include "../include/blog.h"
|
||||
|
||||
#include <QxOrm_Impl.h>
|
||||
|
||||
QX_REGISTER_CPP_QX_BLOG(comment)
|
||||
|
||||
namespace qx {
|
||||
template <> void register_class(QxClass<comment> & t)
|
||||
{
|
||||
t.id(& comment::m_id, comment::str_composite_key());
|
||||
|
||||
t.data(& comment::m_text, "comment_text");
|
||||
t.data(& comment::m_dt_create, "date_creation");
|
||||
|
||||
t.relationManyToOne(& comment::m_blog, blog::str_composite_key());
|
||||
}}
|
||||
209
test/qxBlogCpp11/src/main.cpp
Normal file
209
test/qxBlogCpp11/src/main.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
#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("./qxBlogCpp11.sqlite");
|
||||
|
||||
// Parameters to connect to database
|
||||
qx::QxSqlDatabase::getSingleton()->setDriverName("QSQLITE");
|
||||
qx::QxSqlDatabase::getSingleton()->setDatabaseName("./qxBlogCpp11.sqlite");
|
||||
qx::QxSqlDatabase::getSingleton()->setHostName("localhost");
|
||||
qx::QxSqlDatabase::getSingleton()->setUserName("root");
|
||||
qx::QxSqlDatabase::getSingleton()->setPassword("");
|
||||
|
||||
// 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_0("_111_"); author_1->setId_1(100); author_1->setId_2("1_1");
|
||||
author_1->m_name = "author_1"; author_1->m_sex = author::male; author_1->m_birthdate = QDate::currentDate();
|
||||
author_2->setId_0("_222_"); author_2->setId_1(200); author_2->setId_2("2_2");
|
||||
author_2->m_name = "author_2"; author_2->m_sex = author::female; author_2->m_birthdate = QDate::currentDate();
|
||||
author_3->setId_0("_333_"); author_3->setId_1(300); author_3->setId_2("3_3");
|
||||
author_3->m_name = "author_3"; author_3->m_sex = author::female; author_3->m_birthdate = QDate::currentDate();
|
||||
|
||||
list_author authorX;
|
||||
authorX.insert(author_1->getId(), author_1);
|
||||
authorX.insert(author_2->getId(), author_2);
|
||||
authorX.insert(author_3->getId(), 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_to_std_shared_ptr(* author_2);
|
||||
qAssert(author_clone->getId() == author::type_composite_key("_222_", 200, "2_2"));
|
||||
qAssert(author_clone->m_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);
|
||||
|
||||
// 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->setId_0("101"); category_1->setId_1(10);
|
||||
category_1->setId_2("__11_XX"); category_1->setId_3(10010);
|
||||
category_1->m_name = "category_1"; category_1->m_desc = "desc_1";
|
||||
category_2->setId_0("202"); category_2->setId_1(20);
|
||||
category_2->setId_2("__22_XX"); category_2->setId_3(20020);
|
||||
category_2->m_name = "category_2"; category_2->m_desc = "desc_2";
|
||||
category_3->setId_0("303"); category_3->setId_1(30);
|
||||
category_3->setId_2("__33_XX"); category_3->setId_3(30030);
|
||||
category_3->m_name = "category_3"; category_3->m_desc = "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->getId() == category::type_composite_key("101", 10, "__11_XX", 10010));
|
||||
qAssert(category_2->getId() == category::type_composite_key("202", 20, "__22_XX", 20020));
|
||||
qAssert(category_3->getId() == category::type_composite_key("303", 30, "__33_XX", 30030));
|
||||
|
||||
// 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->setId_0(1);
|
||||
blog_1->setId_1("blog 1");
|
||||
blog_1->m_text = "blog_text_1";
|
||||
blog_1->m_dt_creation = QDateTime::currentDateTime();
|
||||
blog_1->m_author = 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->m_text = "update blog_text_1";
|
||||
blog_1->m_author = 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->setId_0(1);
|
||||
comment_1->setId_1("comment 1");
|
||||
comment_1->m_text = "comment_1 text";
|
||||
comment_1->m_dt_create = QDateTime::currentDateTime();
|
||||
comment_1->m_blog = blog_1;
|
||||
comment_2->setId_0(2);
|
||||
comment_2->setId_1("comment 2");
|
||||
comment_2->m_text = "comment_2 text";
|
||||
comment_2->m_dt_create = QDateTime::currentDateTime();
|
||||
comment_2->m_blog = blog_1;
|
||||
|
||||
daoError = qx::dao::insert(comment_1);
|
||||
daoError = qx::dao::insert(comment_2);
|
||||
qAssert(! daoError.isValid() && (qx::dao::count<comment>() == 2));
|
||||
|
||||
// Add 2 categories to 'blog_1' => must insert into extra-table 'category_blog'
|
||||
blog_1->m_categoryX.insert(category_1->getId(), category_1);
|
||||
blog_1->m_categoryX.insert(category_3->getId(), 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_0(blog_1->getId_0());
|
||||
blog_tmp->setId_1(blog_1->getId_1());
|
||||
daoError = qx::dao::fetch_by_id_with_all_relation(blog_tmp);
|
||||
|
||||
qAssert(! daoError.isValid());
|
||||
qAssert(blog_tmp->m_commentX.count() == 2);
|
||||
qAssert(blog_tmp->m_categoryX.count() == 2);
|
||||
qAssert(blog_tmp->m_text == "update blog_text_1");
|
||||
qAssert(blog_tmp->m_author && blog_tmp->m_author->getId() == author::type_composite_key("_222_", 200, "2_2"));
|
||||
|
||||
// Dump 'blog_tmp' result from database (xml serialization)
|
||||
qx::dump(blog_tmp);
|
||||
|
||||
// Call 'age()' method with class name and method name (reflexion)
|
||||
qx_bool bInvokeOk = qx::QxClassX::invoke("author", "age", author_1);
|
||||
qAssert(bInvokeOk);
|
||||
|
||||
// Test 'isDirty()' method
|
||||
qx::dao::ptr<blog> blog_isdirty = qx::dao::ptr<blog>(new blog());
|
||||
blog_isdirty->setId_0(blog_1->getId_0());
|
||||
blog_isdirty->setId_1(blog_1->getId_1());
|
||||
daoError = qx::dao::fetch_by_id(blog_isdirty);
|
||||
qAssert(! daoError.isValid() && ! blog_isdirty.isDirty());
|
||||
|
||||
blog_isdirty->m_text = "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("|"))); }
|
||||
|
||||
daoError = qx::dao::update(blog_isdirty);
|
||||
qAssert(! daoError.isValid() && ! blog_isdirty.isDirty());
|
||||
qx::dump(blog_isdirty);
|
||||
|
||||
// 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->m_name = "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->m_birthdate = 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("|"))); }
|
||||
|
||||
daoError = qx::dao::save(container_isdirty);
|
||||
qAssert(! daoError.isValid() && ! container_isdirty.isDirty());
|
||||
qx::dump(container_isdirty);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user