mirror of https://github.com/Icinga/icinga2.git
Implement shim for libmysqlclient and libpq
This commit is contained in:
parent
90496b5456
commit
2f953d6204
|
@ -139,13 +139,6 @@ set(HAVE_EDITLINE "${EDITLINE_FOUND}")
|
|||
find_package(Termcap)
|
||||
set(HAVE_TERMCAP "${TERMCAP_FOUND}")
|
||||
|
||||
find_package(PostgreSQL)
|
||||
|
||||
if(PostgreSQL_FOUND)
|
||||
link_directories(${PostgreSQL_LIBRARY_DIRS})
|
||||
include_directories(${PostgreSQL_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib
|
||||
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/lib
|
||||
|
|
|
@ -39,11 +39,25 @@ if(ICINGA2_WITH_MYSQL OR ICINGA2_WITH_PGSQL)
|
|||
endif()
|
||||
|
||||
if(ICINGA2_WITH_MYSQL)
|
||||
add_subdirectory(db_ido_mysql)
|
||||
find_package(MySQL)
|
||||
|
||||
if(MYSQL_FOUND)
|
||||
add_subdirectory(db_ido_mysql)
|
||||
add_subdirectory(mysql_shim)
|
||||
else()
|
||||
message(FATAL_ERROR "You have selected MySQL support, but MySQL could not be found. You can disable the MySQL IDO module using -DICINGA2_WITH_MYSQL=OFF.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ICINGA2_WITH_PGSQL)
|
||||
add_subdirectory(db_ido_pgsql)
|
||||
find_package(PostgreSQL)
|
||||
|
||||
if(PostgreSQL_FOUND)
|
||||
add_subdirectory(db_ido_pgsql)
|
||||
add_subdirectory(pgsql_shim)
|
||||
else()
|
||||
message(FATAL_ERROR "You have selected PostgreSQL support, but PostgreSQL could not be found. You can disable the PostgreSQL IDO module using -DICINGA2_WITH_PGSQL=OFF.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ICINGA2_WITH_DEMO)
|
||||
|
|
|
@ -31,7 +31,7 @@ set(base_SOURCES
|
|||
convert.cpp datetime.cpp datetime.thpp datetime-script.cpp debuginfo.cpp dictionary.cpp dictionary-script.cpp
|
||||
configobject.cpp configobject.thpp configobject-script.cpp configtype.cpp configwriter.cpp dependencygraph.cpp
|
||||
exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp
|
||||
json-script.cpp loader.cpp logger.cpp logger.thpp math-script.cpp
|
||||
json-script.cpp library.cpp loader.cpp logger.cpp logger.thpp math-script.cpp
|
||||
netstring.cpp networkstream.cpp number.cpp number-script.cpp object.cpp
|
||||
object-script.cpp objecttype.cpp primitivetype.cpp process.cpp ringbuffer.cpp scriptframe.cpp
|
||||
function.cpp function.thpp function-script.cpp
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "base/library.hpp"
|
||||
#include "base/loader.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include "base/application.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
/**
|
||||
* Loads the specified library.
|
||||
*
|
||||
* @param name The name of the library.
|
||||
*/
|
||||
Library::Library(const String& name)
|
||||
{
|
||||
String path;
|
||||
#if defined(_WIN32)
|
||||
path = name + ".dll";
|
||||
#elif defined(__APPLE__)
|
||||
path = "lib" + name + "." + Application::GetAppSpecVersion() + ".dylib";
|
||||
#else /* __APPLE__ */
|
||||
path = "lib" + name + ".so." + Application::GetAppSpecVersion();
|
||||
#endif /* _WIN32 */
|
||||
|
||||
Log(LogNotice, "Library")
|
||||
<< "Loading library '" << path << "'";
|
||||
|
||||
#ifdef _WIN32
|
||||
HMODULE hModule = LoadLibrary(path.CStr());
|
||||
|
||||
if (!hModule) {
|
||||
BOOST_THROW_EXCEPTION(win32_error()
|
||||
<< boost::errinfo_api_function("LoadLibrary")
|
||||
<< errinfo_win32_error(GetLastError())
|
||||
<< boost::errinfo_file_name(path));
|
||||
}
|
||||
#else /* _WIN32 */
|
||||
void *hModule = dlopen(path.CStr(), RTLD_NOW | RTLD_GLOBAL);
|
||||
|
||||
if (!hModule) {
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Could not load library '" + path + "': " + dlerror()));
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
Loader::ExecuteDeferredInitializers();
|
||||
|
||||
m_Handle.reset(new LibraryHandle(hModule), [](LibraryHandle *handle) {
|
||||
#ifdef _WIN32
|
||||
FreeLibrary(*handle);
|
||||
#else /* _WIN32 */
|
||||
dlclose(*handle);
|
||||
#endif /* _WIN32 */
|
||||
});
|
||||
}
|
||||
|
||||
void *Library::GetSymbolAddress(const String& name) const
|
||||
{
|
||||
if (!m_Handle)
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Invalid library handle"));
|
||||
|
||||
#ifdef _WIN32
|
||||
return GetProcAddress(*m_Handle.get(), name.CStr());
|
||||
#else /* _WIN32 */
|
||||
return dlsym(*m_Handle.get(), name.CStr());
|
||||
#endif /* _WIN32 */
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LIBRARY_H
|
||||
#define LIBRARY_H
|
||||
|
||||
#include "base/i2-base.hpp"
|
||||
#include "base/string.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
#ifndef _WIN32
|
||||
typedef void *LibraryHandle;
|
||||
#else /* _WIN32 */
|
||||
typedef HMODULE LibraryHandle;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
class Library
|
||||
{
|
||||
public:
|
||||
Library(void) = default;
|
||||
Library(const String& name);
|
||||
|
||||
void *GetSymbolAddress(const String& name) const;
|
||||
|
||||
template<typename T>
|
||||
T GetSymbolAddress(const String& name) const
|
||||
{
|
||||
static_assert(!std::is_same<T, void *>::value, "T must not be void *");
|
||||
|
||||
return reinterpret_cast<T>(GetSymbolAddress(name));
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<LibraryHandle> m_Handle;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* LIBRARY_H */
|
|
@ -18,6 +18,9 @@
|
|||
******************************************************************************/
|
||||
|
||||
#include "base/loader.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include "base/application.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
|
|
|
@ -842,7 +842,6 @@ ExpressionResult LibraryExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dh
|
|||
|
||||
Log(LogNotice, "config")
|
||||
<< "Ignoring explicit load request for library \"" << libres << "\".";
|
||||
//Loader::LoadExtensionLibrary(libres.GetValue());
|
||||
|
||||
return Empty;
|
||||
}
|
||||
|
|
|
@ -15,47 +15,42 @@
|
|||
# along with this program; if not, write to the Free Software Foundation
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
find_package(MySQL)
|
||||
mkclass_target(idomysqlconnection.ti idomysqlconnection.tcpp idomysqlconnection.thpp)
|
||||
|
||||
if(MYSQL_FOUND)
|
||||
mkclass_target(idomysqlconnection.ti idomysqlconnection.tcpp idomysqlconnection.thpp)
|
||||
set(db_ido_mysql_SOURCES
|
||||
idomysqlconnection.cpp idomysqlconnection.thpp
|
||||
)
|
||||
|
||||
set(db_ido_mysql_SOURCES
|
||||
idomysqlconnection.cpp idomysqlconnection.thpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
mkunity_target(db_ido_mysql db_ido_mysql db_ido_mysql_SOURCES)
|
||||
endif()
|
||||
|
||||
add_library(db_ido_mysql STATIC ${db_ido_mysql_SOURCES})
|
||||
|
||||
include_directories(${MYSQL_INCLUDE_DIR})
|
||||
target_link_libraries(db_ido_mysql ${Boost_LIBRARIES} ${MYSQL_LIB} base config icinga db_ido)
|
||||
|
||||
set_target_properties (
|
||||
db_ido_mysql PROPERTIES
|
||||
FOLDER Components
|
||||
)
|
||||
|
||||
install_if_not_exists(
|
||||
${PROJECT_SOURCE_DIR}/etc/icinga2/features-available/ido-mysql.conf
|
||||
${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY schema
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/icinga2-ido-mysql
|
||||
FILES_MATCHING PATTERN "*.sql"
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY schema/upgrade
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/icinga2-ido-mysql/schema
|
||||
FILES_MATCHING PATTERN "*.sql"
|
||||
)
|
||||
|
||||
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}" PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "You have selected MySQL support, but MySQL could not be found. You can disable the MySQL IDO module using -DICINGA2_WITH_MYSQL=OFF.")
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
mkunity_target(db_ido_mysql db_ido_mysql db_ido_mysql_SOURCES)
|
||||
endif()
|
||||
|
||||
add_library(db_ido_mysql STATIC ${db_ido_mysql_SOURCES})
|
||||
|
||||
include_directories(${MYSQL_INCLUDE_DIR})
|
||||
|
||||
target_link_libraries(db_ido_mysql ${Boost_LIBRARIES} base config icinga db_ido)
|
||||
|
||||
set_target_properties (
|
||||
db_ido_mysql PROPERTIES
|
||||
FOLDER Components
|
||||
)
|
||||
|
||||
install_if_not_exists(
|
||||
${PROJECT_SOURCE_DIR}/etc/icinga2/features-available/ido-mysql.conf
|
||||
${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY schema
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/icinga2-ido-mysql
|
||||
FILES_MATCHING PATTERN "*.sql"
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY schema/upgrade
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/icinga2-ido-mysql/schema
|
||||
FILES_MATCHING PATTERN "*.sql"
|
||||
)
|
||||
|
||||
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}" PARENT_SCOPE)
|
||||
|
|
|
@ -46,6 +46,14 @@ void IdoMysqlConnection::OnConfigLoaded(void)
|
|||
ObjectImpl<IdoMysqlConnection>::OnConfigLoaded();
|
||||
|
||||
m_QueryQueue.SetName("IdoMysqlConnection, " + GetName());
|
||||
|
||||
Library shimLibrary{"mysql_shim"};
|
||||
|
||||
auto create_mysql_shim = shimLibrary.GetSymbolAddress<create_mysql_shim_ptr>("create_mysql_shim");
|
||||
|
||||
m_Mysql.reset(create_mysql_shim());
|
||||
|
||||
std::swap(m_Library, shimLibrary);
|
||||
}
|
||||
|
||||
void IdoMysqlConnection::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata)
|
||||
|
@ -98,7 +106,7 @@ void IdoMysqlConnection::Resume(void)
|
|||
m_ReconnectTimer->Start();
|
||||
m_ReconnectTimer->Reschedule(0);
|
||||
|
||||
ASSERT(mysql_thread_safe());
|
||||
ASSERT(m_Mysql->thread_safe());
|
||||
}
|
||||
|
||||
void IdoMysqlConnection::Pause(void)
|
||||
|
@ -127,7 +135,7 @@ void IdoMysqlConnection::ExceptionHandler(boost::exception_ptr exp)
|
|||
<< "Exception during database operation: " << DiagnosticInformation(exp);
|
||||
|
||||
if (GetConnected()) {
|
||||
mysql_close(&m_Connection);
|
||||
m_Mysql->close(&m_Connection);
|
||||
|
||||
SetConnected(false);
|
||||
}
|
||||
|
@ -146,7 +154,7 @@ void IdoMysqlConnection::Disconnect(void)
|
|||
return;
|
||||
|
||||
Query("COMMIT");
|
||||
mysql_close(&m_Connection);
|
||||
m_Mysql->close(&m_Connection);
|
||||
|
||||
SetConnected(false);
|
||||
}
|
||||
|
@ -205,10 +213,10 @@ void IdoMysqlConnection::Reconnect(void)
|
|||
|
||||
if (GetConnected()) {
|
||||
/* Check if we're really still connected */
|
||||
if (mysql_ping(&m_Connection) == 0)
|
||||
if (m_Mysql->ping(&m_Connection) == 0)
|
||||
return;
|
||||
|
||||
mysql_close(&m_Connection);
|
||||
m_Mysql->close(&m_Connection);
|
||||
SetConnected(false);
|
||||
reconnect = true;
|
||||
}
|
||||
|
@ -249,7 +257,7 @@ void IdoMysqlConnection::Reconnect(void)
|
|||
sslCipher = (!isslCipher.IsEmpty()) ? isslCipher.CStr() : nullptr;
|
||||
|
||||
/* connection */
|
||||
if (!mysql_init(&m_Connection)) {
|
||||
if (!m_Mysql->init(&m_Connection)) {
|
||||
Log(LogCritical, "IdoMysqlConnection")
|
||||
<< "mysql_init() failed: out of memory";
|
||||
|
||||
|
@ -257,14 +265,14 @@ void IdoMysqlConnection::Reconnect(void)
|
|||
}
|
||||
|
||||
if (enableSsl)
|
||||
mysql_ssl_set(&m_Connection, sslKey, sslCert, sslCa, sslCaPath, sslCipher);
|
||||
m_Mysql->ssl_set(&m_Connection, sslKey, sslCert, sslCa, sslCaPath, sslCipher);
|
||||
|
||||
if (!mysql_real_connect(&m_Connection, host, user, passwd, db, port, socket_path, CLIENT_FOUND_ROWS | CLIENT_MULTI_STATEMENTS)) {
|
||||
if (!m_Mysql->real_connect(&m_Connection, host, user, passwd, db, port, socket_path, CLIENT_FOUND_ROWS | CLIENT_MULTI_STATEMENTS)) {
|
||||
Log(LogCritical, "IdoMysqlConnection")
|
||||
<< "Connection to database '" << db << "' with user '" << user << "' on '" << host << ":" << port
|
||||
<< "' " << (enableSsl ? "(SSL enabled) " : "") << "failed: \"" << mysql_error(&m_Connection) << "\"";
|
||||
<< "' " << (enableSsl ? "(SSL enabled) " : "") << "failed: \"" << m_Mysql->error(&m_Connection) << "\"";
|
||||
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error(mysql_error(&m_Connection)));
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error(m_Mysql->error(&m_Connection)));
|
||||
}
|
||||
|
||||
SetConnected(true);
|
||||
|
@ -286,7 +294,7 @@ void IdoMysqlConnection::Reconnect(void)
|
|||
row = FetchRow(result);
|
||||
|
||||
if (!row) {
|
||||
mysql_close(&m_Connection);
|
||||
m_Mysql->close(&m_Connection);
|
||||
SetConnected(false);
|
||||
|
||||
Log(LogCritical, "IdoMysqlConnection", "Schema does not provide any valid version! Verify your schema installation.");
|
||||
|
@ -301,7 +309,7 @@ void IdoMysqlConnection::Reconnect(void)
|
|||
SetSchemaVersion(version);
|
||||
|
||||
if (Utility::CompareVersion(IDO_COMPAT_SCHEMA_VERSION, version) < 0) {
|
||||
mysql_close(&m_Connection);
|
||||
m_Mysql->close(&m_Connection);
|
||||
SetConnected(false);
|
||||
|
||||
Log(LogCritical, "IdoMysqlConnection")
|
||||
|
@ -358,7 +366,7 @@ void IdoMysqlConnection::Reconnect(void)
|
|||
<< "Last update by '" << endpoint_name << "' was " << status_update_age << "s ago.";
|
||||
|
||||
if (status_update_age < GetFailoverTimeout()) {
|
||||
mysql_close(&m_Connection);
|
||||
m_Mysql->close(&m_Connection);
|
||||
SetConnected(false);
|
||||
SetShouldConnect(false);
|
||||
|
||||
|
@ -370,7 +378,7 @@ void IdoMysqlConnection::Reconnect(void)
|
|||
Log(LogNotice, "IdoMysqlConnection")
|
||||
<< "Local endpoint '" << my_endpoint->GetName() << "' is not authoritative, bailing out.";
|
||||
|
||||
mysql_close(&m_Connection);
|
||||
m_Mysql->close(&m_Connection);
|
||||
SetConnected(false);
|
||||
|
||||
return;
|
||||
|
@ -533,15 +541,15 @@ void IdoMysqlConnection::FinishAsyncQueries(void)
|
|||
|
||||
String query = querybuf.str();
|
||||
|
||||
if (mysql_query(&m_Connection, query.CStr()) != 0) {
|
||||
if (m_Mysql->query(&m_Connection, query.CStr()) != 0) {
|
||||
std::ostringstream msgbuf;
|
||||
String message = mysql_error(&m_Connection);
|
||||
String message = m_Mysql->error(&m_Connection);
|
||||
msgbuf << "Error \"" << message << "\" when executing query \"" << query << "\"";
|
||||
Log(LogCritical, "IdoMysqlConnection", msgbuf.str());
|
||||
|
||||
BOOST_THROW_EXCEPTION(
|
||||
database_error()
|
||||
<< errinfo_message(mysql_error(&m_Connection))
|
||||
<< errinfo_message(m_Mysql->error(&m_Connection))
|
||||
<< errinfo_database_query(query)
|
||||
);
|
||||
}
|
||||
|
@ -549,40 +557,40 @@ void IdoMysqlConnection::FinishAsyncQueries(void)
|
|||
for (std::vector<IdoAsyncQuery>::size_type i = offset; i < offset + count; i++) {
|
||||
const IdoAsyncQuery& aq = queries[i];
|
||||
|
||||
MYSQL_RES *result = mysql_store_result(&m_Connection);
|
||||
MYSQL_RES *result = m_Mysql->store_result(&m_Connection);
|
||||
|
||||
m_AffectedRows = mysql_affected_rows(&m_Connection);
|
||||
m_AffectedRows = m_Mysql->affected_rows(&m_Connection);
|
||||
|
||||
IdoMysqlResult iresult;
|
||||
|
||||
if (!result) {
|
||||
if (mysql_field_count(&m_Connection) > 0) {
|
||||
if (m_Mysql->field_count(&m_Connection) > 0) {
|
||||
std::ostringstream msgbuf;
|
||||
String message = mysql_error(&m_Connection);
|
||||
String message = m_Mysql->error(&m_Connection);
|
||||
msgbuf << "Error \"" << message << "\" when executing query \"" << aq.Query << "\"";
|
||||
Log(LogCritical, "IdoMysqlConnection", msgbuf.str());
|
||||
|
||||
BOOST_THROW_EXCEPTION(
|
||||
database_error()
|
||||
<< errinfo_message(mysql_error(&m_Connection))
|
||||
<< errinfo_message(m_Mysql->error(&m_Connection))
|
||||
<< errinfo_database_query(query)
|
||||
);
|
||||
}
|
||||
} else
|
||||
iresult = IdoMysqlResult(result, std::ptr_fun(mysql_free_result));
|
||||
iresult = IdoMysqlResult(result, std::bind(&MysqlInterface::free_result, std::cref(m_Mysql), _1));
|
||||
|
||||
if (aq.Callback)
|
||||
aq.Callback(iresult);
|
||||
|
||||
if (mysql_next_result(&m_Connection) > 0) {
|
||||
if (m_Mysql->next_result(&m_Connection) > 0) {
|
||||
std::ostringstream msgbuf;
|
||||
String message = mysql_error(&m_Connection);
|
||||
String message = m_Mysql->error(&m_Connection);
|
||||
msgbuf << "Error \"" << message << "\" when executing query \"" << query << "\"";
|
||||
Log(LogCritical, "IdoMysqlConnection", msgbuf.str());
|
||||
|
||||
BOOST_THROW_EXCEPTION(
|
||||
database_error()
|
||||
<< errinfo_message(mysql_error(&m_Connection))
|
||||
<< errinfo_message(m_Mysql->error(&m_Connection))
|
||||
<< errinfo_database_query(query)
|
||||
);
|
||||
}
|
||||
|
@ -604,33 +612,33 @@ IdoMysqlResult IdoMysqlConnection::Query(const String& query)
|
|||
|
||||
IncreaseQueryCount();
|
||||
|
||||
if (mysql_query(&m_Connection, query.CStr()) != 0) {
|
||||
if (m_Mysql->query(&m_Connection, query.CStr()) != 0) {
|
||||
std::ostringstream msgbuf;
|
||||
String message = mysql_error(&m_Connection);
|
||||
String message = m_Mysql->error(&m_Connection);
|
||||
msgbuf << "Error \"" << message << "\" when executing query \"" << query << "\"";
|
||||
Log(LogCritical, "IdoMysqlConnection", msgbuf.str());
|
||||
|
||||
BOOST_THROW_EXCEPTION(
|
||||
database_error()
|
||||
<< errinfo_message(mysql_error(&m_Connection))
|
||||
<< errinfo_message(m_Mysql->error(&m_Connection))
|
||||
<< errinfo_database_query(query)
|
||||
);
|
||||
}
|
||||
|
||||
MYSQL_RES *result = mysql_store_result(&m_Connection);
|
||||
MYSQL_RES *result = m_Mysql->store_result(&m_Connection);
|
||||
|
||||
m_AffectedRows = mysql_affected_rows(&m_Connection);
|
||||
m_AffectedRows = m_Mysql->affected_rows(&m_Connection);
|
||||
|
||||
if (!result) {
|
||||
if (mysql_field_count(&m_Connection) > 0) {
|
||||
if (m_Mysql->field_count(&m_Connection) > 0) {
|
||||
std::ostringstream msgbuf;
|
||||
String message = mysql_error(&m_Connection);
|
||||
String message = m_Mysql->error(&m_Connection);
|
||||
msgbuf << "Error \"" << message << "\" when executing query \"" << query << "\"";
|
||||
Log(LogCritical, "IdoMysqlConnection", msgbuf.str());
|
||||
|
||||
BOOST_THROW_EXCEPTION(
|
||||
database_error()
|
||||
<< errinfo_message(mysql_error(&m_Connection))
|
||||
<< errinfo_message(m_Mysql->error(&m_Connection))
|
||||
<< errinfo_database_query(query)
|
||||
);
|
||||
}
|
||||
|
@ -638,14 +646,14 @@ IdoMysqlResult IdoMysqlConnection::Query(const String& query)
|
|||
return IdoMysqlResult();
|
||||
}
|
||||
|
||||
return IdoMysqlResult(result, std::ptr_fun(mysql_free_result));
|
||||
return IdoMysqlResult(result, std::bind(&MysqlInterface::free_result, std::cref(m_Mysql), _1));
|
||||
}
|
||||
|
||||
DbReference IdoMysqlConnection::GetLastInsertID(void)
|
||||
{
|
||||
AssertOnWorkQueue();
|
||||
|
||||
return DbReference(mysql_insert_id(&m_Connection));
|
||||
return DbReference(m_Mysql->insert_id(&m_Connection));
|
||||
}
|
||||
|
||||
int IdoMysqlConnection::GetAffectedRows(void)
|
||||
|
@ -664,7 +672,7 @@ String IdoMysqlConnection::Escape(const String& s)
|
|||
size_t length = utf8s.GetLength();
|
||||
char *to = new char[utf8s.GetLength() * 2 + 1];
|
||||
|
||||
mysql_real_escape_string(&m_Connection, to, utf8s.CStr(), length);
|
||||
m_Mysql->real_escape_string(&m_Connection, to, utf8s.CStr(), length);
|
||||
|
||||
String result = String(to);
|
||||
|
||||
|
@ -681,20 +689,20 @@ Dictionary::Ptr IdoMysqlConnection::FetchRow(const IdoMysqlResult& result)
|
|||
MYSQL_FIELD *field;
|
||||
unsigned long *lengths, i;
|
||||
|
||||
row = mysql_fetch_row(result.get());
|
||||
row = m_Mysql->fetch_row(result.get());
|
||||
|
||||
if (!row)
|
||||
return nullptr;
|
||||
|
||||
lengths = mysql_fetch_lengths(result.get());
|
||||
lengths = m_Mysql->fetch_lengths(result.get());
|
||||
|
||||
if (!lengths)
|
||||
return nullptr;
|
||||
|
||||
Dictionary::Ptr dict = new Dictionary();
|
||||
|
||||
mysql_field_seek(result.get(), 0);
|
||||
for (field = mysql_fetch_field(result.get()), i = 0; field; field = mysql_fetch_field(result.get()), i++)
|
||||
m_Mysql->field_seek(result.get(), 0);
|
||||
for (field = m_Mysql->fetch_field(result.get()), i = 0; field; field = m_Mysql->fetch_field(result.get()), i++)
|
||||
dict->Set(field->name, String(row[i], row[i] + lengths[i]));
|
||||
|
||||
return dict;
|
||||
|
|
|
@ -21,10 +21,11 @@
|
|||
#define IDOMYSQLCONNECTION_H
|
||||
|
||||
#include "db_ido_mysql/idomysqlconnection.thpp"
|
||||
#include "mysql_shim/mysqlinterface.hpp"
|
||||
#include "base/array.hpp"
|
||||
#include "base/timer.hpp"
|
||||
#include "base/workqueue.hpp"
|
||||
#include <mysql.h>
|
||||
#include "base/library.hpp"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
@ -74,6 +75,9 @@ private:
|
|||
|
||||
WorkQueue m_QueryQueue;
|
||||
|
||||
Library m_Library;
|
||||
std::unique_ptr<MysqlInterface, MysqlInterfaceDeleter> m_Mysql;
|
||||
|
||||
MYSQL m_Connection;
|
||||
int m_AffectedRows;
|
||||
unsigned int m_MaxPacketSize;
|
||||
|
|
|
@ -15,44 +15,42 @@
|
|||
# along with this program; if not, write to the Free Software Foundation
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
if(PostgreSQL_FOUND)
|
||||
mkclass_target(idopgsqlconnection.ti idopgsqlconnection.tcpp idopgsqlconnection.thpp)
|
||||
mkclass_target(idopgsqlconnection.ti idopgsqlconnection.tcpp idopgsqlconnection.thpp)
|
||||
|
||||
set(db_ido_pgsql_SOURCES
|
||||
idopgsqlconnection.cpp idopgsqlconnection.thpp
|
||||
)
|
||||
set(db_ido_pgsql_SOURCES
|
||||
idopgsqlconnection.cpp idopgsqlconnection.thpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
mkunity_target(db_ido_pgsql db_ido_pgsql db_ido_pgsql_SOURCES)
|
||||
endif()
|
||||
|
||||
add_library(db_ido_pgsql STATIC ${db_ido_pgsql_SOURCES})
|
||||
|
||||
target_link_libraries(db_ido_pgsql ${Boost_LIBRARIES} ${PostgreSQL_LIBRARIES} base config icinga db_ido)
|
||||
|
||||
set_target_properties (
|
||||
db_ido_pgsql PROPERTIES
|
||||
FOLDER Components
|
||||
)
|
||||
|
||||
install_if_not_exists(
|
||||
${PROJECT_SOURCE_DIR}/etc/icinga2/features-available/ido-pgsql.conf
|
||||
${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY schema
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/icinga2-ido-pgsql
|
||||
FILES_MATCHING PATTERN "*.sql"
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY schema/upgrade
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/icinga2-ido-pgsql/schema
|
||||
FILES_MATCHING PATTERN "*.sql"
|
||||
)
|
||||
|
||||
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}" PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "You have selected PostgreSQL support, but PostgreSQL could not be found. You can disable the PostgreSQL IDO module using -DICINGA2_WITH_PGSQL=OFF.")
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
mkunity_target(db_ido_pgsql db_ido_pgsql db_ido_pgsql_SOURCES)
|
||||
endif()
|
||||
|
||||
add_library(db_ido_pgsql STATIC ${db_ido_pgsql_SOURCES})
|
||||
|
||||
include_directories(${PostgreSQL_INCLUDE_DIRS})
|
||||
|
||||
target_link_libraries(db_ido_pgsql ${Boost_LIBRARIES} base config icinga db_ido)
|
||||
|
||||
set_target_properties (
|
||||
db_ido_pgsql PROPERTIES
|
||||
FOLDER Components
|
||||
)
|
||||
|
||||
install_if_not_exists(
|
||||
${PROJECT_SOURCE_DIR}/etc/icinga2/features-available/ido-pgsql.conf
|
||||
${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY schema
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/icinga2-ido-pgsql
|
||||
FILES_MATCHING PATTERN "*.sql"
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY schema/upgrade
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/icinga2-ido-pgsql/schema
|
||||
FILES_MATCHING PATTERN "*.sql"
|
||||
)
|
||||
|
||||
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}" PARENT_SCOPE)
|
||||
|
|
|
@ -50,6 +50,14 @@ void IdoPgsqlConnection::OnConfigLoaded(void)
|
|||
ObjectImpl<IdoPgsqlConnection>::OnConfigLoaded();
|
||||
|
||||
m_QueryQueue.SetName("IdoPgsqlConnection, " + GetName());
|
||||
|
||||
Library shimLibrary{"pgsql_shim"};
|
||||
|
||||
auto create_pgsql_shim = shimLibrary.GetSymbolAddress<create_pgsql_shim_ptr>("create_pgsql_shim");
|
||||
|
||||
m_Pgsql.reset(create_pgsql_shim());
|
||||
|
||||
std::swap(m_Library, shimLibrary);
|
||||
}
|
||||
|
||||
void IdoPgsqlConnection::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata)
|
||||
|
@ -102,7 +110,7 @@ void IdoPgsqlConnection::Resume(void)
|
|||
m_ReconnectTimer->Start();
|
||||
m_ReconnectTimer->Reschedule(0);
|
||||
|
||||
ASSERT(PQisthreadsafe());
|
||||
ASSERT(m_Pgsql->isthreadsafe());
|
||||
}
|
||||
|
||||
void IdoPgsqlConnection::Pause(void)
|
||||
|
@ -126,7 +134,7 @@ void IdoPgsqlConnection::ExceptionHandler(boost::exception_ptr exp)
|
|||
<< "Exception during database operation: " << DiagnosticInformation(exp);
|
||||
|
||||
if (GetConnected()) {
|
||||
PQfinish(m_Connection);
|
||||
m_Pgsql->finish(m_Connection);
|
||||
SetConnected(false);
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +153,7 @@ void IdoPgsqlConnection::Disconnect(void)
|
|||
|
||||
Query("COMMIT");
|
||||
|
||||
PQfinish(m_Connection);
|
||||
m_Pgsql->finish(m_Connection);
|
||||
SetConnected(false);
|
||||
}
|
||||
|
||||
|
@ -193,7 +201,7 @@ void IdoPgsqlConnection::Reconnect(void)
|
|||
Query("SELECT 1");
|
||||
return;
|
||||
} catch (const std::exception&) {
|
||||
PQfinish(m_Connection);
|
||||
m_Pgsql->finish(m_Connection);
|
||||
SetConnected(false);
|
||||
reconnect = true;
|
||||
}
|
||||
|
@ -216,14 +224,14 @@ void IdoPgsqlConnection::Reconnect(void)
|
|||
passwd = (!ipasswd.IsEmpty()) ? ipasswd.CStr() : nullptr;
|
||||
db = (!idb.IsEmpty()) ? idb.CStr() : nullptr;
|
||||
|
||||
m_Connection = PQsetdbLogin(host, port, nullptr, nullptr, db, user, passwd);
|
||||
m_Connection = m_Pgsql->setdbLogin(host, port, nullptr, nullptr, db, user, passwd);
|
||||
|
||||
if (!m_Connection)
|
||||
return;
|
||||
|
||||
if (PQstatus(m_Connection) != CONNECTION_OK) {
|
||||
String message = PQerrorMessage(m_Connection);
|
||||
PQfinish(m_Connection);
|
||||
if (m_Pgsql->status(m_Connection) != CONNECTION_OK) {
|
||||
String message = m_Pgsql->errorMessage(m_Connection);
|
||||
m_Pgsql->finish(m_Connection);
|
||||
SetConnected(false);
|
||||
|
||||
Log(LogCritical, "IdoPgsqlConnection")
|
||||
|
@ -240,7 +248,7 @@ void IdoPgsqlConnection::Reconnect(void)
|
|||
/* explicitely require legacy mode for string escaping in PostgreSQL >= 9.1
|
||||
* changing standard_conforming_strings to on by default
|
||||
*/
|
||||
if (PQserverVersion(m_Connection) >= 90100)
|
||||
if (m_Pgsql->serverVersion(m_Connection) >= 90100)
|
||||
result = Query("SET standard_conforming_strings TO off");
|
||||
|
||||
String dbVersionName = "idoutils";
|
||||
|
@ -249,7 +257,7 @@ void IdoPgsqlConnection::Reconnect(void)
|
|||
Dictionary::Ptr row = FetchRow(result, 0);
|
||||
|
||||
if (!row) {
|
||||
PQfinish(m_Connection);
|
||||
m_Pgsql->finish(m_Connection);
|
||||
SetConnected(false);
|
||||
|
||||
Log(LogCritical, "IdoPgsqlConnection", "Schema does not provide any valid version! Verify your schema installation.");
|
||||
|
@ -262,7 +270,7 @@ void IdoPgsqlConnection::Reconnect(void)
|
|||
SetSchemaVersion(version);
|
||||
|
||||
if (Utility::CompareVersion(IDO_COMPAT_SCHEMA_VERSION, version) < 0) {
|
||||
PQfinish(m_Connection);
|
||||
m_Pgsql->finish(m_Connection);
|
||||
SetConnected(false);
|
||||
|
||||
Log(LogCritical, "IdoPgsqlConnection")
|
||||
|
@ -316,7 +324,7 @@ void IdoPgsqlConnection::Reconnect(void)
|
|||
<< "Last update by '" << endpoint_name << "' was " << status_update_age << "s ago.";
|
||||
|
||||
if (status_update_age < GetFailoverTimeout()) {
|
||||
PQfinish(m_Connection);
|
||||
m_Pgsql->finish(m_Connection);
|
||||
SetConnected(false);
|
||||
SetShouldConnect(false);
|
||||
|
||||
|
@ -328,7 +336,7 @@ void IdoPgsqlConnection::Reconnect(void)
|
|||
Log(LogNotice, "IdoPgsqlConnection")
|
||||
<< "Local endpoint '" << my_endpoint->GetName() << "' is not authoritative, bailing out.";
|
||||
|
||||
PQfinish(m_Connection);
|
||||
m_Pgsql->finish(m_Connection);
|
||||
SetConnected(false);
|
||||
|
||||
return;
|
||||
|
@ -437,10 +445,10 @@ IdoPgsqlResult IdoPgsqlConnection::Query(const String& query)
|
|||
|
||||
IncreaseQueryCount();
|
||||
|
||||
PGresult *result = PQexec(m_Connection, query.CStr());
|
||||
PGresult *result = m_Pgsql->exec(m_Connection, query.CStr());
|
||||
|
||||
if (!result) {
|
||||
String message = PQerrorMessage(m_Connection);
|
||||
String message = m_Pgsql->errorMessage(m_Connection);
|
||||
Log(LogCritical, "IdoPgsqlConnection")
|
||||
<< "Error \"" << message << "\" when executing query \"" << query << "\"";
|
||||
|
||||
|
@ -451,17 +459,17 @@ IdoPgsqlResult IdoPgsqlConnection::Query(const String& query)
|
|||
);
|
||||
}
|
||||
|
||||
char *rowCount = PQcmdTuples(result);
|
||||
char *rowCount = m_Pgsql->cmdTuples(result);
|
||||
m_AffectedRows = atoi(rowCount);
|
||||
|
||||
if (PQresultStatus(result) == PGRES_COMMAND_OK) {
|
||||
PQclear(result);
|
||||
if (m_Pgsql->resultStatus(result) == PGRES_COMMAND_OK) {
|
||||
m_Pgsql->clear(result);
|
||||
return IdoPgsqlResult();
|
||||
}
|
||||
|
||||
if (PQresultStatus(result) != PGRES_TUPLES_OK) {
|
||||
String message = PQresultErrorMessage(result);
|
||||
PQclear(result);
|
||||
if (m_Pgsql->resultStatus(result) != PGRES_TUPLES_OK) {
|
||||
String message = m_Pgsql->resultErrorMessage(result);
|
||||
m_Pgsql->clear(result);
|
||||
|
||||
Log(LogCritical, "IdoPgsqlConnection")
|
||||
<< "Error \"" << message << "\" when executing query \"" << query << "\"";
|
||||
|
@ -473,7 +481,7 @@ IdoPgsqlResult IdoPgsqlConnection::Query(const String& query)
|
|||
);
|
||||
}
|
||||
|
||||
return IdoPgsqlResult(result, std::ptr_fun(PQclear));
|
||||
return IdoPgsqlResult(result, std::bind(&PgsqlInterface::clear, std::cref(m_Pgsql), _1));
|
||||
}
|
||||
|
||||
DbReference IdoPgsqlConnection::GetSequenceValue(const String& table, const String& column)
|
||||
|
@ -508,7 +516,7 @@ String IdoPgsqlConnection::Escape(const String& s)
|
|||
size_t length = utf8s.GetLength();
|
||||
char *to = new char[utf8s.GetLength() * 2 + 1];
|
||||
|
||||
PQescapeStringConn(m_Connection, to, utf8s.CStr(), length, nullptr);
|
||||
m_Pgsql->escapeStringConn(m_Connection, to, utf8s.CStr(), length, nullptr);
|
||||
|
||||
String result = String(to);
|
||||
|
||||
|
@ -521,20 +529,20 @@ Dictionary::Ptr IdoPgsqlConnection::FetchRow(const IdoPgsqlResult& result, int r
|
|||
{
|
||||
AssertOnWorkQueue();
|
||||
|
||||
if (row >= PQntuples(result.get()))
|
||||
if (row >= m_Pgsql->ntuples(result.get()))
|
||||
return nullptr;
|
||||
|
||||
int columns = PQnfields(result.get());
|
||||
int columns = m_Pgsql->nfields(result.get());
|
||||
|
||||
Dictionary::Ptr dict = new Dictionary();
|
||||
|
||||
for (int column = 0; column < columns; column++) {
|
||||
Value value;
|
||||
|
||||
if (!PQgetisnull(result.get(), row, column))
|
||||
value = PQgetvalue(result.get(), row, column);
|
||||
if (!m_Pgsql->getisnull(result.get(), row, column))
|
||||
value = m_Pgsql->getvalue(result.get(), row, column);
|
||||
|
||||
dict->Set(PQfname(result.get(), column), value);
|
||||
dict->Set(m_Pgsql->fname(result.get(), column), value);
|
||||
}
|
||||
|
||||
return dict;
|
||||
|
|
|
@ -21,10 +21,11 @@
|
|||
#define IDOPGSQLCONNECTION_H
|
||||
|
||||
#include "db_ido_pgsql/idopgsqlconnection.thpp"
|
||||
#include "pgsql_shim/pgsqlinterface.hpp"
|
||||
#include "base/array.hpp"
|
||||
#include "base/timer.hpp"
|
||||
#include "base/workqueue.hpp"
|
||||
#include <libpq-fe.h>
|
||||
#include "base/library.hpp"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
@ -66,6 +67,9 @@ private:
|
|||
|
||||
WorkQueue m_QueryQueue;
|
||||
|
||||
Library m_Library;
|
||||
std::unique_ptr<PgsqlInterface, PgsqlInterfaceDeleter> m_Pgsql;
|
||||
|
||||
PGconn *m_Connection;
|
||||
int m_AffectedRows;
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# Icinga 2
|
||||
# Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
include_directories(${MYSQL_INCLUDE_DIR})
|
||||
|
||||
set(mysql_shim_SOURCES
|
||||
mysql_shim.def
|
||||
mysqlinterface.cpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
mkunity_target(mysql_shim mysql_shim mysql_shim_SOURCES)
|
||||
endif()
|
||||
|
||||
add_library(mysql_shim SHARED ${mysql_shim_SOURCES})
|
||||
|
||||
include(GenerateExportHeader)
|
||||
generate_export_header(mysql_shim)
|
||||
|
||||
target_link_libraries(mysql_shim ${MYSQL_LIB})
|
||||
|
||||
set_target_properties (
|
||||
mysql_shim PROPERTIES
|
||||
FOLDER Lib
|
||||
VERSION ${SPEC_VERSION}
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS mysql_shim
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2
|
||||
)
|
|
@ -0,0 +1,3 @@
|
|||
LIBRARY mysql_shim
|
||||
EXPORTS
|
||||
create_mysql_shim
|
|
@ -0,0 +1,131 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "mysql_shim/mysqlinterface.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
struct MysqlInterfaceImpl : public MysqlInterface
|
||||
{
|
||||
void Destroy(void) override
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
my_ulonglong affected_rows(MYSQL *mysql) const override
|
||||
{
|
||||
return mysql_affected_rows(mysql);
|
||||
}
|
||||
|
||||
void close(MYSQL *sock) const override
|
||||
{
|
||||
return mysql_close(sock);
|
||||
}
|
||||
|
||||
const char *error(MYSQL *mysql) const override
|
||||
{
|
||||
return mysql_error(mysql);
|
||||
}
|
||||
|
||||
MYSQL_FIELD *fetch_field(MYSQL_RES *result) const override
|
||||
{
|
||||
return mysql_fetch_field(result);
|
||||
}
|
||||
|
||||
unsigned long *fetch_lengths(MYSQL_RES *result) const override
|
||||
{
|
||||
return mysql_fetch_lengths(result);
|
||||
}
|
||||
|
||||
MYSQL_ROW fetch_row(MYSQL_RES *result) const override
|
||||
{
|
||||
return mysql_fetch_row(result);
|
||||
}
|
||||
|
||||
unsigned int field_count(MYSQL *mysql) const override
|
||||
{
|
||||
return mysql_field_count(mysql);
|
||||
}
|
||||
|
||||
MYSQL_FIELD_OFFSET field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset) const override
|
||||
{
|
||||
return mysql_field_seek(result, offset);
|
||||
}
|
||||
|
||||
void free_result(MYSQL_RES *result) const override
|
||||
{
|
||||
mysql_free_result(result);
|
||||
}
|
||||
|
||||
MYSQL *init(MYSQL *mysql) const override
|
||||
{
|
||||
return mysql_init(mysql);
|
||||
}
|
||||
|
||||
my_ulonglong insert_id(MYSQL *mysql) const override
|
||||
{
|
||||
return mysql_insert_id(mysql);
|
||||
}
|
||||
|
||||
int next_result(MYSQL *mysql) const override
|
||||
{
|
||||
return mysql_next_result(mysql);
|
||||
}
|
||||
|
||||
int ping(MYSQL *mysql) const override
|
||||
{
|
||||
return mysql_ping(mysql);
|
||||
}
|
||||
|
||||
int query(MYSQL *mysql, const char *q) const override
|
||||
{
|
||||
return mysql_query(mysql, q);
|
||||
}
|
||||
|
||||
MYSQL *real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd,
|
||||
const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag) const override
|
||||
{
|
||||
return mysql_real_connect(mysql, host, user, passwd, db, port, unix_socket, clientflag);
|
||||
}
|
||||
|
||||
unsigned long real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length) const override
|
||||
{
|
||||
return mysql_real_escape_string(mysql, to, from, length);
|
||||
}
|
||||
|
||||
my_bool ssl_set(MYSQL *mysql, const char *key, const char *cert, const char *ca, const char *capath, const char *cipher) const override
|
||||
{
|
||||
return mysql_ssl_set(mysql, key, cert, ca, capath, cipher);
|
||||
}
|
||||
|
||||
MYSQL_RES *store_result(MYSQL *mysql) const override
|
||||
{
|
||||
return mysql_store_result(mysql);
|
||||
}
|
||||
|
||||
unsigned int thread_safe(void) const override
|
||||
{
|
||||
return mysql_thread_safe();
|
||||
}
|
||||
};
|
||||
|
||||
MysqlInterface *create_mysql_shim(void)
|
||||
{
|
||||
return new MysqlInterfaceImpl();
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef MYSQLINTERFACE_H
|
||||
#define MYSQLINTERFACE_H
|
||||
|
||||
#include "mysql_shim/mysql_shim_export.h"
|
||||
#include <memory>
|
||||
#include <mysql.h>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
struct MysqlInterface
|
||||
{
|
||||
MysqlInterface(const MysqlInterface&) = delete;
|
||||
MysqlInterface& operator=(MysqlInterface&) = delete;
|
||||
|
||||
virtual void Destroy(void) = 0;
|
||||
|
||||
virtual my_ulonglong affected_rows(MYSQL *mysql) const = 0;
|
||||
virtual void close(MYSQL *sock) const = 0;
|
||||
virtual const char *error(MYSQL *mysql) const = 0;
|
||||
virtual MYSQL_FIELD *fetch_field(MYSQL_RES *result) const = 0;
|
||||
virtual unsigned long *fetch_lengths(MYSQL_RES *result) const = 0;
|
||||
virtual MYSQL_ROW fetch_row(MYSQL_RES *result) const = 0;
|
||||
virtual unsigned int field_count(MYSQL *mysql) const = 0;
|
||||
virtual MYSQL_FIELD_OFFSET field_seek(MYSQL_RES *result,
|
||||
MYSQL_FIELD_OFFSET offset) const = 0;
|
||||
virtual void free_result(MYSQL_RES *result) const = 0;
|
||||
virtual MYSQL *init(MYSQL *mysql) const = 0;
|
||||
virtual my_ulonglong insert_id(MYSQL *mysql) const = 0;
|
||||
virtual int next_result(MYSQL *mysql) const = 0;
|
||||
virtual int ping(MYSQL *mysql) const = 0;
|
||||
virtual int query(MYSQL *mysql, const char *q) const = 0;
|
||||
virtual MYSQL *real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd,
|
||||
const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag) const = 0;
|
||||
virtual unsigned long real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length) const = 0;
|
||||
virtual my_bool ssl_set(MYSQL *mysql, const char *key, const char *cert, const char *ca, const char *capath, const char *cipher) const = 0;
|
||||
virtual MYSQL_RES *store_result(MYSQL *mysql) const = 0;
|
||||
virtual unsigned int thread_safe(void) const = 0;
|
||||
|
||||
protected:
|
||||
MysqlInterface(void) = default;
|
||||
~MysqlInterface(void) = default;
|
||||
};
|
||||
|
||||
struct MysqlInterfaceDeleter
|
||||
{
|
||||
void operator()(MysqlInterface *ifc) const
|
||||
{
|
||||
ifc->Destroy();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
MYSQL_SHIM_EXPORT icinga::MysqlInterface *create_mysql_shim(void);
|
||||
}
|
||||
|
||||
typedef icinga::MysqlInterface *(*create_mysql_shim_ptr)(void);
|
||||
|
||||
#endif /* MYSQLINTERFACE_H */
|
|
@ -0,0 +1,47 @@
|
|||
# Icinga 2
|
||||
# Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
link_directories(${PostgreSQL_LIBRARY_DIRS})
|
||||
include_directories(${PostgreSQL_INCLUDE_DIRS})
|
||||
|
||||
set(pgsql_shim_SOURCES
|
||||
pgsql_shim.def
|
||||
pgsqlinterface.cpp
|
||||
)
|
||||
|
||||
if(ICINGA2_UNITY_BUILD)
|
||||
mkunity_target(pgsql_shim pgsql_shim pgsql_shim_SOURCES)
|
||||
endif()
|
||||
|
||||
add_library(pgsql_shim SHARED ${pgsql_shim_SOURCES})
|
||||
|
||||
include(GenerateExportHeader)
|
||||
generate_export_header(pgsql_shim)
|
||||
|
||||
target_link_libraries(pgsql_shim ${PostgreSQL_LIBRARIES})
|
||||
|
||||
set_target_properties (
|
||||
pgsql_shim PROPERTIES
|
||||
FOLDER Lib
|
||||
VERSION ${SPEC_VERSION}
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS pgsql_shim
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2
|
||||
)
|
|
@ -0,0 +1,3 @@
|
|||
LIBRARY pgsql_shim
|
||||
EXPORTS
|
||||
create_pgsql_shim
|
|
@ -0,0 +1,120 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "pgsql_shim/pgsqlinterface.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
struct PgsqlInterfaceImpl : public PgsqlInterface
|
||||
{
|
||||
void Destroy(void) override
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void clear(PGresult *res) const override
|
||||
{
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
char *cmdTuples(PGresult *res) const override
|
||||
{
|
||||
return PQcmdTuples(res);
|
||||
}
|
||||
|
||||
char *errorMessage(const PGconn *conn) const override
|
||||
{
|
||||
return PQerrorMessage(conn);
|
||||
}
|
||||
|
||||
size_t escapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error) const override
|
||||
{
|
||||
return PQescapeStringConn(conn, to, from, length, error);
|
||||
}
|
||||
|
||||
PGresult *exec(PGconn *conn, const char *query) const override
|
||||
{
|
||||
return PQexec(conn, query);
|
||||
}
|
||||
|
||||
void finish(PGconn *conn) const override
|
||||
{
|
||||
PQfinish(conn);
|
||||
}
|
||||
|
||||
char *fname(const PGresult *res, int field_num) const override
|
||||
{
|
||||
return PQfname(res, field_num);
|
||||
}
|
||||
|
||||
int getisnull(const PGresult *res, int tup_num, int field_num) const override
|
||||
{
|
||||
return PQgetisnull(res, tup_num, field_num);
|
||||
}
|
||||
|
||||
char *getvalue(const PGresult *res, int tup_num, int field_num) const override
|
||||
{
|
||||
return PQgetvalue(res, tup_num, field_num);
|
||||
}
|
||||
|
||||
int isthreadsafe(void) const override
|
||||
{
|
||||
return PQisthreadsafe();
|
||||
}
|
||||
|
||||
int nfields(const PGresult *res) const override
|
||||
{
|
||||
return PQnfields(res);
|
||||
}
|
||||
|
||||
int ntuples(const PGresult *res) const override
|
||||
{
|
||||
return PQntuples(res);
|
||||
}
|
||||
|
||||
char *resultErrorMessage(const PGresult *res) const override
|
||||
{
|
||||
return PQresultErrorMessage(res);
|
||||
}
|
||||
|
||||
ExecStatusType resultStatus(const PGresult *res) const override
|
||||
{
|
||||
return PQresultStatus(res);
|
||||
}
|
||||
|
||||
int serverVersion(const PGconn *conn) const override
|
||||
{
|
||||
return PQserverVersion(conn);
|
||||
}
|
||||
|
||||
PGconn *setdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd) const override
|
||||
{
|
||||
return PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName, login, pwd);
|
||||
}
|
||||
|
||||
ConnStatusType status(const PGconn *conn) const override
|
||||
{
|
||||
return PQstatus(conn);
|
||||
}
|
||||
};
|
||||
|
||||
PgsqlInterface *create_pgsql_shim(void)
|
||||
{
|
||||
return new PgsqlInterfaceImpl();
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef PGSQLINTERFACE_H
|
||||
#define PGSQLINTERFACE_H
|
||||
|
||||
#include "pgsql_shim/pgsql_shim_export.h"
|
||||
#include <memory>
|
||||
#include <libpq-fe.h>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
struct PgsqlInterface
|
||||
{
|
||||
PgsqlInterface(const PgsqlInterface&) = delete;
|
||||
PgsqlInterface& operator=(PgsqlInterface&) = delete;
|
||||
|
||||
virtual void Destroy(void) = 0;
|
||||
|
||||
virtual void clear(PGresult *res) const = 0;
|
||||
virtual char *cmdTuples(PGresult *res) const = 0;
|
||||
virtual char *errorMessage(const PGconn *conn) const = 0;
|
||||
virtual size_t escapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error) const = 0;
|
||||
virtual PGresult *exec(PGconn *conn, const char *query) const = 0;
|
||||
virtual void finish(PGconn *conn) const = 0;
|
||||
virtual char *fname(const PGresult *res, int field_num) const = 0;
|
||||
virtual int getisnull(const PGresult *res, int tup_num, int field_num) const = 0;
|
||||
virtual char *getvalue(const PGresult *res, int tup_num, int field_num) const = 0;
|
||||
virtual int isthreadsafe(void) const = 0;
|
||||
virtual int nfields(const PGresult *res) const = 0;
|
||||
virtual int ntuples(const PGresult *res) const = 0;
|
||||
virtual char *resultErrorMessage(const PGresult *res) const = 0;
|
||||
virtual ExecStatusType resultStatus(const PGresult *res) const = 0;
|
||||
virtual int serverVersion(const PGconn *conn) const = 0;
|
||||
virtual PGconn *setdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd) const = 0;
|
||||
virtual ConnStatusType status(const PGconn *conn) const = 0;
|
||||
|
||||
protected:
|
||||
PgsqlInterface(void) = default;
|
||||
~PgsqlInterface(void) = default;
|
||||
};
|
||||
|
||||
struct PgsqlInterfaceDeleter
|
||||
{
|
||||
void operator()(PgsqlInterface *ifc) const
|
||||
{
|
||||
ifc->Destroy();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
PGSQL_SHIM_EXPORT icinga::PgsqlInterface *create_pgsql_shim(void);
|
||||
}
|
||||
|
||||
typedef icinga::PgsqlInterface *(*create_pgsql_shim_ptr)(void);
|
||||
|
||||
#endif /* PGSQLINTERFACE_H */
|
Loading…
Reference in New Issue