mirror of https://github.com/Icinga/icinga2.git
Add rudimentary support for ido_mysql.
This commit is contained in:
parent
ad83a51547
commit
e66c36ec9e
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include "base/dynamictype.h"
|
#include "base/dynamictype.h"
|
||||||
#include "ido/dbconnection.h"
|
#include "ido/dbconnection.h"
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace icinga
|
namespace icinga
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,11 +17,13 @@ libido_mysql_la_SOURCES = \
|
||||||
libido_mysql_la_CPPFLAGS = \
|
libido_mysql_la_CPPFLAGS = \
|
||||||
$(LTDLINCL) \
|
$(LTDLINCL) \
|
||||||
$(BOOST_CPPFLAGS) \
|
$(BOOST_CPPFLAGS) \
|
||||||
|
$(MYSQL_CFLAGS) \
|
||||||
-I${top_srcdir}/lib \
|
-I${top_srcdir}/lib \
|
||||||
-I${top_srcdir}/components
|
-I${top_srcdir}/components
|
||||||
|
|
||||||
libido_mysql_la_LDFLAGS = \
|
libido_mysql_la_LDFLAGS = \
|
||||||
$(BOOST_LDFLAGS) \
|
$(BOOST_LDFLAGS) \
|
||||||
|
$(MYSQL_LDFLAGS) \
|
||||||
-module \
|
-module \
|
||||||
-no-undefined \
|
-no-undefined \
|
||||||
@RELEASE_INFO@ \
|
@RELEASE_INFO@ \
|
||||||
|
|
|
@ -25,4 +25,7 @@ type MysqlDbConnection {
|
||||||
%attribute string "password",
|
%attribute string "password",
|
||||||
|
|
||||||
%attribute string "database",
|
%attribute string "database",
|
||||||
|
|
||||||
|
%attribute string "instance_name",
|
||||||
|
%attribute string "instance_description"
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,13 @@
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "mysqldbconnection.h"
|
#include "base/logger_fwd.h"
|
||||||
|
#include "base/objectlock.h"
|
||||||
|
#include "ido/dbtype.h"
|
||||||
|
#include "ido_mysql/mysqldbconnection.h"
|
||||||
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
#include <boost/smart_ptr/make_shared.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
@ -31,8 +37,219 @@ MysqlDbConnection::MysqlDbConnection(const Dictionary::Ptr& serializedUpdate)
|
||||||
RegisterAttribute("user", Attribute_Config, &m_User);
|
RegisterAttribute("user", Attribute_Config, &m_User);
|
||||||
RegisterAttribute("password", Attribute_Config, &m_Password);
|
RegisterAttribute("password", Attribute_Config, &m_Password);
|
||||||
RegisterAttribute("database", Attribute_Config, &m_Database);
|
RegisterAttribute("database", Attribute_Config, &m_Database);
|
||||||
|
|
||||||
|
RegisterAttribute("instance_name", Attribute_Config, &m_InstanceName);
|
||||||
|
RegisterAttribute("instance_description", Attribute_Config, &m_InstanceDescription);
|
||||||
|
|
||||||
|
/* TODO: move this to a timer so we can periodically check if we're still connected - and reconnect if necessary */
|
||||||
|
String ihost, iuser, ipasswd, idb;
|
||||||
|
const char *host, *user , *passwd, *db;
|
||||||
|
long port;
|
||||||
|
|
||||||
|
ihost = m_Host;
|
||||||
|
iuser = m_User;
|
||||||
|
ipasswd = m_Password;
|
||||||
|
idb = m_Database;
|
||||||
|
|
||||||
|
host = (!ihost.IsEmpty()) ? ihost.CStr() : NULL;
|
||||||
|
port = m_Port;
|
||||||
|
user = (!iuser.IsEmpty()) ? iuser.CStr() : NULL;
|
||||||
|
passwd = (!ipasswd.IsEmpty()) ? ipasswd.CStr() : NULL;
|
||||||
|
db = (!idb.IsEmpty()) ? idb.CStr() : NULL;
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_ConnectionMutex);
|
||||||
|
|
||||||
|
if (!mysql_init(&m_Connection))
|
||||||
|
BOOST_THROW_EXCEPTION(std::bad_alloc());
|
||||||
|
|
||||||
|
if (!mysql_real_connect(&m_Connection, host, user, passwd, db, port, NULL, 0))
|
||||||
|
BOOST_THROW_EXCEPTION(std::runtime_error(mysql_error(&m_Connection)));
|
||||||
|
|
||||||
|
String instanceName = "default";
|
||||||
|
|
||||||
|
if (!m_InstanceName.IsEmpty())
|
||||||
|
instanceName = m_InstanceName;
|
||||||
|
|
||||||
|
Array::Ptr rows = Query("SELECT instance_id FROM icinga_instances WHERE instance_name = '" + Escape(instanceName) + "'");
|
||||||
|
|
||||||
|
if (rows->GetLength() == 0) {
|
||||||
|
Query("INSERT INTO icinga_instances (instance_name, instance_description) VALUES ('" + Escape(instanceName) + "', '" + m_InstanceDescription + "')");
|
||||||
|
m_InstanceID = GetInsertId();
|
||||||
|
} else {
|
||||||
|
Dictionary::Ptr row = rows->Get(0);
|
||||||
|
m_InstanceID = DbReference(row->Get("instance_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream msgbuf;
|
||||||
|
msgbuf << "MySQL IDO instance id: " << static_cast<long>(m_InstanceID);
|
||||||
|
Log(LogInformation, "ido_mysql", msgbuf.str());
|
||||||
|
|
||||||
|
Query("UPDATE icinga_objects SET is_active = 0");
|
||||||
|
|
||||||
|
std::ostringstream qbuf;
|
||||||
|
qbuf << "SELECT objecttype_id, name1, name2 FROM icinga_objects WHERE instance_id = " << static_cast<long>(m_InstanceID);
|
||||||
|
rows = Query(qbuf.str());
|
||||||
|
|
||||||
|
ObjectLock olock(rows);
|
||||||
|
BOOST_FOREACH(const Dictionary::Ptr& row, rows) {
|
||||||
|
DbType::Ptr dbtype = DbType::GetById(row->Get("objecttype_id"));
|
||||||
|
|
||||||
|
if (!dbtype)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dbtype->GetOrCreateObjectByName(row->Get("name1"), row->Get("name2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAllObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MysqlDbConnection::Stop(void)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_ConnectionMutex);
|
||||||
|
mysql_close(&m_Connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array::Ptr MysqlDbConnection::Query(const String& query)
|
||||||
|
{
|
||||||
|
if (mysql_query(&m_Connection, query.CStr()) != 0)
|
||||||
|
BOOST_THROW_EXCEPTION(std::runtime_error(mysql_error(&m_Connection)));
|
||||||
|
|
||||||
|
MYSQL_RES *result = mysql_store_result(&m_Connection);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
if (mysql_field_count(&m_Connection) > 0)
|
||||||
|
BOOST_THROW_EXCEPTION(std::runtime_error(mysql_error(&m_Connection)));
|
||||||
|
|
||||||
|
return Array::Ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
Array::Ptr rows = boost::make_shared<Array>();
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
Dictionary::Ptr row = FetchRow(result);
|
||||||
|
|
||||||
|
if (!row)
|
||||||
|
break;
|
||||||
|
|
||||||
|
rows->Add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_free_result(result);
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbReference MysqlDbConnection::GetInsertId(void)
|
||||||
|
{
|
||||||
|
return DbReference(mysql_insert_id(&m_Connection));
|
||||||
|
}
|
||||||
|
|
||||||
|
String MysqlDbConnection::Escape(const String& s)
|
||||||
|
{
|
||||||
|
ssize_t length = s.GetLength();
|
||||||
|
char *to = new char[s.GetLength() * 2 + 1];
|
||||||
|
|
||||||
|
mysql_real_escape_string(&m_Connection, to, s.CStr(), length);
|
||||||
|
|
||||||
|
return String(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary::Ptr MysqlDbConnection::FetchRow(MYSQL_RES *result)
|
||||||
|
{
|
||||||
|
MYSQL_ROW row;
|
||||||
|
MYSQL_FIELD *field;
|
||||||
|
unsigned long *lengths, i;
|
||||||
|
|
||||||
|
row = mysql_fetch_row(result);
|
||||||
|
|
||||||
|
if (!row)
|
||||||
|
return Dictionary::Ptr();
|
||||||
|
|
||||||
|
lengths = mysql_fetch_lengths(result);
|
||||||
|
|
||||||
|
if (!lengths)
|
||||||
|
return Dictionary::Ptr();
|
||||||
|
|
||||||
|
Dictionary::Ptr dict = boost::make_shared<Dictionary>();
|
||||||
|
|
||||||
|
mysql_field_seek(result, 0);
|
||||||
|
for (field = mysql_fetch_field(result), i = 0; field; field = mysql_fetch_field(result), i++) {
|
||||||
|
Value value;
|
||||||
|
|
||||||
|
if (field) {
|
||||||
|
value = String(row[i], row[i] + lengths[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
dict->Set(field->name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MysqlDbConnection::UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind) {
|
void MysqlDbConnection::UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind) {
|
||||||
|
DbReference dbref = GetReference(dbobj);
|
||||||
|
|
||||||
|
if (kind == DbObjectRemoved) {
|
||||||
|
if (!dbref.IsValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::ostringstream qbuf;
|
||||||
|
qbuf << "DELETE FROM icinga_" << dbobj->GetType()->GetTable() << "s WHERE id = " << static_cast<long>(dbref);
|
||||||
|
Log(LogWarning, "ido_mysql", "Query: " + qbuf.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream q1buf;
|
||||||
|
|
||||||
|
if (!dbref.IsValid()) {
|
||||||
|
q1buf << "INSERT INTO icinga_objects (instance_id, objecttype_id, name1, name2, is_active) VALUES (";
|
||||||
|
} else {
|
||||||
|
q1buf << "UPDATE icinga_objects SET is_active = 1 WHERE object_id = " << static_cast<long>(dbref);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary::Ptr cols = boost::make_shared<Dictionary>();
|
||||||
|
|
||||||
|
Dictionary::Ptr fields = dbobj->GetFields();
|
||||||
|
|
||||||
|
if (!fields)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ObjectLock olock(fields);
|
||||||
|
|
||||||
|
String key;
|
||||||
|
Value value;
|
||||||
|
BOOST_FOREACH(boost::tie(key, value), fields) {
|
||||||
|
if (value.IsObjectType<DynamicObject>()) {
|
||||||
|
DbObject::Ptr dbobjcol = DbObject::GetOrCreateByObject(value);
|
||||||
|
|
||||||
|
if (!dbobjcol)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DbReference dbrefcol = GetReference(dbobjcol);
|
||||||
|
|
||||||
|
if (!dbrefcol.IsValid()) {
|
||||||
|
UpdateObject(dbobjcol, DbObjectCreated);
|
||||||
|
|
||||||
|
dbrefcol = GetReference(dbobjcol);
|
||||||
|
|
||||||
|
if (!dbrefcol.IsValid())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = static_cast<long>(dbrefcol);
|
||||||
|
}
|
||||||
|
|
||||||
|
cols->Set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream q2buf;
|
||||||
|
|
||||||
|
if (dbref.IsValid()) {
|
||||||
|
q2buf << "UPDATE icinga_" << dbobj->GetType()->GetTable() << "s SET xxx WHERE id = " << static_cast<long>(dbref);
|
||||||
|
} else {
|
||||||
|
q2buf << "INSERT INTO icinga_" << dbobj->GetType()->GetTable() << "s xxx";
|
||||||
|
}
|
||||||
|
|
||||||
|
Log(LogWarning, "ido_mysql", "Query: " + q2buf.str());
|
||||||
}
|
}
|
|
@ -20,9 +20,9 @@
|
||||||
#ifndef MYSQLDBCONNECTION_H
|
#ifndef MYSQLDBCONNECTION_H
|
||||||
#define MYSQLDBCONNECTION_H
|
#define MYSQLDBCONNECTION_H
|
||||||
|
|
||||||
|
#include "base/array.h"
|
||||||
#include "base/dynamictype.h"
|
#include "base/dynamictype.h"
|
||||||
#include "ido/dbconnection.h"
|
#include "ido/dbconnection.h"
|
||||||
#include <vector>
|
|
||||||
#include <mysql/mysql.h>
|
#include <mysql/mysql.h>
|
||||||
|
|
||||||
namespace icinga
|
namespace icinga
|
||||||
|
@ -40,6 +40,7 @@ public:
|
||||||
typedef weak_ptr<MysqlDbConnection> WeakPtr;
|
typedef weak_ptr<MysqlDbConnection> WeakPtr;
|
||||||
|
|
||||||
MysqlDbConnection(const Dictionary::Ptr& serializedUpdate);
|
MysqlDbConnection(const Dictionary::Ptr& serializedUpdate);
|
||||||
|
virtual void Stop(void);
|
||||||
|
|
||||||
virtual void UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind);
|
virtual void UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind);
|
||||||
|
|
||||||
|
@ -49,8 +50,18 @@ private:
|
||||||
Attribute<String> m_User;
|
Attribute<String> m_User;
|
||||||
Attribute<String> m_Password;
|
Attribute<String> m_Password;
|
||||||
Attribute<String> m_Database;
|
Attribute<String> m_Database;
|
||||||
|
Attribute<String> m_InstanceName;
|
||||||
|
Attribute<String> m_InstanceDescription;
|
||||||
|
|
||||||
MYSQL *m_Connection;
|
DbReference m_InstanceID;
|
||||||
|
|
||||||
|
boost::mutex m_ConnectionMutex;
|
||||||
|
MYSQL m_Connection;
|
||||||
|
|
||||||
|
Array::Ptr Query(const String& query);
|
||||||
|
DbReference GetInsertId(void);
|
||||||
|
String Escape(const String& s);
|
||||||
|
Dictionary::Ptr FetchRow(MYSQL_RES *result);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ AX_BOOST_THREAD
|
||||||
AX_BOOST_SYSTEM
|
AX_BOOST_SYSTEM
|
||||||
AX_BOOST_UNIT_TEST_FRAMEWORK
|
AX_BOOST_UNIT_TEST_FRAMEWORK
|
||||||
AX_BOOST_PROGRAM_OPTIONS
|
AX_BOOST_PROGRAM_OPTIONS
|
||||||
|
AX_LIB_MYSQL([5.0])
|
||||||
AX_CHECK_OPENSSL([], [AC_MSG_ERROR([You need the OpenSSL headers and libraries in order to build this application])])
|
AX_CHECK_OPENSSL([], [AC_MSG_ERROR([You need the OpenSSL headers and libraries in order to build this application])])
|
||||||
AC_CHECK_LIB(ssl, SSL_new)
|
AC_CHECK_LIB(ssl, SSL_new)
|
||||||
AC_CHECK_LIB(crypto, X509_NAME_oneline)
|
AC_CHECK_LIB(crypto, X509_NAME_oneline)
|
||||||
|
|
|
@ -29,7 +29,7 @@ DbConnection::DbConnection(const Dictionary::Ptr& serializedUpdate)
|
||||||
|
|
||||||
void DbConnection::Initialize(void)
|
void DbConnection::Initialize(void)
|
||||||
{
|
{
|
||||||
DbObject::OnObjectUpdated.connect(boost::bind(&DbConnection::UpdateObject, this, _1, _2));
|
DbObject::OnObjectUpdated.connect(boost::bind(&DbConnection::InternalUpdateObject, this, _1, _2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DbConnection::SetReference(const DbObject::Ptr& dbobj, const DbReference& dbref)
|
void DbConnection::SetReference(const DbObject::Ptr& dbobj, const DbReference& dbref)
|
||||||
|
@ -57,6 +57,14 @@ void DbConnection::UpdateObject(const DbObject::Ptr&, DbUpdateType)
|
||||||
/* Default handler does nothing. */
|
/* Default handler does nothing. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DbConnection::InternalUpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind)
|
||||||
|
{
|
||||||
|
UpdateObject(dbobj, kind);
|
||||||
|
|
||||||
|
if (kind == DbObjectRemoved)
|
||||||
|
SetReference(dbobj, DbReference());
|
||||||
|
}
|
||||||
|
|
||||||
void DbConnection::UpdateAllObjects(void)
|
void DbConnection::UpdateAllObjects(void)
|
||||||
{
|
{
|
||||||
DynamicType::Ptr type;
|
DynamicType::Ptr type;
|
||||||
|
|
|
@ -48,6 +48,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Initialize(void);
|
void Initialize(void);
|
||||||
|
void InternalUpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind);
|
||||||
|
|
||||||
std::map<DbObject::Ptr, DbReference> m_References;
|
std::map<DbObject::Ptr, DbReference> m_References;
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "ido/dbobject.h"
|
#include "ido/dbobject.h"
|
||||||
#include "ido/dbtype.h"
|
#include "ido/dbtype.h"
|
||||||
|
#include "icinga/service.h"
|
||||||
#include "base/dynamictype.h"
|
#include "base/dynamictype.h"
|
||||||
#include "base/objectlock.h"
|
#include "base/objectlock.h"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
@ -27,8 +28,8 @@ using namespace icinga;
|
||||||
|
|
||||||
boost::signals2::signal<void (const DbObject::Ptr&, DbUpdateType)> DbObject::OnObjectUpdated;
|
boost::signals2::signal<void (const DbObject::Ptr&, DbUpdateType)> DbObject::OnObjectUpdated;
|
||||||
|
|
||||||
DbObject::DbObject(const String& name1, const String& name2)
|
DbObject::DbObject(const shared_ptr<DbType>& type, const String& name1, const String& name2)
|
||||||
: m_Name1(name1), m_Name2(name2), m_Object()
|
: m_Name1(name1), m_Name2(name2), m_Type(type)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void DbObject::StaticInitialize(void)
|
void DbObject::StaticInitialize(void)
|
||||||
|
@ -59,6 +60,16 @@ String DbObject::GetName2(void) const
|
||||||
return m_Name2;
|
return m_Name2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DbType::Ptr DbObject::GetType(void) const
|
||||||
|
{
|
||||||
|
return m_Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DbObject::SendUpdate(DbUpdateType kind)
|
||||||
|
{
|
||||||
|
OnObjectUpdated(GetSelf(), kind);
|
||||||
|
}
|
||||||
|
|
||||||
DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object)
|
DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object)
|
||||||
{
|
{
|
||||||
DbObject::Ptr dbobj = static_pointer_cast<DbObject>(object->GetExtension("DbObject"));
|
DbObject::Ptr dbobj = static_pointer_cast<DbObject>(object->GetExtension("DbObject"));
|
||||||
|
@ -71,7 +82,23 @@ DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object)
|
||||||
if (!dbtype)
|
if (!dbtype)
|
||||||
return DbObject::Ptr();
|
return DbObject::Ptr();
|
||||||
|
|
||||||
/* TODO: Deal with service names. */
|
Service::Ptr service;
|
||||||
|
String name1, name2;
|
||||||
|
|
||||||
|
service = dynamic_pointer_cast<Service>(object);
|
||||||
|
|
||||||
|
if (service) {
|
||||||
|
Host::Ptr host = service->GetHost();
|
||||||
|
|
||||||
|
if (!host)
|
||||||
|
return DbObject::Ptr();
|
||||||
|
|
||||||
|
name1 = service->GetHost()->GetName();
|
||||||
|
name2 = service->GetShortName();
|
||||||
|
} else {
|
||||||
|
name1 = object->GetName();
|
||||||
|
}
|
||||||
|
|
||||||
dbobj = dbtype->GetOrCreateObjectByName(object->GetName(), String());
|
dbobj = dbtype->GetOrCreateObjectByName(object->GetName(), String());
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -86,13 +113,21 @@ DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object)
|
||||||
void DbObject::ObjectRegisteredHandler(const DynamicObject::Ptr& object)
|
void DbObject::ObjectRegisteredHandler(const DynamicObject::Ptr& object)
|
||||||
{
|
{
|
||||||
DbObject::Ptr dbobj = GetOrCreateByObject(object);
|
DbObject::Ptr dbobj = GetOrCreateByObject(object);
|
||||||
OnObjectUpdated(dbobj, DbObjectCreated);
|
|
||||||
|
if (!dbobj)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dbobj->SendUpdate(DbObjectCreated);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DbObject::ObjectUnregisteredHandler(const DynamicObject::Ptr& object)
|
void DbObject::ObjectUnregisteredHandler(const DynamicObject::Ptr& object)
|
||||||
{
|
{
|
||||||
DbObject::Ptr dbobj = GetOrCreateByObject(object);
|
DbObject::Ptr dbobj = GetOrCreateByObject(object);
|
||||||
OnObjectUpdated(dbobj, DbObjectRemoved);
|
|
||||||
|
if (!dbobj)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dbobj->SendUpdate(DbObjectRemoved);
|
||||||
|
|
||||||
{
|
{
|
||||||
ObjectLock olock(object);
|
ObjectLock olock(object);
|
||||||
|
@ -115,5 +150,9 @@ void DbObject::TransactionClosingHandler(double tx, const std::set<DynamicObject
|
||||||
void DbObject::FlushObjectHandler(double tx, const DynamicObject::Ptr& object)
|
void DbObject::FlushObjectHandler(double tx, const DynamicObject::Ptr& object)
|
||||||
{
|
{
|
||||||
DbObject::Ptr dbobj = GetOrCreateByObject(object);
|
DbObject::Ptr dbobj = GetOrCreateByObject(object);
|
||||||
OnObjectUpdated(dbobj, DbObjectUpdated);
|
|
||||||
|
if (!dbobj)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dbobj->SendUpdate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ enum DbUpdateType
|
||||||
DbObjectRemoved
|
DbObjectRemoved
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DbType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A database object.
|
* A database object.
|
||||||
*
|
*
|
||||||
|
@ -49,6 +51,7 @@ public:
|
||||||
|
|
||||||
String GetName1(void) const;
|
String GetName1(void) const;
|
||||||
String GetName2(void) const;
|
String GetName2(void) const;
|
||||||
|
boost::shared_ptr<DbType> GetType(void) const;
|
||||||
|
|
||||||
virtual Dictionary::Ptr GetFields(void) const = 0;
|
virtual Dictionary::Ptr GetFields(void) const = 0;
|
||||||
|
|
||||||
|
@ -56,12 +59,15 @@ public:
|
||||||
|
|
||||||
static boost::signals2::signal<void (const DbObject::Ptr&, DbUpdateType)> OnObjectUpdated;
|
static boost::signals2::signal<void (const DbObject::Ptr&, DbUpdateType)> OnObjectUpdated;
|
||||||
|
|
||||||
|
void SendUpdate(DbUpdateType kind = DbObjectUpdated);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DbObject(const String& name1, const String& name2);
|
DbObject(const boost::shared_ptr<DbType>& type, const String& name1, const String& name2);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String m_Name1;
|
String m_Name1;
|
||||||
String m_Name2;
|
String m_Name2;
|
||||||
|
boost::shared_ptr<DbType> m_Type;
|
||||||
DynamicObject::Ptr m_Object;
|
DynamicObject::Ptr m_Object;
|
||||||
|
|
||||||
friend boost::shared_ptr<DbObject> boost::make_shared<>(const icinga::String&, const icinga::String&);
|
friend boost::shared_ptr<DbObject> boost::make_shared<>(const icinga::String&, const icinga::String&);
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "ido/dbtype.h"
|
#include "ido/dbtype.h"
|
||||||
#include "base/objectlock.h"
|
#include "base/objectlock.h"
|
||||||
#include <boost/thread/once.hpp>
|
#include <boost/thread/once.hpp>
|
||||||
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
@ -64,6 +66,18 @@ DbType::Ptr DbType::GetByName(const String& name)
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DbType::Ptr DbType::GetById(long tid)
|
||||||
|
{
|
||||||
|
String name;
|
||||||
|
DbType::Ptr type;
|
||||||
|
BOOST_FOREACH(boost::tie(name, type), GetTypes()) {
|
||||||
|
if (type->GetTypeId() == tid)
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DbType::Ptr();
|
||||||
|
}
|
||||||
|
|
||||||
DbObject::Ptr DbType::GetOrCreateObjectByName(const String& name1, const String& name2)
|
DbObject::Ptr DbType::GetOrCreateObjectByName(const String& name1, const String& name2)
|
||||||
{
|
{
|
||||||
ASSERT(!OwnsLock());
|
ASSERT(!OwnsLock());
|
||||||
|
|
|
@ -50,6 +50,7 @@ public:
|
||||||
static void RegisterType(const DbType::Ptr& type);
|
static void RegisterType(const DbType::Ptr& type);
|
||||||
|
|
||||||
static DbType::Ptr GetByName(const String& name);
|
static DbType::Ptr GetByName(const String& name);
|
||||||
|
static DbType::Ptr GetById(long tid);
|
||||||
|
|
||||||
DbObject::Ptr GetOrCreateObjectByName(const String& name1, const String& name2);
|
DbObject::Ptr GetOrCreateObjectByName(const String& name1, const String& name2);
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,22 @@
|
||||||
|
|
||||||
#include "ido/hostdbobject.h"
|
#include "ido/hostdbobject.h"
|
||||||
#include "ido/dbtype.h"
|
#include "ido/dbtype.h"
|
||||||
|
#include "icinga/host.h"
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_DBTYPE("Host", "hosts", 1, HostDbObject);
|
REGISTER_DBTYPE("Host", "host", 1, HostDbObject);
|
||||||
|
|
||||||
HostDbObject::HostDbObject(const String& name1, const String& name2)
|
HostDbObject::HostDbObject(const String& name1, const String& name2)
|
||||||
: DbObject(name1, name2)
|
: DbObject(DbType::GetByName("Host"), name1, name2)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Dictionary::Ptr HostDbObject::GetFields(void) const
|
Dictionary::Ptr HostDbObject::GetFields(void) const
|
||||||
{
|
{
|
||||||
|
Dictionary::Ptr fields = boost::make_shared<Dictionary>();
|
||||||
|
Host::Ptr host = static_pointer_cast<Host>(GetObject());
|
||||||
|
|
||||||
|
fields->Set("display_name", host->GetDisplayName());
|
||||||
|
|
||||||
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
# ===========================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_lib_mysql.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_LIB_MYSQL([MINIMUM-VERSION])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# This macro provides tests of availability of MySQL client library of
|
||||||
|
# particular version or newer.
|
||||||
|
#
|
||||||
|
# AX_LIB_MYSQL macro takes only one argument which is optional. If there
|
||||||
|
# is no required version passed, then macro does not run version test.
|
||||||
|
#
|
||||||
|
# The --with-mysql option takes one of three possible values:
|
||||||
|
#
|
||||||
|
# no - do not check for MySQL client library
|
||||||
|
#
|
||||||
|
# yes - do check for MySQL library in standard locations (mysql_config
|
||||||
|
# should be in the PATH)
|
||||||
|
#
|
||||||
|
# path - complete path to mysql_config utility, use this option if
|
||||||
|
# mysql_config can't be found in the PATH
|
||||||
|
#
|
||||||
|
# This macro calls:
|
||||||
|
#
|
||||||
|
# AC_SUBST(MYSQL_CFLAGS)
|
||||||
|
# AC_SUBST(MYSQL_LDFLAGS)
|
||||||
|
# AC_SUBST(MYSQL_VERSION)
|
||||||
|
#
|
||||||
|
# And sets:
|
||||||
|
#
|
||||||
|
# HAVE_MYSQL
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Mateusz Loskot <mateusz@loskot.net>
|
||||||
|
#
|
||||||
|
# Copying and distribution of this file, with or without modification, are
|
||||||
|
# permitted in any medium without royalty provided the copyright notice
|
||||||
|
# and this notice are preserved. This file is offered as-is, without any
|
||||||
|
# warranty.
|
||||||
|
|
||||||
|
#serial 12
|
||||||
|
|
||||||
|
AC_DEFUN([AX_LIB_MYSQL],
|
||||||
|
[
|
||||||
|
AC_ARG_WITH([mysql],
|
||||||
|
AS_HELP_STRING([--with-mysql=@<:@ARG@:>@],
|
||||||
|
[use MySQL client library @<:@default=yes@:>@, optionally specify path to mysql_config]
|
||||||
|
),
|
||||||
|
[
|
||||||
|
if test "$withval" = "no"; then
|
||||||
|
want_mysql="no"
|
||||||
|
elif test "$withval" = "yes"; then
|
||||||
|
want_mysql="yes"
|
||||||
|
else
|
||||||
|
want_mysql="yes"
|
||||||
|
MYSQL_CONFIG="$withval"
|
||||||
|
fi
|
||||||
|
],
|
||||||
|
[want_mysql="yes"]
|
||||||
|
)
|
||||||
|
AC_ARG_VAR([MYSQL_CONFIG], [Full path to mysql_config program])
|
||||||
|
|
||||||
|
MYSQL_CFLAGS=""
|
||||||
|
MYSQL_LDFLAGS=""
|
||||||
|
MYSQL_VERSION=""
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Check MySQL libraries
|
||||||
|
dnl
|
||||||
|
|
||||||
|
if test "$want_mysql" = "yes"; then
|
||||||
|
|
||||||
|
if test -z "$MYSQL_CONFIG" ; then
|
||||||
|
AC_PATH_PROGS([MYSQL_CONFIG], [mysql_config mysql_config5], [no])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$MYSQL_CONFIG" != "no"; then
|
||||||
|
MYSQL_CFLAGS="`$MYSQL_CONFIG --cflags`"
|
||||||
|
MYSQL_LDFLAGS="`$MYSQL_CONFIG --libs`"
|
||||||
|
|
||||||
|
MYSQL_VERSION=`$MYSQL_CONFIG --version`
|
||||||
|
|
||||||
|
found_mysql="yes"
|
||||||
|
else
|
||||||
|
found_mysql="no"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Check if required version of MySQL is available
|
||||||
|
dnl
|
||||||
|
|
||||||
|
|
||||||
|
mysql_version_req=ifelse([$1], [], [], [$1])
|
||||||
|
|
||||||
|
if test "$found_mysql" = "yes" -a -n "$mysql_version_req"; then
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if MySQL version is >= $mysql_version_req])
|
||||||
|
|
||||||
|
dnl Decompose required version string of MySQL
|
||||||
|
dnl and calculate its number representation
|
||||||
|
mysql_version_req_major=`expr $mysql_version_req : '\([[0-9]]*\)'`
|
||||||
|
mysql_version_req_minor=`expr $mysql_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
|
||||||
|
mysql_version_req_micro=`expr $mysql_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
|
||||||
|
if test "x$mysql_version_req_micro" = "x"; then
|
||||||
|
mysql_version_req_micro="0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mysql_version_req_number=`expr $mysql_version_req_major \* 1000000 \
|
||||||
|
\+ $mysql_version_req_minor \* 1000 \
|
||||||
|
\+ $mysql_version_req_micro`
|
||||||
|
|
||||||
|
dnl Decompose version string of installed MySQL
|
||||||
|
dnl and calculate its number representation
|
||||||
|
mysql_version_major=`expr $MYSQL_VERSION : '\([[0-9]]*\)'`
|
||||||
|
mysql_version_minor=`expr $MYSQL_VERSION : '[[0-9]]*\.\([[0-9]]*\)'`
|
||||||
|
mysql_version_micro=`expr $MYSQL_VERSION : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
|
||||||
|
if test "x$mysql_version_micro" = "x"; then
|
||||||
|
mysql_version_micro="0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mysql_version_number=`expr $mysql_version_major \* 1000000 \
|
||||||
|
\+ $mysql_version_minor \* 1000 \
|
||||||
|
\+ $mysql_version_micro`
|
||||||
|
|
||||||
|
mysql_version_check=`expr $mysql_version_number \>\= $mysql_version_req_number`
|
||||||
|
if test "$mysql_version_check" = "1"; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$found_mysql" = "yes" ; then
|
||||||
|
AC_DEFINE([HAVE_MYSQL], [1],
|
||||||
|
[Define to 1 if MySQL libraries are available])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST([MYSQL_VERSION])
|
||||||
|
AC_SUBST([MYSQL_CFLAGS])
|
||||||
|
AC_SUBST([MYSQL_LDFLAGS])
|
||||||
|
])
|
Loading…
Reference in New Issue