ECAttachmentStorage.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #ifndef EC_ATTACHMENT_STORAGE
  18. #define EC_ATTACHMENT_STORAGE
  19. #include <kopano/zcdefs.h>
  20. #include "ECDatabase.h"
  21. #include <list>
  22. #include <mutex>
  23. #include <set>
  24. #include <string>
  25. #include <dirent.h>
  26. #include <sys/types.h>
  27. struct soap;
  28. namespace KC {
  29. class ECSerializer;
  30. class ECLogger;
  31. class ECAttachmentStorage {
  32. public:
  33. ECAttachmentStorage(ECDatabase *lpDatabase, unsigned int ulCompressionLevel);
  34. ULONG AddRef();
  35. ULONG Release();
  36. static ECRESULT CreateAttachmentStorage(ECDatabase *lpDatabase, ECConfig *lpConfig, ECAttachmentStorage **lppAttachmentStorage);
  37. /* Single Instance Attachment wrappers (should not be overridden by subclasses) */
  38. bool ExistAttachment(ULONG ulObjId, ULONG ulPropId);
  39. ECRESULT LoadAttachment(struct soap *soap, ULONG ulObjId, ULONG ulPropId, size_t *lpiSize, unsigned char **lppData);
  40. ECRESULT LoadAttachment(ULONG ulObjId, ULONG ulPropId, size_t *lpiSize, ECSerializer *lpSink);
  41. ECRESULT SaveAttachment(ULONG ulObjId, ULONG ulPropId, bool bDeleteOld, size_t iSize, unsigned char *lpData, ULONG *lpulInstanceId);
  42. ECRESULT SaveAttachment(ULONG ulObjId, ULONG ulPropId, bool bDeleteOld, size_t iSize, ECSerializer *lpSource, ULONG *lpulInstanceId);
  43. ECRESULT SaveAttachment(ULONG ulObjId, ULONG ulPropId, bool bDeleteOld, ULONG ulInstanceId, ULONG *lpulInstanceId);
  44. ECRESULT CopyAttachment(ULONG ulObjId, ULONG ulNewObjId);
  45. ECRESULT DeleteAttachments(const std::list<ULONG> &lstDeleteObjects);
  46. ECRESULT DeleteAttachment(ULONG ulObjId, ULONG ulPropId);
  47. ECRESULT GetSize(ULONG ulObjId, ULONG ulPropId, size_t *lpulSize);
  48. /* Convert ObjectId (hierarchyid) into Instance Id */
  49. ECRESULT GetSingleInstanceId(ULONG ulObjId, ULONG ulPropId, ULONG *lpulInstanceId);
  50. ECRESULT GetSingleInstanceIds(const std::list<ULONG> &lstObjIds, std::list<ULONG> *lstAttachIds);
  51. /* Request parents for a particular Single Instance Id */
  52. ECRESULT GetSingleInstanceParents(ULONG ulInstanceId, std::list<ULONG> *lplstObjIds);
  53. /* Single Instance Attachment handlers (must be overridden by subclasses) */
  54. virtual bool ExistAttachmentInstance(ULONG ulInstanceId) = 0;
  55. virtual ECRESULT Begin() = 0;
  56. virtual ECRESULT Commit() = 0;
  57. virtual ECRESULT Rollback() = 0;
  58. protected:
  59. virtual ~ECAttachmentStorage(void) _kc_impdtor;
  60. /* Single Instance Attachment handlers (must be overridden by subclasses) */
  61. virtual ECRESULT LoadAttachmentInstance(struct soap *soap, ULONG ulInstanceId, size_t *lpiSize, unsigned char **lppData) = 0;
  62. virtual ECRESULT LoadAttachmentInstance(ULONG ulInstanceId, size_t *lpiSize, ECSerializer *lpSink) = 0;
  63. virtual ECRESULT SaveAttachmentInstance(ULONG ulInstanceId, ULONG ulPropId, size_t iSize, unsigned char *lpData) = 0;
  64. virtual ECRESULT SaveAttachmentInstance(ULONG ulInstanceId, ULONG ulPropId, size_t iSize, ECSerializer *lpSource) = 0;
  65. virtual ECRESULT DeleteAttachmentInstances(const std::list<ULONG> &lstDeleteInstances, bool bReplace) = 0;
  66. virtual ECRESULT DeleteAttachmentInstance(ULONG ulInstanceId, bool bReplace) = 0;
  67. virtual ECRESULT GetSizeInstance(ULONG ulInstanceId, size_t *lpulSize, bool *lpbCompressed = NULL) = 0;
  68. private:
  69. /* Add reference between Object and Single Instance */
  70. ECRESULT SetSingleInstanceId(ULONG ulObjId, ULONG ulInstanceId, ULONG ulTag);
  71. /* Count the number of times an attachment is referenced */
  72. ECRESULT IsOrphanedSingleInstance(ULONG ulInstanceId, bool *bOrphan);
  73. ECRESULT GetOrphanedSingleInstances(const std::list<ULONG> &lstInstanceIds, std::list<ULONG> *lplstOrphanedInstanceIds);
  74. ECRESULT DeleteAttachment(ULONG ulObjId, ULONG ulPropId, bool bReplace);
  75. protected:
  76. ECDatabase *m_lpDatabase;
  77. bool m_bFileCompression;
  78. std::string m_CompressionLevel;
  79. ULONG m_ulRef;
  80. std::mutex m_refcnt_lock;
  81. };
  82. class ECDatabaseAttachment _kc_final : public ECAttachmentStorage {
  83. public:
  84. ECDatabaseAttachment(ECDatabase *lpDatabase);
  85. protected:
  86. /* Single Instance Attachment handlers */
  87. virtual bool ExistAttachmentInstance(ULONG ulInstanceId);
  88. virtual ECRESULT LoadAttachmentInstance(struct soap *soap, ULONG ulInstanceId, size_t *lpiSize, unsigned char **lppData);
  89. virtual ECRESULT LoadAttachmentInstance(ULONG ulInstanceId, size_t *lpiSize, ECSerializer *lpSink);
  90. virtual ECRESULT SaveAttachmentInstance(ULONG ulInstanceId, ULONG ulPropId, size_t iSize, unsigned char *lpData);
  91. virtual ECRESULT SaveAttachmentInstance(ULONG ulInstanceId, ULONG ulPropId, size_t iSize, ECSerializer *lpSource);
  92. virtual ECRESULT DeleteAttachmentInstances(const std::list<ULONG> &lstDeleteInstances, bool bReplace);
  93. virtual ECRESULT DeleteAttachmentInstance(ULONG ulInstanceId, bool bReplace);
  94. virtual ECRESULT GetSizeInstance(ULONG ulInstanceId, size_t *lpulSize, bool *lpbCompressed = NULL);
  95. virtual ECRESULT Begin();
  96. virtual ECRESULT Commit();
  97. virtual ECRESULT Rollback();
  98. };
  99. class _kc_export_dycast ECFileAttachment _kc_final :
  100. public ECAttachmentStorage {
  101. public:
  102. _kc_hidden ECFileAttachment(ECDatabase *, const std::string &basepath, unsigned int compr_lvl, bool sync);
  103. protected:
  104. _kc_hidden virtual ~ECFileAttachment(void);
  105. /* Single Instance Attachment handlers */
  106. _kc_hidden virtual bool ExistAttachmentInstance(ULONG instance);
  107. _kc_hidden virtual ECRESULT LoadAttachmentInstance(struct soap *, ULONG instance, size_t *size, unsigned char **data);
  108. _kc_hidden virtual ECRESULT LoadAttachmentInstance(ULONG obj_id, size_t *size, ECSerializer *sink);
  109. _kc_hidden virtual ECRESULT SaveAttachmentInstance(ULONG instance, ULONG prop_id, size_t size, unsigned char *data);
  110. _kc_hidden virtual ECRESULT SaveAttachmentInstance(ULONG obj_id, ULONG prop_id, size_t size, ECSerializer *source);
  111. _kc_hidden virtual ECRESULT DeleteAttachmentInstances(const std::list<ULONG> &instances, bool replace);
  112. _kc_hidden virtual ECRESULT DeleteAttachmentInstance(ULONG instance, bool replace);
  113. _kc_hidden virtual ECRESULT GetSizeInstance(ULONG instance, size_t *size, bool *compr = nullptr);
  114. _kc_hidden virtual ECRESULT Begin(void);
  115. _kc_hidden virtual ECRESULT Commit(void);
  116. _kc_hidden virtual ECRESULT Rollback(void);
  117. private:
  118. _kc_hidden std::string CreateAttachmentFilename(ULONG instance, bool compressed);
  119. size_t attachment_size_safety_limit;
  120. int m_dirFd = -1;
  121. DIR *m_dirp = nullptr;
  122. bool force_changes_to_disk;
  123. /* helper functions for transacted deletion */
  124. _kc_hidden ECRESULT MarkAttachmentForDeletion(ULONG instance);
  125. _kc_hidden ECRESULT DeleteMarkedAttachment(ULONG instance);
  126. _kc_hidden ECRESULT RestoreMarkedAttachment(ULONG instance);
  127. _kc_hidden bool VerifyInstanceSize(ULONG instance, size_t expected_size, const std::string &filename);
  128. std::string m_basepath;
  129. bool m_bTransaction = false;
  130. std::set<ULONG> m_setNewAttachment;
  131. std::set<ULONG> m_setDeletedAttachment;
  132. std::set<ULONG> m_setMarkedAttachment;
  133. };
  134. } /* namespace */
  135. #endif