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 "ido/dbconnection.h"
|
||||
#include <vector>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
|
|
@ -17,11 +17,13 @@ libido_mysql_la_SOURCES = \
|
|||
libido_mysql_la_CPPFLAGS = \
|
||||
$(LTDLINCL) \
|
||||
$(BOOST_CPPFLAGS) \
|
||||
$(MYSQL_CFLAGS) \
|
||||
-I${top_srcdir}/lib \
|
||||
-I${top_srcdir}/components
|
||||
|
||||
libido_mysql_la_LDFLAGS = \
|
||||
$(BOOST_LDFLAGS) \
|
||||
$(MYSQL_LDFLAGS) \
|
||||
-module \
|
||||
-no-undefined \
|
||||
@RELEASE_INFO@ \
|
||||
|
|
|
@ -25,4 +25,7 @@ type MysqlDbConnection {
|
|||
%attribute string "password",
|
||||
|
||||
%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. *
|
||||
******************************************************************************/
|
||||
|
||||
#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;
|
||||
|
||||
|
@ -31,8 +37,219 @@ MysqlDbConnection::MysqlDbConnection(const Dictionary::Ptr& serializedUpdate)
|
|||
RegisterAttribute("user", Attribute_Config, &m_User);
|
||||
RegisterAttribute("password", Attribute_Config, &m_Password);
|
||||
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) {
|
||||
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
|
||||
#define MYSQLDBCONNECTION_H
|
||||
|
||||
#include "base/array.h"
|
||||
#include "base/dynamictype.h"
|
||||
#include "ido/dbconnection.h"
|
||||
#include <vector>
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
namespace icinga
|
||||
|
@ -40,6 +40,7 @@ public:
|
|||
typedef weak_ptr<MysqlDbConnection> WeakPtr;
|
||||
|
||||
MysqlDbConnection(const Dictionary::Ptr& serializedUpdate);
|
||||
virtual void Stop(void);
|
||||
|
||||
virtual void UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind);
|
||||
|
||||
|
@ -49,8 +50,18 @@ private:
|
|||
Attribute<String> m_User;
|
||||
Attribute<String> m_Password;
|
||||
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_UNIT_TEST_FRAMEWORK
|
||||
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])])
|
||||
AC_CHECK_LIB(ssl, SSL_new)
|
||||
AC_CHECK_LIB(crypto, X509_NAME_oneline)
|
||||
|
|
|
@ -29,7 +29,7 @@ DbConnection::DbConnection(const Dictionary::Ptr& serializedUpdate)
|
|||
|
||||
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)
|
||||
|
@ -57,6 +57,14 @@ void DbConnection::UpdateObject(const DbObject::Ptr&, DbUpdateType)
|
|||
/* 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)
|
||||
{
|
||||
DynamicType::Ptr type;
|
||||
|
|
|
@ -48,6 +48,7 @@ protected:
|
|||
|
||||
private:
|
||||
void Initialize(void);
|
||||
void InternalUpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind);
|
||||
|
||||
std::map<DbObject::Ptr, DbReference> m_References;
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "ido/dbobject.h"
|
||||
#include "ido/dbtype.h"
|
||||
#include "icinga/service.h"
|
||||
#include "base/dynamictype.h"
|
||||
#include "base/objectlock.h"
|
||||
#include <boost/foreach.hpp>
|
||||
|
@ -27,8 +28,8 @@ using namespace icinga;
|
|||
|
||||
boost::signals2::signal<void (const DbObject::Ptr&, DbUpdateType)> DbObject::OnObjectUpdated;
|
||||
|
||||
DbObject::DbObject(const String& name1, const String& name2)
|
||||
: m_Name1(name1), m_Name2(name2), m_Object()
|
||||
DbObject::DbObject(const shared_ptr<DbType>& type, const String& name1, const String& name2)
|
||||
: m_Name1(name1), m_Name2(name2), m_Type(type)
|
||||
{ }
|
||||
|
||||
void DbObject::StaticInitialize(void)
|
||||
|
@ -59,6 +60,16 @@ String DbObject::GetName2(void) const
|
|||
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 dbobj = static_pointer_cast<DbObject>(object->GetExtension("DbObject"));
|
||||
|
@ -71,7 +82,23 @@ DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object)
|
|||
if (!dbtype)
|
||||
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());
|
||||
|
||||
{
|
||||
|
@ -86,13 +113,21 @@ DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object)
|
|||
void DbObject::ObjectRegisteredHandler(const DynamicObject::Ptr& object)
|
||||
{
|
||||
DbObject::Ptr dbobj = GetOrCreateByObject(object);
|
||||
OnObjectUpdated(dbobj, DbObjectCreated);
|
||||
|
||||
if (!dbobj)
|
||||
return;
|
||||
|
||||
dbobj->SendUpdate(DbObjectCreated);
|
||||
}
|
||||
|
||||
void DbObject::ObjectUnregisteredHandler(const DynamicObject::Ptr& object)
|
||||
{
|
||||
DbObject::Ptr dbobj = GetOrCreateByObject(object);
|
||||
OnObjectUpdated(dbobj, DbObjectRemoved);
|
||||
|
||||
if (!dbobj)
|
||||
return;
|
||||
|
||||
dbobj->SendUpdate(DbObjectRemoved);
|
||||
|
||||
{
|
||||
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)
|
||||
{
|
||||
DbObject::Ptr dbobj = GetOrCreateByObject(object);
|
||||
OnObjectUpdated(dbobj, DbObjectUpdated);
|
||||
|
||||
if (!dbobj)
|
||||
return;
|
||||
|
||||
dbobj->SendUpdate();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ enum DbUpdateType
|
|||
DbObjectRemoved
|
||||
};
|
||||
|
||||
class DbType;
|
||||
|
||||
/**
|
||||
* A database object.
|
||||
*
|
||||
|
@ -49,6 +51,7 @@ public:
|
|||
|
||||
String GetName1(void) const;
|
||||
String GetName2(void) const;
|
||||
boost::shared_ptr<DbType> GetType(void) const;
|
||||
|
||||
virtual Dictionary::Ptr GetFields(void) const = 0;
|
||||
|
||||
|
@ -56,12 +59,15 @@ public:
|
|||
|
||||
static boost::signals2::signal<void (const DbObject::Ptr&, DbUpdateType)> OnObjectUpdated;
|
||||
|
||||
void SendUpdate(DbUpdateType kind = DbObjectUpdated);
|
||||
|
||||
protected:
|
||||
DbObject(const String& name1, const String& name2);
|
||||
DbObject(const boost::shared_ptr<DbType>& type, const String& name1, const String& name2);
|
||||
|
||||
private:
|
||||
String m_Name1;
|
||||
String m_Name2;
|
||||
boost::shared_ptr<DbType> m_Type;
|
||||
DynamicObject::Ptr m_Object;
|
||||
|
||||
friend boost::shared_ptr<DbObject> boost::make_shared<>(const icinga::String&, const icinga::String&);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "ido/dbtype.h"
|
||||
#include "base/objectlock.h"
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
|
@ -64,6 +66,18 @@ DbType::Ptr DbType::GetByName(const String& name)
|
|||
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)
|
||||
{
|
||||
ASSERT(!OwnsLock());
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
static void RegisterType(const DbType::Ptr& type);
|
||||
|
||||
static DbType::Ptr GetByName(const String& name);
|
||||
static DbType::Ptr GetById(long tid);
|
||||
|
||||
DbObject::Ptr GetOrCreateObjectByName(const String& name1, const String& name2);
|
||||
|
||||
|
|
|
@ -19,16 +19,22 @@
|
|||
|
||||
#include "ido/hostdbobject.h"
|
||||
#include "ido/dbtype.h"
|
||||
#include "icinga/host.h"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_DBTYPE("Host", "hosts", 1, HostDbObject);
|
||||
REGISTER_DBTYPE("Host", "host", 1, HostDbObject);
|
||||
|
||||
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 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