1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2 
3 #ifndef IDOMYSQLCONNECTION_H
4 #define IDOMYSQLCONNECTION_H
5 
6 #include "db_ido_mysql/idomysqlconnection-ti.hpp"
7 #include "mysql_shim/mysqlinterface.hpp"
8 #include "base/array.hpp"
9 #include "base/timer.hpp"
10 #include "base/workqueue.hpp"
11 #include "base/library.hpp"
12 #include <cstdint>
13 
14 namespace icinga
15 {
16 
17 typedef std::shared_ptr<MYSQL_RES> IdoMysqlResult;
18 
19 typedef std::function<void (const IdoMysqlResult&)> IdoAsyncCallback;
20 
21 struct IdoAsyncQuery
22 {
23 	String Query;
24 	IdoAsyncCallback Callback;
25 };
26 
27 /**
28  * An IDO MySQL database connection.
29  *
30  * @ingroup ido
31  */
32 class IdoMysqlConnection final : public ObjectImpl<IdoMysqlConnection>
33 {
34 public:
35 	DECLARE_OBJECT(IdoMysqlConnection);
36 	DECLARE_OBJECTNAME(IdoMysqlConnection);
37 
38 	static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
39 
40 	const char * GetLatestSchemaVersion() const noexcept override;
41 	const char * GetCompatSchemaVersion() const noexcept override;
42 
43 	int GetPendingQueryCount() const override;
44 
45 protected:
46 	void OnConfigLoaded() override;
47 	void Resume() override;
48 	void Pause() override;
49 
50 	void ActivateObject(const DbObject::Ptr& dbobj) override;
51 	void DeactivateObject(const DbObject::Ptr& dbobj) override;
52 	void ExecuteQuery(const DbQuery& query) override;
53 	void ExecuteMultipleQueries(const std::vector<DbQuery>& queries) override;
54 	void CleanUpExecuteQuery(const String& table, const String& time_key, double time_value) override;
55 	void FillIDCache(const DbType::Ptr& type) override;
56 	void NewTransaction() override;
57 	void Disconnect() override;
58 
59 private:
60 	DbReference m_InstanceID;
61 
62 	Library m_Library;
63 	std::unique_ptr<MysqlInterface, MysqlInterfaceDeleter> m_Mysql;
64 
65 	MYSQL m_Connection;
66 	int m_AffectedRows;
67 	unsigned int m_MaxPacketSize;
68 
69 	std::vector<IdoAsyncQuery> m_AsyncQueries;
70 	uint_fast32_t m_UncommittedAsyncQueries = 0;
71 
72 	Timer::Ptr m_ReconnectTimer;
73 	Timer::Ptr m_TxTimer;
74 
75 	IdoMysqlResult Query(const String& query);
76 	DbReference GetLastInsertID();
77 	int GetAffectedRows();
78 	String Escape(const String& s);
79 	Dictionary::Ptr FetchRow(const IdoMysqlResult& result);
80 	void DiscardRows(const IdoMysqlResult& result);
81 
82 	void AsyncQuery(const String& query, const IdoAsyncCallback& callback = IdoAsyncCallback());
83 	void FinishAsyncQueries();
84 
85 	bool FieldToEscapedString(const String& key, const Value& value, Value *result);
86 	void InternalActivateObject(const DbObject::Ptr& dbobj);
87 	void InternalDeactivateObject(const DbObject::Ptr& dbobj);
88 
89 	void Reconnect();
90 
91 	void AssertOnWorkQueue();
92 
93 	void ReconnectTimerHandler();
94 
95 	bool CanExecuteQuery(const DbQuery& query);
96 
97 	void InternalExecuteQuery(const DbQuery& query, int typeOverride = -1);
98 	void InternalExecuteMultipleQueries(const std::vector<DbQuery>& queries);
99 
100 	void FinishExecuteQuery(const DbQuery& query, int type, bool upsert);
101 	void InternalCleanUpExecuteQuery(const String& table, const String& time_key, double time_value);
102 	void InternalNewTransaction();
103 
104 	void ClearTableBySession(const String& table);
105 	void ClearTablesBySession();
106 
107 	void ExceptionHandler(boost::exception_ptr exp);
108 
109 	void FinishConnect(double startTime);
110 };
111 
112 }
113 
114 #endif /* IDOMYSQLCONNECTION_H */
115