| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| **/ |
| |
| #ifndef QUICKSTEP_CATALOG_CATALOG_HPP_ |
| #define QUICKSTEP_CATALOG_CATALOG_HPP_ |
| |
| #include <exception> |
| #include <string> |
| #include <unordered_map> |
| |
| #include "catalog/Catalog.pb.h" |
| #include "catalog/CatalogDatabase.hpp" |
| #include "catalog/CatalogTypedefs.hpp" |
| #include "utility/Macros.hpp" |
| #include "utility/PtrVector.hpp" |
| |
| namespace quickstep { |
| |
| /** \addtogroup Catalog |
| * @{ |
| */ |
| |
| /** |
| * @brief Exception thrown for a database name collision. |
| **/ |
| class DatabaseNameCollision : public std::exception { |
| public: |
| /** |
| * @brief Constructor. |
| * |
| * @param db_name The name of the database for which there was a collision. |
| **/ |
| explicit DatabaseNameCollision(const std::string &db_name) |
| : message_("DatabaseNameCollision: catalog already has a database ") { |
| message_.append(db_name); |
| } |
| |
| ~DatabaseNameCollision() throw() { |
| } |
| |
| virtual const char* what() const throw() { |
| return message_.c_str(); |
| } |
| |
| private: |
| std::string message_; |
| }; |
| |
| |
| /** |
| * @brief Exception thrown when a database with the specified name can't be |
| * found. |
| **/ |
| class DatabaseNameNotFound : public std::exception { |
| public: |
| /** |
| * @brief Constructor. |
| * |
| * @param dbName The database name which could not be found. |
| **/ |
| explicit DatabaseNameNotFound(const std::string &db_name) |
| : message_("DatabaseNameNotFound: catalog has no database named ") { |
| message_.append(db_name); |
| } |
| |
| ~DatabaseNameNotFound() throw() { |
| } |
| |
| virtual const char* what() const throw() { |
| return message_.c_str(); |
| } |
| |
| private: |
| std::string message_; |
| }; |
| |
| |
| /** |
| * @brief Exception thrown when a database with the specified ID can't be |
| * found. |
| **/ |
| class DatabaseIdNotFound : public std::exception { |
| public: |
| /** |
| * @brief Constructor. |
| * |
| * @param id The id which could not be found. |
| **/ |
| explicit DatabaseIdNotFound(const database_id id) |
| : message_("DatabaseIdNotFound: catalog has no database with ID ") { |
| message_.append(std::to_string(id)); |
| } |
| |
| ~DatabaseIdNotFound() throw() { |
| } |
| |
| virtual const char* what() const throw() { |
| return message_.c_str(); |
| } |
| |
| private: |
| std::string message_; |
| }; |
| |
| |
| /** |
| * @brief The entire database catalog. |
| **/ |
| class Catalog { |
| public: |
| typedef std::unordered_map<std::string, CatalogDatabase*>::size_type size_type; |
| typedef PtrVector<CatalogDatabase, true>::const_skip_iterator const_iterator; |
| |
| /** |
| * @brief Construct an empty catalog. |
| **/ |
| Catalog() { |
| } |
| |
| /** |
| * @brief Reconstruct a catalog from its serialized Protocol Buffer form. |
| * |
| * @param proto The Protocol Buffer serialization of a catalog, |
| * previously produced by getProto(). |
| **/ |
| explicit Catalog(const serialization::Catalog &proto); |
| |
| /** |
| * @brief Destructor which recursively destroys children. |
| **/ |
| ~Catalog() { |
| } |
| |
| /** |
| * @brief Check whether a database with the given name exists. |
| * |
| * @param db_name The name to check for. |
| * @return Whether the database exists. |
| **/ |
| bool hasDatabaseWithName(const std::string &db_name) const { |
| return (db_map_.find(db_name) != db_map_.end()); |
| } |
| |
| /** |
| * @brief Check whether a database with the given id exists. |
| * |
| * @param id The id to check for. |
| * @return Whether the database exists. |
| **/ |
| bool hasDatabaseWithId(const database_id id) const { |
| return (idInRange(id) && !db_vec_.elementIsNull(id)); |
| } |
| |
| /** |
| * @brief Get a database by name. |
| * |
| * @param db_name The name to search for. |
| * @exception DatabaseNameNotFound No database with the given name exists. |
| * @return The database with the given name. |
| **/ |
| const CatalogDatabase& getDatabaseByName(const std::string &db_name) const; |
| |
| /** |
| * @brief Get a mutable pointer to a database by name. |
| * |
| * @param db_name The name to search for. |
| * @exception DatabaseNameNotFound No database with the given name exists. |
| * @return The database with the given name. |
| **/ |
| CatalogDatabase* getDatabaseByNameMutable(const std::string &db_name); |
| |
| /** |
| * @brief Get a database by ID. |
| * |
| * @param id The id to search for. |
| * @exception DatabaseIdNotFound No database with the given ID exists. |
| * @return The database with the given ID. |
| **/ |
| const CatalogDatabase& getDatabaseById(const database_id id) const { |
| if (hasDatabaseWithId(id)) { |
| return db_vec_[id]; |
| } else { |
| throw DatabaseIdNotFound(id); |
| } |
| } |
| |
| /** |
| * @brief Get a mutable pointer to a database by ID. |
| * |
| * @param id The id to search for. |
| * @exception DatabaseIdNotFound No database with the given ID exists. |
| * @return The database with the given ID. |
| **/ |
| CatalogDatabase* getDatabaseByIdMutable(const database_id id) { |
| if (hasDatabaseWithId(id)) { |
| return &(db_vec_[id]); |
| } else { |
| throw DatabaseIdNotFound(id); |
| } |
| } |
| |
| /** |
| * @brief Add a new database to the catalog. If the database already has an |
| * ID and/or parent, it will be overwritten. |
| * |
| * @param new_db The database to be added. |
| * @exception DatabaseNameCollision A database with the same name as new_db |
| * is already present in the catalog. |
| * @return The id assigned to the database. |
| **/ |
| database_id addDatabase(CatalogDatabase *new_db); |
| |
| /** |
| * @brief Serialize the catalog as Protocol Buffer. |
| * |
| * @return The Protocol Buffer representation of the catalog. |
| **/ |
| serialization::Catalog getProto() const; |
| |
| /** |
| * @brief Get the number of child databases. |
| * |
| * @return The number of child databases. |
| **/ |
| size_type size() const { |
| return db_map_.size(); |
| } |
| |
| /** |
| * @brief Get an iterator at the beginning of the child databases. |
| * |
| * @return An iterator on the first child database. |
| **/ |
| const_iterator begin() const { |
| return db_vec_.begin_skip(); |
| } |
| |
| /** |
| * @brief Get an iterator at one-past-the-end of the child databases. |
| * |
| * @return An iterator one-past-the-end of the child databases. |
| **/ |
| const_iterator end() const { |
| return db_vec_.end_skip(); |
| } |
| |
| private: |
| /** |
| * @brief Check whether a database_id is within the range of IDs contained |
| * in this Catalog. |
| * |
| * @param id The id to check. |
| * @return true if id is in range, false otherwise. |
| **/ |
| bool idInRange(const database_id id) const { |
| return ((id >= 0) |
| && (static_cast<PtrVector<CatalogDatabase>::size_type>(id) < db_vec_.size())); |
| } |
| |
| /** |
| * @brief Check whether a serialization::Catalog is fully-formed and |
| * all parts are valid. |
| * |
| * @param proto A serialized Protocol Buffer representation of a Catalog, |
| * originally generated by getProto(). |
| * @return Whether proto is fully-formed and valid. |
| **/ |
| static bool ProtoIsValid(const serialization::Catalog &proto); |
| |
| // A vector of databases, and NULL if it has dropped from the catalog. |
| PtrVector<CatalogDatabase, true> db_vec_; |
| |
| // A map from a database name to a pointer to the database. |
| std::unordered_map<std::string, CatalogDatabase*> db_map_; |
| |
| DISALLOW_COPY_AND_ASSIGN(Catalog); |
| }; |
| |
| /** @} */ |
| |
| } // namespace quickstep |
| |
| #endif // QUICKSTEP_CATALOG_CATALOG_HPP_ |