123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- /*
- * Copyright 2005 - 2016 Zarafa and its licensors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- #ifndef ECGENERIC_OBJECTTABLE_H
- #define ECGENERIC_OBJECTTABLE_H
- #define MAX_SORTKEY_LEN 4096
- #include <kopano/zcdefs.h>
- #include <mutex>
- #include "soapH.h"
- #include <list>
- #include <map>
- #include "ECSubRestriction.h"
- #include <kopano/ECKeyTable.h>
- #include "ECDatabase.h"
- #include <kopano/ustringutil.h>
- #include <kopano/ECUnknown.h>
- struct soap;
- namespace KC {
- /*
- * This object is an actual table, with a cursor in-memory. We also keep the complete
- * keyset of the table in memory, so seeks and queries can be really fast. Also, we
- * sort the table once on loading, and simply use that keyset when the rows are actually
- * required. The actual data is always loaded directly from the database.
- */
- typedef std::list<unsigned int> ECListInt;
- typedef std::list<unsigned int>::const_iterator ECListIntIterator;
- #define RESTRICT_MAX_DEPTH 16
- #define OBJECTTABLE_NOTIFY 1
- class ECSession;
- class ECCacheManager;
- typedef std::map<ECTableRow, sObjectTableKey> ECSortedCategoryMap;
- class ECCategory _kc_final {
- public:
- ECCategory(unsigned int ulCategory, struct propVal *lpProps, unsigned int cProps, unsigned int nProps, ECCategory *lpParent, unsigned int ulDepth, bool fExpanded, const ECLocale &locale);
- virtual ~ECCategory();
- void IncLeaf();
- void DecLeaf();
- void IncUnread();
- void DecUnread();
-
- unsigned int GetCount(void) const { return m_ulLeafs; }
-
- ECCategory* GetParent();
-
- ECRESULT GetProp(struct soap* soap, unsigned int ulPropTag, struct propVal *lpPropVal);
- ECRESULT SetProp(unsigned int i, struct propVal *lpPropVal);
- ECRESULT UpdateMinMax(const sObjectTableKey &sKey, unsigned int i, struct propVal *lpPropVal, bool fMax, bool *lpfModified);
- ECRESULT UpdateMinMaxRemove(const sObjectTableKey &sKey, unsigned int i, bool fMax, bool *lpfModified);
-
- size_t GetObjectSize(void) const;
- struct propVal *m_lpProps;
- unsigned int m_cProps;
- ECCategory *m_lpParent;
- unsigned int m_ulDepth;
- unsigned int m_ulCategory;
- bool m_fExpanded;
- unsigned int m_ulUnread = 0, m_ulLeafs = 0;
- const ECLocale& m_locale;
- std::map<sObjectTableKey, struct propVal *> m_mapMinMax;
- ECSortedCategoryMap::iterator iSortedCategory;
- sObjectTableKey m_sCurMinMax;
- };
- struct LEAFINFO {
- bool fUnread;
- ECCategory *lpCategory;
- };
- typedef std::map<sObjectTableKey, ECCategory *, ObjectTableKeyCompare> ECCategoryMap;
- typedef std::map<sObjectTableKey, LEAFINFO, ObjectTableKeyCompare> ECLeafMap;
- class ECGenericObjectTable;
- typedef ECRESULT (* QueryRowDataCallBack)(ECGenericObjectTable *lpThis, struct soap *soap, ECSession *lpSession, ECObjectTableList* lpRowList, struct propTagArray *lpsPropTagArray, void* lpObjectData, struct rowSet **lppRowSet, bool bTableData, bool bTableLimit);
- /*
- * ECGenericObjectTable
- *
- * Some things about adding rows:
- *
- * There are a few functions that are used to add rows, each at a different level. Here is a quick description of each
- * function, ordered in call-stack-order (top calls bottom)
- *
- * UpdateRow(type, objectid, flags)
- * - Checks security for the object
- * - Updates ALL rows for a specific object ID (usually one row since MVI is not being used)
- * AddRowKey(list_of_row_ids, number_of_rows_added *, flags)
- * - Retrieves the sort data for all rows to be added
- * - Applies restriction
- * AddRow(row_id, <sort data>, flags, hidden)
- * - Adds an actual row to the table
- * - Updates category headers
- *
- * During a row deletion, the second layer is skipped since you don't need to retrieve the sort info or do restrictions
- * on deleted rows, and UpdateRow() directly calls DeleteRow(), which is analogous to AddRow().
- *
- * Doing a re-sort deletes all rows and re-adds them from the 'AddRowKey' level.
- *
- * @todo Support more then one multi-value instance property. (Never saw this from Outlook)
- */
- class ECGenericObjectTable : public ECUnknown {
- public:
- ECGenericObjectTable(ECSession *lpSession, unsigned int ulObjType, unsigned int ulFlags, const ECLocale &locale);
- virtual ~ECGenericObjectTable();
- /**
- * An enumeration for the table reload type.
- * The table reload type determines how it should changed
- */
- enum enumReloadType {
- RELOAD_TYPE_SETCOLUMNS, /**< Reload table because changed columns */
- RELOAD_TYPE_SORTORDER /**< Reload table because changed sort order */
- };
- // Client operations
- ECRESULT SeekRow(unsigned int ulBookmark, int lSeekTo, int *lplRowsSought);
- ECRESULT FindRow(struct restrictTable *lpsRestrict, unsigned int ulBookmark, unsigned int ulFlags);
- ECRESULT GetRowCount(unsigned int *lpulRowCount, unsigned int *lpulCurrentRow);
- ECRESULT SetColumns(const struct propTagArray *lpsPropTags, bool bDefaultSet);
- ECRESULT GetColumns(struct soap *soap, ULONG ulFlags, struct propTagArray **lpsPropTags);
- ECRESULT SetSortOrder(struct sortOrderArray *, unsigned int categ, unsigned int expanded) __attribute__((nonnull));
- ECRESULT Restrict(struct restrictTable *lpsRestrict);
- ECRESULT QueryRows(struct soap *soap, unsigned int ulRowCount, unsigned int ulFlags, struct rowSet **lppRowSet);
- ECRESULT CreateBookmark(unsigned int* lpulbkPosition);
- ECRESULT FreeBookmark(unsigned int ulbkPosition);
- ECRESULT ExpandRow(struct soap *soap, xsd__base64Binary sInstanceKey, unsigned int ulRowCount, unsigned int ulFlags, struct rowSet **lppRowSet, unsigned int *lpulRowsLeft);
- ECRESULT CollapseRow(xsd__base64Binary sInstanceKey, unsigned int ulFlags, unsigned int *lpulRows);
- ECRESULT GetCollapseState(struct soap *soap, struct xsd__base64Binary sBookmark, struct xsd__base64Binary *lpsCollapseState);
- ECRESULT SetCollapseState(struct xsd__base64Binary sCollapseState, unsigned int *lpulBookmark);
- virtual ECRESULT GetColumnsAll(ECListInt* lplstProps);
- virtual ECRESULT ReloadTableMVData(ECObjectTableList* lplistRows, ECListInt* lplistMVPropTag);
- // Sort functions
- virtual ECRESULT IsSortKeyExist(const sObjectTableKey* lpsRowItem, unsigned int ulPropTag);
- virtual ECRESULT GetSortKey(sObjectTableKey* lpsRowItem, unsigned int ulPropTag, unsigned int *lpSortLen, unsigned char **lppSortData);
- virtual ECRESULT SetSortKey(sObjectTableKey* lpsRowItem, unsigned int ulPropTag, unsigned int ulSortLen, unsigned char *lpSortData);
- // Server operations
- virtual ECRESULT Clear();
- virtual ECRESULT Populate();
- virtual ECRESULT UpdateRow(unsigned int ulType, unsigned int ulObjId, unsigned int ulFlags);
- virtual ECRESULT UpdateRows(unsigned int ulType, std::list<unsigned int> *lstObjId, unsigned int ulFlags, bool bInitialLoad);
- virtual ECRESULT LoadRows(std::list<unsigned int> *lstObjId, unsigned int ulFlags);
- static ECRESULT GetRestrictPropTagsRecursive(struct restrictTable *lpsRestrict, std::list<ULONG> *lpPropTags, ULONG ulLevel);
- static ECRESULT GetRestrictPropTags(struct restrictTable *lpsRestrict, std::list<ULONG> *lpPrefixTags, struct propTagArray **lppPropTags);
- static ECRESULT MatchRowRestrict(ECCacheManager* lpCacheManager, struct propValArray *lpPropVals, struct restrictTable *lpsRestruct, SUBRESTRICTIONRESULTS *lpSubResults, const ECLocale &locale, bool *fMatch, unsigned int *lpulSubRestriction = NULL);
- virtual ECRESULT GetComputedDepth(struct soap *soap, ECSession *lpSession, unsigned int ulObjId, struct propVal *lpProp);
- bool IsMVSet();
- void SetTableId(unsigned int ulTableId);
-
- virtual ECRESULT GetPropCategory(struct soap *soap, unsigned int ulPropTag, sObjectTableKey sKey, struct propVal *lpPropVal);
- virtual unsigned int GetCategories();
- virtual size_t GetObjectSize(void);
- protected:
- // Add an actual row to the table, and send a notification if required. If you add an existing row, the row is modified and the notification is send as a modification
- ECRESULT AddRow(sObjectTableKey sRowItem, struct propVal *lpProps, unsigned int cProps, unsigned int ulFlags, bool fHidden, ECCategory *lpCategory);
- // Remove an actual row from the table, and send a notification if required. You may try to delete non-existing rows, in which case nothing happens
- ECRESULT DeleteRow(sObjectTableKey sRow, unsigned int ulFlags);
- // Send a notification by getting row data and adding the notification
- ECRESULT AddTableNotif(ECKeyTable::UpdateType, sObjectTableKey sRowItem, sObjectTableKey *lpsPrevRow);
- // Add data to key table
- ECRESULT UpdateKeyTableRow(ECCategory *lpCategory, sObjectTableKey *lpsRowKey, struct propVal *lpProps, unsigned int cValues, bool fHidden, sObjectTableKey *sPrevRow, ECKeyTable::UpdateType *lpulAction);
- // Update min/max field for category
- ECRESULT UpdateCategoryMinMax(sObjectTableKey& lpKey, ECCategory *lpCategory, size_t i, struct propVal *lpProps, size_t cProps, bool *lpfModified);
- virtual ECRESULT ReloadKeyTable();
- ECRESULT GetBinarySortKey(struct propVal *lpsPropVal, unsigned int *lpSortLen, unsigned char **lppSortData);
- ECRESULT GetSortFlags(unsigned int ulPropTag, unsigned char *lpFlags);
- virtual ECRESULT GetMVRowCount(unsigned int ulObjId, unsigned int *lpulCount);
- virtual ECRESULT ReloadTable(enumReloadType eType);
- virtual ECRESULT Load();
- virtual ECRESULT CheckPermissions(unsigned int ulObjId); // normally overridden by subclass
- const ECLocale &GetLocale() const { return m_locale; }
- // Constants
- ECSession* lpSession;
- ECKeyTable* lpKeyTable;
- unsigned int m_ulTableId = -1; /* id of the table from ECTableManager */
- void *m_lpObjectData = nullptr;
- std::recursive_mutex m_hLock; /* Lock for locked internals */
- // Locked internals
- struct sortOrderArray *lpsSortOrderArray = nullptr; /* Stored sort order */
- struct propTagArray *lpsPropTagArray = nullptr; /* Stored column set */
- struct restrictTable *lpsRestrict = nullptr; /* Stored restriction */
- ECObjectTableMap mapObjects; // Map of all objects in this table
- ECListInt m_listMVSortCols; // List of MV sort columns
- bool m_bMVCols = false; /* Are there MV props in the column list */
- bool m_bMVSort = false; /* Are there MV props in the sort order */
- unsigned int m_ulObjType;
- unsigned int m_ulFlags; //< flags from client
- QueryRowDataCallBack m_lpfnQueryRowData = nullptr;
-
- virtual ECRESULT AddRowKey(ECObjectTableList* lpRows, unsigned int *lpulLoaded, unsigned int ulFlags, bool bInitialLoad, bool bOverride, struct restrictTable *lpOverrideRestrict);
- virtual ECRESULT AddCategoryBeforeAddRow(sObjectTableKey sObjKey, struct propVal *lpProps, unsigned int cProps, unsigned int ulFlags, bool fUnread, bool *lpfHidden, ECCategory **lppCategory);
- virtual ECRESULT RemoveCategoryAfterRemoveRow(sObjectTableKey sObjKey, unsigned int ulFlags);
-
- ECCategoryMap m_mapCategories; // Map between instance key of category and category struct
- ECSortedCategoryMap m_mapSortedCategories; // Map between category sort keys and instance key. This is where we track which categories we have
- ECLeafMap m_mapLeafs; // Map between object instance key and LEAFINFO (contains unread flag and category pointer)
- unsigned int m_ulCategory = 1, m_ulCategories = 0;
- unsigned int m_ulExpanded = 0;
- bool m_bPopulated = false;
- ECLocale m_locale;
- };
- } /* namespace */
- #endif // ECGENERIC_OBJECTTABLE_H
|