QxSqlRelation.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /****************************************************************************
  2. **
  3. ** https://www.qxorm.com/
  4. ** Copyright (C) 2013 Lionel Marty (contact@qxorm.com)
  5. **
  6. ** This file is part of the QxOrm library
  7. **
  8. ** This software is provided 'as-is', without any express or implied
  9. ** warranty. In no event will the authors be held liable for any
  10. ** damages arising from the use of this software
  11. **
  12. ** Commercial Usage
  13. ** Licensees holding valid commercial QxOrm licenses may use this file in
  14. ** accordance with the commercial license agreement provided with the
  15. ** Software or, alternatively, in accordance with the terms contained in
  16. ** a written agreement between you and Lionel Marty
  17. **
  18. ** GNU General Public License Usage
  19. ** Alternatively, this file may be used under the terms of the GNU
  20. ** General Public License version 3.0 as published by the Free Software
  21. ** Foundation and appearing in the file 'license.gpl3.txt' included in the
  22. ** packaging of this file. Please review the following information to
  23. ** ensure the GNU General Public License version 3.0 requirements will be
  24. ** met : http://www.gnu.org/copyleft/gpl.html
  25. **
  26. ** If you are unsure which license is appropriate for your use, or
  27. ** if you have questions regarding the use of this file, please contact :
  28. ** contact@qxorm.com
  29. **
  30. ****************************************************************************/
  31. #ifndef _QX_SQL_RELATION_H_
  32. #define _QX_SQL_RELATION_H_
  33. #ifdef _MSC_VER
  34. #pragma once
  35. #endif
  36. /*!
  37. * \file QxSqlRelation.h
  38. * \author Lionel Marty
  39. * \ingroup QxDao
  40. * \brief Base class for all relationships defined between 2 classes (or between 2 tables in database)
  41. */
  42. #include <QxDao/QxDao.h>
  43. #include <QxDao/IxSqlRelation.h>
  44. #include <QxDao/IxSqlQueryBuilder.h>
  45. #include <QxTraits/remove_attr.h>
  46. #include <QxTraits/remove_smart_ptr.h>
  47. #include <QxTraits/generic_container.h>
  48. #include <QxTraits/is_container.h>
  49. #include <QxTraits/is_valid_primary_key.h>
  50. #include <QxTraits/is_qx_registered.h>
  51. #include <QxRegister/IxClass.h>
  52. namespace qx {
  53. template <class T>
  54. class QxClass;
  55. /*!
  56. * \ingroup QxDao
  57. * \brief qx::QxSqlRelation<DataType, Owner> : base class for all relationships defined between 2 classes (or between 2 tables in database)
  58. */
  59. template <class DataType, class Owner>
  60. class QxSqlRelation : public IxSqlRelation
  61. {
  62. protected:
  63. typedef typename qx::trait::remove_attr<DataType>::type type_tmp_1;
  64. typedef typename qx::trait::remove_smart_ptr<type_tmp_1>::type type_tmp_2;
  65. typedef type_tmp_2 type_container;
  66. typedef qx::trait::generic_container<type_container> type_generic_container;
  67. typedef typename type_generic_container::type_item type_item;
  68. typedef typename std::conditional<qx::trait::is_container<type_container>::value, typename type_generic_container::type_value_qx, type_container>::type type_tmp_3;
  69. typedef typename QxSqlRelation<DataType, Owner>::type_tmp_3 type_data;
  70. typedef Owner type_owner;
  71. enum { is_valid = (qx::trait::is_qx_registered<type_data>::value && qx::trait::is_qx_registered<type_owner>::value) };
  72. enum { is_data_pointer = (std::is_pointer<DataType>::value || qx::trait::is_smart_ptr<DataType>::value) };
  73. enum { is_data_container = qx::trait::is_container<type_container>::value };
  74. enum { is_same_data_owner = std::is_same<type_data, type_owner>::value };
  75. public:
  76. QxSqlRelation(IxDataMember * p) : IxSqlRelation(p) { this->setIsSameDataOwner(static_cast<int>(is_same_data_owner)); }
  77. virtual ~QxSqlRelation() { static_assert(is_valid, "is_valid"); }
  78. virtual void init()
  79. {
  80. if (! this->canInit()) { return; }
  81. this->setClass(QxClass<type_data>::getSingleton(), QxClass<type_owner>::getSingleton());
  82. IxSqlRelation::init();
  83. }
  84. protected:
  85. DataType * getDataTypePtr(QxSqlRelationParams & params) const
  86. { qAssert(params.owner() && this->getDataMember()); return static_cast<DataType *>(this->getDataMember()->getValueVoidPtr(params.owner())); }
  87. type_owner & getOwner(QxSqlRelationParams & params) const
  88. { qAssert(params.owner()); return (* static_cast<type_owner *>(params.owner())); }
  89. type_data & getData(QxSqlRelationParams & params) const
  90. { return getData_Helper<is_data_pointer, is_data_container, 0>::get(getDataTypePtr(params)); }
  91. type_container & getContainer(QxSqlRelationParams & params) const
  92. { return getContainer_Helper<is_data_pointer, is_data_container, 0>::get(getDataTypePtr(params)); }
  93. type_item createItem() const
  94. { return createItem_Helper<is_data_container, 0>::get(); }
  95. bool isNullData(QxSqlRelationParams & params) const
  96. { return isNullData_Helper<is_data_pointer, 0>::get(getDataTypePtr(params)); }
  97. bool callTriggerBeforeFetch(type_data & t, QxSqlRelationParams & params) const
  98. {
  99. if (! params.builder().getDaoHelper()) { return true; }
  100. qx::dao::on_before_fetch<type_data>((& t), params.builder().getDaoHelper());
  101. return params.builder().getDaoHelper()->isValid();
  102. }
  103. bool callTriggerAfterFetch(type_data & t, QxSqlRelationParams & params) const
  104. {
  105. if (! params.builder().getDaoHelper()) { return true; }
  106. qx::dao::on_after_fetch<type_data>((& t), params.builder().getDaoHelper());
  107. return params.builder().getDaoHelper()->isValid();
  108. }
  109. private:
  110. template <bool bIsPointer /* = false */, bool bIsContainer /* = false */, int dummy>
  111. struct getData_Helper
  112. { static type_data & get(DataType * t) { return (* t); } };
  113. template <int dummy>
  114. struct getData_Helper<true, false, dummy>
  115. { static type_data & get(DataType * t) { if (! (* t)) { qx::trait::construct_ptr<DataType>::get(* t); }; return (** t); } };
  116. template <int dummy>
  117. struct getData_Helper<false, true, dummy>
  118. { static type_data & get(DataType * t) { qAssert(false); Q_UNUSED(t); type_data * pDummy(NULL); return (* pDummy); } };
  119. template <int dummy>
  120. struct getData_Helper<true, true, dummy>
  121. { static type_data & get(DataType * t) { qAssert(false); Q_UNUSED(t); type_data * pDummy(NULL); return (* pDummy); } };
  122. template <bool bIsPointer /* = false */, bool bIsContainer /* = false */, int dummy>
  123. struct getContainer_Helper
  124. { static type_container & get(DataType * t) { qAssert(false); Q_UNUSED(t); type_container * pDummy(NULL); return (* pDummy); } };
  125. template <int dummy>
  126. struct getContainer_Helper<true, false, dummy>
  127. { static type_container & get(DataType * t) { qAssert(false); Q_UNUSED(t); type_container * pDummy(NULL); return (* pDummy); } };
  128. template <int dummy>
  129. struct getContainer_Helper<false, true, dummy>
  130. { static type_container & get(DataType * t) { return (* t); } };
  131. template <int dummy>
  132. struct getContainer_Helper<true, true, dummy>
  133. { static type_container & get(DataType * t) { if (! (* t)) { qx::trait::construct_ptr<DataType>::get(* t); }; return (** t); } };
  134. template <bool bIsContainer /* = false */, int dummy>
  135. struct createItem_Helper
  136. { static type_item get() { qAssert(false); type_item * pDummy(NULL); return (* pDummy); } };
  137. template <int dummy>
  138. struct createItem_Helper<true, dummy>
  139. { static type_item get() { return type_generic_container::createItem(); } };
  140. template <bool bIsPointer /* = false */, int dummy>
  141. struct isNullData_Helper
  142. { static bool get(DataType * t) { Q_UNUSED(t); return false; } };
  143. template <int dummy>
  144. struct isNullData_Helper<true, dummy>
  145. { static bool get(DataType * t) { return ((! (* t)) ? true : false); } };
  146. };
  147. } // namespace qx
  148. #include <QxDao/QxSqlRelation_OneToOne.h>
  149. #include <QxDao/QxSqlRelation_OneToMany.h>
  150. #include <QxDao/QxSqlRelation_ManyToOne.h>
  151. #include <QxDao/QxSqlRelation_ManyToMany.h>
  152. #include <QxDao/QxSqlRelation_RawData.h>
  153. #endif // _QX_SQL_RELATION_H_