QxDao_DeleteById.inl 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. namespace qx {
  32. namespace dao {
  33. namespace detail {
  34. template <class T>
  35. struct QxDao_DeleteById_Generic
  36. {
  37. static QSqlError deleteById(T & t, QSqlDatabase * pDatabase, bool bVerifySoftDelete)
  38. {
  39. qx::IxSqlQueryBuilder * pBuilder = new qx::QxSqlQueryBuilder_DeleteById<T>(); pBuilder->init();
  40. qx::QxSoftDelete oSoftDelete = pBuilder->getSoftDelete();
  41. if (bVerifySoftDelete && ! oSoftDelete.isEmpty())
  42. { delete pBuilder; pBuilder = new qx::QxSqlQueryBuilder_SoftDeleteById<T>(); }
  43. qx::dao::detail::QxDao_Helper<T> dao(t, pDatabase, "delete by id", pBuilder);
  44. if (! dao.isValid()) { return dao.error(); }
  45. if (dao.isReadOnly()) { return dao.errReadOnly(); }
  46. if (! dao.isValidPrimaryKey(t)) { return dao.errInvalidId(); }
  47. #ifdef _QX_ENABLE_MONGODB
  48. if (dao.isMongoDB())
  49. {
  50. qx::dao::on_before_delete<T>((& t), (& dao)); if (! dao.isValid()) { return dao.error(); }
  51. qx::dao::mongodb::QxMongoDB_Helper::deleteOne((& dao), dao.getDataMemberX()->getClass(), qx::serialization::json::to_string(t, 1, "mongodb:only_id"), NULL); if (! dao.isValid()) { return dao.error(); }
  52. qx::dao::on_after_delete<T>((& t), (& dao)); if (! dao.isValid()) { return dao.error(); }
  53. return dao.error();
  54. }
  55. #endif // _QX_ENABLE_MONGODB
  56. QString sql = dao.builder().buildSql().getSqlQuery();
  57. if (! dao.getDataId() || sql.isEmpty()) { return dao.errEmpty(); }
  58. if (! dao.prepare(sql)) { return dao.errFailed(true); }
  59. IxSqlGenerator * pSqlGenerator = dao.getSqlGenerator();
  60. if (pSqlGenerator) { pSqlGenerator->onBeforeDelete((& dao), (& t)); }
  61. qx::dao::on_before_delete<T>((& t), (& dao)); if (! dao.isValid()) { return dao.error(); }
  62. {
  63. qx::dao::detail::IxDao_Timer timer((& dao), qx::dao::detail::IxDao_Helper::timer_cpp_read_instance);
  64. qx::dao::detail::QxSqlQueryHelper_DeleteById<T>::resolveInput(t, dao.query(), dao.builder());
  65. }
  66. if (! dao.exec(true)) { return dao.errFailed(); }
  67. if (pSqlGenerator) { pSqlGenerator->onAfterDelete((& dao), (& t)); }
  68. qx::dao::on_after_delete<T>((& t), (& dao)); if (! dao.isValid()) { return dao.error(); }
  69. return dao.error();
  70. }
  71. };
  72. template <class T>
  73. struct QxDao_DeleteById_Container
  74. {
  75. static QSqlError deleteById(T & t, QSqlDatabase * pDatabase, bool bVerifySoftDelete)
  76. {
  77. typedef typename qx::trait::generic_container<T>::type_value_qx type_item;
  78. qx::IxSqlQueryBuilder * pBuilder = new qx::QxSqlQueryBuilder_DeleteById<type_item>(); pBuilder->init();
  79. qx::QxSoftDelete oSoftDelete = pBuilder->getSoftDelete();
  80. if (bVerifySoftDelete && ! oSoftDelete.isEmpty())
  81. { delete pBuilder; pBuilder = new qx::QxSqlQueryBuilder_SoftDeleteById<type_item>(); }
  82. if (qx::trait::generic_container<T>::size(t) <= 0) { return QSqlError(); }
  83. qx::dao::detail::QxDao_Helper_Container<T> dao(t, pDatabase, "delete by id", pBuilder);
  84. if (! dao.isValid()) { return dao.error(); }
  85. if (dao.isReadOnly()) { return dao.errReadOnly(); }
  86. #ifdef _QX_ENABLE_MONGODB
  87. if (dao.isMongoDB())
  88. {
  89. for (typename T::iterator it = t.begin(); it != t.end(); ++it) { if (! deleteItem((* it), dao)) { return dao.error(); } }
  90. QStringList & itemsAsJson = dao.itemsAsJson();
  91. qx::dao::mongodb::QxMongoDB_Helper::deleteMany((& dao), dao.getDataMemberX()->getClass(), itemsAsJson, NULL); if (! dao.isValid()) { return dao.error(); }
  92. dao.qxQuery().queryAt(2, "<done>"); dao.itemsAsJson().clear();
  93. for (typename T::iterator it = t.begin(); it != t.end(); ++it) { if (! deleteItem((* it), dao)) { return dao.error(); } }
  94. return dao.error();
  95. }
  96. #endif // _QX_ENABLE_MONGODB
  97. QString sql = dao.builder().buildSql().getSqlQuery();
  98. if (sql.isEmpty()) { return dao.errEmpty(); }
  99. if (! dao.prepare(sql)) { return dao.errFailed(true); }
  100. for (typename T::iterator it = t.begin(); it != t.end(); ++it)
  101. { if (! deleteItem((* it), dao)) { return dao.error(); } }
  102. return dao.error();
  103. }
  104. private:
  105. template <typename U>
  106. static inline bool deleteItem(U & item, qx::dao::detail::QxDao_Helper_Container<T> & dao)
  107. { return deleteItem_Helper<U, std::is_pointer<U>::value || qx::trait::is_smart_ptr<U>::value>::deleteById(item, dao); }
  108. template <typename U, bool bIsPointer /* = true */>
  109. struct deleteItem_Helper
  110. {
  111. static inline bool deleteById(U & item, qx::dao::detail::QxDao_Helper_Container<T> & dao)
  112. { return (item ? qx::dao::detail::QxDao_DeleteById_Container<T>::deleteItem((* item), dao) : true); }
  113. };
  114. template <typename U1, typename U2>
  115. struct deleteItem_Helper<std::pair<U1, U2>, false>
  116. {
  117. static inline bool deleteById(std::pair<U1, U2> & item, qx::dao::detail::QxDao_Helper_Container<T> & dao)
  118. { return qx::dao::detail::QxDao_DeleteById_Container<T>::deleteItem(item.second, dao); }
  119. };
  120. template <typename U1, typename U2>
  121. struct deleteItem_Helper<const std::pair<U1, U2>, false>
  122. {
  123. static inline bool deleteById(const std::pair<U1, U2> & item, qx::dao::detail::QxDao_Helper_Container<T> & dao)
  124. { return qx::dao::detail::QxDao_DeleteById_Container<T>::deleteItem(item.second, dao); }
  125. };
  126. template <typename U1, typename U2>
  127. struct deleteItem_Helper<QPair<U1, U2>, false>
  128. {
  129. static inline bool deleteById(QPair<U1, U2> & item, qx::dao::detail::QxDao_Helper_Container<T> & dao)
  130. { return qx::dao::detail::QxDao_DeleteById_Container<T>::deleteItem(item.second, dao); }
  131. };
  132. template <typename U1, typename U2>
  133. struct deleteItem_Helper<const QPair<U1, U2>, false>
  134. {
  135. static inline bool deleteById(const QPair<U1, U2> & item, qx::dao::detail::QxDao_Helper_Container<T> & dao)
  136. { return qx::dao::detail::QxDao_DeleteById_Container<T>::deleteItem(item.second, dao); }
  137. };
  138. template <typename U>
  139. struct deleteItem_Helper<U, false>
  140. {
  141. static bool deleteById(U & item, qx::dao::detail::QxDao_Helper_Container<T> & dao)
  142. {
  143. if (! dao.isValidPrimaryKey(item)) { dao.errInvalidId(); return false; }
  144. #ifdef _QX_ENABLE_MONGODB
  145. if (dao.isMongoDB())
  146. {
  147. if (dao.qxQuery().queryAt(2) == "<done>") { qx::dao::on_after_delete<U>((& item), (& dao)); return dao.isValid(); }
  148. qx::dao::on_before_delete<U>((& item), (& dao)); if (! dao.isValid()) { return false; }
  149. QVariant id = (dao.getDataId() ? dao.getDataId()->toVariant(& item) : QVariant());
  150. if (! id.isNull() && ! id.toString().isEmpty()) { dao.itemsAsJson().append(id.toString()); }
  151. return dao.isValid();
  152. }
  153. #endif // _QX_ENABLE_MONGODB
  154. IxSqlGenerator * pSqlGenerator = dao.getSqlGenerator();
  155. if (pSqlGenerator) { pSqlGenerator->onBeforeDelete((& dao), (& item)); }
  156. qx::dao::on_before_delete<U>((& item), (& dao)); if (! dao.isValid()) { return false; }
  157. {
  158. qx::dao::detail::IxDao_Timer timer((& dao), qx::dao::detail::IxDao_Helper::timer_cpp_read_instance);
  159. qx::dao::detail::QxSqlQueryHelper_DeleteById<U>::resolveInput(item, dao.query(), dao.builder());
  160. }
  161. if (! dao.exec(true)) { dao.errFailed(); return false; }
  162. if (pSqlGenerator) { pSqlGenerator->onAfterDelete((& dao), (& item)); }
  163. qx::dao::on_after_delete<U>((& item), (& dao)); if (! dao.isValid()) { return false; }
  164. return dao.isValid();
  165. }
  166. };
  167. };
  168. template <class T>
  169. struct QxDao_DeleteById_Ptr
  170. {
  171. static inline QSqlError deleteById(T & t, QSqlDatabase * pDatabase, bool bVerifySoftDelete)
  172. {
  173. if (! t) { return QSqlError(); }
  174. if (bVerifySoftDelete) { return qx::dao::delete_by_id((* t), pDatabase); }
  175. return qx::dao::destroy_by_id((* t), pDatabase);
  176. }
  177. };
  178. template <class T>
  179. struct QxDao_DeleteById
  180. {
  181. static inline QSqlError deleteById(T & t, QSqlDatabase * pDatabase, bool bVerifySoftDelete)
  182. {
  183. typedef typename std::conditional< std::is_pointer<T>::value, qx::dao::detail::QxDao_DeleteById_Ptr<T>, qx::dao::detail::QxDao_DeleteById_Generic<T> >::type type_dao_1;
  184. typedef typename std::conditional< qx::trait::is_smart_ptr<T>::value, qx::dao::detail::QxDao_DeleteById_Ptr<T>, type_dao_1 >::type type_dao_2;
  185. typedef typename std::conditional< qx::trait::is_container<T>::value, qx::dao::detail::QxDao_DeleteById_Container<T>, type_dao_2 >::type type_dao_3;
  186. return type_dao_3::deleteById(t, pDatabase, bVerifySoftDelete);
  187. }
  188. };
  189. } // namespace detail
  190. } // namespace dao
  191. } // namespace qx