From: Vladimir T. <pr...@us...> - 2004-02-14 16:50:30
|
Update of /cvsroot/firebird/OdbcJdbc/IscDbc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12416 Modified Files: Tag: v1-2-beta BinaryBlob.cpp BinaryBlob.h Blob.h IscBlob.cpp IscBlob.h Log Message: - is added direct operations of reading / record of fields of a type blob branch v1-2-beta Index: BinaryBlob.cpp =================================================================== RCS file: /cvsroot/firebird/OdbcJdbc/IscDbc/BinaryBlob.cpp,v retrieving revision 1.3.2.6 retrieving revision 1.3.2.7 diff -b -U3 -r1.3.2.6 -r1.3.2.7 --- BinaryBlob.cpp 3 Feb 2004 08:58:34 -0000 1.3.2.6 +++ BinaryBlob.cpp 14 Feb 2004 16:43:52 -0000 1.3.2.7 @@ -53,6 +53,7 @@ useCount = 1; offset = 0; populated = true; + directLength = 0; } BinaryBlob::BinaryBlob(int minSegmentSize) : Stream (minSegmentSize) @@ -60,6 +61,7 @@ useCount = 1; offset = 0; populated = true; + directLength = 0; } BinaryBlob::~BinaryBlob() Index: BinaryBlob.h =================================================================== RCS file: /cvsroot/firebird/OdbcJdbc/IscDbc/BinaryBlob.h,v retrieving revision 1.2.2.8 retrieving revision 1.2.2.9 diff -b -U3 -r1.2.2.8 -r1.2.2.9 --- BinaryBlob.h 3 Feb 2004 08:58:35 -0000 1.2.2.8 +++ BinaryBlob.h 14 Feb 2004 16:43:52 -0000 1.2.2.9 @@ -48,6 +48,12 @@ virtual void writeStreamHexToBlob(char * sqldata) {}; virtual void writeBlob(char * sqldata, char *data, long length) {}; virtual void writeStringHexToBlob(char * sqldata, char *data, long length) {}; + virtual void directCreateBlob( char * sqldata ) {}; + virtual void directOpenBlob(char * sqldata ) {}; + virtual bool directFetchBlob(char *data, int length, int &lengthRead) { return false; } + virtual bool directGetSegmentToHexStr( char * bufData, int lenData, int &lenRead ) { return false; } + virtual void directWriteBlob( char *data, long length ) {}; + virtual void directCloseBlob() {}; void putSegment (int length, const char *data, bool copyFlag); void putLongSegment(int length, const char * data); int length(); @@ -73,6 +79,7 @@ long sectionId; long recordNumber; bool populated; + int directLength; }; }; // end namespace IscDbcLibrary Index: Blob.h =================================================================== RCS file: /cvsroot/firebird/OdbcJdbc/IscDbc/Blob.h,v retrieving revision 1.2.2.6 retrieving revision 1.2.2.7 diff -b -U3 -r1.2.2.6 -r1.2.2.7 --- Blob.h 3 Feb 2004 08:58:35 -0000 1.2.2.6 +++ Blob.h 14 Feb 2004 16:43:52 -0000 1.2.2.7 @@ -29,6 +29,12 @@ virtual void writeStreamHexToBlob(char * sqldata) = 0; virtual void writeBlob(char * sqldata, char *data, long length) = 0; virtual void writeStringHexToBlob(char * sqldata, char *data, long length) = 0; + virtual void directCreateBlob( char * sqldata ) = 0; + virtual void directOpenBlob(char * sqldata) = 0; + virtual bool directFetchBlob(char *data, int length, int &lengthRead) = 0; + virtual bool directGetSegmentToHexStr( char * bufData, int lenData, int &lenRead ) = 0; + virtual void directWriteBlob( char *data, long length ) = 0; + virtual void directCloseBlob() = 0; virtual void bind(Connection *connect, char * sqldata) = 0; virtual void attach(char * pointBlob, bool fetched, bool clear) = 0; Index: IscBlob.cpp =================================================================== RCS file: /cvsroot/firebird/OdbcJdbc/IscDbc/IscBlob.cpp,v retrieving revision 1.2.2.5 retrieving revision 1.2.2.6 diff -b -U3 -r1.2.2.5 -r1.2.2.6 --- IscBlob.cpp 24 Dec 2003 12:32:07 -0000 1.2.2.5 +++ IscBlob.cpp 14 Feb 2004 16:43:52 -0000 1.2.2.6 @@ -35,6 +35,8 @@ #include "IscStatement.h" #include "SQLError.h" +extern short conwBinToHexStr[]; + namespace IscDbcLibrary { ////////////////////////////////////////////////////////////////////// @@ -45,7 +47,9 @@ { connection = NULL; memset(&blobId,0,sizeof(ISC_QUAD)); + directBlobHandle = NULL; fetched = false; + directBlob = false; enType = enTypeBlob; } @@ -89,6 +93,9 @@ int IscBlob::length() { + if ( directBlob ) + return directLength; + if (!fetched) fetchBlob(); @@ -115,7 +122,7 @@ if (ret) THROW_ISC_EXCEPTION (connection, statusVector); - char buffer [10000]; + char buffer [DEFAULT_BLOB_BUFFER_LENGTH]; unsigned short length; for (;;) @@ -267,4 +274,180 @@ writeBlob(sqldata, data, length); } +// +// Block direct operations reading SQLGetData +// +extern signed long getVaxInteger(const unsigned char * ptr, signed short length); + +void IscBlob::directOpenBlob( char * sqldata ) +{ + ISC_STATUS statusVector [20]; + CFbDll * GDS = connection->GDS; + fetched = false; + + if ( directBlobHandle ) + GDS->_close_blob (statusVector, &directBlobHandle); + + void *transactionHandle = connection->startTransaction(); + int ret = GDS->_open_blob2 (statusVector, &connection->databaseHandle, &transactionHandle, + &directBlobHandle, (ISC_QUAD*) sqldata, 0, NULL); + if (ret) + THROW_ISC_EXCEPTION (connection, statusVector); + + const char blob_info[] = { isc_info_blob_total_length }; + unsigned char buffer[64]; + + ret = GDS->_blob_info ( statusVector, &directBlobHandle, sizeof(blob_info), (char*)blob_info, sizeof(buffer), (char*)buffer); + if (ret) + THROW_ISC_EXCEPTION (connection, statusVector); + + unsigned char * p = buffer; + + if ( *p++ == isc_info_blob_total_length ) + directLength = getVaxInteger(p+2, (short)getVaxInteger(p, 2)); + else + directLength = 0; + directBlob = true; +} + +bool IscBlob::directFetchBlob( char * bufData, int lenData, int &lenRead ) +{ + ISC_STATUS statusVector [20]; + unsigned short length; + bool bEndData = false; + + if ( lenData ) + { + CFbDll * GDS = connection->GDS; + int post = lenData > DEFAULT_BLOB_BUFFER_LENGTH ? DEFAULT_BLOB_BUFFER_LENGTH : lenData; + char *data = bufData; + int ret; + + while ( lenData ) + { + if ( (ret = GDS->_get_segment (statusVector, &directBlobHandle, &length, post, data)) ) + { + if (ret == isc_segstr_eof) + { + directCloseBlob(); + bEndData = true; + break; + } + else if (ret != isc_segment) + THROW_ISC_EXCEPTION (connection, statusVector); + } + data += length; + lenData -= length; + if ( lenData < post ) + post = lenData; + } + + lenRead = data - bufData; + } + return bEndData; +} + +bool IscBlob::directGetSegmentToHexStr( char * bufData, int lenData, int &lenRead ) +{ + ISC_STATUS statusVector [20]; + unsigned short length; + bool bEndData = false; + + if ( lenData ) + { + CFbDll * GDS = connection->GDS; + int post = lenData > DEFAULT_BLOB_BUFFER_LENGTH ? DEFAULT_BLOB_BUFFER_LENGTH : lenData; + char *data = bufData; + int ret; + + while ( lenData ) + { + if ( (ret = GDS->_get_segment (statusVector, &directBlobHandle, &length, post, data)) ) + { + if (ret == isc_segstr_eof) + { + directCloseBlob(); + bEndData = true; + break; + } + else if (ret != isc_segment) + THROW_ISC_EXCEPTION (connection, statusVector); + } + + short *address = (short*)data + length - 1; + unsigned char *end = (unsigned char *)data + length - 1; + + data += length*2; + lenData -= length; + if ( lenData < post ) + post = lenData; + + while( length-- ) + *address-- = conwBinToHexStr[*end--]; + } + + lenRead = data - bufData; + } + return bEndData; +} + +void IscBlob::directCloseBlob() +{ + if ( directBlobHandle ) + { + ISC_STATUS statusVector [20]; + connection->GDS->_close_blob (statusVector, &directBlobHandle); + directBlobHandle = NULL; + } + fetched = true; + directBlob = false; +} + +// +// Block direct operations at record SQLPutData +// +void IscBlob::directCreateBlob( char * sqldata ) +{ + ISC_STATUS statusVector [20]; + CFbDll * GDS = connection->GDS; + + if ( directBlobHandle ) + GDS->_close_blob (statusVector, &directBlobHandle); + + void *transactionHandle = connection->startTransaction(); + GDS->_create_blob2 ( statusVector, + &connection->databaseHandle, + &transactionHandle, + &directBlobHandle, + (ISC_QUAD*) sqldata, + 0, NULL ); + + if ( statusVector [1] ) + THROW_ISC_EXCEPTION (connection, statusVector); +} + +void IscBlob::directWriteBlob( char *data, long length ) +{ + ISC_STATUS statusVector [20]; + CFbDll * GDS = connection->GDS; + + int post = DEFAULT_BLOB_BUFFER_LENGTH; + + while ( length > post ) + { + GDS->_put_segment ( statusVector, &directBlobHandle, post, data); + if ( statusVector [1] ) + THROW_ISC_EXCEPTION ( connection, statusVector ); + data += post; + length -= post; + } + + if ( length > 0 ) + { + GDS->_put_segment ( statusVector, &directBlobHandle, (unsigned short)length, data); + if ( statusVector [1] ) + THROW_ISC_EXCEPTION (connection, statusVector); + } +} + }; // end namespace IscDbcLibrary Index: IscBlob.h =================================================================== RCS file: /cvsroot/firebird/OdbcJdbc/IscDbc/IscBlob.h,v retrieving revision 1.2.2.5 retrieving revision 1.2.2.6 diff -b -U3 -r1.2.2.5 -r1.2.2.6 --- IscBlob.h 24 Dec 2003 12:32:07 -0000 1.2.2.5 +++ IscBlob.h 14 Feb 2004 16:43:52 -0000 1.2.2.6 @@ -55,9 +55,18 @@ IscBlob(IscConnection *connect, XSQLVAR *var); ~IscBlob(); + void directCreateBlob( char * sqldata ); + void directOpenBlob(char * sqldata); + bool directFetchBlob(char *data, int length, int &lengthRead); + bool directGetSegmentToHexStr( char * bufData, int lenData, int &lenRead ); + void directWriteBlob( char *data, long length ); + void directCloseBlob(); + IscConnection *connection; ISC_QUAD blobId; + isc_blob_handle directBlobHandle; bool fetched; + bool directBlob; }; }; // end namespace IscDbcLibrary |