static cell_t SQL_PrepareQuery(IPluginContext *pContext, const cell_t *params) { IDatabase *db = NULL; HandleError err; if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db)) != HandleError_None) { return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err); } char *query, *error; size_t maxlength = (size_t)params[4]; pContext->LocalToString(params[2], &query); pContext->LocalToString(params[3], &error); IPreparedQuery *qr = db->PrepareQuery(query, error, maxlength); if (!qr) { return BAD_HANDLE; } Handle_t hndl = g_HandleSys.CreateHandle(hStmtType, qr, pContext->GetIdentity(), g_pCoreIdent, NULL); if (hndl == BAD_HANDLE) { qr->Destroy(); return BAD_HANDLE; } return hndl; }
static cell_t SQL_Connect(IPluginContext *pContext, const cell_t *params) { char *conf, *err; size_t maxlength = (size_t)params[4]; bool persistent = params[2] ? true : false; pContext->LocalToString(params[1], &conf); pContext->LocalToString(params[3], &err); IDBDriver *driver; IDatabase *db; if (!g_DBMan.Connect(conf, &driver, &db, persistent, err, maxlength)) { return BAD_HANDLE; } Handle_t hndl = g_DBMan.CreateHandle(DBHandle_Database, db, pContext->GetIdentity()); if (!hndl) { db->Close(); return BAD_HANDLE; } /* HACK! Add us to the dependency list */ CExtension *pExt = g_Extensions.GetExtensionFromIdent(driver->GetIdentity()); if (pExt) { g_Extensions.BindChildPlugin(pExt, g_PluginSys.GetPluginByCtx(pContext->GetContext())); } return hndl; }
static cell_t SQL_GetInsertId(IPluginContext *pContext, const cell_t *params) { IDatabase *db = NULL; IQuery *query = NULL; IPreparedQuery *stmt = NULL; HandleError err; if (((err = ReadDbOrStmtHndl(params[1], pContext, &db, &stmt)) != HandleError_None) && ((err = ReadQueryAndDbHndl(params[1], pContext, &query, &db)) != HandleError_None)) { return pContext->ThrowNativeError("Invalid statement, db, or query Handle %x (error: %d)", params[1], err); } if (query) { return db->GetInsertIDForQuery(query); } else if (db) { return db->GetInsertID(); } else if (stmt) { return stmt->GetInsertID(); } return pContext->ThrowNativeError("Unknown error reading db/stmt/query handles"); }
static cell_t SQL_GetError(IPluginContext *pContext, const cell_t *params) { IDatabase *db = NULL; IPreparedQuery *stmt = NULL; HandleError err; if ((err = ReadDbOrStmtHndl(params[1], pContext, &db, &stmt)) != HandleError_None) { return pContext->ThrowNativeError("Invalid statement or db Handle %x (error: %d)", params[1], err); } const char *error = ""; if (db) { error = db->GetError(); } else if (stmt) { error = stmt->GetError(); } if (error[0] == '\0') { return false; } pContext->StringToLocalUTF8(params[2], params[3], error, NULL); return 1; }
static cell_t SQL_QuoteString(IPluginContext *pContext, const cell_t *params) { IDatabase *db = NULL; HandleError err; if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db)) != HandleError_None) { return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err); } char *input, *output; size_t maxlength = (size_t)params[4]; pContext->LocalToString(params[2], &input); pContext->LocalToString(params[3], &output); size_t written; bool s = db->QuoteString(input, output, maxlength, &written); cell_t *addr; pContext->LocalToPhysAddr(params[5], &addr); *addr = (cell_t)written; return s ? 1 : 0; }
static cell AMX_NATIVE_CALL SQL_QuoteStringFmt(AMX *amx, cell *params) { int len; char *str = MF_FormatAmxString(amx, params, 4, &len); size_t newsize; static char buffer[8192]; if (params[1] != 0) { IDatabase *pDb = (IDatabase *)GetHandle(params[1], Handle_Database); if (!pDb) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid database handle: %d", params[1]); return 0; } if (pDb->QuoteString(str, buffer, sizeof(buffer)-1, &newsize) == 0) { MF_SetAmxString(amx, params[2], buffer, params[3]); return newsize; } else { return -1; } } else { if (g_Mysql.QuoteString(str, buffer, sizeof(buffer)-1, &newsize) == 0) { MF_SetAmxString(amx, params[2], buffer, params[3]); return newsize; } else { return -1; } } }
static cell AMX_NATIVE_CALL SQL_SetCharset(AMX *amx, cell *params) { SQL_Connection *sql = (SQL_Connection *)GetHandle(params[1], Handle_Connection); if (!sql) { IDatabase *pDb = (IDatabase *)GetHandle(params[1], Handle_Database); if (!pDb) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid info tuple or database handle: %d", params[1]); return 0; } int len; return pDb->SetCharacterSet(MF_GetAmxString(amx, params[2], 0, &len)); } else { int len; const char *charset = MF_GetAmxString(amx, params[2], 0, &len); if (!sql->charset || stricmp(charset, sql->charset)) { sql->charset = strdup(charset); } return 1; } return 0; }
void MysqlThread::RunThread(IThreadHandle *pHandle) { DatabaseInfo info; info.database = m_db.chars(); info.pass = ""; info.user = ""; info.host = ""; info.port = 0; float save_time = m_qrInfo.queue_time; memset(&m_qrInfo, 0, sizeof(m_qrInfo)); m_qrInfo.queue_time = save_time; IDatabase *pDatabase = g_Sqlite.Connect(&info, &m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.error, 254); IQuery *pQuery = NULL; if (!pDatabase) { m_qrInfo.connect_success = false; m_qrInfo.query_success = false; } else { m_qrInfo.connect_success = true; pQuery = pDatabase->PrepareQuery(m_query.chars()); if (!pQuery->Execute2(&m_qrInfo.amxinfo.info, m_qrInfo.amxinfo.error, 254)) { m_qrInfo.query_success = false; } else { m_qrInfo.query_success = true; } } if (m_qrInfo.query_success && m_qrInfo.amxinfo.info.rs) { m_atomicResult.CopyFrom(m_qrInfo.amxinfo.info.rs); m_qrInfo.amxinfo.info.rs = &m_atomicResult; } if (pQuery) { m_qrInfo.amxinfo.pQuery = pQuery; } else { m_qrInfo.amxinfo.opt_ptr = new char[m_query.length() + 1]; strcpy(m_qrInfo.amxinfo.opt_ptr, m_query.chars()); } if (pDatabase) { pDatabase->FreeHandle(); pDatabase = NULL; } }
void attachSystemTablesLocal(IDatabase & system_database) { system_database.attachTable("one", StorageSystemOne::create("one")); system_database.attachTable("numbers", StorageSystemNumbers::create("numbers", false)); system_database.attachTable("numbers_mt", StorageSystemNumbers::create("numbers_mt", true)); system_database.attachTable("databases", StorageSystemDatabases::create("databases")); system_database.attachTable("tables", StorageSystemTables::create("tables")); system_database.attachTable("columns", StorageSystemColumns::create("columns")); system_database.attachTable("functions", StorageSystemFunctions::create("functions")); system_database.attachTable("events", StorageSystemEvents::create("events")); system_database.attachTable("settings", StorageSystemSettings::create("settings")); system_database.attachTable("build_options", StorageSystemBuildOptions::create("build_options")); }
static cell_t SQL_ExecuteTransaction(IPluginContext *pContext, const cell_t *params) { HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); IDatabase *db = NULL; HandleError err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db); if (err != HandleError_None) return pContext->ThrowNativeError("Invalid database handle %x (error: %d)", params[1], err); Transaction *txn; if ((err = handlesys->ReadHandle(params[2], hTransactionType, &sec, (void **)&txn)) != HandleError_None) return pContext->ThrowNativeError("Invalid transaction handle %x (error %d)", params[2], err); if (!db->GetDriver()->IsThreadSafe()) return pContext->ThrowNativeError("Driver \"%s\" is not thread safe!", db->GetDriver()->GetIdentifier()); IPluginFunction *onSuccess = NULL; IPluginFunction *onError = NULL; if (params[3] != -1 && ((onSuccess = pContext->GetFunctionById(params[3])) == NULL)) return pContext->ThrowNativeError("Function id %x is invalid", params[3]); if (params[4] != -1 && ((onError = pContext->GetFunctionById(params[4])) == NULL)) return pContext->ThrowNativeError("Function id %x is invalid", params[4]); cell_t data = params[5]; PrioQueueLevel priority = PrioQueue_Normal; if (params[6] == (cell_t)PrioQueue_High) priority = PrioQueue_High; else if (params[6] == (cell_t)PrioQueue_Low) priority = PrioQueue_Low; TTransactOp *op = new TTransactOp(db, txn, params[2], pContext->GetIdentity(), onSuccess, onError, data); // The handle owns the underlying Transaction object, but we want to close // the plugin's view both to ensure reliable access for us and to prevent // further tampering on the main thread. To do this, TTransactOp clones the // transaction handle and automatically closes it. Therefore, it's safe to // close the plugin's handle here. handlesys->FreeHandle(params[2], &sec); IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext()); if (pPlugin->GetProperty("DisallowDBThreads", NULL) || !g_DBMan.AddToThreadQueue(op, priority)) { // Do everything right now. op->RunThreadPart(); op->RunThinkPart(); op->Destroy(); } return 0; }
void DBManager::OnHandleDestroy(HandleType_t type, void *object) { if (type == m_DriverType) { /* Ignore */ return; } if (g_HandleSys.TypeCheck(type, m_DatabaseType)) { IDatabase *pdb = (IDatabase *)object; pdb->Close(); } }
static cell_t SQL_UnlockDatabase(IPluginContext *pContext, const cell_t *params) { IDatabase *db = NULL; HandleError err; if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db)) != HandleError_None) { return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err); } db->UnlockFromFullAtomicOperation(); return 1; }
static cell_t SQL_TQuery(IPluginContext *pContext, const cell_t *params) { IDatabase *db = NULL; HandleError err; if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db)) != HandleError_None) { return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err); } if (!db->GetDriver()->IsThreadSafe()) { return pContext->ThrowNativeError("Driver \"%s\" is not thread safe!", db->GetDriver()->GetIdentifier()); } IPluginFunction *pf = pContext->GetFunctionById(params[2]); if (!pf) { return pContext->ThrowNativeError("Function id %x is invalid", params[2]); } char *query; pContext->LocalToString(params[3], &query); cell_t data = params[4]; PrioQueueLevel level = PrioQueue_Normal; if (params[5] == (cell_t)PrioQueue_High) { level = PrioQueue_High; } else if (params[5] == (cell_t)PrioQueue_Low) { level = PrioQueue_Low; } CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext()); TQueryOp *op = new TQueryOp(db, pf, query, data); if (pPlugin->GetProperty("DisallowDBThreads", NULL) || !g_DBMan.AddToThreadQueue(op, level)) { /* Do everything right now */ op->RunThreadPart(); op->RunThinkPart(); op->Destroy(); } return 1; }
void attachSystemTablesServer(IDatabase & system_database, bool has_zookeeper) { attachSystemTablesLocal(system_database); system_database.attachTable("parts", StorageSystemParts::create("parts")); system_database.attachTable("processes", StorageSystemProcesses::create("processes")); system_database.attachTable("metrics", StorageSystemMetrics::create("metrics")); system_database.attachTable("merges", StorageSystemMerges::create("merges")); system_database.attachTable("replicas", StorageSystemReplicas::create("replicas")); system_database.attachTable("replication_queue", StorageSystemReplicationQueue::create("replication_queue")); system_database.attachTable("dictionaries", StorageSystemDictionaries::create("dictionaries")); system_database.attachTable("clusters", StorageSystemClusters::create("clusters")); system_database.attachTable("graphite_retentions", StorageSystemGraphite::create("graphite_retentions")); if (has_zookeeper) system_database.attachTable("zookeeper", StorageSystemZooKeeper::create("zookeeper")); }
static cell_t SQL_SetCharset(IPluginContext *pContext, const cell_t *params) { IDatabase *db = NULL; HandleError err; if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db)) != HandleError_None) { return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err); } char *characterset; pContext->LocalToString(params[2], &characterset); return db->SetCharacterSet(characterset); }
int main() { IDatabase *db; // 初始化数据库连接池 DbConnectPool::getInstance()->load("config.xml"); KY_LOG_INFO("第一次获取test数据库连接"); db = DbConnectPool::getInstance()->getConnect("test"); KY_LOG_INFO("释放数据库连接"); DbConnectPool::getInstance()->release(db); KY_LOG_INFO("第二次获取test数据库连接"); db = DbConnectPool::getInstance()->getConnect("test"); KY_LOG_INFO("开始数据库操作"); if ( db->select("select id,name,age from user") ) { KY_LOG_INFO("affected rows: %ld", db->getAffectedRows()); while ( db->next() ) { int id; long age; string name; id = db->getInt("id"); age = db->getLong("age"); name = db->getString("Name"); KY_LOG_INFO("id: %d name: %s age: %ld", id, name.c_str(), age); } } KY_LOG_INFO("释放数据库连接"); DbConnectPool::getInstance()->release(db); return 0; }
static cell_t SQL_Query(IPluginContext *pContext, const cell_t *params) { IDatabase *db = NULL; HandleError err; if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db)) != HandleError_None) { return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err); } char *query; pContext->LocalToString(params[2], &query); IQuery *qr; if (params[0] >= 3 && params[3] != -1) { qr = db->DoQueryEx(query, params[3]); } else { qr = db->DoQuery(query); } if (!qr) { return BAD_HANDLE; } CombinedQuery *c = new CombinedQuery; c->query = qr; c->db = db; Handle_t hndl = g_HandleSys.CreateHandle(hCombinedQueryType, c, pContext->GetIdentity(), g_pCoreIdent, NULL); if (hndl == BAD_HANDLE) { qr->Destroy(); delete c; return BAD_HANDLE; } return hndl; }
static cell_t SQL_FastQuery(IPluginContext *pContext, const cell_t *params) { IDatabase *db = NULL; HandleError err; if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db)) != HandleError_None) { return pContext->ThrowNativeError("Invalid database Handle %x (error: %d)", params[1], err); } char *query; pContext->LocalToString(params[2], &query); if (params[0] >= 3 && params[3] != -1) { return db->DoSimpleQueryEx(query, params[3]) ? 1 : 0; } return db->DoSimpleQuery(query) ? 1 : 0; }
static cell AMX_NATIVE_CALL SQL_PrepareQuery(AMX *amx, cell *params) { IDatabase *pDb = (IDatabase *)GetHandle(params[1], Handle_Database); if (!pDb) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid database handle: %d", params[1]); return 0; } int len; char *fmt = MF_FormatAmxString(amx, params, 2, &len); IQuery *pQuery = pDb->PrepareQuery(fmt); if (!pQuery) return 0; AmxQueryInfo *qinfo = new AmxQueryInfo; qinfo->pQuery = pQuery; memset(&qinfo->info, 0, sizeof(QueryInfo)); return MakeHandle(qinfo, Handle_Query, FreeQuery); }
void attachSystemTablesAsync(IDatabase & system_database, AsynchronousMetrics & async_metrics) { system_database.attachTable("asynchronous_metrics", StorageSystemAsynchronousMetrics::create("asynchronous_metrics", async_metrics)); }
static cell_t SQL_ConnectCustom(IPluginContext *pContext, const cell_t *params) { KeyValues *kv; HandleError err; kv = g_pSM->ReadKeyValuesHandle(params[1], &err, false); if (kv == NULL) { return pContext->ThrowNativeError("Invalid KeyValues handle %x (error: %d)", params[1], err); } DatabaseInfo info = smcore.GetDBInfoFromKeyValues(kv); IDBDriver *driver; if (info.driver[0] == '\0' || strcmp(info.driver, "default") == 0) { driver = g_DBMan.GetDefaultDriver(); } else { driver = g_DBMan.FindOrLoadDriver(info.driver); } if (driver == NULL) { char buffer[255]; g_pSM->Format(buffer, sizeof(buffer), "Could not find driver \"%s\"", info.driver); pContext->StringToLocalUTF8(params[2], params[3], buffer, NULL); return BAD_HANDLE; } char *buffer; IDatabase *db; pContext->LocalToString(params[2], &buffer); db = driver->Connect(&info, params[4] ? true : false, buffer, params[3]); if (db == NULL) { return BAD_HANDLE; } Handle_t hndl = g_DBMan.CreateHandle(DBHandle_Database, db, pContext->GetIdentity()); if (!hndl) { db->Close(); return pContext->ThrowNativeError("Out of handles!"); } /* HACK! Add us to the dependency list */ IExtension *pExt = g_Extensions.GetExtensionFromIdent(driver->GetIdentity()); if (pExt) { g_Extensions.BindChildPlugin(pExt, scripts->FindPluginByContext(pContext->GetContext())); } return hndl; }
static cell_t SQL_ConnectEx(IPluginContext *pContext, const cell_t *params) { IDBDriver *driver; if (params[1] == BAD_HANDLE) { if ((driver = g_DBMan.GetDefaultDriver()) == NULL) { return pContext->ThrowNativeError("Could not find any default driver"); } } else { HandleError err; if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Driver, (void **)&driver)) != HandleError_None) { return pContext->ThrowNativeError("Invalid driver Handle %x (error: %d)", params[1], err); } } char *host, *user, *pass, *database, *error; size_t maxlength = (size_t)params[7]; bool persistent = params[8] ? true : false; unsigned int port = params[9]; unsigned int maxTimeout = params[10]; pContext->LocalToString(params[2], &host); pContext->LocalToString(params[3], &user); pContext->LocalToString(params[4], &pass); pContext->LocalToString(params[5], &database); pContext->LocalToString(params[6], &error); DatabaseInfo info; info.database = database; info.driver = driver->GetIdentifier(); info.host = host; info.maxTimeout = maxTimeout; info.pass = pass; info.port = port; info.user = user; IDatabase *db = driver->Connect(&info, persistent, error, maxlength); if (db) { Handle_t hndl = g_DBMan.CreateHandle(DBHandle_Database, db, pContext->GetIdentity()); if (!hndl) { db->Close(); return BAD_HANDLE; } /* HACK! Add us to the dependency list */ CExtension *pExt = g_Extensions.GetExtensionFromIdent(driver->GetIdentity()); if (pExt) { g_Extensions.BindChildPlugin(pExt, g_PluginSys.GetPluginByCtx(pContext->GetContext())); } return hndl; } return BAD_HANDLE; }
void FreeDatabase(void *p, unsigned int num) { IDatabase *db = (IDatabase *)p; db->FreeHandle(); }
static cell_t SQL_ConnectCustom(IPluginContext *pContext, const cell_t *params) { KeyValues *kv; HandleError err; kv = g_SourceMod.ReadKeyValuesHandle(params[1], &err, false); if (kv == NULL) { return pContext->ThrowNativeError("Invalid KeyValues handle %x (error: %d)", params[1], err); } DatabaseInfo info; info.database = kv->GetString("database", ""); info.driver = kv->GetString("driver", "default"); info.host = kv->GetString("host", ""); info.maxTimeout = kv->GetInt("timeout", 0); info.pass = kv->GetString("pass", ""); info.port = kv->GetInt("port", 0); info.user = kv->GetString("user", ""); IDBDriver *driver; if (info.driver[0] == '\0' || strcmp(info.driver, "default") == 0) { driver = g_DBMan.GetDefaultDriver(); } else { driver = g_DBMan.FindOrLoadDriver(info.driver); } if (driver == NULL) { char buffer[255]; UTIL_Format(buffer, sizeof(buffer), "Could not find driver \"%s\"", info.driver); pContext->StringToLocalUTF8(params[2], params[3], buffer, NULL); return BAD_HANDLE; } char *buffer; IDatabase *db; pContext->LocalToString(params[2], &buffer); db = driver->Connect(&info, params[4] ? true : false, buffer, params[3]); if (db == NULL) { return BAD_HANDLE; } Handle_t hndl = g_DBMan.CreateHandle(DBHandle_Database, db, pContext->GetIdentity()); if (!hndl) { db->Close(); return pContext->ThrowNativeError("Out of handles!"); } /* HACK! Add us to the dependency list */ CExtension *pExt = g_Extensions.GetExtensionFromIdent(driver->GetIdentity()); if (pExt) { g_Extensions.BindChildPlugin(pExt, g_PluginSys.GetPluginByCtx(pContext->GetContext())); } return hndl; }
IDatabase* DatabaseFactory::getDatabase(EDataTypes dataType, EDataActions dataAction) { FUNCTION_ENTRY("getDatabase"); // Set up a local variable to point to the database that is either created or found IDatabase* theDatabase = NULL; ThreadGuard guard( m_getDatabaseLock ); // get the connection string for this datatype/action std::string dbConnection; // forever loop will exit by exception or when a good db is found while(1) { // If this call fails it will throw something. try { DbConnection::getInstance().getConnectionString(dataType, dataAction, dbConnection); } catch(DbConnectionFailed&) { // we exit the forever loop with this throw TA_THROW(DatabaseException("Unable to find a working database")); } // Get the ID of this thread - we want one database connection per thread int threadId = Thread::getCurrentThreadId(); // Look to see if there is already a database connection for this thread //<ThreadID: Map<ConnectionString, SimpleDBDatabase>> ThreadMap::iterator threadIter ( m_databaseMap.find( threadId )); if ( threadIter == m_databaseMap.end() ) { // add new ConnectionMap. Set db* to null untill it's defined ConnectionMap cmap; cmap.insert( ConnectionMap::value_type( dbConnection, 0 ) ); threadIter = m_databaseMap.insert(ThreadMap::value_type(threadId, cmap) ).first; } ConnectionMap::iterator connIter ( threadIter->second.find( dbConnection ) ); if (connIter == threadIter->second.end()) { connIter = threadIter->second.insert(ConnectionMap::value_type( dbConnection, 0 )).first; } if (connIter->second != 0 ) { // Then the connection already exists. theDatabase = connIter->second; //TODO: need to set dataType and DataAction theDatabase->setDataTypeAction(dataType, dataAction); } else // Database doesn't exist for this thread, so need to create it. { LOG(SourceInfo, DebugUtil::GenericLog, DebugUtil::DebugInfo, "New SimpleDbDatabase object created for thread %lu", threadId); theDatabase = new TA_Base_Core::SimpleDbDatabase(dataType, dataAction); // add to map connIter->second = theDatabase; } // Now that we have a database object, we need to connect it - do this everytime // 'cause if the database is alerady connected, nothing will happen, but if it has // been inadvertandtly disconnected, then it will be reconnected try // The connect line can generate a DatabaseException { theDatabase->connect( dbConnection ); // we can also exit the forever loop this (preferred) way FUNCTION_EXIT; return theDatabase; } catch (DatabaseException&) { // A DatabaseException was generated. Need to delete the database object for now. delete theDatabase; threadIter->second.erase(connIter); TA_Base_Core::Thread::sleep(100); // do not rethrow, just sleep for a while // there may be another database we can talk to. } } // end forever loop }