diff -r 000000000000 -r 08ec8eefde2f persistentstorage/sql/SRC/Server/SqlSrvBlob.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/sql/SRC/Server/SqlSrvBlob.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,280 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "sqlite3.h" +#include "SqlPanic.h" +#include "SqlSrvBlob.h" +#include "SqliteSymbian.h" +#include "SqlSrvUtil.h" +#include "SqlSrvStrings.h" +#include "SqlDb.h" + +/** +Creates a new HBlobBuf instance. + +@param aDb The database handle +@param aDbName The database name, zero-terminated. If the blob belongs to one of the attached databases, + then the attached database name should be used as the value of aDbName, otherwise the + value should be "main" +@param aTableName The name of the table to which the blob belongs, zero-terminated. +@param aColumnName The name of the blob column, zero-terminated. +@param aRowId The ROWID of the row to which the blob belongs +@param aMode Specifies the blob access mode, either HBlobBuf::EReadOnly or HBlobBuf::EReadWrite + +@leave KErrNoMemory, An out of memory condition has occurred; + Note that the function may also leave with some other system wide errors or + database specific errors categorised as ESqlDbError. + +@return A pointer to the created HBlobBuf instance + +@panic SqlDb 4 In _DEBUG mode. NULL aDb parameter. +@panic SqlDb 4 In _DEBUG mode. Negative or zero aRowId. +@panic SqlDb 4 In _DEBUG mode. aMode parameter is not HBlobBuf::EReadOnly or HBlobBuf::EReadWrite. +*/ +HBlobBuf* HBlobBuf::NewL(sqlite3* aDb, const TDesC8& aDbName, const TDesC8& aTableName, const TDesC8& aColumnName, TInt64 aRowId, TMode aMode) + { + __SQLASSERT(aDb != NULL, ESqlPanicBadArgument); + __SQLASSERT(aRowId > 0, ESqlPanicBadArgument); + __SQLASSERT(aMode == HBlobBuf::EReadOnly || aMode == HBlobBuf::EReadWrite, ESqlPanicBadArgument); + + HBlobBuf* self = new (ELeave) HBlobBuf; + CleanupStack::PushL(self); + self->ConstructL(aDb, aDbName, aTableName, aColumnName, aRowId, aMode); + CleanupStack::Pop(self); + return self; + } + +/** +Initializes HBlobBuf data members with their default values. +*/ +HBlobBuf::HBlobBuf() : + iBlobHandle(NULL), + iWrPos(KMinTInt), + iRdPos(KMinTInt) + { + } + +/** +Initializes a new HBlobBuf instance. + +@param aDb The database handle +@param aDbName The database name, zero-terminated. If the blob belongs to one of the attached databases, + then the attached database name should be used as a value of aDbName, otherwise the + value should be "main" +@param aTableName The name of the table to which the blob belongs, zero-terminated. +@param aColumnName The name of the blob column, zero-terminated. +@param aRowId The ROWID of the row to which the blob belongs +@param aMode Specifies the blob access mode, either HBlobBuf::EReadOnly or HBlobBuf::EReadWrite + +@leave KErrNoMemory, An out of memory condition has occurred; + Note that the function may also leave with some other system wide errors or + database specific errors categorised as ESqlDbError. + +@panic SqlDb 4 In _DEBUG mode. NULL aDb parameter. +@panic SqlDb 4 In _DEBUG mode. Negative or zero aRowId. +@panic SqlDb 4 In _DEBUG mode. aMode parameter is not HBlobBuf::EReadOnly or HBlobBuf::EReadWrite. +@panic SqlDb 7 In _DEBUG mode. NULL blob handle. +*/ +void HBlobBuf::ConstructL(sqlite3* aDb, const TDesC8& aDbName, const TDesC8& aTableName, const TDesC8& aColumnName, TInt64 aRowId, TMode aMode) + { + __SQLASSERT(aDb != NULL, ESqlPanicBadArgument); + __SQLASSERT(aRowId > 0, ESqlPanicBadArgument); + __SQLASSERT(aMode == HBlobBuf::EReadOnly || aMode == HBlobBuf::EReadWrite, ESqlPanicBadArgument); + + (void)sqlite3SymbianLastOsError();//clear last OS error + + TInt err = sqlite3_blob_open(aDb, (const char*)aDbName.Ptr(), (const char*)aTableName.Ptr(), (const char*)aColumnName.Ptr(), + aRowId, aMode & HBlobBuf::EReadWrite, &iBlobHandle); + __SQLLEAVE_IF_ERROR(::Sql2OsErrCode(err, sqlite3SymbianLastOsError())); + __SQLASSERT(iBlobHandle != NULL, ESqlPanicInternalError); + iBlobSize = sqlite3_blob_bytes(iBlobHandle); + iWrPos = iRdPos = 0; + } + +/** +Closes the blob handle as part of the HBlobBuf object being destroyed. +*/ +void HBlobBuf::DoRelease() + { + TRAP_IGNORE(DoSynchL()); + } + +/** +Closes the blob handle. +Any buffered data is delivered to the stream. +*/ +void HBlobBuf::DoSynchL() + { + if(iBlobHandle) + { + TInt err = sqlite3_blob_close(iBlobHandle); + iBlobHandle = NULL; // the close is unconditional, even if an error occurs + __SQLLEAVE_IF_ERROR(::Sql2OsErrCode(err, sqlite3SymbianLastOsError())); + } + } + +/** +Reads a data block from the blob with the specified length. + +@param aPtr Pointer to the location where the blob data will be copied +@param aMaxLength The length of the data block to be read + +@leave KErrNoMemory, An out of memory condition has occurred; + KErrEof, An attempt has been made to read beyond the end of the blob; + KErrBadHandle, NULL blob handle; + Note that the function may also leave with some other system + wide errors or database specific errors categorised as ESqlDbError. + +@return The number of bytes read. + +@panic SqlDb 4 In _DEBUG mode. NULL aPtr parameter. +@panic SqlDb 4 In _DEBUG mode. Negative aMaxLength parameter. +@panic SqlDb 2 In _DEBUG mode. NULL iBlobHandle. +*/ +TInt HBlobBuf::DoReadL(TAny* aPtr, TInt aMaxLength) + { + __SQLASSERT(aPtr != NULL, ESqlPanicBadArgument); + __SQLASSERT(aMaxLength >= 0, ESqlPanicBadArgument); + __SQLASSERT(iBlobHandle != NULL, ESqlPanicInvalidObj); + + if(aMaxLength <= 0) + { + return 0; + } + + (void)sqlite3SymbianLastOsError();//clear last OS error + + if(iRdPos >= iBlobSize) + { + __SQLLEAVE(KErrEof); + } + if((aMaxLength + iRdPos) > iBlobSize) + { + aMaxLength = iBlobSize - iRdPos; + } + TInt err = sqlite3_blob_read(BlobHandleL(), aPtr, aMaxLength, iRdPos); + __SQLLEAVE_IF_ERROR(::Sql2OsErrCode(err, sqlite3SymbianLastOsError())); + iRdPos += aMaxLength; + return aMaxLength; + } + +/** +Writes a data block with the specified length to the blob. + +@param aPtr Pointer to the location with the blob data to be written +@param aLength The length of the data block to be written + +@leave KErrNoMemory, An out of memory condition has occurred; + KErrEof, An attempt has been made to write beyond the end of the blob; + KErrBadHandle, NULL blob handle; + Note that the function may also leave with some other system + wide errors or database specific errors categorised as ESqlDbError. + +@panic SqlDb 4 In _DEBUG mode. NULL aPtr parameter. +@panic SqlDb 4 In _DEBUG mode. Negative aLength parameter. +@panic SqlDb 2 In _DEBUG mode. NULL iBlobHandle. +*/ +void HBlobBuf::DoWriteL(const TAny* aPtr, TInt aLength) + { + __SQLASSERT(aPtr != NULL, ESqlPanicBadArgument); + __SQLASSERT(aLength >= 0, ESqlPanicBadArgument); + __SQLASSERT(iBlobHandle != NULL, ESqlPanicInvalidObj); + + if(aLength <= 0) + { + return; + } + + if((iWrPos + aLength) > iBlobSize) + { + __SQLLEAVE(KErrEof); + } + + (void)sqlite3SymbianLastOsError();//clear last OS error + TInt err = sqlite3_blob_write(BlobHandleL(), aPtr, aLength, iWrPos); + err = ::Sql2OsErrCode(err, sqlite3SymbianLastOsError()); + + __SQLLEAVE_IF_ERROR(err); + iWrPos += aLength; + } + +/** +Positions the mark(s) indicated by aMark at aOffset from aLocation. + +@leave KErrEof, An attempt has been made to seek beyond the end of the blob; + KErrBadHandle, NULL blob handle; + Note that the function may also leave with some other system wide errors or + database specific errors categorised as ESqlDbError. + +@return The new stream position (read or write) + +@panic SqlDb 2 In _DEBUG mode. NULL iBlobHandle. +@panic SqlDb 4 In _DEBUG mode. Negative aOffset parameter. +@panic SqlDb 8 In _DEBUG mode. Invalid aMark parameter. +@panic SqlDb 9 In _DEBUG mode. Invalid aLocation parameter. +*/ +TStreamPos HBlobBuf::DoSeekL(MStreamBuf::TMark aMark, TStreamLocation aLocation, TInt aOffset) + { + __SQLASSERT_ALWAYS(!(aMark & ~(ERead | EWrite)), ESqlPanicStreamMarkInvalid); + __SQLASSERT(aOffset >= 0, ESqlPanicBadArgument); + __SQLASSERT(iBlobHandle != NULL, ESqlPanicInvalidObj); + + TInt newPos = 0; + switch(aLocation) + { + case EStreamBeginning: + newPos = aOffset; + break; + case EStreamMark: + newPos = (aMark & MStreamBuf::EWrite ? iWrPos : iRdPos) + aOffset; + break; + case EStreamEnd: + newPos = iBlobSize + aOffset; + break; + default: + __SQLASSERT(0, ESqlPanicStreamLocationInvalid); + newPos = -1; + break; + } + if(newPos < 0 || newPos > iBlobSize) + { + __SQLLEAVE(KErrEof); + } + if(aMark & MStreamBuf::EWrite) + { + iWrPos = newPos; + } + else if(aMark & MStreamBuf::ERead) + { + iRdPos = newPos; + } + return TStreamPos(newPos); + } + +/** +Returns the blob handle, if it is not NULL. + +@leave KErrBadHandle, The blob handle is NULL. + +@return The blob handle +*/ +sqlite3_blob* HBlobBuf::BlobHandleL() + { + if(!iBlobHandle) + { + __SQLLEAVE(KErrBadHandle); + } + return iBlobHandle; + }