diff --git a/arangod/Cluster/ClusterInfo.cpp b/arangod/Cluster/ClusterInfo.cpp index e128629878..73de329edb 100644 --- a/arangod/Cluster/ClusterInfo.cpp +++ b/arangod/Cluster/ClusterInfo.cpp @@ -901,11 +901,83 @@ std::shared_ptr ClusterInfo::getCollectionCurrent( return std::make_shared(0); } +////////////////////////////////////////////////////////////////////////////// +/// @brief ask about a view +/// If it is not found in the cache, the cache is reloaded once. The second +/// argument can be a collection ID or a view name (both cluster-wide). +////////////////////////////////////////////////////////////////////////////// + std::shared_ptr ClusterInfo::getView( - DatabaseID const& vocbase, CollectionID const& view -) { - // FIXME TODO implement - return nullptr; + DatabaseID const& databaseID, ViewID const& viewID) { + + int tries = 0; + + if (!_planProt.isValid) { + loadPlan(); + ++tries; + } + + while (true) { // left by break + { + READ_LOCKER(readLocker, _planProt.lock); + // look up database by id + AllViews::const_iterator it = _plannedViews.find(databaseID); + + if (it != _plannedViews.end()) { + // look up view by id (or by name) + DatabaseViews::const_iterator it2 = + (*it).second.find(viewID); + + if (it2 != (*it).second.end()) { + return (*it2).second; + } + } + } + if (++tries >= 2) { + break; + } + + // must load plan outside the lock + loadPlan(); + } + THROW_ARANGO_EXCEPTION_MESSAGE( + TRI_ERROR_ARANGO_VIEW_NOT_FOUND, + "View not found: " + viewID + " in database " + databaseID); +} + +////////////////////////////////////////////////////////////////////////////// +/// @brief ask about all views of a database +////////////////////////////////////////////////////////////////////////////// + +std::vector> const ClusterInfo::getViews( + DatabaseID const& databaseID) { + std::vector> result; + + // always reload + loadPlan(); + + READ_LOCKER(readLocker, _planProt.lock); + // look up database by id + AllViews::const_iterator it = _plannedViews.find(databaseID); + + if (it == _plannedViews.end()) { + return result; + } + + // iterate over all collections + DatabaseViews::const_iterator it2 = (*it).second.begin(); + while (it2 != (*it).second.end()) { + char c = (*it2).first[0]; + + if (c < '0' || c > '9') { + // skip collections indexed by id + result.push_back((*it2).second); + } + + ++it2; + } + + return result; } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Cluster/ClusterInfo.h b/arangod/Cluster/ClusterInfo.h index f40f1b01ff..365514c97b 100644 --- a/arangod/Cluster/ClusterInfo.h +++ b/arangod/Cluster/ClusterInfo.h @@ -51,6 +51,7 @@ class LogicalCollection; typedef std::string ServerID; // ID of a server typedef std::string DatabaseID; // ID/name of a database typedef std::string CollectionID; // ID of a collection +typedef std::string ViewID; // ID of a view typedef std::string ShardID; // ID of a shard class CollectionInfoCurrent { @@ -226,6 +227,10 @@ class ClusterInfo { typedef std::unordered_map AllCollectionsCurrent; + typedef std::unordered_map> + DatabaseViews; + typedef std::unordered_map AllViews; + private: ////////////////////////////////////////////////////////////////////////////// /// @brief initializes library @@ -315,7 +320,7 @@ class ClusterInfo { CollectionID const&); ////////////////////////////////////////////////////////////////////////////// - /// @brief ask about all collections + /// @brief ask about all collections of a database ////////////////////////////////////////////////////////////////////////////// virtual std::vector> const getCollections( @@ -326,9 +331,16 @@ class ClusterInfo { /// If it is not found in the cache, the cache is reloaded once. The second /// argument can be a collection ID or a view name (both cluster-wide). ////////////////////////////////////////////////////////////////////////////// + std::shared_ptr getView( - DatabaseID const& vocbase, CollectionID const& view - ); + DatabaseID const& vocbase, ViewID const& viewID); + + ////////////////////////////////////////////////////////////////////////////// + /// @brief ask about all views of a database + ////////////////////////////////////////////////////////////////////////////// + + std::vector> const getViews( + DatabaseID const&); ////////////////////////////////////////////////////////////////////////////// /// @brief (re-)load the information about current collections from the agency @@ -659,6 +671,8 @@ class ClusterInfo { // planned shard => servers map std::unordered_map> _shardServers; + AllViews _plannedViews; // from Plan/Views/ + // The Current state: AllCollectionsCurrent _currentCollections; // from Current/Collections/ std::unordered_map>> @@ -709,4 +723,4 @@ class ClusterInfo { } // end namespace arangodb -#endif \ No newline at end of file +#endif