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

📄 connection.cpp

📁 对Oracle数据库OCI的一个轻量级封装
💻 CPP
字号:
// OraLib 0.0.3 / 2002-06-30
//	connection.cpp
//
//	http://606u.dir.bg/
//	606u@dir.bg

#include "_p.h"

#include "oralib.h"


// set to 1 to track OCI's memory usage
#if (0)
	dvoid *malloc_func (dvoid * /* ctxp */, size_t size)
		{ return (malloc (size)); }
	dvoid *realloc_func (dvoid * /* ctxp */, dvoid *ptr, size_t size)
		{ return (realloc (ptr, size)); }
	void free_func (dvoid * /* ctxp */, dvoid *ptr)
		{ free (ptr); }
#else
#	define	malloc_func		NULL
#	define	realloc_func	NULL
#	define	free_func		NULL
#endif


namespace oralib {


connection::connection (void)
{
	initialize ();
}


connection::connection (
	IN const char *service_name,
	IN const char *login,
	IN const char *password,
	IN OPTIONAL unsigned long env_mode,	// = OCI_OBJECT
	IN OPTIONAL bool non_blocking_mode)	// = false
{
	initialize ();
	try
	{
		open (
			service_name,
			login,
			password,
			env_mode,
			non_blocking_mode);
	}
	catch (...)
	{
		close ();
		throw;
	}
}


connection::~connection ()
{
	cleanup (); // calls close
}


void
connection::initialize (void)
{
	environment_handle = NULL;
	server_handle = NULL;
	error_handle = NULL;
	session_handle = NULL;
	svc_context_handle = NULL;

	is_opened = false;
	is_available = false;
	is_blocking = false;
}


void
connection::open (
	IN const char *service_name,
	IN const char *login,
	IN const char *password,
	IN OPTIONAL unsigned long env_mode,	// = OCI_OBJECT
	IN OPTIONAL bool non_blocking_mode)	// = false
{
	// prerequisites
	ASSERT (service_name && login && password);
	ASSERT (!is_opened);

	sword	result;

	// allocate an environment handle
	result = OCIEnvCreate (
		&environment_handle,
		env_mode,
		NULL,		// context
		malloc_func,	// malloc
		realloc_func,	// realloc
		free_func,		// free
		0,			// extra memory to allocate
		NULL);		// pointer to user-memory

	// allocate a server handle
	if (result == OCI_SUCCESS)
		result = OCIHandleAlloc (
			environment_handle,
			(void **) &server_handle,
			OCI_HTYPE_SERVER,
			0,		// extra memory to allocate
			NULL);	// pointer to user-memory
	else
		throw (oralib::error (EC_ENV_CREATE_FAILED, __FILE__, __LINE__));

	// allocate an error handle
	if (result == OCI_SUCCESS)
		result = OCIHandleAlloc (
			environment_handle,
			(void **) &error_handle,
			OCI_HTYPE_ERROR,
			0,		// extra memory to allocate
			NULL);	// pointer to user-memory

	// create a server context
	if (result == OCI_SUCCESS)
		result = OCIServerAttach (
			server_handle,
			error_handle,
			(text *) service_name,
			strlen (service_name),
			OCI_DEFAULT);
	else
		throw (oralib::error (result, environment_handle, __FILE__, __LINE__));

	// allocate a service handle
	if (result == OCI_SUCCESS)
		result = OCIHandleAlloc (
			environment_handle,
			(void **) &svc_context_handle,
			OCI_HTYPE_SVCCTX,
			0,		// extra memory to allocate
			NULL);	// pointer to user-memory
	else
		throw (oralib::error (result, error_handle, __FILE__, __LINE__));

	// set the server attribute in the service context handle
	if (result == OCI_SUCCESS)
		result = OCIAttrSet (
			svc_context_handle,
			OCI_HTYPE_SVCCTX,
			server_handle,
			sizeof (OCIServer *),
			OCI_ATTR_SERVER,
			error_handle);
	else
		throw (oralib::error (result, environment_handle, __FILE__, __LINE__));

	// allocate a user session handle
	if (result == OCI_SUCCESS)
		result = OCIHandleAlloc (
			environment_handle,
			(void **) &session_handle,
			OCI_HTYPE_SESSION,
			0,		// extra memory to allocate
			NULL);	// pointer to user-memory
	else
		throw (oralib::error (result, error_handle, __FILE__, __LINE__));

	// set username and password attributes in user session handle
	if (result == OCI_SUCCESS)
		result = OCIAttrSet (
			session_handle,
			OCI_HTYPE_SESSION,
			(text *) login,
			strlen (login),
			OCI_ATTR_USERNAME,
			error_handle);
	else
		throw (oralib::error (result, environment_handle, __FILE__, __LINE__));

	if (result == OCI_SUCCESS)
		result = OCIAttrSet (
			session_handle,
			OCI_HTYPE_SESSION,
			(text *) password,
			strlen (password),
			OCI_ATTR_PASSWORD,
			error_handle);

	// start the session
	if (result == OCI_SUCCESS)
		result = OCISessionBegin (
			svc_context_handle,
			error_handle,
			session_handle,
			OCI_CRED_RDBMS,
			OCI_DEFAULT);

	// set the user session attribute in the service context handle
	if (result == OCI_SUCCESS)
		result = OCIAttrSet (
			svc_context_handle,
			OCI_HTYPE_SVCCTX,
			session_handle,
			sizeof (OCISession *),
			OCI_ATTR_SESSION,
			error_handle);

	// switch to non-blocking mode?
	if (result == OCI_SUCCESS &&
		non_blocking_mode)
	{
		ub1	attr_value;

		attr_value = 1;
		result = OCIAttrSet (
			server_handle,
			OCI_HTYPE_SERVER,
			&attr_value,
			sizeof (attr_value),
			OCI_ATTR_NONBLOCKING_MODE,
			error_handle);
	}

	if (result == OCI_SUCCESS)
	{
		is_opened = true;
		is_available = true;
		is_blocking = !non_blocking_mode;
	}
	else
		throw (oralib::error (result, error_handle, __FILE__, __LINE__));
}


void
connection::close (void)
{
	sword	result;

	// no prerequisites

	// just in case switch server to blocking mode
	if (server_handle != NULL)
	{
		ub1	attr_value;

		attr_value = 0;
		result = OCIAttrSet (
			server_handle,
			OCI_HTYPE_SERVER,
			&attr_value,
			sizeof (attr_value),
			OCI_ATTR_NONBLOCKING_MODE,
			error_handle);
	}
	else
		result = OCI_SUCCESS;

	// end session
	if (svc_context_handle != NULL &&
		error_handle != NULL)
	{
		if (session_handle != NULL)
			result = OCISessionEnd (
				svc_context_handle,
				error_handle,
				session_handle,
				OCI_DEFAULT);
		else
			result = OCI_SUCCESS;

		// detach from the oracle server
		if (result == OCI_SUCCESS)
			result = OCIServerDetach (
				server_handle,
				error_handle,
				OCI_DEFAULT);
	}
	else
		result = OCI_SUCCESS;

	// free handles
	if (result == OCI_SUCCESS &&
		svc_context_handle != NULL)
		result = OCIHandleFree (
			svc_context_handle,
			OCI_HTYPE_SVCCTX);

	if (result == OCI_SUCCESS &&
		session_handle != NULL)
	{
		svc_context_handle = NULL;
		result = OCIHandleFree (
			session_handle,
			OCI_HTYPE_SESSION);
	}
	
	if (result == OCI_SUCCESS &&
		error_handle != NULL)
	{
		session_handle = NULL;
		result = OCIHandleFree (
			error_handle,
			OCI_HTYPE_ERROR);
	}
	
	if (result == OCI_SUCCESS &&
		server_handle != NULL)
	{
		error_handle = NULL;
		result = OCIHandleFree (
			server_handle,
			OCI_HTYPE_SERVER);
	}

	
	if (result == OCI_SUCCESS &&
		environment_handle != NULL)
	{
		server_handle = NULL;
		result = OCIHandleFree (
			environment_handle,
			OCI_HTYPE_ENV);
		if (result == OCI_SUCCESS)
			environment_handle = NULL;
	}

	if (result == OCI_SUCCESS)
	{
		is_opened = false;
		is_available = false;
		is_blocking = false;
	}
}


void
connection::execute (
	IN const char *sql_block,
	IN OPTIONAL int sql_len)	// = -1
{
	// prerequisites
	ASSERT (sql_block);

	statement st (*this, sql_block, sql_len);
	st.execute_prepared ();
}


statement*
connection::prepare (
	IN const char *sql_block,
	IN OPTIONAL int sql_len)	// = -1
{
	// prerequisites
	ASSERT (sql_block);

	return (new statement (
		*this,
		sql_block,
		sql_len));
}


resultset*
connection::select (
	IN const char *select,
	IN OPTIONAL int select_len)	// = -1
{
	// prerequisites
	ASSERT (select);

	statement	*s = prepare (select, select_len);
	try
	{
		oralib::resultset	*r = s->select ();
		r->attach_statement (s);
		return (r);
	}
	catch (...)
	{
		s->release ();
		throw;
	}
}


};	// oralib namespace

⌨️ 快捷键说明

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