Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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");
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
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;
		}
	}
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
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;
	}
}
Exemplo n.º 9
0
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"));
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
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();
	}
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
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"));
}
Exemplo n.º 15
0
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);
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
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;
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
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);
}
Exemplo n.º 20
0
void attachSystemTablesAsync(IDatabase & system_database, AsynchronousMetrics & async_metrics)
{
    system_database.attachTable("asynchronous_metrics", StorageSystemAsynchronousMetrics::create("asynchronous_metrics", async_metrics));
}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
0
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;
}
Exemplo n.º 23
0
void FreeDatabase(void *p, unsigned int num)
{
	IDatabase *db = (IDatabase *)p;

	db->FreeHandle();
}
Exemplo n.º 24
0
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;
}
Exemplo n.º 25
0
    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
	}