// ------------------------------------------------------------------------------------------------ #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