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

📄 oraclient.cpp

📁 通用的数据库中间库
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	Iora7Cursor(
		Iora7Connection *pIora7Connection,
		SACommand *pCommand);
	virtual ~Iora7Cursor();

	virtual bool IsOpened();
	virtual void Open();
	virtual void Close();

	virtual void Prepare(
		const SAString &sStmt,
		SACommandType_t eCmdType,
		int nPlaceHolderCount,
		saPlaceHolder **ppPlaceHolders);
	// binds parameters
	void Bind(
		int nPlaceHolderCount,
		saPlaceHolder **ppPlaceHolders);
	// executes statement
	virtual void Execute(
		int nPlaceHolderCount,
		saPlaceHolder **ppPlaceHolders);
	// cleans up after execute if needed, so the statement can be reexecuted
	virtual void UnExecute();
	virtual void Cancel();

	virtual bool ResultSetExists();
	virtual void DescribeFields(
		DescribeFields_cb_t fn);
	virtual void SetSelectBuffers();
	virtual bool FetchNext();

	virtual long GetRowsAffected();

	virtual void ReadLongOrLOB(
		ValueType_t eValueType,
		SAValueRead &vr,
		void *pValue,
		unsigned int nFieldBufSize,
		saLongOrLobReader_t fnReader,
		unsigned int nReaderWantedPieceSize,
		void *pAddlData);

	virtual void DescribeParamSP();

	virtual saCommandHandles *NativeHandles();
};

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Iora7Cursor::Iora7Cursor(
	Iora7Connection *pIora7Connection,
	SACommand *pCommand) :
	IoraCursor(pIora7Connection, pCommand)
{
	m_bOpened = false;
	m_bResultSetExist = false;

	m_bPiecewiseBindAllowed = true;
	m_bPiecewiseFetchAllowed = true;
}

/*virtual */
Iora7Cursor::~Iora7Cursor()
{
}

/*virtual */
unsigned int Iora7Cursor::InputBufferSize(
	const SAParam &Param) const
{
	switch(Param.DataType())
	{
		case SA_dtBLob:
		case SA_dtCLob:
			return sizeof(LongContext_t);
		case SA_dtCursor:
			return sizeof(Cda_Def);
		default:
			break;			
	}

	return IoraCursor::InputBufferSize(Param);
}

/*virtual */
unsigned int Iora7Cursor::OutputBufferSize(
	SADataType_t eDataType,
	unsigned int nDataSize) const
{
	switch(eDataType)
	{
	case SA_dtCursor:
		return sizeof(Cda_Def);
	default:
		break;
	}

	return IoraCursor::OutputBufferSize(eDataType, nDataSize);
}

/*virtual */
bool Iora7Cursor::IsOpened()
{
	return m_bOpened;
}

/*virtual */
void Iora7Cursor::Open()
{
	assert(m_bOpened == false);
	((Iora7Connection*)m_pISAConnection)->Check(g_ora7API.oopen(
		&m_handles.m_cda,
		&((Iora7Connection*)m_pISAConnection)->m_handles.m_lda,
		NULL, -1, -1,
		NULL, -1), &m_handles.m_cda);
	m_bOpened = true;
}

/*virtual */
void Iora7Cursor::Close()
{
	assert(m_bOpened != 0);
	((Iora7Connection*)m_pISAConnection)->Check(g_ora7API.oclose(
		&m_handles.m_cda), &m_handles.m_cda);
	m_bOpened = false;
}

//////////////////////////////////////////////////////////////////////
// Iora8Cursor Class
//////////////////////////////////////////////////////////////////////

// helper structures
typedef struct tagBlobReturningContext
{
	SAParam *pParam;
	OCIError *pOCIError;
	OCIEnv *pOCIEnv;
	OCILobLocator ***pppOCILobLocators;
	ub4 **ppLobLocatorsLens;
	int nLobLocatorCol;
	ub4 *pnLobReturnBindsColCount;
	ub4 *pnBLobBindsRowCount;
} BlobReturningContext_t;

class Iora8Cursor : public IoraCursor
{
	ora8CommandHandles	m_handles;

	ub2	m_nOraStmtType;
	bool m_bResultSetCanBe;

	ub2	*m_pDTY;	// array of bound parameters types

	void DiscardPiecewiseFetch();
	void ReadLong(
		LongContext_t *pLongContext,
		saLongOrLobReader_t fnReader,
		unsigned int nReaderWantedPieceSize,
		void *pAddlData);
	void CheckPiecewiseNull();
	SAField *WhichFieldIsPiecewise() const;
	void ReadLob(
		ValueType_t eValueType,
		SAValueRead &vr,
		OCILobLocator* pOCILobLocator,
		saLongOrLobReader_t fnReader,
		unsigned int nReaderWantedPieceSize,
		void *pAddlData);
	void CreateTemporaryLob(
		OCILobLocator **ppLob,
		SAParam &Param);
	// returns total size written
	ub4 BindLob(
		OCILobLocator *pLob,
		SAParam &Param);

	static sb4 LongInBind(
		dvoid *ictxp,
		OCIBind *bindp,
		ub4 iter,
		ub4 index,
		dvoid **bufpp,
		ub4 *alenp,
		ub1 *piecep,
		dvoid **indpp);
	static sb4 LongOutBind(
		dvoid *ictxp,
		OCIBind *bindp,
		ub4 iter,
		ub4 index,
		dvoid **bufpp,
		ub4 **alenp,
		ub1 *piecep,
		dvoid **indpp,
		ub2 **rcodep);
	static sb4 LongDefine(
		dvoid *octxp,
		OCIDefine *defnp,
		ub4 iter,
		dvoid **bufpp, ub4 **alenp, ub1 *piecep,
		dvoid **indp, ub2 **rcodep);

	static sb4 LongDefineOrOutBind(
		dvoid *octxp,
		dvoid **bufpp,
		ub4 **alenpp,
		ub1 *piecep,
		dvoid **indpp);

	// binding LOBs with not NULL values (add returning into clause)
	SAString m_sOriginalStmt;
	ub4 m_nLobReturnBindsColCount;
	ub4 m_nBLobBindsRowCount;
	saPlaceHolder **m_ppLobReturnPlaceHolders;	// m_ppLobReturnPlaceHolders[m_nLobReturnBindsColCount]
	OCILobLocator ***m_pppBLobReturningLocs;	// m_pppBLobReturningLocs[m_nLobReturnBindsColCount][m_nBLobBindsRowCount]
	ub4 **m_ppLobReturningLens;	// m_ppLobReturningLens[m_nLobReturnBindsColCount][m_nBLobBindsRowCount]
	void DestroyLobsReturnBinding();
	void CheckForReparseBeforeBinding(
		int nPlaceHolderCount,
		saPlaceHolder**	ppPlaceHolders);
	void InternalPrepare(
		const SAString &sStmt);
	static sb2 stat_m_BLobReturningNullInd;
	static sb4 LobReturningInBind(
		dvoid *ictxp,
		OCIBind *bindp,
		ub4 iter,
		ub4 index,
		dvoid **bufpp,
		ub4 *alenp,
		ub1 *piecep,
		dvoid **indpp);
	static sb4 LobReturningOutBind(
		dvoid *octxp,
		OCIBind *bindp,
		ub4 iter,
		ub4 index,
		dvoid **bufpp,
		ub4 **alenp,
		ub1 *piecep,
		dvoid **indp,
		ub2 **rcodep);
	void BindReturningLobs();

	// binding using temporary Lobs
	OCILobLocator **m_ppTempLobs;
	int m_cTempLobs;
	void FreeTemporaryLobsIfAny();

protected:
	virtual unsigned int InputBufferSize(
		const SAParam &Param) const;
	virtual unsigned int OutputBufferSize(
		SADataType_t eDataType,
		unsigned int nDataSize) const;
	virtual void SetFieldBuffer(
		int nCol,	// 1-based
		void *pInd,
		unsigned int nIndSize,
		void *pSize,
		unsigned int nSizeSize,
		void *pValue,
		unsigned int nValueSize);
	virtual void ConvertLongOrLOB(
		ValueType_t eValueType,
		SAValueRead &vr,
		void *pValue,
		unsigned int nFieldBufSize);

	virtual SADataType_t CnvtNativeToStd(
		int nNativeType,
		int nNativeSubType,
		int nSize,
		int nPrec,
		int nScale) const;
	virtual int CnvtStdToNative(SADataType_t eDataType) const;

public:
	Iora8Cursor(
		Iora8Connection *pIora8Connection,
		SACommand *pCommand);
	virtual ~Iora8Cursor();

	virtual bool IsOpened();
	virtual void Open();
	virtual void Close();

	virtual void Prepare(
		const SAString &sStmt,
		SACommandType_t eCmdType,
		int nPlaceHolderCount,
		saPlaceHolder **ppPlaceHolders);
	// binds parameters
	void Bind(
		int nPlaceHolderCount,
		saPlaceHolder **ppPlaceHolders);
	// executes statement
	virtual void Execute(
		int nPlaceHolderCount,
		saPlaceHolder **ppPlaceHolders);
	// cleans up after execute if needed, so the statement can be reexecuted
	virtual void UnExecute();
	virtual void Cancel();

	virtual bool ResultSetExists();
	virtual void DescribeFields(
		DescribeFields_cb_t fn);
	virtual void SetSelectBuffers();
	virtual bool FetchNext();

	virtual long GetRowsAffected();

	virtual void ReadLongOrLOB(
		ValueType_t eValueType,
		SAValueRead &vr,
		void *pValue,
		unsigned int nFieldBufSize,
		saLongOrLobReader_t fnReader,
		unsigned int nReaderWantedPieceSize,
		void *pAddlData);

	virtual void DescribeParamSP();

	virtual saCommandHandles *NativeHandles();
};

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

/*static */
sb2 Iora8Cursor::stat_m_BLobReturningNullInd = OCI_IND_NULL;

Iora8Cursor::Iora8Cursor(
	Iora8Connection *pIora8Connection,
	SACommand *pCommand) :
	IoraCursor(pIora8Connection, pCommand)
{
	m_nOraStmtType	= 0;	// unknown
	m_bResultSetCanBe = false;

	m_pDTY = NULL;

	m_nLobReturnBindsColCount = 0;
	m_nBLobBindsRowCount = 0;
	m_ppLobReturnPlaceHolders = NULL;
	m_pppBLobReturningLocs = NULL;
	m_ppLobReturningLens = NULL;

	m_ppTempLobs = NULL;
	m_cTempLobs = 0;
}

/*virtual */
Iora8Cursor::~Iora8Cursor()
{
	try
	{
		if(m_pDTY)
			::free(m_pDTY);
		DestroyLobsReturnBinding();
	}
	catch(SAException &)
	{
	}
}

/*virtual */
unsigned int Iora8Cursor::InputBufferSize(
	const SAParam &Param) const
{
	if(Param.DataType() == SA_dtCursor)
		return sizeof(OCIStmt *);
	
	if(!Param.isNull())
	{
		switch(Param.DataType())
		{
		case SA_dtBLob:
		case SA_dtCLob:
			return ((Iora8Connection*)m_pISAConnection)->IsTemporaryLobSupported()?
				sizeof(OCILobLocator *) :	// if binding using temporary Lob
			sizeof(BlobReturningContext_t);	// if binding 'returning into' clause
		default:
			break;
		}
	}
	
	return IoraCursor::InputBufferSize(Param);
}

/*virtual */
unsigned int Iora8Cursor::OutputBufferSize(
	SADataType_t eDataType,
	unsigned int nDataSize) const
{
	switch(eDataType)
	{
	case SA_dtBLob:
	case SA_dtCLob:
		return sizeof(OCILobLocator *);
	case SA_dtCursor:
		return sizeof(OCIStmt *);
	default:
		break;
	}

	return IoraCursor::OutputBufferSize(eDataType, nDataSize);
}

/*virtual */
bool Iora8Cursor::IsOpened()
{
	return m_handles.m_pOCIStmt != NULL;
}

/*virtual */
void Iora8Cursor::Open()
{
	assert(m_handles.m_pOCIStmt == NULL);
	assert(m_handles.m_pOCIError == NULL);

	Iora8Connection::Check(
		g_ora8API.OCIHandleAlloc(((Iora8Connection*)m_pISAConnection)->m_handles.m_pOCIEnv, (dvoid**)&m_handles.m_pOCIError, OCI_HTYPE_ERROR, 0, (dvoid**)0),
		((Iora8Connection*)m_pISAConnection)->m_handles.m_pOCIEnv, OCI_HTYPE_ENV);
	Iora8Connection::Check(
		g_ora8API.OCIHandleAlloc(((Iora8Connection*)m_pISAConnection)->m_handles.m_pOCIEnv, (dvoid**)&m_handles.m_pOCIStmt, OCI_HTYPE_STMT, 0, NULL),
		((Iora8Connection*)m_pISAConnection)->m_handles.m_pOCIEnv, OCI_HTYPE_ENV);

	assert(m_handles.m_pOCIStmt != NULL);
	assert(m_handles.m_pOCIError != NULL);
}

/*virtual */
void Iora8Cursor::Close()
{
	assert(m_handles.m_pOCIStmt != NULL);
	assert(m_handles.m_pOCIError != NULL);

	Iora8Connection::Check(
		g_ora8API.OCIHandleFree(m_handles.m_pOCIStmt, OCI_HTYPE_STMT), m_handles.m_pOCIStmt, OCI_HTYPE_STMT);
	Iora8Connection::Check(
		g_ora8API.OCIHandleFree(m_handles.m_pOCIError, OCI_HTYPE_ERROR), m_handles.m_pOCIError, OCI_HTYPE_ERROR);
	m_handles.m_pOCIStmt = NULL;
	m_handles.m_pOCIError = NULL;
}

/*virtual */
ISACursor *Iora7Connection::NewCursor(SACommand *m_pCommand)
{
	return new Iora7Cursor(this, m_pCommand);
}

/*virtual */
ISACursor *Iora8Connection::NewCursor(SACommand *m_pCommand)
{
	return new Iora8Cursor(this, m_pCommand);
}

/*virtual */
void Iora7Cursor::Prepare(
	const SAString &sStmt,
	SACommandType_t eCmdType,
	int/* nPlaceHolderCount*/,
	saPlaceHolder**	/*ppPlaceHolders*/)
{
	SAString sStmtOra;
	switch(eCmdType)
	{
		case SA_CmdSQLStmt:
			sStmtOra = sStmt;
			break;
		case SA_CmdStoredProc:
			sStmtOra = CallSubProgramSQL();
			break;
		default:
			assert(false);
	}

	// save because (extraction from Oracle docs):
	// "The pointer to the text of the statement must be available
	// as long as the statement is
	// executed, or data is fetched from it."
	m_sInternalPrepareStmt = sStmtOra;

	((Iora7Connection*)m_pISAConnection)->Check(g_ora7API.oparse(
		&m_handles.m_cda,
		(text*)(const char*)m_sInternalPrepareStmt, -1, 0, 1), &m_handles.m_cda);
}

void Iora7Cursor::BindLongs()
{
	assert(m_bPiecewiseBindAllowed);
	assert(m_handles.m_cda.rc == 3129);	// the next Piece to be inserted is required

⌨️ 快捷键说明

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