⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbcommand.cpp_1

📁 Vc.Net入门与提高源码
💻 CPP_1
📖 第 1 页 / 共 2 页
字号:
	{	
		POSITION begin = inputParams.GetHeadPosition();
		int size = inputParams.GetCount();

		ASSERT(begin != NULL);
		
		for (int i = 0; i < size; i++)
		{
			CStringA paramValue = inputParams.GetNext(begin);
			ULONG   ulCount = 0;
		
			for (int l = ulCount; l < numParams; l++)
			{
				if (cmdInfo->paramTypes[l] == DBPARAMTYPE_INPUT || cmdInfo->paramTypes[l] == DBPARAMTYPE_INPUTOUTPUT)
				{		
					ASSERT(!paramValue.IsEmpty());

					if (!paramValue.IsEmpty())
					{						
						_tcsncpy(m_arrParams[l].szValue, paramValue, paramValue.GetLength());						
					}
					else
					{						
						_tcsncpy(m_arrParams[l].szValue, "", strlen(""));
					}	
					ulCount = l + 1;				
				}	
			}	
		}
	}

	// execute our command and get back a rowset		
	hr = command.Open(NULL, NULL, false);	
	
	if (SUCCEEDED(hr))
	{
		hr = GetResults(command, numParams);
	}
	return hr;
}

HRESULT DBCommand::Execute(CStringA&				cmdName, 
						   CStringA&				connectionString,
						   StringList&				inputParams,
						   IDataSourceCache			*spDataSrcCache,
						   IMemoryCache				*spBinaryCache)
{
	// clear out any old results
	Clean();

	bool dsFromCache = false;
	HRESULT hr = S_OK;
		
	// get a dataconnection
	CDataConnection datasource;	
	hr = GetDataConnection(connectionString, spDataSrcCache, datasource, dsFromCache);
	
	ASSERT(!FAILED(hr));

	if (FAILED(hr))
	{
		// nothing we can do, we can't get a data connection, get out of here
		return hr;
	}

	// if we got here, then we got a data connection somehow, either using the cache,
	// or opening one on our own

	// get information about this stored procedure's parameters						
	CmdInfo *cmdInfo = NULL;
	bool infoFromCache = false;
	
	hr = GetCmdInfo(cmdName, 
					connectionString, 
					spBinaryCache, 
					datasource, 
					&cmdInfo, 
					infoFromCache);

	ASSERT(!FAILED(hr));
	if (FAILED(hr))
	{
		// if we failed, there is a chance that it is because our data connection was 
		// stale, try opening another one
		hr = RecoverDataConnection(connectionString, spDataSrcCache, datasource, dsFromCache);
		
		if (SUCCEEDED(hr))
		{			
			// re-opening the connection worked, try again to get our cmd information
			hr = GetCmdInfo(cmdName, 
							connectionString, 
							spBinaryCache, 
							datasource, 
							&cmdInfo, 
							infoFromCache);
		}
	}
	
	// check to see if we could get our command info
	ASSERT(!FAILED(hr));
	if (FAILED(hr))
	{
		// nothing w can do, just get out
		return hr;
	}

	// if we got here, the we were able to get information about our stored procedure
	// so now execute that stored proc
	hr = ExecuteCommand(datasource,									
						cmdInfo,
						inputParams);				
	ASSERT(!FAILED(hr));

	// not a whole lot of error checking we can do on the returned hr, if the execute
	// command failed, we are going to return the bad hr

	// close the data connection if we didn't get one from the cache
	if (!dsFromCache)
		datasource.Close();

	// delete our command info structure if we didn't get it from the cache
	if (!infoFromCache)
	{
		cmdInfo->paramTypes.RemoveAll();
		delete cmdInfo;
	}

	return hr;
}

HRESULT DBCommand::RecoverDataConnection(	CStringA&			connectionString,
											IDataSourceCache	*spDataSrcCache, 
											CDataConnection&	datasource, 
											bool&				fromCache)
{
	HRESULT hr = S_OK;

	if (spDataSrcCache == NULL)
	{
		// if we weren't give a cache, just open the data connection and return the results
		// also set the from cache flag to false
		fromCache = false;
		hr = datasource.Open(connectionString);
	}
	else
	{
		// if we were given a cache add a new data connection to it and return the results
		// also set the from cache flag to true
		fromCache = true;
		hr = spDataSrcCache->Add(connectionString,connectionString, &datasource);		
	}
	
	return hr;
}

HRESULT DBCommand::GetDataConnection(CStringA&			connectionString, 
									 IDataSourceCache	*spDataSrcCache, 
									 CDataConnection&	datasource,
									 bool& fromCache)
{
	HRESULT hr = S_OK;

	if (spDataSrcCache != NULL)
	{
		// if we are given a cache, try to find the datasource in the cache
		// using the connection string as the id
		if (FAILED(spDataSrcCache->Lookup(connectionString, &datasource)))
		{
			// something went wrong in looking for the dataconnection in our 
			// cache, try to open a new one
			hr = spDataSrcCache->Add(connectionString, connectionString, &datasource);

			ASSERT(!FAILED(hr));
			if (FAILED(hr))
			{
				// if we failed here, that means that we could not add a new connection, there
				// is nothing we can do at this point, just return the failing hr
				return hr;
			}
		}

		// indicate that we got a data connection from the cache
		fromCache = true;
	}
	else
	{
		// if we weren't given a cache to use, just open the data connection normally
		hr = datasource.Open(connectionString);

		ASSERT(!FAILED(hr));
		if (FAILED(hr))
		{
			// nothing we can do if we fail here, just return the failing hr
			return hr;
		}
	}

	return hr;
}

HRESULT DBCommand::BuildCmdStringAndParams(CProcedureParameters&	procInfo,
										   CString&					cmdName,
										   CmdInfo*					cmdInfo)
{
	HRESULT hr = S_OK;

	// go through each parameter and build our call string	
	bool first = true;
	
	CStringA strTemp("? = ");
	CStringA strCmd;
	strCmd.Format("Call %s ", cmdName);

	while (procInfo.MoveNext() == S_OK)
	{			
		// store the type of the parameter
		cmdInfo->paramTypes.Add((WORD)procInfo.m_nType);		
		
		// build the parameter list part of our cmd call string
		switch (procInfo.m_nType)
		{
			case DBPARAMTYPE_RETURNVALUE:
				strTemp += strCmd;
				strCmd = strTemp;				
				break;

			case DBPARAMTYPE_INPUT:
			case DBPARAMTYPE_INPUTOUTPUT:		
			case DBPARAMTYPE_OUTPUT:
				if (first)
				{
					strCmd += "(?";
					first = false;
				}
				else
					strCmd += ", ?";
				break;
			default:
				break;
		}
	}
	if (!first)
		strCmd += ")";

	cmdInfo->cmdCallString.Format("{ %s }", strCmd);
	
	return hr;
}

HRESULT DBCommand::CreateAndStoreCmdInfo(CProcedureParameters&	procInfo,
										 const CSession&		session,
										 IMemoryCache			*spBinaryCache,
										 CString&				cmdName,
										 CString&				connectionString,
										 CmdInfo**				cmdInfo,
										 bool&					infoFromCache)
{
	ASSERT(cmdInfo != NULL);
	if (cmdInfo == NULL)
	{
		return E_FAIL;
	}

	HRESULT hr = S_OK;

	*cmdInfo = new CmdInfo();
	infoFromCache = false;

	ASSERT(*cmdInfo != NULL);
	if (*cmdInfo == NULL)
	{
		// we don't have enough memory!
		return E_OUTOFMEMORY;
	}

	// connect to get information about our stored procedure
	hr = procInfo.Open(session, NULL, NULL, cmdName);

	ASSERT(!FAILED(hr));
	if (FAILED(hr))
	{
		// if we can't get cmd information, nothing to do but return
		return hr;
	}

	// get our cmd info
	hr = BuildCmdStringAndParams(procInfo, cmdName, *cmdInfo);
	
	ASSERT(!FAILED(hr));
	if (FAILED(hr))
	{
		// nothing we can do, we just can't get cmd info
		return hr;
	}
	
	if (spBinaryCache != NULL)
	{
		// try to add this info into the cache
		if (SUCCEEDED(spBinaryCache->Add((LPCSTR)(cmdName + connectionString),
										 (void*)*cmdInfo,
										 sizeof(CmdInfo),
										 NULL,
										 NULL,
										 NULL,
										 NULL)))
		{
			// set this flag so nobody will delete cmdInfo
			infoFromCache = true;
		}		
	}
	else
	{
		// we don't have a cache to use
		infoFromCache = false;
	}

	procInfo.Close();
	procInfo.ClearRecordMemory();
	procInfo.FreeRecordMemory();

	return hr;
}

	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -