2016-03-10 04:57:13 +01:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
#include "Database.hpp"
|
|
|
|
#include "SockAddr.hpp"
|
2016-11-14 13:06:30 +01:00
|
|
|
#include "Metadata.hpp"
|
2016-11-14 14:46:48 +01:00
|
|
|
#include "SearchNode.hpp"
|
2016-03-10 04:57:13 +01:00
|
|
|
#include "LookupResult.hpp"
|
2016-11-14 13:06:30 +01:00
|
|
|
#include "EntryDataList.hpp"
|
2016-03-10 04:57:13 +01:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
namespace SqMod {
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
SQInteger Database::Typename(HSQUIRRELVM vm)
|
|
|
|
{
|
2016-11-14 13:06:30 +01:00
|
|
|
static const SQChar name[] = _SC("SqMMDatabase");
|
2016-03-10 04:57:13 +01:00
|
|
|
sq_pushstring(vm, name, sizeof(name));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2016-11-14 13:06:30 +01:00
|
|
|
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
|
|
|
|
void Database::Validate(CCStr file, Int32 line) const
|
|
|
|
{
|
|
|
|
if (!m_Handle)
|
|
|
|
{
|
|
|
|
SqThrowF("Invalid Maxmind database reference =>[%s:%d]", file, line);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
2016-03-10 04:57:13 +01:00
|
|
|
void Database::Validate() const
|
|
|
|
{
|
2016-11-14 13:06:30 +01:00
|
|
|
if (!m_Handle)
|
|
|
|
{
|
|
|
|
SqThrowF("Invalid Maxmind database reference");
|
|
|
|
}
|
2016-03-10 04:57:13 +01:00
|
|
|
}
|
2016-11-14 13:06:30 +01:00
|
|
|
#endif // _DEBUG
|
2016-03-10 04:57:13 +01:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2016-11-14 13:06:30 +01:00
|
|
|
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
|
|
|
|
const DbRef & Database::GetValid(CCStr file, Int32 line) const
|
2016-03-10 04:57:13 +01:00
|
|
|
{
|
2016-11-14 13:06:30 +01:00
|
|
|
Validate(file, line);
|
|
|
|
return m_Handle;
|
2016-03-10 04:57:13 +01:00
|
|
|
}
|
2016-11-14 13:06:30 +01:00
|
|
|
#else
|
|
|
|
const DbRef & Database::GetValid() const
|
|
|
|
{
|
|
|
|
Validate();
|
|
|
|
return m_Handle;
|
|
|
|
}
|
|
|
|
#endif // _DEBUG
|
2016-03-10 04:57:13 +01:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2016-11-14 13:06:30 +01:00
|
|
|
Metadata Database::GetMetadata() const
|
2016-03-10 04:57:13 +01:00
|
|
|
{
|
2016-11-14 13:06:30 +01:00
|
|
|
return Metadata(m_Handle, &(SQMOD_GET_VALID(*this)->mDb).metadata);
|
2016-03-10 04:57:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2016-11-14 13:06:30 +01:00
|
|
|
Object Database::GetMetadataAsEntryDataList() const
|
2016-03-10 04:57:13 +01:00
|
|
|
{
|
2016-11-14 13:06:30 +01:00
|
|
|
MMDB_entry_data_list_s * entry_data_list = nullptr;
|
|
|
|
// Attempt to retrieve the database meta-data as an entry data list
|
|
|
|
const int status = MMDB_get_metadata_as_entry_data_list(&(SQMOD_GET_VALID(*this)->mDb), &entry_data_list);
|
|
|
|
// Validate the status code
|
2016-03-10 04:57:13 +01:00
|
|
|
if (status != MMDB_SUCCESS)
|
|
|
|
{
|
2016-11-14 13:44:01 +01:00
|
|
|
STHROWF("Unable to get meta-data entry data list [%s]", MMDB_strerror(status));
|
2016-03-10 04:57:13 +01:00
|
|
|
}
|
2016-11-14 13:06:30 +01:00
|
|
|
// Return the resulted list
|
|
|
|
return Object(new EntryDataList(m_Handle, entry_data_list));
|
2016-03-10 04:57:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
LookupResult Database::LookupString(CSStr addr)
|
|
|
|
{
|
|
|
|
// Validate the database handle
|
2016-11-14 13:06:30 +01:00
|
|
|
SQMOD_VALIDATE(*this);
|
2016-03-10 04:57:13 +01:00
|
|
|
// Validate the specified string
|
2016-11-14 13:06:30 +01:00
|
|
|
if (!addr || *addr == '\0')
|
|
|
|
{
|
2016-03-22 23:27:48 +01:00
|
|
|
STHROWF("Invalid address string");
|
2016-11-14 13:06:30 +01:00
|
|
|
}
|
2016-03-10 04:57:13 +01:00
|
|
|
// Dummy variables to obtain the status codes
|
|
|
|
int gai_error, mmdb_error;
|
|
|
|
// Attempt to perform the actual lookup
|
2016-11-14 13:06:30 +01:00
|
|
|
MMDB_lookup_result_s result = MMDB_lookup_string(&m_Handle->mDb, addr, &gai_error, &mmdb_error);
|
2016-03-10 04:57:13 +01:00
|
|
|
// Validate the result of the getaddrinfo() function call
|
|
|
|
if (gai_error != 0)
|
2016-11-14 13:06:30 +01:00
|
|
|
{
|
2016-03-22 23:27:48 +01:00
|
|
|
STHROWF("Unable to resolve address (%s) because [%s]", addr, gai_strerror(gai_error));
|
2016-11-14 13:06:30 +01:00
|
|
|
}
|
2016-03-10 04:57:13 +01:00
|
|
|
// Validate the lookup status code
|
|
|
|
else if (mmdb_error != MMDB_SUCCESS)
|
2016-11-14 13:06:30 +01:00
|
|
|
{
|
2016-03-22 23:27:48 +01:00
|
|
|
STHROWF("Unable to lookup address (%s) because [%s]", addr, MMDB_strerror(mmdb_error));
|
2016-11-14 13:06:30 +01:00
|
|
|
}
|
2016-03-10 04:57:13 +01:00
|
|
|
// Now it's safe to return the lookup result
|
2016-11-14 13:06:30 +01:00
|
|
|
return LookupResult(m_Handle, result);
|
2016-03-10 04:57:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
LookupResult Database::LookupSockAddr(SockAddr & addr)
|
|
|
|
{
|
|
|
|
// Validate the database handle
|
2016-11-14 13:06:30 +01:00
|
|
|
SQMOD_VALIDATE(*this);
|
2016-03-10 04:57:13 +01:00
|
|
|
// Validate the specified socket address
|
|
|
|
if (!addr.IsValid())
|
2016-11-14 13:06:30 +01:00
|
|
|
{
|
2016-03-22 23:27:48 +01:00
|
|
|
STHROWF("Invalid address instance");
|
2016-11-14 13:06:30 +01:00
|
|
|
}
|
2016-03-10 04:57:13 +01:00
|
|
|
// Dummy variable to obtain the status codes
|
|
|
|
int mmdb_error;
|
|
|
|
// Attempt to perform the actual lookup
|
2016-11-14 13:06:30 +01:00
|
|
|
MMDB_lookup_result_s result = MMDB_lookup_sockaddr(&m_Handle->mDb, addr.GetHandle()->ai_addr, &mmdb_error);
|
2016-03-10 04:57:13 +01:00
|
|
|
// Validate the lookup status code
|
|
|
|
if (mmdb_error != MMDB_SUCCESS)
|
2016-11-14 13:06:30 +01:00
|
|
|
{
|
2016-11-14 13:44:01 +01:00
|
|
|
STHROWF("Unable to lookup address (%s) because [%s]", addr.GetAddress(), MMDB_strerror(mmdb_error));
|
2016-11-14 13:06:30 +01:00
|
|
|
}
|
2016-03-10 04:57:13 +01:00
|
|
|
// Now it's safe to return the lookup result
|
2016-11-14 13:06:30 +01:00
|
|
|
return LookupResult(m_Handle, result);
|
|
|
|
}
|
|
|
|
|
2016-11-14 14:46:48 +01:00
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
SearchNode Database::ReadNode(Uint32 node) const
|
|
|
|
{
|
|
|
|
// Validate the database handle
|
|
|
|
SQMOD_VALIDATE(*this);
|
|
|
|
// Prepare a temporary search node
|
|
|
|
MMDB_search_node_s search_node;
|
|
|
|
// Attempt to retrieve the requested node from the database
|
|
|
|
const int status = MMDB_read_node(&(SQMOD_GET_VALID(*this)->mDb), node, &search_node);
|
|
|
|
// Validate the status code
|
|
|
|
if (status != MMDB_SUCCESS)
|
|
|
|
{
|
|
|
|
STHROWF("Unable to get node [%s]", MMDB_strerror(status));
|
|
|
|
}
|
|
|
|
// Return the resulted list
|
|
|
|
return SearchNode(m_Handle, search_node);
|
|
|
|
}
|
|
|
|
|
2016-11-14 13:06:30 +01:00
|
|
|
// ================================================================================================
|
|
|
|
void Register_Database(Table & mmns)
|
|
|
|
{
|
|
|
|
mmns.Bind(_SC("Database"),
|
|
|
|
Class< Database >(mmns.GetVM(), _SC("SqMMDatabase"))
|
|
|
|
// Constructors
|
|
|
|
.Ctor()
|
|
|
|
.Ctor< CSStr >()
|
|
|
|
.Ctor< CSStr, Uint32 >()
|
|
|
|
// Meta-methods
|
|
|
|
.SquirrelFunc(_SC("_typename"), &Database::Typename)
|
|
|
|
.Func(_SC("_tostring"), &Database::ToString)
|
|
|
|
// Properties
|
|
|
|
.Prop(_SC("IsValid"), &Database::IsValid)
|
|
|
|
.Prop(_SC("References"), &Database::GetRefCount)
|
|
|
|
.Prop(_SC("Metadata"), &Database::GetMetadata)
|
|
|
|
.Prop(_SC("MetadataAsEntryDataList"), &Database::GetMetadataAsEntryDataList)
|
2016-11-14 13:44:01 +01:00
|
|
|
// Member methods
|
|
|
|
.Func(_SC("Release"), &Database::Release)
|
2016-11-14 13:06:30 +01:00
|
|
|
.Func(_SC("LookupString"), &Database::LookupString)
|
|
|
|
.Func(_SC("LookupSockAddr"), &Database::LookupSockAddr)
|
2016-11-14 14:46:48 +01:00
|
|
|
.Func(_SC("ReadNode"), &Database::ReadNode)
|
2016-11-14 13:44:01 +01:00
|
|
|
// Member overloads
|
2016-11-14 13:06:30 +01:00
|
|
|
.Overload< void (Database::*)(CSStr) >(_SC("Open"), &Database::Open)
|
|
|
|
.Overload< void (Database::*)(CSStr, Uint32) >(_SC("Open"), &Database::Open)
|
|
|
|
);
|
2016-03-10 04:57:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
} // Namespace:: SqMod
|