1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-09 01:07:16 +01:00
SqMod/modules/mmdb/Database.cpp
Sandu Liviu Catalin 7d1493afd3 More code cleanup and fixes in the MaxmindDB module.
Implemented the SearchNode wrapper.
2016-11-14 15:46:48 +02:00

173 lines
6.0 KiB
C++

// ------------------------------------------------------------------------------------------------
#include "Database.hpp"
#include "SockAddr.hpp"
#include "Metadata.hpp"
#include "SearchNode.hpp"
#include "LookupResult.hpp"
#include "EntryDataList.hpp"
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQInteger Database::Typename(HSQUIRRELVM vm)
{
static const SQChar name[] = _SC("SqMMDatabase");
sq_pushstring(vm, name, sizeof(name));
return 1;
}
// ------------------------------------------------------------------------------------------------
#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
void Database::Validate() const
{
if (!m_Handle)
{
SqThrowF("Invalid Maxmind database reference");
}
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
#if defined(_DEBUG) || defined(SQMOD_EXCEPTLOC)
const DbRef & Database::GetValid(CCStr file, Int32 line) const
{
Validate(file, line);
return m_Handle;
}
#else
const DbRef & Database::GetValid() const
{
Validate();
return m_Handle;
}
#endif // _DEBUG
// ------------------------------------------------------------------------------------------------
Metadata Database::GetMetadata() const
{
return Metadata(m_Handle, &(SQMOD_GET_VALID(*this)->mDb).metadata);
}
// ------------------------------------------------------------------------------------------------
Object Database::GetMetadataAsEntryDataList() const
{
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
if (status != MMDB_SUCCESS)
{
STHROWF("Unable to get meta-data entry data list [%s]", MMDB_strerror(status));
}
// Return the resulted list
return Object(new EntryDataList(m_Handle, entry_data_list));
}
// ------------------------------------------------------------------------------------------------
LookupResult Database::LookupString(CSStr addr)
{
// Validate the database handle
SQMOD_VALIDATE(*this);
// Validate the specified string
if (!addr || *addr == '\0')
{
STHROWF("Invalid address string");
}
// Dummy variables to obtain the status codes
int gai_error, mmdb_error;
// Attempt to perform the actual lookup
MMDB_lookup_result_s result = MMDB_lookup_string(&m_Handle->mDb, addr, &gai_error, &mmdb_error);
// Validate the result of the getaddrinfo() function call
if (gai_error != 0)
{
STHROWF("Unable to resolve address (%s) because [%s]", addr, gai_strerror(gai_error));
}
// Validate the lookup status code
else if (mmdb_error != MMDB_SUCCESS)
{
STHROWF("Unable to lookup address (%s) because [%s]", addr, MMDB_strerror(mmdb_error));
}
// Now it's safe to return the lookup result
return LookupResult(m_Handle, result);
}
// ------------------------------------------------------------------------------------------------
LookupResult Database::LookupSockAddr(SockAddr & addr)
{
// Validate the database handle
SQMOD_VALIDATE(*this);
// Validate the specified socket address
if (!addr.IsValid())
{
STHROWF("Invalid address instance");
}
// Dummy variable to obtain the status codes
int mmdb_error;
// Attempt to perform the actual lookup
MMDB_lookup_result_s result = MMDB_lookup_sockaddr(&m_Handle->mDb, addr.GetHandle()->ai_addr, &mmdb_error);
// Validate the lookup status code
if (mmdb_error != MMDB_SUCCESS)
{
STHROWF("Unable to lookup address (%s) because [%s]", addr.GetAddress(), MMDB_strerror(mmdb_error));
}
// Now it's safe to return the lookup result
return LookupResult(m_Handle, result);
}
// ------------------------------------------------------------------------------------------------
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);
}
// ================================================================================================
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)
// Member methods
.Func(_SC("Release"), &Database::Release)
.Func(_SC("LookupString"), &Database::LookupString)
.Func(_SC("LookupSockAddr"), &Database::LookupSockAddr)
.Func(_SC("ReadNode"), &Database::ReadNode)
// Member overloads
.Overload< void (Database::*)(CSStr) >(_SC("Open"), &Database::Open)
.Overload< void (Database::*)(CSStr, Uint32) >(_SC("Open"), &Database::Open)
);
}
} // Namespace:: SqMod