platform/include/pion/platform/Database.hpp

00001 // ------------------------------------------------------------------------
00002 // Pion is a development platform for building Reactors that process Events
00003 // ------------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
00005 //
00006 // Pion is free software: you can redistribute it and/or modify it under the
00007 // terms of the GNU Affero General Public License as published by the Free
00008 // Software Foundation, either version 3 of the License, or (at your option)
00009 // any later version.
00010 //
00011 // Pion is distributed in the hope that it will be useful, but WITHOUT ANY
00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013 // FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for
00014 // more details.
00015 //
00016 // You should have received a copy of the GNU Affero General Public License
00017 // along with Pion.  If not, see <http://www.gnu.org/licenses/>.
00018 //
00019 
00020 #ifndef __PION_DATABASE_HEADER__
00021 #define __PION_DATABASE_HEADER__
00022 
00023 #include <map>
00024 #include <string>
00025 #include <boost/regex.hpp>
00026 #include <pion/PionConfig.hpp>
00027 #include <pion/platform/Event.hpp>
00028 #include <pion/platform/Vocabulary.hpp>
00029 #include <pion/platform/PlatformPlugin.hpp>
00030 #include <pion/platform/Query.hpp>
00031 #include <pion/PionLogger.hpp>
00032 
00033 
00034 namespace pion {        // begin namespace pion
00035 namespace platform {    // begin namespace platform (Pion Platform Library)
00036 
00037 
00041 class PION_PLATFORM_API Database
00042     : public PlatformPlugin
00043 {
00044 public:
00045 
00047     class DatabaseBusyException : public std::exception {
00048     public:
00049         virtual const char* what() const throw() {
00050             return "Database is busy.  Try again later";
00051         }
00052     };
00053 
00055     class QueryNotFoundException : public PionException {
00056     public:
00057         QueryNotFoundException(const std::string& query_id)
00058             : PionException("Unable find database query identified by: ", query_id) {}
00059     };
00060 
00062     class OpenDatabaseException : public PionException {
00063     public:
00064         OpenDatabaseException(const std::string& db_name)
00065             : PionException("Unable to open database: ", db_name) {}
00066     };
00067 
00069     class DatabaseConfigMissing: public PionException {
00070     public:
00071         DatabaseConfigMissing(const std::string& database_id)
00072             : PionException("Database template element missing: ", database_id) {}
00073     };
00074 
00075     class DatabaseClientException : public PionException {
00076     public:
00077         DatabaseClientException(const std::string& database_id)
00078             : PionException("Database client not defined: ", database_id) {}
00079     };
00080 
00082     class InvalidIsolationLevel : public PionException {
00083     public:
00084         InvalidIsolationLevel(const std::string& database_id)
00085             : PionException("Invalid Isolation level defined: ", database_id) {}
00086     };
00087 
00089     class BadTypePair : public PionException {
00090     public:
00091         BadTypePair(const std::string& bad_pair)
00092             : PionException("Bad SQL Type pair: ", bad_pair) {}
00093     };
00094 
00096     class MissingTypeMap : public PionException {
00097     public:
00098         MissingTypeMap(const std::string& database_id)
00099             : PionException("SQL Type map missing: ", database_id) {}
00100     };
00101 
00102     class MissingTemplateException : public PionException {
00103     public:
00104         MissingTemplateException(const std::string& database_id)
00105             : PionException("Database template file not found: ", database_id) {}
00106     };
00107 
00108     class MissingRootElementException : public PionException {
00109     public:
00110         MissingRootElementException(const std::string& database_id)
00111             : PionException("Database template file missing root element: ", database_id) {}
00112     };
00113 
00114     class ReadConfigException: public PionException {
00115     public:
00116         ReadConfigException(const std::string& database_id)
00117             : PionException("Database template file not readable: ", database_id) {}
00118     };
00119 
00121     Database(const std::string& logger_name)
00122         : m_isolation_level(IL_LevelUnknown), m_logger(PION_GET_LOGGER(logger_name))
00123     {}
00124 
00126     virtual ~Database() {}
00127 
00134     inline QueryPtr getQuery(QueryID query_id) const {
00135         QueryMap::const_iterator i = m_query_map.find(query_id);
00136         if (i == m_query_map.end())
00137             throw QueryNotFoundException(query_id);
00138         return i->second;
00139     }
00140 
00146     virtual boost::shared_ptr<Database> clone(void) const = 0;
00147 
00153     virtual void open(unsigned partition = 0) = 0;
00154 
00156     virtual void close(void) = 0;
00157 
00159     enum CACHEPARAM {
00160         CACHE_INDEX_ROW_OVERHEAD, 
00161         CACHE_PAGE_CACHE_SIZE, 
00162         CACHE_PAGE_UTILIZATION,
00163         DB_FILE_SIZE
00164     };
00165 
00167     virtual boost::uint64_t getCache(CACHEPARAM what) = 0;
00168 
00170     virtual bool is_open(void) const = 0;
00171 
00178     virtual void runQuery(const std::string& sql_query, const boost::regex& suppress) = 0;
00179 
00181     inline void runQuery(const std::string& sql_query)
00182     {
00183         static boost::regex no_suppress;
00184         runQuery(sql_query, no_suppress);
00185     }
00186 
00193     virtual QueryPtr addQuery(QueryID query_id, const std::string& sql_query) = 0;
00194 
00202     virtual void createTable(const Query::FieldMap& field_map,
00203                             std::string& table_name,
00204                             const Query::IndexMap& index_map,
00205                             unsigned partition = 0) = 0;
00206 
00213     virtual void dropTable(std::string& table_name, unsigned partition = 0) = 0;
00214 
00221     virtual bool tableExists(std::string& table_name, unsigned partition = 0) = 0;
00222 
00231     virtual QueryPtr prepareInsertQuery(const Query::FieldMap& field_map,
00232                                         const std::string& table_name) = 0;
00233 
00234     virtual QueryPtr prepareInsertIgnoreQuery(const Query::FieldMap& field_map,
00235                                         const std::string& table_name) = 0;
00236 
00245     virtual pion::platform::QueryPtr prepareFullQuery(const std::string& query, const boost::regex& suppress) = 0;
00246 
00248     inline pion::platform::QueryPtr prepareFullQuery(const std::string& query)
00249     {
00250         static boost::regex no_suppress;
00251         return prepareFullQuery(query, no_suppress);
00252     }
00253 
00259     virtual QueryPtr getBeginTransactionQuery(void) = 0;
00260 
00266     virtual QueryPtr getCommitTransactionQuery(void) = 0;
00267 
00275     virtual void setConfig(const Vocabulary& v, const xmlNodePtr config_ptr);
00276 
00284     void stringReplace(std::string& src, const char* search, const std::string& substitute);
00285 
00295     std::string& stringSubstitutes(std::string& query, const pion::platform::Query::FieldMap& field_map,
00296                                     const std::string& table_name, const std::string& columns_override = "");
00297 
00299     enum IsolationLevel_t {
00300         IL_LevelUnknown = -1,
00301         IL_ReadUncommitted,
00302         IL_ReadCommitted,
00303         IL_RepeatableRead,
00304         IL_Serializable
00305     };
00306 
00307 protected:
00308 
00310     inline void copyDatabase(const Database& d) {
00311         PlatformPlugin::copyPlugin(d);
00312         // clone all the top level defined member variables
00313         m_database_engine = d.m_database_engine;
00314         m_database_client = d.m_database_client;
00315         m_begin_insert = d.m_begin_insert;
00316         m_commit_insert = d.m_commit_insert;
00317         m_create_log = d.m_create_log;
00318         m_create_log_attr = d.m_create_log_attr;
00319         m_insert_log = d.m_insert_log;
00320         m_insert_log_attr = d.m_insert_log_attr;
00321         m_create_stat = d.m_create_stat;
00322         m_create_stat_attr = d.m_create_stat_attr;
00323         m_update_stat = d.m_update_stat;
00324         m_update_stat_attr = d.m_update_stat_attr;
00325         m_select_stat = d.m_select_stat;
00326         m_select_stat_attr = d.m_select_stat_attr;
00327         m_drop_index = d.m_drop_index;
00328         m_drop_index_attr = d.m_drop_index_attr;
00329         m_create_index_normal = d.m_create_index_normal;
00330         m_create_index_normal_attr = d.m_create_index_normal_attr;
00331         m_create_index_unique = d.m_create_index_unique;
00332         m_create_index_unique_attr = d.m_create_index_unique_attr;
00333         m_create_index_custom = d.m_create_index_custom;
00334         m_create_index_custom_attr = d.m_create_index_custom_attr;
00335         m_isolation_level = d.m_isolation_level;
00336         // Query_map will be overridden
00337 //      m_query_map = d.m_query_map;
00338         m_sql_affinity = d.m_sql_affinity;
00339         m_pre_sql = d.m_pre_sql;
00340         m_pre_sql_attr = d.m_pre_sql_attr;
00341         m_options = d.m_options;
00342         m_options_values = d.m_options_values;
00343         m_insert_ignore = d.m_insert_ignore;
00344         m_drop_table = d.m_drop_table;
00345         m_drop_table_attr = d.m_drop_table_attr;
00346     }
00347 
00348 
00350     typedef std::map<QueryID, QueryPtr>     QueryMap;
00351 
00353     static const std::string                INSERT_QUERY_ID;
00354     static const std::string                INSERT_IGNORE_QUERY_ID;
00355 
00356 
00358     static const std::string                BEGIN_QUERY_ID;
00359 
00361     static const std::string                COMMIT_QUERY_ID;
00362 
00363     static const std::string                MAP_ELEMENT_NAME;
00364     static const std::string                PAIR_ELEMENT_NAME;
00365 
00366     static const std::string                CLIENT_ELEMENT_NAME;
00367     static const std::string                BEGIN_ELEMENT_NAME;
00368     static const std::string                COMMIT_ELEMENT_NAME;
00369     static const std::string                CREATE_LOG_ELEMENT_NAME;
00370     static const std::string                INSERT_LOG_ELEMENT_NAME;
00371     static const std::string                ISOLATION_ELEMENT_NAME;
00372     static const std::string                PRESQL_ELEMENT_NAME;
00373     static const std::string                OPTION_ELEMENT_NAME;
00374 
00375     static const std::string                CREATE_STAT_ELEMENT_NAME;
00376     static const std::string                UPDATE_STAT_ELEMENT_NAME;
00377     static const std::string                SELECT_STAT_ELEMENT_NAME;
00378 
00379     static const std::string                DROP_INDEX_ELEMENT_NAME;
00380     static const std::string                CREATE_INDEX_NORMAL_ELEMENT_NAME;
00381     static const std::string                CREATE_INDEX_UNIQUE_ELEMENT_NAME;
00382     static const std::string                CREATE_INDEX_CUSTOM_ELEMENT_NAME;
00383 
00384     static const std::string                IGNORE_ATTRIBUTE_NAME;
00385     static const std::string                OPTION_ATTRIBUTE_NAME;
00386 
00387     static const std::string                INSERT_IGNORE_ELEMENT_NAME;
00388     static const std::string                DROP_TABLE_ELEMENT_NAME;
00389 
00390 
00397     void readConfig(const xmlNodePtr config_ptr, std::string engine_str);
00398 
00404     void readConfigDetails(const xmlNodePtr config_ptr);
00405 
00408     std::string                             m_database_engine;
00409 
00411     std::string                             m_database_client;
00412 
00414     std::string                             m_begin_insert;
00415     std::string                             m_commit_insert;
00416 
00418     std::string                             m_create_log;
00419     boost::regex                            m_create_log_attr;
00420 
00421     std::string                             m_insert_log;
00422     boost::regex                            m_insert_log_attr;
00423 
00424     std::string                             m_create_stat;
00425     boost::regex                            m_create_stat_attr;
00426 
00427     std::string                             m_update_stat;
00428     boost::regex                            m_update_stat_attr;
00429 
00430     std::string                             m_select_stat;
00431     boost::regex                            m_select_stat_attr;
00432 
00433     std::string                             m_drop_index;
00434     boost::regex                            m_drop_index_attr;
00435 
00436     std::string                             m_create_index_normal;
00437     boost::regex                            m_create_index_normal_attr;
00438 
00439     std::string                             m_create_index_unique;
00440     boost::regex                            m_create_index_unique_attr;
00441 
00442     std::string                             m_create_index_custom;
00443     boost::regex                            m_create_index_custom_attr;
00444 
00445     std::string                             m_insert_ignore;
00446     boost::regex                            m_insert_ignore_attr;
00447 
00448     std::string                             m_drop_table;
00449     boost::regex                            m_drop_table_attr;
00450 
00452     IsolationLevel_t                        m_isolation_level;
00453 
00455     QueryMap                                m_query_map;
00456 
00458     std::vector<std::string>                m_sql_affinity;
00459 
00461     std::vector<std::string>                m_pre_sql;
00462 
00464     std::vector<boost::regex>               m_pre_sql_attr;
00465 
00467     std::vector<std::string>                m_options;
00468 
00470     std::vector<std::string>                m_options_values;
00471 
00473     PionLogger                              m_logger;
00474 };
00475 
00476 
00478 typedef boost::shared_ptr<Database>         DatabasePtr;
00479 
00480 
00481 //
00482 // The following symbols must be defined for any Databases that you would
00483 // like to be able to load dynamically using the DatabaseManager::load()
00484 // function.  These are not required for any Databases that you only want
00485 // to link directly into your programs.
00486 //
00487 // Make sure that you replace "DATABASE" with the name of your derived class.
00488 // This name must also match the name of the object file (excluding the
00489 // extension).  These symbols must be linked into your Database's object
00490 // file, not included in any headers that it may use (declarations are OK in
00491 // headers but not the definitions).
00492 //
00493 // The "pion_create" function is used to create new instances of your Database.
00494 // The "pion_destroy" function is used to destroy instances of your Database.
00495 //
00496 // extern "C" PION_PLUGIN_API Database *pion_create_DATABASE(void) {
00497 //      return new DATABASE;
00498 // }
00499 //
00500 // extern "C" PION_PLUGIN_API void pion_destroy_DATABASE(DATABASE *database_ptr) {
00501 //      delete database_ptr;
00502 // }
00503 //
00504 
00505 
00506 }   // end namespace platform
00507 }   // end namespace pion
00508 
00509 #endif

Generated on Wed Apr 13 16:38:34 2011 for pion-platform by  doxygen 1.4.7