From b9b6832a11ce05d88da9a296cf5da0c1653cca04 Mon Sep 17 00:00:00 2001 From: Michael Flaherty Date: Tue, 19 Jun 2018 09:35:37 -0700 Subject: [PATCH] Streamline ConfDb loading proceedure (#791) * Create DatabaseConfBuilder & remove locking * Remove all refcounting This is part 1/n in regards to this PR's rework * Move db conf lookup out of RunThreadPart * Return default configuration for failed lookups * RefPtr members & stop leaks * fix uint comparison warning --- core/logic/AMBuilder | 1 + core/logic/Database.cpp | 222 ++++----------------------- core/logic/Database.h | 39 +---- core/logic/DatabaseConfBuilder.cpp | 184 ++++++++++++++++++++++ core/logic/DatabaseConfBuilder.h | 129 ++++++++++++++++ core/logic/smn_database.cpp | 18 ++- extensions/clientprefs/extension.cpp | 12 +- 7 files changed, 367 insertions(+), 238 deletions(-) create mode 100644 core/logic/DatabaseConfBuilder.cpp create mode 100644 core/logic/DatabaseConfBuilder.h diff --git a/core/logic/AMBuilder b/core/logic/AMBuilder index 8548f0bd..1415faa4 100644 --- a/core/logic/AMBuilder +++ b/core/logic/AMBuilder @@ -84,6 +84,7 @@ for arch in SM.archs: 'frame_tasks.cpp', 'smn_halflife.cpp', 'FrameIterator.cpp', + 'DatabaseConfBuilder.cpp', ] if arch == 'x64': diff --git a/core/logic/Database.cpp b/core/logic/Database.cpp index 2f26717a..7da7ea47 100644 --- a/core/logic/Database.cpp +++ b/core/logic/Database.cpp @@ -47,8 +47,6 @@ static bool s_OneTimeThreaderErrorMsg = false; DBManager::DBManager() : m_Terminate(false), - m_ParseLevel(0), - m_ParseState(0), m_pDefault(NULL) { } @@ -72,7 +70,8 @@ void DBManager::OnSourceModAllInitialized() g_ShareSys.AddInterface(NULL, this); g_pSM->BuildPath(Path_SM, m_Filename, sizeof(m_Filename), "configs/databases.cfg"); - + m_Builder.SetPath(m_Filename); + g_PluginSys.AddPluginsListener(this); g_pSM->AddGameFrameHook(&FrameHook); @@ -80,23 +79,7 @@ void DBManager::OnSourceModAllInitialized() void DBManager::OnSourceModLevelChange(const char *mapName) { - SMCError err; - SMCStates states = {0, 0}; - - /* We lock and don't give up the lock until we're done. - * This way the thread's search won't be searching through a - * potentially empty/corrupt list, which would be very bad. - */ - ke::AutoLock lock(&m_ConfigLock); - if ((err = textparsers->ParseFile_SMC(m_Filename, this, &states)) != SMCError_Okay) - { - logger->LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename); - if (err != SMCError_Custom) - { - const char *txt = textparsers->GetSMCErrorString(err); - logger->LogError("[SM] Line %d: %s", states.line, txt); - } - } + m_Builder.StartParse(); } void DBManager::OnSourceModShutdown() @@ -106,7 +89,6 @@ void DBManager::OnSourceModShutdown() g_PluginSys.RemovePluginsListener(this); g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent); g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent); - ClearConfigs(); } unsigned int DBManager::GetInterfaceVersion() @@ -134,136 +116,10 @@ void DBManager::OnHandleDestroy(HandleType_t type, void *object) } } -void DBManager::ReadSMC_ParseStart() -{ - ClearConfigs(); - m_ParseLevel = 0; - m_ParseState = DBPARSE_LEVEL_NONE; - m_DefDriver.clear(); -} - -void DBManager::ClearConfigs() -{ - List::iterator iter; - for (iter=m_confs.begin(); iter!=m_confs.end(); iter++) - delete (*iter); - m_confs.clear(); -} - -ConfDbInfo s_CurInfo; -SMCResult DBManager::ReadSMC_NewSection(const SMCStates *states, const char *name) -{ - if (m_ParseLevel) - { - m_ParseLevel++; - return SMCResult_Continue; - } - - if (m_ParseState == DBPARSE_LEVEL_NONE) - { - if (strcmp(name, "Databases") == 0) - { - m_ParseState = DBPARSE_LEVEL_MAIN; - } else { - m_ParseLevel++; - } - } else if (m_ParseState == DBPARSE_LEVEL_MAIN) { - s_CurInfo = ConfDbInfo(); - s_CurInfo.name = name; - m_ParseState = DBPARSE_LEVEL_DATABASE; - } else if (m_ParseState == DBPARSE_LEVEL_DATABASE) { - m_ParseLevel++; - } - - return SMCResult_Continue; -} - -SMCResult DBManager::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value) -{ - if (m_ParseLevel) - { - return SMCResult_Continue; - } - - if (m_ParseState == DBPARSE_LEVEL_MAIN) - { - if (strcmp(key, "driver_default") == 0) - { - m_DefDriver.assign(value); - } - } else if (m_ParseState == DBPARSE_LEVEL_DATABASE) { - if (strcmp(key, "driver") == 0) - { - if (strcmp(value, "default") != 0) - { - s_CurInfo.driver = value; - } - } else if (strcmp(key, "database") == 0) { - s_CurInfo.database = value; - } else if (strcmp(key, "host") == 0) { - s_CurInfo.host = value; - } else if (strcmp(key, "user") == 0) { - s_CurInfo.user = value; - } else if (strcmp(key, "pass") == 0) { - s_CurInfo.pass = value; - } else if (strcmp(key, "timeout") == 0) { - s_CurInfo.info.maxTimeout = atoi(value); - } else if (strcmp(key, "port") == 0) { - s_CurInfo.info.port = atoi(value); - } - } - - return SMCResult_Continue; -} - -SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states) -{ - if (m_ParseLevel) - { - m_ParseLevel--; - return SMCResult_Continue; - } - - if (m_ParseState == DBPARSE_LEVEL_DATABASE) - { - ConfDbInfo *cdb = new ConfDbInfo(); - - cdb->name = s_CurInfo.name; - cdb->driver = s_CurInfo.driver; - cdb->host = s_CurInfo.host; - cdb->user = s_CurInfo.user; - cdb->pass = s_CurInfo.pass; - cdb->database = s_CurInfo.database; - cdb->realDriver = s_CurInfo.realDriver; - cdb->info.maxTimeout = s_CurInfo.info.maxTimeout; - cdb->info.port = s_CurInfo.info.port; - - cdb->info.driver = cdb->driver.c_str(); - cdb->info.database = cdb->database.c_str(); - cdb->info.host = cdb->host.c_str(); - cdb->info.user = cdb->user.c_str(); - cdb->info.pass = cdb->pass.c_str(); - - /* Save it.. */ - m_confs.push_back(cdb); - - /* Go up one level */ - m_ParseState = DBPARSE_LEVEL_MAIN; - } else if (m_ParseState == DBPARSE_LEVEL_MAIN) { - m_ParseState = DBPARSE_LEVEL_NONE; - return SMCResult_Halt; - } - - return SMCResult_Continue; -} - -void DBManager::ReadSMC_ParseEnd(bool halted, bool failed) -{ -} - bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent, char *error, size_t maxlength) { - ConfDbInfo *pInfo = GetDatabaseConf(name); + ConfDbInfoList *list = m_Builder.GetConfigList(); + ke::RefPtr pInfo = list->GetDatabaseConf(name); if (!pInfo) { @@ -282,11 +138,12 @@ bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool /* Try to assign a real driver pointer */ if (pInfo->info.driver[0] == '\0') { - if (!m_pDefault && m_DefDriver.size() > 0) + ke::AString defaultDriver = list->GetDefaultDriver(); + if (!m_pDefault && defaultDriver.length() > 0) { - m_pDefault = FindOrLoadDriver(m_DefDriver.c_str()); + m_pDefault = FindOrLoadDriver(defaultDriver.chars()); } - dname = m_DefDriver.size() ? m_DefDriver.c_str() : "default"; + dname = defaultDriver.length() ? defaultDriver.chars() : "default"; pInfo->realDriver = m_pDefault; } else { pInfo->realDriver = FindOrLoadDriver(pInfo->info.driver); @@ -310,7 +167,6 @@ bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool *pdb = NULL; g_pSM->Format(error, maxlength, "Driver \"%s\" not found", dname); - return false; } @@ -323,7 +179,7 @@ void DBManager::AddDriver(IDBDriver *pDriver) */ KillWorkerThread(); - m_drivers.push_back(pDriver); + m_drivers.push_back(pDriver); } void DBManager::RemoveDriver(IDBDriver *pDriver) @@ -343,17 +199,17 @@ void DBManager::RemoveDriver(IDBDriver *pDriver) } } - /* Make sure NOTHING references this! */ - List::iterator iter; - for (iter=m_confs.begin(); iter!=m_confs.end(); iter++) + ConfDbInfoList *list = m_Builder.GetConfigList(); + for (size_t i = 0; i < list->length(); i++) { - ConfDbInfo &db = *(*iter); - if (db.realDriver == pDriver) + ke::RefPtr current = list->at(i); + if (current->realDriver == pDriver) { - db.realDriver = NULL; + current->realDriver = NULL; } } + /* Someone unloaded the default driver? Silly.. */ if (pDriver == m_pDefault) { @@ -389,9 +245,11 @@ void DBManager::RemoveDriver(IDBDriver *pDriver) IDBDriver *DBManager::GetDefaultDriver() { - if (!m_pDefault && m_DefDriver.size() > 0) + ConfDbInfoList *list = m_Builder.GetConfigList(); + ke::AString defaultDriver = list->GetDefaultDriver(); + if (!m_pDefault && defaultDriver.length() > 0) { - m_pDefault = FindOrLoadDriver(m_DefDriver.c_str()); + m_pDefault = FindOrLoadDriver(defaultDriver.chars()); } return m_pDefault; @@ -454,10 +312,16 @@ IDBDriver *DBManager::GetDriver(unsigned int index) const DatabaseInfo *DBManager::FindDatabaseConf(const char *name) { - ConfDbInfo *info = GetDatabaseConf(name); + ConfDbInfoList *list = m_Builder.GetConfigList(); + ke::RefPtr info = list->GetDatabaseConf(name); if (!info) { - return NULL; + // couldn't find requested conf, return default if exists + info = list->GetDefaultConfiguration(); + if (!info) + { + return NULL; + } } return &info->info; @@ -465,18 +329,9 @@ const DatabaseInfo *DBManager::FindDatabaseConf(const char *name) ConfDbInfo *DBManager::GetDatabaseConf(const char *name) { - List::iterator iter; - - for (iter=m_confs.begin(); iter!=m_confs.end(); iter++) - { - ConfDbInfo &conf = *(*iter); - if (conf.name == name) - { - return &conf; - } - } - - return NULL; + ConfDbInfoList *list = m_Builder.GetConfigList(); + ke::RefPtr info(list->GetDatabaseConf(name)); + return info; } IDBDriver *DBManager::FindOrLoadDriver(const char *name) @@ -729,19 +584,10 @@ void DBManager::OnPluginWillUnload(IPlugin *plugin) } } -void DBManager::LockConfig() +ke::AString DBManager::GetDefaultDriverName() { - m_ConfigLock.Lock(); -} - -void DBManager::UnlockConfig() -{ - m_ConfigLock.Unlock(); -} - -const char *DBManager::GetDefaultDriverName() -{ - return m_DefDriver.c_str(); + ConfDbInfoList *list = m_Builder.GetConfigList(); + return list->GetDefaultDriver(); } void DBManager::AddDependency(IExtension *myself, IDBDriver *driver) diff --git a/core/logic/Database.h b/core/logic/Database.h index 3511ad02..c64706f2 100644 --- a/core/logic/Database.h +++ b/core/logic/Database.h @@ -32,39 +32,24 @@ #ifndef _INCLUDE_DATABASE_MANAGER_H_ #define _INCLUDE_DATABASE_MANAGER_H_ -#include #include "common_logic.h" #include -#include +#include #include -#include #include #include #include #include "sm_simple_prioqueue.h" +#include +#include "DatabaseConfBuilder.h" using namespace SourceHook; -struct ConfDbInfo -{ - ConfDbInfo() : realDriver(NULL) - { - } - String name; - String driver; - String host; - String user; - String pass; - String database; - IDBDriver *realDriver; - DatabaseInfo info; -}; class DBManager : public IDBManager, public SMGlobalClass, public IHandleTypeDispatch, - public ITextListener_SMC, public IPluginsListener { public: @@ -83,6 +68,7 @@ public: //IDBManager void AddDriver(IDBDriver *pDrivera); void RemoveDriver(IDBDriver *pDriver); const DatabaseInfo *FindDatabaseConf(const char *name); + ConfDbInfo *GetDatabaseConf(const char *name); bool Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent, char *error, size_t maxlength); unsigned int GetDriverCount(); IDBDriver *GetDriver(unsigned int index); @@ -90,25 +76,16 @@ public: //IDBManager HandleError ReadHandle(Handle_t hndl, DBHandleType type, void **ptr); HandleError ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token); void AddDependency(IExtension *myself, IDBDriver *driver); -public: //ITextListener_SMC - void ReadSMC_ParseStart(); - SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name); - SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value); - SMCResult ReadSMC_LeavingSection(const SMCStates *states); - void ReadSMC_ParseEnd(bool halted, bool failed); public: //ke::IRunnable void Run(); void ThreadMain(); public: //IPluginsListener void OnPluginWillUnload(IPlugin *plugin); public: - ConfDbInfo *GetDatabaseConf(const char *name); IDBDriver *FindOrLoadDriver(const char *name); IDBDriver *GetDefaultDriver(); - const char *GetDefaultDriverName(); + ke::AString GetDefaultDriverName(); bool AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio); - void LockConfig(); - void UnlockConfig(); void RunFrame(); inline HandleType_t GetDatabaseType() { @@ -126,17 +103,13 @@ private: CVector m_drSafety; /* which drivers are safe? */ ke::AutoPtr m_Worker; ke::ConditionVariable m_QueueEvent; - ke::Mutex m_ConfigLock; ke::Mutex m_ThinkLock; bool m_Terminate; - List m_confs; + DatabaseConfBuilder m_Builder; HandleType_t m_DriverType; HandleType_t m_DatabaseType; - String m_DefDriver; char m_Filename[PLATFORM_MAX_PATH]; - unsigned int m_ParseLevel; - unsigned int m_ParseState; IDBDriver *m_pDefault; }; diff --git a/core/logic/DatabaseConfBuilder.cpp b/core/logic/DatabaseConfBuilder.cpp new file mode 100644 index 00000000..93443204 --- /dev/null +++ b/core/logic/DatabaseConfBuilder.cpp @@ -0,0 +1,184 @@ +/** + * vim: set ts=4 sw=4 tw=99 noet : + * ============================================================================= + * SourceMod + * Copyright (C) 2004-2018 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ +#include "DatabaseConfBuilder.h" +#include + +#define DBPARSE_LEVEL_NONE 0 +#define DBPARSE_LEVEL_MAIN 1 +#define DBPARSE_LEVEL_DATABASE 2 + +DatabaseConfBuilder::DatabaseConfBuilder() + : m_ParseList(nullptr), + m_InfoList(new ConfDbInfoList()) +{ +} + +void DatabaseConfBuilder::SetPath(char *str) +{ + m_Filename = str; +} + +DatabaseConfBuilder::~DatabaseConfBuilder() +{ +} + +ConfDbInfoList *DatabaseConfBuilder::GetConfigList() +{ + return m_InfoList; +} + +void DatabaseConfBuilder::StartParse() +{ + SMCError err; + SMCStates states = {0, 0}; + if ((err = textparsers->ParseFile_SMC(m_Filename.chars(), this, &states)) != SMCError_Okay) + { + logger->LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename.chars()); + if (err != SMCError_Custom) + { + const char *txt = textparsers->GetSMCErrorString(err); + logger->LogError("[SM] Line %d: %s", states.line, txt); + } + } +} + +void DatabaseConfBuilder::ReadSMC_ParseStart() +{ + m_ParseLevel = 0; + m_ParseState = DBPARSE_LEVEL_NONE; + + m_ParseList = new ConfDbInfoList(); +} + +SMCResult DatabaseConfBuilder::ReadSMC_NewSection(const SMCStates *states, const char *name) +{ + if (m_ParseLevel) + { + m_ParseLevel++; + return SMCResult_Continue; + } + + if (m_ParseState == DBPARSE_LEVEL_NONE) + { + if (strcmp(name, "Databases") == 0) + { + m_ParseState = DBPARSE_LEVEL_MAIN; + } else { + m_ParseLevel++; + } + } else if (m_ParseState == DBPARSE_LEVEL_MAIN) { + m_ParseCurrent = new ConfDbInfo(); + m_ParseCurrent->name = name; + m_ParseState = DBPARSE_LEVEL_DATABASE; + } else if (m_ParseState == DBPARSE_LEVEL_DATABASE) { + m_ParseLevel++; + } + + return SMCResult_Continue; +} + +SMCResult DatabaseConfBuilder::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value) +{ + if (m_ParseLevel) + { + return SMCResult_Continue; + } + + if (m_ParseState == DBPARSE_LEVEL_MAIN) + { + if (strcmp(key, "driver_default") == 0) + { + m_ParseList->SetDefaultDriver(value); + } + } else if (m_ParseState == DBPARSE_LEVEL_DATABASE) { + if (strcmp(key, "driver") == 0) + { + if (strcmp(value, "default") != 0) + { + m_ParseCurrent->driver = value; + } + } else if (strcmp(key, "database") == 0) { + m_ParseCurrent->database = value; + } else if (strcmp(key, "host") == 0) { + m_ParseCurrent->host = value; + } else if (strcmp(key, "user") == 0) { + m_ParseCurrent->user = value; + } else if (strcmp(key, "pass") == 0) { + m_ParseCurrent->pass = value; + } else if (strcmp(key, "timeout") == 0) { + m_ParseCurrent->info.maxTimeout = atoi(value); + } else if (strcmp(key, "port") == 0) { + m_ParseCurrent->info.port = atoi(value); + } + } + + return SMCResult_Continue; +} + +SMCResult DatabaseConfBuilder::ReadSMC_LeavingSection(const SMCStates *states) +{ + if (m_ParseLevel) + { + m_ParseLevel--; + return SMCResult_Continue; + } + + if (m_ParseState == DBPARSE_LEVEL_DATABASE) + { + m_ParseCurrent->info.driver = m_ParseCurrent->driver.chars(); + m_ParseCurrent->info.database = m_ParseCurrent->database.chars(); + m_ParseCurrent->info.host = m_ParseCurrent->host.chars(); + m_ParseCurrent->info.user = m_ParseCurrent->user.chars(); + m_ParseCurrent->info.pass = m_ParseCurrent->pass.chars(); + + /* Save it.. */ + m_ParseCurrent->AddRef(); + m_ParseList->append(m_ParseCurrent); + m_ParseCurrent = nullptr; + + /* Go up one level */ + m_ParseState = DBPARSE_LEVEL_MAIN; + } else if (m_ParseState == DBPARSE_LEVEL_MAIN) { + m_ParseState = DBPARSE_LEVEL_NONE; + return SMCResult_Halt; + } + + return SMCResult_Continue; +} + +void DatabaseConfBuilder::ReadSMC_ParseEnd(bool halted, bool failed) +{ + m_InfoList->ReleaseMembers(); + delete m_InfoList; + m_InfoList = m_ParseList; + + m_ParseList = nullptr; +} diff --git a/core/logic/DatabaseConfBuilder.h b/core/logic/DatabaseConfBuilder.h new file mode 100644 index 00000000..8d9d3faa --- /dev/null +++ b/core/logic/DatabaseConfBuilder.h @@ -0,0 +1,129 @@ +/** + * vim: set ts=4 sw=4 tw=99 noet : + * ============================================================================= + * SourceMod + * Copyright (C) 2004-2018 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +#ifndef _INCLUDE_DATABASE_CONF_BUILDER_H_ +#define _INCLUDE_DATABASE_CONF_BUILDER_H_ + +#include +#include +#include "common_logic.h" + +#include +#include +#include + +class ConfDbInfo : public ke::RefcountedThreadsafe +{ +public: + ConfDbInfo() : realDriver(NULL) + { + } + ke::AString name; + ke::AString driver; + ke::AString host; + ke::AString user; + ke::AString pass; + ke::AString database; + IDBDriver *realDriver; + DatabaseInfo info; +}; + +class ConfDbInfoList : public ke::Vector +{ + /* Allow internal usage of ConfDbInfoList */ + friend class DBManager; + friend class DatabaseConfBuilder; +private: + ke::AString& GetDefaultDriver() { + return m_DefDriver; + } + + ConfDbInfo *GetDatabaseConf(const char *name) { + for (size_t i = 0; i < this->length(); i++) + { + ConfDbInfo *current = this->at(i); + /* If we run into the default configuration, then we'll save it + * for the next call to GetDefaultConfiguration */ + if (strcmp(current->name.chars(), "default") == 0) + { + m_DefaultConfig = current; + } + if (strcmp(current->name.chars(), name) == 0) + { + return current; + } + } + return nullptr; + } + ConfDbInfo *GetDefaultConfiguration() { + return m_DefaultConfig; + } + void SetDefaultDriver(const char *input) { + m_DefDriver = ke::AString(input); + } + void ReleaseMembers() { + for (size_t i = 0; i < this->length(); i++) { + ConfDbInfo *current = this->at(i); + current->Release(); + } + } +private: + ConfDbInfo *m_DefaultConfig; + ke::AString m_DefDriver; +}; + + +class DatabaseConfBuilder : public ITextListener_SMC +{ +public: + DatabaseConfBuilder(); + ~DatabaseConfBuilder(); + void StartParse(); + void SetPath(char* path); + ConfDbInfoList *GetConfigList(); +public: //ITextListener_SMC + void ReadSMC_ParseStart(); + SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name); + SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value); + SMCResult ReadSMC_LeavingSection(const SMCStates *states); + void ReadSMC_ParseEnd(bool halted, bool failed); + +private: + unsigned int m_ParseLevel; + unsigned int m_ParseState; + ConfDbInfo *m_ParseCurrent; + ConfDbInfoList *m_ParseList; +private: + ke::AString m_Filename; + ConfDbInfoList *m_InfoList; +}; + +#endif //_INCLUDE_DATABASE_CONF_BUILDER_H_ diff --git a/core/logic/smn_database.cpp b/core/logic/smn_database.cpp index 5bfd5cd0..23aee730 100644 --- a/core/logic/smn_database.cpp +++ b/core/logic/smn_database.cpp @@ -314,6 +314,12 @@ public: error[0] = '\0'; strncopy(dbname, _dbname, sizeof(dbname)); me = scripts->FindPluginByContext(m_pFunction->GetParentContext()->GetContext()); + + m_pInfo = g_DBMan.GetDatabaseConf(dbname); + if (!m_pInfo) + { + g_pSM->Format(error, sizeof(error), "Could not find database config \"%s\"", dbname); + } } IdentityToken_t *GetOwner() { @@ -325,15 +331,10 @@ public: } void RunThreadPart() { - g_DBMan.LockConfig(); - const DatabaseInfo *pInfo = g_DBMan.FindDatabaseConf(dbname); - if (!pInfo) + if (m_pInfo) { - g_pSM->Format(error, sizeof(error), "Could not find database config \"%s\"", dbname); - } else { - m_pDatabase = m_pDriver->Connect(pInfo, false, error, sizeof(error)); + m_pDatabase = m_pDriver->Connect(&m_pInfo->info, false, error, sizeof(error)); } - g_DBMan.UnlockConfig(); } void CancelThinkPart() { @@ -383,6 +384,7 @@ public: delete this; } private: + ke::RefPtr m_pInfo; IPlugin *me; IPluginFunction *m_pFunction; IDBDriver *m_pDriver; @@ -453,7 +455,7 @@ static cell_t ConnectToDbAsync(IPluginContext *pContext, const cell_t *params, A g_pSM->Format(error, sizeof(error), "Could not find driver \"%s\"", - pInfo->driver[0] == '\0' ? g_DBMan.GetDefaultDriverName() : pInfo->driver); + pInfo->driver[0] == '\0' ? g_DBMan.GetDefaultDriverName().chars() : pInfo->driver); } else if (!driver->IsThreadSafe()) { g_pSM->Format(error, sizeof(error), diff --git a/extensions/clientprefs/extension.cpp b/extensions/clientprefs/extension.cpp index cd196f38..62231803 100644 --- a/extensions/clientprefs/extension.cpp +++ b/extensions/clientprefs/extension.cpp @@ -56,20 +56,14 @@ bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late) if (DBInfo == NULL) { - DBInfo = dbi->FindDatabaseConf("default"); - + DBInfo = dbi->FindDatabaseConf("storage-local"); if (DBInfo == NULL) { - DBInfo = dbi->FindDatabaseConf("storage-local"); + ke::SafeStrcpy(error, maxlength, "Could not find any suitable database configs"); + return false; } } - if (DBInfo == NULL) - { - ke::SafeStrcpy(error, maxlength, "Could not find any suitable database configs"); - return false; - } - if (DBInfo->driver && DBInfo->driver[0] != '\0') { Driver = dbi->FindOrLoadDriver(DBInfo->driver);