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

📄 lob.cpp

📁 oracle引用库
💻 CPP
字号:
#define __OCICPP_INTERNAL_USE_#include "Lob.h"#include "BFile.h"
#include "OraError.h"

#if ( OCILIBVERMAJOR>=8 && OCILIBVERMINOR>=1 )
#include "TLob.h"
#endif

/*! \class OCICPP::Lob  \brief Encapsulation of Oracle's Large Objects (LOBs)  A brief example for interaction with a lob. Lets assume, there is a table  IMAGES created already (e.g. by issuing the command "create table IMAGES (  KEY integer, IMAGE blob )". Of course, a storage class should be included,  so that the large object(s) can be stored appropriately. After that, you  may write (with an initialized pointer \a con to a Connection-object):  \code  using namespace OCICPP;  con->execUpdate( "insert into IMAGES (KEY,IMAGE) values ( 42, EMPTY_BLOB())" );  Cursor cur;  con->execQuery( "select * from IMAGES where KEY=42 for update", cur );  Lob lob;  cur.fetch();  cur.getBLOB( "IMAGE", lob );  lob.write( "something", 9 );  cur.drop();  \endcode  In detail, a new row is inserted into the IMAGES table (identified by \c 42  ). The table, as mentioned above, stores an integer column as well as a  \b binary \b large \b object (BLOB) column.  For those of you familiar with Oracle Servers, it may not be an insight that  the column IMAGE is initialized with an empty BLOB (by specifying   EMPTY_BLOB()/EMPTY_CLOB() as the content of this column). It would be a  mistake to leave this content out of the insert statement, since the a  NULL-value would be inserted and a NULL-LOB may not be used for reading from  or writing to.  Afterwards, the newly inserted column is being selected \b for \b update,   which is mandatory, if a value from this column is to be modified while the  cursor points to it. The Lob-instance \a lob is being initilized from the  Cursor's current column IMAGE and afterwards 'something' is written into  this BLOB. Alternatively, a real image or some other binary data may be  stored there.*//*!  Create an unbound large object. This object may be used to be initialized  from a Cursor's BLOB / CLOB column, e.g.. */OCICPP::Lob::Lob() : type(BLOB),cache(CACHE_OFF) {	init(0,0,0,type,cache);}OCICPP::Lob::Lob(OCISvcCtx *svcctx,OCILobLocator *lob_desc,OCIError *err,OCICPP::LobType lob_type,OCICPP::CacheMode cache_mode) :type(lob_type), cache(cache_mode){	init(svcctx,lob_desc,err,lob_type,cache_mode);}void OCICPP::Lob::init(OCISvcCtx *svcctx,OCILobLocator *lob_desc,OCIError *err,OCICPP::LobType lob_type,OCICPP::CacheMode cache_mode) {	svchp=svcctx;	lob=lob_desc;	errhp=err;	type=lob_type;	cache=cache_mode;	offset=1;	wasBound=false;	if(svchp && errhp) {		DEBUG(DLEV_DEBUG,"Obtaining LOB len\n");		CHECKERR(errhp,OCILobGetLength(svchp,errhp,lob,(ub4 *)&len));		DEBUG(DLEV_DEBUG,"Lob len is %d\n",len);	} else {		len=0;	}}// This init used for binding Lob's only BLOB could be boundvoid OCICPP::Lob::init(OCIEnv *env,OCISvcCtx *svcctx,OCIError *err) {	svchp=svcctx;	errhp=err;	type=BLOB;	cache=CACHE_OFF;	offset=1;	len=0;	wasBound=true;	DEBUG(DLEV_DEBUG,"called init for binding\n");	if(OCIDescriptorAlloc(env,(void **)&lob,OCI_DTYPE_LOB,0,0)!=OCI_SUCCESS) {		throw OraError("OCICPPLIB: Cannot make new LOB: Handle Allocation failed",OCICPPERROR);	}}	/*!  Destruct a reference to a large object. */OCICPP::Lob::~Lob() {	/* nothing to be done yet 	   all real work is in ~Cursor	   See TODO about how it should work ..	*/	drop();}/*!  Free a previously initalized large object. A lob freed in this manner may be  reused afterwards.  \todo not implemented */void OCICPP::Lob::drop() {	if(wasBound) {		OCIDescriptorFree(lob,OCI_DTYPE_LOB);	}}/*!  Set the position for reading/writing within a large object.  \param dir may be \b OCICPP::LOB_SET, \b OCICPP::LOB_CUR or \b OCICPP::LOB_END .   \arg LOB_SET \a new_offset from begining of the lob. \a new_offset may not be           greater than Lob's length ( getLen() ).  \arg LOB_CUR modifies the access point within the lob relative to the current           position. \a current position \a + \a new_offset may not exceed the           lob's length  \arg LOB_END sets the position from the end of the lob.  \param new_offset is the new distance relative to the given direction \a dir*/void OCICPP::Lob::seek(unsigned new_offset,OCICPP::LobDirection dir) {	if((!len && new_offset>0) ||	   ((dir==OCICPP::LOB_END ||dir==OCICPP::LOB_SET) && new_offset>len) ||	   (dir==OCICPP::LOB_CUR && (new_offset+offset-1)>len)) {		throw OraError("OCICPPLIB: Cannot seek: offset out of range",OCICPPERROR);	}	if(dir==LOB_SET) offset=new_offset+1;	else if(dir==LOB_END) offset=len-new_offset+1;	else if(dir==LOB_CUR) offset=offset+new_offset;	else throw OraError("OCICPPLIB: Cannot seek: Unknown direction",OCICPPERROR);}/*!  Retuns the current position from the start of the lob. For this position, the  inequation 0 <= tell() < getLen() holds. */unsigned OCICPP::Lob::tell() {	return offset-1;}/*!  Read a sequence of \a buf_len bytes from the lob into the buffer \a buf. The  amount of bytes actually transfered is being returned. */unsigned OCICPP::Lob::read(void * buf,int buf_len) {	unsigned off;	unsigned actread=buf_len;	off=offset;	CHECKERR(errhp,OCILobRead(svchp,errhp,lob,(ub4 *)&actread,(ub4)off,buf,(ub4)buf_len,0,			   (sb4 (*)(dvoid *, CONST dvoid *, ub4, ub1)) 0,(ub2) 0, (ub1) SQLCS_IMPLICIT));	offset+=actread;	return actread;}/*!  Write a sequence of \a buf_len bytes into the lob from the buffer \a buf. The  amount of bytes actually transfered is being returned. */unsigned OCICPP::Lob::write(const void *buf,int buf_len) {	unsigned off;	unsigned actread=buf_len;	off=offset;	if(!buf_len) return 0;	DEBUG(DLEV_DEBUG,"Writing to lob |%s|\n",buf);	CHECKERR(errhp,OCILobWrite(svchp,errhp,lob,(ub4 *)&actread,(ub4)off,const_cast<void *>(buf),(ub4)buf_len,OCI_ONE_PIECE,(dvoid *)0,				(sb4 (*)(dvoid *, dvoid *, ub4 *, ub1 *)) 0,(ub2) 0, (ub1) SQLCS_IMPLICIT));	DEBUG(DLEV_DEBUG,"Wrote data done\n");	if((offset+buf_len)>len) {		len=offset+buf_len-1;	}	offset+=actread;	return actread;}/*!  Truncates the lob to a specified to a length of \a new_len bytes.  The function throws an exception if \a new_len is greater than the current  LOB's length. */void OCICPP::Lob::trunc(unsigned new_len) {	if(new_len>len) throw OraError("OCICPPLIB: Cannot truncate LOB: new len greater than len",OCICPPERROR);	CHECKERR(errhp,OCILobTrim(svchp,errhp,lob,(ub4)new_len));	len=new_len;}/*!  \todo not implemented */void OCICPP::Lob::setCacheMode(OCICPP::CacheMode mode) {/* Not implemented Yet */}/*! Load/copy all or a portion of the file into an internal LOB. No character set conversions are performed when copying the FILE data to a CLOB/NCLOB. If the destination's start position is beyond the end of the current data, zero-byte fillers (for BLOBs) or spaces (for CLOBs) are written into the  destination LOB from the end of the data to the beginning of the newly  written data from the source. The destination LOB is extended to  accommodate the newly written data if it extends beyond the current  length of the destination LOB. It is an error to extend the destination LOB beyond the maximum  length allowed (4 gigabytes)  The amount parameter indicates the maximum amount to load. If the end of the source FILE is reached before the specified amount is loaded,the operation terminates without error.*/ void OCICPP::Lob::loadFromBFile(BFile &bfile,unsigned amount,								unsigned int dst_offset,								unsigned int src_offset) {	CHECKERR(errhp,OCILobLoadFromFile(svchp,errhp,lob,bfile.lob,										amount,dst_offset+1,src_offset+1));}void OCICPP::Lob::loadFromFile(FILE *f) {	fseek(f,0,SEEK_SET);	while(!feof(f)) {		char tmp[512];		int b_read;		memset(tmp,0,512);		b_read=fread(tmp,1,511,f);		write(tmp,b_read);	}}void OCICPP::Lob::saveToFile(FILE *f) {	fseek(f,0,SEEK_SET);	unsigned b_read;	char tmp[512];	memset(tmp,0,512);	b_read=read(tmp,511);	while(b_read) {		fwrite(tmp,1,b_read,f);		b_read=read(tmp,511);	}	}std::string OCICPP::Lob::toString() {	string res;	char buf[512];	unsigned actread;	while(actread=read(buf,255)) {		buf[actread]='\0';		res+=buf;	}	return res;}/*!  Retreive the total amount of data stored within this lob. */unsigned OCICPP::Lob::getLen() const {	return len;}/*! Copies data from Lob \a src_lob Both locators must be of the same type (they are both must be BLOB or CLOB) Lob cache must not be enabled for either locator. The \a amount parameter indicates the maximum amount to copy.  If the end of the source LOB is reached before the specified amount is copied, the operation terminates without error.  \sa setCacheMode(), getLen(), loadFromBFile()*/void OCICPP::Lob::copyFrom(Lob &src_lob,unsigned amount,							unsigned dst_off,unsigned src_off) {	CHECKERR(errhp,OCILobCopy(svchp,errhp,lob,							src_lob.lob,amount,dst_off+1,src_off+1));}/*!  Copies data from a BFile \a src_file  \sa copyFrom(Lob &,unsigned,unsigned,unsigned)*/void OCICPP::Lob::copyFrom(BFile &src_file,unsigned amount,							unsigned dst_off,unsigned src_off) {	CHECKERR(errhp,OCILobLoadFromFile(svchp,errhp,lob,src_file.lob,										amount,dst_off,src_off));	}#if ( OCILIBVERMAJOR>=8 && OCILIBVERMINOR>=1 ) || DOXYGEN/*!  Copies data from a temporary Lob \a src_lob  \sa copyFrom(Lob &,unsigned,unsigned,unsigned)  \ora8i_fn */void OCICPP::Lob::copyFrom(TLob &src_lob,unsigned amount,							unsigned dst_off,unsigned src_off) {	CHECKERR(errhp,OCILobCopy(svchp,errhp,lob,src_lob.lob,amount,dst_off+1,src_off+1));}#endif

⌨️ 快捷键说明

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