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

📄 bfile.cpp

📁 oracle引用库
💻 CPP
字号:
#define __OCICPP_INTERNAL_USE_
#include "BFile.h"#include "OraError.h"
/*!  \class OCICPP::BFile  \brief Binary external Files within the Oracle Server's filesystem  BFiles are a mean of representing large objects within the Oracle Server.  Alternatives are Lob and TLob. The main difference between BFiles od the one  side and Lobs and TLobs on the other is, that the BFile does not reside   within the database's tablespaces (whereas Lobs and TLobs do). A BFile is  located  within the server's filesystem and thus has to be accessed there.  Storing data externally has some consequences:  \arg The operating system is responsible for storing these files  \arg The is no way the Oracle Server can preserve these files  \arg Since there is a maximum number of open file handles, one can never be       sure to have access to a BFile, even if it exists  \arg BFiles are (currently?) read-only  On the other hand, there are some advantages:  \arg The BFile does not populate the database tables (which may resolve in       smaller databases)  \arg BFiles are a mean of separating classical database content (in terms of       entities that have a relation) from multimedia data (which typically is       a rather large amount of data)  Oracle states, that there is hardly any measurable performace difference  between the large-object datatypes Lob, TLob and BFile, which leaves the  decission of the type to be used to the user again. However, current policy  seems to discourage the usage of BFiles.  However, they can be very useful (according to the documentation writters  humble opinion) if used carefully (and even reduce work). Imagine a database  storing mainly textual data, where additionally some images or even audio-  or video-sequences are incorporated. Lets again assume that the whole   application is designed in client-server architecture, so that there is a  big database which may be accessed from (many, perhaps browser) clients.  BFiles then offer the capability to map data not stored within the database  throught the Oracle-Layer to the client, so that there is no need to code a  broker of any kind - this leaves one backend less.  Let's look, if there's a Video-Archive identified by \c ZUSE and retreive  the length of the BFILE-column called \b DATA (Error-Handling within this  example is admittedly a little too rought...)  \code  using namespace OCICPP;  int len = 0;  try {    Cursor cur;    con->execQuery( "select * from MM_ARCHIVE WHERE TYPE='V' and ID='ZUSE'",                    cur );    if ( cur.fetch() ) {      BFile bfile;      cur.getFILE( "DATA", bfile );      bfile.open();      len = bfile.getLen();      bfile.close();      bfile.drop();    }    cur.drop();  } catch ( OraError ) {  }  \endcode  For additional information on how to create BFILE entities within the  database, please refer to the Oracle Server Documentation (\b BFILENAME and  \b CREATE \b DIRECTORY ). *//*!  Construct an unbound bfile entity. */OCICPP::BFile::BFile():type(OCICPP::BFILE) {	init(0,0,0);}OCICPP::BFile::BFile(OCISvcCtx *svcctx,OCILobLocator *lob_desc,OCIError *err): type(OCICPP::BFILE) {	init(svcctx,lob_desc,err);}void OCICPP::BFile::init(OCISvcCtx *svcctx,OCILobLocator *lob_desc,OCIError *err) {	boolean flg;	svchp=svcctx;	lob=lob_desc;	errhp=err;	offset=1;	needLobFree=false;	if(svchp && errhp) {		DEBUG(DLEV_DEBUG,"Obtaining BFile len\n");		CHECKERR(errhp,OCILobFileExists(svchp,errhp,lob,&flg));		if(flg==FALSE) {			throw OraError("OCICCPLIB: File not exist on server",OCICPPERROR);		}		CHECKERR(errhp,OCILobGetLength(svchp,errhp,lob,(ub4 *)&len));				DEBUG(DLEV_DEBUG,"BFile len is %d\n",len);	} else {		len=0;	}}void OCICPP::BFile::init(OCIEnv *envhp,OCISvcCtx *svcctx,OCIError *err,						const string &dir,const string &fname) {	boolean flg;	svchp=svcctx;	errhp=err;	offset=1;	needLobFree=true;	if(envhp && svchp && errhp) {		DEBUG(DLEV_DEBUG,"Creating BFILE\n");		if(OCIDescriptorAlloc(envhp,(void **)&lob,OCI_DTYPE_FILE,0,0)!=OCI_SUCCESS) {			throw OraError("OCICPPLIB: Cannot make new BFILE: Handle Allocation failed",OCICPPERROR);		}					CHECKERR(errhp,			OCILobFileSetName(envhp,errhp,&lob,							(OraText*)const_cast<char *>(dir.c_str()),							dir.size(),							(OraText *)const_cast<char *>(fname.c_str()),							fname.size()));												CHECKERR(errhp,OCILobFileExists(svchp,errhp,lob,&flg));		if(flg==FALSE) {			throw OraError("OCICCPLIB: File not exist on server",OCICPPERROR);		}		CHECKERR(errhp,OCILobGetLength(svchp,errhp,lob,(ub4 *)&len));				DEBUG(DLEV_DEBUG,"BFile len is %d\n",len);	} else {		len=0;	}}/*!  Destruct a bfile entity. */OCICPP::BFile::~BFile() {	/* nothing to be done yet 	   all real work is in ~Cursor	   See TODO about how it should work ..	*/	drop();}/*!  Drop a BFile entity. The Oracle Descriptior is freed on demand leaving the  BFile instance ready for being reused. */void OCICPP::BFile::drop() {	if(needLobFree) {		OCIDescriptorFree(lob,OCI_DTYPE_FILE);	}}/*!  Set the position for reading/writing within a bfile.  \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 BFile. \a offset may not be           greater than Bfile's length ( getLen() ).  \arg LOB_CUR modifies the access point within the BFile relative to the current           position. \a current position \a + \a offset may not exceed the           BFile's length  \arg LOB_END sets the position from the end of the BFile.  \param new_offset is the new distance relative to the given direction \a dir*/void OCICPP::BFile::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==OCICPP::LOB_SET) offset=new_offset+1;	else if(dir==OCICPP::LOB_END) offset=len-new_offset+1;	else if(dir==OCICPP::LOB_CUR) offset=offset+new_offset;	else throw OraError("OCICPPLIB: Cannot seek: Unknown direction",OCICPPERROR);}/*!  Retuns the current position from the start of the BFile. For this position,  the inequation 0 <= tell() < getLen() holds. */unsigned OCICPP::BFile::tell() {	return offset-1;}/*!  Open a BFile. Before accessing, such a BFile has to be opened. Please keep  in mind, that there is maximum number of simultaneously opened file handles  withing the Oracle Server process. */void OCICPP::BFile::open() {	CHECKERR(errhp,OCILobFileOpen(svchp,errhp,lob,OCI_FILE_READONLY));}/*!  Close a previously opened BFile. This operation sets one file handle free  again on the Oracle Server again. */void OCICPP::BFile::close() {	CHECKERR(errhp,OCILobFileClose(svchp,errhp,lob));}/*!  Read a sequence of \a buf_len bytes from the BFile into the buffer \a buf.  The amount of bytes actually transfered is being returned. */unsigned OCICPP::BFile::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 *,dvoid *, ub4, ub1)) 0,(ub2) 0, (ub1) SQLCS_IMPLICIT));	offset+=actread;	return actread;}/*!  Retreive the total amount of data stored within this BFile. */unsigned OCICPP::BFile::getLen() const {	return len;}			

⌨️ 快捷键说明

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