1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ 2 3 #ifndef DBCONNECTION_H 4 #define DBCONNECTION_H 5 6 #include "db_ido/i2-db_ido.hpp" 7 #include "db_ido/dbconnection-ti.hpp" 8 #include "db_ido/dbobject.hpp" 9 #include "db_ido/dbquery.hpp" 10 #include "base/timer.hpp" 11 #include "base/ringbuffer.hpp" 12 #include <boost/thread/once.hpp> 13 #include <mutex> 14 15 namespace icinga 16 { 17 18 /** 19 * A database connection. 20 * 21 * @ingroup db_ido 22 */ 23 class DbConnection : public ObjectImpl<DbConnection> 24 { 25 public: 26 DECLARE_OBJECT(DbConnection); 27 28 static void InitializeDbTimer(); 29 30 virtual const char * GetLatestSchemaVersion() const noexcept = 0; 31 virtual const char * GetCompatSchemaVersion() const noexcept = 0; 32 33 void SetConfigHash(const DbObject::Ptr& dbobj, const String& hash); 34 void SetConfigHash(const DbType::Ptr& type, const DbReference& objid, const String& hash); 35 String GetConfigHash(const DbObject::Ptr& dbobj) const; 36 String GetConfigHash(const DbType::Ptr& type, const DbReference& objid) const; 37 38 void SetObjectID(const DbObject::Ptr& dbobj, const DbReference& dbref); 39 DbReference GetObjectID(const DbObject::Ptr& dbobj) const; 40 41 void SetInsertID(const DbObject::Ptr& dbobj, const DbReference& dbref); 42 void SetInsertID(const DbType::Ptr& type, const DbReference& objid, const DbReference& dbref); 43 DbReference GetInsertID(const DbObject::Ptr& dbobj) const; 44 DbReference GetInsertID(const DbType::Ptr& type, const DbReference& objid) const; 45 46 void SetObjectActive(const DbObject::Ptr& dbobj, bool active); 47 bool GetObjectActive(const DbObject::Ptr& dbobj) const; 48 49 void ClearIDCache(); 50 51 void SetConfigUpdate(const DbObject::Ptr& dbobj, bool hasupdate); 52 bool GetConfigUpdate(const DbObject::Ptr& dbobj) const; 53 54 void SetStatusUpdate(const DbObject::Ptr& dbobj, bool hasupdate); 55 bool GetStatusUpdate(const DbObject::Ptr& dbobj) const; 56 57 int GetQueryCount(RingBuffer::SizeType span); 58 virtual int GetPendingQueryCount() const = 0; 59 60 void ValidateFailoverTimeout(const Lazy<double>& lvalue, const ValidationUtils& utils) final; 61 void ValidateCategories(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) final; 62 63 protected: 64 void OnConfigLoaded() override; 65 void Start(bool runtimeCreated) override; 66 void Stop(bool runtimeRemoved) override; 67 void Resume() override; 68 void Pause() override; 69 70 virtual void ExecuteQuery(const DbQuery& query) = 0; 71 virtual void ExecuteMultipleQueries(const std::vector<DbQuery>&) = 0; 72 virtual void ActivateObject(const DbObject::Ptr& dbobj) = 0; 73 virtual void DeactivateObject(const DbObject::Ptr& dbobj) = 0; 74 75 virtual void CleanUpExecuteQuery(const String& table, const String& time_column, double max_age); 76 virtual void FillIDCache(const DbType::Ptr& type) = 0; 77 virtual void NewTransaction() = 0; 78 virtual void Disconnect() = 0; 79 80 void UpdateObject(const ConfigObject::Ptr& object); 81 void UpdateAllObjects(); 82 83 void PrepareDatabase(); 84 85 void IncreaseQueryCount(); 86 87 bool IsIDCacheValid() const; 88 void SetIDCacheValid(bool valid); 89 90 void EnableActiveChangedHandler(); 91 92 static void UpdateProgramStatus(); 93 94 static int GetSessionToken(); 95 96 void IncreasePendingQueries(int count); 97 void DecreasePendingQueries(int count); 98 99 WorkQueue m_QueryQueue{10000000, 1, LogNotice}; 100 101 private: 102 bool m_IDCacheValid{false}; 103 std::map<std::pair<DbType::Ptr, DbReference>, String> m_ConfigHashes; 104 std::map<DbObject::Ptr, DbReference> m_ObjectIDs; 105 std::map<std::pair<DbType::Ptr, DbReference>, DbReference> m_InsertIDs; 106 std::set<DbObject::Ptr> m_ActiveObjects; 107 std::set<DbObject::Ptr> m_ConfigUpdates; 108 std::set<DbObject::Ptr> m_StatusUpdates; 109 Timer::Ptr m_CleanUpTimer; 110 Timer::Ptr m_LogStatsTimer; 111 112 double m_LogStatsTimeout; 113 114 void CleanUpHandler(); 115 void LogStatsHandler(); 116 117 static Timer::Ptr m_ProgramStatusTimer; 118 static boost::once_flag m_OnceFlag; 119 120 static void InsertRuntimeVariable(const String& key, const Value& value); 121 122 mutable std::mutex m_StatsMutex; 123 RingBuffer m_QueryStats{15 * 60}; 124 bool m_ActiveChangedHandler{false}; 125 126 RingBuffer m_InputQueries{10}; 127 RingBuffer m_OutputQueries{10}; 128 Atomic<uint_fast64_t> m_PendingQueries{0}; 129 }; 130 131 struct database_error : virtual std::exception, virtual boost::exception { }; 132 133 struct errinfo_database_query_; 134 typedef boost::error_info<struct errinfo_database_query_, std::string> errinfo_database_query; 135 136 } 137 138 #endif /* DBCONNECTION_H */ 139